Skip to content

Commit 09fedd1

Browse files
authoredDec 3, 2024
feat(clerk-js,elements,react,types): Support OKW Wallet Web3 provider and authentication strategy (#4696)
1 parent 235eaae commit 09fedd1

File tree

17 files changed

+141
-4
lines changed

17 files changed

+141
-4
lines changed
 

‎.changeset/dull-cooks-fry.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/elements': minor
4+
'@clerk/clerk-react': minor
5+
'@clerk/types': minor
6+
---
7+
8+
Support OKW Wallet Web3 provider and authentication strategy

‎packages/clerk-js/src/core/clerk.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
AuthenticateWithCoinbaseWalletParams,
1515
AuthenticateWithGoogleOneTapParams,
1616
AuthenticateWithMetamaskParams,
17+
AuthenticateWithOKXWalletParams,
1718
Clerk as ClerkInterface,
1819
ClerkAPIError,
1920
ClerkAuthenticateWithWeb3Params,
@@ -77,6 +78,7 @@ import {
7778
errorThrower,
7879
generateSignatureWithCoinbaseWallet,
7980
generateSignatureWithMetamask,
81+
generateSignatureWithOKXWallet,
8082
getClerkQueryParam,
8183
getWeb3Identifier,
8284
hasExternalAccountSignUpError,
@@ -1542,6 +1544,18 @@ export class Clerk implements ClerkInterface {
15421544
});
15431545
};
15441546

1547+
public authenticateWithOKXWallet = async (props: AuthenticateWithOKXWalletParams = {}): Promise<void> => {
1548+
if (__BUILD_DISABLE_RHC__) {
1549+
clerkUnsupportedEnvironmentWarning('OKX Wallet');
1550+
return;
1551+
}
1552+
1553+
await this.authenticateWithWeb3({
1554+
...props,
1555+
strategy: 'web3_okx_wallet_signature',
1556+
});
1557+
};
1558+
15451559
public authenticateWithWeb3 = async ({
15461560
redirectUrl,
15471561
signUpContinueUrl,
@@ -1561,7 +1575,11 @@ export class Clerk implements ClerkInterface {
15611575
const provider = strategy.replace('web3_', '').replace('_signature', '') as Web3Provider;
15621576
const identifier = await getWeb3Identifier({ provider });
15631577
const generateSignature =
1564-
provider === 'metamask' ? generateSignatureWithMetamask : generateSignatureWithCoinbaseWallet;
1578+
provider === 'metamask'
1579+
? generateSignatureWithMetamask
1580+
: provider === 'coinbase_wallet'
1581+
? generateSignatureWithCoinbaseWallet
1582+
: generateSignatureWithOKXWallet;
15651583

15661584
const navigate = (to: string) =>
15671585
customNavigate && typeof customNavigate === 'function' ? customNavigate(to) : this.navigate(to);

‎packages/clerk-js/src/core/resources/SignIn.ts

+19
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ import type {
4141
import {
4242
generateSignatureWithCoinbaseWallet,
4343
generateSignatureWithMetamask,
44+
generateSignatureWithOKXWallet,
4445
getCoinbaseWalletIdentifier,
4546
getMetamaskIdentifier,
47+
getOKXWalletIdentifier,
4648
windowNavigate,
4749
} from '../../utils';
4850
import {
@@ -123,6 +125,9 @@ export class SignIn extends BaseResource implements SignInResource {
123125
case 'web3_coinbase_wallet_signature':
124126
config = { web3WalletId: factor.web3WalletId } as Web3SignatureConfig;
125127
break;
128+
case 'web3_okx_wallet_signature':
129+
config = { web3WalletId: factor.web3WalletId } as Web3SignatureConfig;
130+
break;
126131
case 'reset_password_phone_code':
127132
config = { phoneNumberId: factor.phoneNumberId } as ResetPasswordPhoneCodeFactorConfig;
128133
break;
@@ -323,6 +328,20 @@ export class SignIn extends BaseResource implements SignInResource {
323328
});
324329
};
325330

331+
public authenticateWithOKXWallet = async (): Promise<SignInResource> => {
332+
if (__BUILD_DISABLE_RHC__) {
333+
clerkUnsupportedEnvironmentWarning('OKX Wallet');
334+
return this;
335+
}
336+
337+
const identifier = await getOKXWalletIdentifier();
338+
return this.authenticateWithWeb3({
339+
identifier,
340+
generateSignature: generateSignatureWithOKXWallet,
341+
strategy: 'web3_okx_wallet_signature',
342+
});
343+
};
344+
326345
public authenticateWithPasskey = async (params?: AuthenticateWithPasskeyParams): Promise<SignInResource> => {
327346
const { flow } = params || {};
328347

‎packages/clerk-js/src/core/resources/SignUp.ts

+22
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ import type {
2727
import {
2828
generateSignatureWithCoinbaseWallet,
2929
generateSignatureWithMetamask,
30+
generateSignatureWithOKXWallet,
3031
getCoinbaseWalletIdentifier,
3132
getMetamaskIdentifier,
33+
getOKXWalletIdentifier,
3234
windowNavigate,
3335
} from '../../utils';
3436
import { getCaptchaToken, retrieveCaptchaInfo } from '../../utils/captcha';
@@ -295,6 +297,26 @@ export class SignUp extends BaseResource implements SignUpResource {
295297
});
296298
};
297299

300+
public authenticateWithOKXWallet = async (
301+
params?: SignUpAuthenticateWithWeb3Params & {
302+
legalAccepted?: boolean;
303+
},
304+
): Promise<SignUpResource> => {
305+
if (__BUILD_DISABLE_RHC__) {
306+
clerkUnsupportedEnvironmentWarning('OKX Wallet');
307+
return this;
308+
}
309+
310+
const identifier = await getOKXWalletIdentifier();
311+
return this.authenticateWithWeb3({
312+
identifier,
313+
generateSignature: generateSignatureWithOKXWallet,
314+
unsafeMetadata: params?.unsafeMetadata,
315+
strategy: 'web3_okx_wallet_signature',
316+
legalAccepted: params?.legalAccepted,
317+
});
318+
};
319+
298320
public authenticateWithRedirect = async ({
299321
redirectUrl,
300322
redirectUrlComplete,

‎packages/clerk-js/src/ui/common/constants.ts

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ export const WEB3_PROVIDERS: Web3Providers = Object.freeze({
9696
id: 'coinbase_wallet',
9797
name: 'Coinbase Wallet',
9898
},
99+
okx_wallet: {
100+
id: 'okx_wallet',
101+
name: 'OKX Wallet',
102+
},
99103
});
100104

101105
export function getWeb3ProviderData(name: Web3Provider): Web3ProviderData | undefined | null {

‎packages/clerk-js/src/utils/injectedWeb3Providers.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { MetamaskWeb3Provider } from '@clerk/types';
1+
import type { MetamaskWeb3Provider, OKXWalletWeb3Provider } from '@clerk/types';
22

33
//https://eips.ethereum.org/EIPS/eip-6963
44

@@ -27,12 +27,13 @@ interface EIP6963ProviderDetail {
2727
}
2828

2929
type EIP6963AnnounceProviderEvent = CustomEvent<EIP6963ProviderDetail>;
30-
type InjectedWeb3Provider = MetamaskWeb3Provider;
30+
type InjectedWeb3Provider = MetamaskWeb3Provider | OKXWalletWeb3Provider;
3131

3232
class InjectedWeb3Providers {
3333
#providers: EIP6963ProviderDetail[] = [];
3434
#providerIdMap: Record<InjectedWeb3Provider, string> = {
3535
metamask: 'MetaMask',
36+
okx_wallet: 'OKX Wallet',
3637
} as const;
3738
static #instance: InjectedWeb3Providers | null = null;
3839

‎packages/clerk-js/src/utils/web3.ts

+8
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ export async function getCoinbaseWalletIdentifier(): Promise<string> {
4848
return await getWeb3Identifier({ provider: 'coinbase_wallet' });
4949
}
5050

51+
export async function getOKXWalletIdentifier(): Promise<string> {
52+
return await getWeb3Identifier({ provider: 'okx_wallet' });
53+
}
54+
5155
type GenerateSignatureParams = {
5256
identifier: string;
5357
nonce: string;
@@ -61,6 +65,10 @@ export async function generateSignatureWithCoinbaseWallet(params: GenerateSignat
6165
return await generateWeb3Signature({ ...params, provider: 'coinbase_wallet' });
6266
}
6367

68+
export async function generateSignatureWithOKXWallet(params: GenerateSignatureParams): Promise<string> {
69+
return await generateWeb3Signature({ ...params, provider: 'okx_wallet' });
70+
}
71+
6472
async function getEthereumProvider(provider: Web3Provider) {
6573
if (provider === 'coinbase_wallet') {
6674
const CoinbaseWalletSDK = await import('@coinbase/wallet-sdk').then(mod => mod.CoinbaseWalletSDK);

‎packages/elements/src/internals/machines/sign-in/start.machine.ts

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export const SignInStartMachine = setup({
3232
if (strategy === 'web3_coinbase_wallet_signature') {
3333
return parent.getSnapshot().context.clerk.client.signIn.authenticateWithCoinbaseWallet();
3434
}
35+
if (strategy === 'web3_okx_wallet_signature') {
36+
return parent.getSnapshot().context.clerk.client.signIn.authenticateWithOKXWallet();
37+
}
3538
throw new ClerkElementsRuntimeError(`Unsupported Web3 strategy: ${strategy}`);
3639
},
3740
),

‎packages/elements/src/internals/machines/sign-in/verification.machine.ts

+11
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,17 @@ export const SignInFirstFactorMachine = SignInVerificationMachine.provide({
495495

496496
break;
497497
}
498+
case 'web3_okx_wallet_signature': {
499+
const signature = fields.get('signature')?.value as string | undefined;
500+
assertIsDefined(signature, 'Web3 OKX Wallet signature');
501+
502+
attemptParams = {
503+
strategy,
504+
signature,
505+
} satisfies Web3Attempt;
506+
507+
break;
508+
}
498509
default:
499510
throw new ClerkElementsRuntimeError(`Invalid strategy: ${strategy}`);
500511
}

‎packages/elements/src/internals/machines/sign-up/start.machine.ts

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export const SignUpStartMachine = setup({
4444
if (strategy === 'web3_coinbase_wallet_signature') {
4545
return parent.getSnapshot().context.clerk.client.signUp.authenticateWithCoinbaseWallet();
4646
}
47+
if (strategy === 'web3_okx_wallet_signature') {
48+
return parent.getSnapshot().context.clerk.client.signUp.authenticateWithOKXWallet();
49+
}
4750
throw new ClerkElementsRuntimeError(`Unsupported Web3 strategy: ${strategy}`);
4851
},
4952
),

‎packages/elements/src/react/hooks/use-third-party-provider.hook.ts

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ export const useThirdPartyProvider = <
7171
return ref.send({ type: 'AUTHENTICATE.WEB3', strategy: 'web3_coinbase_wallet_signature' });
7272
}
7373

74+
if (provider === 'okx_wallet') {
75+
return ref.send({ type: 'AUTHENTICATE.WEB3', strategy: 'web3_okx_wallet_signature' });
76+
}
77+
7478
return ref.send({ type: 'AUTHENTICATE.OAUTH', strategy: `oauth_${provider}` });
7579
},
7680
[provider, isProviderEnabled, isSaml, ref],

‎packages/elements/src/react/utils/map-scope-to-strategy.ts

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ export function mapScopeToStrategy<T extends `provider:${Strategy}`>(scope: T):
1313
if (scope === 'provider:coinbase_wallet') {
1414
return 'web3_coinbase_wallet_signature';
1515
}
16+
if (scope === 'provider:okx_wallet') {
17+
return 'web3_okx_wallet_signature';
18+
}
1619

1720
if (scope === 'provider:saml') {
1821
return 'saml';

‎packages/react/src/isomorphicClerk.ts

+11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
AuthenticateWithCoinbaseWalletParams,
1010
AuthenticateWithGoogleOneTapParams,
1111
AuthenticateWithMetamaskParams,
12+
AuthenticateWithOKXWalletParams,
1213
Clerk,
1314
ClerkAuthenticateWithWeb3Params,
1415
ClerkOptions,
@@ -128,6 +129,7 @@ type IsomorphicLoadedClerk = Without<
128129
// TODO: Align Promise unknown
129130
authenticateWithMetamask: (params: AuthenticateWithMetamaskParams) => Promise<void>;
130131
authenticateWithCoinbaseWallet: (params: AuthenticateWithCoinbaseWalletParams) => Promise<void>;
132+
authenticateWithOKXWallet: (params: AuthenticateWithOKXWalletParams) => Promise<void>;
131133
authenticateWithWeb3: (params: ClerkAuthenticateWithWeb3Params) => Promise<void>;
132134
authenticateWithGoogleOneTap: (
133135
params: AuthenticateWithGoogleOneTapParams,
@@ -1139,6 +1141,15 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
11391141
}
11401142
};
11411143

1144+
authenticateWithOKXWallet = async (params: AuthenticateWithOKXWalletParams): Promise<void> => {
1145+
const callback = () => this.clerkjs?.authenticateWithOKXWallet(params);
1146+
if (this.clerkjs && this.#loaded) {
1147+
return callback() as Promise<void>;
1148+
} else {
1149+
this.premountMethodCalls.set('authenticateWithOKXWallet', callback);
1150+
}
1151+
};
1152+
11421153
authenticateWithWeb3 = async (params: ClerkAuthenticateWithWeb3Params): Promise<void> => {
11431154
const callback = () => this.clerkjs?.authenticateWithWeb3(params);
11441155
if (this.clerkjs && this.#loaded) {

‎packages/types/src/clerk.ts

+13
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,11 @@ export interface Clerk {
559559
*/
560560
authenticateWithCoinbaseWallet: (params?: AuthenticateWithCoinbaseWalletParams) => Promise<unknown>;
561561

562+
/**
563+
* Authenticates user using their OKX Wallet browser extension
564+
*/
565+
authenticateWithOKXWallet: (params?: AuthenticateWithOKXWalletParams) => Promise<unknown>;
566+
562567
/**
563568
* Authenticates user using their Web3 Wallet browser extension
564569
*/
@@ -1385,6 +1390,14 @@ export interface AuthenticateWithCoinbaseWalletParams {
13851390
legalAccepted?: boolean;
13861391
}
13871392

1393+
export interface AuthenticateWithOKXWalletParams {
1394+
customNavigate?: (to: string) => Promise<unknown>;
1395+
redirectUrl?: string;
1396+
signUpContinueUrl?: string;
1397+
unsafeMetadata?: SignUpUnsafeMetadata;
1398+
legalAccepted?: boolean;
1399+
}
1400+
13881401
export interface AuthenticateWithGoogleOneTapParams {
13891402
token: string;
13901403
legalAccepted?: boolean;

‎packages/types/src/signIn.ts

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ export interface SignInResource extends ClerkResource {
103103

104104
authenticateWithCoinbaseWallet: () => Promise<SignInResource>;
105105

106+
authenticateWithOKXWallet: () => Promise<SignInResource>;
107+
106108
authenticateWithPasskey: (params?: AuthenticateWithPasskeyParams) => Promise<SignInResource>;
107109

108110
createEmailLinkFlow: () => CreateEmailLinkFlowReturn<SignInStartEmailLinkFlowParams, SignInResource>;

‎packages/types/src/signUp.ts

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export interface SignUpResource extends ClerkResource {
9999

100100
authenticateWithMetamask: (params?: SignUpAuthenticateWithWeb3Params) => Promise<SignUpResource>;
101101
authenticateWithCoinbaseWallet: (params?: SignUpAuthenticateWithWeb3Params) => Promise<SignUpResource>;
102+
authenticateWithOKXWallet: (params?: SignUpAuthenticateWithWeb3Params) => Promise<SignUpResource>;
102103
}
103104

104105
export type SignUpStatus = 'missing_requirements' | 'complete' | 'abandoned';

‎packages/types/src/web3.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ export interface Web3ProviderData {
88

99
export type MetamaskWeb3Provider = 'metamask';
1010
export type CoinbaseWalletWeb3Provider = 'coinbase_wallet';
11+
export type OKXWalletWeb3Provider = 'okx_wallet';
1112

12-
export type Web3Provider = MetamaskWeb3Provider | CoinbaseWalletWeb3Provider;
13+
export type Web3Provider = MetamaskWeb3Provider | CoinbaseWalletWeb3Provider | OKXWalletWeb3Provider;
1314

1415
export const WEB3_PROVIDERS: Web3ProviderData[] = [
1516
{
@@ -22,6 +23,11 @@ export const WEB3_PROVIDERS: Web3ProviderData[] = [
2223
strategy: 'web3_coinbase_wallet_signature',
2324
name: 'Coinbase Wallet',
2425
},
26+
{
27+
provider: 'okx_wallet',
28+
strategy: 'web3_okx_wallet_signature',
29+
name: 'OKX Wallet',
30+
},
2531
];
2632

2733
interface getWeb3ProviderDataProps {

0 commit comments

Comments
 (0)