diff --git a/package-lock.json b/package-lock.json index 5efe251d..70eff895 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { - "name": "SHOCKWALLET", + "name": "shockwallet", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "SHOCKWALLET", + "name": "shockwallet", "version": "0.0.1", "dependencies": { "@capacitor-mlkit/barcode-scanning": "^5.4.0", "@capacitor/android": "5.4.0", "@capacitor/app": "5.0.6", "@capacitor/browser": "^5.2.0", - "@capacitor/camera": "^5.0.7", + "@capacitor/camera": "^5.0.10", "@capacitor/clipboard": "^5.0.6", "@capacitor/core": "5.7.8", "@capacitor/filesystem": "^5.1.4", @@ -25,8 +25,8 @@ "@gandlaf21/bolt11-decode": "^3.0.6", "@ionic-native/camera": "^5.36.0", "@ionic/pwa-elements": "^3.2.2", - "@ionic/react": "^7.0.0", - "@ionic/react-router": "^7.0.0", + "@ionic/react": "^8.3.0", + "@ionic/react-router": "^8.3.0", "@noble/curves": "^1.5.0", "@noble/hashes": "^1.5.0", "@noble/secp256k1": "^2.0.0", @@ -76,7 +76,7 @@ "reactjs-qr-reader": "^1.1.0", "sortablejs": "^1.15.1", "styled-components": "^6.0.8", - "uuid": "^9.0.1" + "uuid": "^10.0.0" }, "devDependencies": { "@capacitor/assets": "^3.0.5", @@ -87,7 +87,7 @@ "@types/deep-diff": "^1.0.5", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", - "@types/uuid": "^9.0.7", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", "@vitejs/plugin-legacy": "^4.0.2", @@ -96,12 +96,13 @@ "eslint": "^8.56.0", "eslint-plugin-cypress": "^2.15.1", "eslint-plugin-react": "^7.32.2", - "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-hooks": "^4.6.2", "jsdom": "^22.1.0", "sass": "^1.67.0", "typescript": "^5.3.3", "vite": "^4.3.9", "vite-plugin-eslint": "^1.8.1", + "vite-plugin-pwa": "^0.20.5", "vitest": "^0.32.2" } }, @@ -213,86 +214,42 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", - "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -318,15 +275,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -360,15 +316,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -533,30 +488,28 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -625,13 +578,13 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -664,30 +617,27 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -708,29 +658,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", - "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -740,7 +688,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -752,7 +699,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -766,7 +712,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -774,15 +719,16 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -2105,35 +2051,30 @@ "license": "MIT" }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2142,14 +2083,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2253,10 +2193,9 @@ } }, "node_modules/@capacitor/camera": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@capacitor/camera/-/camera-5.0.8.tgz", - "integrity": "sha512-V9kuBJV4s2AEFMiUiB5vpPD1qdfKRq/iFQ9euntuUYP+bOHQwGnwuERsQd48PoLUPV1up/08J8tJwGxMkDvPTQ==", - "license": "MIT", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@capacitor/camera/-/camera-5.0.10.tgz", + "integrity": "sha512-DOLYjiaOdUQk8mtAAgliqVVJaGegC7VzV4Tk3j1rjXyuc8JeX5SJOfow4v0N+NYxyGMsEEtwNnVZ1B7yzxsrVg==", "peerDependencies": { "@capacitor/core": "^5.0.0" } @@ -2817,11 +2756,11 @@ } }, "node_modules/@ionic/core": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.7.3.tgz", - "integrity": "sha512-DSv6DPuiLU2MXsgDAXKFJW5OXxT7EyPy2jcQf03RcWooWeFryy979mqotPw7BgUuWt/fVGuz2tl3peAJGSqmDQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.3.0.tgz", + "integrity": "sha512-Yv/LA2OOsvdelhvVYKTNL+0AduKXO74DTdQ3lqS/NN512/wCNf2CVt8J62oCs25XOttLAy8RflDUN8joT3bO7A==", "dependencies": { - "@stencil/core": "^4.12.2", + "@stencil/core": "^4.19.2", "ionicons": "^7.2.2", "tslib": "^2.1.0" } @@ -2837,11 +2776,12 @@ } }, "node_modules/@ionic/react": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.7.3.tgz", - "integrity": "sha512-b8jLpqv4dZ9nB9zoxhe0KR1Wk9bWMQ3UXQcOPu20+zYrxExwPqpLJ93LI0bU4F7ellduMjsakvELY486FeRrXw==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.3.0.tgz", + "integrity": "sha512-r343GdjjQENM7otokpj7HKUzArXv7/+2+gsO4stiDE9h24Xs/wlgv5PDrvAB4sE8n/QcV8Vg+glt/Gebm5ZDZQ==", "dependencies": { - "@ionic/core": "7.7.3", + "@ionic/core": "8.3.0", + "@stencil/react-output-target": "^0.6.0", "ionicons": "^7.0.0", "tslib": "*" }, @@ -2851,11 +2791,11 @@ } }, "node_modules/@ionic/react-router": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-7.7.3.tgz", - "integrity": "sha512-NmEk801pfbrqzyTAb5nLDWGseUzm7kMpUy0dMY6OU76tpuHrEFBCFkZYAlTJWqXhkGRj9cR0cMnFAhPtGeSCkg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.3.0.tgz", + "integrity": "sha512-9D12rHTlOBM9H/03u4cyFpJu66zQelHnnOh1JNkTM0qwrMYqyaG87sFpIHvwZ9/R/An0SzjoFBCCoT1SE0HzcA==", "dependencies": { - "@ionic/react": "7.7.3", + "@ionic/react": "8.3.0", "tslib": "*" }, "peerDependencies": { @@ -3126,15 +3066,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -3151,11 +3090,10 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -3165,7 +3103,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -3179,11 +3116,10 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3195,11 +3131,18 @@ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", "peer": true }, + "node_modules/@lit/react": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.5.tgz", + "integrity": "sha512-RSHhrcuSMa4vzhqiTenzXvtQ6QDq3hSPsnHHO3jaPmmvVFeoNNm4DHoQ0zLdKAUvY3wP3tTENSUf7xpyVfrDEA==", + "peerDependencies": { + "@types/react": "17 || 18" + } + }, "node_modules/@noble/ciphers": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", - "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -3253,7 +3196,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -3267,7 +3209,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -3277,7 +3218,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -3441,6 +3381,178 @@ } } }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-babel/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-babel/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@rollup/plugin-babel/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@rollup/plugin-replace/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/@rollup/plugin-replace/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", @@ -3598,9 +3710,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.3.tgz", - "integrity": "sha512-9XkE9i2aXPlApMNeq3tbVHKx0eAfDc7QGyIl6t5NMuQFTOGL5Xd1soF38d+hCIDpUoUUtY7jXWg+iFrlrMzQhg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.21.0.tgz", + "integrity": "sha512-v50lnVbzS8mpMSnEVxR+G75XpvxHKtkJaQrNPE8+/fF6Ppr5z4bcdcBhcP8LPfEW+4BZcic6VifMXRwTopc+kw==", "bin": { "stencil": "bin/stencil" }, @@ -3609,6 +3721,39 @@ "npm": ">=7.10.0" } }, + "node_modules/@stencil/react-output-target": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.6.0.tgz", + "integrity": "sha512-DV2Y1sbsRMY5z57Pdu6OedKTC76sjhXQZMiRJTh7PMRezSu2cj86VlntQ20FrR39Ms79UkxTbF/a/0+huwZB9Q==", + "dependencies": { + "@lit/react": "^1.0.4", + "ts-morph": "^22.0.0" + }, + "peerDependencies": { + "@stencil/core": ">=3 || >= 4.0.0-beta.0 || >= 4.0.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -3843,6 +3988,31 @@ "node": ">=10" } }, + "node_modules/@ts-morph/common": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.23.0.tgz", + "integrity": "sha512-m7Lllj9n/S6sOkCkRftpM7L24uvmfXQFedlW/4hENcuJH1HHm9u5EgxZb9uVjQSCGrbBWBkOGgcTxNg36r6ywA==", + "dependencies": { + "fast-glob": "^3.3.2", + "minimatch": "^9.0.3", + "mkdirp": "^3.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -4184,6 +4354,12 @@ "@types/react-router": "*" } }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, "node_modules/@types/responselike": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", @@ -4286,6 +4462,12 @@ "@types/jest": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", @@ -4293,9 +4475,9 @@ "license": "MIT" }, "node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, "node_modules/@types/yargs": { @@ -5280,7 +5462,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/bare-events": { @@ -5520,9 +5701,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -5538,12 +5719,11 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -5590,8 +5770,19 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "peer": true + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/cac": { "version": "6.7.14", @@ -5713,9 +5904,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001580", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz", - "integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==", + "version": "1.0.30001660", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", + "integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==", "dev": true, "funding": [ { @@ -5730,8 +5921,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/caseless": { "version": "0.12.0", @@ -6009,6 +6199,11 @@ "node": ">=6" } }, + "node_modules/code-block-writer": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.2.tgz", + "integrity": "sha512-XfXzAGiStXSmCIwrkdfvc7FS5Dtj8yelCtyOf2p2skCAfvLd6zu0rGzuS9NSCO3bq1JKpFZ7tbKdKlcd5occQA==" + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -6848,6 +7043,15 @@ "dev": true, "license": "MIT" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", @@ -7142,12 +7346,26 @@ "safer-buffer": "^2.1.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.645", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz", - "integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==", + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, - "license": "ISC" + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.23", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.23.tgz", + "integrity": "sha512-mBhODedOXg4v5QWwl21DjM5amzjmI1zw9EPrPK/5Wx7C8jt33bpZNrC7OhHUG3pxRtbLpr3W2dXT+Ph1SsfRZA==", + "dev": true }, "node_modules/elementtree": { "version": "0.1.7", @@ -7407,11 +7625,10 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -7539,11 +7756,10 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -7995,7 +8211,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -8022,11 +8237,16 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, "node_modules/fastq": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -8077,6 +8297,36 @@ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", "license": "MIT" }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -8354,6 +8604,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "node_modules/get-pkg-repo": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", @@ -8603,11 +8859,31 @@ "dev": true, "license": "MIT" }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -8616,6 +8892,18 @@ "node": ">= 6" } }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", @@ -9085,6 +9373,12 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -9304,6 +9598,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -9395,7 +9704,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9444,7 +9752,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -9480,6 +9787,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -9581,6 +9894,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-set": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", @@ -9776,6 +10098,36 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -9920,7 +10272,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -10028,6 +10379,15 @@ ], "license": "MIT" }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -10137,6 +10497,15 @@ "node": "> 0.8" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -10310,6 +10679,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -10640,7 +11015,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -10737,7 +11111,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10752,7 +11125,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -11040,11 +11412,10 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true, - "license": "MIT" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true }, "node_modules/nodemon": { "version": "2.0.22", @@ -11149,7 +11520,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", - "license": "Unlicense", "dependencies": { "@noble/ciphers": "0.2.0", "@noble/curves": "1.1.0", @@ -11171,7 +11541,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", - "license": "MIT", "dependencies": { "@noble/hashes": "1.3.1" }, @@ -11183,7 +11552,6 @@ "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": ">= 16" }, @@ -13909,6 +14277,11 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -14033,10 +14406,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "license": "ISC" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -14432,7 +14804,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -14468,6 +14839,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -15765,6 +16145,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -15861,7 +16250,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -15891,40 +16279,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -15952,7 +16306,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -16128,6 +16481,15 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -16399,6 +16761,12 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true + }, "node_modules/sortablejs": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz", @@ -16429,12 +16797,18 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -16680,6 +17054,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -16703,6 +17100,15 @@ "node": ">=4" } }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -16974,7 +17380,6 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -16992,8 +17397,7 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/text-decoder": { "version": "1.1.1", @@ -17077,6 +17481,45 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.6.tgz", + "integrity": "sha512-NbBoFBpqfcgd1tCiO8Lkfdk+xrA7mlLR9zgvZcZWQQwU63XAfUePyd6wZBaU93Hqw347lHnwFzttAkemHzzz4g==", + "dev": true, + "dependencies": { + "fdir": "^6.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", + "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinypool": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.5.0.tgz", @@ -17215,6 +17658,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-morph": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-22.0.0.tgz", + "integrity": "sha512-M9MqFGZREyeb5fTl6gNHKZLqBQA0TjA1lea+CR48R8EBTDuWrNqW6ccC5QvjNR4s6wDumD3LTCjOFSp9iwlzaw==", + "dependencies": { + "@ts-morph/common": "~0.23.0", + "code-block-writer": "^13.0.1" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -17564,10 +18016,20 @@ "node": ">=8" } }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -17583,10 +18045,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -17633,9 +18094,9 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -17778,6 +18239,65 @@ "vite": ">=2" } }, + "node_modules/vite-plugin-pwa": { + "version": "0.20.5", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.20.5.tgz", + "integrity": "sha512-aweuI/6G6n4C5Inn0vwHumElU/UEpNuO+9iZzwPZGTCH87TeZ6YFMrEY6ZUBQdIHHlhTsbMDryFARcSuOdsz9Q==", + "dev": true, + "dependencies": { + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^0.2.6", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } + } + }, + "node_modules/vite-plugin-pwa/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/vite-plugin-pwa/node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/vite/node_modules/postcss": { "version": "8.4.33", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", @@ -18096,6 +18616,304 @@ "dev": true, "license": "MIT" }, + "node_modules/workbox-background-sync": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.1.0.tgz", + "integrity": "sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.1.0.tgz", + "integrity": "sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-build": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.1.1.tgz", + "integrity": "sha512-WdkVdC70VMpf5NBCtNbiwdSZeKVuhTEd5PV3mAwpTQCGAB5XbOny1P9egEgNdetv4srAMmMKjvBk4RD58LpooA==", + "dev": true, + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.1.0", + "workbox-broadcast-update": "7.1.0", + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-google-analytics": "7.1.0", + "workbox-navigation-preload": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-range-requests": "7.1.0", + "workbox-recipes": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0", + "workbox-streams": "7.1.0", + "workbox-sw": "7.1.0", + "workbox-window": "7.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.1.0.tgz", + "integrity": "sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==", + "dev": true + }, + "node_modules/workbox-expiration": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.1.0.tgz", + "integrity": "sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.1.0.tgz", + "integrity": "sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==", + "dev": true, + "dependencies": { + "workbox-background-sync": "7.1.0", + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.1.0.tgz", + "integrity": "sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-precaching": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz", + "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.1.0.tgz", + "integrity": "sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-recipes": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.1.0.tgz", + "integrity": "sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==", + "dev": true, + "dependencies": { + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz", + "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz", + "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-streams": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.1.0.tgz", + "integrity": "sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==", + "dev": true, + "dependencies": { + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.1.0.tgz", + "integrity": "sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==", + "dev": true + }, + "node_modules/workbox-window": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.1.0.tgz", + "integrity": "sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==", + "dev": true, + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.1.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", diff --git a/package.json b/package.json index 640a925d..2624820d 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "@capacitor/android": "5.4.0", "@capacitor/app": "5.0.6", "@capacitor/browser": "^5.2.0", - "@capacitor/camera": "^5.0.7", + "@capacitor/camera": "^5.0.10", "@capacitor/clipboard": "^5.0.6", "@capacitor/core": "5.7.8", "@capacitor/filesystem": "^5.1.4", @@ -32,8 +32,8 @@ "@gandlaf21/bolt11-decode": "^3.0.6", "@ionic-native/camera": "^5.36.0", "@ionic/pwa-elements": "^3.2.2", - "@ionic/react": "^7.0.0", - "@ionic/react-router": "^7.0.0", + "@ionic/react": "^8.3.0", + "@ionic/react-router": "^8.3.0", "@noble/curves": "^1.5.0", "@noble/hashes": "^1.5.0", "@noble/secp256k1": "^2.0.0", @@ -83,7 +83,7 @@ "reactjs-qr-reader": "^1.1.0", "sortablejs": "^1.15.1", "styled-components": "^6.0.8", - "uuid": "^9.0.1" + "uuid": "^10.0.0" }, "devDependencies": { "@capacitor/assets": "^3.0.5", @@ -94,7 +94,7 @@ "@types/deep-diff": "^1.0.5", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", - "@types/uuid": "^9.0.7", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", "@vitejs/plugin-legacy": "^4.0.2", @@ -103,12 +103,13 @@ "eslint": "^8.56.0", "eslint-plugin-cypress": "^2.15.1", "eslint-plugin-react": "^7.32.2", - "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-hooks": "^4.6.2", "jsdom": "^22.1.0", "sass": "^1.67.0", "typescript": "^5.3.3", "vite": "^4.3.9", "vite-plugin-eslint": "^1.8.1", + "vite-plugin-pwa": "^0.20.5", "vitest": "^0.32.2" }, "description": "An Ionic project" diff --git a/public/service-worker.js b/public/service-worker.js index dc252b4d..72888fde 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -13,10 +13,18 @@ self.addEventListener('click', event => { }); self.addEventListener('fetch', event => { - event.respondWith( - caches.match(event.request) - .then(response => response || fetch(event.request)) - ); + if (event.request.mode === 'navigate') { + event.respondWith( + fetch(event.request).catch(() => { + return caches.match('/index.html'); + }) + ); + } else { + event.respondWith( + caches.match(event.request) + .then(response => response || fetch(event.request)) + ); + } }); self.addEventListener('beforeinstallprompt', event => { diff --git a/src/Api/bridge/autogenerated/ts/http_client.ts b/src/Api/bridge/autogenerated/ts/http_client.ts index 992a5d3f..c74210e8 100644 --- a/src/Api/bridge/autogenerated/ts/http_client.ts +++ b/src/Api/bridge/autogenerated/ts/http_client.ts @@ -6,6 +6,7 @@ export type ResultError = { status: 'ERROR', reason: string } export type ClientParams = { baseUrl: string retrieveGuestAuth: () => Promise + retrieveNostrAuth: () => Promise encryptCallback: (plain: any) => Promise decryptCallback: (encrypted: any) => Promise deviceId: string @@ -26,6 +27,20 @@ export default (params: ClientParams) => ({ } return { status: 'ERROR', reason: 'invalid response' } }, + GetOrCreateNofferName: async (request: Types.GetOrCreateNofferNameRequest): Promise => { + const auth = await params.retrieveNostrAuth() + if (auth === null) throw new Error('retrieveNostrAuth() returned null') + let finalRoute = '/api/v1/noffer/vanity' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.GetOrCreateNofferNameResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + } + return { status: 'ERROR', reason: 'invalid response' } + }, HandleLnurlPay: async (query: Types.HandleLnurlPay_Query): Promise => { const auth = await params.retrieveGuestAuth() if (auth === null) throw new Error('retrieveGuestAuth() returned null') @@ -42,6 +57,23 @@ export default (params: ClientParams) => ({ } return { status: 'ERROR', reason: 'invalid response' } }, + HandleLnurlPayUsername: async (query: Types.HandleLnurlPayUsername_Query, routeParams: Types.HandleLnurlPayUsername_RouteParams): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/lnurl_pay/:address_name' + finalRoute = finalRoute.replace(':address_name', routeParams['address_name']) + const q = (new URLSearchParams(query)).toString() + finalRoute = finalRoute + (q === '' ? '' : '?' + q) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.HandleLnurlPayResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + } + return { status: 'ERROR', reason: 'invalid response' } + }, HandleLnurlAddress: async (routeParams: Types.HandleLnurlAddress_RouteParams): Promise => { const auth = await params.retrieveGuestAuth() if (auth === null) throw new Error('retrieveGuestAuth() returned null') diff --git a/src/Api/bridge/autogenerated/ts/types.ts b/src/Api/bridge/autogenerated/ts/types.ts index 63073c79..d982f7e1 100644 --- a/src/Api/bridge/autogenerated/ts/types.ts +++ b/src/Api/bridge/autogenerated/ts/types.ts @@ -1,18 +1,27 @@ // This file was autogenerated from a .proto file, DO NOT EDIT! +import { Request } from 'express' export type ResultError = { status: 'ERROR', reason: string } export type RequestInfo = { rpcName: string, batch: boolean, nostr: boolean, batchSize: number } export type RequestStats = { startMs:number, start:bigint, parse: bigint, guard: bigint, validate: bigint, handle: bigint } export type RequestMetric = AuthContext & RequestInfo & RequestStats & { error?: string } export type GuestContext = { } -export type GuestMethodInputs = GetOrCreateVanityName_Input | HandleLnurlPay_Input | HandleLnurlAddress_Input -export type GuestMethodOutputs = GetOrCreateVanityName_Output | HandleLnurlPay_Output | HandleLnurlAddress_Output -export type AuthContext = GuestContext +export type GuestMethodInputs = GetOrCreateVanityName_Input | HandleLnurlPay_Input | HandleLnurlPayUsername_Input | HandleLnurlAddress_Input +export type GuestMethodOutputs = GetOrCreateVanityName_Output | HandleLnurlPay_Output | HandleLnurlPayUsername_Output | HandleLnurlAddress_Output +export type NostrContext = { + nostrPubKey: string +} +export type NostrMethodInputs = GetOrCreateNofferName_Input +export type NostrMethodOutputs = GetOrCreateNofferName_Output +export type AuthContext = GuestContext | NostrContext export type GetOrCreateVanityName_Input = {rpcName:'GetOrCreateVanityName', req: GetOrCreateVanityNameRequest} export type GetOrCreateVanityName_Output = ResultError | ({ status: 'OK' } & GetOrCreateVanityNameResponse) +export type GetOrCreateNofferName_Input = {rpcName:'GetOrCreateNofferName', req: GetOrCreateNofferNameRequest} +export type GetOrCreateNofferName_Output = ResultError | ({ status: 'OK' } & GetOrCreateNofferNameResponse) + export type HandleLnurlPay_Query = { k1?: string amount?: string @@ -20,6 +29,15 @@ export type HandleLnurlPay_Query = { export type HandleLnurlPay_Input = {rpcName:'HandleLnurlPay', query: HandleLnurlPay_Query} export type HandleLnurlPay_Output = ResultError | ({ status: 'OK' } & HandleLnurlPayResponse) +export type HandleLnurlPayUsername_Query = { + amount?: string +} +export type HandleLnurlPayUsername_RouteParams = { + address_name: string +} +export type HandleLnurlPayUsername_Input = {rpcName:'HandleLnurlPayUsername', query: HandleLnurlPayUsername_Query, params: HandleLnurlPayUsername_RouteParams} +export type HandleLnurlPayUsername_Output = ResultError | ({ status: 'OK' } & HandleLnurlPayResponse) + export type HandleLnurlAddress_RouteParams = { address_name: string } @@ -27,9 +45,11 @@ export type HandleLnurlAddress_Input = {rpcName:'HandleLnurlAddress', params: Ha export type HandleLnurlAddress_Output = ResultError | ({ status: 'OK' } & LnurlPayInfoResponse) export type ServerMethods = { - GetOrCreateVanityName?: (req: GetOrCreateVanityName_Input & {ctx: GuestContext }) => Promise - HandleLnurlPay?: (req: HandleLnurlPay_Input & {ctx: GuestContext }) => Promise - HandleLnurlAddress?: (req: HandleLnurlAddress_Input & {ctx: GuestContext }) => Promise + GetOrCreateVanityName?: (req: GetOrCreateVanityName_Input & {ctx: GuestContext, requestObject: Request }) => Promise + GetOrCreateNofferName?: (req: GetOrCreateNofferName_Input & {ctx: NostrContext, requestObject: Request }) => Promise + HandleLnurlPay?: (req: HandleLnurlPay_Input & {ctx: GuestContext, requestObject: Request }) => Promise + HandleLnurlPayUsername?: (req: HandleLnurlPayUsername_Input & {ctx: GuestContext, requestObject: Request }) => Promise + HandleLnurlAddress?: (req: HandleLnurlAddress_Input & {ctx: GuestContext, requestObject: Request }) => Promise } @@ -37,6 +57,88 @@ export type OptionsBaseMessage = { allOptionalsAreSet?: true } +export type HandleLnurlPayResponse = { + pr: string + routes: Empty[] +} +export const HandleLnurlPayResponseOptionalFields: [] = [] +export type HandleLnurlPayResponseOptions = OptionsBaseMessage & { + checkOptionalsAreSet?: [] + pr_CustomCheck?: (v: string) => boolean + routes_ItemOptions?: EmptyOptions + routes_CustomCheck?: (v: Empty[]) => boolean +} +export const HandleLnurlPayResponseValidate = (o?: HandleLnurlPayResponse, opts: HandleLnurlPayResponseOptions = {}, path: string = 'HandleLnurlPayResponse::root.'): Error | null => { + if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message') + if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null') + + if (typeof o.pr !== 'string') return new Error(`${path}.pr: is not a string`) + if (opts.pr_CustomCheck && !opts.pr_CustomCheck(o.pr)) return new Error(`${path}.pr: custom check failed`) + + if (!Array.isArray(o.routes)) return new Error(`${path}.routes: is not an array`) + for (let index = 0; index < o.routes.length; index++) { + const routesErr = EmptyValidate(o.routes[index], opts.routes_ItemOptions, `${path}.routes[${index}]`) + if (routesErr !== null) return routesErr + } + if (opts.routes_CustomCheck && !opts.routes_CustomCheck(o.routes)) return new Error(`${path}.routes: custom check failed`) + + return null +} + +export type LnurlPayInfoResponse = { + maxSendable: number + minSendable: number + metadata: string + allowsNostr?: boolean + nostrPubkey?: string + nip69?: string + tag: string + callback: string +} +export type LnurlPayInfoResponseOptionalField = 'allowsNostr' | 'nostrPubkey' | 'nip69' +export const LnurlPayInfoResponseOptionalFields: LnurlPayInfoResponseOptionalField[] = ['allowsNostr', 'nostrPubkey', 'nip69'] +export type LnurlPayInfoResponseOptions = OptionsBaseMessage & { + checkOptionalsAreSet?: LnurlPayInfoResponseOptionalField[] + maxSendable_CustomCheck?: (v: number) => boolean + minSendable_CustomCheck?: (v: number) => boolean + metadata_CustomCheck?: (v: string) => boolean + allowsNostr_CustomCheck?: (v?: boolean) => boolean + nostrPubkey_CustomCheck?: (v?: string) => boolean + nip69_CustomCheck?: (v?: string) => boolean + tag_CustomCheck?: (v: string) => boolean + callback_CustomCheck?: (v: string) => boolean +} +export const LnurlPayInfoResponseValidate = (o?: LnurlPayInfoResponse, opts: LnurlPayInfoResponseOptions = {}, path: string = 'LnurlPayInfoResponse::root.'): Error | null => { + if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message') + if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null') + + if (typeof o.tag !== 'string') return new Error(`${path}.tag: is not a string`) + if (opts.tag_CustomCheck && !opts.tag_CustomCheck(o.tag)) return new Error(`${path}.tag: custom check failed`) + + if (typeof o.callback !== 'string') return new Error(`${path}.callback: is not a string`) + if (opts.callback_CustomCheck && !opts.callback_CustomCheck(o.callback)) return new Error(`${path}.callback: custom check failed`) + + if (typeof o.maxSendable !== 'number') return new Error(`${path}.maxSendable: is not a number`) + if (opts.maxSendable_CustomCheck && !opts.maxSendable_CustomCheck(o.maxSendable)) return new Error(`${path}.maxSendable: custom check failed`) + + if (typeof o.minSendable !== 'number') return new Error(`${path}.minSendable: is not a number`) + if (opts.minSendable_CustomCheck && !opts.minSendable_CustomCheck(o.minSendable)) return new Error(`${path}.minSendable: custom check failed`) + + if (typeof o.metadata !== 'string') return new Error(`${path}.metadata: is not a string`) + if (opts.metadata_CustomCheck && !opts.metadata_CustomCheck(o.metadata)) return new Error(`${path}.metadata: custom check failed`) + + if ((o.allowsNostr || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('allowsNostr')) && typeof o.allowsNostr !== 'boolean') return new Error(`${path}.allowsNostr: is not a boolean`) + if (opts.allowsNostr_CustomCheck && !opts.allowsNostr_CustomCheck(o.allowsNostr)) return new Error(`${path}.allowsNostr: custom check failed`) + + if ((o.nostrPubkey || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('nostrPubkey')) && typeof o.nostrPubkey !== 'string') return new Error(`${path}.nostrPubkey: is not a string`) + if (opts.nostrPubkey_CustomCheck && !opts.nostrPubkey_CustomCheck(o.nostrPubkey)) return new Error(`${path}.nostrPubkey: custom check failed`) + + if ((o.nip69 || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('nip69')) && typeof o.nip69 !== 'string') return new Error(`${path}.nip69: is not a string`) + if (opts.nip69_CustomCheck && !opts.nip69_CustomCheck(o.nip69)) return new Error(`${path}.nip69: custom check failed`) + + return null +} + export type Empty = { } export const EmptyOptionalFields: [] = [] @@ -92,84 +194,44 @@ export const GetOrCreateVanityNameResponseValidate = (o?: GetOrCreateVanityNameR return null } -export type HandleLnurlPayResponse = { - pr: string - routes: Empty[] +export type GetOrCreateNofferNameRequest = { + noffer: string + k1?: string } -export const HandleLnurlPayResponseOptionalFields: [] = [] -export type HandleLnurlPayResponseOptions = OptionsBaseMessage & { - checkOptionalsAreSet?: [] - pr_CustomCheck?: (v: string) => boolean - routes_ItemOptions?: EmptyOptions - routes_CustomCheck?: (v: Empty[]) => boolean +export type GetOrCreateNofferNameRequestOptionalField = 'k1' +export const GetOrCreateNofferNameRequestOptionalFields: GetOrCreateNofferNameRequestOptionalField[] = ['k1'] +export type GetOrCreateNofferNameRequestOptions = OptionsBaseMessage & { + checkOptionalsAreSet?: GetOrCreateNofferNameRequestOptionalField[] + noffer_CustomCheck?: (v: string) => boolean + k1_CustomCheck?: (v?: string) => boolean } -export const HandleLnurlPayResponseValidate = (o?: HandleLnurlPayResponse, opts: HandleLnurlPayResponseOptions = {}, path: string = 'HandleLnurlPayResponse::root.'): Error | null => { +export const GetOrCreateNofferNameRequestValidate = (o?: GetOrCreateNofferNameRequest, opts: GetOrCreateNofferNameRequestOptions = {}, path: string = 'GetOrCreateNofferNameRequest::root.'): Error | null => { if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message') if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null') - if (typeof o.pr !== 'string') return new Error(`${path}.pr: is not a string`) - if (opts.pr_CustomCheck && !opts.pr_CustomCheck(o.pr)) return new Error(`${path}.pr: custom check failed`) + if (typeof o.noffer !== 'string') return new Error(`${path}.noffer: is not a string`) + if (opts.noffer_CustomCheck && !opts.noffer_CustomCheck(o.noffer)) return new Error(`${path}.noffer: custom check failed`) - if (!Array.isArray(o.routes)) return new Error(`${path}.routes: is not an array`) - for (let index = 0; index < o.routes.length; index++) { - const routesErr = EmptyValidate(o.routes[index], opts.routes_ItemOptions, `${path}.routes[${index}]`) - if (routesErr !== null) return routesErr - } - if (opts.routes_CustomCheck && !opts.routes_CustomCheck(o.routes)) return new Error(`${path}.routes: custom check failed`) + if ((o.k1 || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('k1')) && typeof o.k1 !== 'string') return new Error(`${path}.k1: is not a string`) + if (opts.k1_CustomCheck && !opts.k1_CustomCheck(o.k1)) return new Error(`${path}.k1: custom check failed`) return null } -export type LnurlPayInfoResponse = { - tag: string - callback: string - maxSendable: number - minSendable: number - metadata: string - allowsNostr: boolean - nostrPubkey: string - nip69?: string +export type GetOrCreateNofferNameResponse = { + vanity_name: string } -export type LnurlPayInfoResponseOptionalField = 'nip69' -export const LnurlPayInfoResponseOptionalFields: LnurlPayInfoResponseOptionalField[] = ['nip69'] -export type LnurlPayInfoResponseOptions = OptionsBaseMessage & { - checkOptionalsAreSet?: LnurlPayInfoResponseOptionalField[] - tag_CustomCheck?: (v: string) => boolean - callback_CustomCheck?: (v: string) => boolean - maxSendable_CustomCheck?: (v: number) => boolean - minSendable_CustomCheck?: (v: number) => boolean - metadata_CustomCheck?: (v: string) => boolean - allowsNostr_CustomCheck?: (v: boolean) => boolean - nostrPubkey_CustomCheck?: (v: string) => boolean - nip69_CustomCheck?: (v?: string) => boolean +export const GetOrCreateNofferNameResponseOptionalFields: [] = [] +export type GetOrCreateNofferNameResponseOptions = OptionsBaseMessage & { + checkOptionalsAreSet?: [] + vanity_name_CustomCheck?: (v: string) => boolean } -export const LnurlPayInfoResponseValidate = (o?: LnurlPayInfoResponse, opts: LnurlPayInfoResponseOptions = {}, path: string = 'LnurlPayInfoResponse::root.'): Error | null => { +export const GetOrCreateNofferNameResponseValidate = (o?: GetOrCreateNofferNameResponse, opts: GetOrCreateNofferNameResponseOptions = {}, path: string = 'GetOrCreateNofferNameResponse::root.'): Error | null => { if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message') if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null') - if (typeof o.tag !== 'string') return new Error(`${path}.tag: is not a string`) - if (opts.tag_CustomCheck && !opts.tag_CustomCheck(o.tag)) return new Error(`${path}.tag: custom check failed`) - - if (typeof o.callback !== 'string') return new Error(`${path}.callback: is not a string`) - if (opts.callback_CustomCheck && !opts.callback_CustomCheck(o.callback)) return new Error(`${path}.callback: custom check failed`) - - if (typeof o.maxSendable !== 'number') return new Error(`${path}.maxSendable: is not a number`) - if (opts.maxSendable_CustomCheck && !opts.maxSendable_CustomCheck(o.maxSendable)) return new Error(`${path}.maxSendable: custom check failed`) - - if (typeof o.minSendable !== 'number') return new Error(`${path}.minSendable: is not a number`) - if (opts.minSendable_CustomCheck && !opts.minSendable_CustomCheck(o.minSendable)) return new Error(`${path}.minSendable: custom check failed`) - - if (typeof o.metadata !== 'string') return new Error(`${path}.metadata: is not a string`) - if (opts.metadata_CustomCheck && !opts.metadata_CustomCheck(o.metadata)) return new Error(`${path}.metadata: custom check failed`) - - if (typeof o.allowsNostr !== 'boolean') return new Error(`${path}.allowsNostr: is not a boolean`) - if (opts.allowsNostr_CustomCheck && !opts.allowsNostr_CustomCheck(o.allowsNostr)) return new Error(`${path}.allowsNostr: custom check failed`) - - if (typeof o.nostrPubkey !== 'string') return new Error(`${path}.nostrPubkey: is not a string`) - if (opts.nostrPubkey_CustomCheck && !opts.nostrPubkey_CustomCheck(o.nostrPubkey)) return new Error(`${path}.nostrPubkey: custom check failed`) - - if ((o.nip69 || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('nip69')) && typeof o.nip69 !== 'string') return new Error(`${path}.nip69: is not a string`) - if (opts.nip69_CustomCheck && !opts.nip69_CustomCheck(o.nip69)) return new Error(`${path}.nip69: custom check failed`) + if (typeof o.vanity_name !== 'string') return new Error(`${path}.vanity_name: is not a string`) + if (opts.vanity_name_CustomCheck && !opts.vanity_name_CustomCheck(o.vanity_name)) return new Error(`${path}.vanity_name: custom check failed`) return null } diff --git a/src/Api/bridge/http.ts b/src/Api/bridge/http.ts index 16852813..db2064e3 100644 --- a/src/Api/bridge/http.ts +++ b/src/Api/bridge/http.ts @@ -1,10 +1,11 @@ import NewHttpClient from './autogenerated/ts/http_client' -const CreateHttpClient = (url: string) => { +const CreateHttpClient = (url: string, nostrHeader: string) => { return NewHttpClient({ baseUrl: url, retrieveGuestAuth: async () => { return "" }, encryptCallback: async () => { throw new Error("encryption not enabled") }, decryptCallback: async () => { throw new Error("encryption not enabled") }, + retrieveNostrAuth: async () => { return nostrHeader }, deviceId: "", }) } diff --git a/src/Api/bridge/index.ts b/src/Api/bridge/index.ts index a84d3eb2..df635926 100644 --- a/src/Api/bridge/index.ts +++ b/src/Api/bridge/index.ts @@ -1,14 +1,16 @@ + import CreateBridgeHttpClient, { BridgeHttpClient } from "./http" + export default class Handler { - constructor(bridgeUrl: string) { + constructor(bridgeUrl: string, nostrHeader: string) { console.log(bridgeUrl) - this.bridgeHttp = CreateBridgeHttpClient(bridgeUrl); + this.bridgeHttp = CreateBridgeHttpClient(bridgeUrl, nostrHeader); } bridgeHttp: BridgeHttpClient; - async GetOrCreateVanityName(k1: string, noffer?: string) { - return this.bridgeHttp.GetOrCreateVanityName({ k1, noffer }); + async GetOrCreateNofferName({ noffer, k1 }: { noffer: string, k1?: string }) { + return this.bridgeHttp.GetOrCreateNofferName({ k1, noffer }); } } \ No newline at end of file diff --git a/src/Api/pub/autogenerated/ts/http_client.ts b/src/Api/pub/autogenerated/ts/http_client.ts index 81853d5d..86aeac62 100644 --- a/src/Api/pub/autogenerated/ts/http_client.ts +++ b/src/Api/pub/autogenerated/ts/http_client.ts @@ -5,524 +5,531 @@ export type ResultError = { status: 'ERROR', reason: string } export type ClientParams = { baseUrl: string - retrieveGuestAuth: () => Promise - retrieveUserAuth: () => Promise retrieveAdminAuth: () => Promise - retrieveMetricsAuth: () => Promise retrieveAppAuth: () => Promise + retrieveGuestAuth: () => Promise retrieveGuestWithPubAuth: () => Promise + retrieveMetricsAuth: () => Promise + retrieveUserAuth: () => Promise encryptCallback: (plain: any) => Promise decryptCallback: (encrypted: any) => Promise deviceId: string checkResult?: true } export default (params: ClientParams) => ({ - LndGetInfo: async (request: Types.LndGetInfoRequest): Promise => { + AddApp: async (request: Types.AddAppRequest): Promise => { const auth = await params.retrieveAdminAuth() if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/lnd/getinfo' + let finalRoute = '/api/admin/app/add' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndGetInfoResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AuthAppValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddApp: async (request: Types.AddAppRequest): Promise => { - const auth = await params.retrieveAdminAuth() - if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/app/add' + AddAppInvoice: async (request: Types.AddAppInvoiceRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/add/invoice' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AuthAppValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AuthApp: async (request: Types.AuthAppRequest): Promise => { - const auth = await params.retrieveAdminAuth() - if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/app/auth' + AddAppUser: async (request: Types.AddAppUserRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/add' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AuthAppValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AppUserValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - BanUser: async (request: Types.BanUserRequest): Promise => { - const auth = await params.retrieveAdminAuth() - if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/user/ban' + AddAppUserInvoice: async (request: Types.AddAppUserInvoiceRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/add/invoice' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.BanUserResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetSeed: async (): Promise => { - const auth = await params.retrieveAdminAuth() - if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/seed' - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + AddProduct: async (request: Types.AddProductRequest): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/product/add' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndSeedValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.ProductValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - ListChannels: async (): Promise => { + AuthApp: async (request: Types.AuthAppRequest): Promise => { const auth = await params.retrieveAdminAuth() if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/channels' - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) - if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndChannelsValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } - } - return { status: 'ERROR', reason: 'invalid response' } - }, - GetUsageMetrics: async (): Promise => { - const auth = await params.retrieveMetricsAuth() - if (auth === null) throw new Error('retrieveMetricsAuth() returned null') - let finalRoute = '/api/reports/usage' - const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) + let finalRoute = '/api/admin/app/auth' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.UsageMetricsValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AuthAppValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetAppsMetrics: async (request: Types.AppsMetricsRequest): Promise => { - const auth = await params.retrieveMetricsAuth() - if (auth === null) throw new Error('retrieveMetricsAuth() returned null') - let finalRoute = '/api/reports/apps' + BanUser: async (request: Types.BanUserRequest): Promise => { + const auth = await params.retrieveAdminAuth() + if (auth === null) throw new Error('retrieveAdminAuth() returned null') + let finalRoute = '/api/admin/user/ban' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AppsMetricsValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.BanUserResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLndMetrics: async (request: Types.LndMetricsRequest): Promise => { - const auth = await params.retrieveMetricsAuth() - if (auth === null) throw new Error('retrieveMetricsAuth() returned null') - let finalRoute = '/api/reports/lnd' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + BatchUser: async (requests:Types.UserMethodInputs[]): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/batch' + const { data } = await axios.post(params.baseUrl + finalRoute, {requests}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndMetricsValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } - } + if (data.status === 'OK') { + return { status: 'OK', ...data } + } return { status: 'ERROR', reason: 'invalid response' } }, - CreateOneTimeInviteLink: async (request: Types.CreateOneTimeInviteLinkRequest): Promise => { + CreateOneTimeInviteLink: async (request: Types.CreateOneTimeInviteLinkRequest): Promise => { const auth = await params.retrieveAdminAuth() if (auth === null) throw new Error('retrieveAdminAuth() returned null') let finalRoute = '/api/admin/app/invite/create' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.CreateOneTimeInviteLinkResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetInviteLinkState: async (request: Types.GetInviteTokenStateRequest): Promise => { - const auth = await params.retrieveAdminAuth() - if (auth === null) throw new Error('retrieveAdminAuth() returned null') - let finalRoute = '/api/admin/app/invite/get' + DecodeInvoice: async (request: Types.DecodeInvoiceRequest): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/invoice/decode' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.GetInviteTokenStateResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.DecodeInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - Health: async (): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/health' - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) - if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data - } - return { status: 'ERROR', reason: 'invalid response' } - }, EncryptionExchange: async (request: Types.EncryptionExchangeRequest): Promise => { const auth = await params.retrieveGuestAuth() if (auth === null) throw new Error('retrieveGuestAuth() returned null') let finalRoute = '/api/encryption/exchange' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { return data } return { status: 'ERROR', reason: 'invalid response' } }, - SetMockInvoiceAsPaid: async (request: Types.SetMockInvoiceAsPaidRequest): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/lnd/mock/invoice/paid' + EnrollAdminToken: async (request: Types.EnrollAdminTokenRequest): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/guest/npub/enroll/admin' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlWithdrawInfo: async (query: Types.GetLnurlWithdrawInfo_Query): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/guest/lnurl_withdraw/info' - const q = (new URLSearchParams(query)).toString() - finalRoute = finalRoute + (q === '' ? '' : '?' + q) - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + GetApp: async (): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/get' + const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlWithdrawInfoResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.ApplicationValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - HandleLnurlWithdraw: async (query: Types.HandleLnurlWithdraw_Query): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/guest/lnurl_withdraw/handle' - const q = (new URLSearchParams(query)).toString() - finalRoute = finalRoute + (q === '' ? '' : '?' + q) - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + GetAppUser: async (request: Types.GetAppUserRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/get' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AppUserValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlPayInfo: async (query: Types.GetLnurlPayInfo_Query): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/guest/lnurl_pay/info' - const q = (new URLSearchParams(query)).toString() - finalRoute = finalRoute + (q === '' ? '' : '?' + q) - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + GetAppUserLNURLInfo: async (request: Types.GetAppUserLNURLInfoRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/lnurl/pay/info' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.LnurlPayInfoResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - HandleLnurlPay: async (query: Types.HandleLnurlPay_Query): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/api/guest/lnurl_pay/handle' - const q = (new URLSearchParams(query)).toString() - finalRoute = finalRoute + (q === '' ? '' : '?' + q) - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + GetAppsMetrics: async (request: Types.AppsMetricsRequest): Promise => { + const auth = await params.retrieveMetricsAuth() + if (auth === null) throw new Error('retrieveMetricsAuth() returned null') + let finalRoute = '/api/reports/apps' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.HandleLnurlPayResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AppsMetricsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - HandleLnurlAddress: async (routeParams: Types.HandleLnurlAddress_RouteParams): Promise => { - const auth = await params.retrieveGuestAuth() - if (auth === null) throw new Error('retrieveGuestAuth() returned null') - let finalRoute = '/.well-known/lnurlp/:address_name' - finalRoute = finalRoute.replace(':address_name', routeParams['address_name']) - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + GetHttpCreds: async (cb: (v:ResultError | ({ status: 'OK' }& Types.HttpCreds)) => void): Promise => { throw new Error('http streams are not supported')}, + GetInviteLinkState: async (request: Types.GetInviteTokenStateRequest): Promise => { + const auth = await params.retrieveAdminAuth() + if (auth === null) throw new Error('retrieveAdminAuth() returned null') + let finalRoute = '/api/admin/app/invite/get' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlPayInfoResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.GetInviteTokenStateResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - EnrollAdminToken: async (request: Types.EnrollAdminTokenRequest): Promise => { + GetLNURLChannelLink: async (): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/guest/npub/enroll/admin' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + let finalRoute = '/api/user/lnurl_channel/url' + const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - LinkNPubThroughToken: async (request: Types.LinkNPubThroughTokenRequest): Promise => { - const auth = await params.retrieveGuestWithPubAuth() - if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null') - let finalRoute = '/api/guest/npub/link' + GetLiveUserOperations: async (cb: (v:ResultError | ({ status: 'OK' }& Types.LiveUserOperation)) => void): Promise => { throw new Error('http streams are not supported')}, + GetLndMetrics: async (request: Types.LndMetricsRequest): Promise => { + const auth = await params.retrieveMetricsAuth() + if (auth === null) throw new Error('retrieveMetricsAuth() returned null') + let finalRoute = '/api/reports/lnd' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndMetricsValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise => { - const auth = await params.retrieveGuestWithPubAuth() - if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null') - let finalRoute = '/api/guest/invite' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetLnurlPayInfo: async (query: Types.GetLnurlPayInfo_Query): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/guest/lnurl_pay/info' + const q = (new URLSearchParams(query)).toString() + finalRoute = finalRoute + (q === '' ? '' : '?' + q) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlPayInfoResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetApp: async (): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/get' - const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) + GetLnurlPayLink: async (): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/lnurl_pay/link' + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.ApplicationValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddAppUser: async (request: Types.AddAppUserRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/add' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetLnurlWithdrawInfo: async (query: Types.GetLnurlWithdrawInfo_Query): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/guest/lnurl_withdraw/info' + const q = (new URLSearchParams(query)).toString() + finalRoute = finalRoute + (q === '' ? '' : '?' + q) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AppUserValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlWithdrawInfoResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddAppInvoice: async (request: Types.AddAppInvoiceRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/add/invoice' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetLnurlWithdrawLink: async (): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/lnurl_withdraw/link' + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddAppUserInvoice: async (request: Types.AddAppUserInvoiceRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/add/invoice' + GetMigrationUpdate: async (cb: (v:ResultError | ({ status: 'OK' }& Types.MigrationUpdate)) => void): Promise => { throw new Error('http streams are not supported')}, + GetPaymentState: async (request: Types.GetPaymentStateRequest): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/payment/state' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PaymentStateValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetAppUser: async (request: Types.GetAppUserRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/get' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetSeed: async (): Promise => { + const auth = await params.retrieveAdminAuth() + if (auth === null) throw new Error('retrieveAdminAuth() returned null') + let finalRoute = '/api/admin/seed' + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AppUserValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndSeedValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - PayAppUserInvoice: async (request: Types.PayAppUserInvoiceRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/invoice/pay' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetUsageMetrics: async (): Promise => { + const auth = await params.retrieveMetricsAuth() + if (auth === null) throw new Error('retrieveMetricsAuth() returned null') + let finalRoute = '/api/reports/usage' + const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PayInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.UsageMetricsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - SendAppUserToAppUserPayment: async (request: Types.SendAppUserToAppUserPaymentRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/internal/pay' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + GetUserInfo: async (): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/info' + const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.UserInfoValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - SendAppUserToAppPayment: async (request: Types.SendAppUserToAppPaymentRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/internal/pay' + GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise => { + const auth = await params.retrieveUserAuth() + if (auth === null) throw new Error('retrieveUserAuth() returned null') + let finalRoute = '/api/user/operations' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.GetUserOperationsResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetAppUserLNURLInfo: async (request: Types.GetAppUserLNURLInfoRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/lnurl/pay/info' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + HandleLnurlAddress: async (routeParams: Types.HandleLnurlAddress_RouteParams): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/.well-known/lnurlp/:address_name' + finalRoute = finalRoute.replace(':address_name', routeParams['address_name']) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.LnurlPayInfoResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - SetMockAppUserBalance: async (request: Types.SetMockAppUserBalanceRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/mock/user/blance/set' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + HandleLnurlPay: async (query: Types.HandleLnurlPay_Query): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/guest/lnurl_pay/handle' + const q = (new URLSearchParams(query)).toString() + finalRoute = finalRoute + (q === '' ? '' : '?' + q) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.HandleLnurlPayResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + } + return { status: 'ERROR', reason: 'invalid response' } + }, + HandleLnurlWithdraw: async (query: Types.HandleLnurlWithdraw_Query): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/guest/lnurl_withdraw/handle' + const q = (new URLSearchParams(query)).toString() + finalRoute = finalRoute + (q === '' ? '' : '?' + q) + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { return data } return { status: 'ERROR', reason: 'invalid response' } }, - SetMockAppBalance: async (request: Types.SetMockAppBalanceRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/mock/blance/set' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + Health: async (): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/health' + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { return data } return { status: 'ERROR', reason: 'invalid response' } }, - RequestNPubLinkingToken: async (request: Types.RequestNPubLinkingTokenRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/npub/token' + LinkNPubThroughToken: async (request: Types.LinkNPubThroughTokenRequest): Promise => { + const auth = await params.retrieveGuestWithPubAuth() + if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null') + let finalRoute = '/api/guest/npub/link' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.RequestNPubLinkingTokenResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - ResetNPubLinkingToken: async (request: Types.RequestNPubLinkingTokenRequest): Promise => { - const auth = await params.retrieveAppAuth() - if (auth === null) throw new Error('retrieveAppAuth() returned null') - let finalRoute = '/api/app/user/npub/token/reset' - const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + ListChannels: async (): Promise => { + const auth = await params.retrieveAdminAuth() + if (auth === null) throw new Error('retrieveAdminAuth() returned null') + let finalRoute = '/api/admin/channels' + const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.RequestNPubLinkingTokenResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndChannelsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - UserHealth: async (): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/health' - const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) + LndGetInfo: async (request: Types.LndGetInfoRequest): Promise => { + const auth = await params.retrieveAdminAuth() + if (auth === null) throw new Error('retrieveAdminAuth() returned null') + let finalRoute = '/api/admin/lnd/getinfo' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndGetInfoResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetUserInfo: async (): Promise => { + NewAddress: async (request: Types.NewAddressRequest): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/info' - const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) + let finalRoute = '/api/user/chain/new' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.UserInfoValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewAddressResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddProduct: async (request: Types.AddProductRequest): Promise => { + NewInvoice: async (request: Types.NewInvoiceRequest): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/product/add' + let finalRoute = '/api/user/invoice/new' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.ProductValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewProductInvoice: async (query: Types.NewProductInvoice_Query): Promise => { + NewProductInvoice: async (query: Types.NewProductInvoice_Query): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') let finalRoute = '/api/user/product/get/invoice' @@ -530,180 +537,173 @@ export default (params: ClientParams) => ({ finalRoute = finalRoute + (q === '' ? '' : '?' + q) const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise => { + OpenChannel: async (request: Types.OpenChannelRequest): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/operations' + let finalRoute = '/api/user/open/channel' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.GetUserOperationsResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.OpenChannelResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewAddress: async (request: Types.NewAddressRequest): Promise => { + PayAddress: async (request: Types.PayAddressRequest): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/chain/new' + let finalRoute = '/api/user/chain/pay' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewAddressResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PayAddressResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - PayAddress: async (request: Types.PayAddressRequest): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/chain/pay' + PayAppUserInvoice: async (request: Types.PayAppUserInvoiceRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/invoice/pay' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PayAddressResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PayInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewInvoice: async (request: Types.NewInvoiceRequest): Promise => { + PayInvoice: async (request: Types.PayInvoiceRequest): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/invoice/new' + let finalRoute = '/api/user/invoice/pay' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PayInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - DecodeInvoice: async (request: Types.DecodeInvoiceRequest): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/invoice/decode' + RequestNPubLinkingToken: async (request: Types.RequestNPubLinkingTokenRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/npub/token' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.DecodeInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.RequestNPubLinkingTokenResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - PayInvoice: async (request: Types.PayInvoiceRequest): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/invoice/pay' + ResetNPubLinkingToken: async (request: Types.RequestNPubLinkingTokenRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/npub/token/reset' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PayInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.RequestNPubLinkingTokenResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetPaymentState: async (request: Types.GetPaymentStateRequest): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/payment/state' + SendAppUserToAppPayment: async (request: Types.SendAppUserToAppPaymentRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/internal/pay' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PaymentStateValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - OpenChannel: async (request: Types.OpenChannelRequest): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/open/channel' + SendAppUserToAppUserPayment: async (request: Types.SendAppUserToAppUserPaymentRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/user/internal/pay' const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.OpenChannelResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlWithdrawLink: async (): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/lnurl_withdraw/link' - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + SetMockAppBalance: async (request: Types.SetMockAppBalanceRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/mock/blance/set' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlPayLink: async (): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/lnurl_pay/link' - const { data } = await axios.get(params.baseUrl + finalRoute, { headers: { 'authorization': auth } }) + SetMockAppUserBalance: async (request: Types.SetMockAppUserBalanceRequest): Promise => { + const auth = await params.retrieveAppAuth() + if (auth === null) throw new Error('retrieveAppAuth() returned null') + let finalRoute = '/api/app/mock/user/blance/set' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLNURLChannelLink: async (): Promise => { - const auth = await params.retrieveUserAuth() - if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/lnurl_channel/url' - const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) + SetMockInvoiceAsPaid: async (request: Types.SetMockInvoiceAsPaidRequest): Promise => { + const auth = await params.retrieveGuestAuth() + if (auth === null) throw new Error('retrieveGuestAuth() returned null') + let finalRoute = '/api/lnd/mock/invoice/paid' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data + } + return { status: 'ERROR', reason: 'invalid response' } + }, + UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise => { + const auth = await params.retrieveGuestWithPubAuth() + if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null') + let finalRoute = '/api/guest/invite' + const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLiveUserOperations: async (cb: (v: ResultError | ({ status: 'OK' } & Types.LiveUserOperation)) => void): Promise => { throw new Error('http streams are not supported') }, - GetMigrationUpdate: async (cb: (v: ResultError | ({ status: 'OK' } & Types.MigrationUpdate)) => void): Promise => { throw new Error('http streams are not supported') }, - GetHttpCreds: async (cb: (v: ResultError | ({ status: 'OK' } & Types.HttpCreds)) => void): Promise => { throw new Error('http streams are not supported') }, - BatchUser: async (requests: Types.UserMethodInputs[]): Promise => { + UserHealth: async (): Promise => { const auth = await params.retrieveUserAuth() if (auth === null) throw new Error('retrieveUserAuth() returned null') - let finalRoute = '/api/user/batch' - const { data } = await axios.post(params.baseUrl + finalRoute, { requests }, { headers: { 'authorization': auth } }) + let finalRoute = '/api/user/health' + const { data } = await axios.post(params.baseUrl + finalRoute, {}, { headers: { 'authorization': auth } }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return { status: 'OK', ...data } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } - } + }, }) diff --git a/src/Api/pub/autogenerated/ts/nostr_client.ts b/src/Api/pub/autogenerated/ts/nostr_client.ts index 643ae0b7..6a6fb4c0 100644 --- a/src/Api/pub/autogenerated/ts/nostr_client.ts +++ b/src/Api/pub/autogenerated/ts/nostr_client.ts @@ -5,482 +5,482 @@ export type ResultError = { status: 'ERROR', reason: string } export type NostrClientParams = { pubDestination: string + retrieveNostrAdminAuth: () => Promise + retrieveNostrGuestWithPubAuth: () => Promise retrieveNostrMetricsAuth: () => Promise retrieveNostrUserAuth: () => Promise - retrieveNostrGuestWithPubAuth: () => Promise - retrieveNostrAdminAuth: () => Promise checkResult?: true } -export default (params: NostrClientParams, send: (to: string, message: NostrRequest) => Promise, subscribe: (to: string, message: NostrRequest, cb: (res: any) => void) => void) => ({ - LndGetInfo: async (request: Types.LndGetInfoRequest): Promise => { +export default (params: NostrClientParams, send: (to:string, message: NostrRequest) => Promise, subscribe: (to:string, message: NostrRequest, cb:(res:any)=> void) => void) => ({ + AddApp: async (request: Types.AddAppRequest): Promise => { const auth = await params.retrieveNostrAdminAuth() if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'LndGetInfo', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'AddApp',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndGetInfoResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AuthAppValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddApp: async (request: Types.AddAppRequest): Promise => { - const auth = await params.retrieveNostrAdminAuth() - if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') + AddProduct: async (request: Types.AddProductRequest): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'AddApp', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'AddProduct',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AuthAppValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.ProductValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AuthApp: async (request: Types.AuthAppRequest): Promise => { + AuthApp: async (request: Types.AuthAppRequest): Promise => { const auth = await params.retrieveNostrAdminAuth() if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'AuthApp', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'AuthApp',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.AuthAppValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - BanUser: async (request: Types.BanUserRequest): Promise => { + BanUser: async (request: Types.BanUserRequest): Promise => { const auth = await params.retrieveNostrAdminAuth() if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'BanUser', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'BanUser',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.BanUserResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetSeed: async (): Promise => { - const auth = await params.retrieveNostrAdminAuth() - if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') - const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetSeed', authIdentifier: auth, ...nostrRequest }) + BatchUser: async (requests:Types.UserMethodInputs[]): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + const nostrRequest: NostrRequest = {body:{requests}} + const data = await send(params.pubDestination, {rpcName:'BatchUser',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndSeedValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } - } + if (data.status === 'OK') { + return data + } return { status: 'ERROR', reason: 'invalid response' } }, - ListChannels: async (): Promise => { + CreateOneTimeInviteLink: async (request: Types.CreateOneTimeInviteLinkRequest): Promise => { const auth = await params.retrieveNostrAdminAuth() if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'ListChannels', authIdentifier: auth, ...nostrRequest }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'CreateOneTimeInviteLink',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndChannelsValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.CreateOneTimeInviteLinkResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetUsageMetrics: async (): Promise => { - const auth = await params.retrieveNostrMetricsAuth() - if (auth === null) throw new Error('retrieveNostrMetricsAuth() returned null') + DecodeInvoice: async (request: Types.DecodeInvoiceRequest): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetUsageMetrics', authIdentifier: auth, ...nostrRequest }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'DecodeInvoice',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.UsageMetricsValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.DecodeInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetAppsMetrics: async (request: Types.AppsMetricsRequest): Promise => { - const auth = await params.retrieveNostrMetricsAuth() - if (auth === null) throw new Error('retrieveNostrMetricsAuth() returned null') + EnrollAdminToken: async (request: Types.EnrollAdminTokenRequest): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'GetAppsMetrics', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'EnrollAdminToken',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.AppsMetricsValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - GetLndMetrics: async (request: Types.LndMetricsRequest): Promise => { + GetAppsMetrics: async (request: Types.AppsMetricsRequest): Promise => { const auth = await params.retrieveNostrMetricsAuth() if (auth === null) throw new Error('retrieveNostrMetricsAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'GetLndMetrics', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetAppsMetrics',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LndMetricsValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.AppsMetricsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - CreateOneTimeInviteLink: async (request: Types.CreateOneTimeInviteLinkRequest): Promise => { - const auth = await params.retrieveNostrAdminAuth() - if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') + GetHttpCreds: async (cb: (res:ResultError | ({ status: 'OK' }& Types.HttpCreds)) => void): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'CreateOneTimeInviteLink', authIdentifier: auth, ...nostrRequest }) - if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.CreateOneTimeInviteLinkResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } - } - return { status: 'ERROR', reason: 'invalid response' } + subscribe(params.pubDestination, {rpcName:'GetHttpCreds',authIdentifier:auth, ...nostrRequest }, (data) => { + if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return cb({ status: 'OK', ...result }) + const error = Types.HttpCredsValidate(result) + if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) + } + return cb({ status: 'ERROR', reason: 'invalid response' }) + }) }, - GetInviteLinkState: async (request: Types.GetInviteTokenStateRequest): Promise => { + GetInviteLinkState: async (request: Types.GetInviteTokenStateRequest): Promise => { const auth = await params.retrieveNostrAdminAuth() if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'GetInviteLinkState', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetInviteLinkState',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } + if(!params.checkResult) return { status: 'OK', ...result } const error = Types.GetInviteTokenStateResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - EnrollAdminToken: async (request: Types.EnrollAdminTokenRequest): Promise => { + GetLNURLChannelLink: async (): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'EnrollAdminToken', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetLNURLChannelLink',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - LinkNPubThroughToken: async (request: Types.LinkNPubThroughTokenRequest): Promise => { - const auth = await params.retrieveNostrGuestWithPubAuth() - if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null') + GetLiveUserOperations: async (cb: (res:ResultError | ({ status: 'OK' }& Types.LiveUserOperation)) => void): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'LinkNPubThroughToken', authIdentifier: auth, ...nostrRequest }) - if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data - } - return { status: 'ERROR', reason: 'invalid response' } + subscribe(params.pubDestination, {rpcName:'GetLiveUserOperations',authIdentifier:auth, ...nostrRequest }, (data) => { + if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return cb({ status: 'OK', ...result }) + const error = Types.LiveUserOperationValidate(result) + if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) + } + return cb({ status: 'ERROR', reason: 'invalid response' }) + }) }, - UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise => { - const auth = await params.retrieveNostrGuestWithPubAuth() - if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null') + GetLndMetrics: async (request: Types.LndMetricsRequest): Promise => { + const auth = await params.retrieveNostrMetricsAuth() + if (auth === null) throw new Error('retrieveNostrMetricsAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'UseInviteLink', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetLndMetrics',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndMetricsValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - UserHealth: async (): Promise => { + GetLnurlPayLink: async (): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'UserHealth', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetLnurlPayLink',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetUserInfo: async (): Promise => { + GetLnurlWithdrawLink: async (): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetUserInfo', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetLnurlWithdrawLink',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.UserInfoValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LnurlLinkResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - AddProduct: async (request: Types.AddProductRequest): Promise => { + GetMigrationUpdate: async (cb: (res:ResultError | ({ status: 'OK' }& Types.MigrationUpdate)) => void): Promise => { + const auth = await params.retrieveNostrUserAuth() + if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + const nostrRequest: NostrRequest = {} + subscribe(params.pubDestination, {rpcName:'GetMigrationUpdate',authIdentifier:auth, ...nostrRequest }, (data) => { + if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return cb({ status: 'OK', ...result }) + const error = Types.MigrationUpdateValidate(result) + if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) + } + return cb({ status: 'ERROR', reason: 'invalid response' }) + }) + }, + GetPaymentState: async (request: Types.GetPaymentStateRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'AddProduct', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetPaymentState',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.ProductValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PaymentStateValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewProductInvoice: async (query: Types.NewProductInvoice_Query): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + GetSeed: async (): Promise => { + const auth = await params.retrieveNostrAdminAuth() + if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.query = query - const data = await send(params.pubDestination, { rpcName: 'NewProductInvoice', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetSeed',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndSeedValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + GetUsageMetrics: async (): Promise => { + const auth = await params.retrieveNostrMetricsAuth() + if (auth === null) throw new Error('retrieveNostrMetricsAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'GetUserOperations', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetUsageMetrics',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.GetUserOperationsResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.UsageMetricsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewAddress: async (request: Types.NewAddressRequest): Promise => { + GetUserInfo: async (): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'NewAddress', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetUserInfo',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewAddressResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.UserInfoValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - PayAddress: async (request: Types.PayAddressRequest): Promise => { + GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'PayAddress', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'GetUserOperations',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PayAddressResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.GetUserOperationsResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - NewInvoice: async (request: Types.NewInvoiceRequest): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + LinkNPubThroughToken: async (request: Types.LinkNPubThroughTokenRequest): Promise => { + const auth = await params.retrieveNostrGuestWithPubAuth() + if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'NewInvoice', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'LinkNPubThroughToken',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.NewInvoiceResponseValidate(result) - if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + if (data.status === 'OK') { + return data } return { status: 'ERROR', reason: 'invalid response' } }, - DecodeInvoice: async (request: Types.DecodeInvoiceRequest): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + ListChannels: async (): Promise => { + const auth = await params.retrieveNostrAdminAuth() + if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} - nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'DecodeInvoice', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'ListChannels',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.DecodeInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndChannelsValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - PayInvoice: async (request: Types.PayInvoiceRequest): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + LndGetInfo: async (request: Types.LndGetInfoRequest): Promise => { + const auth = await params.retrieveNostrAdminAuth() + if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'PayInvoice', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'LndGetInfo',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PayInvoiceResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.LndGetInfoResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetPaymentState: async (request: Types.GetPaymentStateRequest): Promise => { + NewAddress: async (request: Types.NewAddressRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'GetPaymentState', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'NewAddress',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.PaymentStateValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewAddressResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - OpenChannel: async (request: Types.OpenChannelRequest): Promise => { + NewInvoice: async (request: Types.NewInvoiceRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} nostrRequest.body = request - const data = await send(params.pubDestination, { rpcName: 'OpenChannel', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'NewInvoice',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.OpenChannelResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlWithdrawLink: async (): Promise => { + NewProductInvoice: async (query: Types.NewProductInvoice_Query): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetLnurlWithdrawLink', authIdentifier: auth, ...nostrRequest }) + nostrRequest.query = query + const data = await send(params.pubDestination, {rpcName:'NewProductInvoice',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.NewInvoiceResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLnurlPayLink: async (): Promise => { + OpenChannel: async (request: Types.OpenChannelRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetLnurlPayLink', authIdentifier: auth, ...nostrRequest }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'OpenChannel',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.OpenChannelResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLNURLChannelLink: async (): Promise => { + PayAddress: async (request: Types.PayAddressRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - const data = await send(params.pubDestination, { rpcName: 'GetLNURLChannelLink', authIdentifier: auth, ...nostrRequest }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'PayAddress',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { const result = data - if (!params.checkResult) return { status: 'OK', ...result } - const error = Types.LnurlLinkResponseValidate(result) + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PayAddressResponseValidate(result) if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } } return { status: 'ERROR', reason: 'invalid response' } }, - GetLiveUserOperations: async (cb: (res: ResultError | ({ status: 'OK' } & Types.LiveUserOperation)) => void): Promise => { + PayInvoice: async (request: Types.PayInvoiceRequest): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - subscribe(params.pubDestination, { rpcName: 'GetLiveUserOperations', authIdentifier: auth, ...nostrRequest }, (data) => { - if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return cb({ status: 'OK', ...result }) - const error = Types.LiveUserOperationValidate(result) - if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) - } - return cb({ status: 'ERROR', reason: 'invalid response' }) - }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'PayInvoice',authIdentifier:auth, ...nostrRequest }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + const result = data + if(!params.checkResult) return { status: 'OK', ...result } + const error = Types.PayInvoiceResponseValidate(result) + if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message } + } + return { status: 'ERROR', reason: 'invalid response' } }, - GetMigrationUpdate: async (cb: (res: ResultError | ({ status: 'OK' } & Types.MigrationUpdate)) => void): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') + UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise => { + const auth = await params.retrieveNostrGuestWithPubAuth() + if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null') const nostrRequest: NostrRequest = {} - subscribe(params.pubDestination, { rpcName: 'GetMigrationUpdate', authIdentifier: auth, ...nostrRequest }, (data) => { - if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return cb({ status: 'OK', ...result }) - const error = Types.MigrationUpdateValidate(result) - if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) - } - return cb({ status: 'ERROR', reason: 'invalid response' }) - }) + nostrRequest.body = request + const data = await send(params.pubDestination, {rpcName:'UseInviteLink',authIdentifier:auth, ...nostrRequest }) + if (data.status === 'ERROR' && typeof data.reason === 'string') return data + if (data.status === 'OK') { + return data + } + return { status: 'ERROR', reason: 'invalid response' } }, - GetHttpCreds: async (cb: (res: ResultError | ({ status: 'OK' } & Types.HttpCreds)) => void): Promise => { + UserHealth: async (): Promise => { const auth = await params.retrieveNostrUserAuth() if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') const nostrRequest: NostrRequest = {} - subscribe(params.pubDestination, { rpcName: 'GetHttpCreds', authIdentifier: auth, ...nostrRequest }, (data) => { - if (data.status === 'ERROR' && typeof data.reason === 'string') return cb(data) - if (data.status === 'OK') { - const result = data - if (!params.checkResult) return cb({ status: 'OK', ...result }) - const error = Types.HttpCredsValidate(result) - if (error === null) { return cb({ status: 'OK', ...result }) } else return cb({ status: 'ERROR', reason: error.message }) - } - return cb({ status: 'ERROR', reason: 'invalid response' }) - }) - }, - BatchUser: async (requests: Types.UserMethodInputs[]): Promise => { - const auth = await params.retrieveNostrUserAuth() - if (auth === null) throw new Error('retrieveNostrUserAuth() returned null') - const nostrRequest: NostrRequest = { body: { requests } } - const data = await send(params.pubDestination, { rpcName: 'BatchUser', authIdentifier: auth, ...nostrRequest }) + const data = await send(params.pubDestination, {rpcName:'UserHealth',authIdentifier:auth, ...nostrRequest }) if (data.status === 'ERROR' && typeof data.reason === 'string') return data - if (data.status === 'OK') { + if (data.status === 'OK') { return data } return { status: 'ERROR', reason: 'invalid response' } - } + }, }) diff --git a/src/Api/pub/autogenerated/ts/nostr_transport.ts b/src/Api/pub/autogenerated/ts/nostr_transport.ts index 34f0c0e6..288d3169 100644 --- a/src/Api/pub/autogenerated/ts/nostr_transport.ts +++ b/src/Api/pub/autogenerated/ts/nostr_transport.ts @@ -16,12 +16,12 @@ export type NostrOptions = { logger?: Logger throwErrors?: true metricsCallback: (metrics: Types.RequestMetric[]) => void - NostrUserAuthGuard: (appId?: string, identifier?: string) => Promise - NostrGuestWithPubAuthGuard: (appId?: string, identifier?: string) => Promise - NostrAdminAuthGuard: (appId?: string, identifier?: string) => Promise - NostrMetricsAuthGuard: (appId?: string, identifier?: string) => Promise + NostrAdminAuthGuard: (appId?:string, identifier?: string) => Promise + NostrGuestWithPubAuthGuard: (appId?:string, identifier?: string) => Promise + NostrMetricsAuthGuard: (appId?:string, identifier?: string) => Promise + NostrUserAuthGuard: (appId?:string, identifier?: string) => Promise } -const logErrorAndReturnResponse = (error: Error, response: string, res: NostrResponse, logger: Logger, metric: Types.RequestMetric, metricsCallback: (metrics: Types.RequestMetric[]) => void) => { +const logErrorAndReturnResponse = (error: Error, response: string, res: NostrResponse, logger: Logger, metric: Types.RequestMetric, metricsCallback: (metrics: Types.RequestMetric[]) => void) => { logger.error(error.message || error); metricsCallback([{ ...metric, error: response }]); res({ status: 'ERROR', reason: response }) } export default (methods: Types.ServerMethods, opts: NostrOptions) => { @@ -32,37 +32,37 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => { const stats: Types.RequestStats = { startMs, start: startTime, parse: process.hrtime.bigint(), guard: 0n, validate: 0n, handle: 0n } let authCtx: Types.AuthContext = {} switch (req.rpcName) { - case 'LndGetInfo': + case 'AddApp': try { - if (!methods.LndGetInfo) throw new Error('method: LndGetInfo is not implemented') + if (!methods.AddApp) throw new Error('method: AddApp is not implemented') const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.LndGetInfoRequestValidate(request) + const error = Types.AddAppRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.LndGetInfo({ rpcName: 'LndGetInfo', ctx: authContext, req: request }) + const response = await methods.AddApp({rpcName:'AddApp', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'AddApp': + case 'AddProduct': try { - if (!methods.AddApp) throw new Error('method: AddApp is not implemented') - const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) + if (!methods.AddProduct) throw new Error('method: AddProduct is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.AddAppRequestValidate(request) + const error = Types.AddProductRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.AddApp({ rpcName: 'AddApp', ctx: authContext, req: request }) + const response = await methods.AddProduct({rpcName:'AddProduct', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break case 'AuthApp': try { @@ -74,11 +74,11 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => { const error = Types.AuthAppRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.AuthApp({ rpcName: 'AuthApp', ctx: authContext, req: request }) + const response = await methods.AuthApp({rpcName:'AuthApp', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break case 'BanUser': try { @@ -90,98 +90,297 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => { const error = Types.BanUserRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.BanUser({ rpcName: 'BanUser', ctx: authContext, req: request }) + const response = await methods.BanUser({rpcName:'BanUser', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetSeed': + case 'BatchUser': try { - if (!methods.GetSeed) throw new Error('method: GetSeed is not implemented') - const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) + info.batch = true + const requests = req.body.requests as Types.UserMethodInputs[] + if (!Array.isArray(requests))throw new Error('invalid body, is not an array') + info.batchSize = requests.length + if (requests.length > 10) throw new Error('too many requests in the batch') + const ctx = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() - authCtx = authContext + authCtx = ctx stats.validate = stats.guard - const response = await methods.GetSeed({ rpcName: 'GetSeed', ctx: authContext }) + const responses = [] + const callsMetrics: Types.RequestMetric[] = [] + for (let i = 0; i < requests.length; i++) { + const operation = requests[i] + const opInfo: Types.RequestInfo = { rpcName: operation.rpcName, batch: true, nostr: true, batchSize: 0 } + const opStats: Types.RequestStats = { startMs, start: startTime, parse: stats.parse, guard: stats.guard, validate: 0n, handle: 0n } + try { + switch(operation.rpcName) { + case 'AddProduct': + if (!methods.AddProduct) { + throw new Error('method not defined: AddProduct') + } else { + const error = Types.AddProductRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.AddProduct({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'DecodeInvoice': + if (!methods.DecodeInvoice) { + throw new Error('method not defined: DecodeInvoice') + } else { + const error = Types.DecodeInvoiceRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.DecodeInvoice({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'EnrollAdminToken': + if (!methods.EnrollAdminToken) { + throw new Error('method not defined: EnrollAdminToken') + } else { + const error = Types.EnrollAdminTokenRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + await methods.EnrollAdminToken({...operation, ctx}); responses.push({ status: 'OK' }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetLNURLChannelLink': + if (!methods.GetLNURLChannelLink) { + throw new Error('method not defined: GetLNURLChannelLink') + } else { + opStats.validate = opStats.guard + const res = await methods.GetLNURLChannelLink({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetLnurlPayLink': + if (!methods.GetLnurlPayLink) { + throw new Error('method not defined: GetLnurlPayLink') + } else { + opStats.validate = opStats.guard + const res = await methods.GetLnurlPayLink({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetLnurlWithdrawLink': + if (!methods.GetLnurlWithdrawLink) { + throw new Error('method not defined: GetLnurlWithdrawLink') + } else { + opStats.validate = opStats.guard + const res = await methods.GetLnurlWithdrawLink({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetPaymentState': + if (!methods.GetPaymentState) { + throw new Error('method not defined: GetPaymentState') + } else { + const error = Types.GetPaymentStateRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.GetPaymentState({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetUserInfo': + if (!methods.GetUserInfo) { + throw new Error('method not defined: GetUserInfo') + } else { + opStats.validate = opStats.guard + const res = await methods.GetUserInfo({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'GetUserOperations': + if (!methods.GetUserOperations) { + throw new Error('method not defined: GetUserOperations') + } else { + const error = Types.GetUserOperationsRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.GetUserOperations({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'NewAddress': + if (!methods.NewAddress) { + throw new Error('method not defined: NewAddress') + } else { + const error = Types.NewAddressRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.NewAddress({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'NewInvoice': + if (!methods.NewInvoice) { + throw new Error('method not defined: NewInvoice') + } else { + const error = Types.NewInvoiceRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.NewInvoice({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'NewProductInvoice': + if (!methods.NewProductInvoice) { + throw new Error('method not defined: NewProductInvoice') + } else { + opStats.validate = opStats.guard + const res = await methods.NewProductInvoice({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'OpenChannel': + if (!methods.OpenChannel) { + throw new Error('method not defined: OpenChannel') + } else { + const error = Types.OpenChannelRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.OpenChannel({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'PayAddress': + if (!methods.PayAddress) { + throw new Error('method not defined: PayAddress') + } else { + const error = Types.PayAddressRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.PayAddress({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'PayInvoice': + if (!methods.PayInvoice) { + throw new Error('method not defined: PayInvoice') + } else { + const error = Types.PayInvoiceRequestValidate(operation.req) + opStats.validate = process.hrtime.bigint() + if (error !== null) throw error + const res = await methods.PayInvoice({...operation, ctx}); responses.push({ status: 'OK', ...res }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + case 'UserHealth': + if (!methods.UserHealth) { + throw new Error('method not defined: UserHealth') + } else { + opStats.validate = opStats.guard + await methods.UserHealth({...operation, ctx}); responses.push({ status: 'OK' }) + opStats.handle = process.hrtime.bigint() + callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) + } + break + default: + throw new Error('unkown rpcName') + } + } catch(ex) {const e = ex as any; logger.error(e.message || e); callsMetrics.push({ ...opInfo, ...opStats, ...ctx, error: e.message }); responses.push({ status: 'ERROR', reason: e.message || e })} + } stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) - opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + res({ status: 'OK', responses }) + opts.metricsCallback([{ ...info, ...stats, ...ctx }, ...callsMetrics]) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'ListChannels': + case 'CreateOneTimeInviteLink': try { - if (!methods.ListChannels) throw new Error('method: ListChannels is not implemented') + if (!methods.CreateOneTimeInviteLink) throw new Error('method: CreateOneTimeInviteLink is not implemented') const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - const response = await methods.ListChannels({ rpcName: 'ListChannels', ctx: authContext }) + const request = req.body + const error = Types.CreateOneTimeInviteLinkRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + const response = await methods.CreateOneTimeInviteLink({rpcName:'CreateOneTimeInviteLink', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetUsageMetrics': + case 'DecodeInvoice': try { - if (!methods.GetUsageMetrics) throw new Error('method: GetUsageMetrics is not implemented') - const authContext = await opts.NostrMetricsAuthGuard(req.appId, req.authIdentifier) + if (!methods.DecodeInvoice) throw new Error('method: DecodeInvoice is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - const response = await methods.GetUsageMetrics({ rpcName: 'GetUsageMetrics', ctx: authContext }) + const request = req.body + const error = Types.DecodeInvoiceRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + const response = await methods.DecodeInvoice({rpcName:'DecodeInvoice', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetAppsMetrics': + case 'EnrollAdminToken': try { - if (!methods.GetAppsMetrics) throw new Error('method: GetAppsMetrics is not implemented') - const authContext = await opts.NostrMetricsAuthGuard(req.appId, req.authIdentifier) + if (!methods.EnrollAdminToken) throw new Error('method: EnrollAdminToken is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.AppsMetricsRequestValidate(request) + const error = Types.EnrollAdminTokenRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.GetAppsMetrics({ rpcName: 'GetAppsMetrics', ctx: authContext, req: request }) + await methods.EnrollAdminToken({rpcName:'EnrollAdminToken', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK'}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetLndMetrics': + case 'GetAppsMetrics': try { - if (!methods.GetLndMetrics) throw new Error('method: GetLndMetrics is not implemented') + if (!methods.GetAppsMetrics) throw new Error('method: GetAppsMetrics is not implemented') const authContext = await opts.NostrMetricsAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.LndMetricsRequestValidate(request) + const error = Types.AppsMetricsRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.GetLndMetrics({ rpcName: 'GetLndMetrics', ctx: authContext, req: request }) + const response = await methods.GetAppsMetrics({rpcName:'GetAppsMetrics', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'CreateOneTimeInviteLink': + case 'GetHttpCreds': try { - if (!methods.CreateOneTimeInviteLink) throw new Error('method: CreateOneTimeInviteLink is not implemented') - const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) + if (!methods.GetHttpCreds) throw new Error('method: GetHttpCreds is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.CreateOneTimeInviteLinkRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.CreateOneTimeInviteLink({ rpcName: 'CreateOneTimeInviteLink', ctx: authContext, req: request }) + stats.validate = stats.guard + methods.GetHttpCreds({rpcName:'GetHttpCreds', ctx:authContext ,cb: (response, err) => { stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) - opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)} else { res({status: 'OK', ...response});opts.metricsCallback([{ ...info, ...stats, ...authContext }])} + }}) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break case 'GetInviteLinkState': try { @@ -193,537 +392,332 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => { const error = Types.GetInviteTokenStateRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.GetInviteLinkState({ rpcName: 'GetInviteLinkState', ctx: authContext, req: request }) + const response = await methods.GetInviteLinkState({rpcName:'GetInviteLinkState', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'EnrollAdminToken': + case 'GetLNURLChannelLink': try { - if (!methods.EnrollAdminToken) throw new Error('method: EnrollAdminToken is not implemented') + if (!methods.GetLNURLChannelLink) throw new Error('method: GetLNURLChannelLink is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.EnrollAdminTokenRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - await methods.EnrollAdminToken({ rpcName: 'EnrollAdminToken', ctx: authContext, req: request }) + stats.validate = stats.guard + const response = await methods.GetLNURLChannelLink({rpcName:'GetLNURLChannelLink', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK' }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'LinkNPubThroughToken': + case 'GetLiveUserOperations': try { - if (!methods.LinkNPubThroughToken) throw new Error('method: LinkNPubThroughToken is not implemented') - const authContext = await opts.NostrGuestWithPubAuthGuard(req.appId, req.authIdentifier) + if (!methods.GetLiveUserOperations) throw new Error('method: GetLiveUserOperations is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.LinkNPubThroughTokenRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - await methods.LinkNPubThroughToken({ rpcName: 'LinkNPubThroughToken', ctx: authContext, req: request }) + stats.validate = stats.guard + methods.GetLiveUserOperations({rpcName:'GetLiveUserOperations', ctx:authContext ,cb: (response, err) => { stats.handle = process.hrtime.bigint() - res({ status: 'OK' }) - opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)} else { res({status: 'OK', ...response});opts.metricsCallback([{ ...info, ...stats, ...authContext }])} + }}) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'UseInviteLink': + case 'GetLndMetrics': try { - if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented') - const authContext = await opts.NostrGuestWithPubAuthGuard(req.appId, req.authIdentifier) + if (!methods.GetLndMetrics) throw new Error('method: GetLndMetrics is not implemented') + const authContext = await opts.NostrMetricsAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.UseInviteLinkRequestValidate(request) + const error = Types.LndMetricsRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - await methods.UseInviteLink({ rpcName: 'UseInviteLink', ctx: authContext, req: request }) + const response = await methods.GetLndMetrics({rpcName:'GetLndMetrics', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK' }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'UserHealth': + case 'GetLnurlPayLink': try { - if (!methods.UserHealth) throw new Error('method: UserHealth is not implemented') + if (!methods.GetLnurlPayLink) throw new Error('method: GetLnurlPayLink is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext stats.validate = stats.guard - await methods.UserHealth({ rpcName: 'UserHealth', ctx: authContext }) + const response = await methods.GetLnurlPayLink({rpcName:'GetLnurlPayLink', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK' }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetUserInfo': + case 'GetLnurlWithdrawLink': try { - if (!methods.GetUserInfo) throw new Error('method: GetUserInfo is not implemented') + if (!methods.GetLnurlWithdrawLink) throw new Error('method: GetLnurlWithdrawLink is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext stats.validate = stats.guard - const response = await methods.GetUserInfo({ rpcName: 'GetUserInfo', ctx: authContext }) + const response = await methods.GetLnurlWithdrawLink({rpcName:'GetLnurlWithdrawLink', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'AddProduct': + case 'GetMigrationUpdate': try { - if (!methods.AddProduct) throw new Error('method: AddProduct is not implemented') + if (!methods.GetMigrationUpdate) throw new Error('method: GetMigrationUpdate is not implemented') + const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + stats.guard = process.hrtime.bigint() + authCtx = authContext + stats.validate = stats.guard + methods.GetMigrationUpdate({rpcName:'GetMigrationUpdate', ctx:authContext ,cb: (response, err) => { + stats.handle = process.hrtime.bigint() + if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)} else { res({status: 'OK', ...response});opts.metricsCallback([{ ...info, ...stats, ...authContext }])} + }}) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + break + case 'GetPaymentState': + try { + if (!methods.GetPaymentState) throw new Error('method: GetPaymentState is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.AddProductRequestValidate(request) + const error = Types.GetPaymentStateRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.AddProduct({ rpcName: 'AddProduct', ctx: authContext, req: request }) + const response = await methods.GetPaymentState({rpcName:'GetPaymentState', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'NewProductInvoice': + case 'GetSeed': try { - if (!methods.NewProductInvoice) throw new Error('method: NewProductInvoice is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.GetSeed) throw new Error('method: GetSeed is not implemented') + const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext stats.validate = stats.guard - const response = await methods.NewProductInvoice({ rpcName: 'NewProductInvoice', ctx: authContext, query: req.query || {} }) + const response = await methods.GetSeed({rpcName:'GetSeed', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetUserOperations': + case 'GetUsageMetrics': try { - if (!methods.GetUserOperations) throw new Error('method: GetUserOperations is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.GetUsageMetrics) throw new Error('method: GetUsageMetrics is not implemented') + const authContext = await opts.NostrMetricsAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.GetUserOperationsRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.GetUserOperations({ rpcName: 'GetUserOperations', ctx: authContext, req: request }) + stats.validate = stats.guard + const response = await methods.GetUsageMetrics({rpcName:'GetUsageMetrics', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'NewAddress': + case 'GetUserInfo': try { - if (!methods.NewAddress) throw new Error('method: NewAddress is not implemented') + if (!methods.GetUserInfo) throw new Error('method: GetUserInfo is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.NewAddressRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.NewAddress({ rpcName: 'NewAddress', ctx: authContext, req: request }) + stats.validate = stats.guard + const response = await methods.GetUserInfo({rpcName:'GetUserInfo', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'PayAddress': + case 'GetUserOperations': try { - if (!methods.PayAddress) throw new Error('method: PayAddress is not implemented') + if (!methods.GetUserOperations) throw new Error('method: GetUserOperations is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.PayAddressRequestValidate(request) + const error = Types.GetUserOperationsRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.PayAddress({ rpcName: 'PayAddress', ctx: authContext, req: request }) + const response = await methods.GetUserOperations({rpcName:'GetUserOperations', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'NewInvoice': + case 'LinkNPubThroughToken': try { - if (!methods.NewInvoice) throw new Error('method: NewInvoice is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.LinkNPubThroughToken) throw new Error('method: LinkNPubThroughToken is not implemented') + const authContext = await opts.NostrGuestWithPubAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.NewInvoiceRequestValidate(request) + const error = Types.LinkNPubThroughTokenRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.NewInvoice({ rpcName: 'NewInvoice', ctx: authContext, req: request }) + await methods.LinkNPubThroughToken({rpcName:'LinkNPubThroughToken', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK'}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'DecodeInvoice': + case 'ListChannels': try { - if (!methods.DecodeInvoice) throw new Error('method: DecodeInvoice is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.ListChannels) throw new Error('method: ListChannels is not implemented') + const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - const request = req.body - const error = Types.DecodeInvoiceRequestValidate(request) - stats.validate = process.hrtime.bigint() - if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.DecodeInvoice({ rpcName: 'DecodeInvoice', ctx: authContext, req: request }) + stats.validate = stats.guard + const response = await methods.ListChannels({rpcName:'ListChannels', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'PayInvoice': + case 'LndGetInfo': try { - if (!methods.PayInvoice) throw new Error('method: PayInvoice is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.LndGetInfo) throw new Error('method: LndGetInfo is not implemented') + const authContext = await opts.NostrAdminAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.PayInvoiceRequestValidate(request) + const error = Types.LndGetInfoRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.PayInvoice({ rpcName: 'PayInvoice', ctx: authContext, req: request }) + const response = await methods.LndGetInfo({rpcName:'LndGetInfo', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetPaymentState': + case 'NewAddress': try { - if (!methods.GetPaymentState) throw new Error('method: GetPaymentState is not implemented') + if (!methods.NewAddress) throw new Error('method: NewAddress is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.GetPaymentStateRequestValidate(request) + const error = Types.NewAddressRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.GetPaymentState({ rpcName: 'GetPaymentState', ctx: authContext, req: request }) + const response = await methods.NewAddress({rpcName:'NewAddress', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'OpenChannel': + case 'NewInvoice': try { - if (!methods.OpenChannel) throw new Error('method: OpenChannel is not implemented') + if (!methods.NewInvoice) throw new Error('method: NewInvoice is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext const request = req.body - const error = Types.OpenChannelRequestValidate(request) + const error = Types.NewInvoiceRequestValidate(request) stats.validate = process.hrtime.bigint() if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) - const response = await methods.OpenChannel({ rpcName: 'OpenChannel', ctx: authContext, req: request }) + const response = await methods.NewInvoice({rpcName:'NewInvoice', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetLnurlWithdrawLink': + case 'NewProductInvoice': try { - if (!methods.GetLnurlWithdrawLink) throw new Error('method: GetLnurlWithdrawLink is not implemented') + if (!methods.NewProductInvoice) throw new Error('method: NewProductInvoice is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext stats.validate = stats.guard - const response = await methods.GetLnurlWithdrawLink({ rpcName: 'GetLnurlWithdrawLink', ctx: authContext }) + const response = await methods.NewProductInvoice({rpcName:'NewProductInvoice', ctx:authContext ,query: req.query||{}}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetLnurlPayLink': + case 'OpenChannel': try { - if (!methods.GetLnurlPayLink) throw new Error('method: GetLnurlPayLink is not implemented') + if (!methods.OpenChannel) throw new Error('method: OpenChannel is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - const response = await methods.GetLnurlPayLink({ rpcName: 'GetLnurlPayLink', ctx: authContext }) + const request = req.body + const error = Types.OpenChannelRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + const response = await methods.OpenChannel({rpcName:'OpenChannel', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetLNURLChannelLink': + case 'PayAddress': try { - if (!methods.GetLNURLChannelLink) throw new Error('method: GetLNURLChannelLink is not implemented') + if (!methods.PayAddress) throw new Error('method: PayAddress is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - const response = await methods.GetLNURLChannelLink({ rpcName: 'GetLNURLChannelLink', ctx: authContext }) + const request = req.body + const error = Types.PayAddressRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + const response = await methods.PayAddress({rpcName:'PayAddress', ctx:authContext , req: request}) stats.handle = process.hrtime.bigint() - res({ status: 'OK', ...response }) + res({status: 'OK', ...response}) opts.metricsCallback([{ ...info, ...stats, ...authContext }]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetLiveUserOperations': + case 'PayInvoice': try { - if (!methods.GetLiveUserOperations) throw new Error('method: GetLiveUserOperations is not implemented') + if (!methods.PayInvoice) throw new Error('method: PayInvoice is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - methods.GetLiveUserOperations({ - rpcName: 'GetLiveUserOperations', ctx: authContext, cb: (response, err) => { - stats.handle = process.hrtime.bigint() - if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback) } else { res({ status: 'OK', ...response }); opts.metricsCallback([{ ...info, ...stats, ...authContext }]) } - } - }) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + const request = req.body + const error = Types.PayInvoiceRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + const response = await methods.PayInvoice({rpcName:'PayInvoice', ctx:authContext , req: request}) + stats.handle = process.hrtime.bigint() + res({status: 'OK', ...response}) + opts.metricsCallback([{ ...info, ...stats, ...authContext }]) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetMigrationUpdate': + case 'UseInviteLink': try { - if (!methods.GetMigrationUpdate) throw new Error('method: GetMigrationUpdate is not implemented') - const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) + if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented') + const authContext = await opts.NostrGuestWithPubAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext - stats.validate = stats.guard - methods.GetMigrationUpdate({ - rpcName: 'GetMigrationUpdate', ctx: authContext, cb: (response, err) => { - stats.handle = process.hrtime.bigint() - if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback) } else { res({ status: 'OK', ...response }); opts.metricsCallback([{ ...info, ...stats, ...authContext }]) } - } - }) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + const request = req.body + const error = Types.UseInviteLinkRequestValidate(request) + stats.validate = process.hrtime.bigint() + if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback) + await methods.UseInviteLink({rpcName:'UseInviteLink', ctx:authContext , req: request}) + stats.handle = process.hrtime.bigint() + res({status: 'OK'}) + opts.metricsCallback([{ ...info, ...stats, ...authContext }]) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - case 'GetHttpCreds': + case 'UserHealth': try { - if (!methods.GetHttpCreds) throw new Error('method: GetHttpCreds is not implemented') + if (!methods.UserHealth) throw new Error('method: UserHealth is not implemented') const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) stats.guard = process.hrtime.bigint() authCtx = authContext stats.validate = stats.guard - methods.GetHttpCreds({ - rpcName: 'GetHttpCreds', ctx: authContext, cb: (response, err) => { - stats.handle = process.hrtime.bigint() - if (err) { logErrorAndReturnResponse(err, err.message, res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback) } else { res({ status: 'OK', ...response }); opts.metricsCallback([{ ...info, ...stats, ...authContext }]) } - } - }) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } - break - case 'BatchUser': - try { - info.batch = true - const requests = req.body.requests as Types.UserMethodInputs[] - if (!Array.isArray(requests)) throw new Error('invalid body, is not an array') - info.batchSize = requests.length - if (requests.length > 10) throw new Error('too many requests in the batch') - const ctx = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier) - stats.guard = process.hrtime.bigint() - authCtx = ctx - stats.validate = stats.guard - const responses = [] - const callsMetrics: Types.RequestMetric[] = [] - for (let i = 0; i < requests.length; i++) { - const operation = requests[i] - const opInfo: Types.RequestInfo = { rpcName: operation.rpcName, batch: true, nostr: true, batchSize: 0 } - const opStats: Types.RequestStats = { startMs, start: startTime, parse: stats.parse, guard: stats.guard, validate: 0n, handle: 0n } - try { - switch (operation.rpcName) { - case 'EnrollAdminToken': - if (!methods.EnrollAdminToken) { - throw new Error('method not defined: EnrollAdminToken') - } else { - const error = Types.EnrollAdminTokenRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - await methods.EnrollAdminToken({ ...operation, ctx }); responses.push({ status: 'OK' }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'UserHealth': - if (!methods.UserHealth) { - throw new Error('method not defined: UserHealth') - } else { - opStats.validate = opStats.guard - await methods.UserHealth({ ...operation, ctx }); responses.push({ status: 'OK' }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetUserInfo': - if (!methods.GetUserInfo) { - throw new Error('method not defined: GetUserInfo') - } else { - opStats.validate = opStats.guard - const res = await methods.GetUserInfo({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'AddProduct': - if (!methods.AddProduct) { - throw new Error('method not defined: AddProduct') - } else { - const error = Types.AddProductRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.AddProduct({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'NewProductInvoice': - if (!methods.NewProductInvoice) { - throw new Error('method not defined: NewProductInvoice') - } else { - opStats.validate = opStats.guard - const res = await methods.NewProductInvoice({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetUserOperations': - if (!methods.GetUserOperations) { - throw new Error('method not defined: GetUserOperations') - } else { - const error = Types.GetUserOperationsRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.GetUserOperations({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'NewAddress': - if (!methods.NewAddress) { - throw new Error('method not defined: NewAddress') - } else { - const error = Types.NewAddressRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.NewAddress({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'PayAddress': - if (!methods.PayAddress) { - throw new Error('method not defined: PayAddress') - } else { - const error = Types.PayAddressRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.PayAddress({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'NewInvoice': - if (!methods.NewInvoice) { - throw new Error('method not defined: NewInvoice') - } else { - const error = Types.NewInvoiceRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.NewInvoice({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'DecodeInvoice': - if (!methods.DecodeInvoice) { - throw new Error('method not defined: DecodeInvoice') - } else { - const error = Types.DecodeInvoiceRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.DecodeInvoice({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'PayInvoice': - if (!methods.PayInvoice) { - throw new Error('method not defined: PayInvoice') - } else { - const error = Types.PayInvoiceRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.PayInvoice({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetPaymentState': - if (!methods.GetPaymentState) { - throw new Error('method not defined: GetPaymentState') - } else { - const error = Types.GetPaymentStateRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.GetPaymentState({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'OpenChannel': - if (!methods.OpenChannel) { - throw new Error('method not defined: OpenChannel') - } else { - const error = Types.OpenChannelRequestValidate(operation.req) - opStats.validate = process.hrtime.bigint() - if (error !== null) throw error - const res = await methods.OpenChannel({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetLnurlWithdrawLink': - if (!methods.GetLnurlWithdrawLink) { - throw new Error('method not defined: GetLnurlWithdrawLink') - } else { - opStats.validate = opStats.guard - const res = await methods.GetLnurlWithdrawLink({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetLnurlPayLink': - if (!methods.GetLnurlPayLink) { - throw new Error('method not defined: GetLnurlPayLink') - } else { - opStats.validate = opStats.guard - const res = await methods.GetLnurlPayLink({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - case 'GetLNURLChannelLink': - if (!methods.GetLNURLChannelLink) { - throw new Error('method not defined: GetLNURLChannelLink') - } else { - opStats.validate = opStats.guard - const res = await methods.GetLNURLChannelLink({ ...operation, ctx }); responses.push({ status: 'OK', ...res }) - opStats.handle = process.hrtime.bigint() - callsMetrics.push({ ...opInfo, ...opStats, ...ctx }) - } - break - default: - throw new Error('unkown rpcName') - } - } catch (ex) { const e = ex as any; logger.error(e.message || e); callsMetrics.push({ ...opInfo, ...opStats, ...ctx, error: e.message }); responses.push({ status: 'ERROR', reason: e.message || e }) } - } + await methods.UserHealth({rpcName:'UserHealth', ctx:authContext }) stats.handle = process.hrtime.bigint() - res({ status: 'OK', responses }) - opts.metricsCallback([{ ...info, ...stats, ...ctx }, ...callsMetrics]) - } catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } + res({status: 'OK'}) + opts.metricsCallback([{ ...info, ...stats, ...authContext }]) + }catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e } break - default: logger.error('unknown rpc call name from nostr event:' + req.rpcName) + default: logger.error('unknown rpc call name from nostr event:'+req.rpcName) } } } diff --git a/src/Api/pub/autogenerated/ts/types.ts b/src/Api/pub/autogenerated/ts/types.ts index e819c110..44149aea 100644 --- a/src/Api/pub/autogenerated/ts/types.ts +++ b/src/Api/pub/autogenerated/ts/types.ts @@ -2,7 +2,7 @@ export type ResultError = { status: 'ERROR', reason: string } export type RequestInfo = { rpcName: string, batch: boolean, nostr: boolean, batchSize: number } -export type RequestStats = { startMs: number, start: bigint, parse: bigint, guard: bigint, validate: bigint, handle: bigint } +export type RequestStats = { startMs:number, start:bigint, parse: bigint, guard: bigint, validate: bigint, handle: bigint } export type RequestMetric = AuthContext & RequestInfo & RequestStats & { error?: string } export type AdminContext = { admin_id: string @@ -38,109 +38,109 @@ export type UserMethodInputs = AddProduct_Input | DecodeInvoice_Input | EnrollAd export type UserMethodOutputs = AddProduct_Output | DecodeInvoice_Output | EnrollAdminToken_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | OpenChannel_Output | PayAddress_Output | PayInvoice_Output | UserHealth_Output export type AuthContext = AdminContext | AppContext | GuestContext | GuestWithPubContext | MetricsContext | UserContext -export type AddApp_Input = { rpcName: 'AddApp', req: AddAppRequest } +export type AddApp_Input = {rpcName:'AddApp', req: AddAppRequest} export type AddApp_Output = ResultError | ({ status: 'OK' } & AuthApp) -export type AddAppInvoice_Input = { rpcName: 'AddAppInvoice', req: AddAppInvoiceRequest } +export type AddAppInvoice_Input = {rpcName:'AddAppInvoice', req: AddAppInvoiceRequest} export type AddAppInvoice_Output = ResultError | ({ status: 'OK' } & NewInvoiceResponse) -export type AddAppUser_Input = { rpcName: 'AddAppUser', req: AddAppUserRequest } +export type AddAppUser_Input = {rpcName:'AddAppUser', req: AddAppUserRequest} export type AddAppUser_Output = ResultError | ({ status: 'OK' } & AppUser) -export type AddAppUserInvoice_Input = { rpcName: 'AddAppUserInvoice', req: AddAppUserInvoiceRequest } +export type AddAppUserInvoice_Input = {rpcName:'AddAppUserInvoice', req: AddAppUserInvoiceRequest} export type AddAppUserInvoice_Output = ResultError | ({ status: 'OK' } & NewInvoiceResponse) -export type AddProduct_Input = { rpcName: 'AddProduct', req: AddProductRequest } +export type AddProduct_Input = {rpcName:'AddProduct', req: AddProductRequest} export type AddProduct_Output = ResultError | ({ status: 'OK' } & Product) -export type AuthApp_Input = { rpcName: 'AuthApp', req: AuthAppRequest } +export type AuthApp_Input = {rpcName:'AuthApp', req: AuthAppRequest} export type AuthApp_Output = ResultError | ({ status: 'OK' } & AuthApp) -export type BanUser_Input = { rpcName: 'BanUser', req: BanUserRequest } +export type BanUser_Input = {rpcName:'BanUser', req: BanUserRequest} export type BanUser_Output = ResultError | ({ status: 'OK' } & BanUserResponse) export type BatchUser_Input = UserMethodInputs export type BatchUser_Output = UserMethodOutputs -export type CreateOneTimeInviteLink_Input = { rpcName: 'CreateOneTimeInviteLink', req: CreateOneTimeInviteLinkRequest } +export type CreateOneTimeInviteLink_Input = {rpcName:'CreateOneTimeInviteLink', req: CreateOneTimeInviteLinkRequest} export type CreateOneTimeInviteLink_Output = ResultError | ({ status: 'OK' } & CreateOneTimeInviteLinkResponse) -export type DecodeInvoice_Input = { rpcName: 'DecodeInvoice', req: DecodeInvoiceRequest } +export type DecodeInvoice_Input = {rpcName:'DecodeInvoice', req: DecodeInvoiceRequest} export type DecodeInvoice_Output = ResultError | ({ status: 'OK' } & DecodeInvoiceResponse) -export type EncryptionExchange_Input = { rpcName: 'EncryptionExchange', req: EncryptionExchangeRequest } +export type EncryptionExchange_Input = {rpcName:'EncryptionExchange', req: EncryptionExchangeRequest} export type EncryptionExchange_Output = ResultError | { status: 'OK' } -export type EnrollAdminToken_Input = { rpcName: 'EnrollAdminToken', req: EnrollAdminTokenRequest } +export type EnrollAdminToken_Input = {rpcName:'EnrollAdminToken', req: EnrollAdminTokenRequest} export type EnrollAdminToken_Output = ResultError | { status: 'OK' } -export type GetApp_Input = { rpcName: 'GetApp' } +export type GetApp_Input = {rpcName:'GetApp'} export type GetApp_Output = ResultError | ({ status: 'OK' } & Application) -export type GetAppUser_Input = { rpcName: 'GetAppUser', req: GetAppUserRequest } +export type GetAppUser_Input = {rpcName:'GetAppUser', req: GetAppUserRequest} export type GetAppUser_Output = ResultError | ({ status: 'OK' } & AppUser) -export type GetAppUserLNURLInfo_Input = { rpcName: 'GetAppUserLNURLInfo', req: GetAppUserLNURLInfoRequest } +export type GetAppUserLNURLInfo_Input = {rpcName:'GetAppUserLNURLInfo', req: GetAppUserLNURLInfoRequest} export type GetAppUserLNURLInfo_Output = ResultError | ({ status: 'OK' } & LnurlPayInfoResponse) -export type GetAppsMetrics_Input = { rpcName: 'GetAppsMetrics', req: AppsMetricsRequest } +export type GetAppsMetrics_Input = {rpcName:'GetAppsMetrics', req: AppsMetricsRequest} export type GetAppsMetrics_Output = ResultError | ({ status: 'OK' } & AppsMetrics) -export type GetHttpCreds_Input = { rpcName: 'GetHttpCreds', cb: (res: HttpCreds, err: Error | null) => void } +export type GetHttpCreds_Input = {rpcName:'GetHttpCreds', cb:(res: HttpCreds, err:Error|null)=> void} export type GetHttpCreds_Output = ResultError | { status: 'OK' } -export type GetInviteLinkState_Input = { rpcName: 'GetInviteLinkState', req: GetInviteTokenStateRequest } +export type GetInviteLinkState_Input = {rpcName:'GetInviteLinkState', req: GetInviteTokenStateRequest} export type GetInviteLinkState_Output = ResultError | ({ status: 'OK' } & GetInviteTokenStateResponse) -export type GetLNURLChannelLink_Input = { rpcName: 'GetLNURLChannelLink' } +export type GetLNURLChannelLink_Input = {rpcName:'GetLNURLChannelLink'} export type GetLNURLChannelLink_Output = ResultError | ({ status: 'OK' } & LnurlLinkResponse) -export type GetLiveUserOperations_Input = { rpcName: 'GetLiveUserOperations', cb: (res: LiveUserOperation, err: Error | null) => void } +export type GetLiveUserOperations_Input = {rpcName:'GetLiveUserOperations', cb:(res: LiveUserOperation, err:Error|null)=> void} export type GetLiveUserOperations_Output = ResultError | { status: 'OK' } -export type GetLndMetrics_Input = { rpcName: 'GetLndMetrics', req: LndMetricsRequest } +export type GetLndMetrics_Input = {rpcName:'GetLndMetrics', req: LndMetricsRequest} export type GetLndMetrics_Output = ResultError | ({ status: 'OK' } & LndMetrics) export type GetLnurlPayInfo_Query = { k1?: string } -export type GetLnurlPayInfo_Input = { rpcName: 'GetLnurlPayInfo', query: GetLnurlPayInfo_Query } +export type GetLnurlPayInfo_Input = {rpcName:'GetLnurlPayInfo', query: GetLnurlPayInfo_Query} export type GetLnurlPayInfo_Output = ResultError | ({ status: 'OK' } & LnurlPayInfoResponse) -export type GetLnurlPayLink_Input = { rpcName: 'GetLnurlPayLink' } +export type GetLnurlPayLink_Input = {rpcName:'GetLnurlPayLink'} export type GetLnurlPayLink_Output = ResultError | ({ status: 'OK' } & LnurlLinkResponse) export type GetLnurlWithdrawInfo_Query = { k1?: string } -export type GetLnurlWithdrawInfo_Input = { rpcName: 'GetLnurlWithdrawInfo', query: GetLnurlWithdrawInfo_Query } +export type GetLnurlWithdrawInfo_Input = {rpcName:'GetLnurlWithdrawInfo', query: GetLnurlWithdrawInfo_Query} export type GetLnurlWithdrawInfo_Output = ResultError | ({ status: 'OK' } & LnurlWithdrawInfoResponse) -export type GetLnurlWithdrawLink_Input = { rpcName: 'GetLnurlWithdrawLink' } +export type GetLnurlWithdrawLink_Input = {rpcName:'GetLnurlWithdrawLink'} export type GetLnurlWithdrawLink_Output = ResultError | ({ status: 'OK' } & LnurlLinkResponse) -export type GetMigrationUpdate_Input = { rpcName: 'GetMigrationUpdate', cb: (res: MigrationUpdate, err: Error | null) => void } +export type GetMigrationUpdate_Input = {rpcName:'GetMigrationUpdate', cb:(res: MigrationUpdate, err:Error|null)=> void} export type GetMigrationUpdate_Output = ResultError | { status: 'OK' } -export type GetPaymentState_Input = { rpcName: 'GetPaymentState', req: GetPaymentStateRequest } +export type GetPaymentState_Input = {rpcName:'GetPaymentState', req: GetPaymentStateRequest} export type GetPaymentState_Output = ResultError | ({ status: 'OK' } & PaymentState) -export type GetSeed_Input = { rpcName: 'GetSeed' } +export type GetSeed_Input = {rpcName:'GetSeed'} export type GetSeed_Output = ResultError | ({ status: 'OK' } & LndSeed) -export type GetUsageMetrics_Input = { rpcName: 'GetUsageMetrics' } +export type GetUsageMetrics_Input = {rpcName:'GetUsageMetrics'} export type GetUsageMetrics_Output = ResultError | ({ status: 'OK' } & UsageMetrics) -export type GetUserInfo_Input = { rpcName: 'GetUserInfo' } +export type GetUserInfo_Input = {rpcName:'GetUserInfo'} export type GetUserInfo_Output = ResultError | ({ status: 'OK' } & UserInfo) -export type GetUserOperations_Input = { rpcName: 'GetUserOperations', req: GetUserOperationsRequest } +export type GetUserOperations_Input = {rpcName:'GetUserOperations', req: GetUserOperationsRequest} export type GetUserOperations_Output = ResultError | ({ status: 'OK' } & GetUserOperationsResponse) export type HandleLnurlAddress_RouteParams = { address_name: string } -export type HandleLnurlAddress_Input = { rpcName: 'HandleLnurlAddress', params: HandleLnurlAddress_RouteParams } +export type HandleLnurlAddress_Input = {rpcName:'HandleLnurlAddress', params: HandleLnurlAddress_RouteParams} export type HandleLnurlAddress_Output = ResultError | ({ status: 'OK' } & LnurlPayInfoResponse) export type HandleLnurlPay_Query = { @@ -149,133 +149,133 @@ export type HandleLnurlPay_Query = { lnurl?: string nostr?: string } -export type HandleLnurlPay_Input = { rpcName: 'HandleLnurlPay', query: HandleLnurlPay_Query } +export type HandleLnurlPay_Input = {rpcName:'HandleLnurlPay', query: HandleLnurlPay_Query} export type HandleLnurlPay_Output = ResultError | ({ status: 'OK' } & HandleLnurlPayResponse) export type HandleLnurlWithdraw_Query = { k1?: string pr?: string } -export type HandleLnurlWithdraw_Input = { rpcName: 'HandleLnurlWithdraw', query: HandleLnurlWithdraw_Query } +export type HandleLnurlWithdraw_Input = {rpcName:'HandleLnurlWithdraw', query: HandleLnurlWithdraw_Query} export type HandleLnurlWithdraw_Output = ResultError | { status: 'OK' } -export type Health_Input = { rpcName: 'Health' } +export type Health_Input = {rpcName:'Health'} export type Health_Output = ResultError | { status: 'OK' } -export type LinkNPubThroughToken_Input = { rpcName: 'LinkNPubThroughToken', req: LinkNPubThroughTokenRequest } +export type LinkNPubThroughToken_Input = {rpcName:'LinkNPubThroughToken', req: LinkNPubThroughTokenRequest} export type LinkNPubThroughToken_Output = ResultError | { status: 'OK' } -export type ListChannels_Input = { rpcName: 'ListChannels' } +export type ListChannels_Input = {rpcName:'ListChannels'} export type ListChannels_Output = ResultError | ({ status: 'OK' } & LndChannels) -export type LndGetInfo_Input = { rpcName: 'LndGetInfo', req: LndGetInfoRequest } +export type LndGetInfo_Input = {rpcName:'LndGetInfo', req: LndGetInfoRequest} export type LndGetInfo_Output = ResultError | ({ status: 'OK' } & LndGetInfoResponse) -export type NewAddress_Input = { rpcName: 'NewAddress', req: NewAddressRequest } +export type NewAddress_Input = {rpcName:'NewAddress', req: NewAddressRequest} export type NewAddress_Output = ResultError | ({ status: 'OK' } & NewAddressResponse) -export type NewInvoice_Input = { rpcName: 'NewInvoice', req: NewInvoiceRequest } +export type NewInvoice_Input = {rpcName:'NewInvoice', req: NewInvoiceRequest} export type NewInvoice_Output = ResultError | ({ status: 'OK' } & NewInvoiceResponse) export type NewProductInvoice_Query = { id?: string } -export type NewProductInvoice_Input = { rpcName: 'NewProductInvoice', query: NewProductInvoice_Query } +export type NewProductInvoice_Input = {rpcName:'NewProductInvoice', query: NewProductInvoice_Query} export type NewProductInvoice_Output = ResultError | ({ status: 'OK' } & NewInvoiceResponse) -export type OpenChannel_Input = { rpcName: 'OpenChannel', req: OpenChannelRequest } +export type OpenChannel_Input = {rpcName:'OpenChannel', req: OpenChannelRequest} export type OpenChannel_Output = ResultError | ({ status: 'OK' } & OpenChannelResponse) -export type PayAddress_Input = { rpcName: 'PayAddress', req: PayAddressRequest } +export type PayAddress_Input = {rpcName:'PayAddress', req: PayAddressRequest} export type PayAddress_Output = ResultError | ({ status: 'OK' } & PayAddressResponse) -export type PayAppUserInvoice_Input = { rpcName: 'PayAppUserInvoice', req: PayAppUserInvoiceRequest } +export type PayAppUserInvoice_Input = {rpcName:'PayAppUserInvoice', req: PayAppUserInvoiceRequest} export type PayAppUserInvoice_Output = ResultError | ({ status: 'OK' } & PayInvoiceResponse) -export type PayInvoice_Input = { rpcName: 'PayInvoice', req: PayInvoiceRequest } +export type PayInvoice_Input = {rpcName:'PayInvoice', req: PayInvoiceRequest} export type PayInvoice_Output = ResultError | ({ status: 'OK' } & PayInvoiceResponse) -export type RequestNPubLinkingToken_Input = { rpcName: 'RequestNPubLinkingToken', req: RequestNPubLinkingTokenRequest } +export type RequestNPubLinkingToken_Input = {rpcName:'RequestNPubLinkingToken', req: RequestNPubLinkingTokenRequest} export type RequestNPubLinkingToken_Output = ResultError | ({ status: 'OK' } & RequestNPubLinkingTokenResponse) -export type ResetNPubLinkingToken_Input = { rpcName: 'ResetNPubLinkingToken', req: RequestNPubLinkingTokenRequest } +export type ResetNPubLinkingToken_Input = {rpcName:'ResetNPubLinkingToken', req: RequestNPubLinkingTokenRequest} export type ResetNPubLinkingToken_Output = ResultError | ({ status: 'OK' } & RequestNPubLinkingTokenResponse) -export type SendAppUserToAppPayment_Input = { rpcName: 'SendAppUserToAppPayment', req: SendAppUserToAppPaymentRequest } +export type SendAppUserToAppPayment_Input = {rpcName:'SendAppUserToAppPayment', req: SendAppUserToAppPaymentRequest} export type SendAppUserToAppPayment_Output = ResultError | { status: 'OK' } -export type SendAppUserToAppUserPayment_Input = { rpcName: 'SendAppUserToAppUserPayment', req: SendAppUserToAppUserPaymentRequest } +export type SendAppUserToAppUserPayment_Input = {rpcName:'SendAppUserToAppUserPayment', req: SendAppUserToAppUserPaymentRequest} export type SendAppUserToAppUserPayment_Output = ResultError | { status: 'OK' } -export type SetMockAppBalance_Input = { rpcName: 'SetMockAppBalance', req: SetMockAppBalanceRequest } +export type SetMockAppBalance_Input = {rpcName:'SetMockAppBalance', req: SetMockAppBalanceRequest} export type SetMockAppBalance_Output = ResultError | { status: 'OK' } -export type SetMockAppUserBalance_Input = { rpcName: 'SetMockAppUserBalance', req: SetMockAppUserBalanceRequest } +export type SetMockAppUserBalance_Input = {rpcName:'SetMockAppUserBalance', req: SetMockAppUserBalanceRequest} export type SetMockAppUserBalance_Output = ResultError | { status: 'OK' } -export type SetMockInvoiceAsPaid_Input = { rpcName: 'SetMockInvoiceAsPaid', req: SetMockInvoiceAsPaidRequest } +export type SetMockInvoiceAsPaid_Input = {rpcName:'SetMockInvoiceAsPaid', req: SetMockInvoiceAsPaidRequest} export type SetMockInvoiceAsPaid_Output = ResultError | { status: 'OK' } -export type UseInviteLink_Input = { rpcName: 'UseInviteLink', req: UseInviteLinkRequest } +export type UseInviteLink_Input = {rpcName:'UseInviteLink', req: UseInviteLinkRequest} export type UseInviteLink_Output = ResultError | { status: 'OK' } -export type UserHealth_Input = { rpcName: 'UserHealth' } +export type UserHealth_Input = {rpcName:'UserHealth'} export type UserHealth_Output = ResultError | { status: 'OK' } export type ServerMethods = { - AddApp?: (req: AddApp_Input & { ctx: AdminContext }) => Promise - AddAppInvoice?: (req: AddAppInvoice_Input & { ctx: AppContext }) => Promise - AddAppUser?: (req: AddAppUser_Input & { ctx: AppContext }) => Promise - AddAppUserInvoice?: (req: AddAppUserInvoice_Input & { ctx: AppContext }) => Promise - AddProduct?: (req: AddProduct_Input & { ctx: UserContext }) => Promise - AuthApp?: (req: AuthApp_Input & { ctx: AdminContext }) => Promise - BanUser?: (req: BanUser_Input & { ctx: AdminContext }) => Promise - CreateOneTimeInviteLink?: (req: CreateOneTimeInviteLink_Input & { ctx: AdminContext }) => Promise - DecodeInvoice?: (req: DecodeInvoice_Input & { ctx: UserContext }) => Promise - EncryptionExchange?: (req: EncryptionExchange_Input & { ctx: GuestContext }) => Promise - EnrollAdminToken?: (req: EnrollAdminToken_Input & { ctx: UserContext }) => Promise - GetApp?: (req: GetApp_Input & { ctx: AppContext }) => Promise - GetAppUser?: (req: GetAppUser_Input & { ctx: AppContext }) => Promise - GetAppUserLNURLInfo?: (req: GetAppUserLNURLInfo_Input & { ctx: AppContext }) => Promise - GetAppsMetrics?: (req: GetAppsMetrics_Input & { ctx: MetricsContext }) => Promise - GetHttpCreds?: (req: GetHttpCreds_Input & { ctx: UserContext }) => Promise - GetInviteLinkState?: (req: GetInviteLinkState_Input & { ctx: AdminContext }) => Promise - GetLNURLChannelLink?: (req: GetLNURLChannelLink_Input & { ctx: UserContext }) => Promise - GetLiveUserOperations?: (req: GetLiveUserOperations_Input & { ctx: UserContext }) => Promise - GetLndMetrics?: (req: GetLndMetrics_Input & { ctx: MetricsContext }) => Promise - GetLnurlPayInfo?: (req: GetLnurlPayInfo_Input & { ctx: GuestContext }) => Promise - GetLnurlPayLink?: (req: GetLnurlPayLink_Input & { ctx: UserContext }) => Promise - GetLnurlWithdrawInfo?: (req: GetLnurlWithdrawInfo_Input & { ctx: GuestContext }) => Promise - GetLnurlWithdrawLink?: (req: GetLnurlWithdrawLink_Input & { ctx: UserContext }) => Promise - GetMigrationUpdate?: (req: GetMigrationUpdate_Input & { ctx: UserContext }) => Promise - GetPaymentState?: (req: GetPaymentState_Input & { ctx: UserContext }) => Promise - GetSeed?: (req: GetSeed_Input & { ctx: AdminContext }) => Promise - GetUsageMetrics?: (req: GetUsageMetrics_Input & { ctx: MetricsContext }) => Promise - GetUserInfo?: (req: GetUserInfo_Input & { ctx: UserContext }) => Promise - GetUserOperations?: (req: GetUserOperations_Input & { ctx: UserContext }) => Promise - HandleLnurlAddress?: (req: HandleLnurlAddress_Input & { ctx: GuestContext }) => Promise - HandleLnurlPay?: (req: HandleLnurlPay_Input & { ctx: GuestContext }) => Promise - HandleLnurlWithdraw?: (req: HandleLnurlWithdraw_Input & { ctx: GuestContext }) => Promise - Health?: (req: Health_Input & { ctx: GuestContext }) => Promise - LinkNPubThroughToken?: (req: LinkNPubThroughToken_Input & { ctx: GuestWithPubContext }) => Promise - ListChannels?: (req: ListChannels_Input & { ctx: AdminContext }) => Promise - LndGetInfo?: (req: LndGetInfo_Input & { ctx: AdminContext }) => Promise - NewAddress?: (req: NewAddress_Input & { ctx: UserContext }) => Promise - NewInvoice?: (req: NewInvoice_Input & { ctx: UserContext }) => Promise - NewProductInvoice?: (req: NewProductInvoice_Input & { ctx: UserContext }) => Promise - OpenChannel?: (req: OpenChannel_Input & { ctx: UserContext }) => Promise - PayAddress?: (req: PayAddress_Input & { ctx: UserContext }) => Promise - PayAppUserInvoice?: (req: PayAppUserInvoice_Input & { ctx: AppContext }) => Promise - PayInvoice?: (req: PayInvoice_Input & { ctx: UserContext }) => Promise - RequestNPubLinkingToken?: (req: RequestNPubLinkingToken_Input & { ctx: AppContext }) => Promise - ResetNPubLinkingToken?: (req: ResetNPubLinkingToken_Input & { ctx: AppContext }) => Promise - SendAppUserToAppPayment?: (req: SendAppUserToAppPayment_Input & { ctx: AppContext }) => Promise - SendAppUserToAppUserPayment?: (req: SendAppUserToAppUserPayment_Input & { ctx: AppContext }) => Promise - SetMockAppBalance?: (req: SetMockAppBalance_Input & { ctx: AppContext }) => Promise - SetMockAppUserBalance?: (req: SetMockAppUserBalance_Input & { ctx: AppContext }) => Promise - SetMockInvoiceAsPaid?: (req: SetMockInvoiceAsPaid_Input & { ctx: GuestContext }) => Promise - UseInviteLink?: (req: UseInviteLink_Input & { ctx: GuestWithPubContext }) => Promise - UserHealth?: (req: UserHealth_Input & { ctx: UserContext }) => Promise + AddApp?: (req: AddApp_Input & {ctx: AdminContext }) => Promise + AddAppInvoice?: (req: AddAppInvoice_Input & {ctx: AppContext }) => Promise + AddAppUser?: (req: AddAppUser_Input & {ctx: AppContext }) => Promise + AddAppUserInvoice?: (req: AddAppUserInvoice_Input & {ctx: AppContext }) => Promise + AddProduct?: (req: AddProduct_Input & {ctx: UserContext }) => Promise + AuthApp?: (req: AuthApp_Input & {ctx: AdminContext }) => Promise + BanUser?: (req: BanUser_Input & {ctx: AdminContext }) => Promise + CreateOneTimeInviteLink?: (req: CreateOneTimeInviteLink_Input & {ctx: AdminContext }) => Promise + DecodeInvoice?: (req: DecodeInvoice_Input & {ctx: UserContext }) => Promise + EncryptionExchange?: (req: EncryptionExchange_Input & {ctx: GuestContext }) => Promise + EnrollAdminToken?: (req: EnrollAdminToken_Input & {ctx: UserContext }) => Promise + GetApp?: (req: GetApp_Input & {ctx: AppContext }) => Promise + GetAppUser?: (req: GetAppUser_Input & {ctx: AppContext }) => Promise + GetAppUserLNURLInfo?: (req: GetAppUserLNURLInfo_Input & {ctx: AppContext }) => Promise + GetAppsMetrics?: (req: GetAppsMetrics_Input & {ctx: MetricsContext }) => Promise + GetHttpCreds?: (req: GetHttpCreds_Input & {ctx: UserContext }) => Promise + GetInviteLinkState?: (req: GetInviteLinkState_Input & {ctx: AdminContext }) => Promise + GetLNURLChannelLink?: (req: GetLNURLChannelLink_Input & {ctx: UserContext }) => Promise + GetLiveUserOperations?: (req: GetLiveUserOperations_Input & {ctx: UserContext }) => Promise + GetLndMetrics?: (req: GetLndMetrics_Input & {ctx: MetricsContext }) => Promise + GetLnurlPayInfo?: (req: GetLnurlPayInfo_Input & {ctx: GuestContext }) => Promise + GetLnurlPayLink?: (req: GetLnurlPayLink_Input & {ctx: UserContext }) => Promise + GetLnurlWithdrawInfo?: (req: GetLnurlWithdrawInfo_Input & {ctx: GuestContext }) => Promise + GetLnurlWithdrawLink?: (req: GetLnurlWithdrawLink_Input & {ctx: UserContext }) => Promise + GetMigrationUpdate?: (req: GetMigrationUpdate_Input & {ctx: UserContext }) => Promise + GetPaymentState?: (req: GetPaymentState_Input & {ctx: UserContext }) => Promise + GetSeed?: (req: GetSeed_Input & {ctx: AdminContext }) => Promise + GetUsageMetrics?: (req: GetUsageMetrics_Input & {ctx: MetricsContext }) => Promise + GetUserInfo?: (req: GetUserInfo_Input & {ctx: UserContext }) => Promise + GetUserOperations?: (req: GetUserOperations_Input & {ctx: UserContext }) => Promise + HandleLnurlAddress?: (req: HandleLnurlAddress_Input & {ctx: GuestContext }) => Promise + HandleLnurlPay?: (req: HandleLnurlPay_Input & {ctx: GuestContext }) => Promise + HandleLnurlWithdraw?: (req: HandleLnurlWithdraw_Input & {ctx: GuestContext }) => Promise + Health?: (req: Health_Input & {ctx: GuestContext }) => Promise + LinkNPubThroughToken?: (req: LinkNPubThroughToken_Input & {ctx: GuestWithPubContext }) => Promise + ListChannels?: (req: ListChannels_Input & {ctx: AdminContext }) => Promise + LndGetInfo?: (req: LndGetInfo_Input & {ctx: AdminContext }) => Promise + NewAddress?: (req: NewAddress_Input & {ctx: UserContext }) => Promise + NewInvoice?: (req: NewInvoice_Input & {ctx: UserContext }) => Promise + NewProductInvoice?: (req: NewProductInvoice_Input & {ctx: UserContext }) => Promise + OpenChannel?: (req: OpenChannel_Input & {ctx: UserContext }) => Promise + PayAddress?: (req: PayAddress_Input & {ctx: UserContext }) => Promise + PayAppUserInvoice?: (req: PayAppUserInvoice_Input & {ctx: AppContext }) => Promise + PayInvoice?: (req: PayInvoice_Input & {ctx: UserContext }) => Promise + RequestNPubLinkingToken?: (req: RequestNPubLinkingToken_Input & {ctx: AppContext }) => Promise + ResetNPubLinkingToken?: (req: ResetNPubLinkingToken_Input & {ctx: AppContext }) => Promise + SendAppUserToAppPayment?: (req: SendAppUserToAppPayment_Input & {ctx: AppContext }) => Promise + SendAppUserToAppUserPayment?: (req: SendAppUserToAppUserPayment_Input & {ctx: AppContext }) => Promise + SetMockAppBalance?: (req: SetMockAppBalance_Input & {ctx: AppContext }) => Promise + SetMockAppUserBalance?: (req: SetMockAppUserBalance_Input & {ctx: AppContext }) => Promise + SetMockInvoiceAsPaid?: (req: SetMockInvoiceAsPaid_Input & {ctx: GuestContext }) => Promise + UseInviteLink?: (req: UseInviteLink_Input & {ctx: GuestWithPubContext }) => Promise + UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise } export enum AddressType { @@ -325,7 +325,7 @@ export const AddAppInvoiceRequestValidate = (o?: AddAppInvoiceRequest, opts: Add const invoice_reqErr = NewInvoiceRequestValidate(o.invoice_req, opts.invoice_req_Options, `${path}.invoice_req`) if (invoice_reqErr !== null) return invoice_reqErr - + if (typeof o.payer_identifier !== 'string') return new Error(`${path}.payer_identifier: is not a string`) if (opts.payer_identifier_CustomCheck && !opts.payer_identifier_CustomCheck(o.payer_identifier)) return new Error(`${path}.payer_identifier: custom check failed`) @@ -379,7 +379,7 @@ export const AddAppUserInvoiceRequestValidate = (o?: AddAppUserInvoiceRequest, o const invoice_reqErr = NewInvoiceRequestValidate(o.invoice_req, opts.invoice_req_Options, `${path}.invoice_req`) if (invoice_reqErr !== null) return invoice_reqErr - + if (typeof o.payer_identifier !== 'string') return new Error(`${path}.payer_identifier: is not a string`) if (opts.payer_identifier_CustomCheck && !opts.payer_identifier_CustomCheck(o.payer_identifier)) return new Error(`${path}.payer_identifier: custom check failed`) @@ -472,7 +472,7 @@ export const AppMetricsValidate = (o?: AppMetrics, opts: AppMetricsOptions = {}, const appErr = ApplicationValidate(o.app, opts.app_Options, `${path}.app`) if (appErr !== null) return appErr - + if (typeof o.available !== 'number') return new Error(`${path}.available: is not a number`) if (opts.available_CustomCheck && !opts.available_CustomCheck(o.available)) return new Error(`${path}.available: custom check failed`) @@ -501,7 +501,7 @@ export const AppMetricsValidate = (o?: AppMetrics, opts: AppMetricsOptions = {}, const usersErr = UsersInfoValidate(o.users, opts.users_Options, `${path}.users`) if (usersErr !== null) return usersErr - + return null } @@ -527,7 +527,7 @@ export const AppUserValidate = (o?: AppUser, opts: AppUserOptions = {}, path: st const infoErr = UserInfoValidate(o.info, opts.info_Options, `${path}.info`) if (infoErr !== null) return infoErr - + if (typeof o.max_withdrawable !== 'number') return new Error(`${path}.max_withdrawable: is not a number`) if (opts.max_withdrawable_CustomCheck && !opts.max_withdrawable_CustomCheck(o.max_withdrawable)) return new Error(`${path}.max_withdrawable: custom check failed`) @@ -636,7 +636,7 @@ export const AuthAppValidate = (o?: AuthApp, opts: AuthAppOptions = {}, path: st const appErr = ApplicationValidate(o.app, opts.app_Options, `${path}.app`) if (appErr !== null) return appErr - + if (typeof o.auth_token !== 'string') return new Error(`${path}.auth_token: is not a string`) if (opts.auth_token_CustomCheck && !opts.auth_token_CustomCheck(o.auth_token)) return new Error(`${path}.auth_token: custom check failed`) @@ -1105,27 +1105,27 @@ export const GetUserOperationsResponseValidate = (o?: GetUserOperationsResponse, const latestIncomingInvoiceOperationsErr = UserOperationsValidate(o.latestIncomingInvoiceOperations, opts.latestIncomingInvoiceOperations_Options, `${path}.latestIncomingInvoiceOperations`) if (latestIncomingInvoiceOperationsErr !== null) return latestIncomingInvoiceOperationsErr - + const latestIncomingTxOperationsErr = UserOperationsValidate(o.latestIncomingTxOperations, opts.latestIncomingTxOperations_Options, `${path}.latestIncomingTxOperations`) if (latestIncomingTxOperationsErr !== null) return latestIncomingTxOperationsErr - + const latestIncomingUserToUserPayemntsErr = UserOperationsValidate(o.latestIncomingUserToUserPayemnts, opts.latestIncomingUserToUserPayemnts_Options, `${path}.latestIncomingUserToUserPayemnts`) if (latestIncomingUserToUserPayemntsErr !== null) return latestIncomingUserToUserPayemntsErr - + const latestOutgoingInvoiceOperationsErr = UserOperationsValidate(o.latestOutgoingInvoiceOperations, opts.latestOutgoingInvoiceOperations_Options, `${path}.latestOutgoingInvoiceOperations`) if (latestOutgoingInvoiceOperationsErr !== null) return latestOutgoingInvoiceOperationsErr - + const latestOutgoingTxOperationsErr = UserOperationsValidate(o.latestOutgoingTxOperations, opts.latestOutgoingTxOperations_Options, `${path}.latestOutgoingTxOperations`) if (latestOutgoingTxOperationsErr !== null) return latestOutgoingTxOperationsErr - + const latestOutgoingUserToUserPayemntsErr = UserOperationsValidate(o.latestOutgoingUserToUserPayemnts, opts.latestOutgoingUserToUserPayemnts_Options, `${path}.latestOutgoingUserToUserPayemnts`) if (latestOutgoingUserToUserPayemntsErr !== null) return latestOutgoingUserToUserPayemntsErr - + return null } @@ -1236,7 +1236,7 @@ export const LiveUserOperationValidate = (o?: LiveUserOperation, opts: LiveUserO const operationErr = UserOperationValidate(o.operation, opts.operation_Options, `${path}.operation`) if (operationErr !== null) return operationErr - + return null } @@ -1604,13 +1604,13 @@ export const MigrationUpdateValidate = (o?: MigrationUpdate, opts: MigrationUpda const closureErr = ClosureMigrationValidate(o.closure, opts.closure_Options, `${path}.closure`) if (closureErr !== null) return closureErr } - + if (typeof o.relays === 'object' || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('relays')) { const relaysErr = RelaysMigrationValidate(o.relays, opts.relays_Options, `${path}.relays`) if (relaysErr !== null) return relaysErr } - + return null } @@ -2353,6 +2353,7 @@ export const UseInviteLinkRequestValidate = (o?: UseInviteLinkRequest, opts: Use export type UserInfo = { balance: number + bridge_url: string max_withdrawable: number network_max_fee_bps: number network_max_fee_fixed: number @@ -2365,6 +2366,7 @@ export const UserInfoOptionalFields: [] = [] export type UserInfoOptions = OptionsBaseMessage & { checkOptionalsAreSet?: [] balance_CustomCheck?: (v: number) => boolean + bridge_url_CustomCheck?: (v: string) => boolean max_withdrawable_CustomCheck?: (v: number) => boolean network_max_fee_bps_CustomCheck?: (v: number) => boolean network_max_fee_fixed_CustomCheck?: (v: number) => boolean @@ -2380,6 +2382,9 @@ export const UserInfoValidate = (o?: UserInfo, opts: UserInfoOptions = {}, path: if (typeof o.balance !== 'number') return new Error(`${path}.balance: is not a number`) if (opts.balance_CustomCheck && !opts.balance_CustomCheck(o.balance)) return new Error(`${path}.balance: custom check failed`) + if (typeof o.bridge_url !== 'string') return new Error(`${path}.bridge_url: is not a string`) + if (opts.bridge_url_CustomCheck && !opts.bridge_url_CustomCheck(o.bridge_url)) return new Error(`${path}.bridge_url: custom check failed`) + if (typeof o.max_withdrawable !== 'number') return new Error(`${path}.max_withdrawable: is not a number`) if (opts.max_withdrawable_CustomCheck && !opts.max_withdrawable_CustomCheck(o.max_withdrawable)) return new Error(`${path}.max_withdrawable: custom check failed`) diff --git a/src/Api/tools/nip98.ts b/src/Api/tools/nip98.ts new file mode 100644 index 00000000..009be107 --- /dev/null +++ b/src/Api/tools/nip98.ts @@ -0,0 +1,227 @@ +import { sha256 } from '@noble/hashes/sha256' +import { bytesToHex } from '@noble/hashes/utils' +import { base64 } from '@scure/base' + +import { Event, EventTemplate, getEventHash, VerifiedEvent, verifiedSymbol } from './event' +import { utf8Decoder, utf8Encoder } from './utils'; +import { schnorr } from '@noble/curves/secp256k1'; + +const verifyEvent = (event: Event): event is VerifiedEvent => { + if (typeof event[verifiedSymbol] === 'boolean') return event[verifiedSymbol] + + const hash = getEventHash(event) + if (hash !== event.id) { + event[verifiedSymbol] = false + return false + } + + try { + const valid = schnorr.verify(event.sig, hash, event.pubkey) + event[verifiedSymbol] = valid + return valid + } catch { + event[verifiedSymbol] = false + return false + } +} + + +const _authorizationScheme = 'Nostr ' +const HTTPAuth = 27235 + +/** + * Generate token for NIP-98 flow. + * + * @example + * const sign = window.nostr.signEvent + * await nip98.getToken('https://example.com/login', 'post', (e) => sign(e), true) + */ +export async function getToken( + loginUrl: string, + httpMethod: string, + sign: (e: EventTemplate) => Promise | Event, + includeAuthorizationScheme: boolean = false, + payload?: Record, +): Promise { + const event: EventTemplate = { + kind: HTTPAuth, + tags: [ + ['u', loginUrl], + ['method', httpMethod], + ], + created_at: Math.round(new Date().getTime() / 1000), + content: '', + } + + if (payload) { + event.tags.push(['payload', hashPayload(payload)]) + } + + const signedEvent = await sign(event) + const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : '' + + return authorizationScheme + base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent))) +} + +/** + * Validate token for NIP-98 flow. + * + * @example + * await nip98.validateToken('Nostr base64token', 'https://example.com/login', 'post') + */ +export async function validateToken(token: string, url: string, method: string): Promise { + const event = await unpackEventFromToken(token).catch(error => { + throw error + }) + + const valid = await validateEvent(event, url, method).catch(error => { + throw error + }) + + return valid +} + +/** + * Unpacks an event from a token. + * + * @param token - The token to unpack. + * @returns A promise that resolves to the unpacked event. + * @throws {Error} If the token is missing, invalid, or cannot be parsed. + */ +export async function unpackEventFromToken(token: string): Promise { + if (!token) { + throw new Error('Missing token') + } + + token = token.replace(_authorizationScheme, '') + + const eventB64 = utf8Decoder.decode(base64.decode(token)) + if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith('{')) { + throw new Error('Invalid token') + } + + const event = JSON.parse(eventB64) as Event + + return event +} + +/** + * Validates the timestamp of an event. + * @param event - The event object to validate. + * @returns A boolean indicating whether the event timestamp is within the last 60 seconds. + */ +export function validateEventTimestamp(event: Event): boolean { + if (!event.created_at) { + return false + } + + return Math.round(new Date().getTime() / 1000) - event.created_at < 60 +} + +/** + * Validates the kind of an event. + * @param event The event to validate. + * @returns A boolean indicating whether the event kind is valid. + */ +export function validateEventKind(event: Event): boolean { + return event.kind === HTTPAuth +} + +/** + * Validates if the given URL matches the URL tag of the event. + * @param event - The event object. + * @param url - The URL to validate. + * @returns A boolean indicating whether the URL is valid or not. + */ +export function validateEventUrlTag(event: Event, url: string): boolean { + const urlTag = event.tags.find(t => t[0] === 'u') + + if (!urlTag) { + return false + } + + return urlTag.length > 0 && urlTag[1] === url +} + +/** + * Validates if the given event has a method tag that matches the specified method. + * @param event - The event to validate. + * @param method - The method to match against the method tag. + * @returns A boolean indicating whether the event has a matching method tag. + */ +export function validateEventMethodTag(event: Event, method: string): boolean { + const methodTag = event.tags.find(t => t[0] === 'method') + + if (!methodTag) { + return false + } + + return methodTag.length > 0 && methodTag[1].toLowerCase() === method.toLowerCase() +} + +/** + * Calculates the hash of a payload. + * @param payload - The payload to be hashed. + * @returns The hash value as a string. + */ +export function hashPayload(payload: any): string { + const hash = sha256(utf8Encoder.encode(JSON.stringify(payload))) + return bytesToHex(hash) +} + +/** + * Validates the event payload tag against the provided payload. + * @param event The event object. + * @param payload The payload to validate. + * @returns A boolean indicating whether the payload tag is valid. + */ +export function validateEventPayloadTag(event: Event, payload: any): boolean { + const payloadTag = event.tags.find(t => t[0] === 'payload') + + if (!payloadTag) { + return false + } + + const payloadHash = hashPayload(payload) + return payloadTag.length > 0 && payloadTag[1] === payloadHash +} + +/** + * Validates a Nostr event for the NIP-98 flow. + * + * @param event - The Nostr event to validate. + * @param url - The URL associated with the event. + * @param method - The HTTP method associated with the event. + * @param body - The request body associated with the event (optional). + * @returns A promise that resolves to a boolean indicating whether the event is valid. + * @throws An error if the event is invalid. + */ +export async function validateEvent(event: Event, url: string, method: string, body?: any): Promise { + if (!verifyEvent(event)) { + throw new Error('Invalid nostr event, signature invalid') + } + + if (!validateEventKind(event)) { + throw new Error('Invalid nostr event, kind invalid') + } + + if (!validateEventTimestamp(event)) { + throw new Error('Invalid nostr event, created_at timestamp invalid') + } + + if (!validateEventUrlTag(event, url)) { + throw new Error('Invalid nostr event, url tag invalid') + } + + if (!validateEventMethodTag(event, method)) { + throw new Error('Invalid nostr event, method tag invalid') + } + + if (Boolean(body) && typeof body === 'object' && Object.keys(body).length > 0) { + if (!validateEventPayloadTag(event, body)) { + throw new Error('Invalid nostr event, payload tag does not match request body hash') + } + } + + return true +} \ No newline at end of file diff --git a/src/App.scss b/src/App.scss index 938e9dfa..6a0883ba 100644 --- a/src/App.scss +++ b/src/App.scss @@ -183,6 +183,8 @@ input[type=number] { @import "./Pages/Automation/Auto.scss"; @import "./Pages/Auth/auth.scss"; @import "./Pages/Notify/notify.scss"; +@import "./Pages/LinkedApp/linkedApp.scss"; +@import "./Pages/Offers//Offers.scss"; @import "./Containers/Header/Header.scss"; @import "./Containers/Footer/Footer.scss"; diff --git a/src/App.tsx b/src/App.tsx index d5ea1b36..09154824 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,11 @@ import { Route } from "react-router-dom"; import React, { useEffect } from "react"; import { IonApp, IonRouterOutlet, setupIonicReact } from "@ionic/react"; -import { IonReactHashRouter } from "@ionic/react-router"; +import { IonReactRouter } from "@ionic/react-router"; import { StatusBar } from "@capacitor/status-bar"; import AppUrlListener from "./Hooks/appUrlListener"; import ErrorBoundary from "./Hooks/ErrorBoundary"; +import { useDispatch } from 'react-redux'; import './App.scss'; import store from './State/store'; @@ -23,11 +24,12 @@ import { Contacts } from './Pages/Contacts'; import { Invitations } from './Pages/Invitations'; import { Auth } from './Pages/Auth'; import { Background } from './Components/Background'; -import { isBrowser } from 'react-device-detect' import { Notify } from './Pages/Notify'; import { Metrics } from './Pages/Metrics'; import { Manage } from "./Pages/Manage"; import { Channels } from "./Pages/Channels"; +import { LinkedApp } from "./Pages/LinkedApp"; +import { Offers } from "./Pages/Offers"; import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; @@ -51,106 +53,146 @@ import LoadingOverlay from "./Components/LoadingOverlay"; setupIonicReact(); -const App: React.FC = () => { +const AppContent: React.FC = () => { + const dispatch = useDispatch(); + useEffect(() => { - if (!isBrowser) setStatusBarColor(); // check wonder it is opened in browser - }, []); + const handleUrlParams = () => { + const url = new URL(window.location.href); + const addSource = url.searchParams.get('addSource'); + const inviteToken = url.searchParams.get('inviteToken'); + + if (addSource) { + dispatch({ type: 'SHOW_ADD_SOURCE_CONFIRMATION', payload: { addSource, inviteToken } }); + window.history.replaceState({}, document.title, url.pathname); + } + }; + + handleUrlParams(); + window.addEventListener('popstate', handleUrlParams); + + return () => { + window.removeEventListener('popstate', handleUrlParams); + }; + }, [dispatch]); + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +const App: React.FC = () => { const setStatusBarColor = async () => { await StatusBar.setBackgroundColor({ color: "#16191c" }); }; + useEffect(() => { + setStatusBarColor(); + }, []); + return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + { const svgCode = ''; return
; -}; \ No newline at end of file +}; + +export const LinkedAppIcon = () => { + const svgCode = + ''; + return
; +} + +export const OffersCodeIcon = () => { + const svgCode = + ''; + return
; +} + +export const ChevronRightIcon = () => { + const svgCode = + ''; + return
+} + +export const pencilIcons = () => { + const svgCode = + ''; + return
+} + +export const combindIcon = () => { + const svgCode = + ''; + return
+} \ No newline at end of file diff --git a/src/Components/BackgroundJobs/NewSourceCheck.tsx b/src/Components/BackgroundJobs/NewSourceCheck.tsx index 2f831af8..febace0f 100644 --- a/src/Components/BackgroundJobs/NewSourceCheck.tsx +++ b/src/Components/BackgroundJobs/NewSourceCheck.tsx @@ -1,8 +1,8 @@ import { useEffect } from "react" import { useDispatch, useSelector } from "../../State/store" -import { DEFAULT_BRIDGE_URL, NOSTR_PUB_DESTINATION, NOSTR_RELAYS, OLD_NOSTR_PUB_DESTINATION, options } from "../../constants" +import { NOSTR_PUB_DESTINATION, NOSTR_RELAYS, OLD_NOSTR_PUB_DESTINATION, options } from "../../constants" import { addSpendSources } from "../../State/Slices/spendSourcesSlice" -import { encodeNprofile } from "../../custom-nip19"; +import { nip19 } from "nostr-tools"; export const NewSourceCheck = () => { const spendSource = useSelector(({ spendSource }) => spendSource) @@ -21,7 +21,7 @@ export const NewSourceCheck = () => { console.log("bootstrap source changed, updating source") - const newProfile = encodeNprofile({ pubkey: NOSTR_PUB_DESTINATION, relays: NOSTR_RELAYS, bridge: [DEFAULT_BRIDGE_URL] }); + const newProfile = nip19.nprofileEncode({ pubkey: NOSTR_PUB_DESTINATION, relays: NOSTR_RELAYS }); dispatch(addSpendSources({ source: { diff --git a/src/Components/NotifyItem/NotifyItem.scss b/src/Components/NotifyItem/NotifyItem.scss index ba34e3d3..4ee3ae61 100644 --- a/src/Components/NotifyItem/NotifyItem.scss +++ b/src/Components/NotifyItem/NotifyItem.scss @@ -3,16 +3,17 @@ // border: 1px solid #8c8c8c; display: flow-root; width: 98%; - margin-bottom: 13px; + margin-bottom: 5px; border-radius: 5px; padding: 3px 0px; box-shadow: 0px 0px 2px #8c8c8c; display: inline-flex; - padding: 12px; + padding: 5px; cursor: pointer; &_icon{ - font-size: 28px; + font-size: 24px; + margin-top: 5px; } &_left{ @@ -27,7 +28,7 @@ } &_header{ - font-size: 14px; + font-size: 12px; color: white; display: inline-flex; width: 100%; @@ -35,13 +36,13 @@ &_desc{ margin-top: 2px; - font-size: 16px; + font-size: 14px; color: #54bbe8; } &_date{ display: flex; - font-size: 14px; + font-size: 12px; color: #a3a3a3; margin-left: auto; } diff --git a/src/Containers/Header/index.tsx b/src/Containers/Header/index.tsx index 3d27fe4a..837b830b 100644 --- a/src/Containers/Header/index.tsx +++ b/src/Containers/Header/index.tsx @@ -1,11 +1,12 @@ import React, { useEffect, useLayoutEffect, useMemo, useState } from "react"; +import { useLocation } from 'react-router-dom'; +import { useIonRouter, isPlatform } from "@ionic/react"; import { UseModal } from "../../Hooks/UseModal"; //It import svg icons library import * as Icons from "../../Assets/SvgIconLibrary"; import SWText from "../../Assets/Images/sw_text.png"; -import { useIonRouter,isPlatform } from "@ionic/react"; import { MenuList } from "../../Components/Modals/MenuList"; import { useSelector } from "../../State/store"; import { Modal } from "../../Components/Modals/Modal"; @@ -26,22 +27,23 @@ const saveLog = (...args: any[]) => { logs.push(line) } export const Header = () => { + const location = useLocation(); + const router = useIonRouter(); + + const isNopeUp: boolean = location.pathname === "/"; + const isLoader: boolean = location.pathname === "/loader"; + const isscan: boolean = location.pathname === "/scan"; + const isreceive: boolean = location.pathname === "/receive"; + const [badge, setBadge] = useState(false); const [logoClickCounter, setLogoClickCounter] = useState(0); const backUpStates = useSelector(state => state.backupStateSlice); - const router = useIonRouter(); const notifications = useSelector(({ notify }) => notify); const debugMode = useSelector(({ prefs }) => prefs.debugMode); const { isShown, toggle } = UseModal(); const { isShown: isDebugShown, toggle: toggleDebugShown } = UseModal(); - const isNopeUp: boolean = router.routeInfo.pathname === "/"; - router.routeInfo; - const isLoader: boolean = router.routeInfo.pathname === "/loader"; - const isscan: boolean = router.routeInfo.pathname === "/scan"; - const isreceive: boolean = router.routeInfo.pathname === "/receive"; - const getNotifyBadge = () => { if (notifications && notifications.notifications.length) { setBadge(notifications.notifications[notifications.notifications.length - 1].date > notifications.checkTime) @@ -154,6 +156,24 @@ export const Header = () => {
Contacts
+
{ + router.push("/LApps"); + toggle(); + }}> +
+ {Icons.LinkedAppIcon()} +
+
Linked Apps
+
+
{ + router.push("/Offers"); + toggle(); + }}> +
+ {Icons.OffersCodeIcon()} +
+
Offer Codes
+
{ router.push("/prefs"); toggle(); @@ -181,7 +201,7 @@ export const Header = () => {
Node Invitations
- { + {/* { !backUpStates.subbedToBackUp &&
{ @@ -193,11 +213,11 @@ export const Header = () => {
Auth
- } + } */}

-{/*
{ +
{ router.push("/sources"); toggle(); }}> @@ -205,7 +225,7 @@ export const Header = () => { {Icons.BuyCryptoIcon()}
Buy Bitcoin
-
*/} +
{ if (debugMode) { toggleDebugShown() @@ -277,21 +297,22 @@ export const Header = () => { } export const PubHeader = () => { + const location = useLocation(); + const router = useIonRouter(); + + const isNopeUp: boolean = location.pathname === "/"; + const isLoader: boolean = location.pathname === "/loader"; + const isscan: boolean = location.pathname === "/scan"; + const isreceive: boolean = location.pathname === "/receive"; + const [badge, setBadge] = useState(false); const [logoClickCounter, setLogoClickCounter] = useState(0); - const router = useIonRouter(); const notifications = useSelector(({ notify }) => notify); const debugMode = useSelector(({ prefs }) => prefs.debugMode); const { isShown, toggle } = UseModal(); const { isShown: isDebugShown, toggle: toggleDebugShown } = UseModal(); - const isNopeUp: boolean = router.routeInfo.pathname === "/"; - router.routeInfo; - const isLoader: boolean = router.routeInfo.pathname === "/loader"; - const isscan: boolean = router.routeInfo.pathname === "/scan"; - const isreceive: boolean = router.routeInfo.pathname === "/receive"; - const getNotifyBadge = () => { if (notifications && notifications.notifications.length) { setBadge(notifications.notifications[notifications.notifications.length - 1].date > notifications.checkTime) diff --git a/src/Layout/index.tsx b/src/Layout/index.tsx index 5a101975..8d8310d9 100644 --- a/src/Layout/index.tsx +++ b/src/Layout/index.tsx @@ -6,6 +6,7 @@ import { LayoutProps } from "./types"; import axios from "axios"; import { useDispatch, useSelector } from "../State/store"; import { setAmount } from "../State/Slices/usdToBTCSlice"; +import { useLocation } from 'react-router-dom'; interface Price { buyPrice: number, @@ -16,10 +17,12 @@ export const Layout: React.FC = ({ children }): JSX.Element => { //reducer const BTCFiatUnit = useSelector(({ prefs }) => prefs.FiatUnit) - const router = useIonRouter(); - const isScan: boolean = router.routeInfo.pathname === "/scan"; - const isPub: boolean = router.routeInfo.pathname === "/metrics" || router.routeInfo.pathname === "/manage" || router.routeInfo.pathname === "/channels" + const location = useLocation(); + const pathname = location?.pathname || window.location.pathname; + + const isScan: boolean = pathname === "/scan"; + const isPub: boolean = pathname === "/metrics" || pathname === "/manage" || pathname === "/channels" const dispatch = useDispatch(); diff --git a/src/Pages/Invitations/index.tsx b/src/Pages/Invitations/index.tsx index 0e04c84b..90762d40 100644 --- a/src/Pages/Invitations/index.tsx +++ b/src/Pages/Invitations/index.tsx @@ -89,7 +89,7 @@ export const Invitations = () => { const reusableLink = selectedSource ? { - link: `${WALLET_URL}/#/sources?addSource=${selectedSource.pasteField}`, + link: `${WALLET_URL}/sources?addSource=${selectedSource.pasteField}`, subNode: selectedSource.label, } : null; @@ -117,7 +117,7 @@ export const Invitations = () => {
{ invitations.invitations && invitations.invitations.map(inv => { - const link = `${WALLET_URL}/#/sources?addSource=${selectedSource?.pasteField}&inviteToken=${inv.inviteToken}` + const link = `${WALLET_URL}/sources?addSource=${selectedSource?.pasteField}&inviteToken=${inv.inviteToken}` return (
@@ -171,16 +171,20 @@ export const Invitations = () => {
One-Time Links
- {oneTimeLinksRender} +
+
+ Gift links coming soon. +
+
-
+ {/*
-
+
*/}
); }; diff --git a/src/Pages/LinkedApp/index.tsx b/src/Pages/LinkedApp/index.tsx new file mode 100644 index 00000000..4af8bf06 --- /dev/null +++ b/src/Pages/LinkedApp/index.tsx @@ -0,0 +1,11 @@ +export const LinkedApp = () => { + + return ( +
+
+
Linked Apps
+
Coming soon.
+
+
+ ); +}; diff --git a/src/Pages/LinkedApp/linkedApp.scss b/src/Pages/LinkedApp/linkedApp.scss new file mode 100644 index 00000000..a0b70895 --- /dev/null +++ b/src/Pages/LinkedApp/linkedApp.scss @@ -0,0 +1,39 @@ +.LinkedApp{ + &_container { + // background-image: linear-gradient(320deg, #151d24 31%, #16191c 60%); + width: 100%; + padding-inline: 5%; + padding-bottom: 30px; + transition-duration: 500ms; + font-family: Montserrat; + justify-content: center; + position: fixed; + left: 0; + height: 100%; + } + + &_header { + display: inline-flex; + align-items: center; + width: 290px; + margin: auto; + aspect-ratio : 1 / 1; + background-color: white; + border: 1px solid #2693c1; + border-radius: 10px; + &_text{ + margin-block: 10px; + text-align: center; + color: white; + font-size: 26px; + font-family: Montserrat; + margin-bottom: 80px; + } + } + + &_description{ + font-size: 12px; + text-align: center; + padding: 50px 0; + } +} \ No newline at end of file diff --git a/src/Pages/NodeUp/index.tsx b/src/Pages/NodeUp/index.tsx index 4cf55c07..e741ca52 100644 --- a/src/Pages/NodeUp/index.tsx +++ b/src/Pages/NodeUp/index.tsx @@ -1,11 +1,11 @@ import { useLayoutEffect } from "react"; import { useIonRouter } from '@ionic/react'; -import { DEFAULT_BRIDGE_URL, NOSTR_PRIVATE_KEY_STORAGE_KEY, NOSTR_PUB_DESTINATION, NOSTR_RELAYS, options } from "../../constants"; +import { NOSTR_PRIVATE_KEY_STORAGE_KEY, NOSTR_PUB_DESTINATION, NOSTR_RELAYS, options } from "../../constants"; import { useDispatch, useSelector } from "../../State/store"; import { addPaySources } from "../../State/Slices/paySourcesSlice"; import { addSpendSources } from "../../State/Slices/spendSourcesSlice"; -import { encodeNprofile } from "../../custom-nip19"; import { generateNewKeyPair } from "../../Api/helpers"; +import { nip19 } from "nostr-tools"; export const NodeUp = () => { const router = useIonRouter(); @@ -50,10 +50,9 @@ export const NodeUp = () => { const id = `${NOSTR_PUB_DESTINATION}-${keyPair.publicKey}`; const bootstrapBalance = "0"; - const nprofile = encodeNprofile({ + const nprofile = nip19.nprofileEncode({ pubkey: NOSTR_PUB_DESTINATION, relays: NOSTR_RELAYS, - bridge: [DEFAULT_BRIDGE_URL] }) diff --git a/src/Pages/Notify/notify.scss b/src/Pages/Notify/notify.scss index 85308c03..35c09b5e 100644 --- a/src/Pages/Notify/notify.scss +++ b/src/Pages/Notify/notify.scss @@ -1,4 +1,8 @@ .Notify{ + display: flex; + flex-direction: column; + margin-inline: auto; + max-width: 800px; &_container { // background-image: linear-gradient(320deg, #151d24 31%, #16191c 60%); width: 100%; diff --git a/src/Pages/Offers/Offers.scss b/src/Pages/Offers/Offers.scss new file mode 100644 index 00000000..388615f9 --- /dev/null +++ b/src/Pages/Offers/Offers.scss @@ -0,0 +1,129 @@ +.Offers{ + display: flex; + flex-direction: column; + margin-inline: auto; + max-width: 800px; + &_container { + // background-image: linear-gradient(320deg, #151d24 31%, #16191c 60%); + width: 100%; + padding-inline: 5%; + padding-bottom: 30px; + transition-duration: 500ms; + font-family: Montserrat; + justify-content: center; + position: fixed; + left: 0; + height: 100%; + margin-top: 30px; + } + + &_header { + display: inline-flex; + align-items: center; + width: 290px; + margin: auto; + aspect-ratio : 1 / 1; + background-color: white; + border: 1px solid #2693c1; + border-radius: 10px; + &_text{ + margin-block: 10px; + text-align: center; + color: white; + font-size: 26px; + font-family: Montserrat; + } + } + + &_connect_state{ + color: red; + text-align: center; + } + + &_item{ + display: flex; + font-size: 12px; + color: #999999; + align-items: start; + .item_title{ + display: flex; + gap: 5px; + background-color: black; + width: 150px; + justify-content: center; + align-items: center; + padding: 5px 10px; + border-radius: 5px; + } + + .item { + display: flex; + margin: 5px 0; + padding: 5px 10px; + background-color: black; + border-radius: 5px; + width: 153px; + gap: 5px; + align-items: center; + } + + .RightIcon{ + margin: 10px; + } + + .offers_dropdown{ + background-color: black; + border-radius: 5px; + } + } + &_source { + border-radius: 5px; + border: 1px solid #2a3035; + padding: 10px; + margin-top: 10px; + + .source_header { + font-size: 16px; + display: flex; + justify-content: space-between; + align-items: center; + } + + .source_data { + font-size: 12px; + color: #adadad; + margin: 5px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .source_footer { + font-size: 12px; + color: #29abe2; + display: flex; + justify-content: space-between; + align-items: center; + } + + .edit_source { + input { + height: 30px; + margin-top: 10px; + margin-bottom: 10px; + font-family: Montserrat; + font-size: 15px; + text-align: start; + width: 100%; + background-color: #16191cf7; + color: #a3a3a3; + box-shadow: rgb(0, 0, 0) 0px 0px 2px 0px; + padding-block: 8px; + padding-left: 10px; + padding-right: 10px; + border: 1px solid #2cb0e9; + border-radius: 5px; + } + } + } +} \ No newline at end of file diff --git a/src/Pages/Offers/index.tsx b/src/Pages/Offers/index.tsx new file mode 100644 index 00000000..ac2090f8 --- /dev/null +++ b/src/Pages/Offers/index.tsx @@ -0,0 +1,226 @@ +import { toast } from "react-toastify"; +import * as Icons from "../../Assets/SvgIconLibrary"; +import { Clipboard } from "@capacitor/clipboard"; +import React, { useEffect, useState } from "react"; +import BootstrapSource from "../../Assets/Images/bootstrap_source.jpg"; +import { useSelector, useDispatch, selectEnabledSpends } from '../../State/store'; +import { SpendFrom } from "../../globalTypes"; + +type OfferItemType = { + title: string; + value: string; + type: string; +}; + +export const Offers = () => { + + const enabledSpendSources = useSelector(selectEnabledSpends); + console.log(enabledSpendSources) + + const [isEdit, setIsEdit] = useState(false); + + const [showDropDown, setShowDropDown] = useState(false); + const [allValue, setAllValue] = useState(enabledSpendSources); + + const [display, setDisplay] = useState(0); + const [rotation, setRotation] = useState(0); + const [value, setValue] = useState(enabledSpendSources[0]); + const [remainValues, setRemailValues] = useState([]); + + const [isConnect, setIsConnect] = useState(true); + const [displayData, setDisplayData] = useState(); + const [offerValue, setOfferValue] = useState(""); + + useEffect(() => { + setShowDropDown(showDropDown); + }, [showDropDown]); + + useEffect(() => { + setDisplayData(value) + setOfferValue(value.pasteField) + }, [value]); + + const dropdown = () => { + const remainValues = allValue.filter((e) => e.label !== value.label); + setRemailValues(remainValues); + setDisplay(display === 0 ? 1 : 0); + setRotation(rotation === 0 ? 90 : 0); + }; + + const arrangeIcon = (value?: string, sourcePub?: string) => { + console.log(value, sourcePub) + switch (value) { + case "0": + return ( + + Avatar + + ); + case "1": + return Icons.mynodeSmall(); + + case "2": + return Icons.uncleSmall(); + + case "3": + return Icons.lightningSmall(); + + case "4": + return Icons.zbdSmall(); + + case "5": + return Icons.stackerSmall(); + + default: + if (sourcePub) { + return ( + + Avatar + + ); + } + if (!value?.includes("http")) { + value = "http://www.google.com/s2/favicons?sz=64&domain=" + value; + } + return ( + + + + ); + } + }; + + const selectOption = (id: SpendFrom) => { + dropdown(); + setValue(id); + }; + + const CopyToClipboard = async (copyText: string) => { + let clipbaordStr = ""; + clipbaordStr = copyText; + await Clipboard.write({ + string: clipbaordStr, + }); + toast.success("Copied to clipboard"); + }; + + const changeOfferHandle = (data : string) => { + setOfferValue(data) + } + + return ( +
+
+
Static Payment Offers
+ {isConnect ? ( + <> +
+
+ {value ? ( +
+ {arrangeIcon(value.icon, value.pubSource ? value.id.split("-")[0] : undefined)} +
{value.label}
+
+ ) : ( +
+ )} +
+ {display === 1 && + remainValues.map((item: SpendFrom) => { + return ( +
{ + selectOption(item); + }} + className="item" + key={item.label} + > + {arrangeIcon(item.icon, item.pubSource ? item.id.split("-")[0] : undefined)} +
{item.label}
+
+ ); + })} +
+
+
+ {Icons.arrow()} +
+
+ {displayData && + (
+
+
Defulat Offer
+
{ + setIsEdit(!isEdit) + }} + > + {Icons.pencilIcons()} +
+
+ {!isEdit ? ( +
{offerValue}
+ ) : ( +
+ { + changeOfferHandle(e.target.value) + }} + /> +
+ )} +
+
Spontaneous Payments
+
{ + CopyToClipboard(offerValue); + }} + > + {Icons.combindIcon()} +
+
+
+ ) + } + + ) : ( +
+ Not Connected +
+ )} +
+
+ ); +}; diff --git a/src/Pages/Receive/index.tsx b/src/Pages/Receive/index.tsx index f8d533f5..26a98297 100644 --- a/src/Pages/Receive/index.tsx +++ b/src/Pages/Receive/index.tsx @@ -7,7 +7,7 @@ import * as Icons from "../../Assets/SvgIconLibrary"; import { UseModal } from '../../Hooks/UseModal'; import { isAxiosError } from 'axios'; import { Modal } from '../../Components/Modals/Modal'; -import { useIonRouter, getPlatforms } from '@ionic/react'; +import { useIonRouter } from '@ionic/react'; import { Buffer } from 'buffer'; import { bech32 } from 'bech32'; import { useSelector } from '../../State/store'; @@ -19,7 +19,6 @@ import { createLnurlInvoice, createNostrInvoice, createNostrPayLink, getNostrBtc import { parseBitcoinInput } from '../../constants'; import { toggleLoading } from '../../State/Slices/loadingOverlay'; import Toggle from '../../Components/Toggle'; -import { decodeNprofile } from '../../custom-nip19'; import { toast } from "react-toastify"; import Toast from "../../Components/Toast"; import { Tab, Tabs } from '../../Components/ReceiveScreenTabs'; @@ -91,20 +90,10 @@ export const Receive = () => { const vanityName = topPaySource.vanityName if (!vanityName) { return null; - } - - if (vanityName.includes("@")) { // lnAddress from LV integration - return vanityName } else { - const decoded = decodeNprofile(topPaySource.pasteField); - const url = decoded.bridge![0]; - console.log({ decoded }) - - const hostName = new URL(url); - const parts = hostName.hostname.split("."); - const domainName = parts.slice(-2).join('.'); - return `${vanityName}@${domainName}` + return vanityName } + }, [paySource]) useEffect(() => { diff --git a/src/Pages/Sources/index.tsx b/src/Pages/Sources/index.tsx index 6bfd689d..e4fe11e9 100644 --- a/src/Pages/Sources/index.tsx +++ b/src/Pages/Sources/index.tsx @@ -13,7 +13,7 @@ import { useSelector, useDispatch } from '../../State/store'; //import reducer import { addPaySources, editPaySources, deletePaySources, setPaySources } from '../../State/Slices/paySourcesSlice'; import { addSpendSources, editSpendSources, deleteSpendSources, setSpendSources } from '../../State/Slices/spendSourcesSlice'; import { Modal } from '../../Components/Modals/Modal'; -import { Destination, InputClassification, NOSTR_PUB_DESTINATION, NOSTR_RELAYS, options, parseBitcoinInput } from '../../constants'; +import { Destination, InputClassification, NOSTR_RELAYS, options, parseBitcoinInput } from '../../constants'; import BootstrapSource from "../../Assets/Images/bootstrap_source.jpg"; import Sortable from 'sortablejs'; import { useIonRouter } from '@ionic/react'; @@ -21,13 +21,13 @@ import { createLnurlInvoice, createNostrInvoice, generateNewKeyPair, handlePayIn import { toggleLoading } from '../../State/Slices/loadingOverlay'; import { removeNotify } from '../../State/Slices/notificationSlice'; import { useLocation } from 'react-router'; -import { CustomProfilePointer, decodeNprofile } from '../../custom-nip19'; +import { decodeNProfile } from '../../custom-nip19'; import { toast } from "react-toastify"; import Toast from "../../Components/Toast"; import { truncateString } from '../../Hooks/truncateString'; import { getNostrClient } from '../../Api'; -import { getPublicKey } from '../../Api/tools'; import { fetchBeacon } from '../../helpers/remoteBackups'; +import { nip19 } from 'nostr-tools'; const arrayMove = (arr: string[], oldIndex: number, newIndex: number) => { const newArr = arr.map(e => e); @@ -73,7 +73,7 @@ export const Sources = () => { } else if (destination.data.includes("nprofile") || destination.type === InputClassification.LNURL || destination.type === InputClassification.LN_ADDRESS) { setSourcePasteField(destination.data); if (destination.data.includes("nprofile")) { - const data = decodeNprofile(destination.data); + const data = decodeNProfile(destination.data); fetchBeacon(data.pubkey, data.relays || NOSTR_RELAYS, 2 * 60).then(beacon => { if (beacon) { setNameFromBeacon(beacon.data.name) @@ -121,11 +121,10 @@ export const Sources = () => { const [sourceLabel, setSourceLabel] = useState(""); const [optional, setOptional] = useState(options.little); - const [modalContent, setModalContent] = useState(); + const [modalContent, setModalContent] = useState(); //This is the state variables what can be used to save sorce id temporarily when edit Source item - const [editPSourceId, setEditPSourceId] = useState(""); - const [editSSourceId, setEditSSourceId] = useState(""); + const [editSourceId, setEditSourceId] = useState(""); const [processingSource, setProcessingSource] = useState(false); const { isShown, toggle } = UseModal(); @@ -143,7 +142,7 @@ export const Sources = () => { const openEditSourcePay = (key: string) => { const source = paySources.sources[key] if (source) { - setEditPSourceId(key); + setEditSourceId(key); setOptional(source.option || ''); setSourceLabel(source.label || ''); setModalContent("editSourcepay"); @@ -154,7 +153,7 @@ export const Sources = () => { const EditSourceSpend_Modal = (key: string) => { const source = spendSources.sources[key]; if (source) { - setEditSSourceId(key); + setEditSourceId(key); setOptional(source.option || ''); setSourceLabel(source.label || ''); setModalContent("editSourcespend"); @@ -173,7 +172,7 @@ export const Sources = () => { toggle(); } - const switchContent = (value: null | undefined | "promptSweep" | "addSource" | "editSourcepay" | "editSourcespend" | "notify" | "sourceNotify" | "sweepLnurlModal" | "acceptInvite") => { + const switchContent = (value: null | undefined | "promptSweep" | "addSource" | "editSourcepay" | "editSourcespend" | "notify" | "sourceNotify" | "sweepLnurlModal" | "acceptInvite" | "deleteSource") => { switch (value) { case 'promptSweep': return promptSweep @@ -196,6 +195,9 @@ export const Sources = () => { case "acceptInvite": return acceptInviteContent + case "deleteSource": + return deleteSource + default: return notifyContent } @@ -217,13 +219,13 @@ export const Sources = () => { const inputSource = splitted[0] const adminEnrollToken = splitted.length > 1 ? splitted[1] : undefined; console.log({ splitted }) - let data: CustomProfilePointer | null = null; + let data: nip19.ProfilePointer | null = null; if (inputSource.startsWith("nprofile")) { // nprofile try { - data = decodeNprofile(inputSource); + data = decodeNProfile(inputSource); const pub = data.pubkey const existingSpendSourceId = spendSources.order.find(id => id.startsWith(pub)); if (existingSpendSourceId) { @@ -389,7 +391,7 @@ export const Sources = () => { return; } const paySourceToEdit: PayTo = { - ...paySources.sources[editPSourceId], + ...paySources.sources[editSourceId], option: optional, label: sourceLabel, }; @@ -405,7 +407,7 @@ export const Sources = () => { return } const spendSourceToEdit: SpendFrom = { - ...spendSources.sources[editSSourceId], + ...spendSources.sources[editSourceId], option: optional, label: sourceLabel }; @@ -416,19 +418,19 @@ export const Sources = () => { }; const deletePaySource = () => { - setEditPSourceId(""); - dispatch(deletePaySources(editPSourceId)) + setEditSourceId(""); + dispatch(deletePaySources(editSourceId)); resetValue(); toggle(); }; const deleteSpendSource = () => { - setEditSSourceId(""); - const associatedNotification = notifications.find(n => n.link === `/sources?sourceId=${editSSourceId}`); + setEditSourceId(""); + const associatedNotification = notifications.find(n => n.link === `/sources?sourceId=${editSourceId}`); if (associatedNotification) { dispatch(removeNotify(associatedNotification.date)); } - dispatch(deleteSpendSources(editSSourceId)) + dispatch(deleteSpendSources(editSourceId)); resetValue(); toggle(); }; @@ -573,8 +575,8 @@ export const Sources = () => { />
- - + +
; @@ -639,6 +641,21 @@ export const Sources = () => {
+ const deleteSource = ( + +
+ Are you sure you want to delete this source? +
+
+ + +
+
+ ); + useEffect(() => { const list = document.getElementById('spend-list'); diff --git a/src/State/bridgeMiddleware.ts b/src/State/bridgeMiddleware.ts index ed687737..7791e3ff 100644 --- a/src/State/bridgeMiddleware.ts +++ b/src/State/bridgeMiddleware.ts @@ -2,43 +2,56 @@ import { AnyAction, createAction, createListenerMiddleware, isAnyOf, ListenerEff import { addPaySources } from "./Slices/paySourcesSlice"; import { AppDispatch, State } from "./store"; import { PayTo } from "../globalTypes"; -import { decodeNprofile } from "../custom-nip19"; import { getNostrClient } from "../Api"; import Bridge from "../Api/bridge"; +import { decodeNProfile } from "../custom-nip19"; +import { finishEvent } from "../Api/tools"; +import { getToken } from "../Api/tools/nip98"; + export const upgradeSourcesToNofferBridge = createAction("upgradeSourcesToNofferBridge"); const enrollToBridge = async (source: PayTo, dispatchCallback: (vanityname: string) => void) => { - const { pubkey, relays, bridge } = decodeNprofile(source.pasteField) - if (bridge && bridge.length > 0) { - const nostrClient = await getNostrClient({ pubkey, relays }, source.keys); + const data = decodeNProfile(source.pasteField) + const { pubkey, relays } = data + const nostrClient = await getNostrClient({ pubkey, relays }, source.keys); - const lnurlPayLinkRes = await nostrClient.GetLnurlPayLink(); - if (lnurlPayLinkRes.status !== "OK") { - throw new Error(lnurlPayLinkRes.reason); - } + const userInfoRes = await nostrClient.GetUserInfo(); + if (userInfoRes.status !== "OK") { + throw new Error(userInfoRes.reason); + } - const userInfoRes = await nostrClient.GetUserInfo(); - if (userInfoRes.status !== "OK") { - throw new Error(userInfoRes.reason); - } + // we still get and send the k1 so that legacy mappings in bridge are moved to nofferMapping + const lnurlPayLinkRes = await nostrClient.GetLnurlPayLink(); + let k1: string | undefined = undefined; + if (lnurlPayLinkRes.status === "OK") { + k1 = lnurlPayLinkRes.k1 + } + + const bridgeUrl = userInfoRes.bridge_url; + if (!bridgeUrl) return; - const bridgeHandler = new Bridge(bridge[0]); - const bridgeRes = await bridgeHandler.GetOrCreateVanityName(lnurlPayLinkRes.k1, userInfoRes.noffer); - if (bridgeRes.status !== "OK") { - throw new Error(bridgeRes.reason); - } - dispatchCallback(bridgeRes.vanity_name) + const payload = { k1, noffer: userInfoRes.noffer } + const nostrHeader = await getToken(`${bridgeUrl}/api/v1/noffer/vanity`, "POST", e => finishEvent(e, source.keys.privateKey), true, payload) + const bridgeHandler = new Bridge(bridgeUrl, nostrHeader); + const bridgeRes = await bridgeHandler.GetOrCreateNofferName(payload); + if (bridgeRes.status !== "OK") { + throw new Error(bridgeRes.reason); } + const hostName = new URL(bridgeUrl); + const parts = hostName.hostname.split("."); + const domainName = parts.slice(-2).join('.'); + + dispatchCallback(`${bridgeRes.vanity_name}@${domainName}`) + } export const bridgeListener = { matcher: isAnyOf(addPaySources, upgradeSourcesToNofferBridge), effect: async (action: AnyAction, listenerApi: ListenerEffectAPI) => { if (upgradeSourcesToNofferBridge.match(action)) { - console.log("CALLLLLED") const paySources = listenerApi.getState().paySource; const nostrPayTos = Object.values(paySources.sources).filter(source => source.pubSource); await Promise.all(nostrPayTos.map(async source => enrollToBridge( diff --git a/src/custom-nip19.ts b/src/custom-nip19.ts index 2e0b38f3..bfd3fa3d 100644 --- a/src/custom-nip19.ts +++ b/src/custom-nip19.ts @@ -6,6 +6,7 @@ */ import { bytesToHex, concatBytes, hexToBytes } from '@noble/hashes/utils'; import { bech32 } from 'bech32'; +import { nip19 } from 'nostr-tools'; export const utf8Decoder = new TextDecoder('utf-8') export const utf8Encoder = new TextEncoder() @@ -103,6 +104,7 @@ export const decodeNoffer = (noffer: string): OfferPointer => { } } +// deprecated export const decodeNprofile = (nprofile: string): CustomProfilePointer => { const { prefix, words } = bech32.decode(nprofile, 5000) if (prefix !== "nprofile") { @@ -120,3 +122,11 @@ export const decodeNprofile = (nprofile: string): CustomProfilePointer => { bridge: tlv[2] ? tlv[2].map(d => utf8Decoder.decode(d)) : [] } } + +export const decodeNProfile = (nprofile:string) => { + const { type, data } = nip19.decode(nprofile); + if (type !== "nprofile") { + throw new Error("Not an nprofile"); + } + return data; +} diff --git a/vite.config.ts b/vite.config.ts index 358d2b06..f8d1e70c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,6 +2,7 @@ import legacy from '@vitejs/plugin-legacy' import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' import eslint from 'vite-plugin-eslint'; +import { VitePWA } from 'vite-plugin-pwa' // https://vitejs.dev/config/ export default defineConfig({ @@ -11,11 +12,44 @@ export default defineConfig({ eslint({ failOnError: false, failOnWarning: false + }), + VitePWA({ + registerType: 'autoUpdate', + includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'], + manifest: { + name: 'Your App Name', + short_name: 'App', + description: 'Your app description', + theme_color: '#ffffff', + icons: [ + { + src: 'pwa-192x192.png', + sizes: '192x192', + type: 'image/png' + }, + { + src: 'pwa-512x512.png', + sizes: '512x512', + type: 'image/png' + } + ] + } }) ], - test: { - globals: true, - environment: 'jsdom', - setupFiles: './src/setupTests.ts', - } + // Remove the 'test' configuration from here + build: { + rollupOptions: { + output: { + manualChunks: undefined, + }, + }, + }, + server: { + host: true, + port: 8100, + }, + // Add this section to handle SPA routing for PWA + preview: { + port: 8080, + }, })