@stridge/kit 0.1.0-alpha.3 → 0.1.0-alpha.30
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 +22 -6
- package/dist/KitProvider.d.ts +29 -0
- package/dist/KitProvider.js +1 -1
- package/dist/_internal/withdraw/driver/index.d.ts +2 -2
- package/dist/deposit/compound/index.d.ts +2 -2
- package/dist/drivers/stridge/createStridgeDepositDriver.js +1 -1
- package/dist/drivers/stridge/createStridgeWithdrawDriver.d.ts +10 -12
- package/dist/drivers/stridge/createStridgeWithdrawDriver.js +1 -1
- package/dist/drivers/stridge/internal/metadata.js +1 -1
- package/dist/drivers/stridge/types.d.ts +7 -4
- package/dist/drivers/stridge-mock/createStridgeMockWithdrawDriver.d.ts +3 -3
- package/dist/drivers/stridge-mock/createStridgeMockWithdrawDriver.js +1 -1
- package/dist/drivers/stridge-mock/fixtures.d.ts +7 -5
- package/dist/drivers/stridge-mock/fixtures.js +1 -1
- package/dist/flows/deposit/dialog/DepositDialog.js +1 -1
- package/dist/flows/deposit/orchestrator/controller.js +1 -1
- package/dist/flows/deposit/orchestrator/types.d.ts +30 -1
- package/dist/flows/deposit/orchestrator/useDeposit.d.ts +18 -1
- package/dist/flows/deposit/orchestrator/useDeposit.js +1 -1
- package/dist/flows/deposit/widgets/deposit/Deposit.js +1 -1
- package/dist/flows/deposit/widgets/deposit/compound/components/Method.d.ts +6 -0
- package/dist/flows/deposit/widgets/deposit/compound/components/Method.js +1 -1
- package/dist/flows/deposit/widgets/deposit/compound/types.d.ts +6 -3
- package/dist/flows/deposit/widgets/deposit-status-banner/DepositStatusBanner.d.ts +7 -0
- package/dist/flows/deposit/widgets/deposit-status-banner/DepositStatusBanner.js +1 -1
- package/dist/flows/deposit/widgets/deposit-status-banner/compound/DepositStatusBanner.js +1 -1
- package/dist/flows/deposit/widgets/deposit-status-banner/compound/components/Hero.js +1 -1
- package/dist/flows/deposit/widgets/deposit-status-banner/compound/components/PrimaryAction.js +1 -1
- package/dist/flows/deposit/widgets/processing-state/ProcessingState.js +1 -1
- package/dist/flows/deposit/widgets/transfer-crypto/compound/components/Address.js +1 -1
- package/dist/flows/deposit/widgets/transfer-crypto/compound/components/Disclosure.d.ts +2 -1
- package/dist/flows/deposit/widgets/transfer-crypto/compound/components/Disclosure.js +1 -1
- package/dist/flows/deposit/widgets/transfer-crypto/compound/components/QrCode.d.ts +4 -10
- package/dist/flows/deposit/widgets/transfer-crypto/compound/components/QrCode.js +1 -1
- package/dist/flows/shared/transformers/pickRelevantSettlement.js +1 -1
- package/dist/flows/withdraw/bindings/WithdrawBindings.d.ts +92 -0
- package/dist/flows/withdraw/bindings/WithdrawBindings.js +1 -0
- package/dist/flows/withdraw/bindings/index.d.ts +1 -0
- package/dist/flows/withdraw/bindings/index.js +1 -0
- package/dist/flows/withdraw/dialog/WithdrawDialog.d.ts +58 -12
- package/dist/flows/withdraw/dialog/WithdrawDialog.js +1 -1
- package/dist/flows/withdraw/driver/payloads.d.ts +16 -1
- package/dist/flows/withdraw/driver/transformers/settlementToWithdrawalPayload.js +1 -1
- package/dist/flows/withdraw/driver/transformers/supportedAssetsToReceiveOptionsPayload.js +1 -1
- package/dist/flows/withdraw/driver/types.d.ts +53 -11
- package/dist/flows/withdraw/orchestrator/controller.js +1 -1
- package/dist/flows/withdraw/orchestrator/index.d.ts +1 -1
- package/dist/flows/withdraw/orchestrator/reducer.js +1 -1
- package/dist/flows/withdraw/orchestrator/types.d.ts +106 -32
- package/dist/flows/withdraw/orchestrator/useWithdraw.d.ts +18 -1
- package/dist/flows/withdraw/orchestrator/useWithdraw.js +1 -1
- package/dist/flows/withdraw/widgets/withdraw-form/WithdrawForm.js +1 -1
- package/dist/flows/withdraw/widgets/withdraw-form/compound/WithdrawForm.js +1 -1
- package/dist/flows/withdraw/widgets/withdraw-form/compound/components/RecipientField.d.ts +7 -5
- package/dist/flows/withdraw/widgets/withdraw-form/compound/components/RecipientField.js +1 -1
- package/dist/flows/withdraw/widgets/withdraw-form/compound/types.d.ts +15 -5
- package/dist/flows/withdraw/widgets/withdraw-form/validation.js +1 -1
- package/dist/flows/withdraw/widgets/withdraw-in-progress/WithdrawInProgress.d.ts +2 -1
- package/dist/flows/withdraw/widgets/withdraw-in-progress/WithdrawInProgress.js +1 -1
- package/dist/i18n/index.d.ts +5 -4
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/locales/ar.js +1 -1
- package/dist/i18n/locales/es.js +1 -1
- package/dist/i18n/locales/source-keys.d.ts +12 -0
- package/dist/i18n/locales/source-keys.js +0 -0
- package/dist/icons/index.d.ts +2 -1
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +1 -1
- package/dist/package.js +1 -0
- package/dist/scope/KitPortalScope.js +1 -1
- package/dist/scope/KitScope.d.ts +18 -1
- package/dist/scope/KitScope.js +1 -1
- package/dist/scope/context.d.ts +17 -1
- package/dist/scope/index.d.ts +1 -1
- package/dist/shared/attribution/Attribution.js +1 -0
- package/dist/shared/attribution/Attribution.slots.js +1 -0
- package/dist/shared/attribution/Attribution.styles.js +1 -0
- package/dist/shared/attribution/index.js +1 -0
- package/dist/shared/chains/index.d.ts +48 -29
- package/dist/shared/chains/index.js +1 -1
- package/dist/shared/constants/brand-intercom.js +1 -0
- package/dist/shared/cuer/Cuer.js +1 -0
- package/dist/shared/cuer/QrCode.js +1 -0
- package/dist/shared/cuer/index.js +1 -0
- package/dist/shared/dialog/Frame.js +1 -1
- package/dist/shared/dialog/StepTransition.js +1 -1
- package/dist/shared/driver/types.d.ts +4 -3
- package/dist/shared/i18n/KitI18nProvider.d.ts +11 -8
- package/dist/shared/i18n/KitI18nProvider.js +1 -1
- package/dist/shared/i18n/createKitI18n.d.ts +79 -16
- package/dist/shared/i18n/createKitI18n.js +1 -1
- package/dist/shared/i18n/useLingui.d.ts +11 -3
- package/dist/shared/icons/LogoIcon.d.ts +13 -0
- package/dist/shared/icons/LogoIcon.js +1 -0
- package/dist/shared/orchestrator/useSettlementWatcher.js +1 -1
- package/dist/shared/primitives/TxHashValue/TxHashValue.js +1 -1
- package/dist/shared/support/SupportButton.d.ts +1 -0
- package/dist/shared/support/SupportButton.js +1 -0
- package/dist/shared/support/SupportConfigContext.d.ts +1 -0
- package/dist/shared/support/SupportConfigContext.js +1 -0
- package/dist/shared/support/SupportLink.d.ts +1 -0
- package/dist/shared/support/SupportLink.js +1 -0
- package/dist/shared/support/SupportSpinner.d.ts +1 -0
- package/dist/shared/support/SupportSpinner.js +1 -0
- package/dist/shared/support/index.d.ts +2 -0
- package/dist/shared/support/index.js +1 -0
- package/dist/shared/support/intercom-loader.d.ts +17 -0
- package/dist/shared/support/intercom-loader.js +1 -0
- package/dist/shared/support/resolveSupport.d.ts +1 -0
- package/dist/shared/support/resolveSupport.js +1 -0
- package/dist/shared/support/types.d.ts +43 -0
- package/dist/shared/support/useIntercomMerchantContext.d.ts +27 -0
- package/dist/shared/support/useIntercomMerchantContext.js +1 -0
- package/dist/shared/support/useIntercomShutdownOnUnmount.js +1 -0
- package/dist/shared/support/useMerchantContext.d.ts +1 -0
- package/dist/shared/support/useMerchantContext.js +1 -0
- package/dist/shared/support/useSupportTrigger.js +1 -0
- package/dist/shared/terms/TermsButton.d.ts +1 -0
- package/dist/shared/terms/TermsButton.js +1 -0
- package/dist/shared/terms/TermsConfigContext.d.ts +1 -0
- package/dist/shared/terms/TermsConfigContext.js +1 -0
- package/dist/shared/terms/TermsLink.d.ts +1 -0
- package/dist/shared/terms/TermsLink.js +1 -0
- package/dist/shared/terms/index.d.ts +1 -0
- package/dist/shared/terms/index.js +1 -0
- package/dist/shared/terms/resolveTerms.d.ts +1 -0
- package/dist/shared/terms/resolveTerms.js +1 -0
- package/dist/shared/terms/types.d.ts +43 -0
- package/dist/shared/ui/Card/Card.styles.js +1 -1
- package/dist/shared/ui/Details/Details.d.ts +9 -1
- package/dist/shared/ui/Details/Details.styles.js +1 -1
- package/dist/shared/ui/Dialog/Dialog.js +1 -1
- package/dist/shared/ui/Dialog/Dialog.styles.js +1 -1
- package/dist/shared/ui/ExternalLink/ExternalLink.js +1 -1
- package/dist/shared/ui/Select/Select.js +1 -1
- package/dist/shared/ui/WalletRow/WalletRow.d.ts +1 -1
- package/dist/shared/ui/WalletRow/WalletRow.js +1 -1
- package/dist/shared/widgets/amount-entry/compound/components/Hero/Hero.js +1 -1
- package/dist/shared/widgets/amount-entry/compound/components/Hero/SwapBackdrop.js +1 -1
- package/dist/shared/widgets/confirm-transfer/compound/components/Disclaimer.d.ts +4 -3
- package/dist/shared/widgets/confirm-transfer/compound/components/Disclaimer.js +1 -1
- package/dist/shared/widgets/error-state/compound/components/AssetValue.js +1 -1
- package/dist/shared/widgets/error-state/compound/components/HelpInfo.js +1 -1
- package/dist/shared/widgets/error-state/compound/components/StatusValue.js +1 -1
- package/dist/shared/widgets/processing-state/compound/ProcessingState.d.ts +1 -5
- package/dist/shared/widgets/processing-state/compound/ProcessingState.js +1 -1
- package/dist/shared/widgets/processing-state/compound/ProcessingState.slots.d.ts +0 -1
- package/dist/shared/widgets/processing-state/compound/ProcessingState.slots.js +1 -1
- package/dist/shared/widgets/processing-state/compound/ProcessingState.styles.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/Details.d.ts +6 -1
- package/dist/shared/widgets/processing-state/compound/components/Details.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/Header.d.ts +4 -3
- package/dist/shared/widgets/processing-state/compound/components/Header.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/Hero.d.ts +11 -7
- package/dist/shared/widgets/processing-state/compound/components/Hero.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/Rows.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/StatusPill.js +1 -1
- package/dist/shared/widgets/processing-state/compound/components/splitAmount.js +1 -0
- package/dist/shared/widgets/processing-state/compound/index.d.ts +1 -1
- package/dist/shared/widgets/processing-state/compound/types.d.ts +7 -26
- package/dist/shared/widgets/success-state/compound/components/Actions.js +1 -1
- package/dist/shared/widgets/success-state/compound/components/AssetValue.js +1 -1
- package/dist/shared/widgets/success-state/compound/components/RouteValue.js +1 -1
- package/dist/shared/widgets/success-state/compound/components/StatusPill.js +1 -1
- package/dist/stridge/StridgeProvider.d.ts +147 -15
- package/dist/stridge/StridgeProvider.js +1 -1
- package/dist/stridge/optionalWagmi.js +1 -0
- package/dist/stridge/stubs.js +1 -1
- package/dist/styles/index.css +58 -12
- package/dist/types.d.ts +5 -4
- package/dist/ui/index.js +1 -1
- package/dist/withdraw/compound/index.d.ts +2 -2
- package/dist/withdraw/dialog/index.d.ts +3 -1
- package/package.json +10 -11
- package/dist/kit/package.js +0 -1
- package/dist/shared/widgets/processing-state/compound/components/Actions.d.ts +0 -17
- package/dist/shared/widgets/processing-state/compound/components/Actions.js +0 -1
- /package/dist/{utils/src/use-copy-to-clipboard.js → shared/utils/useCopyToClipboard.js} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { TxRef } from "../../../shared/driver/types.js";
|
|
2
|
-
import { WithdrawalQuotePayload, WithdrawalSettlementFailurePayload, WithdrawalSettlementPendingPayload, WithdrawalSettlementSuccessPayload } from "../driver/payloads.js";
|
|
3
|
-
import { SubmitWithdrawalInput } from "../driver/types.js";
|
|
4
2
|
import { FailureInfo } from "../../../shared/orchestrator/types.js";
|
|
5
|
-
import {
|
|
3
|
+
import { WithdrawalQuotePayload, WithdrawalSettlementFailurePayload, WithdrawalSettlementPendingPayload, WithdrawalSettlementSuccessPayload } from "../driver/payloads.js";
|
|
4
|
+
import { PrepareWithdrawalInput } from "../driver/types.js";
|
|
5
|
+
import { WithdrawStateName, WithdrawSubmitCallback } from "../orchestrator/types.js";
|
|
6
|
+
import { WithdrawBalanceInput, WithdrawSuggestedRecipient } from "../bindings/WithdrawBindings.js";
|
|
6
7
|
import { WithdrawFormEventCallbacks } from "./WithdrawDialogEventsContext.js";
|
|
7
8
|
import { ErrorInfo } from "react";
|
|
8
9
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
@@ -25,7 +26,10 @@ declare function WithdrawDialog({
|
|
|
25
26
|
onOpened,
|
|
26
27
|
onClosed,
|
|
27
28
|
onStepChanged,
|
|
28
|
-
events
|
|
29
|
+
events,
|
|
30
|
+
balance,
|
|
31
|
+
onSubmit,
|
|
32
|
+
suggestedRecipient
|
|
29
33
|
}?: WithdrawDialog.Props): _$react_jsx_runtime0.JSX.Element;
|
|
30
34
|
declare namespace WithdrawDialog {
|
|
31
35
|
interface Props {
|
|
@@ -56,21 +60,56 @@ declare namespace WithdrawDialog {
|
|
|
56
60
|
* valid for the named event.
|
|
57
61
|
*/
|
|
58
62
|
events?: Events;
|
|
63
|
+
/**
|
|
64
|
+
* Withdrawable balance to display in the form. Two forms:
|
|
65
|
+
*
|
|
66
|
+
* - `number` — bare amount in display units (kit infers symbol from the provider's
|
|
67
|
+
* `asset.symbol`; USD value is short-circuited to $1 for known stablecoins or
|
|
68
|
+
* hidden otherwise).
|
|
69
|
+
* - `{ amount, amountUsd? }` — explicit amount plus an optional pre-computed USD
|
|
70
|
+
* value.
|
|
71
|
+
*
|
|
72
|
+
* Pass `undefined` (or omit) while loading; the form renders a skeleton until a value
|
|
73
|
+
* arrives.
|
|
74
|
+
*/
|
|
75
|
+
balance?: WithdrawBalanceInput;
|
|
76
|
+
/**
|
|
77
|
+
* Submit handler — fires once the kit has prepared a fresh UDA target for the
|
|
78
|
+
* withdrawal. The host's backend (treasury wallet, custodial signer, whatever fits their
|
|
79
|
+
* stack) is responsible for broadcasting a transfer of the brand currency to that UDA;
|
|
80
|
+
* the kit hands a `WithdrawSubmitActions` handle the host calls to advance the FSM at
|
|
81
|
+
* the point its backend reaches the matching state. Required when the dialog is used —
|
|
82
|
+
* a missing callback lands the user on the error screen instead of an infinite spinner.
|
|
83
|
+
*/
|
|
84
|
+
onSubmit?: WithdrawSubmitCallback;
|
|
85
|
+
/**
|
|
86
|
+
* Trusted recipient address surfaced as a one-click prefill chip next to the recipient
|
|
87
|
+
* input. The kit no longer auto-derives this from `wagmi.address` (it misled users on
|
|
88
|
+
* embedded-wallet integrations where wagmi exposes a generated wallet, not the user's
|
|
89
|
+
* primary self-custodial wallet). Pass an explicit address you trust the user wants to
|
|
90
|
+
* fill with — a saved profile wallet, a KYC-bound payout destination, a whitelisted
|
|
91
|
+
* payout. When omitted, no chip renders.
|
|
92
|
+
*/
|
|
93
|
+
suggestedRecipient?: WithdrawSuggestedRecipient;
|
|
59
94
|
}
|
|
60
95
|
/**
|
|
61
96
|
* Operational lifecycle hooks. Splits cleanly into:
|
|
62
97
|
*
|
|
63
98
|
* - **Form-level inputs** (`onRecipientChanged` / `onAmountChanged` / `onReceiveTokenChanged`
|
|
64
99
|
* / `onReceiveChainChanged`) — fire on every change of the form's local state.
|
|
65
|
-
* - **User actions** (`onWithdrawalConfirmed`) —
|
|
100
|
+
* - **User actions** (`onWithdrawalConfirmed`) — fires when the user submits the form, just
|
|
101
|
+
* before the kit hands control to the host's `<WithdrawDialog onSubmit>` callback.
|
|
66
102
|
* - **Quote lifecycle** — track the form's quote entity through `loading → ready / error`.
|
|
67
|
-
* - **Submit lifecycle** — track the
|
|
68
|
-
*
|
|
103
|
+
* - **Submit lifecycle** — track the host-driven progression. The host calls
|
|
104
|
+
* `actions.beginProcessing(tx?)` from inside `onSubmit` to move the orchestrator into
|
|
105
|
+
* `inProgress`; `onWithdrawalSubmitted` fires once a tx hash is surfaced (either via
|
|
106
|
+
* `beginProcessing({ hash })` or a later `setTxHash`). `onSubmissionFailed` fires when
|
|
107
|
+
* the host calls `actions.fail(failure)` or `onSubmit` throws.
|
|
69
108
|
* - **Settlement entity** — track the gateway's settlement payload through pending / succeeded /
|
|
70
109
|
* failed.
|
|
71
110
|
*/
|
|
72
111
|
interface Events extends WithdrawFormEventCallbacks {
|
|
73
|
-
/** User submitted the form
|
|
112
|
+
/** User submitted the form — fires just before the host's `onSubmit` callback runs. */
|
|
74
113
|
onWithdrawalConfirmed?: () => void;
|
|
75
114
|
/** Quote entity reached `ready` with the formatted payload. */
|
|
76
115
|
onQuoteResolved?: (quote: WithdrawalQuotePayload) => void;
|
|
@@ -79,14 +118,21 @@ declare namespace WithdrawDialog {
|
|
|
79
118
|
reason: string;
|
|
80
119
|
code?: string;
|
|
81
120
|
}) => void;
|
|
82
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Orchestrator transitioned into `inProgress` with a tx hash supplied by the host —
|
|
123
|
+
* either passed to `actions.beginProcessing({ hash })` or surfaced later via
|
|
124
|
+
* `actions.setTxHash`.
|
|
125
|
+
*/
|
|
83
126
|
onWithdrawalSubmitted?: (event: {
|
|
84
|
-
input:
|
|
127
|
+
input: PrepareWithdrawalInput;
|
|
85
128
|
tx: TxRef;
|
|
86
129
|
}) => void;
|
|
87
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* Host signaled a user-rejection-shaped failure from `onSubmit` (typically the user
|
|
132
|
+
* backed out of a wallet prompt); the orchestrator routed back to `form{notice}`.
|
|
133
|
+
*/
|
|
88
134
|
onSignatureDeclined?: () => void;
|
|
89
|
-
/**
|
|
135
|
+
/** Host signaled a non-rejection submission failure (backend rejection, network, …). */
|
|
90
136
|
onSubmissionFailed?: (failure: FailureInfo) => void;
|
|
91
137
|
/** The driver's `settlement` entity emitted a progressive pending update. */
|
|
92
138
|
onProcessingProgress?: (update: WithdrawalSettlementPendingPayload) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useDialogLifecycle as e}from"../../../shared/orchestrator/useDialogLifecycle.js";import"../../../shared/orchestrator/index.js";import{
|
|
1
|
+
"use client";import{useDialogLifecycle as e}from"../../../shared/orchestrator/useDialogLifecycle.js";import"../../../shared/orchestrator/index.js";import{useWithdrawBindings as t}from"../bindings/WithdrawBindings.js";import"../bindings/index.js";import{useWithdrawSnapshot as n}from"../driver/context.js";import{useWithdrawEffectiveState as r,useWithdrawState as i}from"../orchestrator/controller.js";import{useWithdraw as a}from"../orchestrator/useWithdraw.js";import"../orchestrator/index.js";import{useIntercomShutdownOnUnmount as o}from"../../../shared/support/useIntercomShutdownOnUnmount.js";import"../../../shared/support/index.js";import{Dialog as s}from"../../../shared/ui/Dialog/Dialog.js";import"../../../shared/ui/Dialog/index.js";import{StepTransition as c}from"../../../shared/dialog/StepTransition.js";import{GatewayKitBoundary as l}from"../../../shared/error-handling/components/GatewayKitBoundary.js";import"../../../shared/error-handling/index.js";import{WithdrawError as u}from"../widgets/withdraw-error/WithdrawError.js";import{WithdrawDialogEventsProvider as d}from"./WithdrawDialogEventsContext.js";import{WithdrawForm as f}from"../widgets/withdraw-form/WithdrawForm.js";import{WithdrawInProgress as p}from"../widgets/withdraw-in-progress/WithdrawInProgress.js";import{WithdrawSuccess as m}from"../widgets/withdraw-success/WithdrawSuccess.js";import"../../../_internal/withdraw/widgets/index.js";import{useRef as h}from"react";import{jsx as g,jsxs as _}from"react/jsx-runtime";function v({container:e,onError:h,onOpened:v,onClosed:b,onStepChanged:x,events:S,balance:C,onSubmit:w,suggestedRecipient:T}={}){let E=i(),D=r(),{close:O}=a(),k=n(),A=E.name!==`closed`;y(E,k.settlement,k.quote,{onOpened:v,onClosed:b,onStepChanged:x,events:S}),o(),t({...C===void 0?{}:{balance:C},...w?{onSubmit:w}:{},...T?{suggestedRecipient:T}:{}});let j=D.name===`submitting`?`form`:D.name;return g(s,{open:A,onOpenChange:e=>e?void 0:O(),children:g(s.Content,{container:e,children:g(l,{onError:h,onReset:O,children:g(d,{events:S??{},children:_(c,{stateKey:j,children:[D.name===`form`||D.name===`submitting`?g(f,{}):null,D.name===`inProgress`?g(p,{}):null,D.name===`success`?g(m,{}):null,D.name===`error`?g(u,{}):null]})})})})})}function y(t,n,r,i){let a=h(i);a.current=i,e({state:t,settlement:n,quote:r,fireFsm:(e,t)=>b(e,t,a.current),fireSettlement:(e,t)=>x(t,a.current),fireQuote:(e,t)=>{if(t.status===e)return;let n=a.current.events;t.status===`ready`&&n?.onQuoteResolved?.(t.payload),t.status===`error`&&n?.onQuoteFailed?.({reason:t.error.message||`Quote failed.`,...t.error.name?{code:t.error.name}:{}})}})}function b(e,t,n){let{onOpened:r,onClosed:i,onStepChanged:a,events:o}=n,s=e.name===`form`&&!!e.ctx?.notice;if(t.name===`form`&&t.ctx?.notice&&!s&&o?.onSignatureDeclined?.(),e.name!==t.name&&(e.name===`closed`&&t.name!==`closed`&&r?.(),e.name!==`closed`&&t.name===`closed`&&i?.(e.name),a?.({from:e.name,to:t.name}),e.name===`form`&&t.name===`submitting`&&o?.onWithdrawalConfirmed?.(),e.name===`submitting`&&t.name===`inProgress`&&t.ctx.tx&&o?.onWithdrawalSubmitted?.({input:t.ctx.input,tx:t.ctx.tx}),t.name===`error`)){let e=t.ctx.failure;e!==void 0&&t.ctx.tx===void 0&&e&&(o?.onSubmissionFailed?.(e),o?.onFailed?.(e))}}function x(e,t){if(e.status!==`ready`&&e.status!==`stale`)return;let n=e.payload,r=t.events;if(r){if(n.kind===`pending`){r.onProcessingProgress?.(n);return}if(n.kind===`succeeded`){r.onSucceeded?.(n);return}n.kind===`failed`&&r.onFailed?.(n)}}export{v as WithdrawDialog};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SettlementFailureKind } from "../../../shared/driver/types.js";
|
|
2
2
|
import { FormattedField } from "../../../shared/format/types.js";
|
|
3
|
+
import { ChainType } from "../../../shared/chains/index.js";
|
|
4
|
+
|
|
3
5
|
//#region src/flows/withdraw/driver/payloads.d.ts
|
|
4
6
|
/**
|
|
5
7
|
* Per-asset balance available to withdraw — the brand-managed source the cash-out flow draws
|
|
@@ -108,6 +110,12 @@ interface WithdrawalSettlementPendingPayload {
|
|
|
108
110
|
kind: "pending";
|
|
109
111
|
receiveAsset: WithdrawalReceiveAssetPayload;
|
|
110
112
|
receiveAmount: FormattedField<number>;
|
|
113
|
+
/**
|
|
114
|
+
* USD value of `receiveAmount` at the settlement leg's price snapshot. Sourced from the
|
|
115
|
+
* gateway leg's `amount_usd` (`to` preferred, `from` fallback). Omitted when neither leg
|
|
116
|
+
* carries a priced amount — the in-progress hero then falls back to the quote's USD figure.
|
|
117
|
+
*/
|
|
118
|
+
receiveAmountUsd?: FormattedField<number>;
|
|
111
119
|
/** Recipient address — the destination the user supplied on the form. */
|
|
112
120
|
recipient: FormattedField<string>;
|
|
113
121
|
/** Unix-ms timestamp when the withdrawal was submitted. */
|
|
@@ -191,8 +199,15 @@ interface ReceiveChainPayload {
|
|
|
191
199
|
networkId: string;
|
|
192
200
|
/** Human-readable network name (e.g. `"Polygon"`). */
|
|
193
201
|
networkName: string;
|
|
194
|
-
/** EIP-155 chain id (numeric). */
|
|
202
|
+
/** EIP-155 chain id (numeric). Only meaningful when `chainType === "evm"`. */
|
|
195
203
|
eip155Id: number;
|
|
204
|
+
/**
|
|
205
|
+
* Chain family this network belongs to — driver-populated from the gateway's `chain_type`
|
|
206
|
+
* tag. The withdraw form drives recipient-address validation off this so a non-EVM receive
|
|
207
|
+
* chain accepts its own address shape instead of the EVM `0x…` form. Drivers that can't
|
|
208
|
+
* determine the family tag it `"unknown"`, which keeps the address gate permissive.
|
|
209
|
+
*/
|
|
210
|
+
chainType: ChainType;
|
|
196
211
|
/** Resolved chain icon URL — derived from the chain's native_currency.logo. */
|
|
197
212
|
chainLogoUrl?: string;
|
|
198
213
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{classifyFailureKind as e,classifySettlementStatus as t}from"../../../shared/transformers/classifySettlementStatus.js";import{parseDecimalSafe as n,parseSmallestUnit as r}from"../../../shared/transformers/parseSmallestUnit.js";import{parseIsoMs as i}from"../../../shared/transformers/parseIsoMs.js";import{formatDurationCompact as a}from"../../../../shared/format/formatDurationCompact.js";import{formatTimestamp as o}from"../../../../shared/format/formatTimestamp.js";import{formatTokenAmount as s}from"../../../../shared/format/formatTokenAmount.js";import{
|
|
1
|
+
import{classifyFailureKind as e,classifySettlementStatus as t}from"../../../shared/transformers/classifySettlementStatus.js";import{parseDecimalSafe as n,parseSmallestUnit as r}from"../../../shared/transformers/parseSmallestUnit.js";import{parseIsoMs as i}from"../../../shared/transformers/parseIsoMs.js";import{formatDurationCompact as a}from"../../../../shared/format/formatDurationCompact.js";import{formatTimestamp as o}from"../../../../shared/format/formatTimestamp.js";import{formatTokenAmount as s}from"../../../../shared/format/formatTokenAmount.js";import{formatUsd as c}from"../../../../shared/format/formatUsd.js";import{shortenAddress as l}from"../../../../shared/format/shortenAddress.js";function u(e,n,r){let i=t(e.status);return i===`completed`?f(e,n,r):i===`failed`?p(e,n,r):d(e,n,r)}function d(e,t,r){let a=e.from,u=e.to,d=i(a?.confirmed_at)??i(e.created_at)??Date.now(),f=m(t,r),p=g(u,t,r),y=_(a,t,r),b=h(u,p)||h(a,y),x=n(u?.amount_usd)||n(a?.amount_usd),S=t.destination.address,C=a?.tx_id,w=a?.eip155_id===void 0?void 0:Number(a.eip155_id);return{kind:`pending`,receiveAsset:f,receiveAmount:{value:b,formatted:s(b,r.i18n,{maxDecimals:p})},...x>0?{receiveAmountUsd:{value:x,formatted:c(x,r.i18n)}}:{},recipient:{value:S,formatted:l(S)},submittedAt:{value:d,formatted:o(d,r.i18n)},...C?{txHash:{value:C,formatted:l(C)},...v(r,w,C)?{txExplorerUrl:v(r,w,C)}:{}}:{}}}function f(e,t,n){let r=e.from,c=e.to,u=i(r?.confirmed_at)??i(e.created_at)??Date.now(),d=i(c?.settled_at)??i(e.updated_at)??Date.now(),f=Math.max(0,d-u),p=Math.round(f/1e3),_=m(t,n),b=g(c,t,n),x=h(c,b),S=t.destination.address,C=r?.tx_id??``,w=r?.eip155_id===void 0?void 0:Number(r.eip155_id),T=c?.tx_id,E=v(n,y(c?.eip155_id)??y(t.destination.eip155_id),T);return{kind:`succeeded`,receiveAsset:_,receiveAmount:{value:x,formatted:s(x,n.i18n,{maxDecimals:b})},recipient:{value:S,formatted:l(S)},submittedAt:{value:u,formatted:o(u,n.i18n)},filledAt:{value:d,formatted:o(d,n.i18n)},totalTime:{value:p,formatted:a(f,n.i18n)},txHash:{value:C,formatted:C?l(C):``},...v(n,w,C)?{txExplorerUrl:v(n,w,C)}:{},...T?{completionTx:{hash:{value:T,formatted:l(T)},...E?{explorerUrl:E}:{}}}:{}}}function p(t,n,r){let a=t.from,c=i(a?.confirmed_at)??i(t.created_at)??Date.now(),u=i(t.updated_at)??Date.now(),d=m(n,r),f=n.destination.address,p=a?.tx_id,h=a?.eip155_id===void 0?void 0:Number(a.eip155_id);return{kind:`failed`,failureKind:e(t.error),receiveAsset:d,receiveAmount:{value:0,formatted:s(0,r.i18n)},recipient:{value:f,formatted:l(f)},submittedAt:{value:c,formatted:o(c,r.i18n)},failedAt:{value:u,formatted:o(u,r.i18n)},...p?{txHash:{value:p,formatted:l(p)},...v(r,h,p)?{txExplorerUrl:v(r,h,p)}:{}}:{}}}function m(e,t){let n=t.receiveAssetEnrichment,r=Number(e.destination.eip155_id);return{symbol:e.destination.asset_symbol,decimals:e.destination.asset_decimals,address:e.destination.asset_address,isNative:!e.destination.asset_address,...n?.assetLogoUrl?{assetLogoUrl:n.assetLogoUrl}:{},networkId:e.destination.network_id,networkName:n?.networkName??e.destination.network_name,...Number.isFinite(r)?{eip155Id:e.destination.eip155_id}:{},...n?.chainLogoUrl?{chainLogoUrl:n.chainLogoUrl}:{}}}function h(e,t){if(!e)return 0;if(e.amount){let t=n(e.amount);if(t>0)return t}return e.raw_amount?r(e.raw_amount,t):0}function g(e,t,n){return n.receiveAssetDecimals??e?.asset_decimals??t.destination.asset_decimals}function _(e,t,n){return n.sendAssetDecimals??e?.asset_decimals??t.destination.asset_decimals}function v(e,t,n){if(!n||t===void 0)return;let r=e.explorers?.[t];if(r)return`${r.replace(/\/+$/,``)}/tx/${n}`}function y(e){if(e==null||e===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}export{u as settlementToWithdrawalPayload};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{toChainType as e}from"../../../../shared/chains/index.js";import{formatNetworkName as t}from"../../../../shared/format/formatNetworkName.js";function n(n,r={}){let i=r.excludedChainIds,a=[];for(let r of n.assets){if(i?.has(r.eip155_id))continue;let n=r.native_currency,o=new Set,s=(e,t)=>`${e.toUpperCase()}@${t.toLowerCase()}`,c=[];if(n?.symbol){let e={symbol:n.symbol,name:n.name??n.symbol,address:``,decimals:typeof n.decimals==`number`?n.decimals:18,isNative:!0,...n.logo?{assetLogoUrl:n.logo}:{}};c.push(e),o.add(s(e.symbol,e.address))}let l=n?.symbol?.toUpperCase();for(let e of r.assets){if(!e.symbol||!e.address||l&&e.symbol.toUpperCase()===l)continue;let t=s(e.symbol,e.address);o.has(t)||(o.add(t),c.push({symbol:e.symbol,name:e.name??e.symbol,address:e.address,decimals:e.decimals,isNative:!1,...e.logo?{assetLogoUrl:e.logo}:{}}))}c.length!==0&&a.push({networkId:r.network_id,networkName:t(r.network_name),eip155Id:r.eip155_id,chainType:e(r.chain_type),...n?.logo?{chainLogoUrl:n.logo}:{},tokens:c})}return a.sort((e,t)=>e.eip155Id-t.eip155Id),a}export{n as supportedAssetsToReceiveOptionsPayload};
|
|
@@ -57,17 +57,57 @@ interface RequestWithdrawalQuoteInput {
|
|
|
57
57
|
recipientAddress: string;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
* Input to {@link WithdrawDriver.
|
|
61
|
-
* — the live driver re-uses the most recent quote for
|
|
62
|
-
* scope both calls.
|
|
60
|
+
* Input to {@link WithdrawDriver.prepareWithdrawal}. Identical to {@link RequestWithdrawalQuoteInput}
|
|
61
|
+
* — the live driver re-uses the most recent quote shape for the gateway/start call, so the same
|
|
62
|
+
* identifying fields scope both calls.
|
|
63
63
|
*/
|
|
64
|
-
type
|
|
64
|
+
type PrepareWithdrawalInput = RequestWithdrawalQuoteInput;
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
66
|
+
* Result of {@link WithdrawDriver.prepareWithdrawal}. Carries everything the host's `onSubmit`
|
|
67
|
+
* callback needs to broadcast a transfer to the Stridge UDA on the brand-currency chain — the
|
|
68
|
+
* UDA address, the chain, the token, the amount — plus the Stridge correlation fields the host
|
|
69
|
+
* may want to mirror into their own backend logs.
|
|
70
|
+
*/
|
|
71
|
+
interface WithdrawPreparation {
|
|
72
|
+
/**
|
|
73
|
+
* Where the host should send brand-currency funds. The kit has already provisioned a UDA
|
|
74
|
+
* (via `gateway/start`); the host's job is to broadcast a single on-chain transfer of
|
|
75
|
+
* `amount` of `tokenSymbol` from their treasury / custodial wallet to `address` on `chainId`.
|
|
76
|
+
* Stridge takes over from there to bridge into the user's chosen recipient/chain/token.
|
|
77
|
+
*/
|
|
78
|
+
depositTarget: {
|
|
79
|
+
/** UDA deposit address on the brand-currency chain. */address: string; /** EIP-155 chain id of the brand-currency network. */
|
|
80
|
+
chainId: number; /** Brand-currency token symbol (e.g. `"USDC"`). */
|
|
81
|
+
tokenSymbol: string; /** ERC-20 contract address of the brand currency. Empty string for native gas tokens. */
|
|
82
|
+
tokenAddress: string; /** On-chain decimal precision (e.g. `6` for USDC on Ethereum, `18` for ETH). */
|
|
83
|
+
tokenDecimals: number; /** `true` when the brand currency is the chain's native gas token. */
|
|
84
|
+
isNative: boolean; /** Exact amount to transfer, in display units (kit-managed decimals already factored in). */
|
|
85
|
+
amount: number;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Stridge correlation slot the host can pass through to their own backend / logs. `owner`
|
|
89
|
+
* is the same value the kit threaded into `gateway/start.owner` for this UDA.
|
|
90
|
+
*/
|
|
91
|
+
correlation: {
|
|
92
|
+
owner: string;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Input to {@link WithdrawDriver.watchSettlement}. `tx` is optional — when the host has
|
|
97
|
+
* surfaced a broadcast tx hash via the orchestrator's `setTxHash` action, the watcher anchors
|
|
98
|
+
* to it for precise matching. When omitted, the watcher falls back to a best-match heuristic
|
|
99
|
+
* (destination tuple + amount tolerance + submit-time window) so the kit can find the relevant
|
|
100
|
+
* settlement even if the host never surfaces a tx hash.
|
|
68
101
|
*/
|
|
69
102
|
interface WatchWithdrawalSettlementInput {
|
|
70
|
-
tx
|
|
103
|
+
tx?: TxRef;
|
|
104
|
+
/**
|
|
105
|
+
* Form snapshot at submit time. The driver uses this in best-match mode to filter
|
|
106
|
+
* `gateway/{owner}` to settlements whose destination matches the user's selection.
|
|
107
|
+
*/
|
|
108
|
+
form: RequestWithdrawalQuoteInput;
|
|
109
|
+
/** Unix-ms timestamp the host called `beginProcessing` — the start of the matching window. */
|
|
110
|
+
submittedAt: number;
|
|
71
111
|
}
|
|
72
112
|
/**
|
|
73
113
|
* Input to {@link WithdrawDriver.watchWithdrawableBalances}. Optional listener — the form's
|
|
@@ -113,10 +153,12 @@ interface WithdrawDriver {
|
|
|
113
153
|
*/
|
|
114
154
|
requestQuote(input: RequestWithdrawalQuoteInput, signal: AbortSignal): Promise<void>;
|
|
115
155
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
156
|
+
* Provisions a fresh UDA for this withdrawal (via `gateway/start`) and returns the deposit
|
|
157
|
+
* target + Stridge correlation slot for the host's `onSubmit` callback to act on. The kit
|
|
158
|
+
* never signs the withdraw transfer itself — the host's backend (treasury wallet, custodial
|
|
159
|
+
* signer, hot-wallet service) does. See {@link WithdrawPreparation}.
|
|
118
160
|
*/
|
|
119
|
-
|
|
161
|
+
prepareWithdrawal(input: PrepareWithdrawalInput, signal: AbortSignal): Promise<WithdrawPreparation>;
|
|
120
162
|
/**
|
|
121
163
|
* Watches the settlement entity through its lifecycle (pending → succeeded / failed). The
|
|
122
164
|
* listener fires on every transition with the new envelope; the FSM consumes these via the
|
|
@@ -130,4 +172,4 @@ interface WithdrawDriver {
|
|
|
130
172
|
watchWithdrawableBalances?(input: WatchWithdrawableBalancesInput, listener: (entity: WithdrawSnapshot["withdrawableBalances"]) => void, signal: AbortSignal): void;
|
|
131
173
|
}
|
|
132
174
|
//#endregion
|
|
133
|
-
export {
|
|
175
|
+
export { PrepareWithdrawalInput, RequestWithdrawalQuoteInput, WatchWithdrawableBalancesInput, WatchWithdrawalSettlementInput, WithdrawDriver, WithdrawPreparation, WithdrawSnapshot };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useLingui as e}from"../../../shared/i18n/useLingui.js";import"../../../i18n/index.js";import{toFailure as t}from"../../../shared/orchestrator/toFailure.js";import{useDriverSettlementListener as n}from"../../../shared/orchestrator/useDriverSettlementListener.js";import{useEffectiveState as r}from"../../../shared/orchestrator/useEffectiveState.js";import{useSettlementWatcher as i}from"../../../shared/orchestrator/useSettlementWatcher.js";import"../../../shared/orchestrator/index.js";import{
|
|
1
|
+
"use client";import{useLingui as e}from"../../../shared/i18n/useLingui.js";import"../../../i18n/index.js";import{toFailure as t}from"../../../shared/orchestrator/toFailure.js";import{useDriverSettlementListener as n}from"../../../shared/orchestrator/useDriverSettlementListener.js";import{useEffectiveState as r}from"../../../shared/orchestrator/useEffectiveState.js";import{useSettlementWatcher as i}from"../../../shared/orchestrator/useSettlementWatcher.js";import"../../../shared/orchestrator/index.js";import{useWithdrawBindingsRef as a}from"../bindings/WithdrawBindings.js";import"../bindings/index.js";import{useWithdrawDriverInstance as o}from"../driver/context.js";import{initialState as s,reducer as c}from"./reducer.js";import{createContext as l,use as u,useCallback as d,useMemo as f,useReducer as p,useRef as m}from"react";import{jsx as h}from"react/jsx-runtime";const g={id:`ldK3jJ`,message:`Failed to submit withdrawal.`},_={id:`kUFhUv`,message:`Withdrawal failed.`},v=l(null);v.displayName=`WithdrawControllerContext`;function y(){let e=u(v);if(!e)throw Error(`useWithdraw / WithdrawControllerProvider must be used inside <KitProvider withdraw={…} />. Mount KitProvider once at the host's app root with a withdraw driver.`);return e}function b(){return u(v)}function x(){return y().state}function S(){return y().effectiveState}function C(){return y().actions}function w({children:e}){let t=o(),[n,a]=p(c,s),l=E(n,a,t),u=n.name===`inProgress`?{form:n.ctx.input,submittedAt:n.ctx.submittedAt,...n.ctx.tx?{tx:n.ctx.tx}:{}}:void 0;i(t,u,u?`${u.submittedAt}|${u.tx?.hash??``}`:void 0),D(n,a,t);let d=r(n),m=T(a,l);return h(v,{value:f(()=>({state:n,effectiveState:d,dispatch:a,controller:m,actions:l}),[n,d,m,l]),children:e})}function T(e,t){let n=d(()=>{e({type:`OPEN`})},[e]),r=d(()=>{e({type:`CLOSE`})},[e]);return f(()=>({open:n,close:r,actions:t}),[n,r,t])}function E(n,r,i){let o=m(n);o.current=n;let s=m(i);s.current=i;let c=m(r);c.current=r;let{i18n:l}=e(),u=m(l);u.current=l;let p=a(),h=d(e=>{let n=s.current;c.current({type:`SUBMIT`,input:e});let r=new AbortController,i={sourceAssetSymbol:e.sourceAssetSymbol,sourceChainId:e.sourceChainId,amount:e.amount,receiveTokenSymbol:e.receiveTokenSymbol,receiveChainId:e.receiveChainId,recipientAddress:e.recipientAddress},a={beginProcessing(e){c.current({type:`BEGIN_PROCESSING`,submittedAt:Date.now(),...e?{tx:e}:{}})},setTxHash(e){c.current({type:`SET_TX_HASH`,tx:e,submittedAt:Date.now()})},fail(e){c.current({type:`MARK_FAILED`,...e?{failure:e}:{}})},succeed(){c.current({type:`MARK_SUCCEEDED`})}};n.prepareWithdrawal(i,r.signal).then(i=>{if(r.signal.aborted)return;let o=p.current.onSubmit;if(!o){c.current({type:`SUBMIT_FAILED`,failure:t(Error(`WithdrawDialog onSubmit is missing.`),u.current._(g)),input:e});return}let s=n.getSnapshot().quote,l=s.status===`ready`||s.status===`stale`?s.payload:void 0;try{let n=o({form:e,depositTarget:i.depositTarget,correlation:i.correlation,...l?{quote:l}:{}},a,r.signal);n&&typeof n.catch==`function`&&n.catch(n=>{r.signal.aborted||c.current({type:`SUBMIT_FAILED`,failure:t(n,u.current._(g)),input:e})})}catch(n){if(r.signal.aborted)return;c.current({type:`SUBMIT_FAILED`,failure:t(n,u.current._(g)),input:e})}}).catch(n=>{r.signal.aborted||c.current({type:`SUBMIT_FAILED`,failure:t(n,u.current._(g)),input:e})})},[]),_=d(()=>{c.current({type:`CLOSE`})},[]),v=d(()=>{c.current({type:`RESET`})},[]),y=d(()=>{c.current({type:`CLEAR_NOTICE`})},[]);return f(()=>({submit:h,close:_,reset:v,clearNotice:y}),[h,_,v,y])}function D(t,r,i){let a=m(t);a.current=t;let{i18n:o}=e(),s=m(o);s.current=o,n(i,(e,t)=>{if(a.current.name===`inProgress`){if(e===`succeeded`){r({type:`SETTLEMENT_SUCCEEDED`});return}if(e===`failed`){let e=t.settlement,n=e.status===`ready`||e.status===`stale`?e.payload:null,i=n&&n.kind===`failed`?{reason:s.current._(_),code:n.failureKind}:void 0;r({type:`SETTLEMENT_FAILED`,...i?{failure:i}:{}})}}})}export{w as WithdrawControllerProvider,y as useControllerContext,b as useOptionalControllerContext,C as useWithdrawActions,S as useWithdrawEffectiveState,x as useWithdrawState};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { FailureInfo } from "../../../shared/orchestrator/types.js";
|
|
2
2
|
import { WithdrawActions, WithdrawController, WithdrawEvent, WithdrawState, WithdrawStateName, WithdrawalFormSnapshot } from "./types.js";
|
|
3
3
|
import { useWithdrawState } from "./controller.js";
|
|
4
|
-
import { useWithdraw } from "./useWithdraw.js";
|
|
4
|
+
import { useOptionalWithdraw, useWithdraw } from "./useWithdraw.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isUserRejectionFailure as e}from"../../../shared/orchestrator/userRejection.js";import"../../../shared/orchestrator/index.js";const t={name:`closed`};function n(e,t){switch(e.name){case`closed`:return r(t);case`form`:return i(e,t);case`submitting`:return a(e,t);case`inProgress`:return o(e,t);case`success`:return s(e,t);case`error`:return c(e,t);default:return l(e)}}function r(e){return e.type===`OPEN`?{name:`form`}:{name:`closed`}}function i(e,t){switch(t.type){case`SUBMIT`:return{name:`submitting`,ctx:{input:t.input}};case`CLEAR_NOTICE`:return e.ctx?.notice?{name:`form`}:e;case`CLOSE`:return{name:`closed`};default:return e}}function a(t,n){switch(n.type){case`
|
|
1
|
+
import{isUserRejectionFailure as e}from"../../../shared/orchestrator/userRejection.js";import"../../../shared/orchestrator/index.js";const t={name:`closed`};function n(e,t){switch(e.name){case`closed`:return r(t);case`form`:return i(e,t);case`submitting`:return a(e,t);case`inProgress`:return o(e,t);case`success`:return s(e,t);case`error`:return c(e,t);default:return l(e)}}function r(e){return e.type===`OPEN`?{name:`form`}:{name:`closed`}}function i(e,t){switch(t.type){case`SUBMIT`:return{name:`submitting`,ctx:{input:t.input}};case`CLEAR_NOTICE`:return e.ctx?.notice?{name:`form`}:e;case`CLOSE`:return{name:`closed`};default:return e}}function a(t,n){switch(n.type){case`BEGIN_PROCESSING`:return{name:`inProgress`,ctx:{input:t.ctx.input,submittedAt:n.submittedAt,...n.tx?{tx:n.tx}:{}}};case`SET_TX_HASH`:return{name:`inProgress`,ctx:{input:t.ctx.input,submittedAt:n.submittedAt,tx:n.tx}};case`MARK_SUCCEEDED`:return{name:`success`,ctx:{input:t.ctx.input}};case`MARK_FAILED`:return{name:`error`,ctx:{input:t.ctx.input,...n.failure?{failure:n.failure}:{}}};case`SUBMIT_FAILED`:return e(n.failure)?{name:`form`,ctx:{notice:n.failure.reason}}:{name:`error`,ctx:{input:n.input,failure:n.failure}};case`CLOSE`:return{name:`closed`};default:return t}}function o(e,t){switch(t.type){case`SET_TX_HASH`:return{name:`inProgress`,ctx:{...e.ctx,tx:t.tx}};case`BEGIN_PROCESSING`:return{name:`inProgress`,ctx:{input:e.ctx.input,submittedAt:e.ctx.submittedAt,...e.ctx.tx?{tx:e.ctx.tx}:t.tx?{tx:t.tx}:{}}};case`MARK_SUCCEEDED`:return{name:`success`,ctx:{input:e.ctx.input,...e.ctx.tx?{tx:e.ctx.tx}:{}}};case`MARK_FAILED`:return{name:`error`,ctx:{input:e.ctx.input,...e.ctx.tx?{tx:e.ctx.tx}:{},...t.failure?{failure:t.failure}:{}}};case`SETTLEMENT_SUCCEEDED`:return{name:`success`,ctx:{input:e.ctx.input,...e.ctx.tx?{tx:e.ctx.tx}:{}}};case`SETTLEMENT_FAILED`:return{name:`error`,ctx:{input:e.ctx.input,...e.ctx.tx?{tx:e.ctx.tx}:{},...t.failure?{failure:t.failure}:{}}};case`CLOSE`:return{name:`closed`};default:return e}}function s(e,t){switch(t.type){case`RESET`:return{name:`form`};case`CLOSE`:return{name:`closed`};default:return e}}function c(e,t){switch(t.type){case`RESET`:return{name:`form`};case`CLOSE`:return{name:`closed`};default:return e}}function l(e){throw Error(`Unhandled withdraw state: ${JSON.stringify(e)}`)}export{t as initialState,n as reducer};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TxRef } from "../../../shared/driver/types.js";
|
|
2
2
|
import { FailureInfo } from "../../../shared/orchestrator/types.js";
|
|
3
|
-
|
|
3
|
+
import { WithdrawalQuotePayload } from "../driver/payloads.js";
|
|
4
|
+
import { WithdrawPreparation } from "../driver/types.js";
|
|
4
5
|
//#region src/flows/withdraw/orchestrator/types.d.ts
|
|
5
6
|
/**
|
|
6
7
|
* Form values captured at submit time. The orchestrator carries this snapshot through every
|
|
@@ -22,22 +23,24 @@ interface WithdrawalFormSnapshot {
|
|
|
22
23
|
receiveChainId: number;
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
|
-
* State machine state for the orchestrated withdraw dialog. Per-state discriminated `ctx`
|
|
26
|
-
* what data is available
|
|
27
|
-
* unrepresentable.
|
|
26
|
+
* State machine state for the orchestrated withdraw dialog. Per-state discriminated `ctx`
|
|
27
|
+
* narrows what data is available.
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* **Host-paced lifecycle** (different from the old wagmi-signed model): the kit stays in
|
|
30
|
+
* `submitting` until the host's `onSubmit` callback calls one of the controller's actions
|
|
31
|
+
* (`beginProcessing`, `fail`, `succeed`). `inProgress` accepts an optional `tx` — the host may
|
|
32
|
+
* move the user into processing before a broadcast tx hash exists; the kit polls
|
|
33
|
+
* `gateway/{owner}` and best-matches the relevant settlement (destination tuple + amount +
|
|
34
|
+
* submit-time window) until the host supplies a tx hash via `setTxHash`. `success` / `error`
|
|
35
|
+
* similarly accept optional `tx` since the host may declare a terminal verdict directly.
|
|
31
36
|
*/
|
|
32
37
|
type WithdrawState = {
|
|
33
38
|
name: "closed";
|
|
34
39
|
} | {
|
|
35
40
|
name: "form";
|
|
36
41
|
/**
|
|
37
|
-
* Optional notice rendered inline near the submit footer.
|
|
38
|
-
*
|
|
39
|
-
* recipient + amount + receive selection) with `notice = "Signature declined…"` so they
|
|
40
|
-
* can retry without losing context. Cleared on the next SUBMIT or CLOSE.
|
|
42
|
+
* Optional notice rendered inline near the submit footer. Cleared on the next SUBMIT
|
|
43
|
+
* or CLOSE.
|
|
41
44
|
*/
|
|
42
45
|
ctx?: {
|
|
43
46
|
notice?: string;
|
|
@@ -50,24 +53,28 @@ type WithdrawState = {
|
|
|
50
53
|
} | {
|
|
51
54
|
name: "inProgress";
|
|
52
55
|
ctx: {
|
|
53
|
-
input: WithdrawalFormSnapshot;
|
|
54
|
-
|
|
56
|
+
input: WithdrawalFormSnapshot; /** Unix-ms timestamp the host moved the FSM into processing (drives best-match windowing). */
|
|
57
|
+
submittedAt: number;
|
|
58
|
+
/**
|
|
59
|
+
* Source-chain broadcast hash, when the host has surfaced one via
|
|
60
|
+
* `actions.setTxHash`. Absent while the kit relies on the best-match heuristic.
|
|
61
|
+
*/
|
|
62
|
+
tx?: TxRef;
|
|
55
63
|
};
|
|
56
64
|
} | {
|
|
57
65
|
name: "success";
|
|
58
66
|
ctx: {
|
|
59
67
|
input: WithdrawalFormSnapshot;
|
|
60
|
-
tx
|
|
68
|
+
tx?: TxRef;
|
|
61
69
|
};
|
|
62
70
|
} | {
|
|
63
71
|
name: "error";
|
|
64
72
|
ctx: {
|
|
65
73
|
/**
|
|
66
74
|
* Form snapshot captured at submit time. Set when error follows a submit attempt;
|
|
67
|
-
* absent when the error path was reached without a known prior submit
|
|
68
|
-
* unreachable in V2 — kept optional so resume-style entries can re-use the slot).
|
|
75
|
+
* absent when the error path was reached without a known prior submit.
|
|
69
76
|
*/
|
|
70
|
-
input?: WithdrawalFormSnapshot; /** Optional non-settlement failure (quote / submission rejection). */
|
|
77
|
+
input?: WithdrawalFormSnapshot; /** Optional non-settlement failure (quote / submission rejection, host-supplied failure). */
|
|
71
78
|
failure?: FailureInfo; /** Source-chain broadcast tx hash when the error followed a successful broadcast. */
|
|
72
79
|
tx?: TxRef;
|
|
73
80
|
};
|
|
@@ -79,6 +86,16 @@ type WithdrawState = {
|
|
|
79
86
|
type WithdrawStateName = WithdrawState["name"];
|
|
80
87
|
/**
|
|
81
88
|
* Reducer event union. Strict discriminated; no stringly-typed transitions.
|
|
89
|
+
*
|
|
90
|
+
* The host-paced lifecycle splits the old `SUBMIT_CONFIRMED { tx }` event into three pieces so
|
|
91
|
+
* the host can move the user forward at whichever step their backend actually completes:
|
|
92
|
+
*
|
|
93
|
+
* - `BEGIN_PROCESSING { tx?, submittedAt }` — host accepted the request; move to inProgress with
|
|
94
|
+
* or without a tx hash.
|
|
95
|
+
* - `SET_TX_HASH { tx }` — host surfaced a broadcast hash later; upgrade best-match polling to
|
|
96
|
+
* tx-anchored.
|
|
97
|
+
* - `MARK_SUCCEEDED` / `MARK_FAILED { failure? }` — host short-circuits to a terminal verdict
|
|
98
|
+
* (e.g. their own settlement verification ran independently of Stridge's poll).
|
|
82
99
|
*/
|
|
83
100
|
type WithdrawEvent = {
|
|
84
101
|
type: "OPEN";
|
|
@@ -88,12 +105,22 @@ type WithdrawEvent = {
|
|
|
88
105
|
type: "SUBMIT";
|
|
89
106
|
input: WithdrawalFormSnapshot;
|
|
90
107
|
} | {
|
|
91
|
-
type: "
|
|
108
|
+
type: "BEGIN_PROCESSING";
|
|
109
|
+
submittedAt: number;
|
|
110
|
+
tx?: TxRef;
|
|
111
|
+
} | {
|
|
112
|
+
type: "SET_TX_HASH";
|
|
92
113
|
tx: TxRef;
|
|
114
|
+
submittedAt: number;
|
|
93
115
|
} | {
|
|
94
116
|
type: "SUBMIT_FAILED";
|
|
95
117
|
failure: FailureInfo;
|
|
96
118
|
input: WithdrawalFormSnapshot;
|
|
119
|
+
} | {
|
|
120
|
+
type: "MARK_SUCCEEDED";
|
|
121
|
+
} | {
|
|
122
|
+
type: "MARK_FAILED";
|
|
123
|
+
failure?: FailureInfo;
|
|
97
124
|
} | {
|
|
98
125
|
type: "SETTLEMENT_SUCCEEDED";
|
|
99
126
|
} | {
|
|
@@ -101,15 +128,7 @@ type WithdrawEvent = {
|
|
|
101
128
|
failure?: FailureInfo;
|
|
102
129
|
} | {
|
|
103
130
|
type: "RESET";
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Drops the inline notice on the `form` state. Dispatched by the form widget when the user
|
|
107
|
-
* starts editing again after a wallet-rejection landed them back on `form{notice}`. Mirror of
|
|
108
|
-
* deposit's `regenerating → ready` transition (where the notice clears as a side-effect of
|
|
109
|
-
* the next quote resolving) — withdraw's form has no FSM-driven phase to ride on, so the
|
|
110
|
-
* widget signals it explicitly.
|
|
111
|
-
*/
|
|
112
|
-
| {
|
|
131
|
+
} | {
|
|
113
132
|
type: "CLEAR_NOTICE";
|
|
114
133
|
};
|
|
115
134
|
/**
|
|
@@ -134,9 +153,10 @@ interface WithdrawController {
|
|
|
134
153
|
*/
|
|
135
154
|
interface WithdrawActions {
|
|
136
155
|
/**
|
|
137
|
-
* Submits the withdrawal
|
|
138
|
-
*
|
|
139
|
-
* the
|
|
156
|
+
* Submits the withdrawal. Dispatches `SUBMIT` synchronously (so the form flips to the
|
|
157
|
+
* loading-button state) and then fires the host's `<WithdrawDialog onSubmit>` callback with
|
|
158
|
+
* the prepared UDA target + a `WithdrawSubmitActions` handle. The kit stays in `submitting`
|
|
159
|
+
* until the host calls one of those actions (`beginProcessing`, `fail`, `succeed`).
|
|
140
160
|
*/
|
|
141
161
|
submit(input: WithdrawalFormSnapshot): void;
|
|
142
162
|
/** Close the dialog. Idempotent. */
|
|
@@ -147,10 +167,64 @@ interface WithdrawActions {
|
|
|
147
167
|
*/
|
|
148
168
|
reset(): void;
|
|
149
169
|
/**
|
|
150
|
-
* Clear the form's inline notice
|
|
151
|
-
* No-op when there's no notice or the FSM isn't on `form`.
|
|
170
|
+
* Clear the form's inline notice. No-op when there's no notice or the FSM isn't on `form`.
|
|
152
171
|
*/
|
|
153
172
|
clearNotice(): void;
|
|
154
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Payload the kit hands to the host's `<WithdrawDialog onSubmit>` callback. Carries everything
|
|
176
|
+
* the host needs to broadcast the source-chain transfer to the UDA (or to validate the request
|
|
177
|
+
* server-side before broadcasting / queueing).
|
|
178
|
+
*/
|
|
179
|
+
interface WithdrawSubmitInput {
|
|
180
|
+
/** What the user picked on the form (recipient, amount, receive token + chain). */
|
|
181
|
+
form: WithdrawalFormSnapshot;
|
|
182
|
+
/** Where the host should send brand-currency funds to trigger the bridge. */
|
|
183
|
+
depositTarget: WithdrawPreparation["depositTarget"];
|
|
184
|
+
/** Stridge correlation slot — useful for backend logs / cross-system traces. */
|
|
185
|
+
correlation: WithdrawPreparation["correlation"];
|
|
186
|
+
/** Active quote payload at submit time, when one is available. */
|
|
187
|
+
quote?: WithdrawalQuotePayload;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Imperative handles the host's `onSubmit` callback receives. Each action advances the kit's
|
|
191
|
+
* FSM at the point the host's backend reaches the matching state. All actions are optional —
|
|
192
|
+
* the host calls only what fits their flow (e.g. backend pre-validates and accepts ⇒
|
|
193
|
+
* `beginProcessing()`; later the broadcast lands ⇒ `setTxHash({ hash })`; settlement watching
|
|
194
|
+
* via Stridge takes over from there). The kit also exposes a `signal` for cancellation when
|
|
195
|
+
* the user closes the dialog mid-submit.
|
|
196
|
+
*/
|
|
197
|
+
interface WithdrawSubmitActions {
|
|
198
|
+
/**
|
|
199
|
+
* Move the FSM into `inProgress`. Pass `tx` if a broadcast hash already exists at this point;
|
|
200
|
+
* otherwise omit — the kit polls `gateway/{owner}` with a best-match heuristic until you
|
|
201
|
+
* call {@link setTxHash}. Idempotent — calling more than once is a no-op.
|
|
202
|
+
*/
|
|
203
|
+
beginProcessing(tx?: TxRef): void;
|
|
204
|
+
/**
|
|
205
|
+
* Surface a broadcast hash mid-processing. Upgrades the watcher from best-match to
|
|
206
|
+
* tx-anchored. Legal from `inProgress` or `submitting` (auto-promotes to `inProgress`).
|
|
207
|
+
*/
|
|
208
|
+
setTxHash(tx: TxRef): void;
|
|
209
|
+
/**
|
|
210
|
+
* Mark the withdraw failed. Legal from `submitting` (pre-broadcast rejection) and
|
|
211
|
+
* `inProgress` (post-broadcast failure). The optional `failure` carries a localized
|
|
212
|
+
* reason + machine code for analytics; omit when the host has nothing meaningful to
|
|
213
|
+
* report and just needs to terminate the flow.
|
|
214
|
+
*/
|
|
215
|
+
fail(failure?: FailureInfo): void;
|
|
216
|
+
/**
|
|
217
|
+
* Mark the withdraw succeeded directly. Useful when the host runs their own settlement
|
|
218
|
+
* verification independently of Stridge's poll. Legal from `submitting` and `inProgress`.
|
|
219
|
+
*/
|
|
220
|
+
succeed(): void;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Host-supplied callback fired when the user submits the withdrawal form. The kit hands the
|
|
224
|
+
* callback the resolved {@link WithdrawSubmitInput} plus a {@link WithdrawSubmitActions} handle
|
|
225
|
+
* the host calls to advance the FSM. The kit does NOT await the callback's promise — the host
|
|
226
|
+
* is in control of pacing via the actions. The `signal` aborts when the user closes the dialog.
|
|
227
|
+
*/
|
|
228
|
+
type WithdrawSubmitCallback = (input: WithdrawSubmitInput, actions: WithdrawSubmitActions, signal: AbortSignal) => void | Promise<void>;
|
|
155
229
|
//#endregion
|
|
156
|
-
export { WithdrawActions, WithdrawController, WithdrawEvent, WithdrawState, WithdrawStateName, WithdrawalFormSnapshot };
|
|
230
|
+
export { WithdrawActions, WithdrawController, WithdrawEvent, WithdrawState, WithdrawStateName, WithdrawSubmitActions, WithdrawSubmitCallback, WithdrawSubmitInput, WithdrawalFormSnapshot };
|
|
@@ -19,5 +19,22 @@ import { WithdrawController } from "./types.js";
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
declare function useWithdraw(): WithdrawController;
|
|
22
|
+
/**
|
|
23
|
+
* Non-throwing variant of {@link useWithdraw} — returns `null` when called outside a
|
|
24
|
+
* `<KitProvider withdraw={…} />`. Lets hosts mount `<StridgeProvider />` conditionally
|
|
25
|
+
* (e.g. only after a wallet is connected) without descendants crashing the moment they render
|
|
26
|
+
* before the provider exists.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const withdraw = useOptionalWithdraw();
|
|
31
|
+
* return (
|
|
32
|
+
* <button onClick={() => withdraw?.open()} disabled={!withdraw}>
|
|
33
|
+
* Withdraw
|
|
34
|
+
* </button>
|
|
35
|
+
* );
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function useOptionalWithdraw(): WithdrawController | null;
|
|
22
39
|
//#endregion
|
|
23
|
-
export { useWithdraw };
|
|
40
|
+
export { useOptionalWithdraw, useWithdraw };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useControllerContext as e}from"./controller.js";function
|
|
1
|
+
"use client";import{useControllerContext as e,useOptionalControllerContext as t}from"./controller.js";function n(){return e().controller}function r(){return t()?.controller??null}export{r as useOptionalWithdraw,n as useWithdraw};
|