# @welshman/dvm [![version](https://badgen.net/npm/v/@welshman/dvm)](https://npmjs.com/package/@welshman/dvm) Utilities for building nostr DVMs. # Request example ```javascript import type {Publish, Subscription} from '@welshman/net' import {makeDvmRequest, DVMEvent} from '@welshman/dvm' const req = makeDvmRequest({ // Create and sign a dvm request event, including any desired tags event: createAndSign({kind: 5300}), // Publish and subscribe to these relays relays: ['wss://relay.damus.io', 'wss://dvms.f7z.io'], // Timeout defaults to 30 seconds timeout: 30_000, // Auto close on first result (defaults to true) autoClose: true, // Listen for and emit `progress` events reportProgress: true, }) // Listen for progress, result, etc req.emitter.on(DVMEvent.Progress, (url, event) => console.log(event)) req.emitter.on(DVMEvent.Result, (url, event) => console.log(event)) ``` # Handler example ```javascript const {bytesToHex} = require('@noble/hashes/utils') const {generateSecretKey} = require('nostr-tools') const {createEvent} = require('@welshman/util') const {subscribe} = require('@welshman/net') const {DVM} = require('@welshman/dvm') // Your DVM's private key. Store this somewhere safe // const hexPrivateKey = bytesToHex(generateSecretKey()) const hexPrivateKey = '9cd387a3aa0c1abc2ef517c8402f29c069b4174e02a426491aec7566501bee67' // Tags that we'll return as content discovery suggestions const tags = [] // Populate the tags with music by Ainsley Costello const sub = subscribe({ timeout: 30_000, relays: ["wss://relay.wavlake.com"], filters: [{ kinds: [31337], '#p': ['8806372af51515bf4aef807291b96487ea1826c966a5596bca86697b5d8b23bc'], }], }) // Push event ids to our suggestions sub.emitter.on('event', (url, e) => tags.push(["e", e.id, url])) const dvm = new DVM({ // The private key used to sign events sk: hexPrivateKey, // Relays that the DVM will listen on relays: ['wss://relay.damus.io', 'wss://dvms.f7z.io'], // Only listen to requests tagging our dvm requireMention: true, // Expire results after 1 hour (the default) expireAfter: 60 * 60, // Handlers for various kinds handlers: { 5300: dvm => ({ handleEvent: async function* (event) { // DVM responses are stringified into the content const content = JSON.stringify(tags) // Yield our response. Kind 7000 can be used for partial results too yield createEvent(event.kind + 1000, {content}) }, }), } }) // Enable logging dvm.logEvents = true // When you're ready dvm.start() // When you're done dvm.stop() ```