@rhinestone/deposit-modal 0.1.19 → 0.1.20
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 +34 -17
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +34 -17
- 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;
|
|
@@ -2525,8 +2531,8 @@ function getEventTxHash(event) {
|
|
|
2525
2531
|
return asString(event.data?.transactionHash);
|
|
2526
2532
|
}
|
|
2527
2533
|
if (event.type === "bridge-started" || event.type === "bridge-complete") {
|
|
2528
|
-
const
|
|
2529
|
-
return asString(
|
|
2534
|
+
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
2535
|
+
return asString(deposit?.transactionHash);
|
|
2530
2536
|
}
|
|
2531
2537
|
if (event.type === "bridge-failed" || event.type === "error") {
|
|
2532
2538
|
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
@@ -2575,6 +2581,7 @@ function ProcessingStep({
|
|
|
2575
2581
|
waitForFinalTx,
|
|
2576
2582
|
service,
|
|
2577
2583
|
flowLabel = "deposit",
|
|
2584
|
+
debug,
|
|
2578
2585
|
onClose,
|
|
2579
2586
|
onNewDeposit,
|
|
2580
2587
|
onDepositComplete,
|
|
@@ -2585,7 +2592,6 @@ function ProcessingStep({
|
|
|
2585
2592
|
const [elapsedSeconds, setElapsedSeconds] = (0, import_react6.useState)(0);
|
|
2586
2593
|
const startTimeRef = (0, import_react6.useRef)(Date.now());
|
|
2587
2594
|
const intervalRef = (0, import_react6.useRef)(null);
|
|
2588
|
-
const sameChainAndToken = targetChain === sourceChain && targetToken.toLowerCase() === sourceToken.toLowerCase();
|
|
2589
2595
|
(0, import_react6.useEffect)(() => {
|
|
2590
2596
|
startTimeRef.current = Date.now();
|
|
2591
2597
|
intervalRef.current = setInterval(() => {
|
|
@@ -2618,6 +2624,15 @@ function ProcessingStep({
|
|
|
2618
2624
|
const lastEvent2 = data.lastEvent;
|
|
2619
2625
|
const eventMatchesTx = isEventForTx(lastEvent2, txHash);
|
|
2620
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
|
+
}
|
|
2621
2636
|
if (!isMounted) return;
|
|
2622
2637
|
if (eventForCurrentTx?.type === "bridge-complete") {
|
|
2623
2638
|
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
@@ -2630,11 +2645,6 @@ function ProcessingStep({
|
|
|
2630
2645
|
onDepositComplete?.(txHash);
|
|
2631
2646
|
return;
|
|
2632
2647
|
}
|
|
2633
|
-
if (eventForCurrentTx?.type === "deposit-received" && sameChainAndToken) {
|
|
2634
|
-
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
2635
|
-
onDepositComplete?.(txHash);
|
|
2636
|
-
return;
|
|
2637
|
-
}
|
|
2638
2648
|
if (eventForCurrentTx?.type === "bridge-failed") {
|
|
2639
2649
|
const formatted = formatBridgeFailedMessage(eventForCurrentTx);
|
|
2640
2650
|
setState({
|
|
@@ -2683,7 +2693,6 @@ function ProcessingStep({
|
|
|
2683
2693
|
smartAccount,
|
|
2684
2694
|
txHash,
|
|
2685
2695
|
service,
|
|
2686
|
-
sameChainAndToken,
|
|
2687
2696
|
waitForFinalTx,
|
|
2688
2697
|
onDepositComplete,
|
|
2689
2698
|
onDepositFailed
|
|
@@ -3572,7 +3581,8 @@ function DepositFlow({
|
|
|
3572
3581
|
onDepositSubmitted,
|
|
3573
3582
|
onDepositComplete,
|
|
3574
3583
|
onDepositFailed,
|
|
3575
|
-
onError
|
|
3584
|
+
onError,
|
|
3585
|
+
debug
|
|
3576
3586
|
}) {
|
|
3577
3587
|
const [step, setStep] = (0, import_react9.useState)({ type: "setup" });
|
|
3578
3588
|
const [flowMode, setFlowMode] = (0, import_react9.useState)(null);
|
|
@@ -3912,7 +3922,8 @@ function DepositFlow({
|
|
|
3912
3922
|
onNewDeposit: handleNewDeposit,
|
|
3913
3923
|
onDepositComplete: handleDepositComplete,
|
|
3914
3924
|
onDepositFailed: handleDepositFailed,
|
|
3915
|
-
onError: handleError
|
|
3925
|
+
onError: handleError,
|
|
3926
|
+
debug
|
|
3916
3927
|
}
|
|
3917
3928
|
)
|
|
3918
3929
|
] });
|
|
@@ -4238,7 +4249,8 @@ function DepositModalInner({
|
|
|
4238
4249
|
onDepositSubmitted,
|
|
4239
4250
|
onDepositComplete,
|
|
4240
4251
|
onDepositFailed,
|
|
4241
|
-
onError
|
|
4252
|
+
onError,
|
|
4253
|
+
debug
|
|
4242
4254
|
}) {
|
|
4243
4255
|
const modalRef = (0, import_react13.useRef)(null);
|
|
4244
4256
|
const [currentStepIndex, setCurrentStepIndex] = (0, import_react13.useState)(0);
|
|
@@ -4406,7 +4418,8 @@ function DepositModalInner({
|
|
|
4406
4418
|
onDepositSubmitted,
|
|
4407
4419
|
onDepositComplete,
|
|
4408
4420
|
onDepositFailed,
|
|
4409
|
-
onError
|
|
4421
|
+
onError,
|
|
4422
|
+
debug
|
|
4410
4423
|
}
|
|
4411
4424
|
)
|
|
4412
4425
|
] })
|
|
@@ -5207,7 +5220,8 @@ function WithdrawFlow({
|
|
|
5207
5220
|
onWithdrawSubmitted,
|
|
5208
5221
|
onWithdrawComplete,
|
|
5209
5222
|
onWithdrawFailed,
|
|
5210
|
-
onError
|
|
5223
|
+
onError,
|
|
5224
|
+
debug
|
|
5211
5225
|
}) {
|
|
5212
5226
|
const [step, setStep] = (0, import_react15.useState)({ type: "form" });
|
|
5213
5227
|
const [isSubmitting, setIsSubmitting] = (0, import_react15.useState)(false);
|
|
@@ -5596,7 +5610,8 @@ function WithdrawFlow({
|
|
|
5596
5610
|
onNewDeposit: () => setStep({ type: "form" }),
|
|
5597
5611
|
onDepositComplete: handleWithdrawComplete,
|
|
5598
5612
|
onDepositFailed: handleWithdrawFailed,
|
|
5599
|
-
onError: handleError
|
|
5613
|
+
onError: handleError,
|
|
5614
|
+
debug
|
|
5600
5615
|
}
|
|
5601
5616
|
)
|
|
5602
5617
|
] });
|
|
@@ -5697,7 +5712,8 @@ function WithdrawModalInner({
|
|
|
5697
5712
|
onWithdrawSubmitted,
|
|
5698
5713
|
onWithdrawComplete,
|
|
5699
5714
|
onWithdrawFailed,
|
|
5700
|
-
onError
|
|
5715
|
+
onError,
|
|
5716
|
+
debug
|
|
5701
5717
|
}) {
|
|
5702
5718
|
const modalRef = (0, import_react17.useRef)(null);
|
|
5703
5719
|
const [currentStepIndex, setCurrentStepIndex] = (0, import_react17.useState)(0);
|
|
@@ -5863,7 +5879,8 @@ function WithdrawModalInner({
|
|
|
5863
5879
|
onWithdrawSubmitted,
|
|
5864
5880
|
onWithdrawComplete,
|
|
5865
5881
|
onWithdrawFailed,
|
|
5866
|
-
onError
|
|
5882
|
+
onError,
|
|
5883
|
+
debug
|
|
5867
5884
|
}
|
|
5868
5885
|
)
|
|
5869
5886
|
] })
|
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;
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -2509,8 +2515,8 @@ function getEventTxHash(event) {
|
|
|
2509
2515
|
return asString(event.data?.transactionHash);
|
|
2510
2516
|
}
|
|
2511
2517
|
if (event.type === "bridge-started" || event.type === "bridge-complete") {
|
|
2512
|
-
const
|
|
2513
|
-
return asString(
|
|
2518
|
+
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
2519
|
+
return asString(deposit?.transactionHash);
|
|
2514
2520
|
}
|
|
2515
2521
|
if (event.type === "bridge-failed" || event.type === "error") {
|
|
2516
2522
|
const deposit = isRecord(event.data?.deposit) ? event.data.deposit : void 0;
|
|
@@ -2562,6 +2568,7 @@ function ProcessingStep({
|
|
|
2562
2568
|
waitForFinalTx,
|
|
2563
2569
|
service,
|
|
2564
2570
|
flowLabel = "deposit",
|
|
2571
|
+
debug,
|
|
2565
2572
|
onClose,
|
|
2566
2573
|
onNewDeposit,
|
|
2567
2574
|
onDepositComplete,
|
|
@@ -2572,7 +2579,6 @@ function ProcessingStep({
|
|
|
2572
2579
|
const [elapsedSeconds, setElapsedSeconds] = useState5(0);
|
|
2573
2580
|
const startTimeRef = useRef4(Date.now());
|
|
2574
2581
|
const intervalRef = useRef4(null);
|
|
2575
|
-
const sameChainAndToken = targetChain === sourceChain && targetToken.toLowerCase() === sourceToken.toLowerCase();
|
|
2576
2582
|
useEffect5(() => {
|
|
2577
2583
|
startTimeRef.current = Date.now();
|
|
2578
2584
|
intervalRef.current = setInterval(() => {
|
|
@@ -2605,6 +2611,15 @@ function ProcessingStep({
|
|
|
2605
2611
|
const lastEvent2 = data.lastEvent;
|
|
2606
2612
|
const eventMatchesTx = isEventForTx(lastEvent2, txHash);
|
|
2607
2613
|
const eventForCurrentTx = eventMatchesTx ? lastEvent2 : void 0;
|
|
2614
|
+
if (debug && lastEvent2) {
|
|
2615
|
+
const eventData = lastEvent2.data;
|
|
2616
|
+
console.log("[deposit-modal] status poll", {
|
|
2617
|
+
type: lastEvent2.type,
|
|
2618
|
+
matchesTx: eventMatchesTx,
|
|
2619
|
+
intentId: eventData?.intentId,
|
|
2620
|
+
data: eventData
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2608
2623
|
if (!isMounted) return;
|
|
2609
2624
|
if (eventForCurrentTx?.type === "bridge-complete") {
|
|
2610
2625
|
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
@@ -2617,11 +2632,6 @@ function ProcessingStep({
|
|
|
2617
2632
|
onDepositComplete?.(txHash);
|
|
2618
2633
|
return;
|
|
2619
2634
|
}
|
|
2620
|
-
if (eventForCurrentTx?.type === "deposit-received" && sameChainAndToken) {
|
|
2621
|
-
setState({ type: "complete", lastEvent: eventForCurrentTx });
|
|
2622
|
-
onDepositComplete?.(txHash);
|
|
2623
|
-
return;
|
|
2624
|
-
}
|
|
2625
2635
|
if (eventForCurrentTx?.type === "bridge-failed") {
|
|
2626
2636
|
const formatted = formatBridgeFailedMessage(eventForCurrentTx);
|
|
2627
2637
|
setState({
|
|
@@ -2670,7 +2680,6 @@ function ProcessingStep({
|
|
|
2670
2680
|
smartAccount,
|
|
2671
2681
|
txHash,
|
|
2672
2682
|
service,
|
|
2673
|
-
sameChainAndToken,
|
|
2674
2683
|
waitForFinalTx,
|
|
2675
2684
|
onDepositComplete,
|
|
2676
2685
|
onDepositFailed
|
|
@@ -3557,7 +3566,8 @@ function DepositFlow({
|
|
|
3557
3566
|
onDepositSubmitted,
|
|
3558
3567
|
onDepositComplete,
|
|
3559
3568
|
onDepositFailed,
|
|
3560
|
-
onError
|
|
3569
|
+
onError,
|
|
3570
|
+
debug
|
|
3561
3571
|
}) {
|
|
3562
3572
|
const [step, setStep] = useState7({ type: "setup" });
|
|
3563
3573
|
const [flowMode, setFlowMode] = useState7(null);
|
|
@@ -3897,7 +3907,8 @@ function DepositFlow({
|
|
|
3897
3907
|
onNewDeposit: handleNewDeposit,
|
|
3898
3908
|
onDepositComplete: handleDepositComplete,
|
|
3899
3909
|
onDepositFailed: handleDepositFailed,
|
|
3900
|
-
onError: handleError
|
|
3910
|
+
onError: handleError,
|
|
3911
|
+
debug
|
|
3901
3912
|
}
|
|
3902
3913
|
)
|
|
3903
3914
|
] });
|
|
@@ -4236,7 +4247,8 @@ function DepositModalInner({
|
|
|
4236
4247
|
onDepositSubmitted,
|
|
4237
4248
|
onDepositComplete,
|
|
4238
4249
|
onDepositFailed,
|
|
4239
|
-
onError
|
|
4250
|
+
onError,
|
|
4251
|
+
debug
|
|
4240
4252
|
}) {
|
|
4241
4253
|
const modalRef = useRef7(null);
|
|
4242
4254
|
const [currentStepIndex, setCurrentStepIndex] = useState9(0);
|
|
@@ -4404,7 +4416,8 @@ function DepositModalInner({
|
|
|
4404
4416
|
onDepositSubmitted,
|
|
4405
4417
|
onDepositComplete,
|
|
4406
4418
|
onDepositFailed,
|
|
4407
|
-
onError
|
|
4419
|
+
onError,
|
|
4420
|
+
debug
|
|
4408
4421
|
}
|
|
4409
4422
|
)
|
|
4410
4423
|
] })
|
|
@@ -5214,7 +5227,8 @@ function WithdrawFlow({
|
|
|
5214
5227
|
onWithdrawSubmitted,
|
|
5215
5228
|
onWithdrawComplete,
|
|
5216
5229
|
onWithdrawFailed,
|
|
5217
|
-
onError
|
|
5230
|
+
onError,
|
|
5231
|
+
debug
|
|
5218
5232
|
}) {
|
|
5219
5233
|
const [step, setStep] = useState11({ type: "form" });
|
|
5220
5234
|
const [isSubmitting, setIsSubmitting] = useState11(false);
|
|
@@ -5603,7 +5617,8 @@ function WithdrawFlow({
|
|
|
5603
5617
|
onNewDeposit: () => setStep({ type: "form" }),
|
|
5604
5618
|
onDepositComplete: handleWithdrawComplete,
|
|
5605
5619
|
onDepositFailed: handleWithdrawFailed,
|
|
5606
|
-
onError: handleError
|
|
5620
|
+
onError: handleError,
|
|
5621
|
+
debug
|
|
5607
5622
|
}
|
|
5608
5623
|
)
|
|
5609
5624
|
] });
|
|
@@ -5708,7 +5723,8 @@ function WithdrawModalInner({
|
|
|
5708
5723
|
onWithdrawSubmitted,
|
|
5709
5724
|
onWithdrawComplete,
|
|
5710
5725
|
onWithdrawFailed,
|
|
5711
|
-
onError
|
|
5726
|
+
onError,
|
|
5727
|
+
debug
|
|
5712
5728
|
}) {
|
|
5713
5729
|
const modalRef = useRef9(null);
|
|
5714
5730
|
const [currentStepIndex, setCurrentStepIndex] = useState12(0);
|
|
@@ -5874,7 +5890,8 @@ function WithdrawModalInner({
|
|
|
5874
5890
|
onWithdrawSubmitted,
|
|
5875
5891
|
onWithdrawComplete,
|
|
5876
5892
|
onWithdrawFailed,
|
|
5877
|
-
onError
|
|
5893
|
+
onError,
|
|
5894
|
+
debug
|
|
5878
5895
|
}
|
|
5879
5896
|
)
|
|
5880
5897
|
] })
|