@unifold/connect-react 0.1.71 → 0.1.73

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/README.md CHANGED
@@ -19,7 +19,7 @@ import { UnifoldProvider } from '@unifold/connect-react';
19
19
 
20
20
  function App() {
21
21
  return (
22
- <UnifoldProvider
22
+ <UnifoldProvider
23
23
  publishableKey="pk_test_your_key"
24
24
  config={{
25
25
  modalTitle: 'Deposit Crypto',
@@ -50,7 +50,7 @@ function DepositButton() {
50
50
  destinationTokenAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
51
51
  destinationTokenSymbol: 'USDC',
52
52
  recipientAddress: '0x606C49ca2Fa4982F07016265040F777eD3DA3160',
53
-
53
+
54
54
  // Optional callbacks (fired immediately)
55
55
  onSuccess: ({ message }) => {
56
56
  console.log('Immediate callback:', message);
@@ -59,7 +59,7 @@ function DepositButton() {
59
59
  console.error('Immediate callback error:', message);
60
60
  },
61
61
  });
62
-
62
+
63
63
  // Handle the result from the promise
64
64
  console.log('Deposit completed!', result);
65
65
  alert('Success: ' + result.message);
@@ -83,6 +83,7 @@ That's it! The modal with full deposit UI will appear automatically.
83
83
  Wraps your application and provides the Unifold context.
84
84
 
85
85
  **Props:**
86
+
86
87
  - `publishableKey` (required): Your Unifold API publishable key
87
88
  - `config` (optional): Configuration object
88
89
  - `modalTitle` (optional): Custom title for the deposit modal
@@ -94,7 +95,7 @@ Wraps your application and provides the Unifold context.
94
95
  - `children` (required): Your React components
95
96
 
96
97
  ```tsx
97
- <UnifoldProvider
98
+ <UnifoldProvider
98
99
  publishableKey="pk_test_..."
99
100
  config={{
100
101
  modalTitle: 'Deposit Crypto',
@@ -111,6 +112,7 @@ Wraps your application and provides the Unifold context.
111
112
  Hook that provides access to the deposit functionality.
112
113
 
113
114
  **Returns:**
115
+
114
116
  - `publishableKey`: The current publishable key
115
117
  - `beginDeposit(config)`: Function to launch the deposit modal (returns a Promise)
116
118
  - `closeDeposit()`: Function to programmatically close the modal
@@ -125,25 +127,26 @@ Launches the deposit modal with the specified configuration. **Returns a Promise
125
127
 
126
128
  **Parameters (DepositConfig):**
127
129
 
128
- | Parameter | Type | Required | Description |
129
- |-----------|------|----------|-------------|
130
- | `userId` | string | ✅ | Your user's unique identifier for wallet creation/tracking |
131
- | `destinationChainId` | string | ✅ | Target blockchain chain ID |
132
- | `destinationTokenAddress` | string | ✅ | Token contract address |
133
- | `destinationTokenSymbol` | string | ✅ | Token symbol (e.g., "USDC") |
134
- | `recipientAddress` | string | ✅ | Recipient wallet address |
135
- | `defaultSourceChainType` | string | - | Prefer source chain type in Transfer Crypto, Wallet Connect, and Connect Exchange (e.g. `"solana"`, `"ethereum"`). Must be paired with `defaultSourceChainId` + symbol or token address. If omitted or no match, each flow uses its normal ordering. |
136
- | `defaultSourceChainId` | string | - | Source chain ID (e.g. `"mainnet"`, `"137"`). Paired with `defaultSourceChainType`. |
137
- | `defaultSourceTokenAddress` | string | - | Source token contract address. Paired with chain type + chain ID. |
138
- | `defaultSourceSymbol` | string | - | Source token symbol (e.g. `"USDC"`). Paired with chain type + chain ID. |
139
- | `prefilledAmountUsd` | string | - | Optional USD amount prefilled for deposit amount inputs (Connect Wallet, Deposit with Card, Bank Transfer, Cash App). It is applied as initial typed input and does not enable checkout mode. |
140
- | `onSuccess` | function | - | Success callback (fired immediately) |
141
- | `onError` | function | - | Error callback (fired immediately) |
142
- | `initialScreen` | `'main' \| 'transfer' \| 'card' \| 'cashapp' \| 'tracker' \| 'pay_with_exchange' \| 'exchange_connect' \| 'wallet_connect'` | - | `main` (default) = deposit menu. `transfer` / `card` use the **same geo/validation gates** as the menu. `tracker` opens the list **without** those gates. `cashapp`, `pay_with_exchange`, `exchange_connect`, `wallet_connect` open their respective flows and **fall back to `main`** when the matching feature flag (`enableCashApp`, `enablePayWithExchange`, `enableConnectExchange`, `enableConnectWallet`) is disabled. If not `main`, the header **back** is hidden at the flow root (standalone); from `main`, back returns to the menu. Inner steps (card quotes/onramp, tracker detail, exchange pending, cashapp payment) still show back. |
130
+ | Parameter | Type | Required | Description |
131
+ | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
132
+ | `userId` | string | ✅ | Your user's unique identifier for wallet creation/tracking |
133
+ | `destinationChainId` | string | ✅ | Target blockchain chain ID |
134
+ | `destinationTokenAddress` | string | ✅ | Token contract address |
135
+ | `destinationTokenSymbol` | string | ✅ | Token symbol (e.g., "USDC") |
136
+ | `recipientAddress` | string | ✅ | Recipient wallet address |
137
+ | `defaultSourceChainType` | string | - | Prefer source chain type in Transfer Crypto, Wallet Connect, and Connect Exchange (e.g. `"solana"`, `"ethereum"`). Must be paired with `defaultSourceChainId` + symbol or token address. If omitted or no match, each flow uses its normal ordering. |
138
+ | `defaultSourceChainId` | string | - | Source chain ID (e.g. `"mainnet"`, `"137"`). Paired with `defaultSourceChainType`. |
139
+ | `defaultSourceTokenAddress` | string | - | Source token contract address. Paired with chain type + chain ID. |
140
+ | `defaultSourceSymbol` | string | - | Source token symbol (e.g. `"USDC"`). Paired with chain type + chain ID. |
141
+ | `prefilledAmountUsd` | string | - | Optional USD amount prefilled for deposit amount inputs (Connect Wallet, Deposit with Card, Bank Transfer, Cash App). It is applied as initial typed input and does not enable checkout mode. |
142
+ | `onSuccess` | function | - | Success callback (fired immediately) |
143
+ | `onError` | function | - | Error callback (fired immediately) |
144
+ | `initialScreen` | `'main' \| 'transfer' \| 'card' \| 'cashapp' \| 'tracker' \| 'pay_with_exchange' \| 'exchange_connect' \| 'wallet_connect'` | - | `main` (default) = deposit menu. `transfer` / `card` use the **same geo/validation gates** as the menu. `tracker` opens the list **without** those gates. `cashapp`, `pay_with_exchange`, `exchange_connect`, `wallet_connect` open their respective flows and **fall back to `main`** when the matching feature flag (`enableCashApp`, `enablePayWithExchange`, `enableConnectExchange`, `enableConnectWallet`) is disabled. If not `main`, the header **back** is hidden at the flow root (standalone); from `main`, back returns to the menu. Inner steps (card quotes/onramp, tracker detail, exchange pending, cashapp payment) still show back. |
143
145
 
144
146
  **Returns:** `Promise<DepositResult>`
145
147
 
146
148
  **DepositResult:**
149
+
147
150
  ```typescript
148
151
  interface DepositResult {
149
152
  message: string;
@@ -153,6 +156,7 @@ interface DepositResult {
153
156
  ```
154
157
 
155
158
  **DepositError:**
159
+
156
160
  ```typescript
157
161
  interface DepositError {
158
162
  message: string;
@@ -218,8 +222,8 @@ const depositPromise = beginDeposit({
218
222
 
219
223
  // Later handling
220
224
  depositPromise
221
- .then(result => console.log('Completed:', result))
222
- .catch(error => console.error('Failed:', error));
225
+ .then((result) => console.log('Completed:', result))
226
+ .catch((error) => console.error('Failed:', error));
223
227
  ```
224
228
 
225
229
  ## Features
@@ -233,6 +237,89 @@ depositPromise
233
237
  - ✅ **SSR-safe** - Works with Next.js and other frameworks
234
238
  - ✅ **Customizable** - Configure per-transaction
235
239
 
240
+ ## Analytics & Journey Events
241
+
242
+ The SDK emits two complementary streams so you can understand the full user journey — what method they chose, where they dropped off, and whether the transaction completed or failed.
243
+
244
+ ### 1. Developer-facing `onEvent` (deposit & withdraw)
245
+
246
+ Pass `onEvent` to `beginDeposit` / `beginWithdraw` to receive lifecycle events. Every event shares the same envelope:
247
+
248
+ ```ts
249
+ {
250
+ id: string; // sevt_<ksuid>
251
+ type: string; // see tables below
252
+ created: number; // unix seconds
253
+ sessionId: string; // asess_<ksuid> — one journey, modal open → close
254
+ externalUserId?: string;// the id you opened the flow with (deposit/withdraw)
255
+ method?: DepositMethod;// deposit events only
256
+ data: { object: ... }; // type-specific payload
257
+ }
258
+ ```
259
+
260
+ `sessionId` is minted when the modal opens and cleared when it closes, so you can correlate every event from one attempt — including the analytics stream below, which sends the same id as `session_id`. Out-of-widget telemetry has no `session_id`.
261
+
262
+ `externalUserId` is the `externalUserId` you passed to `beginDeposit` / `beginWithdraw`, echoed back so one shared `onEvent` handler can attribute a journey without you threading your own id through the call site. Checkout events don't carry it — you open a checkout with a client secret, and the payment intent you created server-side is the key that maps back to your user.
263
+
264
+ **Deposit events (`DepositEventType`)**
265
+
266
+ | `type` | When | `data.object` |
267
+ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
268
+ | `deposit.method_selected` | User picks a funding method | `{ method }` |
269
+ | `deposit.flow_started` | A funding method that initiates a session/tx begins (card, cash app, bank transfer, apple pay, stripe link, wallet connect, connect-exchange). Not emitted for transfer-crypto / pay-with-exchange, which have no in-SDK initiation step. | `{ method?, provider?, amountUsd?, chain? }` |
270
+ | `deposit.token_selected` | User picks an asset — fires with the full identity whenever the token **or** its chain changes | `{ currency?, tokenAddress?, chain?, chainType?, network?, method? }` |
271
+ | `deposit.wallet_selected` | User picks a browser wallet | `{ wallet, walletName?, installed? }` |
272
+ | `deposit.provider_selected` | User picks an onramp/exchange provider | `{ provider, method? }` |
273
+ | `deposit.verification_started` | User reached a step asking them to prove something — KYC, a document, a one-time code, an exchange MFA prompt | `{ method? }` |
274
+ | `deposit.verification_completed` | The check passed | `{ method? }` |
275
+ | `deposit.verification_failed` | The check didn't pass | `{ method? }` — see note below |
276
+ | `deposit.account_connection_started` | User began linking an account held elsewhere (exchange, Stripe Link) | `{ provider, method? }` |
277
+ | `deposit.account_connected` | The external account is linked and usable | `{ provider, method? }` |
278
+ | `deposit.account_connection_failed` | Linking the external account failed or was abandoned | `{ provider, method? }` — no reason: see note below |
279
+ | `deposit.wallet_connection_started` | User began connecting a browser wallet | `{ wallet, method?, chainType? }` |
280
+ | `deposit.wallet_connected` | The wallet is connected and usable | `{ wallet, method?, chainType? }` |
281
+ | `deposit.wallet_connection_failed` | The connection failed, or the user declined it in their wallet | `{ wallet, method?, chainType?, failureReason? }` — `connect_declined` or `connect_failed` |
282
+ | `deposit.flow_failed` | The deposit failed, including before anything reached a chain — a declined signature, a declined card, a purchase cap | `{ method?, message, errorCode? }` |
283
+ | `deposit.limit_reached` | The user is at a purchase cap they can't raise — offer another method | `{ method?, provider? }` |
284
+ | `onramp_session.created` | Hosted onramp session opened | `{}` — a signal; the method and `sessionId` are on the envelope |
285
+ | `direct_execution.succeeded` | Deposit confirmed on-chain | `DirectExecution` |
286
+ | `direct_execution.failed` | Deposit failed on-chain — follows `deposit.flow_failed` with the execution detail | `DirectExecution` (see `failureReason`) |
287
+
288
+ **Withdraw events (`WithdrawEventType`)**
289
+
290
+ | `type` | When | `data.object` |
291
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
292
+ | `withdraw.token_selected` | User picks the destination asset — fires with the full identity whenever the token **or** its chain changes | `{ currency?, tokenAddress?, chain?, chainType?, network?, method? }` |
293
+ | `withdraw.flow_started` | Withdraw form confirmed | `{ token?, chain?, amount?, amountBaseUnit?, amountUsd? }` (telemetry additionally carries `currency` + `network`) |
294
+ | `direct_execution.succeeded` | Withdraw confirmed on-chain | `DirectExecution` |
295
+ | `direct_execution.failed` | Withdraw failed | `DirectExecution` |
296
+
297
+ **Checkout events (`CheckoutEventType`)**
298
+
299
+ | `type` | When | `data.object` |
300
+ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
301
+ | `checkout.method_selected` | User picks how to pay | `{ method }` |
302
+ | `checkout.token_selected` | User picks an asset to pay with — fires with the full identity whenever the token **or** its chain changes | `{ currency?, tokenAddress?, chain?, chainType?, network?, method? }` |
303
+ | `checkout.wallet_selected` | User picks a browser wallet | `{ wallet, walletName?, installed? }` |
304
+ | `checkout.wallet_connection_started` | User began connecting a browser wallet | `{ wallet, method?, chainType? }` |
305
+ | `checkout.wallet_connected` | The wallet is connected and usable | `{ wallet, method?, chainType? }` |
306
+ | `checkout.wallet_connection_failed` | The connection failed, or the user declined it in their wallet | `{ wallet, method?, chainType?, failureReason? }` |
307
+ | `checkout.flow_started` | The payment was submitted | `{ method?, amountUsd?, chain? }` |
308
+ | `checkout.flow_failed` | The payment attempt failed, including before anything reached a chain — a signature declined in the wallet, no deposit address for the wallet's chain | `{ method?, message, errorCode? }` |
309
+ | `payment_intent.succeeded` | Payment confirmed | `CheckoutPaymentIntent` |
310
+
311
+ > Note: `sessionId` is a required field on the envelope. If you construct events yourself (e.g. in tests/mocks), include it.
312
+
313
+ > Note: checkout envelopes carry `paymentIntentId` rather than the `externalUserId` that deposit and withdraw echo — you open a checkout with a client secret, and the intent you created server-side is the key back to your own records. Pass `externalUserId` to `beginCheckout` if you'd rather attribute by user; it's echoed onto every envelope and sent nowhere else.
314
+
315
+ > Note: verification tells you only that a check started, passed or didn't. Which gate it was, which tier, the provider's verdict, the field that didn't match — all of that describes your user rather than the transaction, so it stays in our funnel where support can reach it. The same goes for why an exchange account wouldn't link. Note also that `deposit.verification_failed` can fire on an attempt the user recovers from, such as a mistyped code, and that a provider verifying in tiers produces one started/outcome cycle per tier; when a verification actually ends the flow you get `deposit.limit_reached` or `deposit.flow_failed`, and those are the ones worth acting on. Wallet connections are the exception to all of this: `deposit.wallet_connection_failed` does carry a reason, because declining a prompt in your own wallet is your own visible action.
316
+
317
+ ### 2. Telemetry (funnel analytics)
318
+
319
+ Independently, the SDK forwards funnel events (`widget_opened`, `screen_viewed`, `payment_method_selected`, `token_selected`, `wallet_selected`, `provider_selected`, `payment_method_type_selected`, `verification_started`, `verification_submitted`, `verification_completed`, `verification_failed` (funnel only — only the failure reaches `onEvent`), `account_connection_started`, `account_connected`, `account_connection_failed`, `wallet_connection_started`, `wallet_connected`, `wallet_connection_failed`, `flow_started`, `flow_completed`, `flow_failed`, `back_clicked`, `widget_closed`) to the Unifold backend. Each carries `session_id` (`asess_…`) and, once deposit-addresses returns, the internal `user_id` — so drop-off funnels can be grouped per journey and per user. Early events in a session (before addresses resolve) may omit `user_id`. Abandonment is derived from the funnel (`widget_opened` − `flow_completed`).
320
+
321
+ Events that name an asset carry `currency` and `network` next to the raw `token` and `chain`. Those are the slugs the API serves on every token and chain — lowercase, with non-alphanumerics collapsed to `_` (`USDC.e` → `usdc_e`, `USDC (Perp)` → `usdc_perp`, `Base Sepolia` → `base_sepolia`) — and they are the same identifiers the payment-intents API takes as `destination_currency` / `destination_network`. Group funnels on those; read `token`/`chain` when you want the symbol as displayed or the exact chain id. A currency is not unique per network (Polygon carries both `usdc` and `usdc_e`, HyperCore both `usdc` and `usdc_perp`), so the pair is the key, never the currency alone.
322
+
236
323
  ## Advanced Usage
237
324
 
238
325
  ### Pattern 1: Promise-based (Recommended for Modern Apps)
@@ -250,7 +337,7 @@ const handleDeposit = async () => {
250
337
  destinationTokenSymbol: 'USDC',
251
338
  recipientAddress: '0x606C49ca2Fa4982F07016265040F777eD3DA3160',
252
339
  });
253
-
340
+
254
341
  // Update your UI state
255
342
  setDepositStatus('completed');
256
343
  showSuccessMessage(result.message);
@@ -284,7 +371,7 @@ const handleDeposit = () => {
284
371
  showToast('Error: ' + error.message);
285
372
  },
286
373
  });
287
-
374
+
288
375
  // Code continues immediately without waiting
289
376
  console.log('Deposit modal opened');
290
377
  };
@@ -305,7 +392,7 @@ const handleDeposit = async () => {
305
392
  destinationTokenAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
306
393
  destinationTokenSymbol: 'USDC',
307
394
  recipientAddress: '0x606C49ca2Fa4982F07016265040F777eD3DA3160',
308
-
395
+
309
396
  // Immediate callbacks for real-time feedback
310
397
  onSuccess: (data) => {
311
398
  showToast('Deposit detected!');
@@ -315,13 +402,13 @@ const handleDeposit = async () => {
315
402
  showToast('Error: ' + error.message);
316
403
  },
317
404
  });
318
-
405
+
319
406
  // Continue other work immediately
320
407
  setModalOpen(true);
321
-
408
+
322
409
  // Await the final result
323
410
  const result = await depositPromise;
324
-
411
+
325
412
  // Update final state
326
413
  setDepositComplete(true);
327
414
  navigateToSuccessPage(result);
@@ -359,11 +446,11 @@ setTimeout(() => {
359
446
  Full TypeScript support with type definitions included:
360
447
 
361
448
  ```tsx
362
- import {
363
- UnifoldProvider,
364
- useUnifold,
449
+ import {
450
+ UnifoldProvider,
451
+ useUnifold,
365
452
  DepositConfig,
366
- UnifoldConnectProviderConfig
453
+ UnifoldConnectProviderConfig,
367
454
  } from '@unifold/connect-react';
368
455
 
369
456
  // Provider config
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
  import { QueryClient } from '@tanstack/react-query';
4
4
  import { ChainType, DepositConfirmationMode, DepositMethod, DepositModalInitialScreen, ThemeMode, ThemeConfig, FontConfig, ComponentConfig, WithdrawTransactionInfo, AllowedCountryResult } from '@unifold/ui-react';
5
- export { AllowedCountryResult, BrowserWalletAmountQuickSelect, Button, ButtonProps, ButtonTokens, CardTokens, ComponentConfig, ComponentTokens, ConfirmingView, ContainerTokens, CustomThemeColors, DepositConfirmationMode, DepositModalInitialScreen as DepositInitialScreen, DepositMethod, FontConfig, HeaderTokens, InputTokens, ListTokens, SearchTokens, ThemeColors, ThemeConfig, ThemeMode, UseSupportedDepositTokensOptions, WithdrawTransactionInfo, useSupportedDepositTokens } from '@unifold/ui-react';
5
+ export { AllowedCountryResult, BrowserWalletAmountQuickSelect, Button, ButtonProps, ButtonTokens, CardTokens, ComponentConfig, ComponentTokens, ConfirmingView, ContainerTokens, CustomThemeColors, DepositConfirmationMode, DepositModalInitialScreen as DepositInitialScreen, DepositMethod, FontConfig, HeaderTokens, I18nContextValue, I18nProvider, I18nProviderProps, InputTokens, ListTokens, LocaleCode, SUPPORTED_LOCALES, SearchTokens, ThemeColors, ThemeConfig, ThemeMode, UseSupportedDepositTokensOptions, WithdrawTransactionInfo, detectBrowserLocale, interpolate, normalizeLocale, useI18n, useSupportedDepositTokens } from '@unifold/ui-react';
6
6
  import { CheckoutMethod, CheckoutPaymentIntent, CheckoutEvent, EvmContractCall, DirectExecutionSucceededEvent, DepositEvent, WithdrawDirectExecutionSucceededEvent, WithdrawEvent } from '@unifold/core';
7
7
  export { ActionType, AutoSwapRequest, AutoSwapResponse, ChainType, CheckoutEvent, CheckoutEventType, CheckoutMethod, CheckoutPaymentIntent, CheckoutPaymentIntentData, CheckoutPaymentIntentSucceededEvent, CreateDepositAddressRequest, DefaultTokenChain, DefaultTokenMetadata, DefaultTokenResponse, DepositAddressResponse, DepositEvent, DepositEventType, DepositQuote, DepositQuoteRequest, DestinationToken, DestinationTokenChain, DirectExecution, DirectExecutionResponse, ExecutionStatus, FeaturedToken, FiatCurrenciesResponse, FiatCurrency, I18nStrings, IconUrl, IpAddressResponse, LockedQuoteLimits, LockedQuotePreview, LockedQuotePreviewRequest, OnrampQuote, OnrampQuotesRequest, OnrampQuotesResponse, OnrampSessionCreatedData, OnrampSessionCreatedEvent, OnrampSessionRequest, OnrampSessionResponse, PaymentIntent, PaymentIntentDepositAddress, PaymentIntentStatus, PaymentIntentType, PaymentNetwork, ProjectConfigResponse, QueryExecutionsRequest, QueryExecutionsResponse, SOLANA_USDC_ADDRESS, SendSolanaTransactionRequest, SendSolanaTransactionResponse, SourceToken, SourceTokenNetwork, StripeAccessTokenResponse, StripeAuthIntentResponse, StripeConfigResponse, StripeConfirmRequest, StripeConsumerWallet, StripeCreateSessionRequest, StripeCryptoCustomer, StripeCustomerVerification, StripeDefaultTokenResponse, StripeListResponse, StripeOnrampSession, StripeOnrampTransactionDetails, StripePaymentToken, StripeQuoteRequest, StripeQuotesResponse, SupportedChain, SupportedDepositTokensResponse, SupportedDestinationTokensResponse, SupportedSourceTokensQuery, SupportedSourceTokensResponse, SupportedToken, TokenChain, TokenChainIconUrl, TokenChainsResponse, UserIpInfo, Wallet, WithdrawDirectExecutionSucceededEvent, WithdrawEvent, WithdrawEventType, createDepositAddress, createOnrampSession, generatePrefixedKSUID, getApiBaseUrl, getChainName, getDefaultOnrampToken, getDepositQuote, getFiatCurrencies, getIconUrl, getIconUrlWithCdn, getIpAddress, getOnrampQuotes, getPreferredIconUrl, getProjectConfig, getSupportedDepositTokens, getSupportedDestinationTokens, getTokenChains, getWalletByChainType, i18n, queryExecutions, retrievePaymentIntent, sendSolanaTransaction, setApiConfig, stripeConfirmSession, stripeCreateAuthIntent, stripeCreateSession, stripeExchangeTokens, stripeGetConfig, stripeGetCustomer, stripeGetDefaultToken, stripeGetQuotes, stripeGetSession, stripeListPaymentTokens, stripeListWallets, stripeRefreshQuote, stripeRefreshToken, useUserIp } from '@unifold/core';
8
8
 
@@ -20,6 +20,12 @@ interface UnifoldConnectProviderConfig {
20
20
  */
21
21
  queryClient?: QueryClient;
22
22
  config?: {
23
+ /**
24
+ * UI language as a BCP-47 tag (e.g. "en", "zh", "zh-CN", "zh-TW"). When
25
+ * omitted, the browser locale is auto-detected. Unsupported locales fall
26
+ * back to English.
27
+ */
28
+ locale?: string;
23
29
  modalTitle?: string;
24
30
  /** Custom title for the withdraw modal. @default `"Withdraw"` */
25
31
  withdrawModalTitle?: string;
@@ -66,10 +72,21 @@ interface UnifoldConnectProviderConfig {
66
72
  * launch) at order-creation time.
67
73
  */
68
74
  enableApplePay?: boolean;
69
- /** Main menu — Apple Pay row title. @default `"Pay with Apple Pay"` */
75
+ /** Main menu — Apple Pay row title. @default `"Pay with Apple Pay"` (localized when omitted) */
70
76
  applePayTitle?: string;
71
- /** Main menu — Apple Pay row subtitle. @default `"Instant"` */
77
+ /** Main menu — Apple Pay row subtitle. @default `"Instant"` (localized when omitted) */
72
78
  applePaySubTitle?: string;
79
+ /**
80
+ * Enable "Pay with Google Pay" (headless Coinbase) option. Overrides
81
+ * dashboard default. Resolves as flag ?? dashboard `google_pay.enabled` ??
82
+ * true. The server still gates per-region (US-only, NY excluded at
83
+ * launch) at order-creation time.
84
+ */
85
+ enableGooglePay?: boolean;
86
+ /** Main menu — Google Pay row title. @default `"Pay with Google Pay"` (localized when omitted) */
87
+ googlePayTitle?: string;
88
+ /** Main menu — Google Pay row subtitle. @default `"Instant"` (localized when omitted) */
89
+ googlePaySubTitle?: string;
73
90
  /** Simple accent/primary color override (applies to both light and dark modes) */
74
91
  accentColor?: string;
75
92
  /** Full theme color customization per mode */
@@ -214,6 +231,13 @@ interface WithdrawError {
214
231
  interface CheckoutConfig {
215
232
  /** The client_secret from a PaymentIntent created on your server */
216
233
  clientSecret: string;
234
+ /**
235
+ * Your own id for the payer, echoed onto every `onEvent` envelope so a
236
+ * shared handler can attribute events by user. Optional and purely a
237
+ * passthrough — a checkout is identified by its payment intent, which every
238
+ * envelope already carries as `paymentIntentId`.
239
+ */
240
+ externalUserId?: string;
217
241
  /**
218
242
  * Prefer a source token/chain in Transfer Crypto and Wallet Connect flows.
219
243
  * All four props are optional. To match a specific token, provide `chainType` + `chainId` + (`symbol` OR `tokenAddress`).
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
  import { QueryClient } from '@tanstack/react-query';
4
4
  import { ChainType, DepositConfirmationMode, DepositMethod, DepositModalInitialScreen, ThemeMode, ThemeConfig, FontConfig, ComponentConfig, WithdrawTransactionInfo, AllowedCountryResult } from '@unifold/ui-react';
5
- export { AllowedCountryResult, BrowserWalletAmountQuickSelect, Button, ButtonProps, ButtonTokens, CardTokens, ComponentConfig, ComponentTokens, ConfirmingView, ContainerTokens, CustomThemeColors, DepositConfirmationMode, DepositModalInitialScreen as DepositInitialScreen, DepositMethod, FontConfig, HeaderTokens, InputTokens, ListTokens, SearchTokens, ThemeColors, ThemeConfig, ThemeMode, UseSupportedDepositTokensOptions, WithdrawTransactionInfo, useSupportedDepositTokens } from '@unifold/ui-react';
5
+ export { AllowedCountryResult, BrowserWalletAmountQuickSelect, Button, ButtonProps, ButtonTokens, CardTokens, ComponentConfig, ComponentTokens, ConfirmingView, ContainerTokens, CustomThemeColors, DepositConfirmationMode, DepositModalInitialScreen as DepositInitialScreen, DepositMethod, FontConfig, HeaderTokens, I18nContextValue, I18nProvider, I18nProviderProps, InputTokens, ListTokens, LocaleCode, SUPPORTED_LOCALES, SearchTokens, ThemeColors, ThemeConfig, ThemeMode, UseSupportedDepositTokensOptions, WithdrawTransactionInfo, detectBrowserLocale, interpolate, normalizeLocale, useI18n, useSupportedDepositTokens } from '@unifold/ui-react';
6
6
  import { CheckoutMethod, CheckoutPaymentIntent, CheckoutEvent, EvmContractCall, DirectExecutionSucceededEvent, DepositEvent, WithdrawDirectExecutionSucceededEvent, WithdrawEvent } from '@unifold/core';
7
7
  export { ActionType, AutoSwapRequest, AutoSwapResponse, ChainType, CheckoutEvent, CheckoutEventType, CheckoutMethod, CheckoutPaymentIntent, CheckoutPaymentIntentData, CheckoutPaymentIntentSucceededEvent, CreateDepositAddressRequest, DefaultTokenChain, DefaultTokenMetadata, DefaultTokenResponse, DepositAddressResponse, DepositEvent, DepositEventType, DepositQuote, DepositQuoteRequest, DestinationToken, DestinationTokenChain, DirectExecution, DirectExecutionResponse, ExecutionStatus, FeaturedToken, FiatCurrenciesResponse, FiatCurrency, I18nStrings, IconUrl, IpAddressResponse, LockedQuoteLimits, LockedQuotePreview, LockedQuotePreviewRequest, OnrampQuote, OnrampQuotesRequest, OnrampQuotesResponse, OnrampSessionCreatedData, OnrampSessionCreatedEvent, OnrampSessionRequest, OnrampSessionResponse, PaymentIntent, PaymentIntentDepositAddress, PaymentIntentStatus, PaymentIntentType, PaymentNetwork, ProjectConfigResponse, QueryExecutionsRequest, QueryExecutionsResponse, SOLANA_USDC_ADDRESS, SendSolanaTransactionRequest, SendSolanaTransactionResponse, SourceToken, SourceTokenNetwork, StripeAccessTokenResponse, StripeAuthIntentResponse, StripeConfigResponse, StripeConfirmRequest, StripeConsumerWallet, StripeCreateSessionRequest, StripeCryptoCustomer, StripeCustomerVerification, StripeDefaultTokenResponse, StripeListResponse, StripeOnrampSession, StripeOnrampTransactionDetails, StripePaymentToken, StripeQuoteRequest, StripeQuotesResponse, SupportedChain, SupportedDepositTokensResponse, SupportedDestinationTokensResponse, SupportedSourceTokensQuery, SupportedSourceTokensResponse, SupportedToken, TokenChain, TokenChainIconUrl, TokenChainsResponse, UserIpInfo, Wallet, WithdrawDirectExecutionSucceededEvent, WithdrawEvent, WithdrawEventType, createDepositAddress, createOnrampSession, generatePrefixedKSUID, getApiBaseUrl, getChainName, getDefaultOnrampToken, getDepositQuote, getFiatCurrencies, getIconUrl, getIconUrlWithCdn, getIpAddress, getOnrampQuotes, getPreferredIconUrl, getProjectConfig, getSupportedDepositTokens, getSupportedDestinationTokens, getTokenChains, getWalletByChainType, i18n, queryExecutions, retrievePaymentIntent, sendSolanaTransaction, setApiConfig, stripeConfirmSession, stripeCreateAuthIntent, stripeCreateSession, stripeExchangeTokens, stripeGetConfig, stripeGetCustomer, stripeGetDefaultToken, stripeGetQuotes, stripeGetSession, stripeListPaymentTokens, stripeListWallets, stripeRefreshQuote, stripeRefreshToken, useUserIp } from '@unifold/core';
8
8
 
@@ -20,6 +20,12 @@ interface UnifoldConnectProviderConfig {
20
20
  */
21
21
  queryClient?: QueryClient;
22
22
  config?: {
23
+ /**
24
+ * UI language as a BCP-47 tag (e.g. "en", "zh", "zh-CN", "zh-TW"). When
25
+ * omitted, the browser locale is auto-detected. Unsupported locales fall
26
+ * back to English.
27
+ */
28
+ locale?: string;
23
29
  modalTitle?: string;
24
30
  /** Custom title for the withdraw modal. @default `"Withdraw"` */
25
31
  withdrawModalTitle?: string;
@@ -66,10 +72,21 @@ interface UnifoldConnectProviderConfig {
66
72
  * launch) at order-creation time.
67
73
  */
68
74
  enableApplePay?: boolean;
69
- /** Main menu — Apple Pay row title. @default `"Pay with Apple Pay"` */
75
+ /** Main menu — Apple Pay row title. @default `"Pay with Apple Pay"` (localized when omitted) */
70
76
  applePayTitle?: string;
71
- /** Main menu — Apple Pay row subtitle. @default `"Instant"` */
77
+ /** Main menu — Apple Pay row subtitle. @default `"Instant"` (localized when omitted) */
72
78
  applePaySubTitle?: string;
79
+ /**
80
+ * Enable "Pay with Google Pay" (headless Coinbase) option. Overrides
81
+ * dashboard default. Resolves as flag ?? dashboard `google_pay.enabled` ??
82
+ * true. The server still gates per-region (US-only, NY excluded at
83
+ * launch) at order-creation time.
84
+ */
85
+ enableGooglePay?: boolean;
86
+ /** Main menu — Google Pay row title. @default `"Pay with Google Pay"` (localized when omitted) */
87
+ googlePayTitle?: string;
88
+ /** Main menu — Google Pay row subtitle. @default `"Instant"` (localized when omitted) */
89
+ googlePaySubTitle?: string;
73
90
  /** Simple accent/primary color override (applies to both light and dark modes) */
74
91
  accentColor?: string;
75
92
  /** Full theme color customization per mode */
@@ -214,6 +231,13 @@ interface WithdrawError {
214
231
  interface CheckoutConfig {
215
232
  /** The client_secret from a PaymentIntent created on your server */
216
233
  clientSecret: string;
234
+ /**
235
+ * Your own id for the payer, echoed onto every `onEvent` envelope so a
236
+ * shared handler can attribute events by user. Optional and purely a
237
+ * passthrough — a checkout is identified by its payment intent, which every
238
+ * envelope already carries as `paymentIntentId`.
239
+ */
240
+ externalUserId?: string;
217
241
  /**
218
242
  * Prefer a source token/chain in Transfer Crypto and Wallet Connect flows.
219
243
  * All four props are optional. To match a specific token, provide `chainType` + `chainId` + (`symbol` OR `tokenAddress`).