diff --git a/.changeset/violet-games-dream.md b/.changeset/violet-games-dream.md new file mode 100644 index 00000000000..706c92062b7 --- /dev/null +++ b/.changeset/violet-games-dream.md @@ -0,0 +1,7 @@ +--- +"@clerk/clerk-js": minor +"@clerk/backend": minor +"@clerk/types": minor +--- + +Use EIP-4361 message spec for Web3 wallets sign in signature requests diff --git a/packages/backend/src/api/resources/JSON.ts b/packages/backend/src/api/resources/JSON.ts index 7b769f4495e..a37308485a8 100644 --- a/packages/backend/src/api/resources/JSON.ts +++ b/packages/backend/src/api/resources/JSON.ts @@ -326,6 +326,7 @@ export interface VerificationJSON extends ClerkResourceJSON { verified_at_client?: string; external_verification_redirect_url?: string | null; nonce?: string | null; + message?: string | null; } export interface Web3WalletJSON extends ClerkResourceJSON { diff --git a/packages/backend/src/api/resources/Verification.ts b/packages/backend/src/api/resources/Verification.ts index 35cbfb4d369..451556ecd22 100644 --- a/packages/backend/src/api/resources/Verification.ts +++ b/packages/backend/src/api/resources/Verification.ts @@ -10,6 +10,7 @@ export class Verification { readonly attempts: number | null = null, readonly expireAt: number | null = null, readonly nonce: string | null = null, + readonly message: string | null = null, ) {} static fromJSON(data: VerificationJSON): Verification { diff --git a/packages/clerk-js/src/core/resources/SignIn.ts b/packages/clerk-js/src/core/resources/SignIn.ts index e9124638042..50ce5f39e4c 100644 --- a/packages/clerk-js/src/core/resources/SignIn.ts +++ b/packages/clerk-js/src/core/resources/SignIn.ts @@ -250,14 +250,14 @@ export class SignIn extends BaseResource implements SignInResource { await this.prepareFirstFactor(web3FirstFactor); - const { nonce } = this.firstFactorVerification; - if (!nonce) { + const { message } = this.firstFactorVerification; + if (!message) { clerkVerifyWeb3WalletCalledBeforeCreate('SignIn'); } let signature: string; try { - signature = await generateSignature({ identifier, nonce, provider }); + signature = await generateSignature({ identifier, nonce: message, provider }); } catch (err) { // There is a chance that as a user when you try to setup and use the Coinbase Wallet with an existing // Passkey in order to authenticate, the initial generate signature request to be rejected. For this @@ -266,7 +266,7 @@ export class SignIn extends BaseResource implements SignInResource { // error code 4001 means the user rejected the request // Reference: https://docs.cdp.coinbase.com/wallet-sdk/docs/errors if (provider === 'coinbase_wallet' && err.code === 4001) { - signature = await generateSignature({ identifier, nonce, provider }); + signature = await generateSignature({ identifier, nonce: message, provider }); } else { throw err; } diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index 5f239241227..bf7a06932ea 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -203,14 +203,14 @@ export class SignUp extends BaseResource implements SignUpResource { await this.create({ web3Wallet, unsafeMetadata }); await this.prepareWeb3WalletVerification({ strategy }); - const { nonce } = this.verifications.web3Wallet; - if (!nonce) { + const { message } = this.verifications.web3Wallet; + if (!message) { clerkVerifyWeb3WalletCalledBeforeCreate('SignUp'); } let signature: string; try { - signature = await generateSignature({ identifier, nonce, provider }); + signature = await generateSignature({ identifier, nonce: message, provider }); } catch (err) { // There is a chance that as a first time visitor when you try to setup and use the // Coinbase Wallet from scratch in order to authenticate, the initial generate @@ -220,7 +220,7 @@ export class SignUp extends BaseResource implements SignUpResource { // error code 4001 means the user rejected the request // Reference: https://docs.cdp.coinbase.com/wallet-sdk/docs/errors if (provider === 'coinbase_wallet' && err.code === 4001) { - signature = await generateSignature({ identifier, nonce, provider }); + signature = await generateSignature({ identifier, nonce: message, provider }); } else { throw err; } diff --git a/packages/clerk-js/src/core/resources/Verification.ts b/packages/clerk-js/src/core/resources/Verification.ts index e301098065e..8028c4c1778 100644 --- a/packages/clerk-js/src/core/resources/Verification.ts +++ b/packages/clerk-js/src/core/resources/Verification.ts @@ -23,6 +23,7 @@ export class Verification extends BaseResource implements VerificationResource { status: VerificationStatus | null = null; strategy: string | null = null; nonce: string | null = null; + message: string | null = null; externalVerificationRedirectURL: URL | null = null; attempts: number | null = null; expireAt: Date | null = null; @@ -44,6 +45,7 @@ export class Verification extends BaseResource implements VerificationResource { this.verifiedAtClient = data.verified_at_client; this.strategy = data.strategy; this.nonce = data.nonce || null; + this.message = data.message || null; if (data.external_verification_redirect_url) { this.externalVerificationRedirectURL = new URL(data.external_verification_redirect_url); } else { diff --git a/packages/clerk-js/src/ui/components/UserProfile/Web3Form.tsx b/packages/clerk-js/src/ui/components/UserProfile/Web3Form.tsx index 3f0178c420e..0f607a67916 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/Web3Form.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/Web3Form.tsx @@ -31,8 +31,8 @@ export const AddWeb3WalletActionMenu = withCardStateProvider(() => { let web3Wallet = await user.createWeb3Wallet({ web3Wallet: identifier }); web3Wallet = await web3Wallet.prepareVerification({ strategy }); - const nonce = web3Wallet.verification.nonce as string; - const signature = await generateWeb3Signature({ identifier, nonce, provider }); + const message = web3Wallet.verification.message as string; + const signature = await generateWeb3Signature({ identifier, nonce: message, provider }); await web3Wallet.attemptVerification({ signature }); card.setIdle(); } catch (err) { diff --git a/packages/clerk-js/src/utils/web3.ts b/packages/clerk-js/src/utils/web3.ts index a3cd9626c12..018c0901f6f 100644 --- a/packages/clerk-js/src/utils/web3.ts +++ b/packages/clerk-js/src/utils/web3.ts @@ -21,9 +21,7 @@ export async function getWeb3Identifier(params: GetWeb3IdentifierParams): Promis return (identifiers && identifiers[0]) || ''; } -type GenerateWeb3SignatureParams = { - identifier: string; - nonce: string; +type GenerateWeb3SignatureParams = GenerateSignatureParams & { provider: Web3Provider; }; @@ -55,15 +53,12 @@ type GenerateSignatureParams = { nonce: string; }; -export async function generateSignatureWithMetamask({ identifier, nonce }: GenerateSignatureParams): Promise { - return await generateWeb3Signature({ identifier, nonce, provider: 'metamask' }); +export async function generateSignatureWithMetamask(params: GenerateSignatureParams): Promise { + return await generateWeb3Signature({ ...params, provider: 'metamask' }); } -export async function generateSignatureWithCoinbaseWallet({ - identifier, - nonce, -}: GenerateSignatureParams): Promise { - return await generateWeb3Signature({ identifier, nonce, provider: 'coinbase_wallet' }); +export async function generateSignatureWithCoinbaseWallet(params: GenerateSignatureParams): Promise { + return await generateWeb3Signature({ ...params, provider: 'coinbase_wallet' }); } async function getEthereumProvider(provider: Web3Provider) { diff --git a/packages/types/src/json.ts b/packages/types/src/json.ts index 88a07f00770..01f1a8b0c22 100644 --- a/packages/types/src/json.ts +++ b/packages/types/src/json.ts @@ -261,6 +261,7 @@ export interface VerificationJSON extends ClerkResourceJSON { verified_at_client: string; strategy: string; nonce?: string; + message?: string; external_verification_redirect_url?: string; attempts: number; expire_at: number; diff --git a/packages/types/src/verification.ts b/packages/types/src/verification.ts index 9fa41444e98..5b53a5801cb 100644 --- a/packages/types/src/verification.ts +++ b/packages/types/src/verification.ts @@ -8,6 +8,7 @@ export interface VerificationResource extends ClerkResource { expireAt: Date | null; externalVerificationRedirectURL: URL | null; nonce: string | null; + message: string | null; status: VerificationStatus | null; strategy: string | null; verifiedAtClient: string | null;