{"_id":"@candypoets/lnuts","_rev":"10-cb60dc5e668f221d201c598cbe3d0c44","name":"@candypoets/lnuts","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@candypoets/lnuts","version":"0.1.0","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.0","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"cc8a0a0b69c9b6863a8e903b557dc5abc79ad3fb","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.0.tgz","fileCount":19,"integrity":"sha512-6KW+lZ+Bk2LLSvVYLu2Zbb0grPGjY9mPFVTsrNuHWIyWGuL/c5OtXWTU5xchFtM11dGOsV+zmlS+uk01Q6OI0Q==","signatures":[{"sig":"MEMCIBQdAIRCCqW6mPJ0WoFNjzNIjNPn+unpJO7i8XdPcdMoAh9DLl09UDYWQfIHhif1MSEHoHGo2vtX5GGFcTR7OMaG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":46677},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"3c0008eff7af843f0815bf5eddecbfb41bef57f0","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.0_1763047075389_0.11044066743270098","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@candypoets/lnuts","version":"0.1.1","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.1","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"384b1c9e89ae621fe3a5299dfa70d1ce2e24f1a7","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.1.tgz","fileCount":19,"integrity":"sha512-iLryJ2D1yMc/sUUd6DV6imKcAECX10MUzyT7Lgo5R4Gt43L38nlRIKFkTWcljlDwGholG3pQwXwZxHfCt/SuJg==","signatures":[{"sig":"MEUCIGMkFZ4w84VaOesVqFg5iMxjOIa/NWc2q0h5E9vSzbaDAiEAwHYxVIxfnXM21j6+9ULE7hAsMNRsSW02RPeZrWqJkwY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47623},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"051bc9d4925a8d66d232d46ca57d8112a6c0731a","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.1_1763048309121_0.5083465773042286","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@candypoets/lnuts","version":"0.1.2","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.2","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"e7545a961d2f14ff89827dac64114261640db57d","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.2.tgz","fileCount":19,"integrity":"sha512-BXw4FwQ6YB9WPFfUBsBHLd5zUYKDipyTQOR4Gl1x00DsC8qTrAP5yjFIL3YOkRAmsnR2ByWmg9os46XkZ/KJCQ==","signatures":[{"sig":"MEQCIFlO0T4GKIUSBJ6rwdiX5Fw4RLnphxBMEpXlc3t+QXyOAiA4ONE84JW8c7j/ajM6RFJgg2U3xU0yMlEnQ2ffE+R2lQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47623},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"4dc469cac4e759ef16b3bceefc0319d9f33447e8","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.2_1763048513191_0.20523828449145243","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@candypoets/lnuts","version":"0.1.3","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.3","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"50acb696a050477925f8ef761cda08cfcf4ef1b5","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.3.tgz","fileCount":19,"integrity":"sha512-7NjuCz7EzPhqBbp3SyFFvpc65KgBi1vESpu96emAACBMWw61IHoW80in9MsuyIT00mEo9VJ9BvpIX+0fboXjyQ==","signatures":[{"sig":"MEUCIALvoHiX0lFANPrtgZc4eGVtwIApOaHpp374UDHfRIgdAiEA8WE++jyqCmOa5thkqKF2V/Uq0OpMCbaMeJ7DQaetbh8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47638},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"4dc469cac4e759ef16b3bceefc0319d9f33447e8","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.3_1763050900174_0.1712775277814782","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@candypoets/lnuts","version":"0.1.4","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.4","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"cdb426c78b668cb1aae899306f703feb5aff41be","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.4.tgz","fileCount":19,"integrity":"sha512-8abgabSbeTJVSp31z+jcbEnSQJ32uCguNKa8t8vOnezcLuOT5Yh0muVKcGCSJctgOS+TcRTqavvM6MpWk3svoA==","signatures":[{"sig":"MEQCIEN6CQwwXA3p+hyRttJ/47h/Ef8oaMzacx34nzTUdPIHAiBdFLJ/HBL0sVNHkykXenVWDI3epnBZfYQKyFekA8EbXg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47641},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"fddf0fd032029e609e9ae42a037356732d7bb902","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.4_1763051273119_0.774897460738958","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@candypoets/lnuts","version":"0.1.5","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.5","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"091b866b283c9239ff5853b24a349417ca178caf","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.5.tgz","fileCount":19,"integrity":"sha512-dZLMNqmqTNxyT58A4E9Nwx4XCqILhs5n4iT6xGY42TvXRm5B285pib1ebv/JnagkgNZz7ppqeDDjKyEr/UJ0cQ==","signatures":[{"sig":"MEUCIQD+KCd3Pmqt2KGWggMH9VeavODIP4+wifWlmVu80AlL4gIgXsgsFD4BnsgcwBZirPSmsnnc2UUXg8vOa2/75EhcJ/o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51928},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"7bcc750691cdb2821e1ec43ea67751a3b8ff8309","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{"example":"examples/"},"_nodeVersion":"18.20.3","dependencies":{"ws":"^8.18.3","zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0","@cashu/cashu-ts":"^3.1.1"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","@types/ws":"^8.18.1","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.5_1764156732354_0.4236095341891293","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@candypoets/lnuts","version":"0.1.6","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.1.6","maintainers":[{"name":"sotachi","email":"sotachi@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"dist":{"shasum":"5997f0ca1476e1575596951b717f505f2d13566f","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.1.6.tgz","fileCount":43,"integrity":"sha512-qJzC5o+nK2lCacHxbuxWTYqabn3vvLaRXWrYJdEp5XK7WK7cL/hz6Ku+/ISsw1QRuy7eBMgB2WtmcHtR79n8jA==","signatures":[{"sig":"MEUCIQD1hZn1970PciU7LmPCaCmvvW718Fb1hDXy9Gsnir1RuAIgUPciXFM7LtGaHanrVG5iOYf8CQi2PLQqXgWo2T/RVvE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80550},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"}},"gitHead":"2371933a1c33b54c87da8f12762534de600e5d08","scripts":{"dev":"vite dev","build":"tsc -p tsconfig.build.json --noEmitOnError false","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"sotachi","email":"sotachi@proton.me"},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"10.7.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{},"_nodeVersion":"18.20.3","dependencies":{"ws":"^8.18.3","zod":"^3.22.0","dotenv":"^16.0.0","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0","@cashu/cashu-ts":"^3.1.1"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","@types/ws":"^8.18.1","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.1.6_1764245010661_0.17827137167344653","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@candypoets/lnuts","version":"0.2.4","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.2.4","maintainers":[{"name":"sotachi","email":"sotach1@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"bin":{"lnuts":"dist/standalone.js"},"dist":{"shasum":"5a5d696429a476474f53854e25015c252480f345","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.2.4.tgz","fileCount":41,"integrity":"sha512-wSjayLSEfA+i1pNwU/FP6KHaIAKB1wQmrUB2AO83ebTw864Z4BQHmK4PfZOkLkyDAcuh7/L4JgxBcmobHHqCTA==","signatures":[{"sig":"MEUCIQD7sxnLxBaDvrMAOogPrDSSwG/llpR79rZyYJI0kAQtbQIgJ6cry7tAG9IR0bYZHgLhB3uz2UMZ3N0LdOzj9BmgUHo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@candypoets%2flnuts@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":103184},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.4.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"},"./server":{"types":"./dist/middleware.d.ts","import":"./dist/middleware.js"}},"gitHead":"9713e5a3c8a642bd95f90f5f14bda443d45828a0","scripts":{"dev":"npm run build && npm start","test":"npm run build && node --test tests/*.test.mjs","build":"npm run clean && tsc -p tsconfig.build.json --noEmitOnError false","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","start":"node dist/standalone.js","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ccc4df18-ee8a-4787-a18c-7f55aba16ea4"}},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"11.18.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ws":"^8.21.1","zod":"^3.22.0","dotenv":"^16.0.0","@scure/base":"^1.1.1","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0","@cashu/cashu-ts":"^3.1.1"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","@types/ws":"^8.18.1","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.2.4_1785250727649_0.8642478722223987","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@candypoets/lnuts","version":"0.3.0","keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","_id":"@candypoets/lnuts@0.3.0","maintainers":[{"name":"sotachi","email":"sotach1@proton.me"}],"homepage":"https://github.com/candypoets/lnuts#readme","bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"bin":{"lnuts":"dist/standalone.js"},"dist":{"shasum":"56dea392798092a5ae5881bcd6a451186b9e8279","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.3.0.tgz","fileCount":43,"integrity":"sha512-p4PLdtpcj7SCVC5Llgf8Kx26KJhUjA5bL1rQnUKgacFBfiL8U0u3IyzzYUefgEAme2JaD0IZgTJKktxYtDoFXw==","signatures":[{"sig":"MEQCIEbNzhmkPxUhND/aqdDlnXjnfSf/2m5MGp95OXXmnFpoAiB1GpARqemRyd6+wgCsFeW/0NzOBkdUawgVJNXDFv1iwQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@candypoets%2flnuts@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":122108},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.4.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"},"./server":{"types":"./dist/middleware.d.ts","import":"./dist/middleware.js"}},"gitHead":"5098a0f65c0ae623af23594bedbef7fa2d38eae9","scripts":{"dev":"npm run build && npm start","test":"npm run build && node --test tests/*.test.mjs","build":"npm run clean && tsc -p tsconfig.build.json --noEmitOnError false","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","start":"node dist/standalone.js","preview":"vite preview","examples":"echo 'See examples/ directory for route implementations'","build:vite":"vite build","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ccc4df18-ee8a-4787-a18c-7f55aba16ea4"}},"repository":{"url":"git+https://github.com/candypoets/lnuts.git","type":"git"},"_npmVersion":"11.18.0","description":"LNURL-pay to Cashu mint bridge with Nostr integration","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ws":"^8.21.1","zod":"^3.22.0","dotenv":"^16.0.0","@scure/base":"^1.1.1","nostr-tools":"^2.0.0","better-sqlite3":"^9.0.0","@cashu/cashu-ts":"^3.1.1","light-bolt11-decoder":"^3.2.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","svelte":"^4.0.0","prettier":"^3.0.0","@types/ws":"^8.18.1","typescript":"^5.0.0","@types/node":"^20.0.0","svelte-check":"^3.0.0","@sveltejs/kit":"^2.0.0","@types/better-sqlite3":"^7.6.0","@sveltejs/adapter-node":"^2.0.0","prettier-plugin-svelte":"^3.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lnuts_0.3.0_1785337012912_0.2754701974152116","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@candypoets/lnuts","version":"0.3.1","description":"LNURL-pay to Cashu mint bridge with Nostr integration","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","build":"npm run clean && tsc -p tsconfig.build.json --noEmitOnError false","test":"npm run build && node --test tests/*.test.mjs","build:vite":"vite build","dev":"npm run build && npm start","start":"node dist/standalone.js","preview":"vite preview","prepublishOnly":"npm run build","examples":"echo 'See examples/ directory for route implementations'"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./utils":{"types":"./dist/utils.d.ts","import":"./dist/utils.js"},"./server":{"types":"./dist/middleware.d.ts","import":"./dist/middleware.js"}},"bin":{"lnuts":"dist/standalone.js"},"keywords":["nostr","cashu","lightning","lnurl","ecash"],"author":{"name":"CandyPoets"},"license":"MIT","homepage":"https://github.com/candypoets/lnuts#readme","repository":{"type":"git","url":"git+https://github.com/candypoets/lnuts.git"},"bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"devDependencies":{"@sveltejs/adapter-node":"^2.0.0","@sveltejs/kit":"^2.0.0","@sveltejs/vite-plugin-svelte":"^3.0.0","@types/better-sqlite3":"^7.6.0","@types/node":"^20.0.0","@types/ws":"^8.18.1","prettier":"^3.0.0","prettier-plugin-svelte":"^3.0.0","svelte":"^4.0.0","svelte-check":"^3.0.0","typescript":"^5.0.0","vite":"^5.0.0"},"dependencies":{"@cashu/cashu-ts":"^3.7.1","@scure/base":"^1.1.1","better-sqlite3":"^9.0.0","dotenv":"^16.0.0","light-bolt11-decoder":"^3.2.0","nostr-tools":"^2.0.0","ws":"^8.21.1","zod":"^3.22.0"},"engines":{"node":">=22.4.0"},"gitHead":"a633e8c1563c51ea65a3c0884a097e9d1d880b8e","_id":"@candypoets/lnuts@0.3.1","_nodeVersion":"22.23.1","_npmVersion":"11.19.0","dist":{"integrity":"sha512-odG1wsMIBb96SlnL+So8J9a/gE0hy6dbs0mslNuLC7cezIStu/Tcn+jeao6groGJxcBEUUK3Y+zVjNsEAGX7VQ==","shasum":"09dd3e821bef3763757a56df49e5413e0b9220f3","tarball":"https://registry.npmjs.org/@candypoets/lnuts/-/lnuts-0.3.1.tgz","fileCount":43,"unpackedSize":126649,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@candypoets%2flnuts@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCcieZzV8B+XtOxiPbugqCJZBlNZYHhnX0wtAG/UX559gIgQKiMl3CHfbl+5B1vqWcqJTo+z7VXyrp6dAqxrQdlEeM="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ccc4df18-ee8a-4787-a18c-7f55aba16ea4"}},"directories":{},"maintainers":[{"name":"sotachi","email":"sotach1@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lnuts_0.3.1_1785408287793_0.30933550938272947"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-13T15:17:55.254Z","modified":"2026-07-30T10:44:48.274Z","0.1.0":"2025-11-13T15:17:55.592Z","0.1.1":"2025-11-13T15:38:29.303Z","0.1.2":"2025-11-13T15:41:53.387Z","0.1.3":"2025-11-13T16:21:40.379Z","0.1.4":"2025-11-13T16:27:53.330Z","0.1.5":"2025-11-26T11:32:12.554Z","0.1.6":"2025-11-27T12:03:30.862Z","0.2.4":"2026-07-28T14:58:47.805Z","0.3.0":"2026-07-29T14:56:53.039Z","0.3.1":"2026-07-30T10:44:47.922Z"},"bugs":{"url":"https://github.com/candypoets/lnuts/issues"},"author":{"name":"CandyPoets"},"license":"MIT","homepage":"https://github.com/candypoets/lnuts#readme","keywords":["nostr","cashu","lightning","lnurl","ecash"],"repository":{"type":"git","url":"git+https://github.com/candypoets/lnuts.git"},"description":"LNURL-pay to Cashu mint bridge with Nostr integration","maintainers":[{"name":"sotachi","email":"sotach1@proton.me"}],"readme":"# lnuts\n\n**Turn any Node server into a full LNURL-pay server with just a few configuration variables!**\n\nA Nostr-native LNURL-pay server that bridges Lightning payments to Cashu tokens.\nAnyone can claim an `npub@domain.com` address, select a mint, and retrieve the\nresulting ecash through a NIP-98-authenticated endpoint.\n\n## Features\n\n- **LNURL-pay Endpoint**: Serve `/.well-known/lnurlp/[alias]` for Lightning payments\n- **Nostr Integration**: Claim and manage handles through NIP-98 authentication\n- **NIP-57 zaps**: Optionally issue zap-committed invoices and publish zap receipts\n- **Cashu Mint Bridge**: Automatically mint Cashu tokens when payments are received\n- **Recipient-selected mints**: Each claimed address chooses its own Cashu mint\n- **Private proof retrieval**: Owners pull proofs through NIP-98 HTTP authentication\n- **Automatic Polling**: Continuously polls paid MintQuotes and stores the resulting tokens\n- **Built-in diagnostics**: Inspect configuration, claims, and LNURL-pay responses at `/lnuts`\n- **SQLite Storage**: Persistent storage for claims and payments\n\n## Architecture\n\n```\nUser → Lightning Payment → LNURL-pay → Cashu Mint → Authenticated proof API → User\n```\n\n1. Each pubkey claims one `npub@domain.com` handle through NIP-98 HTTP authentication\n2. Payments come in via LNURL-pay endpoint using an invoice from that mint\n3. The selected Cashu mint generates tokens when payment is confirmed\n4. Tokens remain on the server until the recipient requests `GET /api/proofs`\n5. A valid NIP-98 event proves ownership before any proofs are returned\n\n## Installation\n\nRequires Node.js 22.4 or newer (matching the installed `cashu-ts` runtime).\n\n```bash\nnpm install @candypoets/lnuts\n```\n\n## Configuration\n\nSet up environment variables:\n\n```env\n# Required in production\nLNUTS_DOMAIN=mydomain.com\n\n# Optional\nLNUTS_BASE_URL=https://mydomain.com\nLNUTS_DATABASE_PATH=./data/lnuts.db\nLNUTS_DEFAULT_RELAYS=wss://relay.damus.io,wss://relay.nostr.band,wss://nos.lol\n# Optional: enables NIP-57 zap receipts\nLNUTS_ZAP_NSEC=nsec1...\nLNUTS_PORT=3000\nLNUTS_DEBUG_UI=true\nLNUTS_AUTO_START=true\n```\n\n`LNUTS_BASE_URL` is especially useful locally, for example\n`http://localhost:3000`; otherwise it is derived from `LNUTS_DOMAIN`.\nIt must be the exact public HTTP(S) origin seen by clients, including the\nscheme and port when applicable. For example, use `http://befree:5173`, not\n`befree:5173`.\nThere is no server-wide default mint: every claim must include a `mint` tag.\nWhen `LNUTS_ZAP_NSEC` is configured, LNURL discovery advertises NIP-57 support\nand the corresponding public key. Keep the key stable and secret: it signs zap\nreceipts for every handle served by this deployment. Without it, normal\nLNURL-pay and proof retrieval continue to work unchanged.\n\n## Standalone server and diagnostics UI\n\nNo host framework is required:\n\n```bash\ncp .env.example .env\nnpm run build\nnpm start\n```\n\nOpen `http://localhost:3000/lnuts`. The page can:\n\n- connect to a NIP-07 browser extension or accept an npub/hex public key;\n- list names already claimed by that key;\n- show each Lightning address, LNURL-pay URL, and encoded LNURL;\n- probe an alias and display the raw LNURL-pay response;\n- show the effective non-secret server configuration.\n\nFor a local UI-only smoke test without contacting the mint, set\n`LNUTS_AUTO_START=false`. Turn it back on to exercise invoice creation,\npayment polling and minting.\n\n## Usage with SvelteKit\n\n### 1. Quick Start with Middleware\n\nThe simplest way to add lnuts to your SvelteKit app:\n\n```typescript\n// src/hooks.server.ts\nimport { createLnutsMiddleware } from \"@candypoets/lnuts/server\";\n\nexport const handle = createLnutsMiddleware();\n```\n\n### 2. Advanced: Compose with Other Middleware\n\n```typescript\n// src/hooks.server.ts\nimport { sequence } from \"@sveltejs/kit/hooks\";\nimport { withLnuts } from \"@candypoets/lnuts/server\";\n\nconst myAuthMiddleware = async ({ event, resolve }) => {\n  // Your auth logic\n  return resolve(event);\n};\n\nexport const handle = sequence(withLnuts(), myAuthMiddleware);\n```\n\n### 3. Create Required Routes\n\nLNURL-pay endpoints are automatically handled by the middleware at:\n\n- `GET /.well-known/lnurlp/[alias]` - Returns LNURL metadata\n- `GET /.well-known/lnurlp/[alias]/callback` - Generates Lightning invoice\n\nAPI endpoints for managing claims:\n\n- `POST /api/claims` - Claim, update, or change the signer's handle\n- `DELETE /api/claims/[alias]` - Delete the signer's handle with NIP-98 auth\n- `GET /api/claims/[alias]` - Get information about a specific alias\n- `GET /api/aliases?pubkey=[pubkey]` - Query the active handle for a public key\n- `GET /api/proofs?since=[timestamp]` - Retrieve the signer's proofs with NIP-98 auth\n- `GET /api/lnuts/status` - Non-secret diagnostics data when the UI is enabled\n- `GET /lnuts` - Built-in diagnostics UI when enabled\n\nAll routes are automatically handled by the middleware - no additional route files needed!\n\n## Usage with Node.js / Express\n\n### Express Server Integration\n\n```javascript\nimport express from \"express\";\nimport { createExpressMiddleware } from \"@candypoets/lnuts/server\";\n\nconst app = express();\nconst port = 3000;\n\n// Add body parser for JSON\napp.use(express.json());\n\n// Apply lnuts middleware - it handles all routes automatically\napp.use(\n  createExpressMiddleware({\n    // Optional: override environment variables\n    domain: \"mydomain.com\",\n  }),\n);\n\n// Your other routes\napp.get(\"/\", (req, res) => {\n  res.send(\"Hello World!\");\n});\n\napp.listen(port, () => {\n  console.log(`Server running at http://localhost:${port}`);\n});\n```\n\nAll routes are automatically handled by the middleware - no additional configuration needed!\n\n## Handler Class API\n\n### Constructor Options\n\n```typescript\ninterface LnutsOptions {\n  dbPath?: string; // SQLite file or containing directory\n  nostrRelays?: string[]; // Nostr relays to connect to\n  zapSecretKey?: string; // Optional nsec/hex signer for NIP-57 receipts\n  domain?: string; // Domain name for LNURL metadata\n  baseUrl?: string; // Public origin, including scheme\n  debugUi?: boolean; // Serve /lnuts and its status endpoint\n  autoStart?: boolean; // Whether to auto-start services (default: true)\n}\n```\n\n### Creating an Instance\n\n```typescript\nimport { LnutsHandler } from \"@candypoets/lnuts\";\n\n// Using environment variables\nconst lnuts = new LnutsHandler();\n\n// With custom options\nconst lnuts = new LnutsHandler({\n  domain: \"mydomain.com\",\n  zapSecretKey: process.env.LNUTS_ZAP_NSEC,\n  dbPath: \"./data/lnuts.db\",\n  autoStart: false, // Manual service start\n});\n\n// Manually start services if autoStart is false\nawait lnuts.start();\n```\n\n### Properties\n\n- `db`: Direct access to the SQLite database instance\n- `options`: Configuration options used by the handler\n- `pool`: SimplePool instance for Nostr operations\n- `handle`: SvelteKit-compatible handle function\n\n### Methods\n\n- `start()`: Start payment polling\n- `stop()`: Stop all services\n- `getWallet(mintUrl)`: Get the cached Cashu wallet for a recipient-selected mint\n- `pollPayments()`: Manually trigger payment polling\n- `clone(options)`: Create a new handler instance with modified options\n\n## Database Schema\n\n### Claims Table\n\n- `alias`: The claimed username\n- `pubkey`: Unique Nostr pubkey of the claimer; one active handle per pubkey\n- `p2pk_pubkey`: Optional P2PK pubkey for token locking\n- `relay`: Optional retained recipient metadata\n- `claimed_at`: Timestamp of claim\n\n### Payments Table\n\n- `id`: Unique payment ID\n- `alias`: Associated username\n- `quote_id`: Cashu mint quote ID\n- `mint_quote_expiry`: Mint-provided Unix timestamp when the invoice expires\n- `amount`: Payment amount in sats\n- `invoice`: Lightning invoice\n- `comment`: Optional payment comment\n- `recipient_pubkey`: Snapshot of the owner entitled to retrieve the proofs\n- `locking_pubkey`: Snapshot of the P2PK key used when minting the proofs\n- `mint_preview_json`: Temporary replay-safe mint state, cleared after proofs are stored\n- `status`: pending | minted | expired | failed\n- `created_at`: Payment creation timestamp\n- `updated_at`: Last update timestamp\n\n## Automatic Services\n\n### Payment Polling\n\nThe handler automatically polls the Cashu mint for paid invoices:\n\n- Default interval: 1 second\n- Automatically mints tokens when payment is confirmed\n- Polls each quote until the mint-provided expiry and performs a final check\n- Keeps temporary mint and network failures pending for retry\n- Persists the prepared mint outputs before issuance so an `ISSUED` quote can\n  be recovered after a lost response or process restart\n- Stores tokens for authenticated retrieval\n\nReplay recovery uses the mint's NUT-19 response cache and must occur within the\nretention window advertised by that mint. A legacy `ISSUED` payment created\nwithout prepared mint state is marked failed explicitly because its randomized\nproof secrets cannot be reconstructed.\n\n## API Endpoints\n\n### Claim or Change Handle\n\n`POST /api/claims`\n\nSend the handle settings as JSON and authenticate the exact request with a\nkind `27235` NIP-98 event. The event must include the SHA-256 hash of the exact\nrequest body in its `payload` tag.\n\n```json\n{\n  \"alias\": \"alice\",\n  \"mintUrl\": \"https://mint.example.com\",\n  \"p2pkPubkey\": \"02abc...\"\n}\n```\n\nA pubkey can have only one active handle. A newer authenticated request with a\ndifferent alias changes it; submitting the same alias updates its mint and P2PK\nsettings. The target alias must not belong to another pubkey.\n\n### Delete Handle\n\n`DELETE /api/claims/[alias]`\n\nSign a NIP-98 event for the exact `DELETE` URL and send it in the\n`Authorization` header. Deleting a handle does not delete or transfer historical\nproofs:\n\n```javascript\nconst url = \"https://mydomain.com/api/claims/alice\";\nconst authEvent = finalizeEvent(\n  {\n    kind: 27235,\n    pubkey,\n    created_at: Math.floor(Date.now() / 1000),\n    tags: [\n      [\"u\", url],\n      [\"method\", \"DELETE\"],\n    ],\n    content: \"\",\n  },\n  secretKey,\n);\n\nawait fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    Authorization: `Nostr ${btoa(JSON.stringify(authEvent))}`,\n  },\n});\n```\n\nAfter deletion, the pubkey can claim another handle using a newer NIP-98\nrequest. Old authenticated requests cannot be replayed to restore a deleted\nhandle.\n\n### Get Alias Information\n\n`GET /api/claims/[alias]`\n\nGet information about a specific claimed alias:\n\n```bash\ncurl http://localhost:3000/api/claims/alice\n```\n\nResponse:\n\n```json\n{\n  \"status\": \"success\",\n  \"data\": {\n    \"alias\": \"alice\",\n    \"pubkey\": \"user_pubkey\",\n    \"relay\": \"wss://relay.damus.io\",\n    \"p2pk_pubkey\": \"02abc...\",\n    \"claimed_at\": \"2024-01-01T00:00:00Z\"\n  }\n}\n```\n\n### Query Handle by Public Key\n\n`GET /api/aliases?pubkey=[pubkey]`\n\nGet the active handle owned by a public key. The response remains an array for\nAPI compatibility but contains at most one entry:\n\n```bash\ncurl http://localhost:3000/api/aliases?pubkey=02abc123...\n```\n\nResponse:\n\n```json\n{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"alias\": \"alice\",\n      \"relay\": \"wss://relay.damus.io\",\n      \"p2pk_pubkey\": \"02abc...\",\n      \"claimed_at\": \"2024-01-01T00:00:00Z\"\n    },\n    {\n      \"alias\": \"bob\",\n      \"relay\": \"wss://nos.lol\",\n      \"p2pk_pubkey\": null,\n      \"claimed_at\": \"2024-01-02T00:00:00Z\"\n    }\n  ]\n}\n```\n\n### Retrieve proofs\n\n`GET /api/proofs?since=[timestamp]`\n\nThe request must carry a valid [NIP-98](https://nips.nostr.com/98)\n`Authorization` header. The signed event must be kind `27235`, no more than 60\nseconds old, and contain the exact public URL—including the `since` query\nparameter—and HTTP method:\n\n```javascript\nimport { finalizeEvent } from \"nostr-tools\";\n\nconst since = localStorage.getItem(\"lnuts-received-through\") || \"0\";\nconst url = `https://mydomain.com/api/proofs?since=${since}`;\nconst authEvent = finalizeEvent(\n  {\n    kind: 27235,\n    pubkey,\n    created_at: Math.floor(Date.now() / 1000),\n    tags: [\n      [\"u\", url],\n      [\"method\", \"GET\"],\n    ],\n    content: \"\",\n  },\n  secretKey,\n);\n\nconst response = await fetch(url, {\n  headers: {\n    Authorization: `Nostr ${btoa(JSON.stringify(authEvent))}`,\n  },\n});\nconst { data } = await response.json();\n\n// Save this only after importing every returned token successfully.\nlocalStorage.setItem(\"lnuts-received-through\", String(data.receivedThrough));\n```\n\n`since` is a Unix timestamp in milliseconds meaning “I have received everything\nthrough this time.” Omit it on the first request. The response contains\n`data.proofs` and `data.receivedThrough`; use `receivedThrough` as the next\nrequest's `since` value.\n\nEach proof entry contains `paymentId`, `alias`, `amount` in millisatoshis,\n`mintUrl`, `mintedAt`, and the Cashu `token`. Timestamp boundaries are inclusive,\nso a payment at the exact boundary can appear again. Clients must deduplicate by\n`paymentId`; this intentional overlap prevents payments from being missed.\n\n## Client Utilities\n\nThe library provides utility functions to help clients interact with the lnuts API:\n\nThe claim utilities construct the JSON body and its matching NIP-98 event:\n\n```typescript\nimport {\n  constructClaimRequest,\n  constructClaimAuthorizationEvent,\n  postClaimRequest,\n} from \"@candypoets/lnuts/utils\";\nimport { generateSecretKey, getPublicKey, finalizeEvent } from \"nostr-tools\";\n\nconst secretKey = generateSecretKey();\nconst pubkey = getPublicKey(secretKey);\nconst url = \"https://mydomain.com/api/claims\";\nconst request = constructClaimRequest(\n  \"alice\",\n  \"https://mint.example.com\",\n  \"wss://relay.damus.io\",\n  \"02abc123...\",\n);\nconst unsignedAuth = await constructClaimAuthorizationEvent(\n  request,\n  pubkey,\n  url,\n);\nconst signedAuth = finalizeEvent(unsignedAuth, secretKey);\nconst result = await postClaimRequest(request, signedAuth, url);\n\nif (result.status === \"success\") {\n  console.log(`Successfully claimed alice@mydomain.com!`);\n}\n```\n\n## Nostr authentication\n\nClaims, handle deletion, and proof retrieval all use short-lived kind `27235`\nNIP-98 events. Claim requests additionally require a `payload` tag containing\nthe SHA-256 hash of the exact JSON body. No custom event kinds are used, and\nproofs are never published to Nostr relays.\n\n## NIP-57 zaps\n\nZap support is optional. Set `LNUTS_ZAP_NSEC` (or pass `zapSecretKey`) to make\nLNURL discovery return `allowsNostr: true` and `nostrPubkey`. The callback then:\n\n1. validates the signed kind `9734` request, recipient, amount, and relay list;\n2. asks the recipient-selected Cashu mint for an invoice whose description is\n   the exact zap request;\n3. stores the zap request with the payment;\n4. mints the recipient's P2PK-locked proofs after payment; and\n5. signs and publishes a kind `9735` receipt to the requested relays.\n\nThe selected mint must advertise NUT-23 Bolt11-description support. lnuts\nverifies that the returned invoice has the requested amount and commits to the\nexact zap request, either through its description hash or exact description.\nSome strict NIP-57 clients may require the description-hash form, while current\nNUT-23 mints commonly return the exact-description form. Signed receipts are\nstored before relay delivery, and failed relay publication is retried without\nminting the proofs again. The mint transaction itself is prepared and stored\nbefore issuance, so a lost mint response can be retried with the exact same\nblinded outputs when the mint supports NUT-19.\n\nZap polling stops at the earlier of the mint quote expiry and the BOLT11\ninvoice expiry. If the mint returns a non-expiring quote, lnuts uses the\ninvoice's expiry (BOLT11 defaults this to one hour).\n\n## Security Considerations\n\n### Database Security\n\n- Default location is configurable via `dbPath`\n- Ensure proper file permissions\n- Regular backups recommended\n- Treat the database as secret: pending mint previews and minted Cashu proofs\n  contain bearer-value material\n- Protect `LNUTS_ZAP_NSEC`; changing it invalidates receipts for outstanding zap invoices\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run the self-contained server with environment variables\nLNUTS_DOMAIN=localhost:3000 \\\nLNUTS_BASE_URL=http://localhost:3000 \\\nnpm start\n```\n\n## Testing\n\n```bash\n# Test LNURL endpoint\ncurl http://localhost:3000/.well-known/lnurlp/alice\n\n# Test callback\ncurl \"http://localhost:3000/.well-known/lnurlp/alice/callback?amount=1000000\"\n\n# Submit a claim using a NIP-98 Authorization header\ncurl -X POST http://localhost:3000/api/claims \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Nostr <base64-kind-27235-event>\" \\\n  -d '{\"alias\":\"alice\",\"mintUrl\":\"https://testnut.cashu.space\"}'\n\n# Get alias information\ncurl http://localhost:3000/api/claims/alice\n\n# Query aliases by public key\ncurl http://localhost:3000/api/aliases?pubkey=02abc...\n\n# Test the diagnostics status\ncurl http://localhost:3000/api/lnuts/status\n```\n\n## Examples\n\nThe package can run standalone or as SvelteKit/Express middleware; no generated\nroute files are required.\n\n## Troubleshooting\n\n### Services Not Starting\n\n- Verify the mint selected in the recipient's claim is accessible\n- Check database file permissions\n\n### Proofs Not Available\n\n- Verify the payment has reached the `minted` state\n- Verify the NIP-98 event URL exactly matches the public `/api/proofs` URL\n- Verify the event is signed by the pubkey that owned the alias when the invoice was created\n\n### LNURL Not Working\n\n- Ensure `.well-known/lnurlp` routes are properly configured\n- Verify domain configuration matches actual hostname\n- Check that aliases exist in claims table\n\n## License\n\nMIT\n","readmeFilename":"README.md"}