@rhinestone/deposit-modal 0.1.19 → 0.1.21
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 +23 -1
- package/dist/index.cjs +67 -27
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.mjs +67 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,6 +124,28 @@ import "@rhinestone/deposit-modal/styles.css";
|
|
|
124
124
|
/>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
### Withdrawal flow
|
|
128
|
+
|
|
129
|
+
Prerequisites:
|
|
130
|
+
- A 1/1 Safe (single owner) with ERC20 token balance on a supported source chain
|
|
131
|
+
- The connected wallet must be the sole owner of the Safe
|
|
132
|
+
|
|
133
|
+
End-to-end steps:
|
|
134
|
+
1. User connects wallet (must be the Safe owner)
|
|
135
|
+
2. Modal creates a Rhinestone smart account and signs session authorization
|
|
136
|
+
3. Modal registers the smart account with the backend (`/register`)
|
|
137
|
+
4. User enters withdrawal amount
|
|
138
|
+
5. User signs an EIP-712 `execTransaction` authorizing the ERC20 transfer from the Safe to the smart account
|
|
139
|
+
6. Modal calls `/process/:address` to trigger the bridge intent
|
|
140
|
+
7. Modal polls `/status/:address` for webhook events until the bridge completes on the destination chain
|
|
141
|
+
|
|
142
|
+
To test with the demo configurator:
|
|
143
|
+
1. Switch flow to "Withdraw"
|
|
144
|
+
2. Enter the Safe address
|
|
145
|
+
3. Select the source chain/token matching the Safe's holdings
|
|
146
|
+
4. Select the destination chain/token
|
|
147
|
+
5. The connected wallet (Privy embedded or Reown) must be the Safe's sole owner
|
|
148
|
+
|
|
127
149
|
### Additional Props (beyond shared DepositModal props)
|
|
128
150
|
|
|
129
151
|
| Prop | Type | Required | Description |
|
|
@@ -156,7 +178,7 @@ Also supports `onReady`, `onConnected`, and `onError` (same as DepositModal).
|
|
|
156
178
|
|
|
157
179
|
**Branding**: `logoUrl`, `title`
|
|
158
180
|
|
|
159
|
-
**UI Config**: `showLogo`, `showStepper`, `showBackButton`, `balanceTitle`, `maxDepositUsd`
|
|
181
|
+
**UI Config**: `showLogo`, `showStepper`, `showBackButton`, `balanceTitle`, `maxDepositUsd`, `minDepositUsd`
|
|
160
182
|
|
|
161
183
|
## Utility Exports
|
|
162
184
|
|
package/dist/index.cjs
CHANGED
|
@@ -1937,6 +1937,12 @@ function AmountStep({
|
|
|
1937
1937
|
);
|
|
1938
1938
|
return;
|
|
1939
1939
|
}
|
|
1940
|
+
if (uiConfig?.minDepositUsd && usdValue < uiConfig.minDepositUsd) {
|
|
1941
|
+
setError(
|
|
1942
|
+
`Minimum deposit is ${currencyFormatter.format(uiConfig.minDepositUsd)}`
|
|
1943
|
+
);
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1940
1946
|
if (tokenPriceUsd === null || tokenPriceUsd === 0) {
|
|
1941
1947
|
setError("Unable to determine token price");
|
|
1942
1948
|
return;
|
|
@@ -2210,6 +2216,7 @@ function ConfirmStep({
|
|
|
2210
2216
|
walletClient,
|
|
2211
2217
|
address,
|
|
2212
2218
|
smartAccount,
|
|
2219
|
+
recipient,
|
|
2213
2220
|
asset,
|
|
2214
2221
|
amount,
|
|
2215
2222
|
balance,
|
|
@@ -2305,10 +2312,11 @@ function ConfirmStep({
|
|
|
2305
2312
|
if (!account || !chain) {
|
|
2306
2313
|
throw new Error("Wallet not properly connected");
|
|
2307
2314
|
}
|
|
2315
|
+
const transferTo = sameRoute ? recipient : smartAccount;
|
|
2308
2316
|
const hash = isNativeAsset(asset) ? await walletClient.sendTransaction({
|
|
2309
2317
|
account,
|
|
2310
2318
|
chain,
|
|
2311
|
-
to:
|
|
2319
|
+
to: transferTo,
|
|
2312
2320
|
value: amountUnits
|
|
2313
2321
|
}) : await walletClient.writeContract({
|
|
2314
2322
|
account,
|
|
@@ -2316,7 +2324,7 @@ function ConfirmStep({
|
|
|
2316
2324
|
address: asset.token,
|
|
2317
2325
|
abi: import_viem5.erc20Abi,
|
|
2318
2326
|
functionName: "transfer",
|
|
2319
|
-
args: [
|
|
2327
|
+
args: [transferTo, amountUnits]
|
|
2320
2328
|
});
|
|
2321
2329
|
onDepositSubmitted?.(hash, asset.chainId, amountUnits.toString());
|
|
2322
2330
|
onConfirm(hash, asset.chainId, amountUnits.toString(), asset.token);
|
|
@@ -2525,8 +2533,8 @@ function getEventTxHash(event) {
|
|
|
2525
2533
|
return asString(event.data?.transactionHash);
|
|
2526
2534
|
}
|
|
2527
2535
|
if (event.type === "bridge-started" || event.type === "bridge-complete") {
|
|
2528
|
-
const
|
|
2529
|
-
return asString(
|
|
2536
|
+
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
2537
|
+
return asString(deposit?.transactionHash);
|
|
2530
2538
|
}
|
|
2531
2539
|
if (event.type === "bridge-failed" || event.type === "error") {
|
|
2532
2540
|
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
@@ -2574,19 +2582,29 @@ function ProcessingStep({
|
|
|
2574
2582
|
amount,
|
|
2575
2583
|
waitForFinalTx,
|
|
2576
2584
|
service,
|
|
2585
|
+
directTransfer,
|
|
2577
2586
|
flowLabel = "deposit",
|
|
2587
|
+
debug,
|
|
2578
2588
|
onClose,
|
|
2579
2589
|
onNewDeposit,
|
|
2580
2590
|
onDepositComplete,
|
|
2581
2591
|
onDepositFailed,
|
|
2582
2592
|
onError
|
|
2583
2593
|
}) {
|
|
2584
|
-
const [state, setState] = (0, import_react6.useState)(
|
|
2594
|
+
const [state, setState] = (0, import_react6.useState)(
|
|
2595
|
+
directTransfer ? { type: "complete" } : { type: "processing" }
|
|
2596
|
+
);
|
|
2585
2597
|
const [elapsedSeconds, setElapsedSeconds] = (0, import_react6.useState)(0);
|
|
2586
2598
|
const startTimeRef = (0, import_react6.useRef)(Date.now());
|
|
2587
2599
|
const intervalRef = (0, import_react6.useRef)(null);
|
|
2588
|
-
const sameChainAndToken = targetChain === sourceChain && targetToken.toLowerCase() === sourceToken.toLowerCase();
|
|
2589
2600
|
(0, import_react6.useEffect)(() => {
|
|
2601
|
+
if (directTransfer) {
|
|
2602
|
+
onDepositComplete?.(txHash);
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
}, [directTransfer, txHash, onDepositComplete]);
|
|
2606
|
+
(0, import_react6.useEffect)(() => {
|
|
2607
|
+
if (directTransfer) return;
|
|
2590
2608
|
startTimeRef.current = Date.now();
|
|
2591
2609
|
intervalRef.current = setInterval(() => {
|
|
2592
2610
|
setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1e3));
|
|
@@ -2594,7 +2612,7 @@ function ProcessingStep({
|
|
|
2594
2612
|
return () => {
|
|
2595
2613
|
if (intervalRef.current) clearInterval(intervalRef.current);
|
|
2596
2614
|
};
|
|
2597
|
-
}, []);
|
|
2615
|
+
}, [directTransfer]);
|
|
2598
2616
|
(0, import_react6.useEffect)(() => {
|
|
2599
2617
|
if (state.type === "complete" || state.type === "failed" || state.type === "error") {
|
|
2600
2618
|
if (intervalRef.current) {
|
|
@@ -2607,6 +2625,7 @@ function ProcessingStep({
|
|
|
2607
2625
|
const pollTimeoutRef = (0, import_react6.useRef)(null);
|
|
2608
2626
|
const processTimeoutRef = (0, import_react6.useRef)(null);
|
|
2609
2627
|
(0, import_react6.useEffect)(() => {
|
|
2628
|
+
if (directTransfer) return;
|
|
2610
2629
|
if (state.type !== "processing") {
|
|
2611
2630
|
pollIntervalRef.current = INITIAL_POLL_INTERVAL;
|
|
2612
2631
|
return;
|
|
@@ -2618,6 +2637,15 @@ function ProcessingStep({
|
|
|
2618
2637
|
const lastEvent2 = data.lastEvent;
|
|
2619
2638
|
const eventMatchesTx = isEventForTx(lastEvent2, txHash);
|
|
2620
2639
|
const eventForCurrentTx = eventMatchesTx ? lastEvent2 : void 0;
|
|
2640
|
+
if (debug && lastEvent2) {
|
|
2641
|
+
const eventData = lastEvent2.data;
|
|
2642
|
+
console.log("[deposit-modal] status poll", {
|
|
2643
|
+
type: lastEvent2.type,
|
|
2644
|
+
matchesTx: eventMatchesTx,
|
|
2645
|
+
intentId: eventData?.intentId,
|
|
2646
|
+
data: eventData
|
|
2647
|
+
});
|
|
2648
|
+
}
|
|
2621
2649
|
if (!isMounted) return;
|
|
2622
2650
|
if (eventForCurrentTx?.type === "bridge-complete") {
|
|
2623
2651
|
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
@@ -2630,11 +2658,6 @@ function ProcessingStep({
|
|
|
2630
2658
|
onDepositComplete?.(txHash);
|
|
2631
2659
|
return;
|
|
2632
2660
|
}
|
|
2633
|
-
if (eventForCurrentTx?.type === "deposit-received" && sameChainAndToken) {
|
|
2634
|
-
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
2635
|
-
onDepositComplete?.(txHash);
|
|
2636
|
-
return;
|
|
2637
|
-
}
|
|
2638
2661
|
if (eventForCurrentTx?.type === "bridge-failed") {
|
|
2639
2662
|
const formatted = formatBridgeFailedMessage(eventForCurrentTx);
|
|
2640
2663
|
setState({
|
|
@@ -2679,16 +2702,17 @@ function ProcessingStep({
|
|
|
2679
2702
|
}
|
|
2680
2703
|
};
|
|
2681
2704
|
}, [
|
|
2705
|
+
directTransfer,
|
|
2682
2706
|
state.type,
|
|
2683
2707
|
smartAccount,
|
|
2684
2708
|
txHash,
|
|
2685
2709
|
service,
|
|
2686
|
-
sameChainAndToken,
|
|
2687
2710
|
waitForFinalTx,
|
|
2688
2711
|
onDepositComplete,
|
|
2689
2712
|
onDepositFailed
|
|
2690
2713
|
]);
|
|
2691
2714
|
(0, import_react6.useEffect)(() => {
|
|
2715
|
+
if (directTransfer) return;
|
|
2692
2716
|
if (state.type !== "processing") {
|
|
2693
2717
|
if (processTimeoutRef.current) {
|
|
2694
2718
|
clearTimeout(processTimeoutRef.current);
|
|
@@ -2707,7 +2731,7 @@ function ProcessingStep({
|
|
|
2707
2731
|
processTimeoutRef.current = null;
|
|
2708
2732
|
}
|
|
2709
2733
|
};
|
|
2710
|
-
}, [state.type, onError]);
|
|
2734
|
+
}, [directTransfer, state.type, onError]);
|
|
2711
2735
|
const isError = state.type === "error" || state.type === "failed";
|
|
2712
2736
|
const isComplete = state.type === "complete";
|
|
2713
2737
|
const isProcessing = state.type === "processing";
|
|
@@ -2761,7 +2785,7 @@ function ProcessingStep({
|
|
|
2761
2785
|
}
|
|
2762
2786
|
) }),
|
|
2763
2787
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rs-success-title", children: isEarlyComplete ? `${flowCapitalized} confirmed` : `${flowCapitalized} successful` }),
|
|
2764
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rs-success-subtitle", children: isEarlyComplete ? "Your transfer has been confirmed and funds will arrive shortly." :
|
|
2788
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rs-success-subtitle", children: directTransfer ? "Your transfer is complete." : isEarlyComplete ? "Your transfer has been confirmed and funds will arrive shortly." : "Your funds have been successfully bridged." })
|
|
2765
2789
|
] }),
|
|
2766
2790
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rs-card", children: [
|
|
2767
2791
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rs-card-row", children: [
|
|
@@ -3544,6 +3568,9 @@ var init_public_client = __esm({
|
|
|
3544
3568
|
});
|
|
3545
3569
|
|
|
3546
3570
|
// src/DepositFlow.tsx
|
|
3571
|
+
function isSameRoute(sourceChain, sourceToken, targetChain, targetToken) {
|
|
3572
|
+
return sourceChain === targetChain && sourceToken.toLowerCase() === targetToken.toLowerCase();
|
|
3573
|
+
}
|
|
3547
3574
|
function DepositFlow({
|
|
3548
3575
|
dappWalletClient,
|
|
3549
3576
|
dappPublicClient,
|
|
@@ -3572,7 +3599,8 @@ function DepositFlow({
|
|
|
3572
3599
|
onDepositSubmitted,
|
|
3573
3600
|
onDepositComplete,
|
|
3574
3601
|
onDepositFailed,
|
|
3575
|
-
onError
|
|
3602
|
+
onError,
|
|
3603
|
+
debug
|
|
3576
3604
|
}) {
|
|
3577
3605
|
const [step, setStep] = (0, import_react9.useState)({ type: "setup" });
|
|
3578
3606
|
const [flowMode, setFlowMode] = (0, import_react9.useState)(null);
|
|
@@ -3743,12 +3771,13 @@ function DepositFlow({
|
|
|
3743
3771
|
txHash,
|
|
3744
3772
|
sourceChain: chainId,
|
|
3745
3773
|
sourceToken: token,
|
|
3746
|
-
amount
|
|
3774
|
+
amount,
|
|
3775
|
+
directTransfer: isSameRoute(chainId, token, targetChain, targetToken)
|
|
3747
3776
|
};
|
|
3748
3777
|
});
|
|
3749
3778
|
onDepositSubmitted?.({ txHash, sourceChain: chainId, amount });
|
|
3750
3779
|
},
|
|
3751
|
-
[onDepositSubmitted]
|
|
3780
|
+
[onDepositSubmitted, targetChain, targetToken]
|
|
3752
3781
|
);
|
|
3753
3782
|
const handleConnected = (0, import_react9.useCallback)(
|
|
3754
3783
|
(addr, smartAccount) => {
|
|
@@ -3795,11 +3824,12 @@ function DepositFlow({
|
|
|
3795
3824
|
txHash,
|
|
3796
3825
|
sourceChain: chainId,
|
|
3797
3826
|
sourceToken: token,
|
|
3798
|
-
amount
|
|
3827
|
+
amount,
|
|
3828
|
+
directTransfer: isSameRoute(chainId, token, targetChain, targetToken)
|
|
3799
3829
|
};
|
|
3800
3830
|
});
|
|
3801
3831
|
},
|
|
3802
|
-
[]
|
|
3832
|
+
[targetChain, targetToken]
|
|
3803
3833
|
);
|
|
3804
3834
|
const handleDepositSubmittedCallback = (0, import_react9.useCallback)(
|
|
3805
3835
|
(txHash, sourceChain, amount) => {
|
|
@@ -3908,11 +3938,13 @@ function DepositFlow({
|
|
|
3908
3938
|
amount: step.amount,
|
|
3909
3939
|
waitForFinalTx,
|
|
3910
3940
|
service,
|
|
3941
|
+
directTransfer: step.directTransfer,
|
|
3911
3942
|
onClose,
|
|
3912
3943
|
onNewDeposit: handleNewDeposit,
|
|
3913
3944
|
onDepositComplete: handleDepositComplete,
|
|
3914
3945
|
onDepositFailed: handleDepositFailed,
|
|
3915
|
-
onError: handleError
|
|
3946
|
+
onError: handleError,
|
|
3947
|
+
debug
|
|
3916
3948
|
}
|
|
3917
3949
|
)
|
|
3918
3950
|
] });
|
|
@@ -3981,6 +4013,7 @@ function DepositFlow({
|
|
|
3981
4013
|
walletClient: signerContext.walletClient,
|
|
3982
4014
|
address: ownerAddress,
|
|
3983
4015
|
smartAccount: step.smartAccount,
|
|
4016
|
+
recipient,
|
|
3984
4017
|
asset: step.asset,
|
|
3985
4018
|
amount: step.amount,
|
|
3986
4019
|
balance: step.balance,
|
|
@@ -4004,6 +4037,7 @@ function DepositFlow({
|
|
|
4004
4037
|
amount: step.amount,
|
|
4005
4038
|
waitForFinalTx,
|
|
4006
4039
|
service,
|
|
4040
|
+
directTransfer: step.directTransfer,
|
|
4007
4041
|
onClose,
|
|
4008
4042
|
onNewDeposit: handleNewDeposit,
|
|
4009
4043
|
onDepositComplete: handleDepositComplete,
|
|
@@ -4238,7 +4272,8 @@ function DepositModalInner({
|
|
|
4238
4272
|
onDepositSubmitted,
|
|
4239
4273
|
onDepositComplete,
|
|
4240
4274
|
onDepositFailed,
|
|
4241
|
-
onError
|
|
4275
|
+
onError,
|
|
4276
|
+
debug
|
|
4242
4277
|
}) {
|
|
4243
4278
|
const modalRef = (0, import_react13.useRef)(null);
|
|
4244
4279
|
const [currentStepIndex, setCurrentStepIndex] = (0, import_react13.useState)(0);
|
|
@@ -4406,7 +4441,8 @@ function DepositModalInner({
|
|
|
4406
4441
|
onDepositSubmitted,
|
|
4407
4442
|
onDepositComplete,
|
|
4408
4443
|
onDepositFailed,
|
|
4409
|
-
onError
|
|
4444
|
+
onError,
|
|
4445
|
+
debug
|
|
4410
4446
|
}
|
|
4411
4447
|
)
|
|
4412
4448
|
] })
|
|
@@ -5207,7 +5243,8 @@ function WithdrawFlow({
|
|
|
5207
5243
|
onWithdrawSubmitted,
|
|
5208
5244
|
onWithdrawComplete,
|
|
5209
5245
|
onWithdrawFailed,
|
|
5210
|
-
onError
|
|
5246
|
+
onError,
|
|
5247
|
+
debug
|
|
5211
5248
|
}) {
|
|
5212
5249
|
const [step, setStep] = (0, import_react15.useState)({ type: "form" });
|
|
5213
5250
|
const [isSubmitting, setIsSubmitting] = (0, import_react15.useState)(false);
|
|
@@ -5596,7 +5633,8 @@ function WithdrawFlow({
|
|
|
5596
5633
|
onNewDeposit: () => setStep({ type: "form" }),
|
|
5597
5634
|
onDepositComplete: handleWithdrawComplete,
|
|
5598
5635
|
onDepositFailed: handleWithdrawFailed,
|
|
5599
|
-
onError: handleError
|
|
5636
|
+
onError: handleError,
|
|
5637
|
+
debug
|
|
5600
5638
|
}
|
|
5601
5639
|
)
|
|
5602
5640
|
] });
|
|
@@ -5697,7 +5735,8 @@ function WithdrawModalInner({
|
|
|
5697
5735
|
onWithdrawSubmitted,
|
|
5698
5736
|
onWithdrawComplete,
|
|
5699
5737
|
onWithdrawFailed,
|
|
5700
|
-
onError
|
|
5738
|
+
onError,
|
|
5739
|
+
debug
|
|
5701
5740
|
}) {
|
|
5702
5741
|
const modalRef = (0, import_react17.useRef)(null);
|
|
5703
5742
|
const [currentStepIndex, setCurrentStepIndex] = (0, import_react17.useState)(0);
|
|
@@ -5863,7 +5902,8 @@ function WithdrawModalInner({
|
|
|
5863
5902
|
onWithdrawSubmitted,
|
|
5864
5903
|
onWithdrawComplete,
|
|
5865
5904
|
onWithdrawFailed,
|
|
5866
|
-
onError
|
|
5905
|
+
onError,
|
|
5906
|
+
debug
|
|
5867
5907
|
}
|
|
5868
5908
|
)
|
|
5869
5909
|
] })
|
package/dist/index.d.cts
CHANGED
|
@@ -19,6 +19,7 @@ interface DepositModalUIConfig {
|
|
|
19
19
|
showBackButton?: boolean;
|
|
20
20
|
balanceTitle?: string;
|
|
21
21
|
maxDepositUsd?: number;
|
|
22
|
+
minDepositUsd?: number;
|
|
22
23
|
}
|
|
23
24
|
interface DepositModalBranding {
|
|
24
25
|
logoUrl?: string;
|
|
@@ -71,7 +72,7 @@ interface DepositModalProps {
|
|
|
71
72
|
sourceChain?: Chain | number;
|
|
72
73
|
sourceToken?: Address;
|
|
73
74
|
defaultAmount?: string;
|
|
74
|
-
recipient
|
|
75
|
+
recipient: Address;
|
|
75
76
|
backendUrl?: string;
|
|
76
77
|
rhinestoneApiKey?: string;
|
|
77
78
|
signerAddress?: Address;
|
|
@@ -91,6 +92,7 @@ interface DepositModalProps {
|
|
|
91
92
|
onDepositComplete?: (data: DepositCompleteEventData) => void;
|
|
92
93
|
onDepositFailed?: (data: DepositFailedEventData) => void;
|
|
93
94
|
onError?: (data: ErrorEventData) => void;
|
|
95
|
+
debug?: boolean;
|
|
94
96
|
}
|
|
95
97
|
interface WithdrawSignParams {
|
|
96
98
|
safeAddress: Address;
|
|
@@ -136,6 +138,7 @@ interface WithdrawModalProps {
|
|
|
136
138
|
onWithdrawComplete?: (data: WithdrawCompleteEventData) => void;
|
|
137
139
|
onWithdrawFailed?: (data: WithdrawFailedEventData) => void;
|
|
138
140
|
onError?: (data: ErrorEventData) => void;
|
|
141
|
+
debug?: boolean;
|
|
139
142
|
}
|
|
140
143
|
interface AssetOption {
|
|
141
144
|
id: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface DepositModalUIConfig {
|
|
|
19
19
|
showBackButton?: boolean;
|
|
20
20
|
balanceTitle?: string;
|
|
21
21
|
maxDepositUsd?: number;
|
|
22
|
+
minDepositUsd?: number;
|
|
22
23
|
}
|
|
23
24
|
interface DepositModalBranding {
|
|
24
25
|
logoUrl?: string;
|
|
@@ -71,7 +72,7 @@ interface DepositModalProps {
|
|
|
71
72
|
sourceChain?: Chain | number;
|
|
72
73
|
sourceToken?: Address;
|
|
73
74
|
defaultAmount?: string;
|
|
74
|
-
recipient
|
|
75
|
+
recipient: Address;
|
|
75
76
|
backendUrl?: string;
|
|
76
77
|
rhinestoneApiKey?: string;
|
|
77
78
|
signerAddress?: Address;
|
|
@@ -91,6 +92,7 @@ interface DepositModalProps {
|
|
|
91
92
|
onDepositComplete?: (data: DepositCompleteEventData) => void;
|
|
92
93
|
onDepositFailed?: (data: DepositFailedEventData) => void;
|
|
93
94
|
onError?: (data: ErrorEventData) => void;
|
|
95
|
+
debug?: boolean;
|
|
94
96
|
}
|
|
95
97
|
interface WithdrawSignParams {
|
|
96
98
|
safeAddress: Address;
|
|
@@ -136,6 +138,7 @@ interface WithdrawModalProps {
|
|
|
136
138
|
onWithdrawComplete?: (data: WithdrawCompleteEventData) => void;
|
|
137
139
|
onWithdrawFailed?: (data: WithdrawFailedEventData) => void;
|
|
138
140
|
onError?: (data: ErrorEventData) => void;
|
|
141
|
+
debug?: boolean;
|
|
139
142
|
}
|
|
140
143
|
interface AssetOption {
|
|
141
144
|
id: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1925,6 +1925,12 @@ function AmountStep({
|
|
|
1925
1925
|
);
|
|
1926
1926
|
return;
|
|
1927
1927
|
}
|
|
1928
|
+
if (uiConfig?.minDepositUsd && usdValue < uiConfig.minDepositUsd) {
|
|
1929
|
+
setError(
|
|
1930
|
+
`Minimum deposit is ${currencyFormatter.format(uiConfig.minDepositUsd)}`
|
|
1931
|
+
);
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1928
1934
|
if (tokenPriceUsd === null || tokenPriceUsd === 0) {
|
|
1929
1935
|
setError("Unable to determine token price");
|
|
1930
1936
|
return;
|
|
@@ -2197,6 +2203,7 @@ function ConfirmStep({
|
|
|
2197
2203
|
walletClient,
|
|
2198
2204
|
address,
|
|
2199
2205
|
smartAccount,
|
|
2206
|
+
recipient,
|
|
2200
2207
|
asset,
|
|
2201
2208
|
amount,
|
|
2202
2209
|
balance,
|
|
@@ -2292,10 +2299,11 @@ function ConfirmStep({
|
|
|
2292
2299
|
if (!account || !chain) {
|
|
2293
2300
|
throw new Error("Wallet not properly connected");
|
|
2294
2301
|
}
|
|
2302
|
+
const transferTo = sameRoute ? recipient : smartAccount;
|
|
2295
2303
|
const hash = isNativeAsset(asset) ? await walletClient.sendTransaction({
|
|
2296
2304
|
account,
|
|
2297
2305
|
chain,
|
|
2298
|
-
to:
|
|
2306
|
+
to: transferTo,
|
|
2299
2307
|
value: amountUnits
|
|
2300
2308
|
}) : await walletClient.writeContract({
|
|
2301
2309
|
account,
|
|
@@ -2303,7 +2311,7 @@ function ConfirmStep({
|
|
|
2303
2311
|
address: asset.token,
|
|
2304
2312
|
abi: erc20Abi2,
|
|
2305
2313
|
functionName: "transfer",
|
|
2306
|
-
args: [
|
|
2314
|
+
args: [transferTo, amountUnits]
|
|
2307
2315
|
});
|
|
2308
2316
|
onDepositSubmitted?.(hash, asset.chainId, amountUnits.toString());
|
|
2309
2317
|
onConfirm(hash, asset.chainId, amountUnits.toString(), asset.token);
|
|
@@ -2509,8 +2517,8 @@ function getEventTxHash(event) {
|
|
|
2509
2517
|
return asString(event.data?.transactionHash);
|
|
2510
2518
|
}
|
|
2511
2519
|
if (event.type === "bridge-started" || event.type === "bridge-complete") {
|
|
2512
|
-
const
|
|
2513
|
-
return asString(
|
|
2520
|
+
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
2521
|
+
return asString(deposit?.transactionHash);
|
|
2514
2522
|
}
|
|
2515
2523
|
if (event.type === "bridge-failed" || event.type === "error") {
|
|
2516
2524
|
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
@@ -2561,19 +2569,29 @@ function ProcessingStep({
|
|
|
2561
2569
|
amount,
|
|
2562
2570
|
waitForFinalTx,
|
|
2563
2571
|
service,
|
|
2572
|
+
directTransfer,
|
|
2564
2573
|
flowLabel = "deposit",
|
|
2574
|
+
debug,
|
|
2565
2575
|
onClose,
|
|
2566
2576
|
onNewDeposit,
|
|
2567
2577
|
onDepositComplete,
|
|
2568
2578
|
onDepositFailed,
|
|
2569
2579
|
onError
|
|
2570
2580
|
}) {
|
|
2571
|
-
const [state, setState] = useState5(
|
|
2581
|
+
const [state, setState] = useState5(
|
|
2582
|
+
directTransfer ? { type: "complete" } : { type: "processing" }
|
|
2583
|
+
);
|
|
2572
2584
|
const [elapsedSeconds, setElapsedSeconds] = useState5(0);
|
|
2573
2585
|
const startTimeRef = useRef4(Date.now());
|
|
2574
2586
|
const intervalRef = useRef4(null);
|
|
2575
|
-
const sameChainAndToken = targetChain === sourceChain && targetToken.toLowerCase() === sourceToken.toLowerCase();
|
|
2576
2587
|
useEffect5(() => {
|
|
2588
|
+
if (directTransfer) {
|
|
2589
|
+
onDepositComplete?.(txHash);
|
|
2590
|
+
return;
|
|
2591
|
+
}
|
|
2592
|
+
}, [directTransfer, txHash, onDepositComplete]);
|
|
2593
|
+
useEffect5(() => {
|
|
2594
|
+
if (directTransfer) return;
|
|
2577
2595
|
startTimeRef.current = Date.now();
|
|
2578
2596
|
intervalRef.current = setInterval(() => {
|
|
2579
2597
|
setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1e3));
|
|
@@ -2581,7 +2599,7 @@ function ProcessingStep({
|
|
|
2581
2599
|
return () => {
|
|
2582
2600
|
if (intervalRef.current) clearInterval(intervalRef.current);
|
|
2583
2601
|
};
|
|
2584
|
-
}, []);
|
|
2602
|
+
}, [directTransfer]);
|
|
2585
2603
|
useEffect5(() => {
|
|
2586
2604
|
if (state.type === "complete" || state.type === "failed" || state.type === "error") {
|
|
2587
2605
|
if (intervalRef.current) {
|
|
@@ -2594,6 +2612,7 @@ function ProcessingStep({
|
|
|
2594
2612
|
const pollTimeoutRef = useRef4(null);
|
|
2595
2613
|
const processTimeoutRef = useRef4(null);
|
|
2596
2614
|
useEffect5(() => {
|
|
2615
|
+
if (directTransfer) return;
|
|
2597
2616
|
if (state.type !== "processing") {
|
|
2598
2617
|
pollIntervalRef.current = INITIAL_POLL_INTERVAL;
|
|
2599
2618
|
return;
|
|
@@ -2605,6 +2624,15 @@ function ProcessingStep({
|
|
|
2605
2624
|
const lastEvent2 = data.lastEvent;
|
|
2606
2625
|
const eventMatchesTx = isEventForTx(lastEvent2, txHash);
|
|
2607
2626
|
const eventForCurrentTx = eventMatchesTx ? lastEvent2 : void 0;
|
|
2627
|
+
if (debug && lastEvent2) {
|
|
2628
|
+
const eventData = lastEvent2.data;
|
|
2629
|
+
console.log("[deposit-modal] status poll", {
|
|
2630
|
+
type: lastEvent2.type,
|
|
2631
|
+
matchesTx: eventMatchesTx,
|
|
2632
|
+
intentId: eventData?.intentId,
|
|
2633
|
+
data: eventData
|
|
2634
|
+
});
|
|
2635
|
+
}
|
|
2608
2636
|
if (!isMounted) return;
|
|
2609
2637
|
if (eventForCurrentTx?.type === "bridge-complete") {
|
|
2610
2638
|
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
@@ -2617,11 +2645,6 @@ function ProcessingStep({
|
|
|
2617
2645
|
onDepositComplete?.(txHash);
|
|
2618
2646
|
return;
|
|
2619
2647
|
}
|
|
2620
|
-
if (eventForCurrentTx?.type === "deposit-received" && sameChainAndToken) {
|
|
2621
|
-
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
2622
|
-
onDepositComplete?.(txHash);
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
2648
|
if (eventForCurrentTx?.type === "bridge-failed") {
|
|
2626
2649
|
const formatted = formatBridgeFailedMessage(eventForCurrentTx);
|
|
2627
2650
|
setState({
|
|
@@ -2666,16 +2689,17 @@ function ProcessingStep({
|
|
|
2666
2689
|
}
|
|
2667
2690
|
};
|
|
2668
2691
|
}, [
|
|
2692
|
+
directTransfer,
|
|
2669
2693
|
state.type,
|
|
2670
2694
|
smartAccount,
|
|
2671
2695
|
txHash,
|
|
2672
2696
|
service,
|
|
2673
|
-
sameChainAndToken,
|
|
2674
2697
|
waitForFinalTx,
|
|
2675
2698
|
onDepositComplete,
|
|
2676
2699
|
onDepositFailed
|
|
2677
2700
|
]);
|
|
2678
2701
|
useEffect5(() => {
|
|
2702
|
+
if (directTransfer) return;
|
|
2679
2703
|
if (state.type !== "processing") {
|
|
2680
2704
|
if (processTimeoutRef.current) {
|
|
2681
2705
|
clearTimeout(processTimeoutRef.current);
|
|
@@ -2694,7 +2718,7 @@ function ProcessingStep({
|
|
|
2694
2718
|
processTimeoutRef.current = null;
|
|
2695
2719
|
}
|
|
2696
2720
|
};
|
|
2697
|
-
}, [state.type, onError]);
|
|
2721
|
+
}, [directTransfer, state.type, onError]);
|
|
2698
2722
|
const isError = state.type === "error" || state.type === "failed";
|
|
2699
2723
|
const isComplete = state.type === "complete";
|
|
2700
2724
|
const isProcessing = state.type === "processing";
|
|
@@ -2748,7 +2772,7 @@ function ProcessingStep({
|
|
|
2748
2772
|
}
|
|
2749
2773
|
) }),
|
|
2750
2774
|
/* @__PURE__ */ jsx11("div", { className: "rs-success-title", children: isEarlyComplete ? `${flowCapitalized} confirmed` : `${flowCapitalized} successful` }),
|
|
2751
|
-
/* @__PURE__ */ jsx11("div", { className: "rs-success-subtitle", children: isEarlyComplete ? "Your transfer has been confirmed and funds will arrive shortly." :
|
|
2775
|
+
/* @__PURE__ */ jsx11("div", { className: "rs-success-subtitle", children: directTransfer ? "Your transfer is complete." : isEarlyComplete ? "Your transfer has been confirmed and funds will arrive shortly." : "Your funds have been successfully bridged." })
|
|
2752
2776
|
] }),
|
|
2753
2777
|
/* @__PURE__ */ jsxs10("div", { className: "rs-card", children: [
|
|
2754
2778
|
/* @__PURE__ */ jsxs10("div", { className: "rs-card-row", children: [
|
|
@@ -3529,6 +3553,9 @@ var init_public_client = __esm({
|
|
|
3529
3553
|
// src/DepositFlow.tsx
|
|
3530
3554
|
import { useState as useState7, useCallback as useCallback4, useMemo as useMemo6, useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
3531
3555
|
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3556
|
+
function isSameRoute(sourceChain, sourceToken, targetChain, targetToken) {
|
|
3557
|
+
return sourceChain === targetChain && sourceToken.toLowerCase() === targetToken.toLowerCase();
|
|
3558
|
+
}
|
|
3532
3559
|
function DepositFlow({
|
|
3533
3560
|
dappWalletClient,
|
|
3534
3561
|
dappPublicClient,
|
|
@@ -3557,7 +3584,8 @@ function DepositFlow({
|
|
|
3557
3584
|
onDepositSubmitted,
|
|
3558
3585
|
onDepositComplete,
|
|
3559
3586
|
onDepositFailed,
|
|
3560
|
-
onError
|
|
3587
|
+
onError,
|
|
3588
|
+
debug
|
|
3561
3589
|
}) {
|
|
3562
3590
|
const [step, setStep] = useState7({ type: "setup" });
|
|
3563
3591
|
const [flowMode, setFlowMode] = useState7(null);
|
|
@@ -3728,12 +3756,13 @@ function DepositFlow({
|
|
|
3728
3756
|
txHash,
|
|
3729
3757
|
sourceChain: chainId,
|
|
3730
3758
|
sourceToken: token,
|
|
3731
|
-
amount
|
|
3759
|
+
amount,
|
|
3760
|
+
directTransfer: isSameRoute(chainId, token, targetChain, targetToken)
|
|
3732
3761
|
};
|
|
3733
3762
|
});
|
|
3734
3763
|
onDepositSubmitted?.({ txHash, sourceChain: chainId, amount });
|
|
3735
3764
|
},
|
|
3736
|
-
[onDepositSubmitted]
|
|
3765
|
+
[onDepositSubmitted, targetChain, targetToken]
|
|
3737
3766
|
);
|
|
3738
3767
|
const handleConnected = useCallback4(
|
|
3739
3768
|
(addr, smartAccount) => {
|
|
@@ -3780,11 +3809,12 @@ function DepositFlow({
|
|
|
3780
3809
|
txHash,
|
|
3781
3810
|
sourceChain: chainId,
|
|
3782
3811
|
sourceToken: token,
|
|
3783
|
-
amount
|
|
3812
|
+
amount,
|
|
3813
|
+
directTransfer: isSameRoute(chainId, token, targetChain, targetToken)
|
|
3784
3814
|
};
|
|
3785
3815
|
});
|
|
3786
3816
|
},
|
|
3787
|
-
[]
|
|
3817
|
+
[targetChain, targetToken]
|
|
3788
3818
|
);
|
|
3789
3819
|
const handleDepositSubmittedCallback = useCallback4(
|
|
3790
3820
|
(txHash, sourceChain, amount) => {
|
|
@@ -3893,11 +3923,13 @@ function DepositFlow({
|
|
|
3893
3923
|
amount: step.amount,
|
|
3894
3924
|
waitForFinalTx,
|
|
3895
3925
|
service,
|
|
3926
|
+
directTransfer: step.directTransfer,
|
|
3896
3927
|
onClose,
|
|
3897
3928
|
onNewDeposit: handleNewDeposit,
|
|
3898
3929
|
onDepositComplete: handleDepositComplete,
|
|
3899
3930
|
onDepositFailed: handleDepositFailed,
|
|
3900
|
-
onError: handleError
|
|
3931
|
+
onError: handleError,
|
|
3932
|
+
debug
|
|
3901
3933
|
}
|
|
3902
3934
|
)
|
|
3903
3935
|
] });
|
|
@@ -3966,6 +3998,7 @@ function DepositFlow({
|
|
|
3966
3998
|
walletClient: signerContext.walletClient,
|
|
3967
3999
|
address: ownerAddress,
|
|
3968
4000
|
smartAccount: step.smartAccount,
|
|
4001
|
+
recipient,
|
|
3969
4002
|
asset: step.asset,
|
|
3970
4003
|
amount: step.amount,
|
|
3971
4004
|
balance: step.balance,
|
|
@@ -3989,6 +4022,7 @@ function DepositFlow({
|
|
|
3989
4022
|
amount: step.amount,
|
|
3990
4023
|
waitForFinalTx,
|
|
3991
4024
|
service,
|
|
4025
|
+
directTransfer: step.directTransfer,
|
|
3992
4026
|
onClose,
|
|
3993
4027
|
onNewDeposit: handleNewDeposit,
|
|
3994
4028
|
onDepositComplete: handleDepositComplete,
|
|
@@ -4236,7 +4270,8 @@ function DepositModalInner({
|
|
|
4236
4270
|
onDepositSubmitted,
|
|
4237
4271
|
onDepositComplete,
|
|
4238
4272
|
onDepositFailed,
|
|
4239
|
-
onError
|
|
4273
|
+
onError,
|
|
4274
|
+
debug
|
|
4240
4275
|
}) {
|
|
4241
4276
|
const modalRef = useRef7(null);
|
|
4242
4277
|
const [currentStepIndex, setCurrentStepIndex] = useState9(0);
|
|
@@ -4404,7 +4439,8 @@ function DepositModalInner({
|
|
|
4404
4439
|
onDepositSubmitted,
|
|
4405
4440
|
onDepositComplete,
|
|
4406
4441
|
onDepositFailed,
|
|
4407
|
-
onError
|
|
4442
|
+
onError,
|
|
4443
|
+
debug
|
|
4408
4444
|
}
|
|
4409
4445
|
)
|
|
4410
4446
|
] })
|
|
@@ -5214,7 +5250,8 @@ function WithdrawFlow({
|
|
|
5214
5250
|
onWithdrawSubmitted,
|
|
5215
5251
|
onWithdrawComplete,
|
|
5216
5252
|
onWithdrawFailed,
|
|
5217
|
-
onError
|
|
5253
|
+
onError,
|
|
5254
|
+
debug
|
|
5218
5255
|
}) {
|
|
5219
5256
|
const [step, setStep] = useState11({ type: "form" });
|
|
5220
5257
|
const [isSubmitting, setIsSubmitting] = useState11(false);
|
|
@@ -5603,7 +5640,8 @@ function WithdrawFlow({
|
|
|
5603
5640
|
onNewDeposit: () => setStep({ type: "form" }),
|
|
5604
5641
|
onDepositComplete: handleWithdrawComplete,
|
|
5605
5642
|
onDepositFailed: handleWithdrawFailed,
|
|
5606
|
-
onError: handleError
|
|
5643
|
+
onError: handleError,
|
|
5644
|
+
debug
|
|
5607
5645
|
}
|
|
5608
5646
|
)
|
|
5609
5647
|
] });
|
|
@@ -5708,7 +5746,8 @@ function WithdrawModalInner({
|
|
|
5708
5746
|
onWithdrawSubmitted,
|
|
5709
5747
|
onWithdrawComplete,
|
|
5710
5748
|
onWithdrawFailed,
|
|
5711
|
-
onError
|
|
5749
|
+
onError,
|
|
5750
|
+
debug
|
|
5712
5751
|
}) {
|
|
5713
5752
|
const modalRef = useRef9(null);
|
|
5714
5753
|
const [currentStepIndex, setCurrentStepIndex] = useState12(0);
|
|
@@ -5874,7 +5913,8 @@ function WithdrawModalInner({
|
|
|
5874
5913
|
onWithdrawSubmitted,
|
|
5875
5914
|
onWithdrawComplete,
|
|
5876
5915
|
onWithdrawFailed,
|
|
5877
|
-
onError
|
|
5916
|
+
onError,
|
|
5917
|
+
debug
|
|
5878
5918
|
}
|
|
5879
5919
|
)
|
|
5880
5920
|
] })
|