thirdweb 5.32.2 → 5.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/auth/constants.js +30 -0
- package/dist/cjs/auth/constants.js.map +1 -0
- package/dist/cjs/auth/core/verify-jwt.js +2 -2
- package/dist/cjs/auth/core/verify-jwt.js.map +1 -1
- package/dist/cjs/auth/core/verify-login-payload.js +2 -2
- package/dist/cjs/auth/core/verify-login-payload.js.map +1 -1
- package/dist/cjs/auth/is-erc6492-signature.js +25 -0
- package/dist/cjs/auth/is-erc6492-signature.js.map +1 -0
- package/dist/cjs/auth/parse-erc6492-signature.js +28 -0
- package/dist/cjs/auth/parse-erc6492-signature.js.map +1 -0
- package/dist/cjs/auth/serialize-erc6492-signature.js +36 -0
- package/dist/cjs/auth/serialize-erc6492-signature.js.map +1 -0
- package/dist/cjs/auth/types.js +3 -0
- package/dist/cjs/auth/types.js.map +1 -0
- package/dist/cjs/auth/verify-signature.js +196 -0
- package/dist/cjs/auth/verify-signature.js.map +1 -0
- package/dist/cjs/exports/auth.js +11 -5
- package/dist/cjs/exports/auth.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js +3 -0
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +0 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/WalletSelector.js +3 -0
- package/dist/cjs/react/web/ui/ConnectWallet/WalletSelector.js.map +1 -1
- package/dist/cjs/react/web/ui/MediaRenderer/MediaRenderer.js +19 -26
- package/dist/cjs/react/web/ui/MediaRenderer/MediaRenderer.js.map +1 -1
- package/dist/cjs/react/web/ui/MediaRenderer/ModelViewer.js +2 -2
- package/dist/cjs/react/web/ui/MediaRenderer/ModelViewer.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/coinbase/coinbaseWebSDK.js +2 -2
- package/dist/cjs/wallets/coinbase/coinbaseWebSDK.js.map +1 -1
- package/dist/cjs/wallets/injected/index.js +2 -2
- package/dist/cjs/wallets/injected/index.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +0 -1
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/esm/auth/constants.js +27 -0
- package/dist/esm/auth/constants.js.map +1 -0
- package/dist/esm/auth/core/verify-jwt.js +1 -1
- package/dist/esm/auth/core/verify-jwt.js.map +1 -1
- package/dist/esm/auth/core/verify-login-payload.js +1 -1
- package/dist/esm/auth/core/verify-login-payload.js.map +1 -1
- package/dist/esm/auth/is-erc6492-signature.js +22 -0
- package/dist/esm/auth/is-erc6492-signature.js.map +1 -0
- package/dist/esm/auth/parse-erc6492-signature.js +25 -0
- package/dist/esm/auth/parse-erc6492-signature.js.map +1 -0
- package/dist/esm/auth/serialize-erc6492-signature.js +33 -0
- package/dist/esm/auth/serialize-erc6492-signature.js.map +1 -0
- package/dist/esm/auth/types.js +2 -0
- package/dist/esm/auth/types.js.map +1 -0
- package/dist/esm/auth/verify-signature.js +191 -0
- package/dist/esm/auth/verify-signature.js.map +1 -0
- package/dist/esm/exports/auth.js +4 -1
- package/dist/esm/exports/auth.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js +3 -0
- package/dist/esm/react/web/ui/ConnectWallet/Modal/AllWalletsUI.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js +0 -1
- package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectModalContent.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/WalletSelector.js +3 -0
- package/dist/esm/react/web/ui/ConnectWallet/WalletSelector.js.map +1 -1
- package/dist/esm/react/web/ui/MediaRenderer/MediaRenderer.js +19 -26
- package/dist/esm/react/web/ui/MediaRenderer/MediaRenderer.js.map +1 -1
- package/dist/esm/react/web/ui/MediaRenderer/ModelViewer.js +2 -2
- package/dist/esm/react/web/ui/MediaRenderer/ModelViewer.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/coinbase/coinbaseWebSDK.js +2 -2
- package/dist/esm/wallets/coinbase/coinbaseWebSDK.js.map +1 -1
- package/dist/esm/wallets/injected/index.js +2 -2
- package/dist/esm/wallets/injected/index.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +0 -1
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/types/auth/constants.d.ts +20 -0
- package/dist/types/auth/constants.d.ts.map +1 -0
- package/dist/types/auth/is-erc6492-signature.d.ts +19 -0
- package/dist/types/auth/is-erc6492-signature.d.ts.map +1 -0
- package/dist/types/auth/parse-erc6492-signature.d.ts +24 -0
- package/dist/types/auth/parse-erc6492-signature.d.ts.map +1 -0
- package/dist/types/auth/serialize-erc6492-signature.d.ts +27 -0
- package/dist/types/auth/serialize-erc6492-signature.d.ts.map +1 -0
- package/dist/types/auth/types.d.ts +7 -0
- package/dist/types/auth/types.d.ts.map +1 -0
- package/dist/types/auth/verify-signature.d.ts +70 -0
- package/dist/types/auth/verify-signature.d.ts.map +1 -0
- package/dist/types/exports/auth.d.ts +5 -1
- package/dist/types/exports/auth.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Modal/AllWalletsUI.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectModalContent.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/WalletSelector.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/MediaRenderer.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/ModelViewer.d.ts +1 -1
- package/dist/types/react/web/ui/MediaRenderer/ModelViewer.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/types.d.ts +0 -2
- package/dist/types/react/web/ui/MediaRenderer/types.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/auth/constants.ts +30 -0
- package/src/auth/core/verify-jwt.ts +1 -1
- package/src/auth/core/verify-login-payload.ts +1 -1
- package/src/auth/is-erc6492-signature.test.ts +26 -0
- package/src/auth/is-erc6492-signature.ts +23 -0
- package/src/auth/parse-erc6492-signature.test.ts +30 -0
- package/src/auth/parse-erc6492-signature.ts +38 -0
- package/src/auth/serialize-erc6492-signature.test.ts +23 -0
- package/src/auth/serialize-erc6492-signature.ts +42 -0
- package/src/auth/types.ts +7 -0
- package/src/auth/verify-signature.test.ts +97 -0
- package/src/auth/verify-signature.ts +245 -0
- package/src/exports/auth.ts +9 -1
- package/src/react/web/ui/ConnectWallet/Modal/AllWalletsUI.tsx +3 -0
- package/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx +0 -1
- package/src/react/web/ui/ConnectWallet/WalletSelector.tsx +3 -1
- package/src/react/web/ui/MediaRenderer/MediaRenderer.tsx +151 -111
- package/src/react/web/ui/MediaRenderer/ModelViewer.tsx +5 -5
- package/src/react/web/ui/MediaRenderer/types.ts +0 -3
- package/src/version.ts +1 -1
- package/src/wallets/coinbase/coinbaseWebSDK.ts +2 -2
- package/src/wallets/injected/index.ts +2 -2
- package/src/wallets/smart/index.ts +0 -3
- package/src/wallets/smart/smart-wallet-integration.test.ts +1 -1
- package/dist/cjs/auth/verifySignature.js +0 -137
- package/dist/cjs/auth/verifySignature.js.map +0 -1
- package/dist/esm/auth/verifySignature.js +0 -132
- package/dist/esm/auth/verifySignature.js.map +0 -1
- package/dist/types/auth/verifySignature.d.ts +0 -53
- package/dist/types/auth/verifySignature.d.ts.map +0 -1
- package/src/auth/verifySignature.test.ts +0 -53
- package/src/auth/verifySignature.ts +0 -166
@@ -0,0 +1,30 @@
|
|
1
|
+
export const ERC_6492_MAGIC_VALUE =
|
2
|
+
"0x6492649264926492649264926492649264926492649264926492649264926492" as const;
|
3
|
+
|
4
|
+
// returns either 0x1 (valid) or 0x0 (invalid)
|
5
|
+
export const universalSignatureValidatorAbi = [
|
6
|
+
{
|
7
|
+
inputs: [
|
8
|
+
{
|
9
|
+
internalType: "address",
|
10
|
+
name: "_signer",
|
11
|
+
type: "address",
|
12
|
+
},
|
13
|
+
{
|
14
|
+
internalType: "bytes32",
|
15
|
+
name: "_hash",
|
16
|
+
type: "bytes32",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
internalType: "bytes",
|
20
|
+
name: "_signature",
|
21
|
+
type: "bytes",
|
22
|
+
},
|
23
|
+
],
|
24
|
+
stateMutability: "nonpayable",
|
25
|
+
type: "constructor",
|
26
|
+
},
|
27
|
+
] as const;
|
28
|
+
|
29
|
+
export const universalSignatureValidatorByteCode =
|
30
|
+
"0x60806040523480156200001157600080fd5b50604051620007003803806200070083398101604081905262000034916200056f565b6000620000438484846200004f565b9050806000526001601ff35b600080846001600160a01b0316803b806020016040519081016040528181526000908060200190933c90507f6492649264926492649264926492649264926492649264926492649264926492620000a68462000451565b036200021f57600060608085806020019051810190620000c79190620005ce565b8651929550909350915060000362000192576000836001600160a01b031683604051620000f5919062000643565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5050905080620001905760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b505b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90620001c4908b90869060040162000661565b602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020891906200069d565b6001600160e01b031916149450505050506200044a565b805115620002b157604051630b135d3f60e11b808252906001600160a01b03871690631626ba7e9062000259908890889060040162000661565b602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d91906200069d565b6001600160e01b031916149150506200044a565b8251604114620003195760405162461bcd60e51b815260206004820152603a6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e677468000000000000606482015260840162000187565b620003236200046b565b506020830151604080850151855186939260009185919081106200034b576200034b620006c9565b016020015160f81c9050601b81148015906200036b57508060ff16601c14155b15620003cf5760405162461bcd60e51b815260206004820152603b6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c75650000000000606482015260840162000187565b6040805160008152602081018083528a905260ff83169181019190915260608101849052608081018390526001600160a01b038a169060019060a0016020604051602081039080840390855afa1580156200042e573d6000803e3d6000fd5b505050602060405103516001600160a01b031614955050505050505b9392505050565b60006020825110156200046357600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b03811681146200049f57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004d5578181015183820152602001620004bb565b50506000910152565b600082601f830112620004f057600080fd5b81516001600160401b03808211156200050d576200050d620004a2565b604051601f8301601f19908116603f01168101908282118183101715620005385762000538620004a2565b816040528381528660208588010111156200055257600080fd5b62000565846020830160208901620004b8565b9695505050505050565b6000806000606084860312156200058557600080fd5b8351620005928162000489565b6020850151604086015191945092506001600160401b03811115620005b657600080fd5b620005c486828701620004de565b9150509250925092565b600080600060608486031215620005e457600080fd5b8351620005f18162000489565b60208501519093506001600160401b03808211156200060f57600080fd5b6200061d87838801620004de565b935060408601519150808211156200063457600080fd5b50620005c486828701620004de565b6000825162000657818460208701620004b8565b9190910192915050565b828152604060208201526000825180604084015262000688816060850160208701620004b8565b601f01601f1916919091016060019392505050565b600060208284031215620006b057600080fd5b81516001600160e01b0319811681146200044a57600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572";
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { deccodeJWT } from "../../utils/jwt/decode-jwt.js";
|
2
2
|
import type { JWTPayload } from "../../utils/jwt/types.js";
|
3
|
-
import { verifyEOASignature } from "../
|
3
|
+
import { verifyEOASignature } from "../verify-signature.js";
|
4
4
|
import type { AuthOptions } from "./types.js";
|
5
5
|
|
6
6
|
export type VerifyJWTParams = {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { getCachedChain } from "../../chains/utils.js";
|
2
|
-
import { verifySignature } from "../
|
2
|
+
import { verifySignature } from "../verify-signature.js";
|
3
3
|
import { DEFAULT_LOGIN_STATEMENT, DEFAULT_LOGIN_VERSION } from "./constants.js";
|
4
4
|
import { createLoginMessage } from "./create-login-message.js";
|
5
5
|
import type { AuthOptions, LoginPayload } from "./types.js";
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
2
|
+
import { ANVIL_PKEY_A } from "../../test/src/test-wallets.js";
|
3
|
+
import { signMessage } from "../utils/signatures/sign-message.js";
|
4
|
+
import { isErc6492Signature } from "./is-erc6492-signature.js";
|
5
|
+
import { serializeErc6492Signature } from "./serialize-erc6492-signature.js";
|
6
|
+
|
7
|
+
describe("default", () => {
|
8
|
+
const signature = signMessage({
|
9
|
+
message: "hello world",
|
10
|
+
privateKey: ANVIL_PKEY_A,
|
11
|
+
});
|
12
|
+
|
13
|
+
it("should return false for a standard signature", async () => {
|
14
|
+
expect(isErc6492Signature(signature)).toBe(false);
|
15
|
+
});
|
16
|
+
|
17
|
+
it("should return true for an ERC-6492 signature", () => {
|
18
|
+
const signatureWithMagicValue = serializeErc6492Signature({
|
19
|
+
address: "0xcafebabecafebabecafebabecafebabecafebabe",
|
20
|
+
data: "0xdeadbeef",
|
21
|
+
signature,
|
22
|
+
});
|
23
|
+
|
24
|
+
expect(isErc6492Signature(signatureWithMagicValue)).toBe(true);
|
25
|
+
});
|
26
|
+
});
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { sliceHex } from "viem";
|
2
|
+
import type { Hex } from "../utils/encoding/hex.js";
|
3
|
+
import { ERC_6492_MAGIC_VALUE } from "./constants.js";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @description Determines if a signature is compatible with [ERC6492](https://eips.ethereum.org/EIPS/eip-6492)
|
7
|
+
*
|
8
|
+
* @param {Hex} signature The signature to check for ERC6492 compatibility
|
9
|
+
*
|
10
|
+
* @returns {boolean} True if the signature is compatible with ERC6492, false otherwise
|
11
|
+
*
|
12
|
+
* @example
|
13
|
+
* ```ts
|
14
|
+
* import { isErc6492Signature } from 'thirdweb/auth';
|
15
|
+
*
|
16
|
+
* const isErc6492 = isErc6492Signature('0x1234567890123456789012345678901234567890');
|
17
|
+
* ```
|
18
|
+
*
|
19
|
+
* @auth
|
20
|
+
*/
|
21
|
+
export function isErc6492Signature(signature: Hex): boolean {
|
22
|
+
return sliceHex(signature, -32) === ERC_6492_MAGIC_VALUE;
|
23
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { describe } from "node:test";
|
2
|
+
import { expect, it } from "vitest";
|
3
|
+
import { ANVIL_PKEY_A } from "../../test/src/test-wallets.js";
|
4
|
+
import { signMessage } from "../utils/signatures/sign-message.js";
|
5
|
+
import { parseErc6492Signature } from "./parse-erc6492-signature.js";
|
6
|
+
|
7
|
+
describe("parseErc6492Signature", () => {
|
8
|
+
const signature = signMessage({
|
9
|
+
message: "hello world",
|
10
|
+
privateKey: ANVIL_PKEY_A,
|
11
|
+
});
|
12
|
+
|
13
|
+
it("should return original signature for non-ERC-6492 signature", () => {
|
14
|
+
expect(parseErc6492Signature(signature)).toEqual({ signature });
|
15
|
+
});
|
16
|
+
|
17
|
+
it("should return object with address, data, and signature for ERC-6492 signature", () => {
|
18
|
+
expect(
|
19
|
+
parseErc6492Signature(
|
20
|
+
"0x000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492",
|
21
|
+
),
|
22
|
+
).toMatchInlineSnapshot(`
|
23
|
+
{
|
24
|
+
"address": "0xCafEBAbECAFEbAbEcaFEbabECAfebAbEcAFEBaBe",
|
25
|
+
"data": "0xdeadbeef",
|
26
|
+
"signature": "0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b",
|
27
|
+
}
|
28
|
+
`);
|
29
|
+
});
|
30
|
+
});
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { decodeAbiParameters, isErc6492Signature } from "viem";
|
2
|
+
import type { Hex } from "../utils/encoding/hex.js";
|
3
|
+
import type { OneOf } from "../utils/type-utils.js";
|
4
|
+
import type { Erc6492Signature } from "./types.js";
|
5
|
+
|
6
|
+
export type ParseErc6492SignatureReturnType = OneOf<
|
7
|
+
Erc6492Signature | { signature: Hex }
|
8
|
+
>;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @description Parses a serialized ({@link Hex}) [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492) signature.
|
12
|
+
* If the signature is not in ERC-6492 format, the original signature is returned.
|
13
|
+
*
|
14
|
+
* @param {Hex} signature The signature to parse
|
15
|
+
*
|
16
|
+
* @returns {@link ParseErc6492SignatureReturnType} The parsed (or original) signature
|
17
|
+
*
|
18
|
+
* @example
|
19
|
+
* ```ts
|
20
|
+
* import { parseErc6492Signature } from 'thirdweb/auth';
|
21
|
+
*
|
22
|
+
* const parsedSignature = parseErc6492Signature('0x1234567890123456789012345678901234567890');
|
23
|
+
* ```
|
24
|
+
* @auth
|
25
|
+
*/
|
26
|
+
export function parseErc6492Signature(
|
27
|
+
signature: Hex,
|
28
|
+
): ParseErc6492SignatureReturnType {
|
29
|
+
if (!isErc6492Signature(signature)) {
|
30
|
+
return { signature };
|
31
|
+
}
|
32
|
+
|
33
|
+
const [address, data, originalSignature] = decodeAbiParameters(
|
34
|
+
[{ type: "address" }, { type: "bytes" }, { type: "bytes" }],
|
35
|
+
signature,
|
36
|
+
);
|
37
|
+
return { address: address, data, signature: originalSignature };
|
38
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
2
|
+
import { ANVIL_PKEY_A } from "../../test/src/test-wallets.js";
|
3
|
+
import { signMessage } from "../utils/signatures/sign-message.js";
|
4
|
+
import { serializeErc6492Signature } from "./serialize-erc6492-signature.js";
|
5
|
+
|
6
|
+
describe("serializeErc6492Signature", () => {
|
7
|
+
const signature = signMessage({
|
8
|
+
message: "hello world",
|
9
|
+
privateKey: ANVIL_PKEY_A,
|
10
|
+
});
|
11
|
+
|
12
|
+
it("should serialize a signature", () => {
|
13
|
+
expect(
|
14
|
+
serializeErc6492Signature({
|
15
|
+
address: "0xcafebabecafebabecafebabecafebabecafebabe",
|
16
|
+
data: "0xdeadbeef",
|
17
|
+
signature,
|
18
|
+
}),
|
19
|
+
).toMatchInlineSnapshot(
|
20
|
+
`"0x000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492"`,
|
21
|
+
);
|
22
|
+
});
|
23
|
+
});
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { encodeAbiParameters } from "../utils/abi/encodeAbiParameters.js";
|
2
|
+
import { concatHex } from "../utils/encoding/helpers/concat-hex.js";
|
3
|
+
import type { Hex } from "../utils/encoding/hex.js";
|
4
|
+
import { ERC_6492_MAGIC_VALUE } from "./constants.js";
|
5
|
+
import type { Erc6492Signature } from "./types.js";
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @description Serializes a signature for use with [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492). The signature must be generated by a signer for an [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) Account Factory account with counterfactual deployment addresses.
|
9
|
+
*
|
10
|
+
* @param {@link Erc6492Signature} signature The signature object to serialize into Hex format
|
11
|
+
* @param {string} signature.address The ERC-4337 Account Factory address
|
12
|
+
* @param {Hex} signature.data Account deployment calldata (if not deployed) for counterfactual verification
|
13
|
+
* @param {Hex} signature.signature The original signature
|
14
|
+
*
|
15
|
+
* @returns {Hex} The serialized signature
|
16
|
+
*
|
17
|
+
* @example
|
18
|
+
* ```ts
|
19
|
+
* import { serializeErc6492Signature } from 'thirdweb/auth';
|
20
|
+
*
|
21
|
+
* const serializedSignature = serializeErc6492Signature({
|
22
|
+
* address: '0x...',
|
23
|
+
* data: '0x...',
|
24
|
+
* signature: '0x...',
|
25
|
+
* });
|
26
|
+
* // 0x000000000000000000000000cafebabecafebabecafebabecafebabecafebabe000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492
|
27
|
+
* ```
|
28
|
+
* @auth
|
29
|
+
*/
|
30
|
+
export function serializeErc6492Signature({
|
31
|
+
address,
|
32
|
+
data,
|
33
|
+
signature,
|
34
|
+
}: Erc6492Signature): Hex {
|
35
|
+
return concatHex([
|
36
|
+
encodeAbiParameters(
|
37
|
+
[{ type: "address" }, { type: "bytes" }, { type: "bytes" }],
|
38
|
+
[address, data, signature],
|
39
|
+
),
|
40
|
+
ERC_6492_MAGIC_VALUE,
|
41
|
+
]);
|
42
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import { describe, expect, it, test } from "vitest";
|
2
|
+
import { FORKED_ETHEREUM_CHAIN } from "../../test/src/chains.js";
|
3
|
+
import { TEST_CLIENT } from "../../test/src/test-clients.js";
|
4
|
+
import { TEST_ACCOUNT_A } from "../../test/src/test-wallets.js";
|
5
|
+
import { mainnet } from "../chains/chain-definitions/ethereum.js";
|
6
|
+
import { sepolia } from "../chains/chain-definitions/sepolia.js";
|
7
|
+
import { verifyEOASignature, verifySignature } from "./verify-signature.js";
|
8
|
+
|
9
|
+
describe("verifyEOASignature", () => {
|
10
|
+
test("should return true for a valid signature", async () => {
|
11
|
+
const message = "Hello world!";
|
12
|
+
|
13
|
+
const signature = await TEST_ACCOUNT_A.signMessage({ message });
|
14
|
+
|
15
|
+
const result = await verifyEOASignature({
|
16
|
+
address: TEST_ACCOUNT_A.address,
|
17
|
+
message,
|
18
|
+
signature,
|
19
|
+
});
|
20
|
+
expect(result).toBe(true);
|
21
|
+
});
|
22
|
+
|
23
|
+
test("should return false for an invalid signature", async () => {
|
24
|
+
const options = {
|
25
|
+
message: "Hello, world!",
|
26
|
+
signature: "invalid",
|
27
|
+
address: "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
|
28
|
+
};
|
29
|
+
|
30
|
+
const result = await verifyEOASignature(options);
|
31
|
+
expect(result).toBe(false);
|
32
|
+
});
|
33
|
+
|
34
|
+
test("should return false for a different address", async () => {
|
35
|
+
const message = "Hello, world!";
|
36
|
+
const signature = await TEST_ACCOUNT_A.signMessage({ message });
|
37
|
+
|
38
|
+
const result = await verifyEOASignature({
|
39
|
+
address: "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
|
40
|
+
message,
|
41
|
+
signature,
|
42
|
+
});
|
43
|
+
expect(result).toBe(false);
|
44
|
+
});
|
45
|
+
|
46
|
+
test("should return false for a different message", async () => {
|
47
|
+
const message = "Hello, world!";
|
48
|
+
const signature = await TEST_ACCOUNT_A.signMessage({ message });
|
49
|
+
|
50
|
+
const result = await verifyEOASignature({
|
51
|
+
address: TEST_ACCOUNT_A.address,
|
52
|
+
message: "Hello, world",
|
53
|
+
signature,
|
54
|
+
});
|
55
|
+
expect(result).toBe(false);
|
56
|
+
});
|
57
|
+
});
|
58
|
+
|
59
|
+
describe("verifyContractWalletSignature", async () => {
|
60
|
+
it("should verify a valid signature", async () => {
|
61
|
+
expect(
|
62
|
+
await verifySignature({
|
63
|
+
address: "0x087517aA5153361d5b51B3a062D895443A28458b",
|
64
|
+
message: "Hakuna matata",
|
65
|
+
signature:
|
66
|
+
"0xbc667c1a98b1e5a347944dc6c62d2f8b9669aa05927b8dc39f500ce94fa75ce967a4903869d85eaeea40aaf29642c5152da56bad3bbe5026fb6b9249e234fa7d1b",
|
67
|
+
client: TEST_CLIENT,
|
68
|
+
chain: sepolia,
|
69
|
+
}),
|
70
|
+
).toBe(true);
|
71
|
+
});
|
72
|
+
|
73
|
+
test("should fail with an invalid signature", async () => {
|
74
|
+
expect(
|
75
|
+
await verifySignature({
|
76
|
+
address: "0x087517aA5153361d5b51B3a062D895443A28458b",
|
77
|
+
message: "Hakuna matata",
|
78
|
+
signature: "0xthirdweb",
|
79
|
+
chain: FORKED_ETHEREUM_CHAIN,
|
80
|
+
client: TEST_CLIENT,
|
81
|
+
}),
|
82
|
+
).toBe(false);
|
83
|
+
});
|
84
|
+
|
85
|
+
test("coinbase smart wallet verification", async () => {
|
86
|
+
expect(
|
87
|
+
await verifySignature({
|
88
|
+
address: "0x0b1e353DDcec71a94AC76ad6b7e75618E3A9CA81",
|
89
|
+
message: "Hakuna matata",
|
90
|
+
signature:
|
91
|
+
"0x0000000000000000000000000ba5ed0c6aa8c49038f819e587e2633c4a9f428a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000e43ffba36f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000406e033e8bd44ba8d7fe309535da2dcf38bbf6aa0144937adf2b4851e506a8afe10e8d53896201a64512e72414c2aa3b626b18b2a9931d5dd09d57e147662af7530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000001dadf7562d6e80ba80295ba01e7a749623df8e204ca7109bcda8fbfee67497a1f084be7126e8f59a3b4ffd09dd14804b203bc29c82d6f0e987396f3b825b2549c0000000000000000000000000000000000000000000000000000000000000025f198086b2db17256731bc456673b96bcef23f51d1fbacdd7c4379ef65465572f1900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226c66723934623767656d7249515936623061523253456d417445356a337162716d335a454765625f563338222c226f726967696e223a2268747470733a2f2f6b6579732e636f696e626173652e636f6d222c2263726f73734f726967696e223a66616c73657d000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492",
|
92
|
+
client: TEST_CLIENT,
|
93
|
+
chain: mainnet, // The CBSW factory was deployed more recently than our fork, it's only an eth_call so live mainnet is okay
|
94
|
+
}),
|
95
|
+
).toBe(true);
|
96
|
+
});
|
97
|
+
});
|
@@ -0,0 +1,245 @@
|
|
1
|
+
import { equalBytes } from "@noble/curves/abstract/utils";
|
2
|
+
import {
|
3
|
+
type Signature,
|
4
|
+
encodeDeployData,
|
5
|
+
recoverAddress,
|
6
|
+
serializeSignature,
|
7
|
+
} from "viem";
|
8
|
+
import type { Chain } from "../chains/types.js";
|
9
|
+
import type { ThirdwebClient } from "../client/client.js";
|
10
|
+
import { getContract } from "../contract/contract.js";
|
11
|
+
import { eth_call } from "../rpc/actions/eth_call.js";
|
12
|
+
import { getRpcClient } from "../rpc/rpc.js";
|
13
|
+
import { fromBytes } from "../utils/encoding/from-bytes.js";
|
14
|
+
import { type Hex, isHex } from "../utils/encoding/hex.js";
|
15
|
+
import { toBytes } from "../utils/encoding/to-bytes.js";
|
16
|
+
import { hashMessage } from "../utils/hashing/hashMessage.js";
|
17
|
+
import type { Prettify } from "../utils/type-utils.js";
|
18
|
+
import { DEFAULT_ACCOUNT_FACTORY } from "../wallets/smart/lib/constants.js";
|
19
|
+
import {
|
20
|
+
universalSignatureValidatorAbi,
|
21
|
+
universalSignatureValidatorByteCode,
|
22
|
+
} from "./constants.js";
|
23
|
+
import { isErc6492Signature } from "./is-erc6492-signature.js";
|
24
|
+
import { serializeErc6492Signature } from "./serialize-erc6492-signature.js";
|
25
|
+
|
26
|
+
export type VerifyEOASignatureParams = {
|
27
|
+
message: string;
|
28
|
+
signature: string | Uint8Array | Signature;
|
29
|
+
address: string;
|
30
|
+
};
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Verifies the signature of a message using an Ethereum account's EOA (Externally Owned Account).
|
34
|
+
* @param options - The options for verifying the signature.
|
35
|
+
* @returns A boolean indicating whether the signature is valid.
|
36
|
+
* @throws An error if the signature is invalid.
|
37
|
+
* @example
|
38
|
+
* ```ts
|
39
|
+
* import { verifyEOASignature } from 'thirdweb/auth';
|
40
|
+
*
|
41
|
+
* const isValid = await verifyEOASignature({
|
42
|
+
* message: '0x1234567890123456789012345678901234567890',
|
43
|
+
* signature: '0x1234567890123456789012345678901234567890',
|
44
|
+
* address: '0x1234567890123456789012345678901234567890',
|
45
|
+
* });
|
46
|
+
* ```
|
47
|
+
* @auth
|
48
|
+
*/
|
49
|
+
export async function verifyEOASignature(options: VerifyEOASignatureParams) {
|
50
|
+
const messageHash = hashMessage(options.message);
|
51
|
+
|
52
|
+
if (!isHex(options.signature)) {
|
53
|
+
return false;
|
54
|
+
}
|
55
|
+
|
56
|
+
const recoveredAddress = await recoverAddress({
|
57
|
+
hash: messageHash,
|
58
|
+
signature: options.signature,
|
59
|
+
});
|
60
|
+
|
61
|
+
if (recoveredAddress.toLowerCase() === options.address.toLowerCase()) {
|
62
|
+
return true;
|
63
|
+
}
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
|
67
|
+
export type VerifyContractWalletSignatureParams = Prettify<
|
68
|
+
VerifyEOASignatureParams & {
|
69
|
+
chain: Chain;
|
70
|
+
client: ThirdwebClient;
|
71
|
+
accountFactory?: {
|
72
|
+
address: string;
|
73
|
+
verificationCalldata: Hex;
|
74
|
+
};
|
75
|
+
}
|
76
|
+
>;
|
77
|
+
|
78
|
+
/**
|
79
|
+
* @description Verifies a contract wallet signature using [ERC-6942](https://eips.ethereum.org/EIPS/eip-6942) Signature Validation for Predeploy Contracts.
|
80
|
+
* This function will validate signatures for both deployed and undeployed smart accounts of all signature types.
|
81
|
+
*
|
82
|
+
* @param {@link VerifyContractWalletSignatureParams} options - The parameters for verifying the signature.
|
83
|
+
* @param {string} options.address The address of the contract wallet to verify the signature for. This can be an undeployed coutnerfactual address.
|
84
|
+
* @param {string} options.message The message that was signed
|
85
|
+
* @param {string} options.signature The signature to verify.
|
86
|
+
* @param {Chain} options.chain The chain to verify the signature on. Make sure this was the chain your signature was generated for, even if your smart account exists on multiple chains.
|
87
|
+
* @param {ThirdwebClient} options.client The Thirdweb client to use for necessary RPC requests.
|
88
|
+
* @param {Object} [options.accountFactory] A custom account factory to use for signature verification. This is only necessary if the account is not yet deployed AND the signature was not pre-wrapped for ERC-6492 validation. Most wallets that do not automatically deploy smart accounts prior to signatures will wrap the signature for you.
|
89
|
+
* @param {string} [options.accountFactory.address] The account factory address from which the smart account was or will be deployed.
|
90
|
+
* @param {Hex} [options.accountFactory.verificationCalldata] The account factory verification calldata for predeploy verification. See [EIP-6942](https://eips.ethereum.org/EIPS/eip-6942) for more information.
|
91
|
+
*
|
92
|
+
* @returns A boolean indicating whether the signature is valid.
|
93
|
+
*
|
94
|
+
* @example
|
95
|
+
* ```ts
|
96
|
+
* import { verifyContractWalletSignature } from 'thirdweb/auth';
|
97
|
+
*
|
98
|
+
* const isValid = await verifyContractWalletSignature({
|
99
|
+
* message: '0x..',
|
100
|
+
* signature: '0x..',
|
101
|
+
* address: '0x...',
|
102
|
+
* chain: ...,
|
103
|
+
* client: ...,
|
104
|
+
* });
|
105
|
+
* ```
|
106
|
+
* @auth
|
107
|
+
*/
|
108
|
+
export async function verifyContractWalletSignature({
|
109
|
+
signature,
|
110
|
+
message,
|
111
|
+
address,
|
112
|
+
chain,
|
113
|
+
client,
|
114
|
+
accountFactory,
|
115
|
+
}: VerifyContractWalletSignatureParams) {
|
116
|
+
console.log("verifyContractWalletSignature");
|
117
|
+
const messageHash = hashMessage(message);
|
118
|
+
|
119
|
+
const signatureHex = (() => {
|
120
|
+
if (isHex(signature)) return signature;
|
121
|
+
if (typeof signature === "object" && "r" in signature && "s" in signature)
|
122
|
+
return serializeSignature(signature);
|
123
|
+
if (signature instanceof Uint8Array) return fromBytes(signature, "hex");
|
124
|
+
// We should never hit this but TS doesn't know that
|
125
|
+
throw new Error(
|
126
|
+
`Invalid signature type for signature ${signature}: ${typeof signature}`,
|
127
|
+
);
|
128
|
+
})();
|
129
|
+
|
130
|
+
const accountContract = getContract({
|
131
|
+
address,
|
132
|
+
chain,
|
133
|
+
client,
|
134
|
+
});
|
135
|
+
|
136
|
+
const wrappedSignature = await (async () => {
|
137
|
+
// If this sigature was already wrapped for ERC-6492, carry on
|
138
|
+
if (isErc6492Signature(signatureHex)) return signatureHex;
|
139
|
+
|
140
|
+
// If the contract is already deployed, return the original signature
|
141
|
+
const { isContractDeployed } = await import(
|
142
|
+
"../utils/bytecode/is-contract-deployed.js"
|
143
|
+
);
|
144
|
+
const isDeployed = await isContractDeployed(accountContract);
|
145
|
+
if (!isDeployed) return signatureHex;
|
146
|
+
|
147
|
+
// Otherwise, serialize the signature for ERC-6492 validation
|
148
|
+
return serializeErc6492Signature({
|
149
|
+
address: accountFactory?.address ?? DEFAULT_ACCOUNT_FACTORY,
|
150
|
+
data: accountFactory?.verificationCalldata ?? "0x",
|
151
|
+
signature: signatureHex,
|
152
|
+
});
|
153
|
+
})();
|
154
|
+
|
155
|
+
const verificationData = encodeDeployData({
|
156
|
+
abi: universalSignatureValidatorAbi,
|
157
|
+
args: [address, messageHash, wrappedSignature],
|
158
|
+
bytecode: universalSignatureValidatorByteCode,
|
159
|
+
});
|
160
|
+
|
161
|
+
const rpcRequest = getRpcClient({
|
162
|
+
chain,
|
163
|
+
client,
|
164
|
+
});
|
165
|
+
|
166
|
+
try {
|
167
|
+
const result = await eth_call(rpcRequest, {
|
168
|
+
data: verificationData,
|
169
|
+
});
|
170
|
+
|
171
|
+
const hexResult = isHex(result) ? toBytes(result) : result;
|
172
|
+
return equalBytes(hexResult, toBytes("0x1"));
|
173
|
+
} catch (error) {
|
174
|
+
console.log("error", error);
|
175
|
+
// TODO: Improve overall RPC error handling so we can tell if this was an actual verification failure or some other error
|
176
|
+
// Verification failed somehow
|
177
|
+
return false;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
export type VerifySignatureParams = Prettify<
|
182
|
+
VerifyEOASignatureParams & Partial<VerifyContractWalletSignatureParams>
|
183
|
+
>;
|
184
|
+
|
185
|
+
/**
|
186
|
+
* Verifies the signature based on the provided options.
|
187
|
+
* Handles smart contract wallet signatures and EOA signatures.
|
188
|
+
* **IMPORTANT: in order to check smart contract signatures, a chain and client must be provided. Or, you can use the `verifyContractWalletSignature` function directly if all signatures will be from smart accounts.**
|
189
|
+
* @see verifyContractWalletSignature
|
190
|
+
* @param options - The options for signature verification.
|
191
|
+
* @returns A boolean indicating whether the signature is valid or not.
|
192
|
+
* @example
|
193
|
+
* ```ts
|
194
|
+
* import { verifySignature } from 'thirdweb/auth';
|
195
|
+
*
|
196
|
+
* const isValid = await verifySignature({
|
197
|
+
* message: 'Your message to sign',
|
198
|
+
* signature: '0x91db0222ec371a8c18d3b187a6d2e77789bffca1b96826ef6b8708e0d4a66c80312fc3ae95b8fbc147265abf539bb6f360152be61a0e1411d7f5771a599e769a1c',
|
199
|
+
* address: '0xda9C7A86AeE76701FC1c23ae548e8E93Ba3e42A5',
|
200
|
+
* client: thirdwebClient,
|
201
|
+
* chain: chain
|
202
|
+
* });
|
203
|
+
* ```
|
204
|
+
* @auth
|
205
|
+
*/
|
206
|
+
let warningTriggered = false;
|
207
|
+
export async function verifySignature(options: VerifySignatureParams) {
|
208
|
+
try {
|
209
|
+
const isValidEOASig = await verifyEOASignature(options);
|
210
|
+
if (isValidEOASig) {
|
211
|
+
return true;
|
212
|
+
}
|
213
|
+
} catch {
|
214
|
+
// no-op, we skip to contract signature check
|
215
|
+
}
|
216
|
+
if (isVerifyContractWalletSignatureParams(options)) {
|
217
|
+
try {
|
218
|
+
return await verifyContractWalletSignature(options);
|
219
|
+
} catch {
|
220
|
+
// no-op we skip to return false
|
221
|
+
}
|
222
|
+
} else if (!warningTriggered) {
|
223
|
+
// We only trigger this warning once
|
224
|
+
warningTriggered = true;
|
225
|
+
console.error(`
|
226
|
+
Failed to verify EOA signature and no chain or client provided.
|
227
|
+
|
228
|
+
If you mean to use a smart account, please provide a chain and client.
|
229
|
+
For more information on how to setup a smart account with Auth, see https://portal.thirdweb.com/connect/auth
|
230
|
+
`);
|
231
|
+
}
|
232
|
+
// if we reach here, we have no way to verify the signature
|
233
|
+
return false;
|
234
|
+
}
|
235
|
+
|
236
|
+
function isVerifyContractWalletSignatureParams(
|
237
|
+
options: VerifySignatureParams,
|
238
|
+
): options is VerifyContractWalletSignatureParams {
|
239
|
+
return (
|
240
|
+
"chain" in options &&
|
241
|
+
options.chain !== undefined &&
|
242
|
+
"client" in options &&
|
243
|
+
options.client !== undefined
|
244
|
+
);
|
245
|
+
}
|
package/src/exports/auth.ts
CHANGED
@@ -5,7 +5,15 @@ export {
|
|
5
5
|
type VerifyEOASignatureParams,
|
6
6
|
verifyContractWalletSignature,
|
7
7
|
type VerifyContractWalletSignatureParams,
|
8
|
-
} from "../auth/
|
8
|
+
} from "../auth/verify-signature.js";
|
9
|
+
|
10
|
+
export { isErc6492Signature } from "../auth/is-erc6492-signature.js";
|
11
|
+
export { serializeErc6492Signature } from "../auth/serialize-erc6492-signature.js";
|
12
|
+
export {
|
13
|
+
parseErc6492Signature,
|
14
|
+
type ParseErc6492SignatureReturnType,
|
15
|
+
} from "../auth/parse-erc6492-signature.js";
|
16
|
+
export type { Erc6492Signature } from "../auth/types.js";
|
9
17
|
|
10
18
|
export { createAuth } from "../auth/auth.js";
|
11
19
|
export type {
|
@@ -10,6 +10,7 @@ import { createWallet } from "../../../../../wallets/create-wallet.js";
|
|
10
10
|
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
|
11
11
|
import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
|
12
12
|
import { iconSize, spacing } from "../../../../core/design-system/index.js";
|
13
|
+
import { useSetSelectionData } from "../../../providers/wallet-ui-states-provider.js";
|
13
14
|
import { sortWallets } from "../../../utils/sortWallets.js";
|
14
15
|
import { Spacer } from "../../components/Spacer.js";
|
15
16
|
import { Spinner } from "../../components/Spinner.js";
|
@@ -35,6 +36,7 @@ function AllWalletsUI(props: {
|
|
35
36
|
connectLocale: ConnectLocale;
|
36
37
|
}) {
|
37
38
|
const { itemsToShow, lastItemRef } = useShowMore<HTMLLIElement>(10, 10);
|
39
|
+
const setSelectionData = useSetSelectionData();
|
38
40
|
|
39
41
|
const walletList = useMemo(() => {
|
40
42
|
return walletInfos.filter((wallet) => {
|
@@ -141,6 +143,7 @@ function AllWalletsUI(props: {
|
|
141
143
|
selectWallet={() => {
|
142
144
|
const wallet = createWallet(walletInfo.id);
|
143
145
|
props.onSelect(wallet);
|
146
|
+
setSelectionData({});
|
144
147
|
}}
|
145
148
|
client={props.client}
|
146
149
|
recommendedWallets={props.recommendedWallets}
|
@@ -129,7 +129,6 @@ export const ConnectModalContent = (props: {
|
|
129
129
|
title={props.meta.title || props.connectLocale.defaultModalTitle}
|
130
130
|
wallets={props.wallets}
|
131
131
|
selectWallet={(newWallet) => {
|
132
|
-
setSelectionData({});
|
133
132
|
if (newWallet.onConnectRequested) {
|
134
133
|
newWallet
|
135
134
|
.onConnectRequested()
|