Skip to content

Commit ddeaeeb

Browse files
committed
Initial on-ramp implementation
1 parent 58b5442 commit ddeaeeb

File tree

4 files changed

+112
-15
lines changed

4 files changed

+112
-15
lines changed

examples/with-sdk-js/src/app/page.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,34 @@ export default function AuthPage() {
16741674
</div>
16751675
</div>
16761676
)}
1677+
{authState === AuthState.Authenticated && (
1678+
<div>
1679+
<h2>On Ramp</h2>
1680+
<div className="flex flex-wrap gap-2 mb-2">
1681+
<button
1682+
data-testid="sign-sol-transaction"
1683+
onClick={() =>
1684+
turnkey.handleCoinbaseOnRamp({
1685+
onrampProvider: "FIAT_ON_RAMP_PROVIDER_COINBASE",
1686+
walletAddress: activeWalletAccount?.address!,
1687+
cryptoCurrencyCode: "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH",
1688+
network: "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM",
1689+
paymentMethod: "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL",
1690+
sandboxMode: true,
1691+
})
1692+
}
1693+
style={{
1694+
backgroundColor: "pink",
1695+
borderRadius: "8px",
1696+
padding: "8px 16px",
1697+
color: "black",
1698+
}}
1699+
>
1700+
Coinbase On Ramp
1701+
</button>
1702+
</div>
1703+
</div>
1704+
)}
16771705
<div>
16781706
<h2>Otp Methods</h2>
16791707
<div>

packages/react-wallet-kit/src/providers/client/Provider.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ import type {
151151
HandleAddPasskeyParams,
152152
HandleAddPhoneNumberParams,
153153
HandleAppleOauthParams,
154+
HandleCoinbaseOnRampParams,
154155
HandleConnectExternalWalletParams,
155156
HandleDiscordOauthParams,
156157
HandleExportPrivateKeyParams,
@@ -5129,6 +5130,47 @@ export const ClientProvider: React.FC<ClientProviderProps> = ({
51295130
[pushPage, masterConfig, client, session, user],
51305131
);
51315132

5133+
const handleCoinbaseOnRamp = useCallback(
5134+
async (params: HandleCoinbaseOnRampParams): Promise<void> => {
5135+
const { successPageDuration = 2000 } = params || {};
5136+
const organizationId = params?.organizationId || session?.organizationId;
5137+
if (!organizationId) {
5138+
throw new TurnkeyError(
5139+
"A session or passed in organization ID is required.",
5140+
TurnkeyErrorCodes.INVALID_REQUEST,
5141+
);
5142+
}
5143+
5144+
if (!client)
5145+
throw new TurnkeyError(
5146+
"Client is not initialized.",
5147+
TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED,
5148+
);
5149+
5150+
const res = await client.httpClient.initFiatOnRamp(params);
5151+
const { onRampUrl } = res;
5152+
5153+
// Popup flow (can abstract this into a utility)
5154+
const width = popupWidth;
5155+
const height = popupHeight;
5156+
const left = window.screenX + (window.innerWidth - width) / 2;
5157+
const top = window.screenY + (window.innerHeight - height) / 2;
5158+
5159+
const popupWindow = window.open(
5160+
"about:blank",
5161+
"_blank",
5162+
`width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`,
5163+
);
5164+
5165+
if (!popupWindow) {
5166+
throw new Error("Failed to open Coinbase payment window.");
5167+
}
5168+
5169+
popupWindow.location.href = onRampUrl.toString();
5170+
},
5171+
[masterConfig, client, session, user],
5172+
);
5173+
51325174
useEffect(() => {
51335175
if (proxyAuthConfigRef.current) return;
51345176

@@ -5346,6 +5388,7 @@ export const ClientProvider: React.FC<ClientProviderProps> = ({
53465388
handleConnectExternalWallet,
53475389
handleRemoveUserEmail,
53485390
handleRemoveUserPhoneNumber,
5391+
handleCoinbaseOnRamp,
53495392
}}
53505393
>
53515394
{children}

packages/react-wallet-kit/src/providers/client/Types.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import type {
2424
HandleAddPasskeyParams,
2525
HandleAddPhoneNumberParams,
2626
HandleAppleOauthParams,
27+
HandleCoinbaseOnRampParams,
2728
HandleConnectExternalWalletParams,
2829
HandleDiscordOauthParams,
2930
HandleExportPrivateKeyParams,
@@ -334,7 +335,7 @@ export type ClientContextType = Override<
334335
* @return A void promise.
335336
*/
336337
handleExportPrivateKey: (
337-
params: HandleExportPrivateKeyParams,
338+
params: HandleExportPrivateKeyParams
338339
) => Promise<void>;
339340

340341
/**
@@ -361,7 +362,7 @@ export type ClientContextType = Override<
361362
*/
362363

363364
handleExportWalletAccount: (
364-
params: HandleExportWalletAccountParams,
365+
params: HandleExportWalletAccountParams
365366
) => Promise<void>;
366367

367368
/**
@@ -406,7 +407,7 @@ export type ClientContextType = Override<
406407
* @returns A promise that resolves to the new private key's ID.
407408
*/
408409
handleImportPrivateKey: (
409-
params?: HandleImportPrivateKeyParams,
410+
params?: HandleImportPrivateKeyParams
410411
) => Promise<string>;
411412

412413
/**
@@ -431,7 +432,7 @@ export type ClientContextType = Override<
431432
* @throws {TurnkeyError} If the client is not initialized, no active session is found, or if there is an error updating the user name.
432433
*/
433434
handleUpdateUserEmail: (
434-
params?: HandleUpdateUserEmailParams,
435+
params?: HandleUpdateUserEmailParams
435436
) => Promise<string>;
436437

437438
/**
@@ -458,7 +459,7 @@ export type ClientContextType = Override<
458459
* @throws {TurnkeyError} If the client is not initialized, no active session is found, SMS OTP is not enabled, or if there is an error updating the phone number.
459460
*/
460461
handleUpdateUserPhoneNumber: (
461-
params?: HandleUpdateUserPhoneNumberParams,
462+
params?: HandleUpdateUserPhoneNumberParams
462463
) => Promise<string>;
463464
/**
464465
* Handles the update user email flow.
@@ -483,7 +484,7 @@ export type ClientContextType = Override<
483484
* @throws {TurnkeyError} If the client is not initialized, no active session is found, or if there is an error updating the email.
484485
*/
485486
handleUpdateUserName: (
486-
params?: HandleUpdateUserNameParams,
487+
params?: HandleUpdateUserNameParams
487488
) => Promise<string>;
488489
/**
489490
* Handles the add user email flow.
@@ -533,7 +534,7 @@ export type ClientContextType = Override<
533534
* @throws {TurnkeyError} If the client is not initialized, no active session is found, or if there is an error adding the phone number.
534535
*/
535536
handleAddPhoneNumber: (
536-
params?: HandleAddPhoneNumberParams,
537+
params?: HandleAddPhoneNumberParams
537538
) => Promise<string>;
538539

539540
/**
@@ -557,7 +558,7 @@ export type ClientContextType = Override<
557558
* @throws {TurnkeyError} If the client is not initialized, no active session is found, or if there is an error adding the provider.
558559
*/
559560
handleAddOauthProvider: (
560-
params: HandleAddOauthProviderParams,
561+
params: HandleAddOauthProviderParams
561562
) => Promise<void>;
562563

563564
/**
@@ -583,7 +584,7 @@ export type ClientContextType = Override<
583584
* if there is an error removing the provider, or if the user cancels the action.
584585
*/
585586
handleRemoveOauthProvider: (
586-
params: HandleRemoveOauthProviderParams,
587+
params: HandleRemoveOauthProviderParams
587588
) => Promise<string[]>;
588589

589590
/**
@@ -631,7 +632,7 @@ export type ClientContextType = Override<
631632
* @throws {TurnkeyError} If the client is not initialized, no active session is found, or if there is an error removing the passkey.
632633
*/
633634
handleRemovePasskey: (
634-
params: HandleRemovePasskeyParams,
635+
params: HandleRemovePasskeyParams
635636
) => Promise<string[]>;
636637

637638
/**
@@ -656,7 +657,7 @@ export type ClientContextType = Override<
656657
* @throws {TurnkeyError} If the client is not initialized, if there is an error during the signing process, or if the user cancels the action.
657658
*/
658659
handleSignMessage: (
659-
params: HandleSignMessageParams,
660+
params: HandleSignMessageParams
660661
) => Promise<v1SignRawPayloadResult>;
661662

662663
/**
@@ -677,7 +678,7 @@ export type ClientContextType = Override<
677678
* @throws {TurnkeyError} If the client is not initialized or if the user cancels the action.
678679
*/
679680
handleConnectExternalWallet: (
680-
params?: HandleConnectExternalWalletParams,
681+
params?: HandleConnectExternalWalletParams
681682
) => Promise<{
682683
type: "connect" | "disconnect";
683684
account: WalletAccount;
@@ -700,7 +701,7 @@ export type ClientContextType = Override<
700701
* if the user cancels the action, or if there is an error during the removal process.
701702
*/
702703
handleRemoveUserEmail: (
703-
params?: HandleRemoveUserEmailParams,
704+
params?: HandleRemoveUserEmailParams
704705
) => Promise<string>;
705706

706707
/**
@@ -720,12 +721,15 @@ export type ClientContextType = Override<
720721
* if the user cancels the action, or if there is an error during the removal process.
721722
*/
722723
handleRemoveUserPhoneNumber: (
723-
params?: HandleRemoveUserPhoneNumberParams,
724+
params?: HandleRemoveUserPhoneNumberParams
724725
) => Promise<string>;
726+
727+
// TODO (Amir): Complete JSDoc
728+
handleCoinbaseOnRamp: (params: HandleCoinbaseOnRampParams) => Promise<void>;
725729
}
726730
>;
727731

728732
/** @internal */
729733
export const ClientContext = createContext<ClientContextType | undefined>(
730-
undefined,
734+
undefined
731735
);

packages/react-wallet-kit/src/types/method-types.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import type {
33
StamperType,
44
v1AddressFormat,
55
v1Curve,
6+
v1FiatOnRampBlockchainNetwork,
7+
v1FiatOnRampCryptoCurrency,
8+
v1FiatOnRampCurrency,
9+
v1FiatOnRampPaymentMethod,
10+
v1FiatOnRampProvider,
611
v1HashFunction,
712
v1PayloadEncoding,
813
v1WalletAccountParams,
@@ -227,3 +232,20 @@ export type HandleRemoveUserPhoneNumberParams = {
227232
stampWith?: StamperType | undefined;
228233
organizationId?: string;
229234
};
235+
236+
export type HandleCoinbaseOnRampParams = {
237+
onrampProvider: v1FiatOnRampProvider;
238+
walletAddress: string;
239+
network: v1FiatOnRampBlockchainNetwork;
240+
cryptoCurrencyCode: v1FiatOnRampCryptoCurrency;
241+
fiatCurrencyCode?: v1FiatOnRampCurrency;
242+
fiatCurrencyAmount?: string;
243+
paymentMethod?: v1FiatOnRampPaymentMethod;
244+
countryCode?: string;
245+
countrySubdivisionCode?: string;
246+
sandboxMode?: boolean;
247+
urlForSignature?: string;
248+
successPageDuration?: number | undefined;
249+
stampWith?: StamperType | undefined;
250+
organizationId?: string;
251+
};

0 commit comments

Comments
 (0)