From e0cb85440932c2ff13e8e741816cdcad3c95a90e Mon Sep 17 00:00:00 2001 From: huianyang Date: Wed, 11 Sep 2024 17:37:12 -0700 Subject: [PATCH 01/16] feat: revived @taquiot/wallet-connect-2 package --- package-lock.json | 516 +++++++- .../taquito-wallet-connect-2/package.json | 106 ++ .../taquito-wallet-connect-2/rollup.config.ts | 29 + .../taquito-wallet-connect-2/src/errors.ts | 149 +++ .../src/taquito-wallet-connect-2.ts | 649 +++++++++ .../taquito-wallet-connect-2/src/types.ts | 112 ++ .../taquito-wallet-connect-2/test/data.ts | 137 ++ .../test/taquito-wallet-connect-2.spec.ts | 1166 +++++++++++++++++ .../taquito-wallet-connect-2/tsconfig.json | 9 + .../tsconfig.prod.json | 9 + packages/taquito/src/operations/index.ts | 46 +- tsconfig.base.json | 3 + typedoc.js | 1 + website/package-lock.json | 163 +-- 14 files changed, 2968 insertions(+), 127 deletions(-) create mode 100644 packages/taquito-wallet-connect-2/package.json create mode 100644 packages/taquito-wallet-connect-2/rollup.config.ts create mode 100644 packages/taquito-wallet-connect-2/src/errors.ts create mode 100644 packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts create mode 100644 packages/taquito-wallet-connect-2/src/types.ts create mode 100644 packages/taquito-wallet-connect-2/test/data.ts create mode 100644 packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts create mode 100644 packages/taquito-wallet-connect-2/tsconfig.json create mode 100644 packages/taquito-wallet-connect-2/tsconfig.prod.json diff --git a/package-lock.json b/package-lock.json index 524f553b1a..e862f6f09e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7142,6 +7142,10 @@ "resolved": "packages/taquito-utils", "link": true }, + "node_modules/@taquito/wallet-connect-2": { + "resolved": "packages/taquito-wallet-connect-2", + "link": true + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -7543,6 +7547,17 @@ "@types/node": "*" } }, + "node_modules/@types/pino": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/pino/-/pino-7.0.5.tgz", + "integrity": "sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==", + "deprecated": "This is a stub types definition. pino provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "pino": "*" + } + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -7857,6 +7872,32 @@ "uint8arrays": "^3.1.0" } }, + "node_modules/@walletconnect/encoding": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@walletconnect/encoding/-/encoding-1.0.2.tgz", + "integrity": "sha512-CrwSBrjqJ7rpGQcTL3kU+Ief+Bcuu9PH6JLOb+wM6NITX1GTxR/MfNwnQfhLKK6xpRAyj2/nM04OOH6wS8Imag==", + "license": "MIT", + "dependencies": { + "is-typedarray": "1.0.0", + "tslib": "1.14.1", + "typedarray-to-buffer": "3.1.5" + } + }, + "node_modules/@walletconnect/encoding/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@walletconnect/encoding/node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/@walletconnect/environment": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@walletconnect/environment/-/environment-1.0.1.tgz", @@ -7986,6 +8027,62 @@ } } }, + "node_modules/@walletconnect/legacy-modal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@walletconnect/legacy-modal/-/legacy-modal-2.0.0.tgz", + "integrity": "sha512-jckNd8lMhm4X7dX9TDdxM3bXKJnaqkRs6K2Mo5j6GmbIF9Eyx40jZ5+q457RVxvM6ciZEDT5s1wBHWdWoOo+9Q==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/legacy-types": "^2.0.0", + "@walletconnect/legacy-utils": "^2.0.0", + "copy-to-clipboard": "^3.3.3", + "preact": "^10.12.0", + "qrcode": "^1.5.1" + } + }, + "node_modules/@walletconnect/legacy-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@walletconnect/legacy-types/-/legacy-types-2.0.0.tgz", + "integrity": "sha512-sOVrA7HUdbI1OwKyPOQU0/DdvTSVFlsXWpAk2K2WvP2erTkBWPMTJq6cv2BmKdoJ3p6gLApT7sd+jHi3OF71uw==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/jsonrpc-types": "^1.0.2" + } + }, + "node_modules/@walletconnect/legacy-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@walletconnect/legacy-utils/-/legacy-utils-2.0.0.tgz", + "integrity": "sha512-CPWxSVVXw0kgNCxvU126g4GiV3mzXmC8IPJ15twE46aJ1FX+RHEIfAzFMFz2F2+fEhBxL63A7dwNQKDXorRPcQ==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/encoding": "^1.0.2", + "@walletconnect/jsonrpc-utils": "^1.0.4", + "@walletconnect/legacy-types": "^2.0.0", + "@walletconnect/safe-json": "^1.0.1", + "@walletconnect/window-getters": "^1.0.1", + "@walletconnect/window-metadata": "^1.0.1", + "detect-browser": "^5.3.0", + "query-string": "^6.13.5" + } + }, + "node_modules/@walletconnect/legacy-utils/node_modules/query-string": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", + "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@walletconnect/logger": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@walletconnect/logger/-/logger-2.1.2.tgz", @@ -7997,9 +8094,9 @@ } }, "node_modules/@walletconnect/relay-api": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@walletconnect/relay-api/-/relay-api-1.0.10.tgz", - "integrity": "sha512-tqrdd4zU9VBNqUaXXQASaexklv6A54yEyQQEXYOCr+Jz8Ket0dmPBDyg19LVSNUN2cipAghQc45/KVmfFJ0cYw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@walletconnect/relay-api/-/relay-api-1.0.11.tgz", + "integrity": "sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==", "license": "MIT", "dependencies": { "@walletconnect/jsonrpc-types": "^1.0.2" @@ -9645,7 +9742,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11358,6 +11454,15 @@ "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", "license": "MIT" }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core-js-compat": { "version": "3.37.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", @@ -11862,7 +11967,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12162,6 +12266,12 @@ "node": ">=0.3.1" } }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -16313,7 +16423,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, "license": "MIT" }, "node_modules/is-unicode-supported": { @@ -21489,7 +21598,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -22051,6 +22159,15 @@ "node": ">=4" } }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", @@ -22116,6 +22233,16 @@ "node": ">=4" } }, + "node_modules/preact": { + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prebuild-install": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", @@ -22431,6 +22558,23 @@ ], "license": "MIT" }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/qrcode-svg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/qrcode-svg/-/qrcode-svg-1.1.0.tgz", @@ -22440,6 +22584,166 @@ "qrcode-svg": "bin/qrcode-svg.js" } }, + "node_modules/qrcode/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/qrcode/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/qrcode/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/qrcode/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/qrcode/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qrcode/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/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==", + "license": "ISC" + }, + "node_modules/qrcode/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", @@ -23097,6 +23401,12 @@ "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", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -24027,7 +24337,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, "license": "ISC" }, "node_modules/set-function-length": { @@ -25479,6 +25788,12 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -26914,6 +27229,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" + }, "node_modules/which-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", @@ -28198,6 +28519,185 @@ "ieee754": "^1.2.1" } }, + "packages/taquito-wallet-connect-2": { + "name": "@taquito/wallet-connect-2", + "version": "20.0.1", + "license": "Apache-2.0", + "dependencies": { + "@taquito/taquito": "^20.0.1", + "@walletconnect/legacy-modal": "^2.0.0", + "@walletconnect/sign-client": "^2.16.1", + "@walletconnect/types": "^2.16.1", + "@walletconnect/utils": "^2.16.1" + }, + "devDependencies": { + "@types/bluebird": "^3.5.42", + "@types/chrome": "0.0.171", + "@types/jest": "^29.5.12", + "@types/node": "^22", + "@types/pino": "^7.0.5", + "@types/ws": "^8.5.12", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "colors": "^1.4.0", + "coveralls": "^3.1.1", + "cross-env": "^7.0.3", + "eslint": "^8.57.0", + "jest": "^29.7.0", + "jest-config": "^29.7.0", + "lint-staged": "^15.2.7", + "lodash.camelcase": "^4.3.0", + "prettier": "^3.3.3", + "prompt": "^1.3.0", + "replace-in-file": "^8.1.0", + "rimraf": "^6.0.1", + "rollup": "^4.19.1", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-typescript2": "^0.36.0", + "shelljs": "^0.8.5", + "ts-jest": "^29.2.3", + "ts-node": "^10.9.2", + "ts-toolbelt": "^9.6.0", + "typescript": "~5.5.4" + }, + "engines": { + "node": ">=20" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@types/chrome": { + "version": "0.0.171", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.171.tgz", + "integrity": "sha512-CnCwFKI3COygib3DNJrCjePeoU2OCDGGbUcmftXtQ3loMABsLgwpG8z+LxV4kjQJFzmJDqOyhCSsbY9yyEfapQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/core": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-2.16.1.tgz", + "integrity": "sha512-UlsnEMT5wwFvmxEjX8s4oju7R3zadxNbZgsFeHEsjh7uknY2zgmUe1Lfc5XU6zyPb1Jx7Nqpdx1KN485ee8ogw==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/heartbeat": "1.2.2", + "@walletconnect/jsonrpc-provider": "1.0.14", + "@walletconnect/jsonrpc-types": "1.0.4", + "@walletconnect/jsonrpc-utils": "1.0.8", + "@walletconnect/jsonrpc-ws-connection": "1.0.14", + "@walletconnect/keyvaluestorage": "1.1.1", + "@walletconnect/logger": "2.1.2", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.16.1", + "@walletconnect/utils": "2.16.1", + "events": "3.3.0", + "lodash.isequal": "4.5.0", + "uint8arrays": "3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/heartbeat": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@walletconnect/heartbeat/-/heartbeat-1.2.2.tgz", + "integrity": "sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==", + "license": "MIT", + "dependencies": { + "@walletconnect/events": "^1.0.1", + "@walletconnect/time": "^1.0.2", + "events": "^3.3.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/jsonrpc-provider": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.14.tgz", + "integrity": "sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==", + "license": "MIT", + "dependencies": { + "@walletconnect/jsonrpc-utils": "^1.0.8", + "@walletconnect/safe-json": "^1.0.2", + "events": "^3.3.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/jsonrpc-types": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.4.tgz", + "integrity": "sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==", + "license": "MIT", + "dependencies": { + "events": "^3.3.0", + "keyvaluestorage-interface": "^1.0.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/sign-client": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.16.1.tgz", + "integrity": "sha512-s2Tx2n2duxt+sHtuWXrN9yZVaHaYqcEcjwlTD+55/vs5NUPlISf+fFmZLwSeX1kUlrSBrAuxPUcqQuRTKcjLOA==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/core": "2.16.1", + "@walletconnect/events": "1.0.1", + "@walletconnect/heartbeat": "1.2.2", + "@walletconnect/jsonrpc-utils": "1.0.8", + "@walletconnect/logger": "2.1.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.16.1", + "@walletconnect/utils": "2.16.1", + "events": "3.3.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/types": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-2.16.1.tgz", + "integrity": "sha512-9P4RG4VoDEF+yBF/n2TF12gsvT/aTaeZTVDb/AOayafqiPnmrQZMKmNCJJjq1sfdsDcHXFcZWMGsuCeSJCmrXA==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/events": "1.0.1", + "@walletconnect/heartbeat": "1.2.2", + "@walletconnect/jsonrpc-types": "1.0.4", + "@walletconnect/keyvaluestorage": "1.1.1", + "@walletconnect/logger": "2.1.2", + "events": "3.3.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/@walletconnect/utils": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.16.1.tgz", + "integrity": "sha512-aoQirVoDoiiEtYeYDtNtQxFzwO/oCrz9zqeEEXYJaAwXlGVTS34KFe7W3/Rxd/pldTYKFOZsku2EzpISfH8Wsw==", + "license": "Apache-2.0", + "dependencies": { + "@stablelib/chacha20poly1305": "1.0.1", + "@stablelib/hkdf": "1.0.1", + "@stablelib/random": "1.0.2", + "@stablelib/sha256": "1.0.1", + "@stablelib/x25519": "1.0.3", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.16.1", + "@walletconnect/window-getters": "1.0.1", + "@walletconnect/window-metadata": "1.0.1", + "detect-browser": "5.3.0", + "elliptic": "^6.5.7", + "query-string": "7.1.3", + "uint8arrays": "3.1.0" + } + }, + "packages/taquito-wallet-connect-2/node_modules/uint8arrays": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.0.tgz", + "integrity": "sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==", + "license": "MIT", + "dependencies": { + "multiformats": "^9.4.2" + } + }, "packages/taquito/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", diff --git a/packages/taquito-wallet-connect-2/package.json b/packages/taquito-wallet-connect-2/package.json new file mode 100644 index 0000000000..3ce9de377a --- /dev/null +++ b/packages/taquito-wallet-connect-2/package.json @@ -0,0 +1,106 @@ +{ + "name": "@taquito/wallet-connect-2", + "version": "20.0.1", + "description": "Wallet connect 2 provider", + "keywords": [ + "tezos", + "blockchain", + "websocket" + ], + "main": "dist/taquito-wallet-connect-2.umd.js", + "module": "dist/taquito-wallet-connect-2.es6.js", + "typings": "dist/types/taquito-wallet-connect-2.d.ts", + "files": [ + "signature.json", + "dist" + ], + "publishConfig": { + "access": "public" + }, + "author": "Roxane Letourneau ", + "repository": { + "type": "git", + "url": "" + }, + "license": "Apache-2.0", + "engines": { + "node": ">=20" + }, + "scripts": { + "test": "jest --coverage", + "test:watch": "jest --coverage --watch", + "test:prod": "npm run lint && npm run test -- --no-cache", + "lint": "eslint --ext .js,.ts .", + "precommit": "lint-staged", + "prebuild": "rimraf dist", + "version-stamp": "node ../taquito/version-stamping.js", + "build": "tsc --project ./tsconfig.prod.json --module commonjs && rollup -c rollup.config.ts --bundleConfigAsCjs", + "start": "rollup -c rollup.config.ts --bundleConfigAsCjs -w" + }, + "lint-staged": { + "{src,test}/**/*.ts": [ + "prettier --write", + "eslint --fix" + ] + }, + "jest": { + "transform": { + ".(ts|tsx)": "ts-jest" + }, + "testEnvironment": "node", + "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js" + ], + "moduleNameMapper": { + "^@taquito/taquito$": "/../taquito/src/taquito.ts" + }, + "coveragePathIgnorePatterns": [ + "/node_modules/", + "/test/" + ], + "collectCoverageFrom": [ + "src/**/*.{js,ts}" + ] + }, + "dependencies": { + "@taquito/taquito": "^20.0.1", + "@walletconnect/legacy-modal": "^2.0.0", + "@walletconnect/sign-client": "^2.16.1", + "@walletconnect/types": "^2.16.1", + "@walletconnect/utils": "^2.16.1" + }, + "devDependencies": { + "@types/bluebird": "^3.5.42", + "@types/chrome": "0.0.171", + "@types/jest": "^29.5.12", + "@types/node": "^22", + "@types/pino": "^7.0.5", + "@types/ws": "^8.5.12", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "colors": "^1.4.0", + "coveralls": "^3.1.1", + "cross-env": "^7.0.3", + "eslint": "^8.57.0", + "jest": "^29.7.0", + "jest-config": "^29.7.0", + "lint-staged": "^15.2.7", + "lodash.camelcase": "^4.3.0", + "prettier": "^3.3.3", + "prompt": "^1.3.0", + "replace-in-file": "^8.1.0", + "rimraf": "^6.0.1", + "rollup": "^4.19.1", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-typescript2": "^0.36.0", + "shelljs": "^0.8.5", + "ts-jest": "^29.2.3", + "ts-node": "^10.9.2", + "ts-toolbelt": "^9.6.0", + "typescript": "~5.5.4" + }, + "gitHead": "551e35aeff7d6dcde1c72284238c0ed3c3aae77e" +} \ No newline at end of file diff --git a/packages/taquito-wallet-connect-2/rollup.config.ts b/packages/taquito-wallet-connect-2/rollup.config.ts new file mode 100644 index 0000000000..3769e609e0 --- /dev/null +++ b/packages/taquito-wallet-connect-2/rollup.config.ts @@ -0,0 +1,29 @@ +// import sourceMaps from 'rollup-plugin-sourcemaps'; +import camelCase from 'lodash.camelcase'; +import typescript from 'rollup-plugin-typescript2'; +import json from 'rollup-plugin-json'; + +const pkg = require('./package.json'); + +const libraryName = 'taquito-wallet-connect-2'; + +export default { + input: `src/${libraryName}.ts`, + output: [ + { file: pkg.main, name: camelCase(libraryName), format: 'umd', sourcemap: true }, + { file: pkg.module, format: 'es', sourcemap: true }, + ], + // external: [], + watch: { + include: 'src/**', + }, + plugins: [ + // Allow json resolution + json(), + // Compile TypeScript files + typescript({ tsconfig: './tsconfig.prod.json', useTsconfigDeclarationDir: true }), + + // Resolve source maps to the original source + // sourceMaps(), + ], +}; \ No newline at end of file diff --git a/packages/taquito-wallet-connect-2/src/errors.ts b/packages/taquito-wallet-connect-2/src/errors.ts new file mode 100644 index 0000000000..4ee21a1e80 --- /dev/null +++ b/packages/taquito-wallet-connect-2/src/errors.ts @@ -0,0 +1,149 @@ +import { PermissionScopeMethods } from './types'; + +/** + * @category Error + * @description Error that indicates missing required permission scopes + */ +export class MissingRequiredScope extends Error { + name = 'MissingRequiredScope'; + + constructor(public requiredScopes: PermissionScopeMethods | string) { + super(`Required permission scope were not granted for "${requiredScopes}"`); + } +} + +/** + * @category Error + * @description Error that indicates the wallet returned an invalid namespace + */ +export class InvalidReceivedSessionNamespace extends Error { + name = 'InvalidReceivedSessionNamespace'; + + constructor( + public messageWc: string, + public codeWc: number, + type: 'invalid' | 'incomplete', + public data?: string | string[] + ) { + super(); + const baseMessage = `${codeWc}: ${messageWc}.`; + this.message = data + ? type === 'incomplete' + ? ` ${baseMessage} "${data}" is missing in the session namespace.` + : ` ${baseMessage} "${data}" is invalid.` + : baseMessage; + } +} + +/** + * @category Error + * @description Error that indicates an invalid session key being passed + */ +export class InvalidSessionKey extends Error { + name = 'InvalidSessionKey'; + + constructor(public key: string) { + super(`Invalid session key "${key}"`); + } +} + +/** + * @category Error + * @description Error that indicates the pkh is not part of the active accounts in the session + */ +export class InvalidAccount extends Error { + name = 'InvalidAccount'; + + constructor(public pkh: string) { + super(`Invalid pkh "${pkh}"`); + } +} + +/** + * @category Error + * @description Error that indicates the network is not part of the active networks in the session + */ +export class InvalidNetwork extends Error { + name = 'InvalidNetwork'; + + constructor(public network: string) { + super(`Invalid network "${network}"`); + } +} + +/** + * @category Error + * @description Error that indicates the combinaison pkh-network is not part of the active session + */ +export class InvalidNetworkOrAccount extends Error { + name = 'InvalidNetworkOrAccount'; + + constructor( + public network: string, + public pkh: string + ) { + super( + `No permission. The combinaison "${network}" and "${pkh}" is not part of the active session.` + ); + } +} + +/** + * @category Error + * @description Error that indicates the connection could not be established + */ +export class ConnectionFailed extends Error { + name = 'ConnectionFailed'; + + constructor(public originalError: any) { + super(`Unable to connect`); + } +} + +/** + * @category Error + * @description Error that indicates there is no active session + */ +export class NotConnected extends Error { + name = 'NotConnected'; + + constructor() { + super('Not connected, no active session'); + } +} + +/** + * @category Error + * @description Error that indicates the active account is not specified + */ +export class ActiveAccountUnspecified extends Error { + name = 'ActiveAccountUnspecified'; + + constructor() { + super('Please specify the active account using the "setActiveAccount" method.'); + } +} + +/** + * @category Error + * @description Error that indicates the active network is not specified + */ +export class ActiveNetworkUnspecified extends Error { + name = 'ActiveNetworkUnspecified'; + + constructor() { + super('Please specify the active network using the "setActiveNetwork" method.'); + } +} + +/** + * @category Error + * @description Error that indicates the session is invalid + */ +export class InvalidSession extends Error { + name = 'InvalidSession'; + + constructor(message: string) { + super(message); + } +} diff --git a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts new file mode 100644 index 0000000000..ae791ae870 --- /dev/null +++ b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts @@ -0,0 +1,649 @@ +/** + * @packageDocumentation + * @module @taquito/wallet-connect-2 + */ + +import Client from '@walletconnect/sign-client'; +import { SignClientTypes, SessionTypes, PairingTypes } from '@walletconnect/types'; +import QRCodeModal from '@walletconnect/legacy-modal'; +import { + createOriginationOperation, + createSetDelegateOperation, + createTransferOperation, + createTransferTicketOperation, + createIncreasePaidStorageOperation, + RPCDelegateOperation, + RPCOriginationOperation, + RPCTransferOperation, + RPCTransferTicketOperation, + RPCIncreasePaidStorageOperation, + WalletDelegateParams, + WalletOriginateParams, + WalletProvider, + WalletTransferParams, + WalletTransferTicketParams, + WalletStakeParams, + WalletUnstakeParams, + WalletFinalizeUnstakeParams, + WalletIncreasePaidStorageParams, +} from '@taquito/taquito'; +import { getSdkError } from '@walletconnect/utils'; +import { + NetworkType, + OperationParams, + PermissionScopeMethods, + PermissionScopeParam, + SigningType, +} from './types'; +import { + ActiveAccountUnspecified, + ActiveNetworkUnspecified, + ConnectionFailed, + InvalidAccount, + InvalidNetwork, + InvalidNetworkOrAccount, + InvalidReceivedSessionNamespace, + InvalidSession, + InvalidSessionKey, + MissingRequiredScope, + NotConnected, +} from './errors'; + +export { SignClientTypes, PairingTypes }; +export * from './errors'; +export * from './types'; + +const TEZOS_PLACEHOLDER = 'tezos'; + +export class WalletConnect2 implements WalletProvider { + public signClient: Client; + private session: SessionTypes.Struct | undefined; + private activeAccount: string | undefined; + private activeNetwork: string | undefined; + + constructor(signClient: Client) { + this.signClient = signClient; + + this.signClient.on('session_delete', ({ topic }) => { + if (this.session?.topic === topic) { + this.session = undefined; + } + }); + + this.signClient.on('session_expire', ({ topic }) => { + if (this.session?.topic === topic) { + this.session = undefined; + } + }); + + this.signClient.on('session_update', ({ params, topic }) => { + if (this.session?.topic === topic) { + this.session.namespaces = params.namespaces; + // TODO determine if we need validation on the namespace here + } + }); + + this.signClient.on('session_event', () => { + // TODO Do we need to handle other session events, such as "chainChanged", "accountsChanged", etc. + }); + } + + /** + * @description Initialize a WalletConnect2 provider + * (Initialize a wallect connect 2 client with persisted storage and a network connection) + * + * @example + * ``` + * await WalletConnect2.init({ + * projectId: "YOUR_PROJECT_ID", + * metadata: { + * name: "YOUR_DAPP_NAME", + * description: "YOUR_DAPP_DESCRIPTION", + * icons: ["ICON_URL"], + * url: "DAPP_URL", + * }, + * }); + * ``` + */ + static async init(initParams: SignClientTypes.Options) { + const client = await Client.init(initParams); + return new WalletConnect2(client); + } + + /** + * @description Request permission for a new session and establish a connection. + * + * @param connectParams.permissionScope The networks, methods, and events that will be granted permission + * @param connectParams.pairingTopic Option to connect to an existing active pairing. If pairingTopic is defined, a prompt will appear in the corresponding wallet to accept or decline the session proposal. If no pairingTopic, a QR code modal will open in the dapp, allowing to connect to a wallet. + * @param connectParams.registryUrl Optional registry of wallet deep links to show in the Modal + * @error ConnectionFailed is thrown if no connection can be established with a wallet + */ + async requestPermissions(connectParams: { + permissionScope: PermissionScopeParam; + pairingTopic?: string; + registryUrl?: string; + }) { + // TODO when Tezos wallets will officially support wallet connect 2, we need to provide a default value for registryUrl + try { + const { uri, approval } = await this.signClient.connect({ + requiredNamespaces: { + [TEZOS_PLACEHOLDER]: { + chains: connectParams.permissionScope.networks.map( + (network) => `${TEZOS_PLACEHOLDER}:${network}` + ), + methods: connectParams.permissionScope.methods, + events: connectParams.permissionScope.events ?? [], + }, + }, + pairingTopic: connectParams.pairingTopic, + }); + + if (uri) { + QRCodeModal.open( + uri, + () => { + // noop + }, + { registryUrl: connectParams.registryUrl } + ); + } + const session = await approval(); + this.session = session; + } catch (error) { + throw new ConnectionFailed(error); + } finally { + QRCodeModal.close(); + } + this.validateReceivedNamespace(connectParams.permissionScope, this.session.namespaces); + this.setDefaultAccountAndNetwork(); + } + + /** + * @description Access all existing active pairings + */ + getAvailablePairing() { + return this.signClient.pairing.getAll({ active: true }); + } + + /** + * @description Access all existing sessions + * @return an array of strings which represent the session keys + */ + getAllExistingSessionKeys() { + return this.signClient.session.keys; + } + + /** + * @description Configure the Client with an existing session. + * The session is immediately restored without a prompt on the wallet to accept/decline it. + * @error InvalidSessionKey is thrown if the provided session key doesn't exist + */ + configureWithExistingSessionKey(key: string) { + const sessions = this.getAllExistingSessionKeys(); + if (!sessions.includes(key)) { + throw new InvalidSessionKey(key); + } + this.session = this.signClient.session.get(key); + this.setDefaultAccountAndNetwork(); + } + + async disconnect() { + if (this.session) { + await this.signClient.disconnect({ + topic: this.session.topic, + reason: getSdkError('USER_DISCONNECTED'), + }); + this.clearState(); + } + } + + getPeerMetadata() { + return this.getSession().peer.metadata; + } + + /** + * @description Once the session is establish, send Tezos operations to be approved, signed and inject by the wallet. + * @error MissingRequiredScope is thrown if permission to send operation was not granted + */ + async sendOperations(params: OperationParams[]) { + const session = this.getSession(); + if (!this.getPermittedMethods().includes(PermissionScopeMethods.OPERATION_REQUEST)) { + throw new MissingRequiredScope(PermissionScopeMethods.OPERATION_REQUEST); + } + const network = this.getActiveNetwork(); + const account = await this.getPKH(); + this.validateNetworkAndAccount(network, account); + const hash = await this.signClient.request({ + topic: session.topic, + chainId: `${TEZOS_PLACEHOLDER}:${network}`, + request: { + method: PermissionScopeMethods.OPERATION_REQUEST, + params: { + account, + operations: params, + }, + }, + }); + return hash; + } + + async sign(bytes: string, watermark?: Uint8Array): Promise { + console.log(bytes, watermark); + return ''; + } + + /** + * @description Once the session is establish, send payload to be approved and signed by the wallet. + * @error MissingRequiredScope is thrown if permission to sign payload was not granted + */ + async signPayload(params: { + signingType?: SigningType; + payload: string; + sourceAddress?: string; + }) { + const session = this.getSession(); + if (!this.getPermittedMethods().includes(PermissionScopeMethods.SIGN)) { + throw new MissingRequiredScope(PermissionScopeMethods.SIGN); + } + const network = this.getActiveNetwork(); + const account = await this.getPKH(); + this.validateNetworkAndAccount(network, account); + const signature = await this.signClient.request({ + topic: session.topic, + chainId: `${TEZOS_PLACEHOLDER}:${network}`, + request: { + method: PermissionScopeMethods.SIGN, + params: { + account: params.sourceAddress ?? account, + expression: params.payload, + signingType: params.signingType, + }, + }, + }); + return signature; + } + + /** + * @description Return all connected accounts from the active session + * @error NotConnected if no active session + */ + getAccounts() { + return this.getTezosNamespace().accounts.map((account) => account.split(':')[2]); + } + + /** + * @description Set the active account. + * Must be called if there are multiple accounts in the session and every time the active account is switched + * @param pkh public key hash of the selected account + * @error InvalidAccount thrown if the pkh is not part of the active accounts in the session + */ + setActiveAccount(pkh: string) { + if (!this.getAccounts().includes(pkh)) { + throw new InvalidAccount(pkh); + } + this.activeAccount = pkh; + } + + /** + * @description Access the public key hash of the active account + * @error ActiveAccountUnspecified thrown when there are multiple Tezos account in the session and none is set as the active one + */ + async getPKH() { + if (!this.activeAccount) { + this.getSession(); + throw new ActiveAccountUnspecified(); + } + return this.activeAccount; + } + + /** + * @description Access the public key of the active account + * @error ActiveAccountUnspecified thrown when there are multiple Tezos account in the session and none is set as the active one + */ + async getPK() { + return ''; + } + + /** + * @description Return all networks from the namespace of the active session + * @error NotConnected if no active session + */ + getNetworks() { + return this.getPermittedNetwork(); + } + + /** + * @description Set the active network. + * Must be called if there are multiple network in the session and every time the active network is switched + * @param network selected network + * @error InvalidNetwork thrown if the network is not part of the active networks in the session + */ + setActiveNetwork(network: NetworkType) { + if (!this.getNetworks().includes(network)) { + throw new InvalidNetwork(network); + } + this.activeNetwork = network; + } + + /** + * @description Access the active network + * @error ActiveNetworkUnspecified thorwn when there are multiple Tezos netwroks in the session and none is set as the active one + */ + getActiveNetwork() { + if (!this.activeNetwork) { + this.getSession(); + throw new ActiveNetworkUnspecified(); + } + return this.activeNetwork; + } + + private setDefaultAccountAndNetwork() { + const activeAccount = this.getAccounts(); + if (activeAccount.length === 1) { + this.activeAccount = activeAccount[0]; + } + const activeNetwork = this.getNetworks(); + if (activeNetwork.length === 1) { + this.activeNetwork = activeNetwork[0]; + } + } + + private clearState() { + this.session = undefined; + this.activeAccount = undefined; + this.activeNetwork = undefined; + } + + getSession() { + if (!this.session) { + throw new NotConnected(); + } + return this.session; + } + + isActiveSession() { + return this.session ? true : false; + } + + ping() { + this.signClient.ping({ topic: this.getSession().topic }); + } + + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#non-controller-side-validation-of-incoming-proposal-namespaces-dapp + // TODO: add validations related to Namespaces extensions and related unit tests: + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#210-extensions-may-be-merged-into-namespace + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#212-session-namespaces-extensions-may-extend-methods-and-events-of-proposal-namespaces-extensions + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#213-session-namespaces-extensions-may-contain-accounts-from-chains-not-defined-in-proposal-namespaces-extensions + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#214-session-namespaces-may-add-extensions-not-defined-in-proposal-namespaces-extensions + private validateReceivedNamespace( + scope: PermissionScopeParam, + receivedNamespaces: Record + ) { + if (receivedNamespaces[TEZOS_PLACEHOLDER]) { + this.validateMethods(scope.methods, receivedNamespaces[TEZOS_PLACEHOLDER].methods); + if (scope.events) { + this.validateEvents(scope.events, receivedNamespaces['tezos'].events); + } + this.validateAccounts(scope.networks, receivedNamespaces[TEZOS_PLACEHOLDER].accounts); + } else { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'All namespaces must be approved', + getSdkError('USER_REJECTED').code, + 'incomplete', + 'tezos' + ); + } + } + + private validateMethods(requiredMethods: string[], receivedMethods: string[]) { + const missingMethods: string[] = []; + requiredMethods.forEach((method) => { + if (!receivedMethods.includes(method)) { + missingMethods.push(method); + } + }); + if (missingMethods.length > 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'All methods must be approved', + getSdkError('USER_REJECTED_METHODS').code, + 'incomplete', + missingMethods + ); + } + } + + private validateEvents(requiredEvents: string[], receivedEvents: string[]) { + const missingEvents: string[] = []; + requiredEvents.forEach((method) => { + if (!receivedEvents.includes(method)) { + missingEvents.push(method); + } + }); + if (missingEvents.length > 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'All events must be approved', + getSdkError('USER_REJECTED_EVENTS').code, + 'incomplete', + missingEvents + ); + } + } + + private validateAccounts(requiredNetwork: string[], receivedAccounts: string[]) { + if (receivedAccounts.length === 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'Accounts must not be empty', + getSdkError('USER_REJECTED_CHAINS').code, + 'incomplete' + ); + } + const receivedChains: string[] = []; + const invalidChains: string[] = []; + const missingChains: string[] = []; + const invalidChainsNamespace: string[] = []; + + receivedAccounts.forEach((chain) => { + const accountId = chain.split(':'); + if (accountId.length !== 3) { + invalidChains.push(chain); + } + if (accountId[0] !== TEZOS_PLACEHOLDER) { + invalidChainsNamespace.push(chain); + } + const network = accountId[1]; + if (!receivedChains.includes(network)) { + receivedChains.push(network); + } + }); + + if (invalidChains.length > 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'Accounts must be CAIP-10 compliant', + getSdkError('USER_REJECTED_CHAINS').code, + 'invalid', + invalidChains + ); + } + + if (invalidChainsNamespace.length > 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'Accounts must be defined in matching namespace', + getSdkError('UNSUPPORTED_ACCOUNTS').code, + 'invalid', + invalidChainsNamespace + ); + } + requiredNetwork.forEach((network) => { + if (!receivedChains.includes(network)) { + missingChains.push(network); + } + }); + if (missingChains.length > 0) { + this.clearState(); + throw new InvalidReceivedSessionNamespace( + 'All chains must have at least one account', + getSdkError('USER_REJECTED_CHAINS').code, + 'incomplete', + missingChains + ); + } + } + + private getTezosNamespace(): { + accounts: string[]; + methods: string[]; + events: string[]; + } { + if (TEZOS_PLACEHOLDER in this.getSession().namespaces) { + return this.getSession().namespaces[TEZOS_PLACEHOLDER]; + } else { + throw new InvalidSession('Tezos not found in namespaces'); + } + } + + private getTezosRequiredNamespace(): { + chains?: string[]; + methods: string[]; + events: string[]; + } { + if (TEZOS_PLACEHOLDER in this.getSession().requiredNamespaces) { + return this.getSession().requiredNamespaces[TEZOS_PLACEHOLDER]; + } else { + throw new InvalidSession('Tezos not found in requiredNamespaces'); + } + } + + private validateNetworkAndAccount(network: string, account: string) { + if (!this.getTezosNamespace().accounts.includes(`${TEZOS_PLACEHOLDER}:${network}:${account}`)) { + throw new InvalidNetworkOrAccount(network, account); + } + } + + private getPermittedMethods() { + return this.getTezosRequiredNamespace().methods; + } + + private getPermittedNetwork() { + return this.getTezosRequiredNamespace().chains!.map((chain) => chain.split(':')[1]); + } + + private formatParameters( + params: WalletTransferParams | WalletOriginateParams | WalletDelegateParams + ) { + const formatedParams: any = params; + if (typeof params.fee !== 'undefined') { + formatedParams.fee = params.fee.toString(); + } + if (typeof params.storageLimit !== 'undefined') { + formatedParams.storageLimit = params.storageLimit.toString(); + } + if (typeof params.gasLimit !== 'undefined') { + formatedParams.gasLimit = params.gasLimit.toString(); + } + return formatedParams; + } + + private removeDefaultLimits( + params: + | WalletTransferParams + | WalletTransferTicketParams + | WalletOriginateParams + | WalletDelegateParams + | WalletIncreasePaidStorageParams, + operatedParams: + | Partial + | Partial + | Partial + | Partial + | Partial + ) { + if (typeof params.fee === 'undefined') { + delete operatedParams.fee; + } + if (typeof params.storageLimit === 'undefined') { + delete operatedParams.storage_limit; + } + if (typeof params.gasLimit === 'undefined') { + delete operatedParams.gas_limit; + } + return operatedParams; + } + + async mapTransferParamsToWalletParams(params: () => Promise) { + const walletParams: WalletTransferParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createTransferOperation(this.formatParameters(walletParams)) + ); + } + + async mapTransferTicketParamsToWalletParams(params: () => Promise) { + const walletParams: WalletTransferTicketParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createTransferTicketOperation(this.formatParameters(walletParams)) + ); + } + + async mapStakeParamsToWalletParams(params: () => Promise) { + const walletParams: WalletStakeParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createTransferOperation(this.formatParameters(walletParams)) + ); + } + + async mapUnstakeParamsToWalletParams(params: () => Promise) { + const walletParams: WalletUnstakeParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createTransferOperation(this.formatParameters(walletParams)) + ); + } + + async mapFinalizeUnstakeParamsToWalletParams(params: () => Promise) { + const walletParams: WalletFinalizeUnstakeParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createTransferOperation(this.formatParameters(walletParams)) + ); + } + + async mapOriginateParamsToWalletParams(params: () => Promise) { + const walletParams: WalletOriginateParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createOriginationOperation(this.formatParameters(walletParams)) + ); + } + + async mapDelegateParamsToWalletParams(params: () => Promise) { + const walletParams: WalletDelegateParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createSetDelegateOperation(this.formatParameters(walletParams)) + ); + } + + async mapIncreasePaidStorageWalletParams(params: () => Promise) { + const walletParams: WalletIncreasePaidStorageParams = await params(); + + return this.removeDefaultLimits( + walletParams, + await createIncreasePaidStorageOperation(this.formatParameters(walletParams)) + ); + } +} diff --git a/packages/taquito-wallet-connect-2/src/types.ts b/packages/taquito-wallet-connect-2/src/types.ts new file mode 100644 index 0000000000..d3dff8e13e --- /dev/null +++ b/packages/taquito-wallet-connect-2/src/types.ts @@ -0,0 +1,112 @@ +import { + RPCDelegateOperation, + RPCRegisterGlobalConstantOperation, + RPCOriginationOperation, + RPCRevealOperation, + RPCTransferOperation, + RPCTransferTicketOperation, + RPCIncreasePaidStorageOperation, + RPCBallotOperation, + RPCUpdateConsensusKeyOperation, + RPCDrainDelegateOperation, + RPCProposalsOperation, + RPCSmartRollupAddMessagesOperation, + RPCSmartRollupOriginateOperation, + RPCSmartRollupOutboxMessageOperation, + RPCFailingNoopOperation, +} from '@taquito/taquito'; + +export enum NetworkType { + MAINNET = 'mainnet', + GHOSTNET = 'ghostnet', + WEEKLYNET = 'weeklynet', + OXFORDNET = 'oxfordnet', + PARISNET = 'parisnet', + // QUEBECNET = 'quebecnet', +} + +export interface PermissionScopeParam { + networks: NetworkType[]; + methods: PermissionScopeMethods[]; + events?: PermissionScopeEvents[]; +} +export enum PermissionScopeMethods { + OPERATION_REQUEST = 'tezos_sendOperations', + SIGN = 'tezos_signExpression', +} + +export enum PermissionScopeEvents { + CHAIN_CHANGED = 'chainChanged', + ACCOUNTS_CHANGED = 'accountsChanged', +} + +export enum SigningType { + RAW = 'raw', + OPERATION = 'operation', + MICHELINE = 'micheline', +} + +type WalletDefinedFields = 'source' | 'gas_limit' | 'storage_limit' | 'fee'; +interface WalletOptionalFields { + gas_limit?: string; + storage_limit?: string; + fee?: string; +} + +export interface TransferParams + extends Omit, + WalletOptionalFields {} +export interface OriginateParams + extends Omit, + WalletOptionalFields {} +export interface RevealParams + extends Omit, + WalletOptionalFields {} +export interface DelegateParams + extends Omit, + WalletOptionalFields {} +export interface RegisterGlobalConstantParams + extends Omit, + WalletOptionalFields {} +export interface TransferTicketParams + extends Omit, + WalletOptionalFields {} +export interface IncreasePaidStorageParams + extends Omit, + WalletOptionalFields {} +export interface UpdateConsensusKeyParams + extends Omit, + WalletOptionalFields {} +export type BallotParams = Omit; +export type DrainDelegateParams = Omit; +export type ProposalsParams = Omit; +export type SmartRollupAddMessagesParams = Omit< + RPCSmartRollupAddMessagesOperation, + WalletDefinedFields +>; +export type SmartRollupOriginateParams = Omit< + RPCSmartRollupOriginateOperation, + WalletDefinedFields +>; +export type SmartRollupExecuteOutboxMessageParams = Omit< + RPCSmartRollupOutboxMessageOperation, + WalletDefinedFields +>; +export type FailingNoopParams = Omit; + +export type OperationParams = + | TransferParams + | BallotParams + | IncreasePaidStorageParams + | UpdateConsensusKeyParams + | OriginateParams + | RevealParams + | DelegateParams + | RegisterGlobalConstantParams + | DrainDelegateParams + | ProposalsParams + | SmartRollupAddMessagesParams + | SmartRollupOriginateParams + | SmartRollupExecuteOutboxMessageParams + | FailingNoopParams + | TransferTicketParams; diff --git a/packages/taquito-wallet-connect-2/test/data.ts b/packages/taquito-wallet-connect-2/test/data.ts new file mode 100644 index 0000000000..8caeb2b97a --- /dev/null +++ b/packages/taquito-wallet-connect-2/test/data.ts @@ -0,0 +1,137 @@ +export const sessionExample = { + topic: '272d3c5cfa9f5713bf837803200105c81394249f402fe0927f9ce7c1b319e0f8', + relay: { + protocol: 'irn', + }, + expiry: 1668023668, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: ['tezos_sendOperations'], + events: [], + }, + }, + acknowledged: true, + controller: 'ae8a8b81b2832bd4e3f38f848652d540172f15ff8eeafd4e3d90a00ed623af47', + self: { + publicKey: '01b5630403234ba9745073c9ad081c7b812786b2bcfa8cfe1ff28d800b989f29', + metadata: { + description: '', + url: 'http://localhost:3000', + icons: [], + name: '', + }, + }, + peer: { + publicKey: 'ae8a8b81b2832bd4e3f38f848652d540172f15ff8eeafd4e3d90a00ed623af47', + metadata: { + name: 'React Wallet', + description: 'React Wallet for WalletConnect', + url: 'https://walletconnect.com/', + icons: ['https://avatars.githubusercontent.com/u/37784886'], + }, + }, + requiredNamespaces: { + tezos: { + methods: ['tezos_sendOperations'], + chains: ['tezos:ghostnet'], + events: [], + }, + }, +}; + +export const sessionMultipleChains = { + topic: '5b7d09ec60b46ba32617549cfc62fcc7a79edff14212a0fbecaf38f6aefa09e2', + relay: { + protocol: 'irn', + }, + expiry: 1668634369, + namespaces: { + tezos: { + accounts: [ + 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'tezos:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', + 'tezos:ghostnet:tz2JobFgDoJ5HZ1jAoMgZCyNdbBEdAstkytV', + 'tezos:parisnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'tezos:parisnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', + 'tezos:parisnet:tz2JobFgDoJ5HZ1jAoMgZCyNdbBEdAstkytV', + ], + methods: ['tezos_signExpression'], + events: [], + }, + }, + acknowledged: true, + controller: '9acfbaf43ca1e9a6e1e27d3841c7b71a68176b401f1f29670870e3ca35094d62', + self: { + publicKey: '72dfcd018c5a636c311a0214c19f24e1e52a0f38082e31e3971af9b0296f4767', + metadata: { + description: '', + url: 'http://localhost:3000', + icons: [], + name: '', + }, + }, + peer: { + publicKey: '9acfbaf43ca1e9a6e1e27d3841c7b71a68176b401f1f29670870e3ca35094d62', + metadata: { + name: 'React Wallet', + description: 'React Wallet for WalletConnect', + url: 'https://walletconnect.com/', + icons: ['https://avatars.githubusercontent.com/u/37784886'], + }, + }, + requiredNamespaces: { + tezos: { + methods: ['tezos_signExpression'], + chains: ['tezos:ghostnet', 'tezos:parisnet'], + events: [], + }, + }, +}; + +export const existingPairings = [ + { + topic: 'db507c396bed3286e281266aa4cb7804f52b4b0193fae9a4b0c8c10b21c29c6a', + expiry: 1673202920, + relay: { + protocol: 'irn', + }, + active: true, + peerMetadata: { + name: 'Kukai Wallet', + description: + 'Manage your digital assets and seamlessly connect with experiences and apps on Tezos.', + url: 'https://wallet.kukai.app', + icons: [], + }, + }, +]; + +export const fakeCode = [ + { + prim: 'parameter', + args: [ + { + prim: 'nat', + }, + ], + }, + { + prim: 'storage', + args: [ + { + prim: 'nat', + }, + ], + }, + { + prim: 'code', + args: [ + [ + { + prim: 'AMOUNT', + }, + ], + ], + }, +]; diff --git a/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts new file mode 100644 index 0000000000..67f69957d8 --- /dev/null +++ b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts @@ -0,0 +1,1166 @@ +import { OpKind } from '@taquito/taquito'; +import { + NetworkType, + PermissionScopeEvents, + PermissionScopeMethods, + SigningType, + TransferParams, + WalletConnect2, +} from '../src/taquito-wallet-connect-2'; +import { existingPairings, fakeCode, sessionExample, sessionMultipleChains } from './data'; + +describe('Wallet connect 2 tests', () => { + let sessionDeletedEvent: (eventParams: { topic: string }) => void; + let sessionExpiredEvent: (eventParams: { topic: string }) => void; + let sessionUpdatedEvent: (eventParams: { topic: string; params: any }) => void; + let walletConnect: WalletConnect2; + let mockSignClient: { + on: any; + connect: jest.Mock; + pairing: { + getAll: jest.Mock; + }; + session: { + keys: string[]; + get: jest.Mock; + }; + disconnect: jest.Mock; + peer: { + metadata: any; + }; + request: jest.Mock; + }; + + beforeEach(() => { + mockSignClient = { + on: (eventName: string, eventFct: any) => { + if (eventName === 'session_delete') { + sessionDeletedEvent = eventFct; + } else if (eventName == 'session_expire') { + sessionExpiredEvent = eventFct; + } else if (eventName == 'session_update') { + sessionUpdatedEvent = eventFct; + } + }, + connect: jest.fn(), + pairing: { + getAll: jest.fn(), + }, + session: { + keys: [sessionExample.topic, sessionMultipleChains.topic], + get: jest.fn(), + }, + disconnect: jest.fn(), + peer: { + metadata: sessionExample.peer.metadata, + }, + request: jest.fn(), + }; + mockSignClient.connect.mockReturnValue({ approval: async () => sessionExample }); + walletConnect = new WalletConnect2(mockSignClient as any); + }); + + it('verify that WalletConnect2 is instantiable', async () => { + expect(new WalletConnect2(mockSignClient as any)).toBeInstanceOf(WalletConnect2); + }); + + it('should establish a connection successfully', async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(mockSignClient.connect).toHaveBeenCalledWith({ + requiredNamespaces: { + tezos: { + chains: ['tezos:ghostnet'], + methods: ['tezos_sendOperations'], + events: [], + }, + }, + }); + }); + + it('should throw an error if connection fails', async () => { + mockSignClient.connect.mockRejectedValue(new Error()); + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow('Unable to connect'); + }); + + it('should throw an error if tezos is not part of the requiredNamespace', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + requiredNamespaces: { + unknown: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow('Tezos not found in requiredNamespaces'); + }); + + describe('test pairing', () => { + beforeEach(async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + }); + + it('should access all existing active pairings with getAvailablePairing', async () => { + mockSignClient.pairing.getAll.mockReturnValue(existingPairings); + expect(walletConnect.getAvailablePairing()).toEqual(existingPairings); + }); + + it('should access peer metadata with getPeerMetadata', async () => { + expect(walletConnect.getPeerMetadata()).toEqual(sessionExample.peer.metadata); + }); + }); + + describe('test session', () => { + beforeEach(async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + }); + + it('should access all existing session keys with getAllExistingSessionKeys', async () => { + const sessionKeys = walletConnect.getAllExistingSessionKeys(); + expect(sessionKeys).toEqual([sessionExample.topic, sessionMultipleChains.topic]); + }); + + it('should use an existing session with configureWithExistingSessionKey', async () => { + expect(walletConnect.getSession().topic).toEqual(sessionExample.topic); + + mockSignClient.session.get.mockReturnValue(sessionMultipleChains); + walletConnect.configureWithExistingSessionKey(sessionMultipleChains.topic); + + expect(mockSignClient.session.get).toHaveBeenCalledWith(sessionMultipleChains.topic); + expect(walletConnect.getSession().topic).toEqual(sessionMultipleChains.topic); + }); + + it('should throw an error if the session key does not exist', async () => { + expect(() => walletConnect.configureWithExistingSessionKey('test')).toThrow( + 'Invalid session key "test"' + ); + }); + + it('should delete session when calling disconnect', async () => { + expect(walletConnect.isActiveSession()).toBeTruthy(); + await walletConnect.disconnect(); + expect(mockSignClient.disconnect).toHaveBeenCalledTimes(1); + expect(walletConnect.isActiveSession()).toBeFalsy(); + }); + }); + + describe('test active network', () => { + beforeEach(async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + }); + + it('should access permitted networks', async () => { + expect(walletConnect.getNetworks()).toEqual([NetworkType.GHOSTNET, NetworkType.PARISNET]); + }); + + it('should set the active network successfully', async () => { + walletConnect.setActiveNetwork(NetworkType.PARISNET); + expect(walletConnect.getActiveNetwork()).toEqual(NetworkType.PARISNET); + }); + + it('should fail to set the active network when it is not part of the session namespace', async () => { + expect(() => walletConnect.setActiveNetwork(NetworkType.OXFORDNET)).toThrow( + 'Invalid network "oxfordnet"' + ); + }); + + it('should throw an error when no active network is set and session namespace has multiple networks', async () => { + expect(() => walletConnect.getActiveNetwork()).toThrow( + 'Please specify the active network using the "setActiveNetwork" method.' + ); + }); + + it('should delete active network when calling disconnect', async () => { + walletConnect.setActiveNetwork(NetworkType.GHOSTNET); + expect(walletConnect.getActiveNetwork()).toEqual(NetworkType.GHOSTNET); + + await walletConnect.disconnect(); + expect(mockSignClient.disconnect).toHaveBeenCalledTimes(1); + + expect(() => walletConnect.getActiveNetwork()).toThrow('Not connected, no active session'); + }); + }); + + describe('test active account', () => { + it('should return active account when session namespace only have one', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionExample }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(await walletConnect.getPKH()).toEqual('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + }); + + it('should throw an error when no active account is set and session namespace has multiple accounts', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + await expect(walletConnect.getPKH()).rejects.toThrow( + 'Please specify the active account using the "setActiveAccount" method.' + ); + }); + + it('should set the active account successfully', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + walletConnect.setActiveAccount('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + expect(await walletConnect.getPKH()).toEqual('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + }); + + it('should fail to set the active account when it is not part of the session namespace', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + expect(() => walletConnect.setActiveAccount('test')).toThrow('Invalid pkh "test"'); + }); + + it('should delete active account when calling disconnect', async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(await walletConnect.getPKH()).toEqual('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + await walletConnect.disconnect(); + expect(mockSignClient.disconnect).toHaveBeenCalledTimes(1); + await expect(walletConnect.getPKH()).rejects.toThrow('Not connected, no active session'); + }); + }); + + describe('test validation of incoming proposal namespaces', () => { + it('should fail to establish a connection if the proposal namespace does not have any accounts', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#21-session-namespaces-must-not-have-accounts-empty + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: [], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow('5001: Accounts must not be empty.'); + }); + + it('should fail to establish a connection if the proposal namespace addresses are not CAIP-10 compliant', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#22-session-namespaces-addresses-must-be-caip-10-compliant + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow( + '5001: Accounts must be CAIP-10 compliant. "tezos:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh" is invalid.' + ); + }); + + it('should fail to establish a connection if the received namespace is missing a requested method', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#23-session-namespaces-must-approve-all-methods + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow( + '5002: All methods must be approved. "tezos_signExpression" is missing in the session namespace.' + ); + }); + + it('should fail to establish a connection if the received namespace is missing multiple requested methods', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow( + '5002: All methods must be approved. "tezos_sendOperations,tezos_signExpression" is missing in the session namespace.' + ); + }); + + it('should fail to establish a connection if the received namespace is missing account in a requested chain', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#24-session-namespaces-must-contain-at-least-one-account-in-requested-chains + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }) + ).rejects.toThrow( + '5001: All chains must have at least one account. "parisnet" is missing in the session namespace.' + ); + }); + + it('should fail to establish a connection if the received namespace is missing account in requested chains', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#24-session-namespaces-must-contain-at-least-one-account-in-requested-chains + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET, NetworkType.OXFORDNET], + }, + }) + ).rejects.toThrow( + '5001: All chains must have at least one account. "parisnet,oxfordnet" is missing in the session namespace.' + ); + }); + + it('should establish a connection successfully if the received namespace contains multiple accounts for one chain', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#25-session-namespaces-may-contain-multiple-accounts-for-one-chain + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: [ + 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'tezos:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', + ], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(mockSignClient.connect).toHaveBeenCalledWith({ + requiredNamespaces: { + tezos: { + chains: ['tezos:ghostnet'], + methods: ['tezos_sendOperations'], + events: [], + }, + }, + }); + }); + + it('should establish a connection successfully even if the received namespace extend methods and events', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#26-session-namespaces-may-extend-methods-and-events-of-proposal-namespaces + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + events: [PermissionScopeEvents.ACCOUNTS_CHANGED], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(mockSignClient.connect).toHaveBeenCalledWith({ + requiredNamespaces: { + tezos: { + chains: ['tezos:ghostnet'], + methods: ['tezos_sendOperations'], + events: [], + }, + }, + }); + }); + + it('should fail to establish a connection if an account in the received namespace do not contain the namespace prefix', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#27-all-accounts-in-the-namespace-must-contain-the-namespace-prefix + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: [ + 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'unknown:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', + ], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow( + '5103: Accounts must be defined in matching namespace. "unknown:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G" is invalid.' + ); + }); + + it('should establish a connection successfully even if the received namespace contain an account from a chain not defined in Proposal Namespaces', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#28-session-namespaces-may-contain-accounts-from-chains-not-defined-in-proposal-namespaces + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: [ + 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'tezos:limanet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + ], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [PermissionScopeEvents.ACCOUNTS_CHANGED], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(mockSignClient.connect).toHaveBeenCalledWith({ + requiredNamespaces: { + tezos: { + chains: ['tezos:ghostnet'], + methods: ['tezos_sendOperations'], + events: [], + }, + }, + }); + }); + + it('should fail to establish a connection if received namespace does not contain tezos', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#29-session-namespaces-must-have-at-least-the-same-namespaces-as-the-proposal-namespaces + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + unknown: { + accounts: ['unknown:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }) + ).rejects.toThrow( + '5000: All namespaces must be approved. "tezos" is missing in the session namespace.' + ); + }); + + it('should fail to establish a connection if received namespace is mising requested events', async () => { + // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#211-session-namespaces-must-approve-all-events + + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + }; + }, + }); + + await expect( + walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + events: [PermissionScopeEvents.ACCOUNTS_CHANGED], + }, + }) + ).rejects.toThrow( + '5003: All events must be approved. "accountsChanged" is missing in the session namespace.' + ); + }); + }); + + describe('test sendOperations', () => { + it('should send transaction operation successfully', async () => { + const mockedOpHash = 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf'; + mockSignClient.request.mockResolvedValue(mockedOpHash); + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params: TransferParams[] = [ + { + kind: OpKind.TRANSACTION, + amount: '100000', + destination: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }, + ]; + + const opHash = await walletConnect.sendOperations(params); + + expect(mockSignClient.request).toHaveBeenCalledWith({ + topic: sessionExample.topic, + chainId: `tezos:ghostnet`, + request: { + method: PermissionScopeMethods.OPERATION_REQUEST, + params: { + account: 'tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + operations: params, + }, + }, + }); + + expect(opHash).toEqual(mockedOpHash); + }); + + it('should send transaction operation with defined limits successfully', async () => { + const mockedOpHash = 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf'; + mockSignClient.request.mockResolvedValue(mockedOpHash); + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params: TransferParams[] = [ + { + kind: OpKind.TRANSACTION, + fee: '400', + gas_limit: '4000', + storage_limit: '400', + amount: '0', + destination: 'KT1QKmcNBcfzVTXG2kBcE6XqXtEuYYUzMcT5', + parameters: { + entrypoint: 'simple_param', + value: { + int: '5', + }, + }, + }, + ]; + + const opHash = await walletConnect.sendOperations(params); + + expect(mockSignClient.request).toHaveBeenCalledWith({ + topic: sessionExample.topic, + chainId: `tezos:ghostnet`, + request: { + method: PermissionScopeMethods.OPERATION_REQUEST, + params: { + account: 'tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + operations: params, + }, + }, + }); + + expect(opHash).toEqual(mockedOpHash); + }); + + it('should fail to send transaction operation if permission is not granted', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.SIGN], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.SIGN], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params: TransferParams[] = [ + { + kind: OpKind.TRANSACTION, + amount: '100000', + destination: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }, + ]; + + await expect(walletConnect.sendOperations(params)).rejects.toThrow( + 'Required permission scope were not granted for "tezos_sendOperations"' + ); + }); + + it('should fail to send operation if mismatch between account-network', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: [ + 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', + 'tezos:parisnet:tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', + ], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + chains: ['tezos:ghostnet', 'tezos:parisnet'], + events: [], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + walletConnect.setActiveAccount('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + walletConnect.setActiveNetwork(NetworkType.PARISNET); + + const params: TransferParams[] = [ + { + kind: OpKind.TRANSACTION, + amount: '100000', + destination: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }, + ]; + + await expect(walletConnect.sendOperations(params)).rejects.toThrow( + 'No permission. The combinaison "parisnet" and "tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh" is not part of the active session.' + ); + }); + }); + + describe('test sign payload', () => { + it('should sign payload successfully', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.SIGN], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.SIGN], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + const mockedSignature = + 'edsigtpDN7L5LfzvYWM22fvYA4dPVr9wXaYje7z4nmBrT6ZxkGnHS6u3UuvD9TQv3BmNRSUgnMH1dKsAaLWhfuXXj63myo2m3De'; + mockSignClient.request.mockResolvedValue(mockedSignature); + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params = { + signingType: SigningType.MICHELINE, + payload: + '05010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + sourceAddress: 'tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p', + }; + + const sig = await walletConnect.signPayload(params); + + expect(mockSignClient.request).toHaveBeenCalledWith({ + topic: sessionExample.topic, + chainId: `tezos:ghostnet`, + request: { + method: PermissionScopeMethods.SIGN, + params: { + account: 'tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p', + expression: params.payload, + signingType: params.signingType, + }, + }, + }); + + expect(sig).toEqual(mockedSignature); + }); + + it('should sign payload successfully when params.sourceAddress is undefined', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p'], + methods: [PermissionScopeMethods.SIGN], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.SIGN], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + const mockedSignature = + 'edsigtpDN7L5LfzvYWM22fvYA4dPVr9wXaYje7z4nmBrT6ZxkGnHS6u3UuvD9TQv3BmNRSUgnMH1dKsAaLWhfuXXj63myo2m3De'; + mockSignClient.request.mockResolvedValue(mockedSignature); + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.SIGN], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params = { + signingType: SigningType.MICHELINE, + payload: + '05010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + }; + + const sig = await walletConnect.signPayload(params); + + expect(mockSignClient.request).toHaveBeenCalledWith({ + topic: sessionExample.topic, + chainId: `tezos:ghostnet`, + request: { + method: PermissionScopeMethods.SIGN, + params: { + account: 'tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p', + expression: params.payload, + signingType: params.signingType, + }, + }, + }); + + expect(sig).toEqual(mockedSignature); + }); + + it('should fail to sign payload if permission is not granted', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + + const params = { + signingType: SigningType.MICHELINE, + payload: + '05010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + }; + + await expect(walletConnect.signPayload(params)).rejects.toThrow( + 'Required permission scope were not granted for "tezos_signExpression"' + ); + }); + }); + + describe('test map params to wallet params', () => { + it('should transform the transfer parameters appropriately', async () => { + const params = async () => { + return { + to: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + amount: 0.1, + }; + }; + + const mappedParams = { + kind: 'transaction', + amount: '100000', + destination: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }; + + expect(await walletConnect.mapTransferParamsToWalletParams(params)).toEqual(mappedParams); + }); + + it('should transform the transfer parameters appropriately including limits', async () => { + const params = async () => { + return { + to: 'KT1QKmcNBcfzVTXG2kBcE6XqXtEuYYUzMcT5', + amount: 0, + fee: 400, + mutez: false, + gasLimit: 4000, + storageLimit: 0, + parameter: { + entrypoint: 'simple_param', + value: { + int: '5', + }, + }, + }; + }; + + const mappedParams = { + kind: 'transaction', + fee: '400', + gas_limit: '4000', + storage_limit: '0', + amount: '0', + destination: 'KT1QKmcNBcfzVTXG2kBcE6XqXtEuYYUzMcT5', + parameters: { + entrypoint: 'simple_param', + value: { + int: '5', + }, + }, + }; + + expect(await walletConnect.mapTransferParamsToWalletParams(params)).toEqual(mappedParams); + }); + + it('should transform the origination parameters appropriately', async () => { + const params = async () => { + return { + code: fakeCode, + init: [], + }; + }; + + const mappedParams = { + kind: 'origination', + balance: '0', + script: { + code: fakeCode, + storage: [], + }, + }; + + expect(await walletConnect.mapOriginateParamsToWalletParams(params)).toEqual(mappedParams); + }); + + it('should transform the transfer parameters appropriately including limits', async () => { + const params = async () => { + return { + code: fakeCode, + init: [], + fee: 400, + mutez: false, + gasLimit: 4000, + storageLimit: 0, + }; + }; + + const mappedParams = { + kind: 'origination', + balance: '0', + script: { + code: fakeCode, + storage: [], + }, + fee: '400', + gas_limit: '4000', + storage_limit: '0', + }; + + expect(await walletConnect.mapOriginateParamsToWalletParams(params)).toEqual(mappedParams); + }); + + it('should transform the delegation parameters appropriately', async () => { + const params = async () => { + return { + delegate: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }; + }; + + const mappedParams = { + kind: 'delegation', + delegate: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + }; + + expect(await walletConnect.mapDelegateParamsToWalletParams(params)).toEqual(mappedParams); + }); + + it('should transform the delegation parameters appropriately including limits', async () => { + const params = async () => { + return { + delegate: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + fee: 400, + gasLimit: 4000, + storageLimit: 0, + }; + }; + + const mappedParams = { + kind: 'delegation', + delegate: 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb', + fee: '400', + gas_limit: '4000', + storage_limit: '0', + }; + + expect(await walletConnect.mapDelegateParamsToWalletParams(params)).toEqual(mappedParams); + }); + }); + + describe('test events', () => { + beforeEach(async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.OPERATION_REQUEST], + networks: [NetworkType.GHOSTNET], + }, + }); + }); + + it('should delete session when session_delete event is received', async () => { + expect(walletConnect.isActiveSession()).toBeTruthy(); + sessionDeletedEvent({ topic: sessionExample.topic }); + expect(walletConnect.isActiveSession()).toBeFalsy(); + }); + + it('should delete session when session_expire event is received', async () => { + expect(walletConnect.isActiveSession()).toBeTruthy(); + sessionExpiredEvent({ topic: sessionExample.topic }); + expect(walletConnect.isActiveSession()).toBeFalsy(); + }); + + it('should update session when session_update event is received', async () => { + expect(walletConnect.getSession().namespaces).toEqual(sessionExample.namespaces); + sessionUpdatedEvent({ topic: sessionExample.topic, params: sessionMultipleChains }); + expect(walletConnect.getSession().namespaces).toEqual(sessionMultipleChains.namespaces); + }); + }); +}); diff --git a/packages/taquito-wallet-connect-2/tsconfig.json b/packages/taquito-wallet-connect-2/tsconfig.json new file mode 100644 index 0000000000..e57afa6671 --- /dev/null +++ b/packages/taquito-wallet-connect-2/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declarationDir": "dist/types", + "outDir": "dist/lib", + "jsx": "react", + }, + "include": ["src"] +} \ No newline at end of file diff --git a/packages/taquito-wallet-connect-2/tsconfig.prod.json b/packages/taquito-wallet-connect-2/tsconfig.prod.json new file mode 100644 index 0000000000..829f48441b --- /dev/null +++ b/packages/taquito-wallet-connect-2/tsconfig.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.prod.json", + "compilerOptions": { + "declarationDir": "./dist/types", + "outDir": "./dist/lib", + "jsx": "react" + }, + "include": ["./src/**/*"] +} \ No newline at end of file diff --git a/packages/taquito/src/operations/index.ts b/packages/taquito/src/operations/index.ts index 51f6101893..d6fe88e9ab 100644 --- a/packages/taquito/src/operations/index.ts +++ b/packages/taquito/src/operations/index.ts @@ -1,48 +1,4 @@ -export { - OpKind, - withKind, - ParamsWithKind, - RPCOperation, - RPCOpWithFee, - RPCOpWithSource, - SourceKinds, - GasConsumingOperation, - StorageConsumingOperation, - FeeConsumingOperation, - ForgedBytes, - PrepareOperationParams, - OriginateParamsBase, - OriginateParams, - RPCOriginationOperation, - DelegateParams, - RegisterDelegateParams, - RPCDelegateOperation, - TransferParams, - RPCTransferOperation, - RegisterGlobalConstantParams, - RPCRegisterGlobalConstantOperation, - IncreasePaidStorageParams, - RPCIncreasePaidStorageOperation, - TransferTicketParams, - RPCTransferTicketOperation, - UpdateConsensusKeyParams, - RPCUpdateConsensusKeyOperation, - SmartRollupAddMessagesParams, - RPCSmartRollupAddMessagesOperation, - SmartRollupOriginateParams, - RPCSmartRollupOriginateOperation, - ActivationParams, - RPCActivateOperation, - BallotParams, - RPCBallotOperation, - DrainDelegateParams, - RPCDrainDelegateOperation, - FailingNoopParams, - RPCFailingNoopOperation, - ProposalsParams, - RPCProposalsOperation, - RPCRevealOperation, -} from './types'; +export * from './types'; export { TezosOperationError, TezosOperationErrorWithMessage, diff --git a/tsconfig.base.json b/tsconfig.base.json index 9e41dc1888..0edfaf7fac 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -71,6 +71,9 @@ ], "@taquito/utils": [ "taquito-utils/src/taquito-utils.ts" + ], + "@taquito/wallet-connect-2": [ + "taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts" ] } } diff --git a/typedoc.js b/typedoc.js index b203de8373..9527a148ec 100644 --- a/typedoc.js +++ b/typedoc.js @@ -18,6 +18,7 @@ module.exports = { './packages/taquito-contracts-library/src/taquito-contracts-library.ts', './packages/taquito-sapling/src/taquito-sapling.ts', './packages/taquito-michel-codec/src/taquito-michel-codec.ts', + './packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts', ], exclude: [ '**/*.spec.ts', diff --git a/website/package-lock.json b/website/package-lock.json index 667391afce..f0b85814cd 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -121,7 +121,7 @@ "webpack-subresource-integrity": "^5.1.0" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-beacon-wallet": { @@ -166,7 +166,7 @@ "webpack-cli": "^5.1.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-core": { @@ -182,7 +182,7 @@ "rollup-plugin-typescript2": "^0.36.0" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-http-utils": { @@ -223,7 +223,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-ledger-signer": { @@ -267,13 +267,13 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-michel-codec": { "name": "@taquito/michel-codec", "version": "20.0.1", - "license": "MIT", + "license": "Apache-2.0", "dependencies": { "@taquito/core": "^20.0.1" }, @@ -300,7 +300,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-michelson-encoder": { @@ -342,7 +342,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-remote-signer": { @@ -387,7 +387,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-rpc": { @@ -428,7 +428,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-signer": { @@ -482,7 +482,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-tzip12": { @@ -524,7 +524,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-tzip16": { @@ -571,7 +571,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "../packages/taquito-utils": { @@ -619,7 +619,7 @@ "typescript": "~5.5.4" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@algolia/autocomplete-core": { @@ -8427,9 +8427,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -8440,7 +8440,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -11915,37 +11915,37 @@ "license": "Apache-2.0" }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -11977,6 +11977,15 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11984,9 +11993,9 @@ "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, "node_modules/express/node_modules/range-parser": { @@ -12262,13 +12271,13 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -12288,6 +12297,15 @@ "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -14588,12 +14606,6 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "license": "MIT" }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15872,10 +15884,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "license": "MIT" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -18068,13 +18083,10 @@ } }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -19195,12 +19207,12 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -19658,7 +19670,7 @@ "history": "^4.9.0", "hoist-non-react-statics": "^3.1.0", "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", + "path-to-regexp": "^3.3.0", "prop-types": "^15.6.2", "react-is": "^16.6.0", "tiny-invariant": "^1.0.2", @@ -21071,9 +21083,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -21145,7 +21157,7 @@ "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", + "path-to-regexp": "^3.3.0", "range-parser": "1.2.0" } }, @@ -21182,12 +21194,6 @@ "node": "*" } }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "license": "MIT" - }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -21267,20 +21273,29 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -24008,7 +24023,7 @@ "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", "default-gateway": "^6.0.3", - "express": "^4.17.3", + "express": "^4.20.0", "graceful-fs": "^4.2.6", "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", From bc60f8b1e602bf6c8cd6ad908ff3d9b15355e0ec Mon Sep 17 00:00:00 2001 From: huianyang Date: Thu, 19 Sep 2024 12:48:19 -0700 Subject: [PATCH 02/16] docs: adding website doc with live code example (modal isn't working yet) --- docs/wallet_connect_2.md | 120 +++++ package-lock.json | 440 +++++++++++++++++- .../taquito-wallet-connect-2/package.json | 1 + .../src/taquito-wallet-connect-2.ts | 32 +- website/package-lock.json | 59 +++ website/package.json | 2 + website/sidebars.js | 1 + website/src/theme/CodeBlock/index.js | 7 + website/src/theme/Playground/index.js | 4 + 9 files changed, 650 insertions(+), 16 deletions(-) create mode 100644 docs/wallet_connect_2.md diff --git a/docs/wallet_connect_2.md b/docs/wallet_connect_2.md new file mode 100644 index 0000000000..ad5dfd8ceb --- /dev/null +++ b/docs/wallet_connect_2.md @@ -0,0 +1,120 @@ +--- +title: Wallet Connect 2 +author: Roxane Letourneau +--- + +The `@taquito/wallet-connect-2` package provides a `WalletConnect2` class which implements the `WalletProvider` interface. The package is intended to be used by dapp developers. Similarly to `BeaconWallet`, an instance of `WalletConnect2` can be injected into the `TezosToolkit` to work with the wallet API. + +## Instantiate `WalletConnect2` and connect to a wallet + +The first step is to instantiate `WalletConnect2` by passing your dapp details as a parameter of the `init` method as follows: + +```ts +import { WalletConnect2 } from "@taquito/wallet-connect-2"; + +const walletConnect = await WalletConnect2.init({ + projectId: "YOUR_PROJECT_ID", // Your Project ID gives you access to WalletConnect Cloud + metadata: { + name: "YOUR_DAPP_NAME", + description: "YOUR_DAPP_DESCRIPTION", + icons: ["ICON_URL"], + url: "DAPP_URL", + }, +}); +``` +`YOUR_PROJECT_ID` can be obtained from [WalletConnect Cloud](https://cloud.walletconnect.com/sign-in) + +The second step is to establish a connection to a wallet using the `requestPermissions` method: + +```ts +import { NetworkType, PermissionScopeMethods } from "@taquito/wallet-connect-2"; + +await walletConnect.requestPermissions({ + permissionScope: { + networks: [NetworkType.GHOSTNET], + methods: [ + PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN + ], + }, + // registryUrl: "https://www.tezos.help/wcdata/" +}); +``` + +The parameter of the `requestPermissions` method has a `permissionScope` property allowing to specify the networks, methods, and events that will be granted permission. + +It has an optional `pairingTopic` property, which allows connecting to an existing active pairing. If `pairingTopic` is undefined, a QR/deep-links Modal will open in the dapp, allowing the user to connect to a wallet. If `pairingTopic` is defined, no modal will be shown in the dapp, and a prompt will appear in the corresponding wallet to accept or decline the session proposal. The list of active pairings can be accessed using the `getAvailablePairing` method. A good practice is to show the dapp user available pairings if they exist and to allow him to connect through one of them (skip the QR/deep-links Modal) or to connect using a new pairing (using the QR/deep-links) + +The parameter of the `requestPermissions` method also has an optional `registryUrl` parameter allowing to customize the list of wallet deep links to show in the Modal. + +If no connection can be established with a wallet, the error `ConnectionFailed` will be thrown. + +Suppose there is a need to restore a session in the dapp rather than using the `requestPermissions` method, which would establish a new session. In that case, it is possible to configure the `WalletConnect2` class with an existing session using the `configureWithExistingSessionKey` method. The session will be immediately restored without a prompt in the wallet to accept/decline it. The list of existing sessions can be retrieved with the `getAllExistingSessionKeys` method. An `InvalidSessionKey` error will be thrown if the provided session key doesn't exist. + +## Send Tezos operation with `WalletConnect2` and `TezosToolkit` + +Once an instance of `WalletConnect2` is created and a session is established, it can be injected into the `TezosToolkit` using its `setWalletProvider` method. Methods of the wallet API can be invoked to send operations to the blockchain. Those operations will be signed and injected by the wallet. The permission `PermissionScopeMethods.OPERATION_REQUEST` must have been granted, or the error `MissingRequiredScope` will be thrown. + +Wallet connect 2 allows granting permission for multiple accounts in a session. The `setActiveAccount` must be called to set the active account that will be used to prepare the operation. It should be called every time the active account is updated in the dapp. It is possible to retrieve a list of all connected accounts using the `getAccounts` method. The `getPKH` method will return the public key hash of the active account. Note that if only one account is present in the session, it will be set as the active one by default. + +In the same order of ideas, `setActiveNetwork` must be called to specify the active network. The `getNetworks` method retrieves the list of available networks in the session. + +Here is a complete example of using wallet connect to perform a transfer operation: + +```js live noInline noConfig +Tezos.setRpcProvider('https://ghostnet.ecadinfra.com/'); + +WalletConnect2.init({ + logger: 'debug', + projectId: MY_PROJECT_ID, + metadata: { + name: 'Taquito website', + description: 'Taquito website with WalletConnect2', + url: 'https://tezostaquito.io/', + icons: [], + }, +}) + .then((walletConnect) => { + walletConnect + .requestPermissions({ + permissionScope: { + networks: [NetworkType.GHOSTNET], + methods: [PermissionScopeMethods.OPERATION_REQUEST], + }, + // registryUrl: 'https://www.tezos.help/wcdata/', + }) + .then(() => { + Tezos.setWalletProvider(walletConnect); + Tezos.wallet + .transfer({ to: 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY', amount: 1 }) + .send() + .then((op) => { + console.log(`Waiting for ${op.opHash} to be confirmed...`); + return op.confirmation().then(() => op.opHash); + }) + .then((hash) => console.log(`https://ghostnet.tzkt.io/${hash}`)); + }); + }) + .catch((err) => console.log(err)); +``` + +## Sign payload with `WalletConnect2` + +The `signPayload` method of `WalletConnect2` can be called to sign a payload. The response will be a string representing the signature. The permission `PermissionScopeMethods.SIGN` must have been granted, or the error `MissingRequiredScope` will be thrown. + +## Events handling + +Wallet connect 2 allows listening to specific events. Taquito has listeners on the events `session_delete`, `session_expire`, and `session_update` and will update his internal session member accordingly if one of these events is emitted. The dapp should also handle those events as follow: + +```ts +walletConnect.signClient.on("session_delete", ({ topic }) => { + // The session was deleted from the wallet + // the dapp should listen for the event and reset the dapp state, + // clean up from user session (for example, go back to the connect wallet page) +}); + +walletConnect.signClient.on("session_update", ({ topic }) => { + // The session was updated in the wallet + // Does the accounts/network have changed, which requires calling the `setActiveAccount/setActiveNetwork` methods? + // Update the app's state (selected account, available accounts, balance, ...) +}); +``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e862f6f09e..3540ad49f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4808,6 +4808,106 @@ "node": ">= 6" } }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz", + "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.0.0" + } + }, + "node_modules/@motionone/animation": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "license": "MIT", + "dependencies": { + "@motionone/easing": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.18.0.tgz", + "integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==", + "license": "MIT", + "dependencies": { + "@motionone/animation": "^10.18.0", + "@motionone/generators": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "license": "MIT", + "dependencies": { + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/svelte": { + "version": "10.16.4", + "resolved": "https://registry.npmjs.org/@motionone/svelte/-/svelte-10.16.4.tgz", + "integrity": "sha512-zRVqk20lD1xqe+yEDZhMYgftsuHc25+9JSo+r0a0OWUJFocjSV9D/+UGhX4xgJsuwB9acPzXLr20w40VnY2PQA==", + "license": "MIT", + "dependencies": { + "@motionone/dom": "^10.16.4", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.17.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==", + "license": "MIT" + }, + "node_modules/@motionone/utils": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.17.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/vue": { + "version": "10.16.4", + "resolved": "https://registry.npmjs.org/@motionone/vue/-/vue-10.16.4.tgz", + "integrity": "sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==", + "deprecated": "Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion", + "license": "MIT", + "dependencies": { + "@motionone/dom": "^10.16.4", + "tslib": "^2.3.1" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", @@ -7592,6 +7692,12 @@ "form-data": "^4.0.0" } }, + "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==", + "license": "MIT" + }, "node_modules/@types/typedarray-to-buffer": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/typedarray-to-buffer/-/typedarray-to-buffer-4.0.4.tgz", @@ -8093,6 +8199,215 @@ "pino": "7.11.0" } }, + "node_modules/@walletconnect/modal": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@walletconnect/modal/-/modal-2.6.2.tgz", + "integrity": "sha512-eFopgKi8AjKf/0U4SemvcYw9zlLpx9njVN8sf6DAkowC2Md0gPU/UNEbH1Wwj407pEKnEds98pKWib1NN1ACoA==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/modal-core": "2.6.2", + "@walletconnect/modal-ui": "2.6.2" + } + }, + "node_modules/@walletconnect/modal-core": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@walletconnect/modal-core/-/modal-core-2.6.2.tgz", + "integrity": "sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA==", + "license": "Apache-2.0", + "dependencies": { + "valtio": "1.11.2" + } + }, + "node_modules/@walletconnect/modal-ui": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@walletconnect/modal-ui/-/modal-ui-2.6.2.tgz", + "integrity": "sha512-rbdstM1HPGvr7jprQkyPggX7rP4XiCG85ZA+zWBEX0dVQg8PpAgRUqpeub4xQKDgY7pY/xLRXSiCVdWGqvG2HA==", + "license": "Apache-2.0", + "dependencies": { + "@walletconnect/modal-core": "2.6.2", + "lit": "2.8.0", + "motion": "10.16.2", + "qrcode": "1.5.3" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/@walletconnect/modal-ui/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/qrcode": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz", + "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "encode-utf8": "^1.0.3", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/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==", + "license": "ISC" + }, + "node_modules/@walletconnect/modal-ui/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@walletconnect/modal-ui/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@walletconnect/relay-api": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@walletconnect/relay-api/-/relay-api-1.0.11.tgz", @@ -12448,6 +12763,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, + "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==", + "license": "MIT" + }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -15377,6 +15698,12 @@ "node": ">= 0.4" } }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "license": "MIT" + }, "node_modules/highlight.js": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", @@ -18381,7 +18708,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -19469,6 +19795,37 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/lit": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz", + "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^1.6.0", + "lit-element": "^3.3.0", + "lit-html": "^2.8.0" + } + }, + "node_modules/lit-element": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", + "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.1.0", + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.8.0" + } + }, + "node_modules/lit-html": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", + "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, "node_modules/load-json-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", @@ -19955,6 +20312,19 @@ "node": ">=0.10.0" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -20528,6 +20898,20 @@ "node": "*" } }, + "node_modules/motion": { + "version": "10.16.2", + "resolved": "https://registry.npmjs.org/motion/-/motion-10.16.2.tgz", + "integrity": "sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ==", + "license": "MIT", + "dependencies": { + "@motionone/animation": "^10.15.1", + "@motionone/dom": "^10.16.2", + "@motionone/svelte": "^10.16.2", + "@motionone/types": "^10.15.1", + "@motionone/utils": "^10.15.1", + "@motionone/vue": "^10.16.2" + } + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -22498,6 +22882,12 @@ "dev": true, "license": "MIT" }, + "node_modules/proxy-compare": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.1.tgz", + "integrity": "sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==", + "license": "MIT" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -22862,6 +23252,19 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -26698,6 +27101,15 @@ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "license": "MIT" }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -26761,6 +27173,31 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/valtio": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/valtio/-/valtio-1.11.2.tgz", + "integrity": "sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw==", + "license": "MIT", + "dependencies": { + "proxy-compare": "2.5.1", + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -28526,6 +28963,7 @@ "dependencies": { "@taquito/taquito": "^20.0.1", "@walletconnect/legacy-modal": "^2.0.0", + "@walletconnect/modal": "^2.6.2", "@walletconnect/sign-client": "^2.16.1", "@walletconnect/types": "^2.16.1", "@walletconnect/utils": "^2.16.1" diff --git a/packages/taquito-wallet-connect-2/package.json b/packages/taquito-wallet-connect-2/package.json index 3ce9de377a..c971bd1ccc 100644 --- a/packages/taquito-wallet-connect-2/package.json +++ b/packages/taquito-wallet-connect-2/package.json @@ -68,6 +68,7 @@ "dependencies": { "@taquito/taquito": "^20.0.1", "@walletconnect/legacy-modal": "^2.0.0", + "@walletconnect/modal": "^2.6.2", "@walletconnect/sign-client": "^2.16.1", "@walletconnect/types": "^2.16.1", "@walletconnect/utils": "^2.16.1" diff --git a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts index ae791ae870..26303db2d1 100644 --- a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts +++ b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts @@ -5,7 +5,9 @@ import Client from '@walletconnect/sign-client'; import { SignClientTypes, SessionTypes, PairingTypes } from '@walletconnect/types'; -import QRCodeModal from '@walletconnect/legacy-modal'; +// import QRCodeModal from '@walletconnect/legacy-modal'; +import { WalletConnectModal } from '@walletconnect/modal'; + import { createOriginationOperation, createSetDelegateOperation, @@ -60,10 +62,12 @@ export class WalletConnect2 implements WalletProvider { private session: SessionTypes.Struct | undefined; private activeAccount: string | undefined; private activeNetwork: string | undefined; + private WalletConnectModal: WalletConnectModal; - constructor(signClient: Client) { + constructor(signClient: Client, WalletConnectModal: WalletConnectModal) { this.signClient = signClient; - + this.WalletConnectModal = WalletConnectModal; + signClient.metadata; this.signClient.on('session_delete', ({ topic }) => { if (this.session?.topic === topic) { this.session = undefined; @@ -106,8 +110,12 @@ export class WalletConnect2 implements WalletProvider { * ``` */ static async init(initParams: SignClientTypes.Options) { + if (!initParams.projectId) { + throw new Error('projectId is required'); + } const client = await Client.init(initParams); - return new WalletConnect2(client); + const walletConnectModal = new WalletConnectModal({ projectId: initParams.projectId }); + return new WalletConnect2(client, walletConnectModal); } /** @@ -139,22 +147,16 @@ export class WalletConnect2 implements WalletProvider { }); if (uri) { - QRCodeModal.open( - uri, - () => { - // noop - }, - { registryUrl: connectParams.registryUrl } - ); + this.WalletConnectModal.openModal({ uri, chains: [TEZOS_PLACEHOLDER] }); + + this.session = await approval(); } - const session = await approval(); - this.session = session; } catch (error) { throw new ConnectionFailed(error); } finally { - QRCodeModal.close(); + // QRCodeModal.close(); } - this.validateReceivedNamespace(connectParams.permissionScope, this.session.namespaces); + this.validateReceivedNamespace(connectParams.permissionScope, this.session!.namespaces); this.setDefaultAccountAndNetwork(); } diff --git a/website/package-lock.json b/website/package-lock.json index f0b85814cd..337e982681 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -33,6 +33,7 @@ "@taquito/tzip12": "file:../packages/taquito-tzip12", "@taquito/tzip16": "file:../packages/taquito-tzip16", "@taquito/utils": "file:../packages/taquito-utils", + "@taquito/wallet-connect-2": "file:../packages/taquito-wallet-connect-2", "abort-controller": "^3.0.0", "algoliasearch": "^4.23.2", "axios": "^0.28.0", @@ -63,6 +64,7 @@ "devDependencies": { "@docusaurus/module-type-aliases": "2.4.3", "@tsconfig/docusaurus": "^2.0.2", + "lokijs": "^1.5.12", "typescript": "^5.2.2" } }, @@ -622,6 +624,52 @@ "node": ">=20" } }, + "../packages/taquito-wallet-connect-2": { + "name": "@taquito/wallet-connect-2", + "version": "20.0.1", + "license": "Apache-2.0", + "dependencies": { + "@taquito/taquito": "^20.0.1", + "@walletconnect/legacy-modal": "^2.0.0", + "@walletconnect/modal": "^2.6.2", + "@walletconnect/sign-client": "^2.16.1", + "@walletconnect/types": "^2.16.1", + "@walletconnect/utils": "^2.16.1" + }, + "devDependencies": { + "@types/bluebird": "^3.5.42", + "@types/chrome": "0.0.171", + "@types/jest": "^29.5.12", + "@types/node": "^22", + "@types/pino": "^7.0.5", + "@types/ws": "^8.5.12", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "colors": "^1.4.0", + "coveralls": "^3.1.1", + "cross-env": "^7.0.3", + "eslint": "^8.57.0", + "jest": "^29.7.0", + "jest-config": "^29.7.0", + "lint-staged": "^15.2.7", + "lodash.camelcase": "^4.3.0", + "prettier": "^3.3.3", + "prompt": "^1.3.0", + "replace-in-file": "^8.1.0", + "rimraf": "^6.0.1", + "rollup": "^4.19.1", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-typescript2": "^0.36.0", + "shelljs": "^0.8.5", + "ts-jest": "^29.2.3", + "ts-node": "^10.9.2", + "ts-toolbelt": "^9.6.0", + "typescript": "~5.5.4" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/@algolia/autocomplete-core": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", @@ -7024,6 +7072,10 @@ "resolved": "../packages/taquito-utils", "link": true }, + "node_modules/@taquito/wallet-connect-2": { + "resolved": "../packages/taquito-wallet-connect-2", + "link": true + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -15538,6 +15590,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lokijs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz", + "integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==", + "dev": true, + "license": "MIT" + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", diff --git a/website/package.json b/website/package.json index 9018983c01..a617626059 100644 --- a/website/package.json +++ b/website/package.json @@ -40,6 +40,7 @@ "@taquito/tzip12": "file:../packages/taquito-tzip12", "@taquito/tzip16": "file:../packages/taquito-tzip16", "@taquito/utils": "file:../packages/taquito-utils", + "@taquito/wallet-connect-2": "file:../packages/taquito-wallet-connect-2", "abort-controller": "^3.0.0", "algoliasearch": "^4.23.2", "axios": "^0.28.0", @@ -70,6 +71,7 @@ "devDependencies": { "@docusaurus/module-type-aliases": "2.4.3", "@tsconfig/docusaurus": "^2.0.2", + "lokijs": "^1.5.12", "typescript": "^5.2.2" }, "browserslist": { diff --git a/website/sidebars.js b/website/sidebars.js index 1bd49b70f0..e42dfade5c 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -83,6 +83,7 @@ const sidebars = { collapsible: false, items: [ 'beaconwallet-singleton', + 'wallet_connect_2', 'wallets', 'transaction_limits', ], diff --git a/website/src/theme/CodeBlock/index.js b/website/src/theme/CodeBlock/index.js index 039eb162ec..98d1eb6544 100755 --- a/website/src/theme/CodeBlock/index.js +++ b/website/src/theme/CodeBlock/index.js @@ -88,6 +88,7 @@ export default ({ const { Schema, ParameterSchema, Token } = await import("@taquito/michelson-encoder"); const { Parser, packDataBytes, emitMicheline } = await import('@taquito/michel-codec'); const { RpcClient } = await import('@taquito/rpc'); + const { WalletConnect2, PermissionScopeMethods, NetworkType } = await import('@taquito/wallet-connect-2'); const TransportWebHID = (await import("@ledgerhq/hw-transport-webhid")).default; let wallet; @@ -140,6 +141,9 @@ export default ({ emitMicheline, RpcReadAdapter, RpcClient, + WalletConnect2, + PermissionScopeMethods, + NetworkType, Ed25519, ECDSA, Path, @@ -202,6 +206,9 @@ export default ({ RpcClient: dependencies?.RpcClient, InMemorySpendingKey: dependencies?.InMemorySpendingKey, InMemoryViewingKey: dependencies?.InMemoryViewingKey, + WalletConnect2: dependencies?.WalletConnect2, + PermissionScopeMethods: dependencies?.PermissionScopeMethods, + NetworkType: dependencies?.NetworkType, Ed25519: dependencies?.Ed25519, ECDSA: dependencies?.ECDSA, Path: dependencies?.Path, diff --git a/website/src/theme/Playground/index.js b/website/src/theme/Playground/index.js index ad30778705..3589655a60 100755 --- a/website/src/theme/Playground/index.js +++ b/website/src/theme/Playground/index.js @@ -68,6 +68,10 @@ class SemiLiveProvider extends LiveProvider { let console = {log: value => render("" + value + "\\n")}; +// Needed for the wallet connect 2 live code example +// https://cloud.walletconnect.com/sign-in +const MY_PROJECT_ID = 'ba97fd7d1e89eae02f7c330e14ce1f36' + ${template()} //contract used in example "estimate a contract origination" From 37dd379c68c1ff47984373f29ce9685297028a55 Mon Sep 17 00:00:00 2001 From: huianyang Date: Thu, 26 Sep 2024 10:59:46 -0700 Subject: [PATCH 03/16] feat: has qrcode modal working with @walletconnect/legacy-modal --- docs/wallet_connect_2.md | 10 +- package-lock.json | 213 +++++++++--------- .../taquito-wallet-connect-2/package.json | 6 +- .../src/taquito-wallet-connect-2.ts | 52 +++-- .../taquito-wallet-connect-2/src/types.ts | 5 +- .../taquito-wallet-connect-2/test/data.ts | 8 +- .../test/taquito-wallet-connect-2.spec.ts | 140 ++++++------ website/package-lock.json | 14 +- 8 files changed, 229 insertions(+), 219 deletions(-) diff --git a/docs/wallet_connect_2.md b/docs/wallet_connect_2.md index ad5dfd8ceb..fba5d0b377 100644 --- a/docs/wallet_connect_2.md +++ b/docs/wallet_connect_2.md @@ -33,7 +33,7 @@ await walletConnect.requestPermissions({ permissionScope: { networks: [NetworkType.GHOSTNET], methods: [ - PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN + PermissionScopeMethods.TEZOS_SEND, PermissionScopeMethods.TEZOS_SIGN ], }, // registryUrl: "https://www.tezos.help/wcdata/" @@ -52,7 +52,7 @@ Suppose there is a need to restore a session in the dapp rather than using the ` ## Send Tezos operation with `WalletConnect2` and `TezosToolkit` -Once an instance of `WalletConnect2` is created and a session is established, it can be injected into the `TezosToolkit` using its `setWalletProvider` method. Methods of the wallet API can be invoked to send operations to the blockchain. Those operations will be signed and injected by the wallet. The permission `PermissionScopeMethods.OPERATION_REQUEST` must have been granted, or the error `MissingRequiredScope` will be thrown. +Once an instance of `WalletConnect2` is created and a session is established, it can be injected into the `TezosToolkit` using its `setWalletProvider` method. Methods of the wallet API can be invoked to send operations to the blockchain. Those operations will be signed and injected by the wallet. The permission `PermissionScopeMethods.TEZOS_SEND` must have been granted, or the error `MissingRequiredScope` will be thrown. Wallet connect 2 allows granting permission for multiple accounts in a session. The `setActiveAccount` must be called to set the active account that will be used to prepare the operation. It should be called every time the active account is updated in the dapp. It is possible to retrieve a list of all connected accounts using the `getAccounts` method. The `getPKH` method will return the public key hash of the active account. Note that if only one account is present in the session, it will be set as the active one by default. @@ -65,7 +65,7 @@ Tezos.setRpcProvider('https://ghostnet.ecadinfra.com/'); WalletConnect2.init({ logger: 'debug', - projectId: MY_PROJECT_ID, + projectId: '861613623da99d7285aaad8279a87ee9', metadata: { name: 'Taquito website', description: 'Taquito website with WalletConnect2', @@ -78,7 +78,7 @@ WalletConnect2.init({ .requestPermissions({ permissionScope: { networks: [NetworkType.GHOSTNET], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], }, // registryUrl: 'https://www.tezos.help/wcdata/', }) @@ -99,7 +99,7 @@ WalletConnect2.init({ ## Sign payload with `WalletConnect2` -The `signPayload` method of `WalletConnect2` can be called to sign a payload. The response will be a string representing the signature. The permission `PermissionScopeMethods.SIGN` must have been granted, or the error `MissingRequiredScope` will be thrown. +The `signPayload` method of `WalletConnect2` can be called to sign a payload. The response will be a string representing the signature. The permission `PermissionScopeMethods.TEZOS_SIGN` must have been granted, or the error `MissingRequiredScope` will be thrown. ## Events handling diff --git a/package-lock.json b/package-lock.json index 3540ad49f9..58406f9bff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "taquito", "workspaces": [ "packages/*", "packages/taquito-michel-codec/pack-test-tool", @@ -6548,9 +6549,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.1.tgz", - "integrity": "sha512-XzqSg714++M+FXhHfXpS1tDnNZNpgxxuGZWlRG/jSj+VEPmZ0yg6jV4E0AL3uyBKxO8mO3xtOsP5mQ+XLfrlww==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", "cpu": [ "arm" ], @@ -6562,9 +6563,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.1.tgz", - "integrity": "sha512-thFUbkHteM20BGShD6P08aungq4irbIZKUNbG70LN8RkO7YztcGPiKTTGZS7Kw+x5h8hOXs0i4OaHwFxlpQN6A==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", "cpu": [ "arm64" ], @@ -6576,9 +6577,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.1.tgz", - "integrity": "sha512-8o6eqeFZzVLia2hKPUZk4jdE3zW7LCcZr+MD18tXkgBBid3lssGVAYuox8x6YHoEPDdDa9ixTaStcmx88lio5Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", "cpu": [ "arm64" ], @@ -6590,9 +6591,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.1.tgz", - "integrity": "sha512-4T42heKsnbjkn7ovYiAdDVRRWZLU9Kmhdt6HafZxFcUdpjlBlxj4wDrt1yFWLk7G4+E+8p2C9tcmSu0KA6auGA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", "cpu": [ "x64" ], @@ -6604,9 +6605,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.1.tgz", - "integrity": "sha512-MXg1xp+e5GhZ3Vit1gGEyoC+dyQUBy2JgVQ+3hUrD9wZMkUw/ywgkpK7oZgnB6kPpGrxJ41clkPPnsknuD6M2Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", "cpu": [ "arm" ], @@ -6618,9 +6619,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.1.tgz", - "integrity": "sha512-DZNLwIY4ftPSRVkJEaxYkq7u2zel7aah57HESuNkUnz+3bZHxwkCUkrfS2IWC1sxK6F2QNIR0Qr/YXw7nkF3Pw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", "cpu": [ "arm" ], @@ -6632,9 +6633,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.1.tgz", - "integrity": "sha512-C7evongnjyxdngSDRRSQv5GvyfISizgtk9RM+z2biV5kY6S/NF/wta7K+DanmktC5DkuaJQgoKGf7KUDmA7RUw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", "cpu": [ "arm64" ], @@ -6646,9 +6647,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.1.tgz", - "integrity": "sha512-89tFWqxfxLLHkAthAcrTs9etAoBFRduNfWdl2xUs/yLV+7XDrJ5yuXMHptNqf1Zw0UCA3cAutkAiAokYCkaPtw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", "cpu": [ "arm64" ], @@ -6660,9 +6661,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.1.tgz", - "integrity": "sha512-PromGeV50sq+YfaisG8W3fd+Cl6mnOOiNv2qKKqKCpiiEke2KiKVyDqG/Mb9GWKbYMHj5a01fq/qlUR28PFhCQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", "cpu": [ "ppc64" ], @@ -6674,9 +6675,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.1.tgz", - "integrity": "sha512-/1BmHYh+iz0cNCP0oHCuF8CSiNj0JOGf0jRlSo3L/FAyZyG2rGBuKpkZVH9YF+x58r1jgWxvm1aRg3DHrLDt6A==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", "cpu": [ "riscv64" ], @@ -6688,9 +6689,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.1.tgz", - "integrity": "sha512-0cYP5rGkQWRZKy9/HtsWVStLXzCF3cCBTRI+qRL8Z+wkYlqN7zrSYm6FuY5Kd5ysS5aH0q5lVgb/WbG4jqXN1Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", "cpu": [ "s390x" ], @@ -6702,9 +6703,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.1.tgz", - "integrity": "sha512-XUXeI9eM8rMP8aGvii/aOOiMvTs7xlCosq9xCjcqI9+5hBxtjDpD+7Abm1ZhVIFE1J2h2VIg0t2DX/gjespC2Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", "cpu": [ "x64" ], @@ -6716,9 +6717,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.1.tgz", - "integrity": "sha512-V7cBw/cKXMfEVhpSvVZhC+iGifD6U1zJ4tbibjjN+Xi3blSXaj/rJynAkCFFQfoG6VZrAiP7uGVzL440Q6Me2Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", "cpu": [ "x64" ], @@ -6730,9 +6731,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.1.tgz", - "integrity": "sha512-88brja2vldW/76jWATlBqHEoGjJLRnP0WOEKAUbMcXaAZnemNhlAHSyj4jIwMoP2T750LE9lblvD4e2jXleZsA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", "cpu": [ "arm64" ], @@ -6744,9 +6745,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.1.tgz", - "integrity": "sha512-LdxxcqRVSXi6k6JUrTah1rHuaupoeuiv38du8Mt4r4IPer3kwlTo+RuvfE8KzZ/tL6BhaPlzJ3835i6CxrFIRQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", "cpu": [ "ia32" ], @@ -6758,9 +6759,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.1.tgz", - "integrity": "sha512-2bIrL28PcK3YCqD9anGxDxamxdiJAxA+l7fWIwM5o8UqNy1t3d1NdAweO2XhA0KTDJ5aH1FsuiT5+7VhtHliXg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", "cpu": [ "x64" ], @@ -22259,9 +22260,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true, "license": "ISC" }, @@ -22575,9 +22576,9 @@ } }, "node_modules/postcss": { - "version": "8.4.40", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", - "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -22596,8 +22597,8 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -24094,9 +24095,9 @@ } }, "node_modules/rollup": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.1.tgz", - "integrity": "sha512-K5vziVlg7hTpYfFBI+91zHBEMo6jafYXpkMlqZjg7/zhIG9iHqazBf4xz9AVdjS9BruRn280ROqLI7G3OFRIlw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", "dev": true, "license": "MIT", "dependencies": { @@ -24110,22 +24111,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.1", - "@rollup/rollup-android-arm64": "4.19.1", - "@rollup/rollup-darwin-arm64": "4.19.1", - "@rollup/rollup-darwin-x64": "4.19.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.1", - "@rollup/rollup-linux-arm-musleabihf": "4.19.1", - "@rollup/rollup-linux-arm64-gnu": "4.19.1", - "@rollup/rollup-linux-arm64-musl": "4.19.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.1", - "@rollup/rollup-linux-riscv64-gnu": "4.19.1", - "@rollup/rollup-linux-s390x-gnu": "4.19.1", - "@rollup/rollup-linux-x64-gnu": "4.19.1", - "@rollup/rollup-linux-x64-musl": "4.19.1", - "@rollup/rollup-win32-arm64-msvc": "4.19.1", - "@rollup/rollup-win32-ia32-msvc": "4.19.1", - "@rollup/rollup-win32-x64-msvc": "4.19.1", + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", "fsevents": "~2.3.2" } }, @@ -25094,9 +25095,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -27214,15 +27215,15 @@ } }, "node_modules/vite": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", - "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -27241,6 +27242,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -27258,6 +27260,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -28964,9 +28969,9 @@ "@taquito/taquito": "^20.0.1", "@walletconnect/legacy-modal": "^2.0.0", "@walletconnect/modal": "^2.6.2", - "@walletconnect/sign-client": "^2.16.1", - "@walletconnect/types": "^2.16.1", - "@walletconnect/utils": "^2.16.1" + "@walletconnect/sign-client": "^2.16.2", + "@walletconnect/types": "^2.16.2", + "@walletconnect/utils": "^2.16.2" }, "devDependencies": { "@types/bluebird": "^3.5.42", @@ -29014,9 +29019,9 @@ } }, "packages/taquito-wallet-connect-2/node_modules/@walletconnect/core": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-2.16.1.tgz", - "integrity": "sha512-UlsnEMT5wwFvmxEjX8s4oju7R3zadxNbZgsFeHEsjh7uknY2zgmUe1Lfc5XU6zyPb1Jx7Nqpdx1KN485ee8ogw==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-2.16.2.tgz", + "integrity": "sha512-Xf1SqLSB8KffNsgUGDE/CguAcKMD+3EKfqfqNhWpimxe1QDZDUw8xq+nnxfx6MAb8fdx9GYe6Lvknx2SAAeAHw==", "license": "Apache-2.0", "dependencies": { "@walletconnect/heartbeat": "1.2.2", @@ -29030,8 +29035,8 @@ "@walletconnect/relay-auth": "1.0.4", "@walletconnect/safe-json": "1.0.2", "@walletconnect/time": "1.0.2", - "@walletconnect/types": "2.16.1", - "@walletconnect/utils": "2.16.1", + "@walletconnect/types": "2.16.2", + "@walletconnect/utils": "2.16.2", "events": "3.3.0", "lodash.isequal": "4.5.0", "uint8arrays": "3.1.0" @@ -29073,26 +29078,26 @@ } }, "packages/taquito-wallet-connect-2/node_modules/@walletconnect/sign-client": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.16.1.tgz", - "integrity": "sha512-s2Tx2n2duxt+sHtuWXrN9yZVaHaYqcEcjwlTD+55/vs5NUPlISf+fFmZLwSeX1kUlrSBrAuxPUcqQuRTKcjLOA==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.16.2.tgz", + "integrity": "sha512-R/hk2P3UN5u3FV22E7h9S/Oy8IbDwaBGH7St/BzOpJCjFmf6CF5S3GZVjrXPBesvRF94CROkqMF89wz5HkZepA==", "license": "Apache-2.0", "dependencies": { - "@walletconnect/core": "2.16.1", + "@walletconnect/core": "2.16.2", "@walletconnect/events": "1.0.1", "@walletconnect/heartbeat": "1.2.2", "@walletconnect/jsonrpc-utils": "1.0.8", "@walletconnect/logger": "2.1.2", "@walletconnect/time": "1.0.2", - "@walletconnect/types": "2.16.1", - "@walletconnect/utils": "2.16.1", + "@walletconnect/types": "2.16.2", + "@walletconnect/utils": "2.16.2", "events": "3.3.0" } }, "packages/taquito-wallet-connect-2/node_modules/@walletconnect/types": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-2.16.1.tgz", - "integrity": "sha512-9P4RG4VoDEF+yBF/n2TF12gsvT/aTaeZTVDb/AOayafqiPnmrQZMKmNCJJjq1sfdsDcHXFcZWMGsuCeSJCmrXA==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-2.16.2.tgz", + "integrity": "sha512-IIV9kQh6b/WpwhfgPixpziE+8XK/FtdnfvN1oOMs5h+lgwr46OJknPY2p7eS6vvdvEP3xMEc1Kbu1i4tlnroiw==", "license": "Apache-2.0", "dependencies": { "@walletconnect/events": "1.0.1", @@ -29104,9 +29109,9 @@ } }, "packages/taquito-wallet-connect-2/node_modules/@walletconnect/utils": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.16.1.tgz", - "integrity": "sha512-aoQirVoDoiiEtYeYDtNtQxFzwO/oCrz9zqeEEXYJaAwXlGVTS34KFe7W3/Rxd/pldTYKFOZsku2EzpISfH8Wsw==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.16.2.tgz", + "integrity": "sha512-CEMxMCIqvwXd8YIEXfBoCiWY8DtUevJ/w14Si+cmTHWHBDWKRZll7+QUXgICIBx5kyX3GMAKNABaTlg2A2CPSg==", "license": "Apache-2.0", "dependencies": { "@stablelib/chacha20poly1305": "1.0.1", @@ -29118,7 +29123,7 @@ "@walletconnect/relay-auth": "1.0.4", "@walletconnect/safe-json": "1.0.2", "@walletconnect/time": "1.0.2", - "@walletconnect/types": "2.16.1", + "@walletconnect/types": "2.16.2", "@walletconnect/window-getters": "1.0.1", "@walletconnect/window-metadata": "1.0.1", "detect-browser": "5.3.0", diff --git a/packages/taquito-wallet-connect-2/package.json b/packages/taquito-wallet-connect-2/package.json index c971bd1ccc..17155cb6fa 100644 --- a/packages/taquito-wallet-connect-2/package.json +++ b/packages/taquito-wallet-connect-2/package.json @@ -69,9 +69,9 @@ "@taquito/taquito": "^20.0.1", "@walletconnect/legacy-modal": "^2.0.0", "@walletconnect/modal": "^2.6.2", - "@walletconnect/sign-client": "^2.16.1", - "@walletconnect/types": "^2.16.1", - "@walletconnect/utils": "^2.16.1" + "@walletconnect/sign-client": "^2.16.2", + "@walletconnect/types": "^2.16.2", + "@walletconnect/utils": "^2.16.2" }, "devDependencies": { "@types/bluebird": "^3.5.42", diff --git a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts index 26303db2d1..549e21bc69 100644 --- a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts +++ b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts @@ -5,8 +5,8 @@ import Client from '@walletconnect/sign-client'; import { SignClientTypes, SessionTypes, PairingTypes } from '@walletconnect/types'; -// import QRCodeModal from '@walletconnect/legacy-modal'; -import { WalletConnectModal } from '@walletconnect/modal'; +import QRCodeModal from '@walletconnect/legacy-modal'; +// import { WalletConnectModal } from '@walletconnect/modal'; import { createOriginationOperation, @@ -62,12 +62,14 @@ export class WalletConnect2 implements WalletProvider { private session: SessionTypes.Struct | undefined; private activeAccount: string | undefined; private activeNetwork: string | undefined; - private WalletConnectModal: WalletConnectModal; + // private WalletConnectModal: WalletConnectModal; + + constructor(signClient: Client) { + // constructor(signClient: Client, WalletConnectModal: WalletConnectModal) { - constructor(signClient: Client, WalletConnectModal: WalletConnectModal) { this.signClient = signClient; - this.WalletConnectModal = WalletConnectModal; - signClient.metadata; + // this.WalletConnectModal = WalletConnectModal; + this.signClient.on('session_delete', ({ topic }) => { if (this.session?.topic === topic) { this.session = undefined; @@ -110,12 +112,13 @@ export class WalletConnect2 implements WalletProvider { * ``` */ static async init(initParams: SignClientTypes.Options) { - if (!initParams.projectId) { - throw new Error('projectId is required'); - } + // if (!initParams.projectId) { + // throw new Error('projectId is required'); + // } const client = await Client.init(initParams); - const walletConnectModal = new WalletConnectModal({ projectId: initParams.projectId }); - return new WalletConnect2(client, walletConnectModal); + // const walletConnectModal = new WalletConnectModal({ projectId: initParams.projectId }); + return new WalletConnect2(client); + // return new WalletConnect2(client, walletConnectModal); } /** @@ -147,16 +150,17 @@ export class WalletConnect2 implements WalletProvider { }); if (uri) { - this.WalletConnectModal.openModal({ uri, chains: [TEZOS_PLACEHOLDER] }); - - this.session = await approval(); + QRCodeModal.open(uri, () => {}, { registryUrl: connectParams.registryUrl }); + // this.WalletConnectModal.openModal({ uri, chains: [TEZOS_PLACEHOLDER] }); + // this.session = await approval(); } + this.session = await approval(); } catch (error) { throw new ConnectionFailed(error); } finally { - // QRCodeModal.close(); + QRCodeModal.close(); } - this.validateReceivedNamespace(connectParams.permissionScope, this.session!.namespaces); + this.validateReceivedNamespace(connectParams.permissionScope, this.session.namespaces); this.setDefaultAccountAndNetwork(); } @@ -209,24 +213,24 @@ export class WalletConnect2 implements WalletProvider { */ async sendOperations(params: OperationParams[]) { const session = this.getSession(); - if (!this.getPermittedMethods().includes(PermissionScopeMethods.OPERATION_REQUEST)) { - throw new MissingRequiredScope(PermissionScopeMethods.OPERATION_REQUEST); + if (!this.getPermittedMethods().includes(PermissionScopeMethods.TEZOS_SEND)) { + throw new MissingRequiredScope(PermissionScopeMethods.TEZOS_SEND); } const network = this.getActiveNetwork(); const account = await this.getPKH(); this.validateNetworkAndAccount(network, account); - const hash = await this.signClient.request({ + const { transactionHash } = await this.signClient.request<{ transactionHash: string }>({ topic: session.topic, chainId: `${TEZOS_PLACEHOLDER}:${network}`, request: { - method: PermissionScopeMethods.OPERATION_REQUEST, + method: PermissionScopeMethods.TEZOS_SEND, params: { account, operations: params, }, }, }); - return hash; + return transactionHash; } async sign(bytes: string, watermark?: Uint8Array): Promise { @@ -244,8 +248,8 @@ export class WalletConnect2 implements WalletProvider { sourceAddress?: string; }) { const session = this.getSession(); - if (!this.getPermittedMethods().includes(PermissionScopeMethods.SIGN)) { - throw new MissingRequiredScope(PermissionScopeMethods.SIGN); + if (!this.getPermittedMethods().includes(PermissionScopeMethods.TEZOS_SIGN)) { + throw new MissingRequiredScope(PermissionScopeMethods.TEZOS_SIGN); } const network = this.getActiveNetwork(); const account = await this.getPKH(); @@ -254,7 +258,7 @@ export class WalletConnect2 implements WalletProvider { topic: session.topic, chainId: `${TEZOS_PLACEHOLDER}:${network}`, request: { - method: PermissionScopeMethods.SIGN, + method: PermissionScopeMethods.TEZOS_SIGN, params: { account: params.sourceAddress ?? account, expression: params.payload, diff --git a/packages/taquito-wallet-connect-2/src/types.ts b/packages/taquito-wallet-connect-2/src/types.ts index d3dff8e13e..2cd435a828 100644 --- a/packages/taquito-wallet-connect-2/src/types.ts +++ b/packages/taquito-wallet-connect-2/src/types.ts @@ -31,8 +31,9 @@ export interface PermissionScopeParam { events?: PermissionScopeEvents[]; } export enum PermissionScopeMethods { - OPERATION_REQUEST = 'tezos_sendOperations', - SIGN = 'tezos_signExpression', + TEZOS_GET_ACCOUNTS = 'tezos_getAccounts', + TEZOS_SEND = 'tezos_send', + TEZOS_SIGN = 'tezos_sign', } export enum PermissionScopeEvents { diff --git a/packages/taquito-wallet-connect-2/test/data.ts b/packages/taquito-wallet-connect-2/test/data.ts index 8caeb2b97a..6bbe490850 100644 --- a/packages/taquito-wallet-connect-2/test/data.ts +++ b/packages/taquito-wallet-connect-2/test/data.ts @@ -7,7 +7,7 @@ export const sessionExample = { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], events: [], }, }, @@ -33,7 +33,7 @@ export const sessionExample = { }, requiredNamespaces: { tezos: { - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], chains: ['tezos:ghostnet'], events: [], }, @@ -56,7 +56,7 @@ export const sessionMultipleChains = { 'tezos:parisnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', 'tezos:parisnet:tz2JobFgDoJ5HZ1jAoMgZCyNdbBEdAstkytV', ], - methods: ['tezos_signExpression'], + methods: ['tezos_sign'], events: [], }, }, @@ -82,7 +82,7 @@ export const sessionMultipleChains = { }, requiredNamespaces: { tezos: { - methods: ['tezos_signExpression'], + methods: ['tezos_sign'], chains: ['tezos:ghostnet', 'tezos:parisnet'], events: [], }, diff --git a/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts index 67f69957d8..2befdce964 100644 --- a/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts +++ b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts @@ -67,7 +67,7 @@ describe('Wallet connect 2 tests', () => { it('should establish a connection successfully', async () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -76,7 +76,7 @@ describe('Wallet connect 2 tests', () => { requiredNamespaces: { tezos: { chains: ['tezos:ghostnet'], - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], events: [], }, }, @@ -88,7 +88,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -102,7 +102,7 @@ describe('Wallet connect 2 tests', () => { ...sessionExample, requiredNamespaces: { unknown: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], chains: ['tezos:ghostnet'], events: [], }, @@ -114,7 +114,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -125,7 +125,7 @@ describe('Wallet connect 2 tests', () => { beforeEach(async () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -145,7 +145,7 @@ describe('Wallet connect 2 tests', () => { beforeEach(async () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -186,7 +186,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }); @@ -230,7 +230,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -243,7 +243,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }); @@ -258,7 +258,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }); @@ -272,7 +272,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }); @@ -283,7 +283,7 @@ describe('Wallet connect 2 tests', () => { it('should delete active account when calling disconnect', async () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -306,7 +306,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: [], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -317,7 +317,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -334,7 +334,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -345,7 +345,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -360,12 +360,12 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SEND, PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET], }, }) ).rejects.toThrow( - '5002: All methods must be approved. "tezos_signExpression" is missing in the session namespace.' + '5002: All methods must be approved. "tezos_sign" is missing in the session namespace.' ); }); @@ -388,12 +388,12 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SEND, PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET], }, }) ).rejects.toThrow( - '5002: All methods must be approved. "tezos_sendOperations,tezos_signExpression" is missing in the session namespace.' + '5002: All methods must be approved. "tezos_send,tezos_sign" is missing in the session namespace.' ); }); @@ -407,7 +407,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -418,7 +418,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }) @@ -437,7 +437,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -448,7 +448,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET, NetworkType.OXFORDNET], }, }) @@ -470,7 +470,7 @@ describe('Wallet connect 2 tests', () => { 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', 'tezos:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', ], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -480,7 +480,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -489,7 +489,7 @@ describe('Wallet connect 2 tests', () => { requiredNamespaces: { tezos: { chains: ['tezos:ghostnet'], - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], events: [], }, }, @@ -506,7 +506,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST, PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SEND, PermissionScopeMethods.TEZOS_SIGN], events: [PermissionScopeEvents.ACCOUNTS_CHANGED], }, }, @@ -516,7 +516,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -525,7 +525,7 @@ describe('Wallet connect 2 tests', () => { requiredNamespaces: { tezos: { chains: ['tezos:ghostnet'], - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], events: [], }, }, @@ -545,7 +545,7 @@ describe('Wallet connect 2 tests', () => { 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', 'unknown:ghostnet:tz2BxqkU3UvZrqA22vbEaSGyjR9bEQwc4k2G', ], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -556,7 +556,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -578,7 +578,7 @@ describe('Wallet connect 2 tests', () => { 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', 'tezos:limanet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', ], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [PermissionScopeEvents.ACCOUNTS_CHANGED], }, }, @@ -588,7 +588,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -597,7 +597,7 @@ describe('Wallet connect 2 tests', () => { requiredNamespaces: { tezos: { chains: ['tezos:ghostnet'], - methods: ['tezos_sendOperations'], + methods: ['tezos_send'], events: [], }, }, @@ -614,7 +614,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { unknown: { accounts: ['unknown:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -625,7 +625,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }) @@ -644,7 +644,7 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, @@ -655,7 +655,7 @@ describe('Wallet connect 2 tests', () => { await expect( walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], events: [PermissionScopeEvents.ACCOUNTS_CHANGED], }, @@ -668,11 +668,11 @@ describe('Wallet connect 2 tests', () => { describe('test sendOperations', () => { it('should send transaction operation successfully', async () => { - const mockedOpHash = 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf'; - mockSignClient.request.mockResolvedValue(mockedOpHash); + const mockRequestResponse = { transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf' }; + mockSignClient.request.mockResolvedValue(mockRequestResponse); await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -691,7 +691,7 @@ describe('Wallet connect 2 tests', () => { topic: sessionExample.topic, chainId: `tezos:ghostnet`, request: { - method: PermissionScopeMethods.OPERATION_REQUEST, + method: PermissionScopeMethods.TEZOS_SEND, params: { account: 'tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', operations: params, @@ -699,15 +699,15 @@ describe('Wallet connect 2 tests', () => { }, }); - expect(opHash).toEqual(mockedOpHash); + expect(opHash).toEqual(mockRequestResponse.transactionHash); }); it('should send transaction operation with defined limits successfully', async () => { - const mockedOpHash = 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf'; - mockSignClient.request.mockResolvedValue(mockedOpHash); + const mockRequestResponse = { transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf' }; + mockSignClient.request.mockResolvedValue(mockRequestResponse); await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -735,7 +735,7 @@ describe('Wallet connect 2 tests', () => { topic: sessionExample.topic, chainId: `tezos:ghostnet`, request: { - method: PermissionScopeMethods.OPERATION_REQUEST, + method: PermissionScopeMethods.TEZOS_SEND, params: { account: 'tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', operations: params, @@ -743,7 +743,7 @@ describe('Wallet connect 2 tests', () => { }, }); - expect(opHash).toEqual(mockedOpHash); + expect(opHash).toEqual(mockRequestResponse.transactionHash); }); it('should fail to send transaction operation if permission is not granted', async () => { @@ -754,13 +754,13 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], events: [], }, }, requiredNamespaces: { tezos: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], chains: ['tezos:ghostnet'], events: [], }, @@ -771,7 +771,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET], }, }); @@ -785,7 +785,7 @@ describe('Wallet connect 2 tests', () => { ]; await expect(walletConnect.sendOperations(params)).rejects.toThrow( - 'Required permission scope were not granted for "tezos_sendOperations"' + 'Required permission scope were not granted for "tezos_send"' ); }); @@ -800,13 +800,13 @@ describe('Wallet connect 2 tests', () => { 'tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh', 'tezos:parisnet:tz1ZfrERcALBwmAqwonRXYVQBDT9BjNjBHJu', ], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, requiredNamespaces: { tezos: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], chains: ['tezos:ghostnet', 'tezos:parisnet'], events: [], }, @@ -817,7 +817,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], }, }); @@ -848,13 +848,13 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], events: [], }, }, requiredNamespaces: { tezos: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], chains: ['tezos:ghostnet'], events: [], }, @@ -868,7 +868,7 @@ describe('Wallet connect 2 tests', () => { mockSignClient.request.mockResolvedValue(mockedSignature); await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET], }, }); @@ -886,7 +886,7 @@ describe('Wallet connect 2 tests', () => { topic: sessionExample.topic, chainId: `tezos:ghostnet`, request: { - method: PermissionScopeMethods.SIGN, + method: PermissionScopeMethods.TEZOS_SIGN, params: { account: 'tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p', expression: params.payload, @@ -906,13 +906,13 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p'], - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], events: [], }, }, requiredNamespaces: { tezos: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], chains: ['tezos:ghostnet'], events: [], }, @@ -926,7 +926,7 @@ describe('Wallet connect 2 tests', () => { mockSignClient.request.mockResolvedValue(mockedSignature); await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.SIGN], + methods: [PermissionScopeMethods.TEZOS_SIGN], networks: [NetworkType.GHOSTNET], }, }); @@ -943,7 +943,7 @@ describe('Wallet connect 2 tests', () => { topic: sessionExample.topic, chainId: `tezos:ghostnet`, request: { - method: PermissionScopeMethods.SIGN, + method: PermissionScopeMethods.TEZOS_SIGN, params: { account: 'tz1hWt34L3dnwrpBeG9RWJPQVTgTTAmH1b1p', expression: params.payload, @@ -963,13 +963,13 @@ describe('Wallet connect 2 tests', () => { namespaces: { tezos: { accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], events: [], }, }, requiredNamespaces: { tezos: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], chains: ['tezos:ghostnet'], events: [], }, @@ -980,7 +980,7 @@ describe('Wallet connect 2 tests', () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); @@ -992,7 +992,7 @@ describe('Wallet connect 2 tests', () => { }; await expect(walletConnect.signPayload(params)).rejects.toThrow( - 'Required permission scope were not granted for "tezos_signExpression"' + 'Required permission scope were not granted for "tezos_sign"' ); }); }); @@ -1139,7 +1139,7 @@ describe('Wallet connect 2 tests', () => { beforeEach(async () => { await walletConnect.requestPermissions({ permissionScope: { - methods: [PermissionScopeMethods.OPERATION_REQUEST], + methods: [PermissionScopeMethods.TEZOS_SEND], networks: [NetworkType.GHOSTNET], }, }); diff --git a/website/package-lock.json b/website/package-lock.json index 337e982681..836e5dcaa2 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -632,9 +632,9 @@ "@taquito/taquito": "^20.0.1", "@walletconnect/legacy-modal": "^2.0.0", "@walletconnect/modal": "^2.6.2", - "@walletconnect/sign-client": "^2.16.1", - "@walletconnect/types": "^2.16.1", - "@walletconnect/utils": "^2.16.1" + "@walletconnect/sign-client": "^2.16.2", + "@walletconnect/types": "^2.16.2", + "@walletconnect/utils": "^2.16.2" }, "devDependencies": { "@types/bluebird": "^3.5.42", @@ -11467,9 +11467,9 @@ } }, "node_modules/dompurify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", - "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.7.tgz", + "integrity": "sha512-2q4bEI+coQM8f5ez7kt2xclg1XsecaV9ASJk/54vwlfRRNQfDqJz2pzQ8t0Ix/ToBpXlVjrRIx7pFC/o8itG2Q==", "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/domutils": { @@ -15979,7 +15979,7 @@ "d3": "^7.4.0", "dagre-d3-es": "7.0.9", "dayjs": "^1.11.7", - "dompurify": "2.4.3", + "dompurify": "^2.5.4", "elkjs": "^0.8.2", "khroma": "^2.0.0", "lodash-es": "^4.17.21", From 410c28c50c9fb6041d1fbed9ce46b2c09de3cce6 Mon Sep 17 00:00:00 2001 From: huianyang Date: Thu, 26 Sep 2024 12:08:16 -0700 Subject: [PATCH 04/16] feat: fill-in wc2 logic of sing and getPK --- .../src/taquito-wallet-connect-2.ts | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts index 549e21bc69..9008975ac4 100644 --- a/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts +++ b/packages/taquito-wallet-connect-2/src/taquito-wallet-connect-2.ts @@ -233,9 +233,33 @@ export class WalletConnect2 implements WalletProvider { return transactionHash; } + // TODO need unit and test-dapp test async sign(bytes: string, watermark?: Uint8Array): Promise { console.log(bytes, watermark); - return ''; + const session = this.getSession(); + if (!this.getPermittedMethods().includes(PermissionScopeMethods.TEZOS_SIGN)) { + throw new MissingRequiredScope(PermissionScopeMethods.TEZOS_SIGN); + } + const network = this.getActiveNetwork(); + const account = await this.getPKH(); + this.validateNetworkAndAccount(network, account); + let expression = bytes; + if (watermark) { + expression = + Array.from(watermark, (byte) => byte.toString(16).padStart(2, '0')).join('') + expression; + } + const signature = await this.signClient.request({ + topic: session.topic, + chainId: `${TEZOS_PLACEHOLDER}:${network}`, + request: { + method: PermissionScopeMethods.TEZOS_SIGN, + params: { + expression, + signingType: SigningType.RAW, + }, + }, + }); + return signature; } /** @@ -266,6 +290,7 @@ export class WalletConnect2 implements WalletProvider { }, }, }); + console.log(signature); return signature; } @@ -302,12 +327,17 @@ export class WalletConnect2 implements WalletProvider { return this.activeAccount; } + // TODO need test-dapp test /** * @description Access the public key of the active account * @error ActiveAccountUnspecified thrown when there are multiple Tezos account in the session and none is set as the active one */ async getPK() { - return ''; + if (!this.activeAccount) { + this.getSession(); + throw new ActiveAccountUnspecified(); + } + return this.getSession().self.publicKey; } /** @@ -540,7 +570,12 @@ export class WalletConnect2 implements WalletProvider { } private formatParameters( - params: WalletTransferParams | WalletOriginateParams | WalletDelegateParams + params: + | WalletTransferParams + | WalletTransferTicketParams + | WalletOriginateParams + | WalletDelegateParams + | WalletIncreasePaidStorageParams ) { const formatedParams: any = params; if (typeof params.fee !== 'undefined') { From 25d970aacfe6cf8c7f9a249114cec9d6e6e61b51 Mon Sep 17 00:00:00 2001 From: huianyang Date: Thu, 26 Sep 2024 12:16:37 -0700 Subject: [PATCH 05/16] test: added unit test ofr sign and getPK --- .../test/taquito-wallet-connect-2.spec.ts | 179 +++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts index 2befdce964..05486fbb7b 100644 --- a/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts +++ b/packages/taquito-wallet-connect-2/test/taquito-wallet-connect-2.spec.ts @@ -295,6 +295,83 @@ describe('Wallet connect 2 tests', () => { }); }); + describe('test public key', () => { + it('should return public key when session namespace only have one', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionExample }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SEND], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(await walletConnect.getPK()).toEqual( + '01b5630403234ba9745073c9ad081c7b812786b2bcfa8cfe1ff28d800b989f29' + ); + }); + + it('should throw an error when no active account is set and session namespace has multiple accounts', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + await expect(walletConnect.getPK()).rejects.toThrow( + 'Please specify the active account using the "setActiveAccount" method.' + ); + }); + + it('should set the active account successfully', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + walletConnect.setActiveAccount('tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'); + expect(await walletConnect.getPK()).toEqual( + '72dfcd018c5a636c311a0214c19f24e1e52a0f38082e31e3971af9b0296f4767' + ); + }); + + it('should fail to set the active account when it is not part of the session namespace', async () => { + mockSignClient.connect.mockReturnValue({ approval: async () => sessionMultipleChains }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SIGN], + networks: [NetworkType.GHOSTNET, NetworkType.PARISNET], + }, + }); + + expect(() => walletConnect.setActiveAccount('test')).toThrow('Invalid pkh "test"'); + }); + + it('should delete active account when calling disconnect', async () => { + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SEND], + networks: [NetworkType.GHOSTNET], + }, + }); + + expect(await walletConnect.getPK()).toEqual( + '01b5630403234ba9745073c9ad081c7b812786b2bcfa8cfe1ff28d800b989f29' + ); + await walletConnect.disconnect(); + expect(mockSignClient.disconnect).toHaveBeenCalledTimes(1); + await expect(walletConnect.getPK()).rejects.toThrow('Not connected, no active session'); + }); + }); + describe('test validation of incoming proposal namespaces', () => { it('should fail to establish a connection if the proposal namespace does not have any accounts', async () => { // https://docs.walletconnect.com/2.0/specs/clients/sign/session-namespaces#21-session-namespaces-must-not-have-accounts-empty @@ -668,7 +745,9 @@ describe('Wallet connect 2 tests', () => { describe('test sendOperations', () => { it('should send transaction operation successfully', async () => { - const mockRequestResponse = { transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf' }; + const mockRequestResponse = { + transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf', + }; mockSignClient.request.mockResolvedValue(mockRequestResponse); await walletConnect.requestPermissions({ permissionScope: { @@ -703,7 +782,9 @@ describe('Wallet connect 2 tests', () => { }); it('should send transaction operation with defined limits successfully', async () => { - const mockRequestResponse = { transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf' }; + const mockRequestResponse = { + transactionHash: 'onoNdgS5qcpuxyQVUEerSGCZQdyA3aGbC3nKoQmHJGic5AH9kQf', + }; mockSignClient.request.mockResolvedValue(mockRequestResponse); await walletConnect.requestPermissions({ permissionScope: { @@ -997,6 +1078,100 @@ describe('Wallet connect 2 tests', () => { }); }); + describe('test sign', () => { + it('should sign successfully', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.TEZOS_SIGN], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.TEZOS_SIGN], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + const mockedSignature = + 'edsigtpDN7L5LfzvYWM22fvYA4dPVr9wXaYje7z4nmBrT6ZxkGnHS6u3UuvD9TQv3BmNRSUgnMH1dKsAaLWhfuXXj63myo2m3De'; + mockSignClient.request.mockResolvedValue(mockedSignature); + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SIGN], + networks: [NetworkType.GHOSTNET], + }, + }); + + const sig = await walletConnect.sign( + '010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + new Uint8Array([5]) + ); + + expect(mockSignClient.request).toHaveBeenCalledWith({ + topic: sessionExample.topic, + chainId: `tezos:ghostnet`, + request: { + method: PermissionScopeMethods.TEZOS_SIGN, + params: { + expression: + '05010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + signingType: SigningType.RAW, + }, + }, + }); + + expect(sig).toEqual(mockedSignature); + }); + + it('should fail to sign payload if permission is not granted', async () => { + mockSignClient.connect.mockReturnValue({ + approval: async () => { + return { + ...sessionExample, + namespaces: { + tezos: { + accounts: ['tezos:ghostnet:tz2AJ8DYxeRSUWr8zS5DcFfJYzTSNYzALxSh'], + methods: [PermissionScopeMethods.TEZOS_SEND], + events: [], + }, + }, + requiredNamespaces: { + tezos: { + methods: [PermissionScopeMethods.TEZOS_SEND], + chains: ['tezos:ghostnet'], + events: [], + }, + }, + }; + }, + }); + + await walletConnect.requestPermissions({ + permissionScope: { + methods: [PermissionScopeMethods.TEZOS_SEND], + networks: [NetworkType.GHOSTNET], + }, + }); + + await expect( + walletConnect.sign( + '010031363454657a6f73205369676e6564204d6573736167653a207461717569746f2d746573742d646170702e6e65746c6966792e6170702f20323032322d31322d31335432333a30353a30372e3938375a2074657374', + new Uint8Array([5]) + ) + ).rejects.toThrow('Required permission scope were not granted for "tezos_sign"'); + }); + }); + describe('test map params to wallet params', () => { it('should transform the transfer parameters appropriately', async () => { const params = async () => { From 902b3523e7831ab03d17ed876221885fbb031745 Mon Sep 17 00:00:00 2001 From: huianyang Date: Thu, 10 Oct 2024 12:43:51 -0700 Subject: [PATCH 06/16] chore: dependencies update to fix vulnerbilities --- website/package-lock.json | 388 ++++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 186 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index b5a26bb1f4..26be4ae8b7 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -5400,7 +5400,7 @@ "slash": "^3.0.0", "ssri": "^9.0.1", "strong-log-transformer": "2.1.0", - "tar": "6.1.11", + "tar": "6.2.1", "temp-dir": "1.0.0", "upath": "2.0.1", "uuid": "^9.0.0", @@ -6873,12 +6873,15 @@ "license": "MIT" }, "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@slorber/static-site-generator-webpack-plugin": { @@ -7153,15 +7156,15 @@ } }, "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "license": "MIT", "dependencies": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/@taquito/beacon-wallet": { @@ -7310,6 +7313,18 @@ "@types/node": "*" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -7392,6 +7407,12 @@ "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "license": "MIT" }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT" + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -7437,6 +7458,15 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/mdast": { "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", @@ -7560,6 +7590,15 @@ "@types/react-router": "*" } }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -9062,19 +9101,28 @@ "node": ">=10" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "license": "MIT", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { "node": ">=8" @@ -9095,24 +9143,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -10017,9 +10047,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11188,15 +11218,30 @@ } }, "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "dependencies": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dedent": { @@ -11248,10 +11293,13 @@ } }, "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "license": "MIT" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/define-data-property": { "version": "1.1.4", @@ -11621,9 +11669,9 @@ } }, "node_modules/dompurify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", - "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.4.tgz", + "integrity": "sha512-l5NNozANzaLPPe0XaAwvg3uZcHtDBnziX/HjsY1UcDj1MxTK8Dd0Kv096jyPK5HRzs/XM5IMj20dW8Fk+HnbUA==", "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/domutils": { @@ -11722,12 +11770,6 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "license": "BSD-3-Clause" - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -12127,9 +12169,9 @@ "license": "Apache-2.0" }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -12137,7 +12179,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -12151,7 +12193,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "^3.3.0", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -12195,12 +12237,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "license": "MIT" - }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -13337,37 +13373,28 @@ } }, "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.6" - } - }, - "node_modules/got/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" + "node": ">=10.19.0" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, "node_modules/graceful-fs": { @@ -14034,6 +14061,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -14824,12 +14876,6 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "license": "MIT" }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15020,9 +15066,9 @@ } }, "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "license": "MIT" }, "node_modules/json-parse-better-errors": { @@ -15120,12 +15166,12 @@ } }, "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "license": "MIT", "dependencies": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "node_modules/khroma": { @@ -15258,7 +15304,7 @@ "slash": "3.0.0", "ssri": "^9.0.1", "strong-log-transformer": "2.1.0", - "tar": "6.1.11", + "tar": "6.2.1", "temp-dir": "1.0.0", "typescript": ">=3 < 6", "upath": "2.0.1", @@ -15803,12 +15849,12 @@ } }, "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/lru-cache": { @@ -16151,7 +16197,7 @@ "d3": "^7.4.0", "dagre-d3-es": "7.0.9", "dayjs": "^1.11.7", - "dompurify": "2.4.3", + "dompurify": "2.5.4", "elkjs": "^0.8.2", "khroma": "^2.0.0", "lodash-es": "^4.17.21", @@ -17654,12 +17700,12 @@ } }, "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/p-finally": { @@ -17823,7 +17869,7 @@ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "license": "MIT", "dependencies": { - "got": "^9.6.0", + "got": "^11.8.5", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" @@ -18326,13 +18372,10 @@ } }, "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -19178,15 +19221,6 @@ "postcss": "^8.2.15" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -19937,7 +19971,7 @@ "history": "^4.9.0", "hoist-non-react-statics": "^3.1.0", "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", + "path-to-regexp": "^3.3.0", "prop-types": "^15.6.2", "react-is": "^16.6.0", "tiny-invariant": "^1.0.2", @@ -20731,7 +20765,7 @@ "parse-entities": "^2.0.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", - "trim": "0.0.1", + "trim": "0.0.3", "trim-trailing-lines": "^1.0.0", "unherit": "^1.0.4", "unist-util-remove-position": "^2.0.0", @@ -20920,6 +20954,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -20957,12 +20997,15 @@ "license": "MIT" }, "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "license": "MIT", "dependencies": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/restore-cursor": { @@ -21446,7 +21489,7 @@ "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", + "path-to-regexp": "^3.3.0", "range-parser": "1.2.0" } }, @@ -21483,12 +21526,6 @@ "node": "*" } }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "license": "MIT" - }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -22608,20 +22645,20 @@ } }, "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" } }, "node_modules/tar-stream": { @@ -22640,6 +22677,15 @@ "node": ">=6" } }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -22881,15 +22927,6 @@ "node": ">=4" } }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -22927,9 +22964,9 @@ "license": "MIT" }, "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.3.tgz", + "integrity": "sha512-h82ywcYhHK7veeelXrCScdH7HkWfbIT1D/CgYO+nmDarz3SGNssVBMws6jU16Ga60AJCRAvPV6w6RLuNerQqjg==", "deprecated": "Use String.prototype.trim() instead" }, "node_modules/trim-newlines": { @@ -23858,18 +23895,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "license": "MIT", - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/use-composed-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", @@ -24057,7 +24082,7 @@ "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", "license": "MIT", "dependencies": { - "axios": "^0.25.0", + "axios": "^0.28.0", "joi": "^17.6.0", "lodash": "^4.17.21", "minimist": "^1.2.5", @@ -24070,15 +24095,6 @@ "node": ">=10.0.0" } }, - "node_modules/wait-on/node_modules/axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.7" - } - }, "node_modules/watchpack": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", From 303376c7759ee168f35b14bddeb70a64c69cbfb0 Mon Sep 17 00:00:00 2001 From: huianyang Date: Fri, 25 Oct 2024 14:42:41 -0700 Subject: [PATCH 07/16] feat: testdapp with walletconnect option --- README.md | 2 + apps/taquito-test-dapp/package.json | 2 + apps/taquito-test-dapp/src/App.svelte | 53 +- apps/taquito-test-dapp/src/config.ts | 29 +- .../src/lib/ModalActivePairing.svelte | 79 +++ .../src/lib/TestContainer.svelte | 36 +- apps/taquito-test-dapp/src/lib/Wallet.svelte | 338 +++++++------ apps/taquito-test-dapp/src/store.ts | 25 +- apps/taquito-test-dapp/src/tests.ts | 43 +- apps/taquito-test-dapp/src/types.ts | 10 +- apps/taquito-test-dapp/vite.config.ts | 3 +- package-lock.json | 457 +++++++++++++++++- package.json | 3 +- .../taquito-wallet-connect-2/package.json | 2 +- .../src/taquito-wallet-connect-2.ts | 5 +- website/package-lock.json | 61 +-- 16 files changed, 852 insertions(+), 296 deletions(-) create mode 100644 apps/taquito-test-dapp/src/lib/ModalActivePairing.svelte diff --git a/README.md b/README.md index 0446d3bac9..7efbb26282 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ Taquito is organized as a [monorepo](https://en.wikipedia.org/wiki/Monorepo), an | [@taquito/contracts-library](packages/taquito-contracts-library) | Provides functionality specify static data related to contracts | | [@taquito/ledger-signer](packages/taquito-ledger-signer) | Provides functionality for ledger signer provider | | [@taquito/timelock](packages/taquito-timelock) | Provides functionality to create and open timelocks | +| [@taquito/wallet-connect](packages/taquito-wallet-connect) | WalletConnect2 class can be injected into the `TezosToolkit` to work with the wallet API. | + ## API Documentation diff --git a/apps/taquito-test-dapp/package.json b/apps/taquito-test-dapp/package.json index a06b83bec3..78b3dbb161 100644 --- a/apps/taquito-test-dapp/package.json +++ b/apps/taquito-test-dapp/package.json @@ -30,7 +30,9 @@ "@taquito/core": "^20.1.0", "@taquito/taquito": "^20.1.0", "@taquito/utils": "^20.1.0", + "@taquito/wallet-connect-2": "^20.1.0", "buffer": "^6.0.3", + "svelte-modals": "^2.0.0-beta.2", "svelte-select": "^5.8.3", "vite-compatible-readable-stream": "^3.6.1" }, diff --git a/apps/taquito-test-dapp/src/App.svelte b/apps/taquito-test-dapp/src/App.svelte index c3447e11a2..e1e5dd40f8 100644 --- a/apps/taquito-test-dapp/src/App.svelte +++ b/apps/taquito-test-dapp/src/App.svelte @@ -4,7 +4,7 @@ import { NetworkType } from "@airgap/beacon-types"; import Select from "svelte-select"; import { getRpcUrl } from "./config"; - import store from "./store"; + import store, { SDK } from "./store"; import Layout from "./Layout.svelte"; import TestContainer from "./lib/TestContainer.svelte"; @@ -13,7 +13,6 @@ let browser = ""; let availableNetworks = [ { value: "ghostnet", label: "Ghostnet", group: "current testnets" }, - { value: "oxfordnet", label: "Oxfordnet", group: "current testnets" }, { value: "parisnet", label: "Parisnet", group: "current testnets" }, { value: "mainnet", label: "Mainnet", group: "mainnet" }, { value: "dailynet", label: "Dailynet", group: "other testnets" }, @@ -40,9 +39,6 @@ case "ghostnet": store.updateNetworkType(NetworkType.GHOSTNET); break; - case "oxfordnet": - store.updateNetworkType(NetworkType.OXFORDNET); - break; case "parisnet": store.updateNetworkType(NetworkType.PARISNET); break; @@ -129,6 +125,18 @@ margin: 10px 0px; } + .sdk { + border: 1px solid; + border-radius: 10px; + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 20px; + grid-row-gap: 10px; + align-items: center; + width: 100%; + } + button { width: 100%; justify-content: center; @@ -175,15 +183,32 @@
(use Chrome for a better experience)
{/if}
- +
+ Connect using beacon sdk + +
+
+ Connect using Wallet Connect 2 + +
+ {/each} +

or

+ +
+ + +{/if} \ No newline at end of file diff --git a/apps/taquito-test-dapp/src/lib/TestContainer.svelte b/apps/taquito-test-dapp/src/lib/TestContainer.svelte index 89c466b26f..69d46d805c 100644 --- a/apps/taquito-test-dapp/src/lib/TestContainer.svelte +++ b/apps/taquito-test-dapp/src/lib/TestContainer.svelte @@ -5,14 +5,26 @@ import { shortenHash } from "../utils"; import { NetworkType } from "@airgap/beacon-types"; import { getTzKtUrl } from "../config"; + import { BeaconWallet } from "@taquito/beacon-wallet"; let test: TestSettings | undefined; let executionTime = 0; let loading = false; let success: boolean | undefined; let opHash = ""; - let input = { text: "", fee: 400, storageLimit: 400, gasLimit: 1320, amount: 0, address: "", delegate: "", stake: 0, unstake: 0 }; + let input = { + text: "", + fee: 400, + storageLimit: 400, + gasLimit: 1320, + amount: 0, + address: "", + delegate: "", + stake: 0, + unstake: 0, + }; let testResult: { id: string; title: string; body: any }; + let error: Error | undefined; const run = async () => { success = undefined; @@ -70,7 +82,8 @@ }; } } else { - throw "Error"; + error = result.error; + throw result.error; } } catch (error) { console.log(error); @@ -82,7 +95,9 @@ }; const switchAccount = async () => { - await $store.wallet.clearActiveAccount(); + if ($store.wallet instanceof BeaconWallet) { + await $store.wallet.clearActiveAccount(); + } store.updateUserAddress(undefined); store.updateUserBalance(undefined); store.updateWallet(undefined); @@ -306,21 +321,21 @@ bind:value={input.text} /> - {:else if test.inputRequired && test.inputType === "delegate"} + {:else if test.inputRequired && test.inputType === "delegate"}
- {:else if test.inputRequired && test.inputType === "stake"} + {:else if test.inputRequired && test.inputType === "stake"}
- {:else if test.inputRequired && test.inputType === "unstake"} + {:else if test.inputRequired && test.inputType === "unstake"}
{/if}
diff --git a/apps/taquito-test-dapp/src/lib/Wallet.svelte b/apps/taquito-test-dapp/src/lib/Wallet.svelte index e14fb992f2..48983e1803 100644 --- a/apps/taquito-test-dapp/src/lib/Wallet.svelte +++ b/apps/taquito-test-dapp/src/lib/Wallet.svelte @@ -3,105 +3,213 @@ import { fly } from "svelte/transition"; import { TezosToolkit } from "@taquito/taquito"; import { BeaconWallet } from "@taquito/beacon-wallet"; - import { BeaconEvent, type DAppClientOptions } from "@airgap/beacon-sdk"; - import store from "../store"; + import store, { SDK } from "../store"; import { formatTokenAmount, shortenHash } from "../utils"; - import { - defaultMatrixNode, - getRpcUrl, - defaultNetworkType, - type SupportedNetworks, - } from "../config"; + import { defaultMatrixNode, getRpcUrl } from "../config"; import type { TezosAccountAddress } from "../types"; + import { WalletConnect2, PermissionScopeMethods, NetworkType as NetworkTypeWc2 } from "@taquito/wallet-connect-2"; + import { Modals, closeModal, openModal } from "svelte-modals"; + import ModalActivePairing from "./ModalActivePairing.svelte"; + import type { NetworkType as NetworkTypeBeacon } from "@airgap/beacon-sdk"; let showDialog = false; let connectedWallet = ""; - const createNewWallet = (config: { networkType: SupportedNetworks }) => { - const wallet = new BeaconWallet({ + const selectExistingPairing = (wallet: WalletConnect2, existingPairing: any[]) => { + openModal( + ModalActivePairing, + { + title: "Select available pairing", + options: existingPairing, + }, + { + on: { + select: async (event) => { + closeModal(); + const topic = event.detail === "new_pairing" ? undefined : event.detail.topic; + await requestPermissionWc2(wallet, topic); + }, + }, + } + ); + }; + + const createNewBeaconWallet = () => { + return new BeaconWallet({ name: "Taquito Test Dapp", matrixNodes: [defaultMatrixNode] as any, - network: { - type: config.networkType, - rpcUrl: getRpcUrl(config.networkType), - }, - walletConnectOptions: { - projectId: "ba97fd7d1e89eae02f7c330e14ce1f36", + preferredNetwork: $store.networkType as NetworkTypeBeacon, + }); + }; + + const createNewWalletConnect2 = async () => { + const wallet = await WalletConnect2.init({ + logger: "debug", + projectId: "861613623da99d7285aaad8279a87ee9", // Your Project ID gives you access to WalletConnect Cloud. + metadata: { + name: "Taquito Test Dapp", + description: "Test Taquito with WalletConnect2", + icons: [], + url: "", }, - enableMetrics: $store.enableMetrics, }); - wallet.client.subscribeToEvent(BeaconEvent.ACTIVE_ACCOUNT_SET, () => {}); + wallet.signClient.on("session_ping", ({ id, topic }) => { + console.log("session_ping in test dapp", id, topic); + }); + wallet.signClient.on("session_delete", ({ topic }) => { + console.log("EVEN: session_delete", topic); + if (!wallet.isActiveSession()) { + resetApp(); + } + }); + wallet.signClient.on("session_update", async ({ topic }) => { + console.log("EVEN: session_update", topic); + const allAccounts = wallet.getAccounts(); + await updateStore(wallet, allAccounts); + }); return wallet; }; - const connectWallet = async () => { - const wallet = await setWallet({ - networkType: $store.networkType, + const requestPermissionWc2 = async (wallet: WalletConnect2, pairingTopic?: string) => { + await wallet.requestPermissions({ + permissionScope: { + networks: [$store.networkType as NetworkTypeWc2], + events: [], + methods: [PermissionScopeMethods.TEZOS_SEND, PermissionScopeMethods.TEZOS_SIGN], + }, + pairingTopic, + registryUrl: "https://www.tezos.help/wcdata/" }); + const allAccounts = wallet.getAccounts(); + await updateStore(wallet, allAccounts); + }; - await subscribeToAllEvents(wallet); - - try { - await wallet.requestPermissions(); + const connectWalletWithExistingSession = async (sessionId: string) => { + const newWallet = await createNewWalletConnect2(); + newWallet.configureWithExistingSessionKey(sessionId); + const allAccounts = newWallet.getAccounts(); + await updateStore(newWallet, allAccounts); + }; - const userAddress = (await wallet.getPKH()) as TezosAccountAddress; - store.updateUserAddress(userAddress); - const url = getRpcUrl($store.networkType); - const Tezos = new TezosToolkit(url); - Tezos.setWalletProvider(wallet); - store.updateTezos(Tezos); + const connectWallet = async () => { + if (!$store.wallet) { + if ($store.sdk === SDK.BEACON) { + const newWallet = createNewBeaconWallet(); + await newWallet.requestPermissions({ + network: { + type: $store.networkType as NetworkTypeBeacon, + rpcUrl: getRpcUrl($store.networkType), + }, + }); - const balance = await Tezos.tz.getBalance(userAddress); - if (balance) { - store.updateUserBalance(balance.toNumber()); + const peers = await newWallet.client.getPeers(); + connectedWallet = peers[0].name; + await updateStore(newWallet); + } else if ($store.sdk === SDK.WC2) { + const newWallet = await createNewWalletConnect2(); + const existingPairing = newWallet.getAvailablePairing(); + if (existingPairing.length > 0) { + selectExistingPairing(newWallet, existingPairing); + } else { + await requestPermissionWc2(newWallet); + } } + } else { + return $store.wallet; + } + }; + const updateUserBalance = async (userAddress: string) => { + const balance = await $store.Tezos!.tz.getBalance(userAddress); + if (balance) { + store.updateUserBalance(balance.toNumber()); + } + }; + + const updateStore = async (wallet: BeaconWallet | WalletConnect2, allAccounts?: string[]) => { + try { store.updateWallet(wallet); + let userAddress: TezosAccountAddress; + if (allAccounts) { + if (allAccounts.length > 1) { + userAddress = allAccounts.shift() as TezosAccountAddress; + store.updateAvailableAccounts(allAccounts); + } else { + store.updateAvailableAccounts([]); + userAddress = allAccounts[0] as TezosAccountAddress; + } + } else { + userAddress = (await wallet.getPKH()) as TezosAccountAddress; + } + store.updateUserAddress(userAddress); + if (wallet instanceof WalletConnect2) { + wallet.setActiveAccount(userAddress); + wallet.setActiveNetwork($store.networkType as any); + } + + const Tezos = new TezosToolkit(getRpcUrl($store.networkType)); + Tezos.setWalletProvider(wallet); + store.updateTezos(Tezos); - const peers = await wallet.client.getPeers(); - connectedWallet = peers[0].name; + await updateUserBalance(userAddress); } catch (err) { console.error(err); } }; - const disconnectWallet = async () => { - await $store.wallet?.clearActiveAccount(); + const resetApp = async () => { store.updateUserAddress(undefined); store.updateUserBalance(undefined); store.updateWallet(undefined); store.updateSelectedTest(undefined); + store.updateTests([]); + store.updateAvailableAccounts([]); }; - export const setWallet = async (config: { networkType: SupportedNetworks }) => { - store.updateNetworkType(config.networkType); - - const wallet = createNewWallet(config); - store.updateWallet(wallet); - const url = getRpcUrl(config.networkType); - const Tezos = new TezosToolkit(url); - Tezos.setWalletProvider(wallet); - store.updateTezos(Tezos); - - // const activeAccount = await wallet.client.getActiveAccount(); - // if (activeAccount) { - // const userAddress = (await wallet.getPKH()) as TezosAccountAddress; - // store.updateUserAddress(userAddress); + const disconnectWallet = async () => { + if ($store.wallet instanceof BeaconWallet) { + await $store.wallet.clearActiveAccount(); + } else if ($store.wallet instanceof WalletConnect2) { + await $store.wallet.disconnect(); + } + resetApp(); + }; - // const balance = await Tezos.tz.getBalance(userAddress); - // if (balance) { - // store.updateUserBalance(balance.toNumber()); - // } - // } - return wallet; + const switchActiveAccount = (newActiveAccount: string) => { + const currentPkh = $store.userAddress; + const availablePkh = $store.availableAccounts; + const index = availablePkh!.indexOf(newActiveAccount, 0); + if (index > -1) { + availablePkh!.splice(index, 1); + } + availablePkh!.push(currentPkh!); + store.updateAvailableAccounts(availablePkh!); + store.updateUserAddress(newActiveAccount); + if ($store.wallet instanceof WalletConnect2) { + $store.wallet.setActiveAccount(newActiveAccount); + } + updateUserBalance(newActiveAccount); }; onMount(async () => { - store.updateNetworkType(defaultNetworkType); + console.log("onmount wallet", $store); + if ( + window && + window.localStorage && + window.localStorage["wc@2:client:0.3//session"] && + window.localStorage["wc@2:client:0.3//session"] !== "[]" + ) { + const sessions = JSON.parse(window.localStorage["wc@2:client:0.3//session"]); + const lastSession = sessions[sessions.length - 1].topic; + store.updateSdk(SDK.WC2); + await connectWalletWithExistingSession(lastSession); + } else { + await connectWallet(); + } }); afterUpdate(async () => { - if ($store.wallet) { + if ($store.wallet instanceof BeaconWallet) { const activeAccount = await $store.wallet.client.getActiveAccount(); if (activeAccount) { const peers = await $store.wallet.client.getPeers(); @@ -109,92 +217,10 @@ connectedWallet = peers[0].name; } } + } else if ($store.wallet instanceof WalletConnect2) { + connectedWallet = $store.wallet.getPeerMetadata().name; } }); - - const saveLog = (data: unknown, eventType: BeaconEvent) => { - const log = JSON.stringify({ eventType, data }); - store.addEvent(log); - }; - - async function subscribeToAllEvents(wallet: BeaconWallet) { - await wallet.client.subscribeToEvent(BeaconEvent.PERMISSION_REQUEST_SENT, (data) => - saveLog(data, BeaconEvent.PERMISSION_REQUEST_SENT), - ); - await wallet.client.subscribeToEvent(BeaconEvent.PERMISSION_REQUEST_SUCCESS, (data) => - saveLog(data, BeaconEvent.PERMISSION_REQUEST_SUCCESS), - ); - await wallet.client.subscribeToEvent(BeaconEvent.PERMISSION_REQUEST_ERROR, (data) => - saveLog(data, BeaconEvent.PERMISSION_REQUEST_ERROR), - ); - await wallet.client.subscribeToEvent(BeaconEvent.OPERATION_REQUEST_SENT, (data) => - saveLog(data, BeaconEvent.OPERATION_REQUEST_SENT), - ); - await wallet.client.subscribeToEvent(BeaconEvent.OPERATION_REQUEST_SUCCESS, (data) => - saveLog(data, BeaconEvent.OPERATION_REQUEST_SUCCESS), - ); - await wallet.client.subscribeToEvent(BeaconEvent.OPERATION_REQUEST_ERROR, (data) => - saveLog(data, BeaconEvent.OPERATION_REQUEST_ERROR), - ); - await wallet.client.subscribeToEvent(BeaconEvent.SIGN_REQUEST_SENT, (data) => - saveLog(data, BeaconEvent.SIGN_REQUEST_SENT), - ); - await wallet.client.subscribeToEvent(BeaconEvent.SIGN_REQUEST_SUCCESS, (data) => - saveLog(data, BeaconEvent.SIGN_REQUEST_SUCCESS), - ); - await wallet.client.subscribeToEvent(BeaconEvent.SIGN_REQUEST_ERROR, (data) => - saveLog(data, BeaconEvent.SIGN_REQUEST_ERROR), - ); - await wallet.client.subscribeToEvent(BeaconEvent.BROADCAST_REQUEST_SENT, (data) => - saveLog(data, BeaconEvent.BROADCAST_REQUEST_SENT), - ); - await wallet.client.subscribeToEvent(BeaconEvent.BROADCAST_REQUEST_SUCCESS, (data) => - saveLog(data, BeaconEvent.BROADCAST_REQUEST_SUCCESS), - ); - await wallet.client.subscribeToEvent(BeaconEvent.BROADCAST_REQUEST_ERROR, (data) => - saveLog(data, BeaconEvent.BROADCAST_REQUEST_ERROR), - ); - await wallet.client.subscribeToEvent(BeaconEvent.ACKNOWLEDGE_RECEIVED, (data) => - saveLog(data, BeaconEvent.ACKNOWLEDGE_RECEIVED), - ); - await wallet.client.subscribeToEvent(BeaconEvent.LOCAL_RATE_LIMIT_REACHED, (data) => - saveLog(data, BeaconEvent.LOCAL_RATE_LIMIT_REACHED), - ); - await wallet.client.subscribeToEvent(BeaconEvent.NO_PERMISSIONS, (data) => - saveLog(data, BeaconEvent.NO_PERMISSIONS), - ); - - await wallet.client.subscribeToEvent(BeaconEvent.ACTIVE_ACCOUNT_SET, (data) => { - saveLog(data, BeaconEvent.ACTIVE_ACCOUNT_SET); - store.updateUserAddress(data.address); - store.updateNetworkType(data.network.type as SupportedNetworks); - }); - - await wallet.client.subscribeToEvent(BeaconEvent.ACTIVE_TRANSPORT_SET, (data) => - saveLog(data, BeaconEvent.ACTIVE_TRANSPORT_SET), - ); - await wallet.client.subscribeToEvent(BeaconEvent.SHOW_PREPARE, (data) => - saveLog(data, BeaconEvent.SHOW_PREPARE), - ); - await wallet.client.subscribeToEvent(BeaconEvent.HIDE_UI, (data) => - saveLog(data, BeaconEvent.HIDE_UI), - ); - await wallet.client.subscribeToEvent(BeaconEvent.PAIR_INIT, (data) => - saveLog(data, BeaconEvent.PAIR_INIT), - ); - await wallet.client.subscribeToEvent(BeaconEvent.PAIR_SUCCESS, (data) => - saveLog(data, BeaconEvent.PAIR_SUCCESS), - ); - await wallet.client.subscribeToEvent(BeaconEvent.CHANNEL_CLOSED, (data) => - saveLog(data, BeaconEvent.CHANNEL_CLOSED), - ); - await wallet.client.subscribeToEvent(BeaconEvent.INTERNAL_ERROR, (data) => - saveLog(data, BeaconEvent.INTERNAL_ERROR), - ); - await wallet.client.subscribeToEvent(BeaconEvent.UNKNOWN, (data) => - saveLog(data, BeaconEvent.UNKNOWN), - ); - }