From 859e546fe1fc9093bea1cfbdb166ea2a3ec604ed Mon Sep 17 00:00:00 2001 From: Erik Brakke Date: Wed, 3 May 2023 17:10:11 -0600 Subject: [PATCH] decode token with cashu-ts --- package-lock.json | 136 +++++++++++++++++++++++++++++++++++++--------- package.json | 3 +- src/js/token.js | 81 +-------------------------- 3 files changed, 115 insertions(+), 105 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53a73b1b..c5b2fb1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "@capacitor/clipboard": "^4.1.0", + "@cashu/cashu-ts": "^0.8.0-rc.0", "@chenfengyuan/vue-qrcode": "^2.0.0", "@quasar/extras": "^1.0.0", "@vueuse/core": "^10.0.2", @@ -16,6 +17,7 @@ "core-js": "^3.6.5", "light-bolt11-decoder": "^3.0.0", "pinia": "^2.0.35", + "qrcode": "^1.5.1", "qrcode-reader-vue3": "^3.1.2", "quasar": "^2.6.0", "underscore": "^1.13.6", @@ -41,7 +43,7 @@ "workbox-webpack-plugin": "^6.5.4" }, "engines": { - "node": ">= 12.22.1", + "node": ">=16.11.0", "npm": ">= 6.13.4", "yarn": ">= 1.21.1" } @@ -2086,6 +2088,40 @@ "tslib": "^2.1.0" } }, + "node_modules/@cashu/cashu-ts": { + "version": "0.8.0-rc.0", + "resolved": "https://registry.npmjs.org/@cashu/cashu-ts/-/cashu-ts-0.8.0-rc.0.tgz", + "integrity": "sha512-ujl3wpSbEFleQQcF++FhC2hrzA3ElN+KGTIvQXcVP9eD4V+QmP9BGtFdwFHEUQll59I7tSvrJIFpPGMUnVAu4g==", + "dependencies": { + "@gandlaf21/bolt11-decode": "^3.0.6", + "@noble/curves": "^1.0.0", + "axios": "^1.2.1", + "buffer": "^6.0.3" + } + }, + "node_modules/@cashu/cashu-ts/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/@chenfengyuan/vue-qrcode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@chenfengyuan/vue-qrcode/-/vue-qrcode-2.0.0.tgz", @@ -2320,6 +2356,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@gandlaf21/bolt11-decode": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@gandlaf21/bolt11-decode/-/bolt11-decode-3.0.6.tgz", + "integrity": "sha512-KUcAK2b9or8J47hzNTM2A+xdU0jCGIL4oC4TDyUlRYMfS5dBVOh4ywg9r3TZD8C/eVx7r14Hp4F79CSDjyCWTQ==", + "dependencies": { + "bech32": "^1.1.2", + "bn.js": "^4.11.8", + "buffer": "^6.0.3" + } + }, + "node_modules/@gandlaf21/bolt11-decode/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3254,6 +3323,31 @@ "eslint-scope": "5.1.1" } }, + "node_modules/@noble/curves": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", + "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "1.3.0" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6004,7 +6098,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -6026,6 +6119,11 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -6061,6 +6159,11 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -6692,7 +6795,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -7530,7 +7632,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7735,8 +7836,7 @@ "node_modules/dijkstrajs": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.2.tgz", - "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==", - "peer": true + "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==" }, "node_modules/dir-compare": { "version": "3.3.0", @@ -8462,8 +8562,7 @@ "node_modules/encode-utf8": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "peer": true + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -11588,7 +11687,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -16557,7 +16655,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", - "peer": true, "engines": { "node": ">=10.13.0" } @@ -17356,7 +17453,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.1.tgz", "integrity": "sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==", - "peer": true, "dependencies": { "dijkstrajs": "^1.0.1", "encode-utf8": "^1.0.3", @@ -17870,8 +17966,7 @@ "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "peer": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/requires-port": { "version": "1.0.0", @@ -18577,8 +18672,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "peer": true + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-value": { "version": "2.0.1", @@ -21446,8 +21540,7 @@ "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "peer": true + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "node_modules/which-typed-array": { "version": "1.1.9", @@ -21880,8 +21973,7 @@ "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "peer": true + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "node_modules/yallist": { "version": "3.1.1", @@ -21902,7 +21994,6 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "peer": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -21924,7 +22015,6 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "peer": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -21937,7 +22027,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -21950,7 +22039,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -21962,7 +22050,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -21977,7 +22064,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "peer": true, "dependencies": { "p-limit": "^2.2.0" }, diff --git a/package.json b/package.json index f17abc60..716bf09d 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,15 @@ }, "dependencies": { "@capacitor/clipboard": "^4.1.0", + "@cashu/cashu-ts": "^0.8.0-rc.0", "@chenfengyuan/vue-qrcode": "^2.0.0", "@quasar/extras": "^1.0.0", "@vueuse/core": "^10.0.2", "axios": "^1.3.3", "core-js": "^3.6.5", "light-bolt11-decoder": "^3.0.0", - "qrcode": "^1.5.1", "pinia": "^2.0.35", + "qrcode": "^1.5.1", "qrcode-reader-vue3": "^3.1.2", "quasar": "^2.6.0", "underscore": "^1.13.6", diff --git a/src/js/token.js b/src/js/token.js index 5462836a..674d2a60 100644 --- a/src/js/token.js +++ b/src/js/token.js @@ -1,3 +1,4 @@ +import { getDecodedToken } from "@cashu/cashu-ts"; /** * Functions related to cashu tokens * @typedef {{C: string, amount: number, id: number, secret: number}} Proof @@ -13,11 +14,7 @@ export default { decode, getProofs, getMint }; */ function decode(encoded_token) { if (!encoded_token || encoded_token === "") return ""; - encoded_token = cropPrefixes(encoded_token); - if (isV2Token(encoded_token)) return parseV2Token(encoded_token); - if (isV3Token(encoded_token)) return parseV3Token(encoded_token); - - throw new Error("Unknown token format"); + return getDecodedToken(encoded_token); } /** @@ -49,77 +46,3 @@ function getMint(decoded_token) { return ""; } } - -/** - * @param {string} token - * @returns {boolean} - */ -function isV2Token(token) { - return token.startsWith("eyJwcm9"); -} - -/** - * - * @param {string} token - * @returns {boolean} - */ -function isV3Token(token) { - return token.startsWith("cashuA"); -} - -/** - * @param {string} encoded_token - * @returns {{token: Token[]}} - */ -function parseV3Token(encoded_token) { - let prefix = "cashuA"; - let token_parsed = encoded_token.slice(prefix.length); - let tokenJson = getTokenJSON(token_parsed); - if ( - !(tokenJson.token.length > 0) || - !(tokenJson.token[0].proofs.length > 0) - ) { - throw new Error("No proofs in encoded token"); - } - return tokenJson; -} - -/** - * @param {string} encoded_token - * @returns {{token: Token[]}} - */ -function parseV2Token(encoded_token) { - let tokenV2 = getTokenJSON(encoded_token); - let newToken = { - token: [ - { - proofs: tokenV2.proofs, - mint: tokenV2.mints[0].url, - }, - ], - }; - return newToken; -} - -/** - * @param {string} token - * @returns {{token: Token[]}} - */ -function getTokenJSON(token) { - return JSON.parse(atob(token)); -} - -/** - * - * @param {string} token - * @returns {string} - */ -function cropPrefixes(token) { - let uriPrefixes = ["web+cashu://", "cashu://", "cashu:"]; - uriPrefixes.forEach((prefix) => { - if (token.startsWith(prefix)) { - token = token.slice(prefix.length); - } - }); - return token; -}