chore(nostr-client): move dev scripts to dev/ folder

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>
This commit is contained in:
Patrick Mulligan 2026-02-16 17:48:49 -05:00
commit 5448a620a9
10 changed files with 3 additions and 3 deletions

View file

@ -0,0 +1,181 @@
#!/usr/bin/env node
/**
* Test script to simulate a wallet sending an ndebit claim request
* This tests whether Lightning.Pub sends Kind 21002 responses after the fix
*/
import { Relay } from 'nostr-tools/relay'
import { nip44, finalizeEvent, generateSecretKey, getPublicKey } from 'nostr-tools'
import { decodeBech32 } from '@shocknet/clink-sdk'
const { getConversationKey, encrypt, decrypt } = nip44
const NDEBIT =
'ndebit1qgpkzardqyg8wue69uhhxarjvee8jw3hxumnwqpqf05wyqarxsdm9d62fh9lsa6wqc2r0a37cgd00mp3gnydpf5w9uusavytcn'
const RELAY_URL = 'ws://localhost:7777'
const AMOUNT_SATS = 5000 // Small test amount
// Generate a wallet keypair for this test
const WALLET_PRIVATE_KEY = generateSecretKey()
const WALLET_PUBLIC_KEY = getPublicKey(WALLET_PRIVATE_KEY)
async function main() {
console.log('🔧 Test: ndebit claim flow (NIP-44 v2)')
console.log('='.repeat(50))
// Decode ndebit to get Lightning.Pub pubkey and pointer
const decoded = decodeBech32(NDEBIT)
const LPUB_PUBKEY = decoded.data.pubkey
const POINTER = decoded.data.pointer
console.log(`\n📍 Lightning.Pub pubkey: ${LPUB_PUBKEY.slice(0, 16)}...`)
console.log(`🔑 Pointer (user ID): ${POINTER.slice(0, 16)}...`)
console.log(`👛 Test wallet pubkey: ${WALLET_PUBLIC_KEY.slice(0, 16)}...`)
console.log(`💰 Amount: ${AMOUNT_SATS} sats`)
// Connect to relay
console.log(`\n🔌 Connecting to relay: ${RELAY_URL}`)
const relay = await Relay.connect(RELAY_URL)
console.log('✅ Connected!')
// Build the debit request data (NdebitData format)
// Using newNdebitFullAccessRequest format with amount
const debitData = {
amount_sats: AMOUNT_SATS,
pointer: POINTER,
}
// Encrypt using NIP-44 v2
const conversationKey = getConversationKey(WALLET_PRIVATE_KEY, LPUB_PUBKEY)
const encryptedContent = encrypt(JSON.stringify(debitData), conversationKey)
// Build event with correct tags (including clink_version)
const event = finalizeEvent(
{
kind: 21002,
created_at: Math.floor(Date.now() / 1000),
tags: [
['p', LPUB_PUBKEY],
['clink_version', '1'],
],
content: encryptedContent,
},
WALLET_PRIVATE_KEY
)
console.log(`\n📤 Sending Kind 21002 debit request`)
console.log(` Event ID: ${event.id.slice(0, 16)}...`)
console.log(` Content length: ${encryptedContent.length} chars`)
// Subscribe for responses BEFORE sending the request
let responseReceived = false
const startTime = Date.now()
// Filter for Kind 21002 responses from Lightning.Pub that reference our event
const sub = relay.subscribe(
[
{
kinds: [21002],
authors: [LPUB_PUBKEY],
'#p': [WALLET_PUBLIC_KEY],
'#e': [event.id],
since: Math.floor(Date.now() / 1000) - 5,
},
],
{
onevent(evt) {
console.log(`\n📥 Received Kind 21002 response!`)
console.log(` Event ID: ${evt.id.slice(0, 16)}...`)
console.log(` Author: ${evt.pubkey.slice(0, 16)}...`)
// Check #e tag (should reference our original event)
const eTag = evt.tags.find((t) => t[0] === 'e')
if (eTag) {
console.log(` #e tag: ${eTag[1].slice(0, 16)}...`)
if (eTag[1] === event.id) {
console.log(' ✅ Correctly references our original event!')
}
} else {
console.log(' ⚠️ No #e tag found')
}
try {
const response = JSON.parse(decrypt(evt.content, conversationKey))
console.log(`\n📋 Response content:`)
console.log(JSON.stringify(response, null, 2))
if (response.res === 'OK') {
console.log('\n✅✅✅ SUCCESS! Lightning.Pub sent Kind 21002 response correctly!')
console.log(' The fix is working!')
} else if (response.res === 'GFY' || response.error) {
console.log(`\n⚠️ Response indicates error: ${response.error || 'unknown'}`)
console.log(' (Expected if payment denied or auth required)')
}
} catch (e) {
console.log(' ❌ Could not decrypt response:', e.message)
}
responseReceived = true
},
}
)
// Publish the debit request
await relay.publish(event)
console.log('✅ Request published!')
// Wait for response with timeout
console.log('\n⏳ Waiting for Kind 21002 response (30s timeout)...')
const timeout = 30000
const checkInterval = 1000
while (!responseReceived && Date.now() - startTime < timeout) {
await new Promise((r) => setTimeout(r, checkInterval))
const elapsed = Math.floor((Date.now() - startTime) / 1000)
process.stdout.write(`\r ${elapsed}s elapsed...`)
}
console.log('')
if (!responseReceived) {
console.log('\n❌❌❌ TIMEOUT! No Kind 21002 response received.')
console.log(' This means the fix did NOT work or there was another issue.')
// Let's check what Kind 21002 events exist
console.log('\n🔍 Checking for any Kind 21002 events on relay...')
let foundEvents = 0
const allDebitSub = relay.subscribe(
[
{
kinds: [21002],
limit: 10,
},
],
{
onevent(evt) {
foundEvents++
const pTags = evt.tags.filter((t) => t[0] === 'p').map((t) => t[1].slice(0, 8) + '...')
const eTags = evt.tags.filter((t) => t[0] === 'e').map((t) => t[1].slice(0, 8) + '...')
console.log(
` ${foundEvents}. id=${evt.id.slice(0, 12)}... by=${evt.pubkey.slice(0, 8)}... #p=${pTags.join(',')} #e=${eTags.join(',')}`
)
},
oneose() {
console.log(` (Found ${foundEvents} Kind 21002 events total)`)
},
}
)
await new Promise((r) => setTimeout(r, 3000))
allDebitSub.close()
}
sub.close()
relay.close()
console.log('\n🏁 Test complete')
process.exit(responseReceived ? 0 : 1)
}
main().catch((e) => {
console.error('Fatal error:', e)
process.exit(1)
})