diff --git a/.dockerignore b/.dockerignore index 135641f4..7fab354e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,21 +2,3 @@ .github build node_modules - -# Runtime state files (should not be baked into image) -*.sqlite -*.sqlite-journal -*.sqlite-wal -*.sqlite-shm -*.db -admin.connect -admin.enroll -admin.npub -app.nprofile -.jwt_secret - -# Runtime data directories -metric_cache/ -metric_events/ -bundler_events/ -logs/ diff --git a/Dockerfile b/Dockerfile index 1d3df65b..6001419a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20 +FROM node:18 WORKDIR /app diff --git a/package-lock.json b/package-lock.json index 47556424..701b7072 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,6 @@ "zip-a-folder": "^3.1.9" }, "devDependencies": { - "@types/better-sqlite3": "^7.6.13", "@types/chai": "^4.3.4", "@types/chai-string": "^1.4.5", "@types/cors": "^2.8.17", @@ -83,19 +82,19 @@ "license": "MIT" }, "node_modules/@bufbuild/protobuf": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.11.0.tgz", - "integrity": "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.7.0.tgz", + "integrity": "sha512-qn6tAIZEw5i/wiESBF4nQxZkl86aY4KoO0IkUa2Lh+rya64oTOdJQFlZuMwI1Qz9VBJQrQC4QlSA2DNek5gCOA==", "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@bufbuild/protoplugin": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-2.11.0.tgz", - "integrity": "sha512-lyZVNFUHArIOt4W0+dwYBe5GBwbKzbOy8ObaloEqsw9Mmiwv2O48TwddDoHN4itylC+BaEGqFdI1W8WQt2vWJQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-2.7.0.tgz", + "integrity": "sha512-yUdg8hXzFGR6K8ren7aXly2hT9BxClId814VB142YeZPatY0wqD3c0D8KfIz5nIeMdoPt0/Pm/RycFJCNGMD6w==", "license": "Apache-2.0", "dependencies": { - "@bufbuild/protobuf": "2.11.0", - "@typescript/vfs": "^1.6.2", + "@bufbuild/protobuf": "2.7.0", + "@typescript/vfs": "^1.5.2", "typescript": "5.4.5" } }, @@ -135,13 +134,21 @@ "node": ">=12" } }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/@grpc/grpc-js": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", - "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", + "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", "license": "Apache-2.0", "dependencies": { - "@grpc/proto-loader": "^0.8.0", + "@grpc/proto-loader": "^0.7.13", "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { @@ -149,14 +156,14 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.5.3", + "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { @@ -166,25 +173,121 @@ "node": ">=6" } }, - "node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "license": "BlueOak-1.0.0", + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", "engines": { - "node": ">=18" + "node": "20 || >=22" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", "dependencies": { - "minipass": "^7.0.4" + "@isaacs/balanced-match": "^4.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@js-sdsl/ordered-map": { @@ -198,30 +301,29 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.3.tgz", - "integrity": "sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", "license": "BSD-3-Clause", "dependencies": { - "consola": "^3.2.3", "detect-libc": "^2.0.0", - "https-proxy-agent": "^7.0.5", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", "node-fetch": "^2.6.7", - "nopt": "^8.0.0", - "semver": "^7.5.3", - "tar": "^7.4.0" + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" }, "bin": { "node-pre-gyp": "bin/node-pre-gyp" - }, - "engines": { - "node": ">=18" } }, "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -231,39 +333,33 @@ } }, "node_modules/@noble/ciphers": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.1.1.tgz", - "integrity": "sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", + "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==", "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/curves": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", - "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "license": "MIT", "dependencies": { - "@noble/hashes": "2.0.1" - }, - "engines": { - "node": ">= 20.19.0" + "@noble/hashes": "1.3.2" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", "license": "MIT", "engines": { - "node": ">= 20.19.0" + "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -316,6 +412,48 @@ "node": ">= 8" } }, + "node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@openzeppelin/contracts": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.4.0.tgz", @@ -474,121 +612,6 @@ } }, "node_modules/@scure/bip32": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-2.0.1.tgz", - "integrity": "sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA==", - "license": "MIT", - "dependencies": { - "@noble/curves": "2.0.1", - "@noble/hashes": "2.0.1", - "@scure/base": "2.0.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@scure/base": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", - "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-2.0.1.tgz", - "integrity": "sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "2.0.1", - "@scure/base": "2.0.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39/node_modules/@scure/base": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", - "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@shocknet/clink-sdk": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@shocknet/clink-sdk/-/clink-sdk-1.5.4.tgz", - "integrity": "sha512-YrKR7oFjzUmBhm4p8pT6mP3YC7UdWbIlh5PMXHSwSLfJhL8Ddx91NLIfOHUTcQa1cDf27uvillMFXYrVUMCRuQ==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "^1.8.0", - "@scure/base": "^1.2.5", - "nostr-tools": "2.15.1", - "rimraf": "^6.0.1", - "typescript": "^5.8.3" - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/@noble/ciphers": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", - "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip32": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", @@ -602,7 +625,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip32/node_modules/@noble/curves": { + "node_modules/@scure/bip32/node_modules/@noble/curves": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", @@ -614,7 +637,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip32/node_modules/@noble/curves/node_modules/@noble/hashes": { + "node_modules/@scure/bip32/node_modules/@noble/curves/node_modules/@noble/hashes": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", @@ -626,7 +649,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip32/node_modules/@noble/hashes": { + "node_modules/@scure/bip32/node_modules/@noble/hashes": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", @@ -638,7 +661,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip32/node_modules/@scure/base": { + "node_modules/@scure/bip32/node_modules/@scure/base": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", @@ -647,7 +670,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip39": { + "node_modules/@scure/bip39": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", @@ -660,7 +683,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip39/node_modules/@noble/hashes": { + "node_modules/@scure/bip39/node_modules/@noble/hashes": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", @@ -672,7 +695,7 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/@scure/bip39/node_modules/@scure/base": { + "node_modules/@scure/bip39/node_modules/@scure/base": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", @@ -681,40 +704,35 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@shocknet/clink-sdk/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "node_modules/@shocknet/clink-sdk": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@shocknet/clink-sdk/-/clink-sdk-1.4.0.tgz", + "integrity": "sha512-J0PWE8CVRJrFF1Zi/UhChhvOrlmDj7LRJTpR6rbHlFPmjC5TGIW6891tVWWv+JmUR0jzez9QHFrHnc8DgIJYCQ==", "license": "MIT", "dependencies": { - "jackspeak": "^4.2.3" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" + "@noble/hashes": "^1.8.0", + "@scure/base": "^1.2.5", + "nostr-tools": "^2.13.0", + "rimraf": "^6.0.1", + "typescript": "^5.8.3" } }, "node_modules/@shocknet/clink-sdk/node_modules/glob": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", - "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", - "license": "BlueOak-1.0.0", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "license": "ISC", "dependencies": { - "minimatch": "^10.2.0", + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, "engines": { "node": "20 || >=22" }, @@ -723,12 +741,12 @@ } }, "node_modules/@shocknet/clink-sdk/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", - "license": "BlueOak-1.0.0", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { "node": "20 || >=22" @@ -737,61 +755,23 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@shocknet/clink-sdk/node_modules/nostr-tools": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.15.1.tgz", - "integrity": "sha512-LpetHDR9ltnkpJDkva/SONgyKBbsoV+5yLB8DWc0/U3lCWGtoWJw6Nbc2vR2Ai67RIQYrBQeZLyMlhwVZRK/9A==", - "license": "Unlicense", - "dependencies": { - "@noble/ciphers": "^0.5.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.1", - "@scure/base": "1.1.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1", - "nostr-wasm": "0.1.0" - }, - "peerDependencies": { - "typescript": ">=5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@shocknet/clink-sdk/node_modules/nostr-tools/node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "license": "MIT", + "node_modules/@shocknet/clink-sdk/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@shocknet/clink-sdk/node_modules/nostr-tools/node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT" - }, "node_modules/@shocknet/clink-sdk/node_modules/rimraf": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", - "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", - "license": "BlueOak-1.0.0", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "license": "ISC", "dependencies": { - "glob": "^13.0.0", - "package-json-from-dist": "^1.0.1" + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" }, "bin": { "rimraf": "dist/esm/bin.mjs" @@ -804,9 +784,9 @@ } }, "node_modules/@shocknet/clink-sdk/node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -864,10 +844,21 @@ "@stablelib/wipe": "^1.0.1" } }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "devOptional": true, "license": "MIT" }, @@ -892,16 +883,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/@types/better-sqlite3": { - "version": "7.6.13", - "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", - "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -967,21 +948,21 @@ "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", - "@types/serve-static": "^1" + "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.8", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", - "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -1008,9 +989,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", "dev": true, "license": "MIT" }, @@ -1067,44 +1048,35 @@ "license": "MIT" }, "node_modules/@types/secp256k1": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.7.tgz", - "integrity": "sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@types/send": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -1133,9 +1105,9 @@ } }, "node_modules/@typescript/vfs": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.2.tgz", - "integrity": "sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.1.tgz", + "integrity": "sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==", "license": "MIT", "dependencies": { "debug": "^4.1.1" @@ -1182,13 +1154,10 @@ } }, "node_modules/abbrev": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", - "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", @@ -1254,12 +1223,44 @@ } }, "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", + "dependencies": { + "debug": "4" + }, "engines": { - "node": ">= 14" + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/ajv": { @@ -1303,9 +1304,9 @@ } }, "node_modules/ansis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", - "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", "license": "ISC", "engines": { "node": ">=14" @@ -1334,6 +1335,12 @@ "node": ">= 6.0.0" } }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", + "license": "ISC" + }, "node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", @@ -1370,47 +1377,6 @@ "node": ">= 14" } }, - "node_modules/archiver-utils/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/archiver-utils/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/archiver-utils/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/archiver-utils/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -1444,17 +1410,10 @@ "ieee754": "^1.2.1" } }, - "node_modules/archiver-utils/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, "node_modules/archiver-utils/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -1507,6 +1466,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/archiver-utils/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/archiver-utils/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -1548,55 +1516,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/archiver-utils/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/archiver-utils/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/archiver-utils/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/archiver/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -1657,6 +1576,43 @@ "streamx": "^2.15.0" } }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1740,29 +1696,21 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "node_modules/b4a": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.4.tgz", - "integrity": "sha512-u20zJLDaSWpxaZ+zaAkEIB2dZZ1o+DF4T/MRbmsvGp9nletHOyiai19OzX1fF8xUBYsO1bPXxODvcd0978pnug==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "license": "Apache-2.0" }, "node_modules/balanced-match": { "version": "1.0.2", @@ -1771,23 +1719,16 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.1.tgz", + "integrity": "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==", "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } + "optional": true }, "node_modules/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", + "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", "license": "MIT" }, "node_modules/base64-js": { @@ -1826,9 +1767,9 @@ "license": "MIT" }, "node_modules/better-sqlite3": { - "version": "12.6.2", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.2.tgz", - "integrity": "sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.2.0.tgz", + "integrity": "sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -1836,7 +1777,7 @@ "prebuild-install": "^7.1.1" }, "engines": { - "node": "20.x || 22.x || 23.x || 24.x || 25.x" + "node": "20.x || 22.x || 23.x || 24.x" } }, "node_modules/bignumber.js": { @@ -1914,10 +1855,13 @@ } }, "node_modules/bip66": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-2.0.0.tgz", - "integrity": "sha512-kBG+hSpgvZBrkIm9dt5T1Hd/7xGCPEX2npoxAWZfsK1FvjgaxySEh2WizjyIstWXriKo9K9uJ4u0OnsyLDUPXQ==", - "license": "MIT" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } }, "node_modules/bitcoin-core": { "version": "4.2.0", @@ -1954,6 +1898,40 @@ "node": ">=8.0.0" } }, + "node_modules/bitcoinjs-lib/node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, + "node_modules/bitcoinjs-lib/node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bitcoinjs-lib/node_modules/bs58check": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", + "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^5.0.0" + } + }, + "node_modules/bitcoinjs-lib/node_modules/varuint-bitcoin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", + "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, "node_modules/bitset": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/bitset/-/bitset-5.2.3.tgz", @@ -1993,6 +1971,15 @@ "node": ">= 6" } }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/blech32": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/blech32/-/blech32-1.1.2.tgz", @@ -2014,29 +2001,29 @@ "peer": true }, "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { - "bytes": "~3.1.2", + "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", "type-is": "~1.6.18", - "unpipe": "~1.0.0" + "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8", @@ -2059,19 +2046,19 @@ "license": "MIT" }, "node_modules/boltz-core": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/boltz-core/-/boltz-core-3.1.2.tgz", - "integrity": "sha512-FxDcOuANAvRKI/1IHKySjfBXDcXCXR3ImM9ndjYGN5km8lXGJWwYEt85KtTBNFTPSdBcNnkOPQ1nXJK6R62gCg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/boltz-core/-/boltz-core-3.0.0.tgz", + "integrity": "sha512-L0jzUnTIb/vir9k6yVlCkV8I29ZeBK7LWq3rrDcp/KP7bB0VvKR5JTceua8g2KBCBM5HOMVDEuPW3c9/82/Nmg==", "license": "AGPL-3.0", "dependencies": { "@boltz/bitcoin-ops": "^2.0.0", - "@openzeppelin/contracts": "^5.4.0", + "@openzeppelin/contracts": "^5.2.0", "@vulpemventures/secp256k1-zkp": "^3.2.1", "bip32": "^4.0.0", "bip65": "^1.0.3", "bip66": "^2.0.0", "bitcoinjs-lib": "^6.1.7", - "bn.js": "^5.2.2", + "bn.js": "^5.2.1", "ecpair": "^3.0.0", "varuint-bitcoin": "^2.0.0" }, @@ -2082,14 +2069,17 @@ "liquidjs-lib": "^6.0.2-liquid.37" } }, - "node_modules/boltz-core/node_modules/varuint-bitcoin": { + "node_modules/boltz-core/node_modules/bip66": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-2.0.0.tgz", - "integrity": "sha512-6QZbU/rHO2ZQYpWFDALCDSRsXbAs1VOEmXAxtbtjLtKuMJ/FQ8YbhfxlaiKv5nklci0M6lZtlZyxo9Q+qNnyog==", - "license": "MIT", - "dependencies": { - "uint8array-tools": "^0.0.8" - } + "resolved": "https://registry.npmjs.org/bip66/-/bip66-2.0.0.tgz", + "integrity": "sha512-kBG+hSpgvZBrkIm9dt5T1Hd/7xGCPEX2npoxAWZfsK1FvjgaxySEh2WizjyIstWXriKo9K9uJ4u0OnsyLDUPXQ==", + "license": "MIT" + }, + "node_modules/boltz-core/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.12", @@ -2135,22 +2125,22 @@ } }, "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", "license": "MIT", "dependencies": { - "base-x": "^4.0.0" + "base-x": "^5.0.0" } }, "node_modules/bs58check": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", - "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-4.0.0.tgz", + "integrity": "sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==", "license": "MIT", "dependencies": { "@noble/hashes": "^1.2.0", - "bs58": "^5.0.0" + "bs58": "^6.0.0" } }, "node_modules/buffer": { @@ -2199,6 +2189,21 @@ "license": "MIT", "optional": true }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", @@ -2226,6 +2231,65 @@ "node": ">= 0.8" } }, + "node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2356,28 +2420,38 @@ } }, "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", "engines": { - "node": ">=18" + "node": ">=10" } }, "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "license": "MIT", "dependencies": { "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" + "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.10" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2410,6 +2484,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2493,14 +2576,11 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -2524,18 +2604,18 @@ } }, "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, "node_modules/copyfiles": { @@ -2602,9 +2682,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -2612,10 +2692,6 @@ }, "engines": { "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" } }, "node_modules/crc-32": { @@ -2786,15 +2862,15 @@ } }, "node_modules/dayjs": { - "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", "license": "MIT" }, "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2852,9 +2928,9 @@ } }, "node_modules/dedent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", - "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", + "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -2912,6 +2988,12 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2932,18 +3014,18 @@ } }, "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "license": "Apache-2.0", "engines": { "node": ">=8" } }, "node_modules/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "devOptional": true, "license": "BSD-3-Clause", "engines": { @@ -3088,23 +3170,6 @@ "secp256k1": "3.7.1" } }, - "node_modules/eccrypto/node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/eccrypto/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT", - "optional": true - }, "node_modules/eccrypto/node_modules/nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -3142,42 +3207,40 @@ } }, "node_modules/ecpair": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ecpair/-/ecpair-3.0.1.tgz", - "integrity": "sha512-uz8wMFvtdr58TLrXnAesBsoMEyY8UudLOfApcyg40XfZjP+gt1xO4cuZSIkZ8hTMTQ8+ETgt7xSIV4eM7M6VNw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ecpair/-/ecpair-3.0.0.tgz", + "integrity": "sha512-kf4JxjsRQoD4EBzpYjGAcR0t9i/4oAeRPtyCpKvSwyotgkc6oA4E4M0/e+kep7cXe+mgxAvoeh/jdgH9h5+Wxw==", "license": "MIT", "dependencies": { "uint8array-tools": "^0.0.8", - "valibot": "^1.2.0", + "valibot": "^0.37.0", "wif": "^5.0.0" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/ecpair/node_modules/base-x": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", - "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", - "license": "MIT" - }, - "node_modules/ecpair/node_modules/bs58": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", - "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "node_modules/ecpair/node_modules/uint8array-tools": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.8.tgz", + "integrity": "sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==", "license": "MIT", - "dependencies": { - "base-x": "^5.0.0" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/ecpair/node_modules/bs58check": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-4.0.0.tgz", - "integrity": "sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==", + "node_modules/ecpair/node_modules/valibot": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.37.0.tgz", + "integrity": "sha512-FQz52I8RXgFgOHym3XHYSREbNtkgSjF9prvMFH1nBsRyfL6SfCzoT1GuSDTlbsuPubM7/6Kbw0ZMQb8A+V+VsQ==", "license": "MIT", - "dependencies": { - "@noble/hashes": "^1.2.0", - "bs58": "^6.0.0" + "peerDependencies": { + "typescript": ">=5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/ecpair/node_modules/wif": { @@ -3210,12 +3273,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3231,6 +3288,31 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -3240,6 +3322,25 @@ "once": "^1.4.0" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3333,15 +3434,6 @@ "node": ">=0.8.x" } }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.7.0" - } - }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -3363,39 +3455,39 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "~2.4.1", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", - "statuses": "~2.0.1", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -3473,9 +3565,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -3500,17 +3592,17 @@ } }, "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", - "on-finished": "~2.4.1", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~2.0.2", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -3583,6 +3675,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3593,9 +3697,9 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -3632,6 +3736,30 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3662,6 +3790,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3736,7 +3885,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "deprecated": "Glob versions prior to v9 are no longer supported", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -3803,12 +3952,12 @@ "license": "ISC" }, "node_modules/grpc-tools": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.13.1.tgz", - "integrity": "sha512-0sttMUxThNIkCTJq5qI0xXMz5zWqV2u3yG1kR3Sj9OokGIoyRBFjoInK9NyW7x5fH7knj48Roh1gq5xbl0VoDQ==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.13.0.tgz", + "integrity": "sha512-7CbkJ1yWPfX0nHjbYG58BQThNhbICXBZynzCUxCb3LzX5X9B3hQbRY2STiRgIEiLILlK9fgl0z0QVGwPCdXf5g==", "hasInstallScript": true, "dependencies": { - "@mapbox/node-pre-gyp": "^2.0.0" + "@mapbox/node-pre-gyp": "^1.0.5" }, "bin": { "grpc_tools_node_protoc": "bin/protoc.js", @@ -3887,19 +4036,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" + }, "node_modules/hash-base": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "license": "MIT", "dependencies": { "inherits": "^2.0.4", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.1" + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" }, "engines": { - "node": ">= 0.8" + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/hash.js": { @@ -3935,24 +4112,44 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "engines": { + "node": ">= 6" } }, "node_modules/http-signature": { @@ -3971,16 +4168,27 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "^2.0.0" } }, "node_modules/iconv-lite": { @@ -4031,6 +4239,36 @@ "dev": true, "license": "ISC" }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "license": "ISC", + "optional": true, + "peer": true + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4054,6 +4292,17 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4118,6 +4367,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4161,9 +4418,9 @@ "license": "MIT" }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "license": "MIT" }, "node_modules/isexe": { @@ -4179,12 +4436,12 @@ "license": "MIT" }, "node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^9.0.0" + "@isaacs/cliui": "^8.0.2" }, "engines": { "node": "20 || >=22" @@ -4227,12 +4484,12 @@ "license": "ISC" }, "node_modules/jsonwebtoken": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", - "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "license": "MIT", "dependencies": { - "jws": "^4.0.1", + "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -4249,9 +4506,9 @@ } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4276,9 +4533,9 @@ } }, "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -4287,12 +4544,12 @@ } }, "node_modules/jws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "license": "MIT", "dependencies": { - "jwa": "^2.0.1", + "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, @@ -4308,6 +4565,42 @@ "node": ">= 0.6.3" } }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/light-bolt11-decoder": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/light-bolt11-decoder/-/light-bolt11-decoder-3.2.0.tgz", @@ -4364,16 +4657,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/liquidjs-lib/node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", - "license": "MIT", - "peer": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/liquidjs-lib/node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -4411,10 +4694,20 @@ "node": ">=8.0.0" } }, + "node_modules/liquidjs-lib/node_modules/varuint-bitcoin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", + "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.camelcase": { @@ -4481,14 +4774,38 @@ } }, "node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", - "license": "BlueOak-1.0.0", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "license": "ISC", "engines": { "node": "20 || >=22" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -4496,6 +4813,63 @@ "devOptional": true, "license": "ISC" }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -4644,24 +5018,182 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "license": "ISC", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "license": "MIT", "dependencies": { - "minipass": "^7.1.2" + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/mkdirp": { @@ -4717,7 +5249,7 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "deprecated": "Glob versions prior to v9 are no longer supported", "license": "ISC", "optional": true, "dependencies": { @@ -4759,9 +5291,9 @@ } }, "node_modules/nan": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz", - "integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "license": "MIT", "optional": true }, @@ -4791,9 +5323,9 @@ } }, "node_modules/node-abi": { - "version": "3.87.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", - "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -4803,9 +5335,9 @@ } }, "node_modules/node-abi/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4840,6 +5372,32 @@ } } }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -4851,6 +5409,103 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -4900,43 +5555,19 @@ "readable-stream": "~1.0.31" } }, - "node_modules/noms/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/noms/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/noms/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "license": "MIT" - }, "node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "license": "ISC", "dependencies": { - "abbrev": "^3.0.0" + "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=6" } }, "node_modules/normalize-path": { @@ -4949,17 +5580,17 @@ } }, "node_modules/nostr-tools": { - "version": "2.23.1", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.23.1.tgz", - "integrity": "sha512-Q5SJ1omrseBFXtLwqDhufpFLA6vX3rS/IuBCc974qaYX6YKGwEPxa/ZsyxruUOr+b+5EpWL2hFmCB5AueYrfBw==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.16.2.tgz", + "integrity": "sha512-ZxH9EbSt5ypURZj2TGNJxZd0Omb5ag5KZSu8IyJMCdLyg2KKz+2GA0sP/cSawCQEkyviIN4eRT4G2gB/t9lMRw==", "license": "Unlicense", "dependencies": { - "@noble/ciphers": "2.1.1", - "@noble/curves": "2.0.1", - "@noble/hashes": "2.0.1", - "@scure/base": "2.0.0", - "@scure/bip32": "2.0.1", - "@scure/bip39": "2.0.1", + "@noble/ciphers": "^0.5.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1", "nostr-wasm": "0.1.0" }, "peerDependencies": { @@ -4972,25 +5603,28 @@ } }, "node_modules/nostr-tools/node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", "license": "MIT", "engines": { - "node": ">= 20.19.0" + "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/nostr-tools/node_modules/@scure/base": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", - "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" }, "node_modules/nostr-wasm": { "version": "0.1.0", @@ -4998,6 +5632,19 @@ "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==", "license": "MIT" }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -5049,6 +5696,23 @@ "wrappy": "1" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -5083,9 +5747,9 @@ } }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", @@ -5098,6 +5762,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -5135,14 +5808,14 @@ "license": "MIT" }, "node_modules/pg": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.18.0.tgz", - "integrity": "sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==", + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.11.0", - "pg-protocol": "^1.11.0", + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -5150,7 +5823,7 @@ "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.3.0" + "pg-cloudflare": "^1.2.7" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -5162,16 +5835,16 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", - "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", - "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", "license": "MIT" }, "node_modules/pg-int8": { @@ -5184,18 +5857,18 @@ } }, "node_modules/pg-pool": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", - "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", - "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", "license": "MIT" }, "node_modules/pg-types": { @@ -5254,9 +5927,9 @@ } }, "node_modules/postgres-bytea": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5324,6 +5997,29 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/protobufjs": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", @@ -5414,12 +6110,12 @@ } }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -5468,15 +6164,15 @@ } }, "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" @@ -5498,26 +6194,17 @@ } }, "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/readdir-glob": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", @@ -5614,9 +6301,9 @@ } }, "node_modules/request/node_modules/qs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", - "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.6" @@ -5641,6 +6328,17 @@ "node": ">=0.10.0" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -5668,16 +6366,13 @@ } }, "node_modules/ripemd160": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "license": "MIT", "dependencies": { - "hash-base": "^3.1.2", - "inherits": "^2.0.4" - }, - "engines": { - "node": ">= 0.8" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "node_modules/run-parallel": { @@ -5760,12 +6455,6 @@ "node": ">=18.0.0" } }, - "node_modules/secp256k1/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/secp256k1/node_modules/elliptic": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", @@ -5791,24 +6480,24 @@ } }, "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.4.1", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~2.0.2" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -5829,21 +6518,36 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "~0.19.1" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5981,16 +6685,10 @@ } }, "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -6094,6 +6792,50 @@ "license": "MIT", "peer": true }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -6119,6 +6861,40 @@ "node": ">=14" } }, + "node_modules/sqlite3": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", + "tar": "^6.1.11" + }, + "optionalDependencies": { + "node-gyp": "8.x" + }, + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/sqlite3/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -6144,15 +6920,43 @@ "node": ">=0.10.0" } }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/standard-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz", "integrity": "sha512-4v7qzU7oLJfMI5EltUSHCaaOd65J6S4BqKRWgzMi4EYaE5fvNabPxmAPGdxpGXqrcWjhDGI/H09CIdEuUOUeXg==" }, "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6165,29 +6969,22 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", "license": "MIT", "dependencies": { - "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "license": "MIT" }, "node_modules/string-width": { @@ -6267,25 +7064,26 @@ } }, "node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", - "license": "BlueOak-1.0.0", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" } }, "node_modules/tar-fs": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -6330,10 +7128,19 @@ "node": ">= 6" } }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/text-decoder": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.6.tgz", - "integrity": "sha512-27FeW5GQFDfw0FpwMQhMagB7BztOOlmjcSRi97t2oplhKVTZtp0DZbSegSaXS5IIC6mxMvBG4AR1Sgc6BX3CQg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" @@ -6349,6 +7156,42 @@ "xtend": "~4.0.1" } }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/tiny-secp256k1": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.4.tgz", @@ -6371,9 +7214,9 @@ } }, "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", + "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", "license": "MIT", "dependencies": { "isarray": "^2.0.5", @@ -6598,23 +7441,22 @@ "license": "MIT" }, "node_modules/typeorm": { - "version": "0.3.28", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.28.tgz", - "integrity": "sha512-6GH7wXhtfq2D33ZuRXYwIsl/qM5685WZcODZb7noOOcRMteM9KF2x2ap3H0EBjnSV0VO4gNAfJT5Ukp0PkOlvg==", + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.26.tgz", + "integrity": "sha512-o2RrBNn3lczx1qv4j+JliVMmtkPSqEGpG0UuZkt9tCfWkoXKu8MZnjvp2GjWPll1SehwemQw6xrbVRhmOglj8Q==", "license": "MIT", "dependencies": { "@sqltools/formatter": "^1.2.5", - "ansis": "^4.2.0", + "ansis": "^3.17.0", "app-root-path": "^3.1.0", "buffer": "^6.0.3", - "dayjs": "^1.11.19", - "debug": "^4.4.3", - "dedent": "^1.7.0", - "dotenv": "^16.6.1", - "glob": "^10.5.0", - "reflect-metadata": "^0.2.2", - "sha.js": "^2.4.12", - "sql-highlight": "^6.1.0", + "dayjs": "^1.11.13", + "debug": "^4.4.0", + "dedent": "^1.6.0", + "dotenv": "^16.4.7", + "glob": "^10.4.5", + "sha.js": "^2.4.11", + "sql-highlight": "^6.0.0", "tslib": "^2.8.1", "uuid": "^11.1.0", "yargs": "^17.7.2" @@ -6631,18 +7473,19 @@ "url": "https://opencollective.com/typeorm" }, "peerDependencies": { - "@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0", "@sap/hana-client": "^2.14.22", "better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0", "ioredis": "^5.0.4", "mongodb": "^5.8.0 || ^6.0.0", - "mssql": "^9.1.1 || ^10.0.0 || ^11.0.0 || ^12.0.0", + "mssql": "^9.1.1 || ^10.0.1 || ^11.0.1", "mysql2": "^2.2.5 || ^3.0.1", "oracledb": "^6.3.0", "pg": "^8.5.1", "pg-native": "^3.0.0", "pg-query-stream": "^4.0.0", "redis": "^3.1.1 || ^4.0.0 || ^5.0.14", + "reflect-metadata": "^0.1.14 || ^0.2.0", "sql.js": "^1.4.0", "sqlite3": "^5.0.3", "ts-node": "^10.7.0", @@ -6699,47 +7542,6 @@ } } }, - "node_modules/typeorm/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/typeorm/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/typeorm/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/typeorm/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -6773,17 +7575,10 @@ "ieee754": "^1.2.1" } }, - "node_modules/typeorm/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, "node_modules/typeorm/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -6836,6 +7631,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/typeorm/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/typeorm/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -6852,38 +7656,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/typeorm/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typeorm/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/typeorm/node_modules/uuid": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", @@ -6897,23 +7669,6 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/typeorm/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/typescript": { "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", @@ -6927,15 +7682,6 @@ "node": ">=14.17" } }, - "node_modules/uint8array-tools": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.8.tgz", - "integrity": "sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", @@ -6943,6 +7689,28 @@ "dev": true, "license": "MIT" }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6979,6 +7747,21 @@ "pct-encode": "~1.0.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7010,27 +7793,22 @@ "devOptional": true, "license": "MIT" }, - "node_modules/valibot": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.2.0.tgz", - "integrity": "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==", - "license": "MIT", - "peerDependencies": { - "typescript": ">=5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/varuint-bitcoin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", - "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-2.0.0.tgz", + "integrity": "sha512-6QZbU/rHO2ZQYpWFDALCDSRsXbAs1VOEmXAxtbtjLtKuMJ/FQ8YbhfxlaiKv5nklci0M6lZtlZyxo9Q+qNnyog==", "license": "MIT", "dependencies": { - "safe-buffer": "^5.1.1" + "uint8array-tools": "^0.0.8" + } + }, + "node_modules/varuint-bitcoin/node_modules/uint8array-tools": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.8.tgz", + "integrity": "sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" } }, "node_modules/vary": { @@ -7094,9 +7872,9 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -7126,6 +7904,15 @@ "node": ">=20.11" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/wif": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", @@ -7225,9 +8012,9 @@ } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -7264,13 +8051,10 @@ } }, "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", @@ -7320,40 +8104,15 @@ "is-glob": "^4.0.3" } }, - "node_modules/zip-a-folder/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", - "license": "MIT", - "dependencies": { - "jackspeak": "^4.2.3" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/zip-a-folder/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/zip-a-folder/node_modules/glob": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", - "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "BlueOak-1.0.0", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "license": "ISC", "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", - "minimatch": "^10.1.1", + "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -7369,12 +8128,12 @@ } }, "node_modules/zip-a-folder/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", - "license": "BlueOak-1.0.0", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { "node": "20 || >=22" @@ -7383,6 +8142,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/zip-a-folder/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", diff --git a/package.json b/package.json index 54f95e5c..7db3acdb 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "zip-a-folder": "^3.1.9" }, "devDependencies": { - "@types/better-sqlite3": "^7.6.13", "@types/chai": "^4.3.4", "@types/chai-string": "^1.4.5", "@types/cors": "^2.8.17", @@ -94,4 +93,4 @@ "typescript": "5.5.4" }, "overrides": {} -} +} \ No newline at end of file diff --git a/src/extensions/README.md b/src/extensions/README.md deleted file mode 100644 index 2f4e0b15..00000000 --- a/src/extensions/README.md +++ /dev/null @@ -1,731 +0,0 @@ -# Lightning.Pub Extension System - -A modular extension system that allows third-party functionality to be added to Lightning.Pub without modifying core code. - -## Table of Contents - -- [Overview](#overview) -- [Architecture](#architecture) -- [Creating an Extension](#creating-an-extension) -- [Extension Lifecycle](#extension-lifecycle) -- [ExtensionContext API](#extensioncontext-api) -- [Database Isolation](#database-isolation) -- [RPC Methods](#rpc-methods) -- [HTTP Routes](#http-routes) -- [Event Handling](#event-handling) -- [Configuration](#configuration) -- [Examples](#examples) - ---- - -## Overview - -The extension system provides: - -- **Modularity**: Extensions are self-contained modules with their own code and data -- **Isolation**: Each extension gets its own SQLite database -- **Integration**: Extensions can register RPC methods, handle events, and interact with Lightning.Pub's payment and Nostr systems -- **Lifecycle Management**: Automatic discovery, loading, and graceful shutdown - -### Built-in Extensions - -| Extension | Description | -|-----------|-------------| -| `marketplace` | NIP-15 Nostr marketplace for selling products via Lightning | -| `withdraw` | LNURL-withdraw (LUD-03) for vouchers, faucets, and gifts | - ---- - -## Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Lightning.Pub │ -├─────────────────────────────────────────────────────────────────┤ -│ Extension Loader │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ Extension A │ │ Extension B │ │ Extension C │ ... │ -│ │ ┌───────┐ │ │ ┌───────┐ │ │ ┌───────┐ │ │ -│ │ │Context│ │ │ │Context│ │ │ │Context│ │ │ -│ │ └───────┘ │ │ └───────┘ │ │ └───────┘ │ │ -│ │ ┌───────┐ │ │ ┌───────┐ │ │ ┌───────┐ │ │ -│ │ │ DB │ │ │ │ DB │ │ │ │ DB │ │ │ -│ │ └───────┘ │ │ └───────┘ │ │ └───────┘ │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Payment Manager │ Nostr Transport │ Application Manager │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### Key Components - -| Component | File | Description | -|-----------|------|-------------| -| `ExtensionLoader` | `loader.ts` | Discovers, loads, and manages extensions | -| `ExtensionContext` | `context.ts` | Bridge between extensions and Lightning.Pub | -| `ExtensionDatabase` | `database.ts` | Isolated SQLite database per extension | - ---- - -## Creating an Extension - -### Directory Structure - -``` -src/extensions/ -└── my-extension/ - ├── index.ts # Main entry point (required) - ├── types.ts # TypeScript interfaces - ├── migrations.ts # Database migrations - └── managers/ # Business logic - └── myManager.ts -``` - -### Minimal Extension - -```typescript -// src/extensions/my-extension/index.ts - -import { Extension, ExtensionInfo, ExtensionContext, ExtensionDatabase } from '../types.js' - -export default class MyExtension implements Extension { - readonly info: ExtensionInfo = { - id: 'my-extension', // Must match directory name - name: 'My Extension', - version: '1.0.0', - description: 'Does something useful', - author: 'Your Name', - minPubVersion: '1.0.0' // Minimum Lightning.Pub version - } - - async initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise { - // Run migrations - await db.execute(` - CREATE TABLE IF NOT EXISTS my_table ( - id TEXT PRIMARY KEY, - data TEXT - ) - `) - - // Register RPC methods - ctx.registerMethod('my-extension.doSomething', async (req, appId) => { - return { result: 'done' } - }) - - ctx.log('info', 'Extension initialized') - } - - async shutdown(): Promise { - // Cleanup resources - } -} -``` - -### Extension Interface - -```typescript -interface Extension { - // Required: Extension metadata - readonly info: ExtensionInfo - - // Required: Called once when extension is loaded - initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise - - // Optional: Called when Lightning.Pub shuts down - shutdown?(): Promise - - // Optional: Health check for monitoring - healthCheck?(): Promise -} - -interface ExtensionInfo { - id: string // Unique identifier (lowercase, no spaces) - name: string // Display name - version: string // Semver version - description: string // Short description - author: string // Author name - minPubVersion?: string // Minimum Lightning.Pub version - dependencies?: string[] // Other extension IDs required -} -``` - ---- - -## Extension Lifecycle - -``` -┌──────────────┐ -│ Discover │ Scan extensions directory for index.ts files -└──────┬───────┘ - │ - ▼ -┌──────────────┐ -│ Load │ Import module, instantiate class -└──────┬───────┘ - │ - ▼ -┌──────────────┐ -│ Initialize │ Create database, call initialize() -└──────┬───────┘ - │ - ▼ -┌──────────────┐ -│ Ready │ Extension is active, handling requests -└──────┬───────┘ - │ - ▼ (on shutdown) -┌──────────────┐ -│ Shutdown │ Call shutdown(), close database -└──────────────┘ -``` - -### States - -| State | Description | -|-------|-------------| -| `loading` | Extension is being loaded | -| `ready` | Extension is active and healthy | -| `error` | Initialization failed | -| `stopped` | Extension has been shut down | - ---- - -## ExtensionContext API - -The `ExtensionContext` is passed to your extension during initialization. It provides access to Lightning.Pub functionality. - -### Application Management - -```typescript -// Get information about an application -const app = await ctx.getApplication(applicationId) -// Returns: { id, name, nostr_public, balance_sats } | null -``` - -### Payment Operations - -```typescript -// Create a Lightning invoice -const invoice = await ctx.createInvoice(amountSats, { - memo: 'Payment for service', - expiry: 3600, // seconds - metadata: { order_id: '123' } // Returned in payment callback -}) -// Returns: { id, paymentRequest, paymentHash, expiry } - -// Pay a Lightning invoice -const result = await ctx.payInvoice(applicationId, bolt11Invoice, maxFeeSats) -// Returns: { paymentHash, feeSats } -``` - -### Nostr Operations - -```typescript -// Send encrypted DM (NIP-44) -const eventId = await ctx.sendEncryptedDM(applicationId, recipientPubkey, content) - -// Publish a Nostr event (signed by application's key) -const eventId = await ctx.publishNostrEvent({ - kind: 30017, - pubkey: appPubkey, - created_at: Math.floor(Date.now() / 1000), - tags: [['d', 'identifier']], - content: JSON.stringify(data) -}) -``` - -### RPC Method Registration - -```typescript -// Register a method that can be called via RPC -ctx.registerMethod('my-extension.methodName', async (request, applicationId, userPubkey?) => { - // request: The RPC request payload - // applicationId: The calling application's ID - // userPubkey: The user's Nostr pubkey (if authenticated) - - return { result: 'success' } -}) -``` - -### Event Subscriptions - -```typescript -// Subscribe to payment received events -ctx.onPaymentReceived(async (payment) => { - // payment: { invoiceId, paymentHash, amountSats, metadata } - - if (payment.metadata?.extension === 'my-extension') { - // Handle payment for this extension - } -}) - -// Subscribe to incoming Nostr events -ctx.onNostrEvent(async (event, applicationId) => { - // event: { id, pubkey, kind, tags, content, created_at } - // applicationId: The application this event is for - - if (event.kind === 4) { // DM - // Handle incoming message - } -}) -``` - -### Logging - -```typescript -ctx.log('debug', 'Detailed debugging info') -ctx.log('info', 'Normal operation info') -ctx.log('warn', 'Warning message') -ctx.log('error', 'Error occurred', errorObject) -``` - ---- - -## Database Isolation - -Each extension gets its own SQLite database file at: -``` -{databaseDir}/{extension-id}.db -``` - -### Database Interface - -```typescript -interface ExtensionDatabase { - // Execute write queries (INSERT, UPDATE, DELETE, CREATE) - execute(sql: string, params?: any[]): Promise<{ changes?: number; lastId?: number }> - - // Execute read queries (SELECT) - query(sql: string, params?: any[]): Promise - - // Run multiple statements in a transaction - transaction(fn: () => Promise): Promise -} -``` - -### Migration Pattern - -```typescript -// migrations.ts - -export interface Migration { - version: number - name: string - up: (db: ExtensionDatabase) => Promise -} - -export const migrations: Migration[] = [ - { - version: 1, - name: 'create_initial_tables', - up: async (db) => { - await db.execute(` - CREATE TABLE items ( - id TEXT PRIMARY KEY, - name TEXT NOT NULL, - created_at INTEGER NOT NULL - ) - `) - } - }, - { - version: 2, - name: 'add_status_column', - up: async (db) => { - await db.execute(`ALTER TABLE items ADD COLUMN status TEXT DEFAULT 'active'`) - } - } -] - -// Run migrations in initialize() -export async function runMigrations(db: ExtensionDatabase): Promise { - const result = await db.query<{ value: string }>( - `SELECT value FROM _extension_meta WHERE key = 'migration_version'` - ).catch(() => []) - - const currentVersion = result.length > 0 ? parseInt(result[0].value, 10) : 0 - - for (const migration of migrations) { - if (migration.version > currentVersion) { - console.log(`Running migration ${migration.version}: ${migration.name}`) - await migration.up(db) - await db.execute( - `INSERT INTO _extension_meta (key, value) VALUES ('migration_version', ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value`, - [String(migration.version)] - ) - } - } -} -``` - ---- - -## RPC Methods - -Extensions register RPC methods that can be called by clients. - -### Naming Convention - -Methods should be namespaced with the extension ID: -``` -{extension-id}.{methodName} -``` - -Examples: -- `marketplace.createStall` -- `withdraw.createLink` - -### Method Handler Signature - -```typescript -type RpcMethodHandler = ( - request: any, // The request payload - applicationId: string, // The calling application - userPubkey?: string // The authenticated user (if any) -) => Promise -``` - -### Example - -```typescript -ctx.registerMethod('my-extension.createItem', async (req, appId, userPubkey) => { - // Validate request - if (!req.name) { - throw new Error('Name is required') - } - - // Create item - const item = await this.manager.create(appId, req) - - // Return response - return { item } -}) -``` - ---- - -## HTTP Routes - -Some extensions need HTTP endpoints (e.g., LNURL protocol). Extensions can define routes that the main application mounts. - -### Defining Routes - -```typescript -interface HttpRoute { - method: 'GET' | 'POST' - path: string - handler: (req: HttpRequest) => Promise -} - -interface HttpRequest { - params: Record // URL path params - query: Record // Query string params - body?: any // POST body - headers: Record -} - -interface HttpResponse { - status: number - body: any - headers?: Record -} -``` - -### Example - -```typescript -class MyExtension implements Extension { - getHttpRoutes(): HttpRoute[] { - return [ - { - method: 'GET', - path: '/api/v1/my-extension/:id', - handler: async (req) => { - const item = await this.getItem(req.params.id) - return { - status: 200, - body: item, - headers: { 'Content-Type': 'application/json' } - } - } - } - ] - } -} -``` - ---- - -## Event Handling - -### Payment Callbacks - -When you create an invoice with metadata, you'll receive that metadata back in the payment callback: - -```typescript -// Creating invoice with metadata -const invoice = await ctx.createInvoice(1000, { - metadata: { - extension: 'my-extension', - order_id: 'order-123' - } -}) - -// Handling payment -ctx.onPaymentReceived(async (payment) => { - if (payment.metadata?.extension === 'my-extension') { - const orderId = payment.metadata.order_id - await this.handlePayment(orderId, payment) - } -}) -``` - -### Nostr Events - -Subscribe to Nostr events for your application: - -```typescript -ctx.onNostrEvent(async (event, applicationId) => { - // Filter by event kind - if (event.kind === 4) { // Encrypted DM - await this.handleDirectMessage(event, applicationId) - } -}) -``` - ---- - -## Configuration - -### Loader Configuration - -```typescript -interface ExtensionLoaderConfig { - extensionsDir: string // Directory containing extensions - databaseDir: string // Directory for extension databases - enabledExtensions?: string[] // Whitelist (if set, only these load) - disabledExtensions?: string[] // Blacklist -} -``` - -### Usage - -```typescript -import { createExtensionLoader } from './extensions' - -const loader = createExtensionLoader({ - extensionsDir: './src/extensions', - databaseDir: './data/extensions', - disabledExtensions: ['experimental-ext'] -}, mainHandler) - -await loader.loadAll() - -// Call extension methods -const result = await loader.callMethod( - 'marketplace.createStall', - { name: 'My Shop', currency: 'sat', shipping_zones: [] }, - applicationId, - userPubkey -) - -// Dispatch events -loader.dispatchPaymentReceived(paymentData) -loader.dispatchNostrEvent(event, applicationId) - -// Shutdown -await loader.shutdown() -``` - ---- - -## Examples - -### Example: Simple Counter Extension - -```typescript -// src/extensions/counter/index.ts - -import { Extension, ExtensionInfo, ExtensionContext, ExtensionDatabase } from '../types.js' - -export default class CounterExtension implements Extension { - readonly info: ExtensionInfo = { - id: 'counter', - name: 'Simple Counter', - version: '1.0.0', - description: 'A simple counter for each application', - author: 'Example' - } - - private db!: ExtensionDatabase - - async initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise { - this.db = db - - await db.execute(` - CREATE TABLE IF NOT EXISTS counters ( - application_id TEXT PRIMARY KEY, - count INTEGER NOT NULL DEFAULT 0 - ) - `) - - ctx.registerMethod('counter.increment', async (req, appId) => { - await db.execute( - `INSERT INTO counters (application_id, count) VALUES (?, 1) - ON CONFLICT(application_id) DO UPDATE SET count = count + 1`, - [appId] - ) - const result = await db.query<{ count: number }>( - 'SELECT count FROM counters WHERE application_id = ?', - [appId] - ) - return { count: result[0]?.count || 0 } - }) - - ctx.registerMethod('counter.get', async (req, appId) => { - const result = await db.query<{ count: number }>( - 'SELECT count FROM counters WHERE application_id = ?', - [appId] - ) - return { count: result[0]?.count || 0 } - }) - - ctx.registerMethod('counter.reset', async (req, appId) => { - await db.execute( - 'UPDATE counters SET count = 0 WHERE application_id = ?', - [appId] - ) - return { count: 0 } - }) - } -} -``` - -### Example: Payment-Triggered Extension - -```typescript -// src/extensions/donations/index.ts - -import { Extension, ExtensionContext, ExtensionDatabase } from '../types.js' - -export default class DonationsExtension implements Extension { - readonly info = { - id: 'donations', - name: 'Donations', - version: '1.0.0', - description: 'Accept donations with thank-you messages', - author: 'Example' - } - - private db!: ExtensionDatabase - private ctx!: ExtensionContext - - async initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise { - this.db = db - this.ctx = ctx - - await db.execute(` - CREATE TABLE IF NOT EXISTS donations ( - id TEXT PRIMARY KEY, - application_id TEXT NOT NULL, - amount_sats INTEGER NOT NULL, - donor_pubkey TEXT, - message TEXT, - created_at INTEGER NOT NULL - ) - `) - - // Create donation invoice - ctx.registerMethod('donations.createInvoice', async (req, appId) => { - const invoice = await ctx.createInvoice(req.amount_sats, { - memo: req.message || 'Donation', - metadata: { - extension: 'donations', - donor_pubkey: req.donor_pubkey, - message: req.message - } - }) - return { invoice: invoice.paymentRequest } - }) - - // Handle successful payments - ctx.onPaymentReceived(async (payment) => { - if (payment.metadata?.extension !== 'donations') return - - // Record donation - await db.execute( - `INSERT INTO donations (id, application_id, amount_sats, donor_pubkey, message, created_at) - VALUES (?, ?, ?, ?, ?, ?)`, - [ - payment.paymentHash, - payment.metadata.application_id, - payment.amountSats, - payment.metadata.donor_pubkey, - payment.metadata.message, - Math.floor(Date.now() / 1000) - ] - ) - - // Send thank-you DM if donor has pubkey - if (payment.metadata.donor_pubkey) { - await ctx.sendEncryptedDM( - payment.metadata.application_id, - payment.metadata.donor_pubkey, - `Thank you for your donation of ${payment.amountSats} sats!` - ) - } - }) - - // List donations - ctx.registerMethod('donations.list', async (req, appId) => { - const donations = await db.query( - `SELECT * FROM donations WHERE application_id = ? ORDER BY created_at DESC LIMIT ?`, - [appId, req.limit || 50] - ) - return { donations } - }) - } -} -``` - ---- - -## Best Practices - -1. **Namespace your methods**: Always prefix RPC methods with your extension ID -2. **Use migrations**: Never modify existing migration files; create new ones -3. **Handle errors gracefully**: Throw descriptive errors, don't return error objects -4. **Clean up in shutdown**: Close connections, cancel timers, etc. -5. **Log appropriately**: Use debug for verbose info, error for failures -6. **Validate inputs**: Check request parameters before processing -7. **Use transactions**: For multi-step database operations -8. **Document your API**: Include types and descriptions for RPC methods - ---- - -## Troubleshooting - -### Extension not loading - -1. Check that directory name matches `info.id` -2. Verify `index.ts` has a default export -3. Check for TypeScript/import errors in logs - -### Database errors - -1. Check migration syntax -2. Verify column types match queries -3. Look for migration version conflicts - -### RPC method not found - -1. Verify method is registered in `initialize()` -2. Check method name includes extension prefix -3. Ensure extension status is `ready` - -### Payment callbacks not firing - -1. Verify `metadata.extension` matches your extension ID -2. Check that `onPaymentReceived` is registered in `initialize()` -3. Confirm invoice was created through the extension diff --git a/src/extensions/context.ts b/src/extensions/context.ts deleted file mode 100644 index f18891f5..00000000 --- a/src/extensions/context.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { - ExtensionContext, - ExtensionDatabase, - ExtensionInfo, - ApplicationInfo, - CreateInvoiceOptions, - CreatedInvoice, - PaymentReceivedData, - NostrEvent, - UnsignedNostrEvent, - RpcMethodHandler, - LnurlPayInfo -} from './types.js' - -/** - * Main Handler interface (from Lightning.Pub) - * This is a minimal interface - the actual MainHandler has more methods - */ -export interface MainHandlerInterface { - // Application management - applicationManager: { - getById(id: string): Promise - PayAppUserInvoice(appId: string, req: { - amount: number - invoice: string - user_identifier: string - debit_npub?: string - }): Promise<{ - preimage: string - amount_paid: number - network_fee: number - service_fee: number - }> - } - - // Payment operations - paymentManager: { - createInvoice(params: { - applicationId: string - amountSats: number - memo?: string - expiry?: number - metadata?: Record - }): Promise<{ - id: string - paymentRequest: string - paymentHash: string - expiry: number - }> - - payInvoice(params: { - applicationId: string - paymentRequest: string - maxFeeSats?: number - userPubkey?: string - }): Promise<{ - paymentHash: string - feeSats: number - }> - - /** - * Get LNURL-pay info for a user by their Nostr pubkey - * This enables Lightning Address (LUD-16) and zap (NIP-57) support - */ - getLnurlPayInfoByPubkey(pubkeyHex: string, options?: { - metadata?: string - description?: string - }): Promise - } - - // Nostr operations - sendNostrEvent(event: any): Promise - sendEncryptedDM(applicationId: string, recipientPubkey: string, content: string): Promise -} - -/** - * Callback registries for extension events - */ -interface CallbackRegistries { - paymentReceived: Array<(payment: PaymentReceivedData) => Promise> - nostrEvent: Array<(event: NostrEvent, applicationId: string) => Promise> -} - -/** - * Registered RPC method - */ -interface RegisteredMethod { - extensionId: string - handler: RpcMethodHandler -} - -/** - * Extension Context Implementation - * - * Provides the interface for extensions to interact with Lightning.Pub. - * Each extension gets its own context instance. - */ -export class ExtensionContextImpl implements ExtensionContext { - private callbacks: CallbackRegistries = { - paymentReceived: [], - nostrEvent: [] - } - - constructor( - private extensionInfo: ExtensionInfo, - private database: ExtensionDatabase, - private mainHandler: MainHandlerInterface, - private methodRegistry: Map - ) {} - - /** - * Get information about an application - */ - async getApplication(applicationId: string): Promise { - try { - const app = await this.mainHandler.applicationManager.getById(applicationId) - if (!app) return null - - return { - id: app.id, - name: app.name, - nostr_public: app.nostr_public, - balance_sats: app.balance || 0 - } - } catch (e) { - this.log('error', `Failed to get application ${applicationId}:`, e) - return null - } - } - - /** - * Create a Lightning invoice - */ - async createInvoice(amountSats: number, options: CreateInvoiceOptions = {}): Promise { - // Note: In practice, this needs an applicationId. Extensions typically - // get this from the RPC request context. For now, we'll need to handle - // this in the actual implementation. - throw new Error('createInvoice requires applicationId from request context') - } - - /** - * Create invoice with explicit application ID - * This is the internal method used by extensions - */ - async createInvoiceForApp( - applicationId: string, - amountSats: number, - options: CreateInvoiceOptions = {} - ): Promise { - const result = await this.mainHandler.paymentManager.createInvoice({ - applicationId, - amountSats, - memo: options.memo, - expiry: options.expiry, - metadata: { - ...options.metadata, - extension: this.extensionInfo.id - } - }) - - return { - id: result.id, - paymentRequest: result.paymentRequest, - paymentHash: result.paymentHash, - expiry: result.expiry - } - } - - /** - * Pay a Lightning invoice - * If userPubkey is provided, pays from that user's balance instead of app.owner - */ - async payInvoice( - applicationId: string, - paymentRequest: string, - maxFeeSats?: number, - userPubkey?: string - ): Promise<{ paymentHash: string; feeSats: number }> { - return this.mainHandler.paymentManager.payInvoice({ - applicationId, - paymentRequest, - maxFeeSats, - userPubkey - }) - } - - /** - * Send an encrypted DM via Nostr - */ - async sendEncryptedDM( - applicationId: string, - recipientPubkey: string, - content: string - ): Promise { - return this.mainHandler.sendEncryptedDM(applicationId, recipientPubkey, content) - } - - /** - * Publish a Nostr event - */ - async publishNostrEvent(event: UnsignedNostrEvent): Promise { - return this.mainHandler.sendNostrEvent(event) - } - - /** - * Get LNURL-pay info for a user by pubkey - * Enables Lightning Address and zap support - */ - async getLnurlPayInfo(pubkeyHex: string, options?: { - metadata?: string - description?: string - }): Promise { - return this.mainHandler.paymentManager.getLnurlPayInfoByPubkey(pubkeyHex, options) - } - - /** - * Subscribe to payment received callbacks - */ - onPaymentReceived(callback: (payment: PaymentReceivedData) => Promise): void { - this.callbacks.paymentReceived.push(callback) - } - - /** - * Subscribe to incoming Nostr events - */ - onNostrEvent(callback: (event: NostrEvent, applicationId: string) => Promise): void { - this.callbacks.nostrEvent.push(callback) - } - - /** - * Register an RPC method - */ - registerMethod(name: string, handler: RpcMethodHandler): void { - const fullName = name.startsWith(`${this.extensionInfo.id}.`) - ? name - : `${this.extensionInfo.id}.${name}` - - if (this.methodRegistry.has(fullName)) { - throw new Error(`RPC method ${fullName} already registered`) - } - - this.methodRegistry.set(fullName, { - extensionId: this.extensionInfo.id, - handler - }) - - this.log('debug', `Registered RPC method: ${fullName}`) - } - - /** - * Get the extension's database - */ - getDatabase(): ExtensionDatabase { - return this.database - } - - /** - * Log a message - */ - log(level: 'debug' | 'info' | 'warn' | 'error', message: string, ...args: any[]): void { - const prefix = `[Extension:${this.extensionInfo.id}]` - switch (level) { - case 'debug': - console.debug(prefix, message, ...args) - break - case 'info': - console.info(prefix, message, ...args) - break - case 'warn': - console.warn(prefix, message, ...args) - break - case 'error': - console.error(prefix, message, ...args) - break - } - } - - // ===== Internal Methods (called by ExtensionLoader) ===== - - /** - * Dispatch payment received event to extension callbacks - */ - async dispatchPaymentReceived(payment: PaymentReceivedData): Promise { - for (const callback of this.callbacks.paymentReceived) { - try { - await callback(payment) - } catch (e) { - this.log('error', 'Error in payment callback:', e) - } - } - } - - /** - * Dispatch Nostr event to extension callbacks - */ - async dispatchNostrEvent(event: NostrEvent, applicationId: string): Promise { - for (const callback of this.callbacks.nostrEvent) { - try { - await callback(event, applicationId) - } catch (e) { - this.log('error', 'Error in Nostr event callback:', e) - } - } - } - - /** - * Get registered callbacks for external access - */ - getCallbacks(): CallbackRegistries { - return this.callbacks - } -} - -/** - * Create an extension context - */ -export function createExtensionContext( - extensionInfo: ExtensionInfo, - database: ExtensionDatabase, - mainHandler: MainHandlerInterface, - methodRegistry: Map -): ExtensionContextImpl { - return new ExtensionContextImpl(extensionInfo, database, mainHandler, methodRegistry) -} diff --git a/src/extensions/database.ts b/src/extensions/database.ts deleted file mode 100644 index 6f300c36..00000000 --- a/src/extensions/database.ts +++ /dev/null @@ -1,148 +0,0 @@ -import Database from 'better-sqlite3' -import path from 'path' -import fs from 'fs' -import { ExtensionDatabase } from './types.js' - -/** - * Extension Database Implementation - * - * Provides isolated SQLite database access for each extension. - * Uses better-sqlite3 for synchronous, high-performance access. - */ -export class ExtensionDatabaseImpl implements ExtensionDatabase { - private db: Database.Database - private extensionId: string - - constructor(extensionId: string, databaseDir: string) { - this.extensionId = extensionId - - // Ensure database directory exists - if (!fs.existsSync(databaseDir)) { - fs.mkdirSync(databaseDir, { recursive: true }) - } - - // Create database file for this extension - const dbPath = path.join(databaseDir, `${extensionId}.db`) - this.db = new Database(dbPath) - - // Enable WAL mode for better concurrency - this.db.pragma('journal_mode = WAL') - - // Enable foreign keys - this.db.pragma('foreign_keys = ON') - - // Create metadata table for tracking migrations - this.db.exec(` - CREATE TABLE IF NOT EXISTS _extension_meta ( - key TEXT PRIMARY KEY, - value TEXT NOT NULL - ) - `) - } - - /** - * Execute a write query (INSERT, UPDATE, DELETE, CREATE, etc.) - */ - async execute(sql: string, params: any[] = []): Promise<{ changes?: number; lastId?: number }> { - try { - const stmt = this.db.prepare(sql) - const result = stmt.run(...params) - - return { - changes: result.changes, - lastId: result.lastInsertRowid as number - } - } catch (e) { - console.error(`[Extension:${this.extensionId}] Database execute error:`, e) - throw e - } - } - - /** - * Execute a read query (SELECT) - */ - async query(sql: string, params: any[] = []): Promise { - try { - const stmt = this.db.prepare(sql) - return stmt.all(...params) as T[] - } catch (e) { - console.error(`[Extension:${this.extensionId}] Database query error:`, e) - throw e - } - } - - /** - * Execute multiple statements in a transaction - */ - async transaction(fn: () => Promise): Promise { - const runTransaction = this.db.transaction(() => { - // Note: better-sqlite3 transactions are synchronous - // We wrap the async function but it executes synchronously - return fn() - }) - - return runTransaction() as T - } - - /** - * Get a metadata value - */ - async getMeta(key: string): Promise { - const rows = await this.query<{ value: string }>( - 'SELECT value FROM _extension_meta WHERE key = ?', - [key] - ) - return rows.length > 0 ? rows[0].value : null - } - - /** - * Set a metadata value - */ - async setMeta(key: string, value: string): Promise { - await this.execute( - `INSERT INTO _extension_meta (key, value) VALUES (?, ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value`, - [key, value] - ) - } - - /** - * Get current migration version - */ - async getMigrationVersion(): Promise { - const version = await this.getMeta('migration_version') - return version ? parseInt(version, 10) : 0 - } - - /** - * Set migration version - */ - async setMigrationVersion(version: number): Promise { - await this.setMeta('migration_version', String(version)) - } - - /** - * Close the database connection - */ - close(): void { - this.db.close() - } - - /** - * Get the underlying database for advanced operations - * (Use with caution - bypasses isolation) - */ - getUnderlyingDb(): Database.Database { - return this.db - } -} - -/** - * Create an extension database instance - */ -export function createExtensionDatabase( - extensionId: string, - databaseDir: string -): ExtensionDatabaseImpl { - return new ExtensionDatabaseImpl(extensionId, databaseDir) -} diff --git a/src/extensions/index.ts b/src/extensions/index.ts deleted file mode 100644 index 208b7c86..00000000 --- a/src/extensions/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Lightning.Pub Extension System - * - * This module provides the extension infrastructure for Lightning.Pub. - * Extensions can add functionality like marketplaces, subscriptions, - * tipping, and more. - * - * Usage: - * - * ```typescript - * import { createExtensionLoader, ExtensionLoaderConfig } from './extensions' - * - * const config: ExtensionLoaderConfig = { - * extensionsDir: './extensions', - * databaseDir: './data/extensions' - * } - * - * const loader = createExtensionLoader(config, mainHandler) - * await loader.loadAll() - * - * // Call extension methods - * const result = await loader.callMethod( - * 'marketplace.createStall', - * { name: 'My Shop', currency: 'sat', shipping_zones: [...] }, - * applicationId - * ) - * ``` - */ - -// Export types -export { - Extension, - ExtensionInfo, - ExtensionContext, - ExtensionDatabase, - ExtensionModule, - ExtensionConstructor, - LoadedExtension, - ExtensionLoaderConfig, - ApplicationInfo, - CreateInvoiceOptions, - CreatedInvoice, - PaymentReceivedData, - NostrEvent, - UnsignedNostrEvent, - RpcMethodHandler -} from './types.js' - -// Export loader -export { ExtensionLoader, createExtensionLoader } from './loader.js' - -// Export database utilities -export { ExtensionDatabaseImpl, createExtensionDatabase } from './database.js' - -// Export context utilities -export { ExtensionContextImpl, createExtensionContext, MainHandlerInterface } from './context.js' diff --git a/src/extensions/loader.ts b/src/extensions/loader.ts deleted file mode 100644 index 9fc453c0..00000000 --- a/src/extensions/loader.ts +++ /dev/null @@ -1,406 +0,0 @@ -import path from 'path' -import fs from 'fs' -import { - Extension, - ExtensionInfo, - ExtensionModule, - LoadedExtension, - ExtensionLoaderConfig, - RpcMethodHandler, - PaymentReceivedData, - NostrEvent -} from './types.js' -import { ExtensionDatabaseImpl, createExtensionDatabase } from './database.js' -import { ExtensionContextImpl, createExtensionContext, MainHandlerInterface } from './context.js' - -/** - * Registered RPC method entry - */ -interface RegisteredMethod { - extensionId: string - handler: RpcMethodHandler -} - -/** - * Extension Loader - * - * Discovers, loads, and manages Lightning.Pub extensions. - * Provides lifecycle management and event dispatching. - */ -export class ExtensionLoader { - private config: ExtensionLoaderConfig - private mainHandler: MainHandlerInterface - private extensions: Map = new Map() - private contexts: Map = new Map() - private methodRegistry: Map = new Map() - private initialized = false - - constructor(config: ExtensionLoaderConfig, mainHandler: MainHandlerInterface) { - this.config = config - this.mainHandler = mainHandler - } - - /** - * Discover and load all extensions - */ - async loadAll(): Promise { - if (this.initialized) { - throw new Error('Extension loader already initialized') - } - - console.log('[Extensions] Loading extensions from:', this.config.extensionsDir) - - // Ensure directories exist - if (!fs.existsSync(this.config.extensionsDir)) { - console.log('[Extensions] Extensions directory does not exist, creating...') - fs.mkdirSync(this.config.extensionsDir, { recursive: true }) - this.initialized = true - return - } - - if (!fs.existsSync(this.config.databaseDir)) { - fs.mkdirSync(this.config.databaseDir, { recursive: true }) - } - - // Discover extensions - const extensionDirs = await this.discoverExtensions() - console.log(`[Extensions] Found ${extensionDirs.length} extension(s)`) - - // Load extensions in dependency order - const loadOrder = await this.resolveDependencies(extensionDirs) - - for (const extDir of loadOrder) { - try { - await this.loadExtension(extDir) - } catch (e) { - console.error(`[Extensions] Failed to load extension from ${extDir}:`, e) - } - } - - this.initialized = true - console.log(`[Extensions] Loaded ${this.extensions.size} extension(s)`) - } - - /** - * Discover extension directories - */ - private async discoverExtensions(): Promise { - const entries = fs.readdirSync(this.config.extensionsDir, { withFileTypes: true }) - const extensionDirs: string[] = [] - - for (const entry of entries) { - if (!entry.isDirectory()) continue - - const extDir = path.join(this.config.extensionsDir, entry.name) - const indexPath = path.join(extDir, 'index.ts') - const indexJsPath = path.join(extDir, 'index.js') - - // Check for index file - if (fs.existsSync(indexPath) || fs.existsSync(indexJsPath)) { - // Check enabled/disabled lists - if (this.config.disabledExtensions?.includes(entry.name)) { - console.log(`[Extensions] Skipping disabled extension: ${entry.name}`) - continue - } - - if (this.config.enabledExtensions && - !this.config.enabledExtensions.includes(entry.name)) { - console.log(`[Extensions] Skipping non-enabled extension: ${entry.name}`) - continue - } - - extensionDirs.push(extDir) - } - } - - return extensionDirs - } - - /** - * Resolve extension dependencies and return load order - */ - private async resolveDependencies(extensionDirs: string[]): Promise { - // For now, simple alphabetical order - // TODO: Implement proper dependency resolution with topological sort - return extensionDirs.sort() - } - - /** - * Load a single extension - */ - private async loadExtension(extensionDir: string): Promise { - const dirName = path.basename(extensionDir) - console.log(`[Extensions] Loading extension: ${dirName}`) - - // Determine index file path - let indexPath = path.join(extensionDir, 'index.js') - if (!fs.existsSync(indexPath)) { - indexPath = path.join(extensionDir, 'index.ts') - } - - // Dynamic import - const moduleUrl = `file://${indexPath}` - const module = await import(moduleUrl) as ExtensionModule - - if (!module.default) { - throw new Error(`Extension ${dirName} has no default export`) - } - - // Instantiate extension - const ExtensionClass = module.default - const instance = new ExtensionClass() as Extension - - if (!instance.info) { - throw new Error(`Extension ${dirName} has no info property`) - } - - const info = instance.info - - // Validate extension ID matches directory name - if (info.id !== dirName) { - console.warn( - `[Extensions] Extension ID '${info.id}' doesn't match directory '${dirName}'` - ) - } - - // Check for duplicate - if (this.extensions.has(info.id)) { - throw new Error(`Extension ${info.id} already loaded`) - } - - // Create isolated database - const database = createExtensionDatabase(info.id, this.config.databaseDir) - - // Create context - const context = createExtensionContext( - info, - database, - this.mainHandler, - this.methodRegistry - ) - - // Track as loading - const loaded: LoadedExtension = { - info, - instance, - database, - status: 'loading', - loadedAt: Date.now() - } - this.extensions.set(info.id, loaded) - this.contexts.set(info.id, context) - - try { - // Initialize extension - await instance.initialize(context, database) - - loaded.status = 'ready' - console.log(`[Extensions] Extension ${info.id} v${info.version} loaded successfully`) - } catch (e) { - loaded.status = 'error' - loaded.error = e as Error - console.error(`[Extensions] Extension ${info.id} initialization failed:`, e) - throw e - } - } - - /** - * Unload a specific extension - */ - async unloadExtension(extensionId: string): Promise { - const loaded = this.extensions.get(extensionId) - if (!loaded) { - throw new Error(`Extension ${extensionId} not found`) - } - - console.log(`[Extensions] Unloading extension: ${extensionId}`) - - try { - // Call shutdown if available - if (loaded.instance.shutdown) { - await loaded.instance.shutdown() - } - - loaded.status = 'stopped' - } catch (e) { - console.error(`[Extensions] Error during ${extensionId} shutdown:`, e) - } - - // Close database - if (loaded.database instanceof ExtensionDatabaseImpl) { - loaded.database.close() - } - - // Remove registered methods - for (const [name, method] of this.methodRegistry.entries()) { - if (method.extensionId === extensionId) { - this.methodRegistry.delete(name) - } - } - - // Remove from maps - this.extensions.delete(extensionId) - this.contexts.delete(extensionId) - } - - /** - * Shutdown all extensions - */ - async shutdown(): Promise { - console.log('[Extensions] Shutting down all extensions...') - - for (const extensionId of this.extensions.keys()) { - try { - await this.unloadExtension(extensionId) - } catch (e) { - console.error(`[Extensions] Error unloading ${extensionId}:`, e) - } - } - - console.log('[Extensions] All extensions shut down') - } - - /** - * Get a loaded extension - */ - getExtension(extensionId: string): LoadedExtension | undefined { - return this.extensions.get(extensionId) - } - - /** - * Get all loaded extensions - */ - getAllExtensions(): LoadedExtension[] { - return Array.from(this.extensions.values()) - } - - /** - * Check if an extension is loaded and ready - */ - isReady(extensionId: string): boolean { - const ext = this.extensions.get(extensionId) - return ext?.status === 'ready' - } - - /** - * Get all registered RPC methods - */ - getRegisteredMethods(): Map { - return this.methodRegistry - } - - /** - * Call an extension RPC method - */ - async callMethod( - methodName: string, - request: any, - applicationId: string, - userPubkey?: string - ): Promise { - const method = this.methodRegistry.get(methodName) - if (!method) { - throw new Error(`Unknown method: ${methodName}`) - } - - const ext = this.extensions.get(method.extensionId) - if (!ext || ext.status !== 'ready') { - throw new Error(`Extension ${method.extensionId} not ready`) - } - - return method.handler(request, applicationId, userPubkey) - } - - /** - * Check if a method exists - */ - hasMethod(methodName: string): boolean { - return this.methodRegistry.has(methodName) - } - - /** - * Dispatch payment received event to all extensions - */ - async dispatchPaymentReceived(payment: PaymentReceivedData): Promise { - for (const context of this.contexts.values()) { - try { - await context.dispatchPaymentReceived(payment) - } catch (e) { - console.error('[Extensions] Error dispatching payment:', e) - } - } - } - - /** - * Dispatch Nostr event to all extensions - */ - async dispatchNostrEvent(event: NostrEvent, applicationId: string): Promise { - for (const context of this.contexts.values()) { - try { - await context.dispatchNostrEvent(event, applicationId) - } catch (e) { - console.error('[Extensions] Error dispatching Nostr event:', e) - } - } - } - - /** - * Run health checks on all extensions - */ - async healthCheck(): Promise> { - const results = new Map() - - for (const [id, ext] of this.extensions.entries()) { - if (ext.status !== 'ready') { - results.set(id, false) - continue - } - - try { - if (ext.instance.healthCheck) { - results.set(id, await ext.instance.healthCheck()) - } else { - results.set(id, true) - } - } catch (e) { - results.set(id, false) - } - } - - return results - } - - /** - * Get extension status summary - */ - getStatus(): { - total: number - ready: number - error: number - extensions: Array<{ id: string; name: string; version: string; status: string }> - } { - const extensions = this.getAllExtensions().map(ext => ({ - id: ext.info.id, - name: ext.info.name, - version: ext.info.version, - status: ext.status - })) - - return { - total: extensions.length, - ready: extensions.filter(e => e.status === 'ready').length, - error: extensions.filter(e => e.status === 'error').length, - extensions - } - } -} - -/** - * Create an extension loader instance - */ -export function createExtensionLoader( - config: ExtensionLoaderConfig, - mainHandler: MainHandlerInterface -): ExtensionLoader { - return new ExtensionLoader(config, mainHandler) -} diff --git a/src/extensions/mainHandlerAdapter.ts b/src/extensions/mainHandlerAdapter.ts deleted file mode 100644 index fec73c3f..00000000 --- a/src/extensions/mainHandlerAdapter.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * MainHandler Adapter for Extension System - * - * Wraps the Lightning.Pub mainHandler to provide the MainHandlerInterface - * required by the extension system. - */ - -import { MainHandlerInterface } from './context.js' -import { LnurlPayInfo } from './types.js' -import type Main from '../services/main/index.js' - -/** - * Create an adapter that wraps mainHandler for extension use - */ -export function createMainHandlerAdapter(mainHandler: Main): MainHandlerInterface { - return { - applicationManager: { - async getById(id: string) { - // The applicationManager stores apps internally - // We need to access it through the storage layer - try { - const app = await mainHandler.storage.applicationStorage.GetApplication(id) - if (!app) return null - - return { - id: app.app_id, - name: app.name, - nostr_public: app.nostr_public_key || '', - balance: app.owner?.balance_sats || 0 - } - } catch (e) { - // GetApplication throws if not found - return null - } - }, - - async PayAppUserInvoice(appId, req) { - return mainHandler.applicationManager.PayAppUserInvoice(appId, req) - } - }, - - paymentManager: { - async createInvoice(params: { - applicationId: string - amountSats: number - memo?: string - expiry?: number - metadata?: Record - }) { - // Get the app to find the user ID - const app = await mainHandler.storage.applicationStorage.GetApplication(params.applicationId) - if (!app) { - throw new Error(`Application not found: ${params.applicationId}`) - } - - // Create invoice using the app owner's user ID - const result = await mainHandler.paymentManager.NewInvoice( - app.owner.user_id, - { - amountSats: params.amountSats, - memo: params.memo || '' - }, - { - expiry: params.expiry || 3600 - } - ) - - return { - id: result.invoice.split(':')[0] || result.invoice, // Extract ID if present - paymentRequest: result.invoice, - paymentHash: '', // Not directly available from NewInvoice response - expiry: Date.now() + (params.expiry || 3600) * 1000 - } - }, - - async payInvoice(params: { - applicationId: string - paymentRequest: string - maxFeeSats?: number - userPubkey?: string - }) { - // Get the app to find the user ID and app reference - const app = await mainHandler.storage.applicationStorage.GetApplication(params.applicationId) - if (!app) { - throw new Error(`Application not found: ${params.applicationId}`) - } - - if (params.userPubkey) { - // Resolve the Nostr user's ApplicationUser to get their identifier - const appUser = await mainHandler.storage.applicationStorage.GetOrCreateNostrAppUser(app, params.userPubkey) - console.log(`[MainHandlerAdapter] Paying via PayAppUserInvoice from Nostr user ${params.userPubkey.slice(0, 8)}... (identifier: ${appUser.identifier})`) - - // Use applicationManager.PayAppUserInvoice so notifyAppUserPayment fires - // This sends LiveUserOperation events via Nostr for real-time balance updates - const result = await mainHandler.applicationManager.PayAppUserInvoice( - params.applicationId, - { - invoice: params.paymentRequest, - amount: 0, // Use invoice amount - user_identifier: appUser.identifier - } - ) - - return { - paymentHash: result.preimage || '', - feeSats: result.network_fee || 0 - } - } - - // Fallback: pay from app owner's balance (no Nostr user context) - const result = await mainHandler.paymentManager.PayInvoice( - app.owner.user_id, - { - invoice: params.paymentRequest, - amount: 0 - }, - app, - {} - ) - - return { - paymentHash: result.preimage || '', - feeSats: result.network_fee || 0 - } - }, - - async getLnurlPayInfoByPubkey(pubkeyHex: string, options?: { - metadata?: string - description?: string - }): Promise { - // This would need implementation based on how Lightning.Pub handles LNURL-pay - // For now, throw not implemented - throw new Error('getLnurlPayInfoByPubkey not yet implemented') - } - }, - - async sendNostrEvent(event: any): Promise { - // The mainHandler doesn't directly expose nostrSend - // This would need to be implemented through the nostrMiddleware - // For now, return null (not implemented) - console.warn('[MainHandlerAdapter] sendNostrEvent not fully implemented') - return null - }, - - async sendEncryptedDM( - applicationId: string, - recipientPubkey: string, - content: string - ): Promise { - // This would need implementation using NIP-44 encryption - // For now, throw not implemented - throw new Error('sendEncryptedDM not yet implemented') - } - } -} diff --git a/src/extensions/types.ts b/src/extensions/types.ts deleted file mode 100644 index 66a4c46a..00000000 --- a/src/extensions/types.ts +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Extension System Core Types - * - * These types define the contract between Lightning.Pub and extensions. - */ - -/** - * Extension metadata - */ -export interface ExtensionInfo { - id: string // Unique identifier (lowercase, no spaces) - name: string // Display name - version: string // Semver version - description: string // Short description - author: string // Author name or organization - minPubVersion?: string // Minimum Lightning.Pub version required - dependencies?: string[] // Other extension IDs this depends on -} - -/** - * Extension database interface - * Provides isolated database access for each extension - */ -export interface ExtensionDatabase { - /** - * Execute a write query (INSERT, UPDATE, DELETE, CREATE, etc.) - */ - execute(sql: string, params?: any[]): Promise<{ changes?: number; lastId?: number }> - - /** - * Execute a read query (SELECT) - */ - query(sql: string, params?: any[]): Promise - - /** - * Execute multiple statements in a transaction - */ - transaction(fn: () => Promise): Promise -} - -/** - * Application info provided to extensions - */ -export interface ApplicationInfo { - id: string - name: string - nostr_public: string // Application's Nostr pubkey (hex) - balance_sats: number -} - -/** - * Invoice creation options - */ -export interface CreateInvoiceOptions { - memo?: string - expiry?: number // Seconds until expiry - metadata?: Record // Custom metadata for callbacks -} - -/** - * Created invoice result - */ -export interface CreatedInvoice { - id: string // Internal invoice ID - paymentRequest: string // BOLT11 invoice string - paymentHash: string // Payment hash (hex) - expiry: number // Expiry timestamp -} - -/** - * Payment received callback data - */ -export interface PaymentReceivedData { - invoiceId: string - paymentHash: string - amountSats: number - metadata?: Record -} - -/** - * LNURL-pay info response (LUD-06/LUD-16) - * Used for Lightning Address and zap support - */ -export interface LnurlPayInfo { - tag: 'payRequest' - callback: string // URL to call with amount - minSendable: number // Minimum msats - maxSendable: number // Maximum msats - metadata: string // JSON-encoded metadata array - allowsNostr?: boolean // Whether zaps are supported - nostrPubkey?: string // Pubkey for zap receipts (hex) -} - -/** - * Nostr event structure (minimal) - */ -export interface NostrEvent { - id: string - pubkey: string - created_at: number - kind: number - tags: string[][] - content: string - sig?: string -} - -/** - * Unsigned Nostr event for publishing - */ -export interface UnsignedNostrEvent { - kind: number - pubkey: string - created_at: number - tags: string[][] - content: string -} - -/** - * RPC method handler function - */ -export type RpcMethodHandler = ( - request: any, - applicationId: string, - userPubkey?: string -) => Promise - -/** - * Extension context - interface provided to extensions for interacting with Lightning.Pub - */ -export interface ExtensionContext { - /** - * Get information about an application - */ - getApplication(applicationId: string): Promise - - /** - * Create a Lightning invoice - */ - createInvoice(amountSats: number, options?: CreateInvoiceOptions): Promise - - /** - * Pay a Lightning invoice (requires sufficient balance) - * If userPubkey is provided, pays from that user's balance instead of app.owner - */ - payInvoice(applicationId: string, paymentRequest: string, maxFeeSats?: number, userPubkey?: string): Promise<{ - paymentHash: string - feeSats: number - }> - - /** - * Send an encrypted DM via Nostr (NIP-44) - */ - sendEncryptedDM(applicationId: string, recipientPubkey: string, content: string): Promise - - /** - * Publish a Nostr event (signed by application's key) - */ - publishNostrEvent(event: UnsignedNostrEvent): Promise - - /** - * Get LNURL-pay info for a user (by pubkey) - * Used to enable Lightning Address support (LUD-16) and zaps (NIP-57) - */ - getLnurlPayInfo(pubkeyHex: string, options?: { - metadata?: string // Custom metadata JSON - description?: string // Human-readable description - }): Promise - - /** - * Subscribe to payment received callbacks - */ - onPaymentReceived(callback: (payment: PaymentReceivedData) => Promise): void - - /** - * Subscribe to incoming Nostr events for the application - */ - onNostrEvent(callback: (event: NostrEvent, applicationId: string) => Promise): void - - /** - * Register an RPC method - */ - registerMethod(name: string, handler: RpcMethodHandler): void - - /** - * Get the extension's isolated database - */ - getDatabase(): ExtensionDatabase - - /** - * Log a message (prefixed with extension ID) - */ - log(level: 'debug' | 'info' | 'warn' | 'error', message: string, ...args: any[]): void -} - -/** - * HTTP route handler types - * Used by extensions that expose HTTP endpoints (e.g. LNURL, .well-known) - */ -export interface HttpRequest { - method: string - path: string - params: Record - query: Record - headers: Record - body?: any -} - -export interface HttpResponse { - status: number - body: any - headers?: Record -} - -export interface HttpRoute { - method: 'GET' | 'POST' - path: string - handler: (req: HttpRequest) => Promise -} - -/** - * Extension interface - what extensions must implement - */ -export interface Extension { - /** - * Extension metadata - */ - readonly info: ExtensionInfo - - /** - * Initialize the extension - * Called once when the extension is loaded - */ - initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise - - /** - * Shutdown the extension - * Called when Lightning.Pub is shutting down - */ - shutdown?(): Promise - - /** - * Health check - * Return true if extension is healthy - */ - healthCheck?(): Promise - - /** - * Get HTTP routes exposed by this extension - * The main HTTP server will mount these routes - */ - getHttpRoutes?(): HttpRoute[] -} - -/** - * Extension constructor type - */ -export type ExtensionConstructor = new () => Extension - -/** - * Extension module default export - */ -export interface ExtensionModule { - default: ExtensionConstructor -} - -/** - * Loaded extension state - */ -export interface LoadedExtension { - info: ExtensionInfo - instance: Extension - database: ExtensionDatabase - status: 'loading' | 'ready' | 'error' | 'stopped' - error?: Error - loadedAt: number -} - -/** - * Extension loader configuration - */ -export interface ExtensionLoaderConfig { - extensionsDir: string // Directory containing extensions - databaseDir: string // Directory for extension databases - enabledExtensions?: string[] // If set, only load these extensions - disabledExtensions?: string[] // Extensions to skip -} diff --git a/src/extensions/withdraw/index.ts b/src/extensions/withdraw/index.ts deleted file mode 100644 index 1a38930b..00000000 --- a/src/extensions/withdraw/index.ts +++ /dev/null @@ -1,383 +0,0 @@ -/** - * LNURL-withdraw Extension for Lightning.Pub - * - * Implements LUD-03 (LNURL-withdraw) for creating withdraw links - * that allow anyone to pull funds from a Lightning wallet. - * - * Use cases: - * - Quick vouchers (batch single-use codes) - * - Faucets - * - Gift cards / prepaid cards - * - Tips / donations - */ - -import { - Extension, - ExtensionInfo, - ExtensionContext, - ExtensionDatabase, - CreateWithdrawLinkRequest, - UpdateWithdrawLinkRequest, - HttpRoute, - HttpRequest, - HttpResponse -} from './types.js' -import { runMigrations } from './migrations.js' -import { WithdrawManager } from './managers/withdrawManager.js' - -/** - * LNURL-withdraw Extension - */ -export default class WithdrawExtension implements Extension { - readonly info: ExtensionInfo = { - id: 'withdraw', - name: 'LNURL Withdraw', - version: '1.0.0', - description: 'Create withdraw links for vouchers, faucets, and gifts (LUD-03)', - author: 'Lightning.Pub', - minPubVersion: '1.0.0' - } - - private manager!: WithdrawManager - private baseUrl: string = '' - - /** - * Initialize the extension - */ - async initialize(ctx: ExtensionContext, db: ExtensionDatabase): Promise { - // Run migrations - await runMigrations(db) - - // Initialize manager - this.manager = new WithdrawManager(db, ctx) - - // Register RPC methods - this.registerRpcMethods(ctx) - - // Register HTTP routes for LNURL protocol - this.registerHttpRoutes(ctx) - - ctx.log('info', 'Extension initialized') - } - - /** - * Shutdown the extension - */ - async shutdown(): Promise { - // Cleanup if needed - } - - /** - * Set the base URL for LNURL generation - * This should be called by the main application after loading - */ - setBaseUrl(url: string): void { - this.baseUrl = url - this.manager.setBaseUrl(url) - } - - /** - * Get HTTP routes for this extension - * These need to be mounted by the main HTTP server - */ - getHttpRoutes(): HttpRoute[] { - return [ - // Create withdraw link (HTTP API for ATM/external integrations) - { - method: 'POST', - path: '/api/v1/withdraw/create', - handler: this.handleCreateWithdrawLink.bind(this) - }, - // LNURL callback (user submits invoice) - MUST be before :unique_hash routes - { - method: 'GET', - path: '/api/v1/lnurl/cb/:unique_hash', - handler: this.handleLnurlCallback.bind(this) - }, - // Initial LNURL request (unique link with use hash) - { - method: 'GET', - path: '/api/v1/lnurl/:unique_hash/:id_unique_hash', - handler: this.handleLnurlUniqueRequest.bind(this) - }, - // Initial LNURL request (simple link) - MUST be last (catches all) - { - method: 'GET', - path: '/api/v1/lnurl/:unique_hash', - handler: this.handleLnurlRequest.bind(this) - } - ] - } - - /** - * Register RPC methods with the extension context - */ - private registerRpcMethods(ctx: ExtensionContext): void { - // Create withdraw link - ctx.registerMethod('withdraw.createLink', async (req, appId, userPubkey) => { - const link = await this.manager.create(appId, req as CreateWithdrawLinkRequest, userPubkey) - const stats = await this.manager.getWithdrawalStats(link.id) - return { - link, - total_withdrawn_sats: stats.total_sats, - withdrawals_count: stats.count - } - }) - - // Create quick vouchers - ctx.registerMethod('withdraw.createVouchers', async (req, appId) => { - const vouchers = await this.manager.createVouchers( - appId, - req.title, - req.amount, - req.count, - req.description - ) - return { - vouchers, - total_amount_sats: req.amount * req.count - } - }) - - // Get withdraw link - ctx.registerMethod('withdraw.getLink', async (req, appId) => { - const link = await this.manager.get(req.id, appId) - if (!link) throw new Error('Withdraw link not found') - const stats = await this.manager.getWithdrawalStats(link.id) - return { - link, - total_withdrawn_sats: stats.total_sats, - withdrawals_count: stats.count - } - }) - - // List withdraw links - ctx.registerMethod('withdraw.listLinks', async (req, appId) => { - const links = await this.manager.list( - appId, - req.include_spent || false, - req.limit, - req.offset - ) - return { links } - }) - - // Update withdraw link - ctx.registerMethod('withdraw.updateLink', async (req, appId) => { - const link = await this.manager.update(req.id, appId, req as UpdateWithdrawLinkRequest) - if (!link) throw new Error('Withdraw link not found') - const stats = await this.manager.getWithdrawalStats(link.id) - return { - link, - total_withdrawn_sats: stats.total_sats, - withdrawals_count: stats.count - } - }) - - // Delete withdraw link - ctx.registerMethod('withdraw.deleteLink', async (req, appId) => { - const success = await this.manager.delete(req.id, appId) - if (!success) throw new Error('Withdraw link not found') - return { success } - }) - - // List withdrawals - ctx.registerMethod('withdraw.listWithdrawals', async (req, appId) => { - const withdrawals = await this.manager.listWithdrawals( - appId, - req.link_id, - req.limit, - req.offset - ) - return { withdrawals } - }) - - // Get withdrawal stats - ctx.registerMethod('withdraw.getStats', async (req, appId) => { - // Get all links to calculate total stats - const links = await this.manager.list(appId, true) - - let totalLinks = links.length - let activeLinks = 0 - let spentLinks = 0 - let totalWithdrawn = 0 - let totalWithdrawals = 0 - - for (const link of links) { - if (link.used >= link.uses) { - spentLinks++ - } else { - activeLinks++ - } - const stats = await this.manager.getWithdrawalStats(link.id) - totalWithdrawn += stats.total_sats - totalWithdrawals += stats.count - } - - return { - total_links: totalLinks, - active_links: activeLinks, - spent_links: spentLinks, - total_withdrawn_sats: totalWithdrawn, - total_withdrawals: totalWithdrawals - } - }) - } - - /** - * Register HTTP routes (called by extension context) - */ - private registerHttpRoutes(ctx: ExtensionContext): void { - // HTTP routes are exposed via getHttpRoutes() - // The main application is responsible for mounting them - ctx.log('debug', 'HTTP routes registered for LNURL protocol') - } - - // ========================================================================= - // HTTP Route Handlers - // ========================================================================= - - /** - * Handle create withdraw link request (HTTP API) - * POST /api/v1/withdraw/create - * - * Body: { - * title: string - * min_withdrawable: number (sats) - * max_withdrawable: number (sats) - * uses?: number (defaults to 1) - * wait_time?: number (seconds between uses, defaults to 0) - * } - * - * Auth: Bearer token in Authorization header (app_) - * - * Returns: { - * link: { lnurl, unique_hash, id, ... } - * } - */ - private async handleCreateWithdrawLink(req: HttpRequest): Promise { - try { - const { title, min_withdrawable, max_withdrawable, uses, wait_time } = req.body - - // Extract app_id from Authorization header (Bearer app_) - const authHeader = req.headers?.authorization || req.headers?.Authorization || '' - let app_id = 'default' - if (authHeader.startsWith('Bearer app_')) { - app_id = authHeader.replace('Bearer app_', '') - } - - if (!title || !min_withdrawable) { - return { - status: 400, - body: { status: 'ERROR', reason: 'Missing required fields: title, min_withdrawable' }, - headers: { 'Content-Type': 'application/json' } - } - } - - const link = await this.manager.create(app_id, { - title, - min_withdrawable, - max_withdrawable: max_withdrawable || min_withdrawable, - uses: uses || 1, - wait_time: wait_time || 0, - is_unique: false // Simple single-use links for ATM - }) - - // Return in format expected by ATM client - return { - status: 200, - body: { - status: 'OK', - link: { - lnurl: link.lnurl, - unique_hash: link.unique_hash, - id: link.id, - title: link.title, - min_withdrawable: link.min_withdrawable, - max_withdrawable: link.max_withdrawable, - uses: link.uses, - used: link.used - } - }, - headers: { 'Content-Type': 'application/json' } - } - } catch (error: any) { - return { - status: 500, - body: { status: 'ERROR', reason: error.message }, - headers: { 'Content-Type': 'application/json' } - } - } - } - - /** - * Handle initial LNURL request (simple link) - * GET /api/v1/lnurl/:unique_hash - */ - private async handleLnurlRequest(req: HttpRequest): Promise { - const { unique_hash } = req.params - - const result = await this.manager.handleLnurlRequest(unique_hash) - - return { - status: 200, - body: result, - headers: { - 'Content-Type': 'application/json' - } - } - } - - /** - * Handle initial LNURL request (unique link) - * GET /api/v1/lnurl/:unique_hash/:id_unique_hash - */ - private async handleLnurlUniqueRequest(req: HttpRequest): Promise { - const { unique_hash, id_unique_hash } = req.params - - const result = await this.manager.handleLnurlRequest(unique_hash, id_unique_hash) - - return { - status: 200, - body: result, - headers: { - 'Content-Type': 'application/json' - } - } - } - - /** - * Handle LNURL callback (user submits invoice) - * GET /api/v1/lnurl/cb/:unique_hash?k1=...&pr=...&id_unique_hash=... - */ - private async handleLnurlCallback(req: HttpRequest): Promise { - const { unique_hash } = req.params - const { k1, pr, id_unique_hash } = req.query - - if (!k1 || !pr) { - return { - status: 200, - body: { status: 'ERROR', reason: 'Missing k1 or pr parameter' }, - headers: { 'Content-Type': 'application/json' } - } - } - - const result = await this.manager.handleLnurlCallback(unique_hash, { - k1, - pr, - id_unique_hash - }) - - return { - status: 200, - body: result, - headers: { - 'Content-Type': 'application/json' - } - } - } -} - -// Export types for external use -export * from './types.js' -export { WithdrawManager } from './managers/withdrawManager.js' diff --git a/src/extensions/withdraw/managers/withdrawManager.ts b/src/extensions/withdraw/managers/withdrawManager.ts deleted file mode 100644 index 5f76008e..00000000 --- a/src/extensions/withdraw/managers/withdrawManager.ts +++ /dev/null @@ -1,717 +0,0 @@ -/** - * Withdraw Link Manager - * - * Handles CRUD operations for withdraw links and processes withdrawals - */ - -import { - ExtensionContext, - ExtensionDatabase, - WithdrawLink, - Withdrawal, - CreateWithdrawLinkRequest, - UpdateWithdrawLinkRequest, - WithdrawLinkWithLnurl, - LnurlWithdrawResponse, - LnurlErrorResponse, - LnurlSuccessResponse, - LnurlCallbackParams -} from '../types.js' -import { - generateId, - generateK1, - generateUniqueHash, - generateUseHash, - verifyUseHash, - encodeLnurl, - buildLnurlUrl, - buildUniqueLnurlUrl, - buildCallbackUrl, - satsToMsats -} from '../utils/lnurl.js' - -/** - * Database row types - */ -interface WithdrawLinkRow { - id: string - application_id: string - title: string - description: string | null - min_withdrawable: number - max_withdrawable: number - uses: number - used: number - wait_time: number - unique_hash: string - k1: string - is_unique: number - uses_csv: string - open_time: number - creator_pubkey: string | null - webhook_url: string | null - webhook_headers: string | null - webhook_body: string | null - created_at: number - updated_at: number -} - -interface WithdrawalRow { - id: string - link_id: string - application_id: string - payment_hash: string - amount_sats: number - fee_sats: number - recipient_node: string | null - webhook_success: number | null - webhook_response: string | null - created_at: number -} - -/** - * Convert row to WithdrawLink - */ -function rowToLink(row: WithdrawLinkRow): WithdrawLink { - return { - id: row.id, - application_id: row.application_id, - title: row.title, - description: row.description || undefined, - min_withdrawable: row.min_withdrawable, - max_withdrawable: row.max_withdrawable, - uses: row.uses, - used: row.used, - wait_time: row.wait_time, - unique_hash: row.unique_hash, - k1: row.k1, - is_unique: row.is_unique === 1, - uses_csv: row.uses_csv, - open_time: row.open_time, - creator_pubkey: row.creator_pubkey || undefined, - webhook_url: row.webhook_url || undefined, - webhook_headers: row.webhook_headers || undefined, - webhook_body: row.webhook_body || undefined, - created_at: row.created_at, - updated_at: row.updated_at - } -} - -/** - * Convert row to Withdrawal - */ -function rowToWithdrawal(row: WithdrawalRow): Withdrawal { - return { - id: row.id, - link_id: row.link_id, - application_id: row.application_id, - payment_hash: row.payment_hash, - amount_sats: row.amount_sats, - fee_sats: row.fee_sats, - recipient_node: row.recipient_node || undefined, - webhook_success: row.webhook_success === null ? undefined : row.webhook_success === 1, - webhook_response: row.webhook_response || undefined, - created_at: row.created_at - } -} - -/** - * WithdrawManager - Handles withdraw link operations - */ -export class WithdrawManager { - private baseUrl: string = '' - - constructor( - private db: ExtensionDatabase, - private ctx: ExtensionContext - ) {} - - /** - * Set the base URL for LNURL generation - */ - setBaseUrl(url: string): void { - this.baseUrl = url.replace(/\/$/, '') - } - - /** - * Add LNURL to a withdraw link - */ - private addLnurl(link: WithdrawLink): WithdrawLinkWithLnurl { - const lnurlUrl = buildLnurlUrl(this.baseUrl, link.unique_hash) - return { - ...link, - lnurl: encodeLnurl(lnurlUrl), - lnurl_url: lnurlUrl - } - } - - // ========================================================================= - // CRUD Operations - // ========================================================================= - - /** - * Create a new withdraw link - */ - async create(applicationId: string, req: CreateWithdrawLinkRequest, creatorPubkey?: string): Promise { - // Validation - if (req.uses < 1 || req.uses > 250) { - throw new Error('Uses must be between 1 and 250') - } - if (req.min_withdrawable < 1) { - throw new Error('Min withdrawable must be at least 1 sat') - } - if (req.max_withdrawable < req.min_withdrawable) { - throw new Error('Max withdrawable must be >= min withdrawable') - } - if (req.wait_time < 0) { - throw new Error('Wait time cannot be negative') - } - - // Validate webhook JSON if provided - if (req.webhook_headers) { - try { - JSON.parse(req.webhook_headers) - } catch { - throw new Error('webhook_headers must be valid JSON') - } - } - if (req.webhook_body) { - try { - JSON.parse(req.webhook_body) - } catch { - throw new Error('webhook_body must be valid JSON') - } - } - - const now = Math.floor(Date.now() / 1000) - const id = generateId() - const usesCsv = Array.from({ length: req.uses }, (_, i) => String(i)).join(',') - - const link: WithdrawLink = { - id, - application_id: applicationId, - title: req.title.trim(), - description: req.description?.trim(), - min_withdrawable: req.min_withdrawable, - max_withdrawable: req.max_withdrawable, - uses: req.uses, - used: 0, - wait_time: req.wait_time, - unique_hash: generateUniqueHash(), - k1: generateK1(), - is_unique: req.is_unique || false, - uses_csv: usesCsv, - open_time: now, - creator_pubkey: creatorPubkey, - webhook_url: req.webhook_url, - webhook_headers: req.webhook_headers, - webhook_body: req.webhook_body, - created_at: now, - updated_at: now - } - - await this.db.execute( - `INSERT INTO withdraw_links ( - id, application_id, title, description, - min_withdrawable, max_withdrawable, uses, used, wait_time, - unique_hash, k1, is_unique, uses_csv, open_time, - creator_pubkey, - webhook_url, webhook_headers, webhook_body, - created_at, updated_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - [ - link.id, link.application_id, link.title, link.description || null, - link.min_withdrawable, link.max_withdrawable, link.uses, link.used, link.wait_time, - link.unique_hash, link.k1, link.is_unique ? 1 : 0, link.uses_csv, link.open_time, - link.creator_pubkey || null, - link.webhook_url || null, link.webhook_headers || null, link.webhook_body || null, - link.created_at, link.updated_at - ] - ) - - return this.addLnurl(link) - } - - /** - * Create multiple vouchers (single-use withdraw links) - */ - async createVouchers( - applicationId: string, - title: string, - amount: number, - count: number, - description?: string - ): Promise { - if (count < 1 || count > 100) { - throw new Error('Count must be between 1 and 100') - } - if (amount < 1) { - throw new Error('Amount must be at least 1 sat') - } - - const vouchers: WithdrawLinkWithLnurl[] = [] - - for (let i = 0; i < count; i++) { - const voucher = await this.create(applicationId, { - title: `${title} #${i + 1}`, - description, - min_withdrawable: amount, - max_withdrawable: amount, - uses: 1, - wait_time: 0, - is_unique: false - }) - vouchers.push(voucher) - } - - return vouchers - } - - /** - * Get a withdraw link by ID - */ - async get(id: string, applicationId: string): Promise { - const rows = await this.db.query( - 'SELECT * FROM withdraw_links WHERE id = ? AND application_id = ?', - [id, applicationId] - ) - - if (rows.length === 0) return null - return this.addLnurl(rowToLink(rows[0])) - } - - /** - * Get a withdraw link by unique hash (for LNURL) - */ - async getByHash(uniqueHash: string): Promise { - const rows = await this.db.query( - 'SELECT * FROM withdraw_links WHERE unique_hash = ?', - [uniqueHash] - ) - - if (rows.length === 0) return null - return rowToLink(rows[0]) - } - - /** - * List withdraw links for an application - */ - async list( - applicationId: string, - includeSpent: boolean = false, - limit?: number, - offset?: number - ): Promise { - let sql = 'SELECT * FROM withdraw_links WHERE application_id = ?' - const params: any[] = [applicationId] - - if (!includeSpent) { - sql += ' AND used < uses' - } - - sql += ' ORDER BY created_at DESC' - - if (limit) { - sql += ' LIMIT ?' - params.push(limit) - if (offset) { - sql += ' OFFSET ?' - params.push(offset) - } - } - - const rows = await this.db.query(sql, params) - return rows.map(row => this.addLnurl(rowToLink(row))) - } - - /** - * Update a withdraw link - */ - async update( - id: string, - applicationId: string, - req: UpdateWithdrawLinkRequest - ): Promise { - const existing = await this.get(id, applicationId) - if (!existing) return null - - // Validation - if (req.uses !== undefined) { - if (req.uses < 1 || req.uses > 250) { - throw new Error('Uses must be between 1 and 250') - } - if (req.uses < existing.used) { - throw new Error('Cannot reduce uses below current used count') - } - } - - const minWith = req.min_withdrawable ?? existing.min_withdrawable - const maxWith = req.max_withdrawable ?? existing.max_withdrawable - - if (minWith < 1) { - throw new Error('Min withdrawable must be at least 1 sat') - } - if (maxWith < minWith) { - throw new Error('Max withdrawable must be >= min withdrawable') - } - - // Handle uses change - let usesCsv = existing.uses_csv - const newUses = req.uses ?? existing.uses - if (newUses !== existing.uses) { - const currentUses = usesCsv.split(',').filter(u => u !== '') - if (newUses > existing.uses) { - // Add more uses - const lastNum = currentUses.length > 0 ? parseInt(currentUses[currentUses.length - 1], 10) : -1 - for (let i = lastNum + 1; currentUses.length < (newUses - existing.used); i++) { - currentUses.push(String(i)) - } - } else { - // Remove uses (keep first N) - usesCsv = currentUses.slice(0, newUses - existing.used).join(',') - } - usesCsv = currentUses.join(',') - } - - const now = Math.floor(Date.now() / 1000) - - await this.db.execute( - `UPDATE withdraw_links SET - title = ?, description = ?, - min_withdrawable = ?, max_withdrawable = ?, - uses = ?, wait_time = ?, is_unique = ?, uses_csv = ?, - webhook_url = ?, webhook_headers = ?, webhook_body = ?, - updated_at = ? - WHERE id = ? AND application_id = ?`, - [ - req.title ?? existing.title, - req.description ?? existing.description ?? null, - minWith, maxWith, - newUses, - req.wait_time ?? existing.wait_time, - (req.is_unique ?? existing.is_unique) ? 1 : 0, - usesCsv, - req.webhook_url ?? existing.webhook_url ?? null, - req.webhook_headers ?? existing.webhook_headers ?? null, - req.webhook_body ?? existing.webhook_body ?? null, - now, - id, applicationId - ] - ) - - return this.get(id, applicationId) - } - - /** - * Delete a withdraw link - */ - async delete(id: string, applicationId: string): Promise { - const result = await this.db.execute( - 'DELETE FROM withdraw_links WHERE id = ? AND application_id = ?', - [id, applicationId] - ) - return (result.changes || 0) > 0 - } - - // ========================================================================= - // LNURL Protocol Handlers - // ========================================================================= - - /** - * Handle initial LNURL request (user scans QR) - * Returns withdraw parameters - */ - async handleLnurlRequest( - uniqueHash: string, - idUniqueHash?: string - ): Promise { - const link = await this.getByHash(uniqueHash) - - if (!link) { - return { status: 'ERROR', reason: 'Withdraw link does not exist.' } - } - - if (link.used >= link.uses) { - return { status: 'ERROR', reason: 'Withdraw link is spent.' } - } - - // For unique links, require id_unique_hash - if (link.is_unique && !idUniqueHash) { - return { status: 'ERROR', reason: 'This link requires a unique hash.' } - } - - // Verify unique hash if provided - if (idUniqueHash) { - const useNumber = verifyUseHash(link.id, link.unique_hash, link.uses_csv, idUniqueHash) - if (!useNumber) { - return { status: 'ERROR', reason: 'Invalid unique hash.' } - } - } - - const callbackUrl = buildCallbackUrl(this.baseUrl, link.unique_hash) - - return { - tag: 'withdrawRequest', - callback: idUniqueHash ? `${callbackUrl}?id_unique_hash=${idUniqueHash}` : callbackUrl, - k1: link.k1, - minWithdrawable: satsToMsats(link.min_withdrawable), - maxWithdrawable: satsToMsats(link.max_withdrawable), - defaultDescription: link.title - } - } - - /** - * Handle LNURL callback (user submits invoice) - * Pays the invoice and records the withdrawal - */ - async handleLnurlCallback( - uniqueHash: string, - params: LnurlCallbackParams - ): Promise { - const link = await this.getByHash(uniqueHash) - - if (!link) { - return { status: 'ERROR', reason: 'Withdraw link not found.' } - } - - if (link.used >= link.uses) { - return { status: 'ERROR', reason: 'Withdraw link is spent.' } - } - - if (link.k1 !== params.k1) { - return { status: 'ERROR', reason: 'Invalid k1.' } - } - - // Check wait time - const now = Math.floor(Date.now() / 1000) - if (now < link.open_time) { - const waitSecs = link.open_time - now - return { status: 'ERROR', reason: `Please wait ${waitSecs} seconds.` } - } - - // For unique links, verify and consume the use hash - if (params.id_unique_hash) { - const useNumber = verifyUseHash(link.id, link.unique_hash, link.uses_csv, params.id_unique_hash) - if (!useNumber) { - return { status: 'ERROR', reason: 'Invalid unique hash.' } - } - } else if (link.is_unique) { - return { status: 'ERROR', reason: 'Unique hash required.' } - } - - // Prevent double-spending with hash check - try { - await this.createHashCheck(params.id_unique_hash || uniqueHash, params.k1) - } catch { - return { status: 'ERROR', reason: 'Withdrawal already in progress.' } - } - - try { - // Pay the invoice from the creator's balance (if created via Nostr RPC) - const payment = await this.ctx.payInvoice( - link.application_id, - params.pr, - link.max_withdrawable, - link.creator_pubkey - ) - - // Record the withdrawal - await this.recordWithdrawal(link, payment.paymentHash, link.max_withdrawable, payment.feeSats) - - // Increment usage - await this.incrementUsage(link, params.id_unique_hash) - - // Clean up hash check - await this.deleteHashCheck(params.id_unique_hash || uniqueHash) - - // Dispatch webhook if configured - if (link.webhook_url) { - this.dispatchWebhook(link, payment.paymentHash, params.pr).catch(err => { - console.error('[Withdraw] Webhook error:', err) - }) - } - - return { status: 'OK' } - } catch (err: any) { - // Clean up hash check on failure - await this.deleteHashCheck(params.id_unique_hash || uniqueHash) - return { status: 'ERROR', reason: `Payment failed: ${err.message}` } - } - } - - // ========================================================================= - // Helper Methods - // ========================================================================= - - /** - * Increment link usage and update open_time - */ - private async incrementUsage(link: WithdrawLink, idUniqueHash?: string): Promise { - const now = Math.floor(Date.now() / 1000) - let usesCsv = link.uses_csv - - // Remove used hash from uses_csv if unique - if (idUniqueHash) { - const uses = usesCsv.split(',').filter(u => { - const hash = generateUseHash(link.id, link.unique_hash, u.trim()) - return hash !== idUniqueHash - }) - usesCsv = uses.join(',') - } - - await this.db.execute( - `UPDATE withdraw_links SET - used = used + 1, - open_time = ?, - uses_csv = ?, - updated_at = ? - WHERE id = ?`, - [now + link.wait_time, usesCsv, now, link.id] - ) - } - - /** - * Record a successful withdrawal - */ - private async recordWithdrawal( - link: WithdrawLink, - paymentHash: string, - amountSats: number, - feeSats: number - ): Promise { - const now = Math.floor(Date.now() / 1000) - - await this.db.execute( - `INSERT INTO withdrawals ( - id, link_id, application_id, - payment_hash, amount_sats, fee_sats, - created_at - ) VALUES (?, ?, ?, ?, ?, ?, ?)`, - [ - generateId(), - link.id, - link.application_id, - paymentHash, - amountSats, - feeSats, - now - ] - ) - } - - /** - * Create hash check to prevent double-spending - */ - private async createHashCheck(hash: string, k1: string): Promise { - const now = Math.floor(Date.now() / 1000) - await this.db.execute( - 'INSERT INTO hash_checks (hash, k1, created_at) VALUES (?, ?, ?)', - [hash, k1, now] - ) - } - - /** - * Delete hash check after completion - */ - private async deleteHashCheck(hash: string): Promise { - await this.db.execute('DELETE FROM hash_checks WHERE hash = ?', [hash]) - } - - /** - * List withdrawals - */ - async listWithdrawals( - applicationId: string, - linkId?: string, - limit?: number, - offset?: number - ): Promise { - let sql = 'SELECT * FROM withdrawals WHERE application_id = ?' - const params: any[] = [applicationId] - - if (linkId) { - sql += ' AND link_id = ?' - params.push(linkId) - } - - sql += ' ORDER BY created_at DESC' - - if (limit) { - sql += ' LIMIT ?' - params.push(limit) - if (offset) { - sql += ' OFFSET ?' - params.push(offset) - } - } - - const rows = await this.db.query(sql, params) - return rows.map(rowToWithdrawal) - } - - /** - * Get withdrawal stats for a link - */ - async getWithdrawalStats(linkId: string): Promise<{ total_sats: number; count: number }> { - const result = await this.db.query<{ total: number; count: number }>( - `SELECT COALESCE(SUM(amount_sats), 0) as total, COUNT(*) as count - FROM withdrawals WHERE link_id = ?`, - [linkId] - ) - return { - total_sats: result[0]?.total || 0, - count: result[0]?.count || 0 - } - } - - /** - * Dispatch webhook notification - */ - private async dispatchWebhook( - link: WithdrawLink, - paymentHash: string, - paymentRequest: string - ): Promise { - if (!link.webhook_url) return - - try { - const headers: Record = { - 'Content-Type': 'application/json' - } - - if (link.webhook_headers) { - Object.assign(headers, JSON.parse(link.webhook_headers)) - } - - const body = { - payment_hash: paymentHash, - payment_request: paymentRequest, - lnurlw: link.id, - body: link.webhook_body ? JSON.parse(link.webhook_body) : {} - } - - const response = await fetch(link.webhook_url, { - method: 'POST', - headers, - body: JSON.stringify(body) - }) - - // Update withdrawal record with webhook result - await this.db.execute( - `UPDATE withdrawals SET - webhook_success = ?, - webhook_response = ? - WHERE payment_hash = ?`, - [response.ok ? 1 : 0, await response.text(), paymentHash] - ) - } catch (err: any) { - await this.db.execute( - `UPDATE withdrawals SET - webhook_success = 0, - webhook_response = ? - WHERE payment_hash = ?`, - [err.message, paymentHash] - ) - } - } -} diff --git a/src/extensions/withdraw/migrations.ts b/src/extensions/withdraw/migrations.ts deleted file mode 100644 index 1625638a..00000000 --- a/src/extensions/withdraw/migrations.ts +++ /dev/null @@ -1,164 +0,0 @@ -/** - * LNURL-withdraw Extension Database Migrations - */ - -import { ExtensionDatabase } from '../types.js' - -export interface Migration { - version: number - name: string - up: (db: ExtensionDatabase) => Promise - down?: (db: ExtensionDatabase) => Promise -} - -export const migrations: Migration[] = [ - { - version: 1, - name: 'create_withdraw_links_table', - up: async (db: ExtensionDatabase) => { - await db.execute(` - CREATE TABLE IF NOT EXISTS withdraw_links ( - id TEXT PRIMARY KEY, - application_id TEXT NOT NULL, - - -- Display - title TEXT NOT NULL, - description TEXT, - - -- Amounts (sats) - min_withdrawable INTEGER NOT NULL, - max_withdrawable INTEGER NOT NULL, - - -- Usage limits - uses INTEGER NOT NULL DEFAULT 1, - used INTEGER NOT NULL DEFAULT 0, - wait_time INTEGER NOT NULL DEFAULT 0, - - -- Security - unique_hash TEXT NOT NULL UNIQUE, - k1 TEXT NOT NULL, - is_unique INTEGER NOT NULL DEFAULT 0, - uses_csv TEXT NOT NULL DEFAULT '', - - -- Rate limiting - open_time INTEGER NOT NULL DEFAULT 0, - - -- Webhooks - webhook_url TEXT, - webhook_headers TEXT, - webhook_body TEXT, - - -- Timestamps - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - ) - `) - - // Index for looking up by unique_hash (LNURL) - await db.execute(` - CREATE INDEX IF NOT EXISTS idx_withdraw_links_unique_hash - ON withdraw_links(unique_hash) - `) - - // Index for listing by application - await db.execute(` - CREATE INDEX IF NOT EXISTS idx_withdraw_links_application - ON withdraw_links(application_id, created_at DESC) - `) - } - }, - { - version: 2, - name: 'create_withdrawals_table', - up: async (db: ExtensionDatabase) => { - await db.execute(` - CREATE TABLE IF NOT EXISTS withdrawals ( - id TEXT PRIMARY KEY, - link_id TEXT NOT NULL, - application_id TEXT NOT NULL, - - -- Payment details - payment_hash TEXT NOT NULL, - amount_sats INTEGER NOT NULL, - fee_sats INTEGER NOT NULL DEFAULT 0, - - -- Recipient - recipient_node TEXT, - - -- Webhook result - webhook_success INTEGER, - webhook_response TEXT, - - -- Timestamp - created_at INTEGER NOT NULL, - - FOREIGN KEY (link_id) REFERENCES withdraw_links(id) ON DELETE CASCADE - ) - `) - - // Index for listing withdrawals by link - await db.execute(` - CREATE INDEX IF NOT EXISTS idx_withdrawals_link - ON withdrawals(link_id, created_at DESC) - `) - - // Index for looking up by payment hash - await db.execute(` - CREATE INDEX IF NOT EXISTS idx_withdrawals_payment_hash - ON withdrawals(payment_hash) - `) - } - }, - { - version: 3, - name: 'create_hash_checks_table', - up: async (db: ExtensionDatabase) => { - // Temporary table to prevent double-spending during payment processing - await db.execute(` - CREATE TABLE IF NOT EXISTS hash_checks ( - hash TEXT PRIMARY KEY, - k1 TEXT NOT NULL, - created_at INTEGER NOT NULL - ) - `) - } - }, - { - version: 4, - name: 'add_creator_pubkey_column', - up: async (db: ExtensionDatabase) => { - // Store the Nostr pubkey of the user who created the withdraw link - // so that when the LNURL callback fires, we debit the correct user's balance - await db.execute(` - ALTER TABLE withdraw_links ADD COLUMN creator_pubkey TEXT - `) - } - } -] - -/** - * Run all pending migrations - */ -export async function runMigrations(db: ExtensionDatabase): Promise { - // Get current version - const versionResult = await db.query<{ value: string }>( - `SELECT value FROM _extension_meta WHERE key = 'migration_version'` - ).catch(() => []) - - const currentVersion = versionResult.length > 0 ? parseInt(versionResult[0].value, 10) : 0 - - // Run pending migrations - for (const migration of migrations) { - if (migration.version > currentVersion) { - console.log(`[Withdraw] Running migration ${migration.version}: ${migration.name}`) - await migration.up(db) - - // Update version - await db.execute( - `INSERT INTO _extension_meta (key, value) VALUES ('migration_version', ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value`, - [String(migration.version)] - ) - } - } -} diff --git a/src/extensions/withdraw/types.ts b/src/extensions/withdraw/types.ts deleted file mode 100644 index 88d25f33..00000000 --- a/src/extensions/withdraw/types.ts +++ /dev/null @@ -1,264 +0,0 @@ -/** - * LNURL-withdraw Extension Types - * Implements LUD-03 (LNURL-withdraw) for Lightning.Pub - */ - -// Re-export base extension types -export { - Extension, - ExtensionInfo, - ExtensionContext, - ExtensionDatabase, - ApplicationInfo, - RpcMethodHandler -} from '../types.js' - -// ============================================================================ -// Core Data Types -// ============================================================================ - -/** - * A withdraw link that can be used to pull funds - */ -export interface WithdrawLink { - id: string - application_id: string - - // Display - title: string - description?: string - - // Amounts (in sats) - min_withdrawable: number - max_withdrawable: number - - // Usage limits - uses: number // Total allowed uses - used: number // Times used so far - wait_time: number // Seconds between uses - - // Security - unique_hash: string // For LNURL URL - k1: string // Challenge for callback - is_unique: boolean // Generate unique code per use - uses_csv: string // Comma-separated list of available use IDs - - // Rate limiting - open_time: number // Unix timestamp when next use is allowed - - // Creator identity (for Nostr RPC-created links) - creator_pubkey?: string // Nostr pubkey of the user who created this link - - // Webhook notifications - webhook_url?: string - webhook_headers?: string // JSON string - webhook_body?: string // JSON string - - // Timestamps - created_at: number - updated_at: number -} - -/** - * Withdrawal record - tracks each successful withdrawal - */ -export interface Withdrawal { - id: string - link_id: string - application_id: string - - // Payment details - payment_hash: string - amount_sats: number - fee_sats: number - - // Recipient (if known) - recipient_node?: string - - // Webhook result - webhook_success?: boolean - webhook_response?: string - - // Timestamp - created_at: number -} - -/** - * Hash check - prevents double-spending during payment - */ -export interface HashCheck { - hash: string - k1: string - created_at: number -} - -// ============================================================================ -// LNURL Protocol Types (LUD-03) -// ============================================================================ - -/** - * LNURL-withdraw response (first call) - * Returned when user scans the QR code - */ -export interface LnurlWithdrawResponse { - tag: 'withdrawRequest' - callback: string // URL to call with invoice - k1: string // Challenge - minWithdrawable: number // Millisats - maxWithdrawable: number // Millisats - defaultDescription: string -} - -/** - * LNURL error response - */ -export interface LnurlErrorResponse { - status: 'ERROR' - reason: string -} - -/** - * LNURL success response - */ -export interface LnurlSuccessResponse { - status: 'OK' -} - -// ============================================================================ -// RPC Request/Response Types -// ============================================================================ - -/** - * Create a new withdraw link - */ -export interface CreateWithdrawLinkRequest { - title: string - description?: string - min_withdrawable: number // sats - max_withdrawable: number // sats - uses: number // 1-250 - wait_time: number // seconds between uses - is_unique?: boolean // generate unique code per use - webhook_url?: string - webhook_headers?: string // JSON - webhook_body?: string // JSON -} - -/** - * Update an existing withdraw link - */ -export interface UpdateWithdrawLinkRequest { - id: string - title?: string - description?: string - min_withdrawable?: number - max_withdrawable?: number - uses?: number - wait_time?: number - is_unique?: boolean - webhook_url?: string - webhook_headers?: string - webhook_body?: string -} - -/** - * Get withdraw link by ID - */ -export interface GetWithdrawLinkRequest { - id: string -} - -/** - * List withdraw links - */ -export interface ListWithdrawLinksRequest { - include_spent?: boolean // Include fully used links - limit?: number - offset?: number -} - -/** - * Delete withdraw link - */ -export interface DeleteWithdrawLinkRequest { - id: string -} - -/** - * Create quick vouchers (batch of single-use links) - */ -export interface CreateVouchersRequest { - title: string - amount: number // sats per voucher - count: number // number of vouchers (1-100) - description?: string -} - -/** - * Get withdraw link with LNURL - */ -export interface WithdrawLinkWithLnurl extends WithdrawLink { - lnurl: string // bech32 encoded LNURL - lnurl_url: string // raw callback URL -} - -/** - * List withdrawals for a link - */ -export interface ListWithdrawalsRequest { - link_id?: string - limit?: number - offset?: number -} - -/** - * Withdraw link response with stats - */ -export interface WithdrawLinkResponse { - link: WithdrawLinkWithLnurl - total_withdrawn_sats: number - withdrawals_count: number -} - -/** - * Vouchers response - */ -export interface VouchersResponse { - vouchers: WithdrawLinkWithLnurl[] - total_amount_sats: number -} - -// ============================================================================ -// HTTP Handler Types -// ============================================================================ - -/** - * LNURL callback parameters - */ -export interface LnurlCallbackParams { - k1: string // Challenge from initial response - pr: string // Payment request (BOLT11 invoice) - id_unique_hash?: string // For unique links -} - -/** - * HTTP route handler - */ -export interface HttpRoute { - method: 'GET' | 'POST' - path: string - handler: (req: HttpRequest) => Promise -} - -export interface HttpRequest { - params: Record - query: Record - body?: any - headers: Record -} - -export interface HttpResponse { - status: number - body: any - headers?: Record -} diff --git a/src/extensions/withdraw/utils/lnurl.ts b/src/extensions/withdraw/utils/lnurl.ts deleted file mode 100644 index 96926c52..00000000 --- a/src/extensions/withdraw/utils/lnurl.ts +++ /dev/null @@ -1,131 +0,0 @@ -/** - * LNURL Encoding Utilities - * - * LNURL is a bech32-encoded URL with hrp "lnurl" - * See: https://github.com/lnurl/luds - */ - -import { bech32 } from 'bech32' -import crypto from 'crypto' - -/** - * Encode a URL as LNURL (bech32) - */ -export function encodeLnurl(url: string): string { - const words = bech32.toWords(Buffer.from(url, 'utf8')) - return bech32.encode('lnurl', words, 2000) // 2000 char limit for URLs -} - -/** - * Decode an LNURL to a URL - */ -export function decodeLnurl(lnurl: string): string { - const { prefix, words } = bech32.decode(lnurl, 2000) - if (prefix !== 'lnurl') { - throw new Error('Invalid LNURL prefix') - } - return Buffer.from(bech32.fromWords(words)).toString('utf8') -} - -/** - * Generate a URL-safe random ID - */ -export function generateId(length: number = 22): string { - const bytes = crypto.randomBytes(Math.ceil(length * 3 / 4)) - return bytes.toString('base64url').slice(0, length) -} - -/** - * Generate a k1 challenge (32 bytes hex) - */ -export function generateK1(): string { - return crypto.randomBytes(32).toString('hex') -} - -/** - * Generate a unique hash for a link - */ -export function generateUniqueHash(): string { - return generateId(32) -} - -/** - * Generate a unique hash for a specific use of a link - * This creates a deterministic hash based on link ID, unique_hash, and use number - */ -export function generateUseHash(linkId: string, uniqueHash: string, useNumber: string): string { - const data = `${linkId}${uniqueHash}${useNumber}` - return crypto.createHash('sha256').update(data).digest('hex').slice(0, 32) -} - -/** - * Verify a use hash matches one of the available uses - */ -export function verifyUseHash( - linkId: string, - uniqueHash: string, - usesCsv: string, - providedHash: string -): string | null { - const uses = usesCsv.split(',').filter(u => u.trim() !== '') - - for (const useNumber of uses) { - const expectedHash = generateUseHash(linkId, uniqueHash, useNumber.trim()) - if (expectedHash === providedHash) { - return useNumber.trim() - } - } - - return null -} - -/** - * Build the LNURL callback URL for a withdraw link - */ -export function buildLnurlUrl(baseUrl: string, uniqueHash: string): string { - // Remove trailing slash from baseUrl - const base = baseUrl.replace(/\/$/, '') - return `${base}/api/v1/lnurl/${uniqueHash}` -} - -/** - * Build the LNURL callback URL for a unique withdraw link - */ -export function buildUniqueLnurlUrl( - baseUrl: string, - uniqueHash: string, - useHash: string -): string { - const base = baseUrl.replace(/\/$/, '') - return `${base}/api/v1/lnurl/${uniqueHash}/${useHash}` -} - -/** - * Build the callback URL for the second step (where user sends invoice) - */ -export function buildCallbackUrl(baseUrl: string, uniqueHash: string): string { - const base = baseUrl.replace(/\/$/, '') - return `${base}/api/v1/lnurl/cb/${uniqueHash}` -} - -/** - * Sats to millisats - */ -export function satsToMsats(sats: number): number { - return sats * 1000 -} - -/** - * Millisats to sats - */ -export function msatsToSats(msats: number): number { - return Math.floor(msats / 1000) -} - -/** - * Validate a BOLT11 invoice (basic check) - */ -export function isValidBolt11(invoice: string): boolean { - const lower = invoice.toLowerCase() - return lower.startsWith('lnbc') || lower.startsWith('lntb') || lower.startsWith('lnbcrt') -} diff --git a/src/index.ts b/src/index.ts index 5fbb21dc..fbe6802c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,4 @@ import 'dotenv/config' -import express from 'express' -import cors from 'cors' -import path from 'path' -import { fileURLToPath } from 'url' import NewServer from '../proto/autogenerated/ts/express_server.js' import GetServerMethods from './services/serverMethods/index.js' import serverOptions from './auth.js'; @@ -12,15 +8,9 @@ import { initMainHandler, initSettings } from './services/main/init.js'; import { nip19 } from 'nostr-tools' import { LoadStorageSettingsFromEnv } from './services/storage/index.js'; import { AppInfo } from './services/nostr/nostrPool.js'; -import { createExtensionLoader, ExtensionLoader } from './extensions/loader.js' -import { createMainHandlerAdapter } from './extensions/mainHandlerAdapter.js' -import type { HttpRoute } from './extensions/withdraw/types.js' //@ts-ignore const { nprofileEncode } = nip19 -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) - const start = async () => { const log = getLogger({}) @@ -35,42 +25,6 @@ const start = async () => { const { mainHandler, localProviderClient, wizard, adminManager } = keepOn const serverMethods = GetServerMethods(mainHandler) - - // Initialize extension system BEFORE nostrMiddleware so RPC methods are available - let extensionLoader: ExtensionLoader | null = null - const mainPort = settingsManager.getSettings().serviceSettings.servicePort - const extensionPort = mainPort + 1 - - // Extension routes run on a separate port (main port + 1) - // SERVICE_URL for extensions should point to this port for LNURL to work - // In production, use a reverse proxy to route /api/v1/lnurl/* to extension port - const extensionServiceUrl = process.env.EXTENSION_SERVICE_URL || `http://localhost:${extensionPort}` - - try { - log("initializing extension system") - const extensionsDir = path.join(__dirname, 'extensions') - const databaseDir = path.join(__dirname, '..', 'data', 'extensions') - - const mainHandlerAdapter = createMainHandlerAdapter(mainHandler) - extensionLoader = createExtensionLoader( - { extensionsDir, databaseDir }, - mainHandlerAdapter - ) - - await extensionLoader.loadAll() - log(`loaded ${extensionLoader.getAllExtensions().length} extension(s)`) - - // Set base URL for LNURL generation on withdraw extension - const withdrawExt = extensionLoader.getExtension('withdraw') - if (withdrawExt && withdrawExt.instance && 'setBaseUrl' in withdrawExt.instance) { - (withdrawExt.instance as any).setBaseUrl(extensionServiceUrl) - log(`withdraw extension base URL set to ${extensionServiceUrl}`) - } - } catch (e) { - log(`extension system initialization failed: ${e}`) - } - - // Initialize nostr middleware with extension loader for RPC routing log("initializing nostr middleware") const relays = settingsManager.getSettings().nostrRelaySettings.relays const maxEventContentLength = settingsManager.getSettings().nostrRelaySettings.maxEventContentLength @@ -91,8 +45,7 @@ const start = async () => { { relays, maxEventContentLength, apps }, - (e, p) => mainHandler.liquidityProvider.onEvent(e, p), - { extensionLoader: extensionLoader || undefined } + (e, p) => mainHandler.liquidityProvider.onEvent(e, p) ) exitHandler(() => { Stop(); mainHandler.Stop() }) log("starting server") @@ -105,58 +58,8 @@ const start = async () => { wizard.AddConnectInfo(appNprofile, relays) } adminManager.setAppNprofile(appNprofile) - - // Create Express app for extension HTTP routes - const extensionApp = express() - extensionApp.use(cors()) // Enable CORS for all origins (ATM apps, wallets, etc.) - extensionApp.use(express.json()) - - // Mount extension HTTP routes - if (extensionLoader) { - for (const ext of extensionLoader.getAllExtensions()) { - if (ext.status === 'ready' && 'getHttpRoutes' in ext.instance) { - const routes = (ext.instance as any).getHttpRoutes() as HttpRoute[] - for (const route of routes) { - log(`mounting extension route: ${route.method} ${route.path}`) - const handler = async (req: express.Request, res: express.Response) => { - try { - const httpReq = { - params: req.params, - query: req.query as Record, - body: req.body, - headers: req.headers as Record - } - const result = await route.handler(httpReq) - res.status(result.status) - if (result.headers) { - for (const [key, value] of Object.entries(result.headers)) { - res.setHeader(key, value) - } - } - res.json(result.body) - } catch (e: any) { - log(`extension route error: ${e.message}`) - res.status(500).json({ status: 'ERROR', reason: e.message }) - } - } - if (route.method === 'GET') { - extensionApp.get(route.path, handler) - } else if (route.method === 'POST') { - extensionApp.post(route.path, handler) - } - } - } - } - } - - // Start extension routes server - extensionApp.listen(extensionPort, () => { - log(`extension HTTP routes listening on port ${extensionPort}`) - }) - - // Start main proto server const Server = NewServer(serverMethods, serverOptions(mainHandler)) - Server.Listen(mainPort) + Server.Listen(settingsManager.getSettings().serviceSettings.servicePort) } start() diff --git a/src/nostrMiddleware.ts b/src/nostrMiddleware.ts index ed9ef993..250543c7 100644 --- a/src/nostrMiddleware.ts +++ b/src/nostrMiddleware.ts @@ -5,15 +5,9 @@ import * as Types from '../proto/autogenerated/ts/types.js' import NewNostrTransport, { NostrRequest } from '../proto/autogenerated/ts/nostr_transport.js'; import { ERROR, getLogger } from "./services/helpers/logger.js"; import { NdebitData, NofferData, NmanageRequest } from "@shocknet/clink-sdk"; -import type { ExtensionLoader } from "./extensions/loader.js" type ExportedCalls = { Stop: () => void, Send: NostrSend, Ping: () => Promise, Reset: (settings: NostrSettings) => void } type ClientEventCallback = (e: { requestId: string }, fromPub: string) => void - -export type NostrMiddlewareOptions = { - extensionLoader?: ExtensionLoader -} - -export default (serverMethods: Types.ServerMethods, mainHandler: Main, nostrSettings: NostrSettings, onClientEvent: ClientEventCallback, options?: NostrMiddlewareOptions): ExportedCalls => { +export default (serverMethods: Types.ServerMethods, mainHandler: Main, nostrSettings: NostrSettings, onClientEvent: ClientEventCallback): ExportedCalls => { const log = getLogger({}) const nostrTransport = NewNostrTransport(serverMethods, { NostrUserAuthGuard: async (appId, pub) => { @@ -108,31 +102,6 @@ export default (serverMethods: Types.ServerMethods, mainHandler: Main, nostrSett log(ERROR, "authIdentifier does not match", j.authIdentifier || "--", event.pub) return } - - // Check if this is an extension RPC method - const extensionLoader = options?.extensionLoader - if (extensionLoader && j.rpcName && extensionLoader.hasMethod(j.rpcName)) { - // Route to extension - log(`[Nostr] Routing to extension method: ${j.rpcName}`) - extensionLoader.callMethod(j.rpcName, j.body || {}, event.appId, event.pub) - .then(result => { - const response = { status: 'OK', requestId: j.requestId, ...result } - nostr.Send( - { type: 'app', appId: event.appId }, - { type: 'content', pub: event.pub, content: JSON.stringify(response) } - ) - }) - .catch(err => { - log(ERROR, `Extension method ${j.rpcName} failed:`, err.message) - const response = { status: 'ERROR', requestId: j.requestId, reason: err.message } - nostr.Send( - { type: 'app', appId: event.appId }, - { type: 'content', pub: event.pub, content: JSON.stringify(response) } - ) - }) - return - } - nostrTransport({ ...j, appId: event.appId }, res => { nostr.Send({ type: 'app', appId: event.appId }, { type: 'content', pub: event.pub, content: JSON.stringify({ ...res, requestId: j.requestId }) }) }, event.startAtNano, event.startAtMs) @@ -143,7 +112,7 @@ export default (serverMethods: Types.ServerMethods, mainHandler: Main, nostrSett return { Stop: () => { mainHandler.adminManager.setNostrConnected(false); return nostr.Stop }, - Send: async (...args) => nostr.Send(...args), + Send: (...args) => nostr.Send(...args), Ping: () => nostr.Ping(), Reset: (settings: NostrSettings) => nostr.Reset(settings) } diff --git a/src/services/lnd/lnd.ts b/src/services/lnd/lnd.ts index ce19eae5..fb3815dd 100644 --- a/src/services/lnd/lnd.ts +++ b/src/services/lnd/lnd.ts @@ -142,20 +142,15 @@ export default class { return new Promise((res, rej) => { const interval = setInterval(async () => { try { - const info = await this.GetInfo() - if (!info.syncedToChain || !info.syncedToGraph) { - this.log("LND responding but not synced yet, waiting...") - return - } + await this.GetInfo() clearInterval(interval) this.ready = true res() } catch (err) { this.log(INFO, "LND is not ready yet, will try again in 1 second") - } - if (Date.now() - now > 1000 * 60 * 10) { - clearInterval(interval) - rej(new Error("LND not synced after 10 minutes")) + if (Date.now() - now > 1000 * 60) { + rej(new Error("LND not ready after 1 minute")) + } } }, 1000) }) diff --git a/src/services/lnd/payInvoiceReq.ts b/src/services/lnd/payInvoiceReq.ts index 3ae28c30..3b90dd3d 100644 --- a/src/services/lnd/payInvoiceReq.ts +++ b/src/services/lnd/payInvoiceReq.ts @@ -9,7 +9,7 @@ export const PayInvoiceReq = (invoice: string, amount: number, feeLimit: number) maxParts: 3, timeoutSeconds: 50, - allowSelfPayment: true, + allowSelfPayment: false, amp: false, amtMsat: 0n, cltvLimit: 0, diff --git a/src/services/main/applicationManager.ts b/src/services/main/applicationManager.ts index 0f186e4c..d118c66c 100644 --- a/src/services/main/applicationManager.ts +++ b/src/services/main/applicationManager.ts @@ -241,8 +241,6 @@ export default class { const paid = await this.paymentManager.PayInvoice(appUser.user.user_id, req, app, { ack: pendingOp => { this.notifyAppUserPayment(appUser, pendingOp) } }) - // Refresh appUser balance from DB so notification has accurate latest_balance - appUser.user.balance_sats = paid.latest_balance this.notifyAppUserPayment(appUser, paid.operation) getLogger({ appName: app.name })(appUser.identifier, "invoice paid", paid.amount_paid, "sats") return paid diff --git a/src/services/main/debitManager.ts b/src/services/main/debitManager.ts index 53375217..28579d31 100644 --- a/src/services/main/debitManager.ts +++ b/src/services/main/debitManager.ts @@ -153,14 +153,13 @@ export class DebitManager { } notifyPaymentSuccess = (debitRes: NdebitSuccess, event: { pub: string, id: string, appId: string }) => { - this.logger("✅ [DEBIT REQUEST] Payment successful, sending OK response to", event.pub.slice(0, 16) + "...", "for event", event.id.slice(0, 16) + "...") this.sendDebitResponse(debitRes, event) } sendDebitResponse = (debitRes: NdebitFailure | NdebitSuccess, event: { pub: string, id: string, appId: string }) => { - this.logger("📤 [DEBIT RESPONSE] Sending Kind 21002 response:", JSON.stringify(debitRes), "to", event.pub.slice(0, 16) + "...") const e = newNdebitResponse(JSON.stringify(debitRes), event) this.storage.NostrSender().Send({ type: 'app', appId: event.appId }, { type: 'event', event: e, encrypt: { toPub: event.pub } }) + } payNdebitInvoice = async (event: NostrEvent, pointerdata: NdebitData): Promise => { diff --git a/src/services/main/watchdog.ts b/src/services/main/watchdog.ts index 3c12b676..d9d585ba 100644 --- a/src/services/main/watchdog.ts +++ b/src/services/main/watchdog.ts @@ -238,17 +238,13 @@ export class Watchdog { const knownMaxIndex = Math.max(maxFromDb, this.latestPaymentIndexOffset) const newLatest = await this.lnd.GetLatestPaymentIndex(knownMaxIndex) const historyMismatch = newLatest > knownMaxIndex - if (historyMismatch) { - this.log("Payment index advanced from", knownMaxIndex, "to", newLatest, "- updating offset (likely LND restart or external payment)") - this.latestPaymentIndexOffset = newLatest - } const deny = await this.checkBalanceUpdate(deltaLnd, deltaUsers) + if (historyMismatch) { + getLogger({ component: 'bark' })("History mismatch detected in absolute update, locking outgoing operations") + this.lnd.LockOutgoingOperations() + return + } if (deny) { - if (historyMismatch) { - getLogger({ component: 'bark' })("Balance mismatch with unexpected payment history, locking outgoing operations") - this.lnd.LockOutgoingOperations() - return - } this.log("Balance mismatch detected in absolute update, but history is ok") } this.lnd.UnlockOutgoingOperations() diff --git a/src/services/nostr/handler.ts b/src/services/nostr/handler.ts index b9ecfe70..d1fa46ec 100644 --- a/src/services/nostr/handler.ts +++ b/src/services/nostr/handler.ts @@ -132,12 +132,12 @@ const handleNostrSettings = (settings: NostrSettings) => { send(event) }) } */ -const sendToNostr: NostrSend = async (initiator, data, relays) => { +const sendToNostr: NostrSend = (initiator, data, relays) => { if (!subProcessHandler) { getLogger({ component: "nostrMiddleware" })(ERROR, "nostr was not initialized") return } - await subProcessHandler.Send(initiator, data, relays) + subProcessHandler.Send(initiator, data, relays) } send({ type: 'ready' }) diff --git a/src/services/nostr/nip44v1.ts b/src/services/nostr/nip44v1.ts index 1eb18046..0f37f620 100644 --- a/src/services/nostr/nip44v1.ts +++ b/src/services/nostr/nip44v1.ts @@ -1,14 +1,14 @@ -import { base64, hex } from "@scure/base"; +import { base64 } from "@scure/base"; import { randomBytes } from "@noble/hashes/utils"; import { streamXOR as xchacha20 } from "@stablelib/xchacha20"; -import { secp256k1 } from "@noble/curves/secp256k1.js"; +import { secp256k1 } from "@noble/curves/secp256k1"; import { sha256 } from "@noble/hashes/sha256"; export type EncryptedData = { ciphertext: Uint8Array; nonce: Uint8Array; } export const getSharedSecret = (privateKey: string, publicKey: string) => { - const key = secp256k1.getSharedSecret(hex.decode(privateKey), hex.decode("02" + publicKey)); + const key = secp256k1.getSharedSecret(privateKey, "02" + publicKey); return sha256(key.slice(1, 33)); } diff --git a/src/services/nostr/nostrPool.ts b/src/services/nostr/nostrPool.ts index e766d25f..1d3c0e5e 100644 --- a/src/services/nostr/nostrPool.ts +++ b/src/services/nostr/nostrPool.ts @@ -16,7 +16,7 @@ export type SendDataContent = { type: "content", content: string, pub: string } export type SendDataEvent = { type: "event", event: UnsignedEvent, encrypt?: { toPub: string } } export type SendData = SendDataContent | SendDataEvent export type SendInitiator = { type: 'app', appId: string } | { type: 'client', clientId: string } -export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => Promise +export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => void export type LinkedProviderInfo = { pubkey: string, clientId: string, relayUrl: string } export type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string, provider?: LinkedProviderInfo } @@ -203,26 +203,21 @@ export class NostrPool { const signed = finalizeEvent(event, Buffer.from(keys.privateKey, 'hex')) let sent = false const log = getLogger({ appName: keys.name }) - this.log(`📤 Publishing Kind ${event.kind} event to ${relays.length} relay(s): ${relays.join(', ')}`) + // const r = relays ? relays : this.getServiceRelays() const pool = new SimplePool() - try { - await Promise.all(pool.publish(relays, signed).map(async p => { - try { - await p - sent = true - } catch (e: any) { - this.log(ERROR, `Failed to publish Kind ${event.kind} event:`, e.message || e) - log(e) - } - })) - if (!sent) { - this.log(ERROR, `Failed to send Kind ${event.kind} event to any relay`) - log("failed to send event") - } else { - this.log(`✅ Kind ${event.kind} event published successfully (id: ${signed.id.slice(0, 16)}...)`) + await Promise.all(pool.publish(relays, signed).map(async p => { + try { + await p + sent = true + } catch (e: any) { + console.log(e) + log(e) } - } finally { - pool.close(relays) + })) + if (!sent) { + log("failed to send event") + } else { + //log("sent event") } } diff --git a/src/services/nostr/sender.ts b/src/services/nostr/sender.ts index 8437b9af..1fd336a5 100644 --- a/src/services/nostr/sender.ts +++ b/src/services/nostr/sender.ts @@ -1,7 +1,7 @@ import { NostrSend, SendData, SendInitiator } from "./nostrPool.js" -import { ERROR, getLogger } from "../helpers/logger.js" +import { getLogger } from "../helpers/logger.js" export class NostrSender { - private _nostrSend: NostrSend = async () => { throw new Error('nostr send not initialized yet') } + private _nostrSend: NostrSend = () => { throw new Error('nostr send not initialized yet') } private isReady: boolean = false private onReadyCallbacks: (() => void)[] = [] private pendingSends: { initiator: SendInitiator, data: SendData, relays?: string[] | undefined }[] = [] @@ -12,12 +12,7 @@ export class NostrSender { this.isReady = true this.onReadyCallbacks.forEach(cb => cb()) this.onReadyCallbacks = [] - // Process pending sends with proper error handling - this.pendingSends.forEach(send => { - this._nostrSend(send.initiator, send.data, send.relays).catch(e => { - this.log(ERROR, "failed to send pending event", e.message || e) - }) - }) + this.pendingSends.forEach(send => this._nostrSend(send.initiator, send.data, send.relays)) this.pendingSends = [] } OnReady(callback: () => void) { @@ -27,16 +22,13 @@ export class NostrSender { this.onReadyCallbacks.push(callback) } } - Send(initiator: SendInitiator, data: SendData, relays?: string[] | undefined): void { + Send(initiator: SendInitiator, data: SendData, relays?: string[] | undefined) { if (!this.isReady) { this.log("tried to send before nostr was ready, caching request") this.pendingSends.push({ initiator, data, relays }) return } - // Fire and forget but log errors - this._nostrSend(initiator, data, relays).catch(e => { - this.log(ERROR, "failed to send event", e.message || e) - }) + this._nostrSend(initiator, data, relays) } IsReady() { return this.isReady diff --git a/src/services/storage/tlv/tlvFilesStorageProcessor.ts b/src/services/storage/tlv/tlvFilesStorageProcessor.ts index caccb949..2b4189e4 100644 --- a/src/services/storage/tlv/tlvFilesStorageProcessor.ts +++ b/src/services/storage/tlv/tlvFilesStorageProcessor.ts @@ -126,7 +126,7 @@ class TlvFilesStorageProcessor { throw new Error('Unknown metric type: ' + t) } }) - this.wrtc.attachNostrSend(async (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => { + this.wrtc.attachNostrSend((initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => { this.sendResponse({ success: true, type: 'nostrSend', diff --git a/src/services/webRTC/index.ts b/src/services/webRTC/index.ts index a2cc90af..8ee8d884 100644 --- a/src/services/webRTC/index.ts +++ b/src/services/webRTC/index.ts @@ -27,11 +27,11 @@ export default class webRTC { attachNostrSend(f: NostrSend) { this._nostrSend = f } - private nostrSend: NostrSend = async (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => { + private nostrSend: NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => { if (!this._nostrSend) { throw new Error("No nostrSend attached") } - await this._nostrSend(initiator, data, relays) + this._nostrSend(initiator, data, relays) } private sendCandidate = (u: WebRtcUserInfo, candidate: string) => {