Move 9 development/testing .mjs scripts out of the package root into dev/ to keep the published package clean. Update relative imports and dev.sh reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
import { NostrClient, loadIdentityFromHex, encryptContent, decryptJSON } from '../dist/index.js'
|
|
import { Relay } from 'nostr-tools/relay'
|
|
import { finalizeEvent } from 'nostr-tools'
|
|
import { randomUUID } from 'crypto'
|
|
|
|
const DEV_PRIVATE_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
|
const LIGHTNING_PUB_PUBKEY =
|
|
process.env.LIGHTNING_PUB_PUBKEY ||
|
|
'4a72e400a254bf74a70cc711ab97e461b8d4fd9738b1ac3b5194cdeb3192ab91'
|
|
const RELAY_URL = process.env.NOSTR_RELAY_URL || 'ws://localhost:7777'
|
|
|
|
// Get a fresh invoice from Alice first:
|
|
// docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt 1000
|
|
const TEST_INVOICE = process.argv[2]
|
|
|
|
if (!TEST_INVOICE) {
|
|
console.log('Usage: node test-pay.mjs <invoice>')
|
|
console.log(
|
|
'Generate invoice: docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt 1000'
|
|
)
|
|
process.exit(1)
|
|
}
|
|
|
|
async function main() {
|
|
const identity = loadIdentityFromHex(DEV_PRIVATE_KEY)
|
|
console.log('Using identity:', identity.publicKey)
|
|
|
|
console.log('Connecting to relay...')
|
|
const relay = await Relay.connect(RELAY_URL)
|
|
console.log('Connected!')
|
|
|
|
const requestId = randomUUID()
|
|
|
|
// Check if invoice has amount (look for pattern before '1' separator)
|
|
const amountMatch = TEST_INVOICE.toLowerCase().match(/ln(?:bc|tb|bcrt)(\d+)?([munp])?1/)
|
|
const hasAmount = amountMatch && amountMatch[1]
|
|
console.log('Invoice amount match:', amountMatch ? amountMatch.slice(0, 3) : null)
|
|
console.log('Has embedded amount:', hasAmount)
|
|
|
|
// Build body - amount is always required (use 0 for invoices with embedded amounts)
|
|
const body = {
|
|
invoice: TEST_INVOICE,
|
|
amount: hasAmount ? 0 : 2000, // 0 means "use invoice amount"
|
|
}
|
|
console.log('Body amount:', body.amount, hasAmount ? '(use invoice amount)' : '(explicit amount)')
|
|
|
|
const rpcRequest = {
|
|
rpcName: 'PayInvoice',
|
|
params: {},
|
|
query: {},
|
|
body,
|
|
authIdentifier: identity.publicKey,
|
|
requestId,
|
|
}
|
|
|
|
console.log('\nRequest structure:', JSON.stringify(rpcRequest, null, 2))
|
|
|
|
const encryptedContent = encryptContent(identity, LIGHTNING_PUB_PUBKEY, rpcRequest)
|
|
|
|
const event = finalizeEvent(
|
|
{
|
|
kind: 21000,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
tags: [['p', LIGHTNING_PUB_PUBKEY]],
|
|
content: encryptedContent,
|
|
},
|
|
identity.privateKey
|
|
)
|
|
|
|
console.log('\nPublishing PayInvoice request (event id:', event.id.substring(0, 16) + '...)...')
|
|
|
|
// Subscribe to responses
|
|
const filter = {
|
|
kinds: [21000],
|
|
authors: [LIGHTNING_PUB_PUBKEY],
|
|
since: Math.floor(Date.now() / 1000) - 5,
|
|
}
|
|
|
|
let responseReceived = false
|
|
const sub = relay.subscribe([filter], {
|
|
onevent(evt) {
|
|
// Check if for us
|
|
const pTags = evt.tags.filter((t) => t[0] === 'p')
|
|
if (!pTags.some((t) => t[1] === identity.publicKey)) return
|
|
|
|
console.log('\nGot response event:', evt.id.substring(0, 16) + '...')
|
|
try {
|
|
const response = decryptJSON(identity, LIGHTNING_PUB_PUBKEY, evt.content)
|
|
console.log('Response:', JSON.stringify(response, null, 2))
|
|
if (response.requestId === requestId) {
|
|
responseReceived = true
|
|
}
|
|
} catch (err) {
|
|
console.log('Failed to decrypt:', err.message)
|
|
}
|
|
},
|
|
})
|
|
|
|
await relay.publish(event)
|
|
console.log('Request published, waiting for response...')
|
|
|
|
// Wait for response
|
|
for (let i = 0; i < 20; i++) {
|
|
await new Promise((r) => setTimeout(r, 500))
|
|
if (responseReceived) break
|
|
}
|
|
|
|
if (!responseReceived) {
|
|
console.log('\nNo response received for our requestId within timeout')
|
|
}
|
|
|
|
sub.close()
|
|
relay.close()
|
|
}
|
|
|
|
main().catch(console.error)
|