diff --git a/dapps/react-dapp-v2/package.json b/dapps/react-dapp-v2/package.json index 03cebb3..330cc3f 100644 --- a/dapps/react-dapp-v2/package.json +++ b/dapps/react-dapp-v2/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@ethereumjs/tx": "^3.5.0", + "@polkadot/util-crypto": "^10.1.2", "@solana/web3.js": "^1.36.0", "@walletconnect/encoding": "^1.0.1", "@walletconnect/qrcode-modal": "^1.7.8", diff --git a/dapps/react-dapp-v2/public/assets/westend-logo.svg b/dapps/react-dapp-v2/public/assets/westend-logo.svg new file mode 100644 index 0000000..3e0599e --- /dev/null +++ b/dapps/react-dapp-v2/public/assets/westend-logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/dapps/react-dapp-v2/src/chains/polkadot.ts b/dapps/react-dapp-v2/src/chains/polkadot.ts index 22feda5..5619384 100644 --- a/dapps/react-dapp-v2/src/chains/polkadot.ts +++ b/dapps/react-dapp-v2/src/chains/polkadot.ts @@ -1,12 +1,29 @@ -import { JsonRpcRequest } from "@walletconnect/jsonrpc-utils"; +import { ChainsMap } from "caip-api"; import { BLOCKCHAIN_LOGO_BASE_URL } from "../constants"; - +import { JsonRpcRequest } from "@walletconnect/jsonrpc-utils"; import { NamespaceMetadata, ChainMetadata, ChainRequestRender, } from "../helpers"; +export const PolkadotChainData: ChainsMap = { + ["91b171bb158e2d3848fa23a9f1c25182"]: { + id: "polkadot:91b171bb158e2d3848fa23a9f1c25182", + name: "Polkadot Mainnet", + rpc: ["wss://rpc.polkadot.io"], + slip44: 0, + testnet: false, + }, + ["e143f23803ac50e8f6f8e62695d1ce9e"]: { + id: "polkadot:e143f23803ac50e8f6f8e62695d1ce9e", + name: "Polkadot Testnet (Westend)", + rpc: ["wss://westend-rpc.polkadot.io"], + slip44: 0, + testnet: false, + }, +}; + export const PolkadotMetadata: NamespaceMetadata = { // eslint-disable-next-line no-useless-computed-key ["91b171bb158e2d3848fa23a9f1c25182"]: { @@ -15,6 +32,10 @@ export const PolkadotMetadata: NamespaceMetadata = { "polkadot:91b171bb158e2d3848fa23a9f1c25182.png", rgb: "230, 1, 122", }, + ["e143f23803ac50e8f6f8e62695d1ce9e"]: { + logo: "/assets/westend-logo.svg", + rgb: "218, 104, 167", + }, }; export function getChainMetadata(chainId: string): ChainMetadata { diff --git a/dapps/react-dapp-v2/src/constants/default.ts b/dapps/react-dapp-v2/src/constants/default.ts index 3fb6a58..eaccfb5 100644 --- a/dapps/react-dapp-v2/src/constants/default.ts +++ b/dapps/react-dapp-v2/src/constants/default.ts @@ -8,6 +8,7 @@ export const DEFAULT_MAIN_CHAINS = [ "eip155:42220", "cosmos:cosmoshub-4", "solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ", + "polkadot:91b171bb158e2d3848fa23a9f1c25182", ]; export const DEFAULT_TEST_CHAINS = [ @@ -18,6 +19,7 @@ export const DEFAULT_TEST_CHAINS = [ "eip155:421611", "eip155:44787", "solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K", + "polkadot:e143f23803ac50e8f6f8e62695d1ce9e", ]; export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS]; @@ -71,5 +73,15 @@ export enum DEFAULT_SOLANA_METHODS { export enum DEFAULT_SOLANA_EVENTS {} +/** + * POLKADOT + */ +export enum DEFAULT_POLKADOT_METHODS { + POLKADOT_SIGN_TRANSACTION = "polkadot_signTransaction", + POLKADOT_SIGN_MESSAGE = "polkadot_signMessage", +} + +export enum DEFAULT_POLKADOT_EVENTS {} + export const DEFAULT_GITHUB_REPO_URL = "https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2"; diff --git a/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx b/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx index 3c701db..ab07fd5 100644 --- a/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx +++ b/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx @@ -7,6 +7,7 @@ import { useState, } from "react"; import { SolanaChainData } from "../chains/solana"; +import { PolkadotChainData } from "../chains/polkadot"; import { ChainNamespaces, getAllChainNamespaces } from "../helpers"; @@ -41,6 +42,8 @@ export function ChainDataContextProvider({ try { if (namespace === "solana") { chains = SolanaChainData; + } else if (namespace === "polkadot") { + chains = PolkadotChainData; } else { chains = await apiGetChainNamespace(namespace); } diff --git a/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx b/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx index 32cbb4d..ec57d02 100644 --- a/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx +++ b/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx @@ -29,8 +29,10 @@ import { DEFAULT_COSMOS_METHODS, DEFAULT_EIP155_METHODS, DEFAULT_SOLANA_METHODS, + DEFAULT_POLKADOT_METHODS, } from "../constants"; import { useChainData } from "./ChainDataContext"; +import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto"; /** * Types @@ -61,6 +63,10 @@ interface IContext { testSignMessage: TRpcRequestCallback; testSignTransaction: TRpcRequestCallback; }; + polkadotRpc: { + testSignMessage: TRpcRequestCallback; + testSignTransaction: TRpcRequestCallback; + }; rpcResult?: IFormattedRpcResponse | null; isRpcRequestPending: boolean; isTestnet: boolean; @@ -613,7 +619,77 @@ export function JsonRpcContextProvider({ } ), }; + // -------- POLKADOT RPC METHODS -------- + const polkadotRpc = { + testSignTransaction: _createJsonRpcRequestHandler( + async (chainId: string, address: string): Promise => { + // Below example is a scale encoded payload for system.remark("this is a test wallet-connect remark") transaction. + // decode url: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/extrinsics/decode/0x00019074686973206973206120746573742077616c6c65742d636f6e6e6563742072656d61726b + const transactionPayload = + "0x00019074686973206973206120746573742077616c6c65742d636f6e6e6563742072656d61726b05010000222400000d00000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3dc1f37ce7899cf20f63f5ea343f33e9e7b229c7e245049c2a7afc236861fc8b4"; + try { + const result = await client!.request<{ payload: string; signature: string }>({ + chainId, + topic: session!.topic, + request: { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION, + params: { + address, + transactionPayload, + }, + }, + }); + + // sr25519 signatures need to wait for WASM to load + await cryptoWaitReady(); + const { isValid: valid } = signatureVerify(transactionPayload, result.signature, address); + + return { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION, + address, + valid, + result: result.signature, + }; + } catch (error: any) { + throw new Error(error); + } + }, + ), + testSignMessage: _createJsonRpcRequestHandler( + async (chainId: string, address: string): Promise => { + + const message = `This is an example message to be signed - ${Date.now()}`; + + try { + const result = await client!.request<{ signature: string }>({ + chainId, + topic: session!.topic, + request: { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE, + params: { + address, + message, + }, + }, + }); + + // sr25519 signatures need to wait for WASM to load + await cryptoWaitReady(); + const { isValid: valid } = signatureVerify(message, result.signature, address); + + return { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE, + address, + valid, + result: result.signature, + }; + } catch (error: any) { + throw new Error(error); + } + }, + ), + }; return ( { @@ -28,6 +30,8 @@ export const getSupportedMethodsByNamespace = (namespace: string) => { return Object.values(DEFAULT_COSMOS_METHODS); case "solana": return Object.values(DEFAULT_SOLANA_METHODS); + case "polkadot": + return Object.values(DEFAULT_POLKADOT_METHODS); default: throw new Error(`No default methods for namespace: ${namespace}`); } @@ -41,6 +45,8 @@ export const getSupportedEventsByNamespace = (namespace: string) => { return Object.values(DEFAULT_COSMOS_EVENTS); case "solana": return Object.values(DEFAULT_SOLANA_EVENTS); + case "polkadot": + return Object.values(DEFAULT_POLKADOT_EVENTS); default: throw new Error(`No default events for namespace: ${namespace}`); } diff --git a/dapps/react-dapp-v2/src/pages/index.tsx b/dapps/react-dapp-v2/src/pages/index.tsx index aa4680e..b347933 100644 --- a/dapps/react-dapp-v2/src/pages/index.tsx +++ b/dapps/react-dapp-v2/src/pages/index.tsx @@ -11,6 +11,7 @@ import { DEFAULT_EIP155_METHODS, DEFAULT_MAIN_CHAINS, DEFAULT_SOLANA_METHODS, + DEFAULT_POLKADOT_METHODS, DEFAULT_TEST_CHAINS, } from "../constants"; import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers"; @@ -64,6 +65,7 @@ const Home: NextPage = () => { ethereumRpc, cosmosRpc, solanaRpc, + polkadotRpc, isRpcRequestPending, rpcResult, isTestnet, @@ -185,6 +187,26 @@ const Home: NextPage = () => { ]; }; + const getPolkadotActions = (): AccountAction[] => { + const onSignTransaction = async (chainId: string, address: string) => { + openRequestModal(); + await polkadotRpc.testSignTransaction(chainId, address); + }; + const onSignMessage = async (chainId: string, address: string) => { + openRequestModal(); + await polkadotRpc.testSignMessage(chainId, address); + }; + return [ + { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION, + callback: onSignTransaction, + }, + { + method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE, + callback: onSignMessage, + }, + ]; + }; const getBlockchainActions = (chainId: string) => { const [namespace] = chainId.split(":"); switch (namespace) { @@ -194,6 +216,8 @@ const Home: NextPage = () => { return getCosmosActions(); case "solana": return getSolanaActions(); + case "polkadot": + return getPolkadotActions(); default: break; } diff --git a/dapps/react-dapp-v2/yarn.lock b/dapps/react-dapp-v2/yarn.lock index d5726ae..65f605f 100644 --- a/dapps/react-dapp-v2/yarn.lock +++ b/dapps/react-dapp-v2/yarn.lock @@ -1966,6 +1966,16 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.4.tgz#0134c4cd5df39033347614ce5fc26af485ac9048" integrity sha512-5Pl1tdMJWLy4rvzU1ecx0nHWgDPqoYuvYoXE/5X0Clu9si/yOuBIj573F2kOTY7mu0LX2wgCJVSnyK0abHBxIw== +"@noble/hashes@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" + integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== + +"@noble/secp256k1@1.6.3": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" + integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2015,6 +2025,135 @@ schema-utils "^2.6.5" source-map "^0.7.3" +"@polkadot/networks@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.2.tgz#a42c93c5dd1f56b99ca50ec9d4e8076088148086" + integrity sha512-67ZPqdhLYDGNX1jMEa3+hujh9j30Dr9AdqgdjE8Z3GdWoEVRp9Zda3DXMnDIQlRBQ32pRZty7dFhIq61Bv/whQ== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/util" "10.1.2" + "@substrate/ss58-registry" "^1.25.0" + +"@polkadot/util-crypto@^10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.2.tgz#60779ad64e79542a06302ae7d9a2515482b563f4" + integrity sha512-lSgxSLF/XkksL8St3kyw8SCLic0JvyIf8uOezQZYyjSJKT3Gl8gGu9wCAKNAmboU0FgO8cnLO9AcAEkhCHvnyw== + dependencies: + "@babel/runtime" "^7.18.9" + "@noble/hashes" "1.1.2" + "@noble/secp256k1" "1.6.3" + "@polkadot/networks" "10.1.2" + "@polkadot/util" "10.1.2" + "@polkadot/wasm-crypto" "^6.3.1" + "@polkadot/x-bigint" "10.1.2" + "@polkadot/x-randomvalues" "10.1.2" + "@scure/base" "1.1.1" + ed2curve "^0.3.0" + tweetnacl "^1.0.3" + +"@polkadot/util@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.2.tgz#2eded0c159c16c4a3c48ff45c4ced05c62fb4660" + integrity sha512-gYSpJyrrw5gZWgTVu6PJ1PBUzi3GqwmaK6XRgi4deHmQRn9TEXTToGtHmleJWnaTCRW8Vvh5B5RNNV2C/+va4w== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-bigint" "10.1.2" + "@polkadot/x-global" "10.1.2" + "@polkadot/x-textdecoder" "10.1.2" + "@polkadot/x-textencoder" "10.1.2" + "@types/bn.js" "^5.1.0" + bn.js "^5.2.1" + +"@polkadot/wasm-bridge@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-6.3.1.tgz#439fa78e80947a7cb695443e1f64b25c30bb1487" + integrity sha512-1TYkHsb9AEFhU9uZj3biEnN2yKQNzdrwSjiTvfCYnt97pnEkKsZI6cku+YPZQv5w/x9CQa5Yua9e2DVVZSivGA== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/wasm-crypto-asmjs@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-6.3.1.tgz#e8f469c9cf4a7709c8131a96f857291953f3e30a" + integrity sha512-zbombRfA5v/mUWQQhgg2YwaxhRmxRIrvskw65x+lruax3b6xPBFDs7yplopiJU3r8h2pTgQvX/DUksvqz2TCRQ== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/wasm-crypto-init@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-init/-/wasm-crypto-init-6.3.1.tgz#b590220c53c94b9a54d5dc236d0cbe943db76706" + integrity sha512-9yaUBcu+snwjJLmPPGl3cyGRQ1afyFGm16qzTM0sgG/ZCfUlK4uk8KWZe+sBUKgoxb2oXY7Y4WklKgQI1YBdfw== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-bridge" "6.3.1" + "@polkadot/wasm-crypto-asmjs" "6.3.1" + "@polkadot/wasm-crypto-wasm" "6.3.1" + +"@polkadot/wasm-crypto-wasm@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-6.3.1.tgz#67f720e7f9694fef096abe9d60abbac02e032383" + integrity sha512-idSlzKGVzCfeCMRHsacRvqwojSaTadFxL/Dbls4z1thvfa3U9Ku0d2qVtlwg7Hj+tYWDiuP8Kygs+6bQwfs0XA== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-util" "6.3.1" + +"@polkadot/wasm-crypto@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-6.3.1.tgz#63f5798aca2b2ff0696f190e6862d9781d8f280c" + integrity sha512-OO8h0qeVkqp4xYZaRVl4iuWOEtq282pNBHDKb6SOJuI2g59eWGcKh4EQU9Me2VP6qzojIqptrkrVt7KQXC68gA== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-bridge" "6.3.1" + "@polkadot/wasm-crypto-asmjs" "6.3.1" + "@polkadot/wasm-crypto-init" "6.3.1" + "@polkadot/wasm-crypto-wasm" "6.3.1" + "@polkadot/wasm-util" "6.3.1" + +"@polkadot/wasm-util@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-util/-/wasm-util-6.3.1.tgz#439ebb68a436317af388ed6438b8f879df3afcda" + integrity sha512-12oAv5J7Yoc9m6jixrSaQCxpOkWOyzHx3DMC8qmLjRiwdBWxqLmImOVRVnFsbaxqSbhBIHRuJphVxWE+GZETDg== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/x-bigint@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.2.tgz#5070af6a3a5aa66eba85597837ce6eb44ad7dc02" + integrity sha512-TCwv3NjQdfLb7CBYR8EA5t0CrMfYx3IF4hKjctuplL+mDNI0VzNn4qVKW62AjouI8kMbn7VyBPfoBeuYX8Ixrw== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-global@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.2.tgz#66c2ceb6ef5043bc6bddd5e944f35e64e9d6a0a9" + integrity sha512-//r3NVLYdYQs0So0IK8Pa0pnL5pPi0geQWE6qjTtPD0oszuN9SUDqDlFQj3I3vqQOwgybbzBGNYRRinP8B2xUg== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/x-randomvalues@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.2.tgz#8a0f15eb0558f837dd10060ad808707fe8b64c05" + integrity sha512-KOu6iZWye9KD6qoahiqZ0alrT/5FSGL4XXLhVSg69xAqD6yG2oi2aKA6cZpDU19uZGqVneqsgpebDsrZ0nLUEg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-textdecoder@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.2.tgz#833627fc55b388483857de922b534b70fc349a0a" + integrity sha512-liMlSSKfLGTvcUPz1fMicH2HoKLgSjzxFYsbNfXJOe9GobQfSrAOcprM0j4gNJqN5EoZhze9Sf1rMTORQwomtg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-textencoder@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.2.tgz#a728a89d117456749211fcf520ca0e846654df89" + integrity sha512-bSMvesZ43Er6+jogt9IfwWN/E8bhkl4a9nNnpyS/vTh+j6n/DfDQrvYpKDpRIn7oJA6lfs/mL9Jo5jjJTngaxg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -2101,6 +2240,11 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27" integrity sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA== +"@scure/base@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -2279,6 +2423,11 @@ "@stablelib/random" "^1.0.1" "@stablelib/wipe" "^1.0.1" +"@substrate/ss58-registry@^1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.25.0.tgz#0fcd8c9c0e53963a88fbed41f2cbd8a1a5c74cde" + integrity sha512-LmCH4QJRdHaeLsLTPSgJaXguMoIW+Ig9fA9LRPpeya9HefVAJ7gZuUYinldv+QmX7evNm5CL0rspNUS8l1DvXg== + "@surma/rollup-plugin-off-main-thread@^1.1.1": version "1.4.2" resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58" @@ -5652,6 +5801,13 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +ed2curve@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ed2curve/-/ed2curve-0.3.0.tgz#322b575152a45305429d546b071823a93129a05d" + integrity sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ== + dependencies: + tweetnacl "1.x.x" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -12947,7 +13103,7 @@ tweetnacl-util@^0.15.0: resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== -tweetnacl@^1.0.0, tweetnacl@^1.0.3: +tweetnacl@1.x.x, tweetnacl@^1.0.0, tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== diff --git a/wallets/react-wallet-v2/package.json b/wallets/react-wallet-v2/package.json index 32daf27..f98fb45 100644 --- a/wallets/react-wallet-v2/package.json +++ b/wallets/react-wallet-v2/package.json @@ -13,6 +13,7 @@ "@cosmjs/proto-signing": "0.28.4", "@json-rpc-tools/utils": "1.7.6", "@nextui-org/react": "1.0.8-beta.5", + "@polkadot/keyring": "^10.1.2", "@solana/web3.js": "1.43.0", "@walletconnect/sign-client": "2.0.0-rc.1", "@walletconnect/utils": "2.0.0-rc.1", diff --git a/wallets/react-wallet-v2/public/chain-logos/polkadot.svg b/wallets/react-wallet-v2/public/chain-logos/polkadot.svg new file mode 100644 index 0000000..dc99ea8 --- /dev/null +++ b/wallets/react-wallet-v2/public/chain-logos/polkadot.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/wallets/react-wallet-v2/public/chain-logos/westend.svg b/wallets/react-wallet-v2/public/chain-logos/westend.svg new file mode 100644 index 0000000..3e0599e --- /dev/null +++ b/wallets/react-wallet-v2/public/chain-logos/westend.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/wallets/react-wallet-v2/src/components/Modal.tsx b/wallets/react-wallet-v2/src/components/Modal.tsx index e79f798..76d5c92 100644 --- a/wallets/react-wallet-v2/src/components/Modal.tsx +++ b/wallets/react-wallet-v2/src/components/Modal.tsx @@ -3,6 +3,7 @@ import SessionProposalModal from '@/views/SessionProposalModal' import SessionSendTransactionModal from '@/views/SessionSendTransactionModal' import SessionSignCosmosModal from '@/views/SessionSignCosmosModal' import SessionRequestModal from '@/views/SessionSignModal' +import SessionSignPolkadotModal from '@/views/SessionSignPolkadotModal' import SessionSignSolanaModal from '@/views/SessionSignSolanaModal' import SessionSignTypedDataModal from '@/views/SessionSignTypedDataModal' import SessionUnsuportedMethodModal from '@/views/SessionUnsuportedMethodModal' @@ -21,6 +22,7 @@ export default function Modal() { {view === 'SessionUnsuportedMethodModal' && } {view === 'SessionSignCosmosModal' && } {view === 'SessionSignSolanaModal' && } + {view === 'SessionSignPolkadotModal' && } ) } diff --git a/wallets/react-wallet-v2/src/data/PolkadotData.ts b/wallets/react-wallet-v2/src/data/PolkadotData.ts new file mode 100644 index 0000000..a9978a9 --- /dev/null +++ b/wallets/react-wallet-v2/src/data/PolkadotData.ts @@ -0,0 +1,35 @@ +/** + * Types + */ +export type TPolkadotChain = keyof typeof POLKADOT_MAINNET_CHAINS + +/** + * Chains + */ +export const POLKADOT_MAINNET_CHAINS = { + 'polkadot:91b171bb158e2d3848fa23a9f1c25182': { + chainId: '91b171bb158e2d3848fa23a9f1c25182', + name: 'Polkadot', + logo: '/chain-logos/polkadot.svg', + rgb: '230, 1, 122', + rpc: '' + } +} + +export const POLKADOT_TEST_CHAINS = { + 'polkadot:e143f23803ac50e8f6f8e62695d1ce9e': { + chainId: 'e143f23803ac50e8f6f8e62695d1ce9e', + name: 'Polkadot Westend', + logo: '/chain-logos/westend.svg', + rgb: '218, 104, 167', + rpc: '' + } +} + +/** + * Methods + */ +export const POLKADOT_SIGNING_METHODS = { + POLKADOT_SIGN_TRANSACTION: 'polkadot_signTransaction', + POLKADOT_SIGN_MESSAGE: 'polkadot_signMessage' +} diff --git a/wallets/react-wallet-v2/src/hooks/useInitialization.ts b/wallets/react-wallet-v2/src/hooks/useInitialization.ts index f57009d..79438e8 100644 --- a/wallets/react-wallet-v2/src/hooks/useInitialization.ts +++ b/wallets/react-wallet-v2/src/hooks/useInitialization.ts @@ -2,6 +2,7 @@ import SettingsStore from '@/store/SettingsStore' import { createOrRestoreCosmosWallet } from '@/utils/CosmosWalletUtil' import { createOrRestoreEIP155Wallet } from '@/utils/EIP155WalletUtil' import { createOrRestoreSolanaWallet } from '@/utils/SolanaWalletUtil' +import { createOrRestorePolkadotWallet } from '@/utils/PolkadotWalletUtil' import { createSignClient } from '@/utils/WalletConnectUtil' import { useCallback, useEffect, useState } from 'react' @@ -13,10 +14,12 @@ export default function useInitialization() { const { eip155Addresses } = createOrRestoreEIP155Wallet() const { cosmosAddresses } = await createOrRestoreCosmosWallet() const { solanaAddresses } = await createOrRestoreSolanaWallet() + const { polkadotAddresses } = await createOrRestorePolkadotWallet() SettingsStore.setEIP155Address(eip155Addresses[0]) SettingsStore.setCosmosAddress(cosmosAddresses[0]) SettingsStore.setSolanaAddress(solanaAddresses[0]) + SettingsStore.setPolkadotAddress(polkadotAddresses[0]) await createSignClient() diff --git a/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts b/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts index a1a6a65..c5cc0db 100644 --- a/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts +++ b/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts @@ -1,6 +1,7 @@ import { COSMOS_SIGNING_METHODS } from '@/data/COSMOSData' import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data' import { SOLANA_SIGNING_METHODS } from '@/data/SolanaData' +import { POLKADOT_SIGNING_METHODS } from '@/data/PolkadotData' import ModalStore from '@/store/ModalStore' import { signClient } from '@/utils/WalletConnectUtil' import { SignClientTypes } from '@walletconnect/types' @@ -48,7 +49,9 @@ export default function useWalletConnectEventsManager(initialized: boolean) { case SOLANA_SIGNING_METHODS.SOLANA_SIGN_MESSAGE: case SOLANA_SIGNING_METHODS.SOLANA_SIGN_TRANSACTION: return ModalStore.open('SessionSignSolanaModal', { requestEvent, requestSession }) - + case POLKADOT_SIGNING_METHODS.POLKADOT_SIGN_MESSAGE: + case POLKADOT_SIGNING_METHODS.POLKADOT_SIGN_TRANSACTION: + return ModalStore.open('SessionSignPolkadotModal', { requestEvent, requestSession }) default: return ModalStore.open('SessionUnsuportedMethodModal', { requestEvent, requestSession }) } diff --git a/wallets/react-wallet-v2/src/lib/PolkadotLib.ts b/wallets/react-wallet-v2/src/lib/PolkadotLib.ts new file mode 100644 index 0000000..b610582 --- /dev/null +++ b/wallets/react-wallet-v2/src/lib/PolkadotLib.ts @@ -0,0 +1,60 @@ +import { Keyring } from '@polkadot/keyring' +import { cryptoWaitReady, mnemonicGenerate } from '@polkadot/util-crypto' +import { KeyringPair } from '@polkadot/keyring/types' +import { stringToU8a, u8aToHex, hexToU8a } from '@polkadot/util' +import { HexString } from '@polkadot/util/types' + +/** + * Types + */ +interface IInitArguments { + mnemonic?: string +} + +/** + * Library + */ +export default class PolkadotLib { + keypair: KeyringPair + mnemonic: string + + constructor(keypair: KeyringPair, mnemonic: string) { + this.keypair = keypair + this.mnemonic = mnemonic + } + + static async init({ mnemonic }: IInitArguments) { + // wait till WASM is initialized, in case it is not initialized already (WASM is required for 'sr25519'). + await cryptoWaitReady() + + // create a keyring to load the account. + const keyring = new Keyring({ type: 'sr25519', ss58Format: 1 }) + + mnemonic = mnemonic || mnemonicGenerate() + const keypair = keyring.createFromUri(mnemonic) + + return new PolkadotLib(keypair, mnemonic) + } + + public getAddress() { + return this.keypair.address + } + + public getMnemonic() { + return this.mnemonic + } + + public async signMessage(message: string) { + // create the message, actual signature and verify + const messageU8a = stringToU8a(message) + const sigU8a = this.keypair.sign(messageU8a) + const signature = u8aToHex(sigU8a) + return { signature } + } + + public async signTransaction(payload: HexString) { + const sigU8a = this.keypair.sign(hexToU8a(payload), { withType: true }) + const signature = u8aToHex(sigU8a) + return { payload, signature } + } +} diff --git a/wallets/react-wallet-v2/src/pages/index.tsx b/wallets/react-wallet-v2/src/pages/index.tsx index 85748ed..921a66a 100644 --- a/wallets/react-wallet-v2/src/pages/index.tsx +++ b/wallets/react-wallet-v2/src/pages/index.tsx @@ -4,13 +4,16 @@ import PageHeader from '@/components/PageHeader' import { COSMOS_MAINNET_CHAINS } from '@/data/COSMOSData' import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data' import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData' +import { POLKADOT_MAINNET_CHAINS, POLKADOT_TEST_CHAINS } from '@/data/PolkadotData' import SettingsStore from '@/store/SettingsStore' import { Text } from '@nextui-org/react' import { Fragment } from 'react' import { useSnapshot } from 'valtio' export default function HomePage() { - const { testNets, eip155Address, cosmosAddress, solanaAddress } = useSnapshot(SettingsStore.state) + const { testNets, eip155Address, cosmosAddress, solanaAddress, polkadotAddress } = useSnapshot( + SettingsStore.state + ) return ( @@ -29,6 +32,9 @@ export default function HomePage() { {Object.values(SOLANA_MAINNET_CHAINS).map(({ name, logo, rgb }) => ( ))} + {Object.values(POLKADOT_MAINNET_CHAINS).map(({ name, logo, rgb }) => ( + + ))} {testNets ? ( @@ -41,6 +47,9 @@ export default function HomePage() { {Object.values(SOLANA_TEST_CHAINS).map(({ name, logo, rgb }) => ( ))} + {Object.values(POLKADOT_TEST_CHAINS).map(({ name, logo, rgb }) => ( + + ))} ) : null} diff --git a/wallets/react-wallet-v2/src/store/ModalStore.ts b/wallets/react-wallet-v2/src/store/ModalStore.ts index 4718ad7..52c776b 100644 --- a/wallets/react-wallet-v2/src/store/ModalStore.ts +++ b/wallets/react-wallet-v2/src/store/ModalStore.ts @@ -20,6 +20,7 @@ interface State { | 'SessionUnsuportedMethodModal' | 'SessionSignCosmosModal' | 'SessionSignSolanaModal' + | 'SessionSignPolkadotModal' data?: ModalData } diff --git a/wallets/react-wallet-v2/src/store/SettingsStore.ts b/wallets/react-wallet-v2/src/store/SettingsStore.ts index 5099004..a6ef677 100644 --- a/wallets/react-wallet-v2/src/store/SettingsStore.ts +++ b/wallets/react-wallet-v2/src/store/SettingsStore.ts @@ -9,6 +9,7 @@ interface State { eip155Address: string cosmosAddress: string solanaAddress: string + polkadotAddress: string } /** @@ -19,7 +20,8 @@ const state = proxy({ account: 0, eip155Address: '', cosmosAddress: '', - solanaAddress: '' + solanaAddress: '', + polkadotAddress: '' }) /** @@ -44,6 +46,10 @@ const SettingsStore = { state.solanaAddress = solanaAddress }, + setPolkadotAddress(polkadotAddress: string) { + state.polkadotAddress = polkadotAddress + }, + toggleTestNets() { state.testNets = !state.testNets if (state.testNets) { diff --git a/wallets/react-wallet-v2/src/utils/HelperUtil.ts b/wallets/react-wallet-v2/src/utils/HelperUtil.ts index c50477b..7ae71f8 100644 --- a/wallets/react-wallet-v2/src/utils/HelperUtil.ts +++ b/wallets/react-wallet-v2/src/utils/HelperUtil.ts @@ -94,6 +94,13 @@ export function isSolanaChain(chain: string) { return chain.includes('solana') } +/** + * Check if chain is part of POLKADOT standard + */ +export function isPolkadotChain(chain: string) { + return chain.includes('polkadot') +} + /** * Formats chainId to its name */ diff --git a/wallets/react-wallet-v2/src/utils/PolkadotRequestHandlerUtil.ts b/wallets/react-wallet-v2/src/utils/PolkadotRequestHandlerUtil.ts new file mode 100644 index 0000000..aafb791 --- /dev/null +++ b/wallets/react-wallet-v2/src/utils/PolkadotRequestHandlerUtil.ts @@ -0,0 +1,33 @@ +import { POLKADOT_SIGNING_METHODS } from '@/data/PolkadotData' +import { getWalletAddressFromParams } from '@/utils/HelperUtil' +import { polkadotAddresses, polkadotWallets } from '@/utils/PolkadotWalletUtil' +import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils' +import { SignClientTypes } from '@walletconnect/types' +import { getSdkError } from '@walletconnect/utils' + +export async function approvePolkadotRequest( + requestEvent: SignClientTypes.EventArguments['session_request'] +) { + const { params, id } = requestEvent + const { request } = params + const wallet = polkadotWallets[getWalletAddressFromParams(polkadotAddresses, params)] + + switch (request.method) { + case POLKADOT_SIGNING_METHODS.POLKADOT_SIGN_MESSAGE: + const signature = await wallet.signMessage(request.params.message) + return formatJsonRpcResult(id, signature) + + case POLKADOT_SIGNING_METHODS.POLKADOT_SIGN_TRANSACTION: + const signedTx = await wallet.signTransaction(request.params.transactionPayload) + return formatJsonRpcResult(id, signedTx) + + default: + throw new Error(getSdkError('INVALID_METHOD').message) + } +} + +export function rejectPolkadotRequest(request: SignClientTypes.EventArguments['session_request']) { + const { id } = request + + return formatJsonRpcError(id, getSdkError('USER_REJECTED_METHODS').message) +} diff --git a/wallets/react-wallet-v2/src/utils/PolkadotWalletUtil.ts b/wallets/react-wallet-v2/src/utils/PolkadotWalletUtil.ts new file mode 100644 index 0000000..2c8267f --- /dev/null +++ b/wallets/react-wallet-v2/src/utils/PolkadotWalletUtil.ts @@ -0,0 +1,43 @@ +import PolkadotLib from '@/lib/PolkadotLib' + +export let wallet1: PolkadotLib +export let wallet2: PolkadotLib +export let polkadotWallets: Record +export let polkadotAddresses: string[] + +let address1: string +let address2: string + +/** + * Utilities + */ +export async function createOrRestorePolkadotWallet() { + const mnemonic1 = localStorage.getItem('POLKADOT_MNEMONIC_1') + const mnemonic2 = localStorage.getItem('POLKADOT_MNEMONIC_2') + + if (mnemonic1 && mnemonic2) { + wallet1 = await PolkadotLib.init({ mnemonic: mnemonic1 }) + wallet2 = await PolkadotLib.init({ mnemonic: mnemonic2 }) + } else { + wallet1 = await PolkadotLib.init({}) + wallet2 = await PolkadotLib.init({}) + + // Don't store mnemonic in local storage in a production project! + localStorage.setItem('POLKADOT_MNEMONIC_1', wallet1.getMnemonic()) + localStorage.setItem('POLKADOT_MNEMONIC_2', wallet2.getMnemonic()) + } + + address1 = wallet1.getAddress() + address2 = wallet2.getAddress() + + polkadotWallets = { + [address1]: wallet1, + [address2]: wallet2 + } + polkadotAddresses = Object.keys(polkadotWallets) + + return { + polkadotWallets, + polkadotAddresses + } +} diff --git a/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx b/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx index c78edf5..fc16504 100644 --- a/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx +++ b/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx @@ -5,7 +5,8 @@ import SessionProposalChainCard from '@/components/SessionProposalChainCard' import ModalStore from '@/store/ModalStore' import { cosmosAddresses } from '@/utils/CosmosWalletUtil' import { eip155Addresses } from '@/utils/EIP155WalletUtil' -import { isCosmosChain, isEIP155Chain, isSolanaChain } from '@/utils/HelperUtil' +import { polkadotAddresses } from '@/utils/PolkadotWalletUtil' +import { isCosmosChain, isEIP155Chain, isSolanaChain, isPolkadotChain } from '@/utils/HelperUtil' import { solanaAddresses } from '@/utils/SolanaWalletUtil' import { signClient } from '@/utils/WalletConnectUtil' import { Button, Divider, Modal, Text } from '@nextui-org/react' @@ -112,6 +113,15 @@ export default function SessionProposalModal() { chain={chain} /> ) + } else if (isPolkadotChain(chain)) { + return ( + + ) } } diff --git a/wallets/react-wallet-v2/src/views/SessionSignPolkadotModal.tsx b/wallets/react-wallet-v2/src/views/SessionSignPolkadotModal.tsx new file mode 100644 index 0000000..b6ccd65 --- /dev/null +++ b/wallets/react-wallet-v2/src/views/SessionSignPolkadotModal.tsx @@ -0,0 +1,78 @@ +import ProjectInfoCard from '@/components/ProjectInfoCard' +import RequestDataCard from '@/components/RequestDataCard' +import RequesDetailsCard from '@/components/RequestDetalilsCard' +import RequestMethodCard from '@/components/RequestMethodCard' +import RequestModalContainer from '@/components/RequestModalContainer' +import ModalStore from '@/store/ModalStore' +import { approvePolkadotRequest, rejectPolkadotRequest } from '@/utils/PolkadotRequestHandlerUtil' +import { signClient } from '@/utils/WalletConnectUtil' +import { Button, Divider, Modal, Text } from '@nextui-org/react' +import { Fragment } from 'react' + +export default function SessionSignPolkadotModal() { + // Get request and wallet data from store + const requestEvent = ModalStore.state.data?.requestEvent + const requestSession = ModalStore.state.data?.requestSession + + // Ensure request and wallet are defined + if (!requestEvent || !requestSession) { + return Missing request data + } + + // Get required request data + const { topic, params } = requestEvent + const { request, chainId } = params + + // Handle approve action (logic varies based on request method) + async function onApprove() { + if (requestEvent) { + const response = await approvePolkadotRequest(requestEvent) + await signClient.respond({ + topic, + response + }) + ModalStore.close() + } + } + + // Handle reject action + async function onReject() { + if (requestEvent) { + const response = rejectPolkadotRequest(requestEvent) + await signClient.respond({ + topic, + response + }) + ModalStore.close() + } + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/wallets/react-wallet-v2/yarn.lock b/wallets/react-wallet-v2/yarn.lock index d4f2d8b..ac7e8f1 100644 --- a/wallets/react-wallet-v2/yarn.lock +++ b/wallets/react-wallet-v2/yarn.lock @@ -100,6 +100,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1106,11 +1113,21 @@ "@react-types/shared" "3.11.0" "@stitches/react" "1.2.7" +"@noble/hashes@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" + integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== + "@noble/hashes@^1": version "1.0.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== +"@noble/secp256k1@1.6.3": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" + integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1146,6 +1163,144 @@ enc-utils "^3.0.0" randombytes "^2.1.0" +"@polkadot/keyring@^10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-10.1.2.tgz#a7e70bd091d2ceb48e7fee005cc3dbe6cf8c8d32" + integrity sha512-b6hP3JFGYjsNNT3NO7I8fWRPqovgL4IvjvLttkfzpM6eM1zRRupqQ+Q50Jdl/3YUcr26PcxQcdRqJku4WyDABg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/util" "10.1.2" + "@polkadot/util-crypto" "10.1.2" + +"@polkadot/networks@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.2.tgz#a42c93c5dd1f56b99ca50ec9d4e8076088148086" + integrity sha512-67ZPqdhLYDGNX1jMEa3+hujh9j30Dr9AdqgdjE8Z3GdWoEVRp9Zda3DXMnDIQlRBQ32pRZty7dFhIq61Bv/whQ== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/util" "10.1.2" + "@substrate/ss58-registry" "^1.25.0" + +"@polkadot/util-crypto@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.2.tgz#60779ad64e79542a06302ae7d9a2515482b563f4" + integrity sha512-lSgxSLF/XkksL8St3kyw8SCLic0JvyIf8uOezQZYyjSJKT3Gl8gGu9wCAKNAmboU0FgO8cnLO9AcAEkhCHvnyw== + dependencies: + "@babel/runtime" "^7.18.9" + "@noble/hashes" "1.1.2" + "@noble/secp256k1" "1.6.3" + "@polkadot/networks" "10.1.2" + "@polkadot/util" "10.1.2" + "@polkadot/wasm-crypto" "^6.3.1" + "@polkadot/x-bigint" "10.1.2" + "@polkadot/x-randomvalues" "10.1.2" + "@scure/base" "1.1.1" + ed2curve "^0.3.0" + tweetnacl "^1.0.3" + +"@polkadot/util@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.2.tgz#2eded0c159c16c4a3c48ff45c4ced05c62fb4660" + integrity sha512-gYSpJyrrw5gZWgTVu6PJ1PBUzi3GqwmaK6XRgi4deHmQRn9TEXTToGtHmleJWnaTCRW8Vvh5B5RNNV2C/+va4w== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-bigint" "10.1.2" + "@polkadot/x-global" "10.1.2" + "@polkadot/x-textdecoder" "10.1.2" + "@polkadot/x-textencoder" "10.1.2" + "@types/bn.js" "^5.1.0" + bn.js "^5.2.1" + +"@polkadot/wasm-bridge@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-6.3.1.tgz#439fa78e80947a7cb695443e1f64b25c30bb1487" + integrity sha512-1TYkHsb9AEFhU9uZj3biEnN2yKQNzdrwSjiTvfCYnt97pnEkKsZI6cku+YPZQv5w/x9CQa5Yua9e2DVVZSivGA== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/wasm-crypto-asmjs@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-6.3.1.tgz#e8f469c9cf4a7709c8131a96f857291953f3e30a" + integrity sha512-zbombRfA5v/mUWQQhgg2YwaxhRmxRIrvskw65x+lruax3b6xPBFDs7yplopiJU3r8h2pTgQvX/DUksvqz2TCRQ== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/wasm-crypto-init@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-init/-/wasm-crypto-init-6.3.1.tgz#b590220c53c94b9a54d5dc236d0cbe943db76706" + integrity sha512-9yaUBcu+snwjJLmPPGl3cyGRQ1afyFGm16qzTM0sgG/ZCfUlK4uk8KWZe+sBUKgoxb2oXY7Y4WklKgQI1YBdfw== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-bridge" "6.3.1" + "@polkadot/wasm-crypto-asmjs" "6.3.1" + "@polkadot/wasm-crypto-wasm" "6.3.1" + +"@polkadot/wasm-crypto-wasm@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-6.3.1.tgz#67f720e7f9694fef096abe9d60abbac02e032383" + integrity sha512-idSlzKGVzCfeCMRHsacRvqwojSaTadFxL/Dbls4z1thvfa3U9Ku0d2qVtlwg7Hj+tYWDiuP8Kygs+6bQwfs0XA== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-util" "6.3.1" + +"@polkadot/wasm-crypto@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-6.3.1.tgz#63f5798aca2b2ff0696f190e6862d9781d8f280c" + integrity sha512-OO8h0qeVkqp4xYZaRVl4iuWOEtq282pNBHDKb6SOJuI2g59eWGcKh4EQU9Me2VP6qzojIqptrkrVt7KQXC68gA== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/wasm-bridge" "6.3.1" + "@polkadot/wasm-crypto-asmjs" "6.3.1" + "@polkadot/wasm-crypto-init" "6.3.1" + "@polkadot/wasm-crypto-wasm" "6.3.1" + "@polkadot/wasm-util" "6.3.1" + +"@polkadot/wasm-util@6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-util/-/wasm-util-6.3.1.tgz#439ebb68a436317af388ed6438b8f879df3afcda" + integrity sha512-12oAv5J7Yoc9m6jixrSaQCxpOkWOyzHx3DMC8qmLjRiwdBWxqLmImOVRVnFsbaxqSbhBIHRuJphVxWE+GZETDg== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/x-bigint@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.2.tgz#5070af6a3a5aa66eba85597837ce6eb44ad7dc02" + integrity sha512-TCwv3NjQdfLb7CBYR8EA5t0CrMfYx3IF4hKjctuplL+mDNI0VzNn4qVKW62AjouI8kMbn7VyBPfoBeuYX8Ixrw== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-global@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.2.tgz#66c2ceb6ef5043bc6bddd5e944f35e64e9d6a0a9" + integrity sha512-//r3NVLYdYQs0So0IK8Pa0pnL5pPi0geQWE6qjTtPD0oszuN9SUDqDlFQj3I3vqQOwgybbzBGNYRRinP8B2xUg== + dependencies: + "@babel/runtime" "^7.18.9" + +"@polkadot/x-randomvalues@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.2.tgz#8a0f15eb0558f837dd10060ad808707fe8b64c05" + integrity sha512-KOu6iZWye9KD6qoahiqZ0alrT/5FSGL4XXLhVSg69xAqD6yG2oi2aKA6cZpDU19uZGqVneqsgpebDsrZ0nLUEg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-textdecoder@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.2.tgz#833627fc55b388483857de922b534b70fc349a0a" + integrity sha512-liMlSSKfLGTvcUPz1fMicH2HoKLgSjzxFYsbNfXJOe9GobQfSrAOcprM0j4gNJqN5EoZhze9Sf1rMTORQwomtg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + +"@polkadot/x-textencoder@10.1.2": + version "10.1.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.2.tgz#a728a89d117456749211fcf520ca0e846654df89" + integrity sha512-bSMvesZ43Er6+jogt9IfwWN/E8bhkl4a9nNnpyS/vTh+j6n/DfDQrvYpKDpRIn7oJA6lfs/mL9Jo5jjJTngaxg== + dependencies: + "@babel/runtime" "^7.18.9" + "@polkadot/x-global" "10.1.2" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1635,6 +1790,11 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0" integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw== +"@scure/base@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + "@solana/buffer-layout-utils@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" @@ -1835,6 +1995,18 @@ resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.7.tgz#aea2403fac726db66d1740d29557e3910b1a1dc7" integrity sha512-6AxpUag7OW55ANzRnuy7R15FEyQeZ66fytVo3BBilFIU0mfo3t49CAMcEAL/A1SbhSj/FCdWkn/XrbjGBTJTzg== +"@substrate/ss58-registry@^1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.25.0.tgz#0fcd8c9c0e53963a88fbed41f2cbd8a1a5c74cde" + integrity sha512-LmCH4QJRdHaeLsLTPSgJaXguMoIW+Ig9fA9LRPpeya9HefVAJ7gZuUYinldv+QmX7evNm5CL0rspNUS8l1DvXg== + +"@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + "@types/connect@^3.4.33": version "3.4.35" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" @@ -2832,6 +3004,13 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +ed2curve@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ed2curve/-/ed2curve-0.3.0.tgz#322b575152a45305429d546b071823a93129a05d" + integrity sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ== + dependencies: + tweetnacl "1.x.x" + elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -5131,7 +5310,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tweetnacl@^1.0.0, tweetnacl@^1.0.3: +tweetnacl@1.x.x, tweetnacl@^1.0.0, tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==