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>
133 lines
3.8 KiB
JavaScript
133 lines
3.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Fund the ATM's Lightning.Pub account via Nostr RPC
|
|
*
|
|
* This creates an invoice for the ATM user (authenticated via Nostr),
|
|
* so the funds go directly to the user that will be queried for balance.
|
|
*
|
|
* Usage:
|
|
* VITE_ATM_PRIVATE_KEY=xxx VITE_LIGHTNING_PUB_PUBKEY=yyy node fund-dev.mjs [amount]
|
|
*/
|
|
import { NostrClient, loadIdentityFromHex, encryptContent, decryptJSON } from '../dist/index.js'
|
|
import { finalizeEvent } from 'nostr-tools'
|
|
import { randomUUID } from 'crypto'
|
|
|
|
const ATM_PRIVATE_KEY = process.env.VITE_ATM_PRIVATE_KEY
|
|
const LIGHTNING_PUB_PUBKEY = process.env.VITE_LIGHTNING_PUB_PUBKEY
|
|
const RELAY_URL = process.env.VITE_RELAY_URL || 'ws://localhost:7777'
|
|
const APP_ID = process.env.VITE_APP_ID || ''
|
|
const FUND_AMOUNT = parseInt(process.argv[2] || process.env.FUND_AMOUNT || '100000', 10)
|
|
|
|
if (!ATM_PRIVATE_KEY) {
|
|
console.error('Error: VITE_ATM_PRIVATE_KEY environment variable required')
|
|
process.exit(1)
|
|
}
|
|
|
|
if (!LIGHTNING_PUB_PUBKEY) {
|
|
console.error('Error: VITE_LIGHTNING_PUB_PUBKEY environment variable required')
|
|
process.exit(1)
|
|
}
|
|
|
|
if (!APP_ID) {
|
|
console.error('Error: VITE_APP_ID environment variable required')
|
|
console.error('This ensures funds go to the same user as LNURL-withdraw uses')
|
|
process.exit(1)
|
|
}
|
|
|
|
async function main() {
|
|
const identity = loadIdentityFromHex(ATM_PRIVATE_KEY)
|
|
console.error('[fund-dev] ATM pubkey:', identity.publicKey)
|
|
console.error('[fund-dev] Lightning.Pub pubkey:', LIGHTNING_PUB_PUBKEY)
|
|
console.error('[fund-dev] Creating invoice for', FUND_AMOUNT, 'sats')
|
|
|
|
const client = new NostrClient({
|
|
relays: [{ url: RELAY_URL }],
|
|
identity,
|
|
})
|
|
|
|
await client.connect()
|
|
console.error('[fund-dev] Connected to relay:', RELAY_URL)
|
|
|
|
const requestId = randomUUID()
|
|
|
|
console.error('[fund-dev] App ID:', APP_ID)
|
|
|
|
// Correct RPC structure per Lightning.Pub documentation
|
|
// appId ensures the Nostr user is created under the same app as HTTP API users
|
|
const rpcRequest = {
|
|
rpcName: 'NewInvoice',
|
|
params: {},
|
|
query: {},
|
|
body: {
|
|
amountSats: FUND_AMOUNT,
|
|
memo: `ATM funding (${FUND_AMOUNT} sats)`,
|
|
},
|
|
authIdentifier: identity.publicKey,
|
|
requestId,
|
|
appId: APP_ID,
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
// Subscribe to responses before publishing
|
|
let invoice = null
|
|
const subId = client.subscribe(
|
|
[
|
|
{
|
|
kinds: [21000],
|
|
authors: [LIGHTNING_PUB_PUBKEY],
|
|
'#p': [identity.publicKey],
|
|
since: Math.floor(Date.now() / 1000) - 5,
|
|
},
|
|
],
|
|
{
|
|
onEvent: (evt) => {
|
|
try {
|
|
const response = decryptJSON(identity, LIGHTNING_PUB_PUBKEY, evt.content)
|
|
if (response.requestId === requestId && response.invoice) {
|
|
invoice = response.invoice
|
|
console.error('[fund-dev] Got invoice!')
|
|
}
|
|
} catch (err) {
|
|
// Ignore decrypt errors for other messages
|
|
}
|
|
},
|
|
}
|
|
)
|
|
|
|
await client.publish(event)
|
|
console.error('[fund-dev] Request published, waiting for invoice...')
|
|
|
|
// Wait up to 15 seconds for response
|
|
for (let i = 0; i < 30; i++) {
|
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
if (invoice) break
|
|
}
|
|
|
|
client.unsubscribe(subId)
|
|
client.disconnect()
|
|
|
|
if (!invoice) {
|
|
console.error('[fund-dev] Error: No invoice received within timeout')
|
|
process.exit(1)
|
|
}
|
|
|
|
// Output just the invoice to stdout (for piping to payment command)
|
|
console.log(invoice)
|
|
process.exit(0)
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('[fund-dev] Error:', err.message)
|
|
process.exit(1)
|
|
})
|