From ec9538861f90cb492988b3869435aa5442f6b4b2 Mon Sep 17 00:00:00 2001 From: Tolgahan Arikan Date: Thu, 19 Dec 2024 13:57:58 +0300 Subject: [PATCH 1/2] Add signTypedData support for waas connector --- examples/react/package.json | 4 +- examples/react/src/components/Connected.tsx | 97 +++++++++++++++++ packages/kit/package.json | 18 +-- .../wagmiConnectors/sequenceWaasConnector.ts | 48 +++++++- pnpm-lock.yaml | 103 +++++++++++++++--- 5 files changed, 239 insertions(+), 31 deletions(-) diff --git a/examples/react/package.json b/examples/react/package.json index 4fc4be42..648d6aa2 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -17,8 +17,8 @@ "@0xsequence/kit-wallet": "workspace:*", "@0xsequence/kit-example-shared-components": "workspace:*", "@tanstack/react-query": "^5.37.1", - "@0xsequence/network": "2.1.4", - "@0xsequence/waas": "2.1.4", + "@0xsequence/network": ">= 2.1.4", + "@0xsequence/waas": "0.0.0-20241218203257", "framer-motion": "^8.5.2", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/examples/react/src/components/Connected.tsx b/examples/react/src/components/Connected.tsx index 22c030a3..c2c9678c 100644 --- a/examples/react/src/components/Connected.tsx +++ b/examples/react/src/components/Connected.tsx @@ -74,6 +74,9 @@ export const Connected = () => { const [isSigningMessage, setIsSigningMessage] = React.useState(false) const [isMessageValid, setIsMessageValid] = React.useState() const [messageSig, setMessageSig] = React.useState() + const [isSigningTypedData, setIsSigningTypedData] = React.useState(false) + const [typedDataSig, setTypedDataSig] = React.useState() + const [isTypedDataValid, setIsTypedDataValid] = React.useState() const [lastTxnDataHash, setLastTxnDataHash] = React.useState() const [lastTxnDataHash2, setLastTxnDataHash2] = React.useState() @@ -192,6 +195,69 @@ export const Connected = () => { } }, [txnData, txnData2, txnData3]) + const domain = { + name: 'Sequence Example', + version: '1', + chainId: chainId, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + } as const + + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' } + ] + } as const + + const value = { + name: 'John Doe', + wallet: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + } as const + + const signTypedData = async () => { + if (!walletClient || !address || !publicClient) { + return + } + + setIsSigningTypedData(true) + + try { + const sig = await walletClient.signTypedData({ + account: address, + domain, + types, + primaryType: 'Person', + message: value + }) + + console.log('signature:', sig) + + const [account] = await walletClient.getAddresses() + + const isValid = await publicClient.verifyTypedData({ + address: account, + domain, + types, + primaryType: 'Person', + message: value, + signature: sig + }) + + console.log('isValid?', isValid) + + setTypedDataSig(sig) + setIsTypedDataValid(isValid) + setIsSigningTypedData(false) + } catch (e) { + setIsSigningTypedData(false) + if (e instanceof Error) { + console.error(e.cause) + } else { + console.error(e) + } + } + } + const signMessage = async () => { if (!walletClient || !publicClient) { return @@ -411,6 +477,7 @@ export const Connected = () => { setLastTxnDataHash2(undefined) setLastTxnDataHash3(undefined) setIsMessageValid(undefined) + setTypedDataSig(undefined) resetWriteContract() resetSendUnsponsoredTransaction() resetSendTransaction() @@ -503,6 +570,36 @@ export const Connected = () => { )} + + {typedDataSig && ( + + Signed typed data: + + {JSON.stringify( + { + domain, + types, + primaryType: 'Person', + message: value + }, + null, + 2 + )} + + Signature: + + {typedDataSig} + + + isValid: {isTypedDataValid?.toString()} + + + )} onClickAddFunds()} /> {(chainId === ChainId.ARBITRUM_NOVA || chainId === ChainId.ARBITRUM_SEPOLIA) && ( = 2.1.4", + "@0xsequence/auth": ">= 2.1.4", + "@0xsequence/core": ">= 2.1.4", "@0xsequence/design-system": "^1.7.8", "@0xsequence/ethauth": "^1.0.0", - "@0xsequence/indexer": "^2.1.4", - "@0xsequence/metadata": "^2.1.4", - "@0xsequence/network": "^2.1.4", - "@0xsequence/provider": "^2.1.4", - "@0xsequence/utils": "^2.1.4", - "@0xsequence/waas": "^2.1.4", + "@0xsequence/indexer": ">= 2.1.4", + "@0xsequence/metadata": ">= 2.1.4", + "@0xsequence/network": ">= 2.1.4", + "@0xsequence/provider": ">= 2.1.4", + "@0xsequence/utils": ">= 2.1.4", + "@0xsequence/waas": "0.0.0-20241218203257", "framer-motion": "^8.5.2", "uuid": "^10.0.0" }, diff --git a/packages/kit/src/connectors/wagmiConnectors/sequenceWaasConnector.ts b/packages/kit/src/connectors/wagmiConnectors/sequenceWaasConnector.ts index a78608dc..923e3d21 100644 --- a/packages/kit/src/connectors/wagmiConnectors/sequenceWaasConnector.ts +++ b/packages/kit/src/connectors/wagmiConnectors/sequenceWaasConnector.ts @@ -379,12 +379,7 @@ export class SequenceWaasProvider extends ethers.AbstractProvider implements EIP } } - if ( - method === 'eth_sign' || - method === 'eth_signTypedData' || - method === 'eth_signTypedData_v4' || - method === 'personal_sign' - ) { + if (method === 'eth_sign' || method === 'personal_sign') { if (this.requestConfirmationHandler && this.showConfirmation) { const id = uuidv4() const confirmation = await this.requestConfirmationHandler.confirmSignMessageRequest( @@ -422,6 +417,47 @@ export class SequenceWaasProvider extends ethers.AbstractProvider implements EIP return sig.data.signature } + if (method === 'eth_signTypedData' || method === 'eth_signTypedData_v4') { + if (this.requestConfirmationHandler && this.showConfirmation) { + const id = uuidv4() + const confirmation = await this.requestConfirmationHandler.confirmSignMessageRequest( + id, + JSON.stringify(JSON.parse(params?.[1]), null, 2), // Pretty print the typed data for confirmation + Number(this.currentNetwork.chainId) + ) + + if (!confirmation.confirmed) { + throw new UserRejectedRequestError(new Error('User rejected sign typed data request')) + } + + if (id !== confirmation.id) { + throw new UserRejectedRequestError(new Error('User confirmation ids do not match')) + } + } + + let sig + + try { + sig = await this.sequenceWaas.signTypedData({ + typedData: JSON.parse(params?.[1]), + network: Number(this.currentNetwork.chainId) + }) + } catch (error) { + if (isSessionInvalidOrNotFoundError(error)) { + await this.emit('error', error) + throw new ProviderDisconnectedError(new Error('Provider is not connected')) + } else { + const message = + typeof error === 'object' && error !== null && 'cause' in error + ? (String(error.cause) ?? 'Failed to sign typed data') + : 'Failed to sign typed data' + throw new InternalRpcError(new Error(message)) + } + } + + return sig.data.signature + } + return await this.jsonRpcProvider.send(method, params ?? []) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92c59aae..4bbbb145 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -175,11 +175,11 @@ importers: specifier: workspace:* version: link:../../packages/wallet '@0xsequence/network': - specifier: 2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/waas': - specifier: 2.1.4 - version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + specifier: 0.0.0-20241218203257 + version: 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@tanstack/react-query': specifier: ^5.37.1 version: 5.56.2(react@18.3.1) @@ -303,13 +303,13 @@ importers: packages/kit: dependencies: '@0xsequence/api': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4 '@0xsequence/auth': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/core': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/design-system': specifier: ^1.7.8 @@ -318,23 +318,23 @@ importers: specifier: ^1.0.0 version: 1.0.0(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/indexer': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.8 '@0xsequence/metadata': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4 '@0xsequence/network': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/provider': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/utils': - specifier: ^2.1.4 + specifier: '>= 2.1.4' version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@0xsequence/waas': - specifier: ^2.1.4 - version: 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + specifier: 0.0.0-20241218203257 + version: 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@react-oauth/google': specifier: '>= 0.11.1' version: 0.12.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -441,6 +441,9 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/abi@0.0.0-20241218203257': + resolution: {integrity: sha512-nNVJBh7j7bfi5YbFVEsPADZmKQXWQuzb3TbRiRVkqaGLnTVITRGHoHGDQq+VS090s/MnOl6k2342InqaiuTpoA==} + '@0xsequence/abi@2.1.3': resolution: {integrity: sha512-koeVkNUc/xm4yiAA1fC89r6oe6gQHwsVNkH6bTLicw1Wl9zWxqcv3GVtdFcmdablBumM4vAySHejxSEuM4S8TA==} @@ -460,6 +463,11 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/core@0.0.0-20241218203257': + resolution: {integrity: sha512-3h5nIu+HFronThusrfwFdKb1iJpAUjqCLvh/X7dLHQa/I9AJA2c9vOuhAxkuFQ0fAeY3vAHqnKf6ivq9f1ro+g==} + peerDependencies: + ethers: '>=6' + '@0xsequence/core@2.1.3': resolution: {integrity: sha512-GA5dl0tEPNywQpqKjhX9LiKJqFwc8WFnN6WD8QeFL57lQS6akMyZUHw9miCLeGTyzaMX0SiFTeQM/ztSbMEXdQ==} peerDependencies: @@ -487,6 +495,9 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/indexer@0.0.0-20241218203257': + resolution: {integrity: sha512-ndrcPkwunAVg8XM13w9KDnNtRuybh0rE0LDxgt89hpm0HToveCgp8Xs1c87EIvlj4eooU/Zkb0P0Ji3fcDD7cw==} + '@0xsequence/indexer@2.1.3': resolution: {integrity: sha512-49QUo3TgecAaqNNi0n0/1AGV6c1wfNAPsYOCFFhotNJvxgVYfEBseSPx/bFN1QCYDX2v5fdMQmsWJ1iiNFKdFw==} @@ -507,6 +518,11 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/network@0.0.0-20241218203257': + resolution: {integrity: sha512-8T3Aw5nUXHJvWR7fLzYZL5Y3ki7ki7zTDUDRCSk34gfWU8YM2tNrGsuvqOI4Y53yfC/Ho7a82IkFy1YY8DPTBg==} + peerDependencies: + ethers: '>=6' + '@0xsequence/network@2.1.3': resolution: {integrity: sha512-Ghtvyf1qqxzzQYOaSpKDV6c5DyfmUpSoD5Lr+u2zswTCGvgK1tSic94lzKbu2WOmUAKbsXiVDvawoFaQyaMnGQ==} peerDependencies: @@ -522,6 +538,11 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/relayer@0.0.0-20241218203257': + resolution: {integrity: sha512-oEcRZAdpM3cICZiaXQYYacpulFmwtMtuBUYTo7LFhMw/Ng97aBz9cKjIrwLxnCoMif61E6p6JZkzSUL94tC0wg==} + peerDependencies: + ethers: '>=6' + '@0xsequence/relayer@2.1.3': resolution: {integrity: sha512-8+WgbUT+ORvQwnHiegotHPLmxh/tl96VtUk0jDpEJX6iADaCpMshUqqvw4rUccV2G19jJQrhFP6DhEHTesLTBQ==} peerDependencies: @@ -547,6 +568,11 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/utils@0.0.0-20241218203257': + resolution: {integrity: sha512-LVOA3NTB28CW/NlXDheAB/Q+8abjtltW0JfUI79x33ZkbrHGBeUdiy2WZpWmxgFQSa0EyoHyyg1inxZH4Ch9XA==} + peerDependencies: + ethers: '>=6' + '@0xsequence/utils@2.1.3': resolution: {integrity: sha512-ZoHq6NpAbDFSXBkwaAxJYGQC8tSwKVSuwpyLQPdVkGWZhpkbifbML+RBEMe2x57biVj1c0EqF4K3xh0sYgQQEg==} peerDependencies: @@ -557,6 +583,11 @@ packages: peerDependencies: ethers: '>=6' + '@0xsequence/waas@0.0.0-20241218203257': + resolution: {integrity: sha512-a36KEGVNd3YE9W9xS+XntnAKsJVSdzajv6i4XDdB3Dwm4dXz/uZora0Nkv0Zczjv6n7gGGFOYbjwIF4bYdZ8WA==} + peerDependencies: + ethers: '>=6' + '@0xsequence/waas@2.1.4': resolution: {integrity: sha512-zQpTXMkr7uN9bZdKvrHE8X90tDXZkZ1YaJfwd0KpWQwz0S70QSzg2vFV6YQjt8y4YgXxG3vXRybL7abgLQ7/Mg==} peerDependencies: @@ -6457,6 +6488,7 @@ packages: sudo-prompt@9.2.1: resolution: {integrity: sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. superstruct@1.0.4: resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} @@ -7134,6 +7166,8 @@ snapshots: '@0xsequence/wallet': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/abi@0.0.0-20241218203257': {} + '@0xsequence/abi@2.1.3': {} '@0xsequence/abi@2.1.4': {} @@ -7169,6 +7203,12 @@ snapshots: '@0xsequence/wallet': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/core@0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@0xsequence/abi': 0.0.0-20241218203257 + '@0xsequence/utils': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/core@2.1.3(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@0xsequence/abi': 2.1.3 @@ -7217,6 +7257,8 @@ snapshots: '@0xsequence/utils': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/indexer@0.0.0-20241218203257': {} + '@0xsequence/indexer@2.1.3': {} '@0xsequence/indexer@2.1.4': {} @@ -7234,6 +7276,14 @@ snapshots: '@0xsequence/wallet': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/network@0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@0xsequence/core': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@0xsequence/indexer': 0.0.0-20241218203257 + '@0xsequence/relayer': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@0xsequence/utils': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/network@2.1.3(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@0xsequence/core': 2.1.3(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -7266,6 +7316,13 @@ snapshots: eventemitter2: 6.4.9 webextension-polyfill: 0.10.0 + '@0xsequence/relayer@0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@0xsequence/abi': 0.0.0-20241218203257 + '@0xsequence/core': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@0xsequence/utils': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/relayer@2.1.3(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@0xsequence/abi': 2.1.3 @@ -7300,6 +7357,11 @@ snapshots: '@0xsequence/core': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@0xsequence/utils@0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + js-base64: 3.7.7 + '@0xsequence/utils@2.1.3(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -7310,6 +7372,19 @@ snapshots: ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) js-base64: 3.7.7 + '@0xsequence/waas@0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@0xsequence/core': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@0xsequence/network': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@0xsequence/utils': 0.0.0-20241218203257(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@aws-sdk/client-cognito-identity-provider': 3.654.0 + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + idb: 7.1.1 + json-canonicalize: 1.0.6 + jwt-decode: 4.0.0 + transitivePeerDependencies: + - aws-crt + '@0xsequence/waas@2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@0xsequence/core': 2.1.4(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -8808,7 +8883,7 @@ snapshots: '@databeat/tracker@0.9.3': dependencies: - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.0 '@ecies/ciphers@0.2.2(@noble/ciphers@1.1.3)': dependencies: From 6704d0bc6d97efdfca75b9367c5d25055ea86d4a Mon Sep 17 00:00:00 2001 From: Tolgahan Arikan Date: Thu, 19 Dec 2024 13:59:40 +0300 Subject: [PATCH 2/2] Update example config for debug mode --- examples/react/src/config.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/react/src/config.ts b/examples/react/src/config.ts index 9349f0c2..03900639 100644 --- a/examples/react/src/config.ts +++ b/examples/react/src/config.ts @@ -82,13 +82,15 @@ export const config = }, walletConnect: { projectId: walletConnectProjectId - } + }, + isDev: isDebugMode }) : createConfig('universal', { ...kitConfig, appName: 'Kit Demo', chainIds: [ ChainId.ARBITRUM_NOVA, + ChainId.ARBITRUM, ChainId.ARBITRUM_SEPOLIA, ChainId.POLYGON, ChainId.IMMUTABLE_ZKEVM, @@ -110,10 +112,14 @@ export const getErc1155SaleContractConfig = (walletAddress: string) => ({ // contractAddress: '0xf0056139095224f4eec53c578ab4de1e227b9597', // collectionAddress: '0x92473261f2c26f2264429c451f70b0192f858795', wallet: walletAddress, - items: [{ - tokenId: '1', - quantity: '1' - }], - onSuccess: () => { console.log('success') }, + items: [ + { + tokenId: '1', + quantity: '1' + } + ], + onSuccess: () => { + console.log('success') + }, isDev: isDebugMode })