@oasisprotocol/privana-sdk 0.4.4 → 0.5.1
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/dist/chunk-4IW4V7YJ.cjs +3805 -0
- package/dist/chunk-4IW4V7YJ.cjs.map +1 -0
- package/dist/chunk-SAJ7K5WT.js +3716 -0
- package/dist/chunk-SAJ7K5WT.js.map +1 -0
- package/dist/index.cjs +2528 -636
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +2 -2
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +177 -334
- package/dist/index.d.ts +177 -334
- package/dist/index.js +2152 -359
- package/dist/index.js.map +1 -1
- package/dist/on-ramp.cjs +10 -974
- package/dist/on-ramp.cjs.map +1 -1
- package/dist/on-ramp.d.cts +50 -4
- package/dist/on-ramp.d.ts +50 -4
- package/dist/on-ramp.js +1 -975
- package/dist/on-ramp.js.map +1 -1
- package/dist/pending-lock-BdkuMjmY.d.cts +600 -0
- package/dist/pending-lock-BdkuMjmY.d.ts +600 -0
- package/package.json +3 -2
- package/dist/chunk-NMRIKUDN.cjs +0 -1775
- package/dist/chunk-NMRIKUDN.cjs.map +0 -1
- package/dist/chunk-WV6CGHEF.js +0 -1720
- package/dist/chunk-WV6CGHEF.js.map +0 -1
- package/dist/on-ramp-CdXqJjmm.d.cts +0 -115
- package/dist/on-ramp-CdXqJjmm.d.ts +0 -115
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunk4IW4V7YJ_cjs = require('./chunk-4IW4V7YJ.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var reactQuery = require('@tanstack/react-query');
|
|
7
7
|
var wagmi = require('wagmi');
|
|
@@ -10,6 +10,8 @@ var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
|
10
10
|
var lucideReact = require('lucide-react');
|
|
11
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
12
|
var sonner = require('sonner');
|
|
13
|
+
var qrcode_react = require('qrcode.react');
|
|
14
|
+
var moonpayReact = require('@moonpay/moonpay-react');
|
|
13
15
|
|
|
14
16
|
function _interopNamespace(e) {
|
|
15
17
|
if (e && e.__esModule) return e;
|
|
@@ -31,216 +33,20 @@ function _interopNamespace(e) {
|
|
|
31
33
|
|
|
32
34
|
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
33
35
|
|
|
34
|
-
// src/sdk/signatures/eip712-types.ts
|
|
35
|
-
function createDomain(chainId, verifyingContract) {
|
|
36
|
-
return {
|
|
37
|
-
name: "AccountingModule",
|
|
38
|
-
version: "1",
|
|
39
|
-
chainId,
|
|
40
|
-
verifyingContract
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
var LOCK_TYPES = {
|
|
44
|
-
Lock: [
|
|
45
|
-
{ name: "serviceAddress", type: "address" },
|
|
46
|
-
{ name: "tokenId", type: "bytes32" },
|
|
47
|
-
{ name: "amount", type: "uint256" },
|
|
48
|
-
{ name: "expiry", type: "uint256" },
|
|
49
|
-
{ name: "nonce", type: "uint256" }
|
|
50
|
-
]
|
|
51
|
-
};
|
|
52
|
-
var TRANSFER_TYPES = {
|
|
53
|
-
Transfer: [
|
|
54
|
-
{ name: "toAddress", type: "address" },
|
|
55
|
-
{ name: "tokenId", type: "bytes32" },
|
|
56
|
-
{ name: "amount", type: "uint256" },
|
|
57
|
-
{ name: "nonce", type: "uint256" }
|
|
58
|
-
]
|
|
59
|
-
};
|
|
60
|
-
var TRANSFER_LOCKED_TYPES = {
|
|
61
|
-
TransferLocked: [
|
|
62
|
-
{ name: "userAddress", type: "address" },
|
|
63
|
-
{ name: "toAddress", type: "address" },
|
|
64
|
-
{ name: "lockId", type: "uint256" },
|
|
65
|
-
{ name: "amount", type: "uint256" },
|
|
66
|
-
{ name: "nonce", type: "uint256" },
|
|
67
|
-
{ name: "serviceAddress", type: "address" }
|
|
68
|
-
]
|
|
69
|
-
};
|
|
70
|
-
var WITHDRAW_TYPES = {
|
|
71
|
-
Withdraw: [
|
|
72
|
-
{ name: "tokenId", type: "bytes32" },
|
|
73
|
-
{ name: "amount", type: "uint256" },
|
|
74
|
-
{ name: "nonce", type: "uint256" }
|
|
75
|
-
]
|
|
76
|
-
};
|
|
77
|
-
var MODIFY_LOCK_TYPES = {
|
|
78
|
-
ModifyLock: [
|
|
79
|
-
{ name: "lockId", type: "uint256" },
|
|
80
|
-
{ name: "amount", type: "uint256" },
|
|
81
|
-
{ name: "newExpiry", type: "uint256" },
|
|
82
|
-
{ name: "nonce", type: "uint256" }
|
|
83
|
-
]
|
|
84
|
-
};
|
|
85
|
-
var WITHDRAW_FROM_LOCK_TYPES = {
|
|
86
|
-
WithdrawFromLock: [
|
|
87
|
-
{ name: "userAddress", type: "address" },
|
|
88
|
-
{ name: "toAddress", type: "address" },
|
|
89
|
-
{ name: "lockId", type: "uint256" },
|
|
90
|
-
{ name: "amount", type: "uint256" },
|
|
91
|
-
{ name: "nonce", type: "uint256" }
|
|
92
|
-
]
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// src/sdk/signatures/sign-lock.ts
|
|
96
|
-
async function signLockMessage({
|
|
97
|
-
walletClient,
|
|
98
|
-
chainId,
|
|
99
|
-
verifyingContract,
|
|
100
|
-
message
|
|
101
|
-
}) {
|
|
102
|
-
const account = walletClient.account;
|
|
103
|
-
if (!account) {
|
|
104
|
-
throw new Error("No account connected to wallet client");
|
|
105
|
-
}
|
|
106
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
107
|
-
const signature = await walletClient.signTypedData({
|
|
108
|
-
account,
|
|
109
|
-
domain,
|
|
110
|
-
types: LOCK_TYPES,
|
|
111
|
-
primaryType: "Lock",
|
|
112
|
-
message
|
|
113
|
-
});
|
|
114
|
-
return signature;
|
|
115
|
-
}
|
|
116
|
-
function createLockExpiry(minutesFromNow = 60) {
|
|
117
|
-
return BigInt(Math.floor(Date.now() / 1e3) + minutesFromNow * 60);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// src/sdk/signatures/sign-modify-lock.ts
|
|
121
|
-
async function signModifyLockMessage({
|
|
122
|
-
walletClient,
|
|
123
|
-
chainId,
|
|
124
|
-
verifyingContract,
|
|
125
|
-
message
|
|
126
|
-
}) {
|
|
127
|
-
const account = walletClient.account;
|
|
128
|
-
if (!account) {
|
|
129
|
-
throw new Error("No account connected to wallet client");
|
|
130
|
-
}
|
|
131
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
132
|
-
const signature = await walletClient.signTypedData({
|
|
133
|
-
account,
|
|
134
|
-
domain,
|
|
135
|
-
types: MODIFY_LOCK_TYPES,
|
|
136
|
-
primaryType: "ModifyLock",
|
|
137
|
-
message
|
|
138
|
-
});
|
|
139
|
-
return signature;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// src/sdk/signatures/sign-transfer.ts
|
|
143
|
-
async function signTransferMessage({
|
|
144
|
-
walletClient,
|
|
145
|
-
chainId,
|
|
146
|
-
verifyingContract,
|
|
147
|
-
message
|
|
148
|
-
}) {
|
|
149
|
-
const account = walletClient.account;
|
|
150
|
-
if (!account) {
|
|
151
|
-
throw new Error("No account connected to wallet client");
|
|
152
|
-
}
|
|
153
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
154
|
-
const signature = await walletClient.signTypedData({
|
|
155
|
-
account,
|
|
156
|
-
domain,
|
|
157
|
-
types: TRANSFER_TYPES,
|
|
158
|
-
primaryType: "Transfer",
|
|
159
|
-
message
|
|
160
|
-
});
|
|
161
|
-
return signature;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/sdk/signatures/sign-transfer-locked.ts
|
|
165
|
-
async function signTransferLockedMessage({
|
|
166
|
-
walletClient,
|
|
167
|
-
chainId,
|
|
168
|
-
verifyingContract,
|
|
169
|
-
message
|
|
170
|
-
}) {
|
|
171
|
-
const account = walletClient.account;
|
|
172
|
-
if (!account) {
|
|
173
|
-
throw new Error("No account connected to wallet client");
|
|
174
|
-
}
|
|
175
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
176
|
-
const signature = await walletClient.signTypedData({
|
|
177
|
-
account,
|
|
178
|
-
domain,
|
|
179
|
-
types: TRANSFER_LOCKED_TYPES,
|
|
180
|
-
primaryType: "TransferLocked",
|
|
181
|
-
message
|
|
182
|
-
});
|
|
183
|
-
return signature;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// src/sdk/signatures/sign-withdraw.ts
|
|
187
|
-
async function signWithdrawMessage({
|
|
188
|
-
walletClient,
|
|
189
|
-
chainId,
|
|
190
|
-
verifyingContract,
|
|
191
|
-
message
|
|
192
|
-
}) {
|
|
193
|
-
const account = walletClient.account;
|
|
194
|
-
if (!account) {
|
|
195
|
-
throw new Error("No account connected to wallet client");
|
|
196
|
-
}
|
|
197
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
198
|
-
const signature = await walletClient.signTypedData({
|
|
199
|
-
account,
|
|
200
|
-
domain,
|
|
201
|
-
types: WITHDRAW_TYPES,
|
|
202
|
-
primaryType: "Withdraw",
|
|
203
|
-
message
|
|
204
|
-
});
|
|
205
|
-
return signature;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// src/sdk/signatures/sign-withdraw-from-lock.ts
|
|
209
|
-
async function signWithdrawFromLockMessage({
|
|
210
|
-
walletClient,
|
|
211
|
-
chainId,
|
|
212
|
-
verifyingContract,
|
|
213
|
-
message
|
|
214
|
-
}) {
|
|
215
|
-
const account = walletClient.account;
|
|
216
|
-
if (!account) {
|
|
217
|
-
throw new Error("No account connected to wallet client");
|
|
218
|
-
}
|
|
219
|
-
const domain = createDomain(chainId, verifyingContract);
|
|
220
|
-
const signature = await walletClient.signTypedData({
|
|
221
|
-
account,
|
|
222
|
-
domain,
|
|
223
|
-
types: WITHDRAW_FROM_LOCK_TYPES,
|
|
224
|
-
primaryType: "WithdrawFromLock",
|
|
225
|
-
message
|
|
226
|
-
});
|
|
227
|
-
return signature;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
36
|
// src/sdk/hooks/use-privana-client.ts
|
|
231
37
|
function usePrivanaClient() {
|
|
232
|
-
const { client } =
|
|
38
|
+
const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
233
39
|
return client;
|
|
234
40
|
}
|
|
235
41
|
var hostedAuthExchangeInflight = /* @__PURE__ */ new Map();
|
|
236
42
|
function normalizeHostedAuthError(error) {
|
|
237
|
-
if (error instanceof
|
|
238
|
-
return new
|
|
43
|
+
if (error instanceof chunk4IW4V7YJ_cjs.AccountingApiError && error.detail) {
|
|
44
|
+
return new chunk4IW4V7YJ_cjs.HostedAuthError(error.detail);
|
|
239
45
|
}
|
|
240
46
|
if (error instanceof Error) {
|
|
241
47
|
return error;
|
|
242
48
|
}
|
|
243
|
-
return new
|
|
49
|
+
return new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted authentication failed.");
|
|
244
50
|
}
|
|
245
51
|
function useHostedRedirectAuth() {
|
|
246
52
|
const {
|
|
@@ -251,30 +57,30 @@ function useHostedRedirectAuth() {
|
|
|
251
57
|
setHostedAuthSession,
|
|
252
58
|
clearHostedAuthSession,
|
|
253
59
|
refreshHostedAuthSession
|
|
254
|
-
} =
|
|
60
|
+
} = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
255
61
|
const [error, setError] = react.useState(null);
|
|
256
62
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
257
63
|
const loginInflight = react.useRef(null);
|
|
258
64
|
const completionInflight = react.useRef(null);
|
|
259
65
|
const pendingStorageKey = react.useMemo(
|
|
260
|
-
() => hostedAuthConfig ?
|
|
66
|
+
() => hostedAuthConfig ? chunk4IW4V7YJ_cjs.createHostedAuthPendingStorageKey(client.getBaseUrl(), hostedAuthConfig) : null,
|
|
261
67
|
[client, hostedAuthConfig]
|
|
262
68
|
);
|
|
263
69
|
const clearPendingLogin = react.useCallback(() => {
|
|
264
70
|
if (!pendingStorageKey || typeof window === "undefined") return;
|
|
265
|
-
|
|
71
|
+
chunk4IW4V7YJ_cjs.clearHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
|
|
266
72
|
}, [pendingStorageKey]);
|
|
267
73
|
const login = react.useCallback(async () => {
|
|
268
74
|
if (!hostedAuthConfig) {
|
|
269
|
-
throw new
|
|
75
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthRequiredError(
|
|
270
76
|
"Hosted redirect authentication is not configured for this provider."
|
|
271
77
|
);
|
|
272
78
|
}
|
|
273
79
|
if (typeof window === "undefined") {
|
|
274
|
-
throw new
|
|
80
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
|
|
275
81
|
}
|
|
276
82
|
if (!pendingStorageKey) {
|
|
277
|
-
throw new
|
|
83
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
|
|
278
84
|
}
|
|
279
85
|
if (loginInflight.current) {
|
|
280
86
|
return loginInflight.current;
|
|
@@ -283,10 +89,10 @@ function useHostedRedirectAuth() {
|
|
|
283
89
|
setIsLoading(true);
|
|
284
90
|
setError(null);
|
|
285
91
|
try {
|
|
286
|
-
const verifier =
|
|
287
|
-
const codeChallenge = await
|
|
288
|
-
const state =
|
|
289
|
-
|
|
92
|
+
const verifier = chunk4IW4V7YJ_cjs.createPkceVerifier();
|
|
93
|
+
const codeChallenge = await chunk4IW4V7YJ_cjs.createPkceChallenge(verifier);
|
|
94
|
+
const state = chunk4IW4V7YJ_cjs.createHostedAuthState();
|
|
95
|
+
chunk4IW4V7YJ_cjs.persistHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey, {
|
|
290
96
|
codeVerifier: verifier,
|
|
291
97
|
state
|
|
292
98
|
});
|
|
@@ -315,15 +121,15 @@ function useHostedRedirectAuth() {
|
|
|
315
121
|
}, [clearPendingLogin, client, hostedAuthConfig, networkConfig.chainId, pendingStorageKey]);
|
|
316
122
|
const completeLogin = react.useCallback(async () => {
|
|
317
123
|
if (!hostedAuthConfig) {
|
|
318
|
-
throw new
|
|
124
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthRequiredError(
|
|
319
125
|
"Hosted redirect authentication is not configured for this provider."
|
|
320
126
|
);
|
|
321
127
|
}
|
|
322
128
|
if (typeof window === "undefined") {
|
|
323
|
-
throw new
|
|
129
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
|
|
324
130
|
}
|
|
325
131
|
if (!pendingStorageKey) {
|
|
326
|
-
throw new
|
|
132
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
|
|
327
133
|
}
|
|
328
134
|
if (completionInflight.current) {
|
|
329
135
|
return completionInflight.current;
|
|
@@ -333,30 +139,30 @@ function useHostedRedirectAuth() {
|
|
|
333
139
|
setError(null);
|
|
334
140
|
const callbackUrl = new URL(window.location.href);
|
|
335
141
|
const cleanupCallbackUrl = () => {
|
|
336
|
-
window.history.replaceState(null, "",
|
|
142
|
+
window.history.replaceState(null, "", chunk4IW4V7YJ_cjs.stripHostedAuthCallbackParams(callbackUrl));
|
|
337
143
|
};
|
|
338
144
|
try {
|
|
339
|
-
const callback =
|
|
145
|
+
const callback = chunk4IW4V7YJ_cjs.parseHostedAuthCallback(callbackUrl, hostedAuthConfig.redirectUri);
|
|
340
146
|
if (!callback) {
|
|
341
147
|
return null;
|
|
342
148
|
}
|
|
343
|
-
const pending =
|
|
149
|
+
const pending = chunk4IW4V7YJ_cjs.readHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
|
|
344
150
|
if (!pending) {
|
|
345
151
|
clearPendingLogin();
|
|
346
152
|
cleanupCallbackUrl();
|
|
347
|
-
throw new
|
|
153
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError(
|
|
348
154
|
"Hosted authentication response could not be matched to a pending login request."
|
|
349
155
|
);
|
|
350
156
|
}
|
|
351
157
|
if (!callback.state || callback.state !== pending.state) {
|
|
352
158
|
clearPendingLogin();
|
|
353
159
|
cleanupCallbackUrl();
|
|
354
|
-
throw new
|
|
160
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthStateMismatchError();
|
|
355
161
|
}
|
|
356
162
|
if ("error" in callback) {
|
|
357
163
|
clearPendingLogin();
|
|
358
164
|
cleanupCallbackUrl();
|
|
359
|
-
throw new
|
|
165
|
+
throw new chunk4IW4V7YJ_cjs.HostedAuthError(
|
|
360
166
|
callback.errorDescription || callback.error || "Hosted authentication failed."
|
|
361
167
|
);
|
|
362
168
|
}
|
|
@@ -371,7 +177,7 @@ function useHostedRedirectAuth() {
|
|
|
371
177
|
client_id: hostedAuthConfig.clientId,
|
|
372
178
|
redirect_uri: hostedAuthConfig.redirectUri
|
|
373
179
|
});
|
|
374
|
-
const session =
|
|
180
|
+
const session = chunk4IW4V7YJ_cjs.buildHostedAuthSession(response, hostedAuthConfig);
|
|
375
181
|
setHostedAuthSession(session);
|
|
376
182
|
clearPendingLogin();
|
|
377
183
|
cleanupCallbackUrl();
|
|
@@ -416,7 +222,7 @@ function useHostedRedirectAuth() {
|
|
|
416
222
|
try {
|
|
417
223
|
return await refreshHostedAuthSession();
|
|
418
224
|
} catch (refreshError) {
|
|
419
|
-
const normalizedError = refreshError instanceof Error ? refreshError : new
|
|
225
|
+
const normalizedError = refreshError instanceof Error ? refreshError : new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted authentication refresh failed.");
|
|
420
226
|
setError(normalizedError);
|
|
421
227
|
throw normalizedError;
|
|
422
228
|
} finally {
|
|
@@ -436,12 +242,12 @@ function useHostedRedirectAuth() {
|
|
|
436
242
|
}
|
|
437
243
|
function useBalance(options = {}) {
|
|
438
244
|
const queryClient = react.useContext(reactQuery.QueryClientContext);
|
|
439
|
-
const accountingContext =
|
|
245
|
+
const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
|
|
440
246
|
const hasProviders = !!queryClient && !!accountingContext;
|
|
441
247
|
const client = accountingContext?.client;
|
|
442
248
|
const defaultToken = accountingContext?.defaultToken;
|
|
443
249
|
const pollingInterval = accountingContext?.pollingInterval ?? 1e4;
|
|
444
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
250
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
445
251
|
const tokenId = options.tokenId ?? defaultToken?.id;
|
|
446
252
|
const query = reactQuery.useQuery({
|
|
447
253
|
queryKey: ["accounting-balance", ...privateReadQueryScope, tokenId],
|
|
@@ -458,7 +264,7 @@ function useBalance(options = {}) {
|
|
|
458
264
|
return {
|
|
459
265
|
balance: balanceWei,
|
|
460
266
|
balanceWei,
|
|
461
|
-
balanceFormatted:
|
|
267
|
+
balanceFormatted: chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei),
|
|
462
268
|
tokenSymbol: query.data?.token_symbol ?? "",
|
|
463
269
|
chainId: query.data?.chain_id ?? "",
|
|
464
270
|
isLoading: query.isPending || query.isLoading,
|
|
@@ -468,8 +274,8 @@ function useBalance(options = {}) {
|
|
|
468
274
|
};
|
|
469
275
|
}
|
|
470
276
|
function useBatchBalances(options) {
|
|
471
|
-
const { client, pollingInterval } =
|
|
472
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
277
|
+
const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
278
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
473
279
|
const query = reactQuery.useQuery({
|
|
474
280
|
queryKey: ["accounting-batch-balances", ...privateReadQueryScope, options.tokenIds],
|
|
475
281
|
queryFn: async () => {
|
|
@@ -487,75 +293,22 @@ function useBatchBalances(options) {
|
|
|
487
293
|
refetch: query.refetch
|
|
488
294
|
};
|
|
489
295
|
}
|
|
490
|
-
function useEnsureCorrectChain() {
|
|
491
|
-
const config = wagmi.useConfig();
|
|
492
|
-
const chainId = wagmi.useChainId();
|
|
493
|
-
const { switchChainAsync } = wagmi.useSwitchChain();
|
|
494
|
-
const waitUntilOnChain = react.useCallback(
|
|
495
|
-
async (expectedChainId, timeoutMs, pollIntervalMs = 250) => {
|
|
496
|
-
const startedAt = Date.now();
|
|
497
|
-
while (Date.now() - startedAt < timeoutMs) {
|
|
498
|
-
const currentChainId = chunkNMRIKUDN_cjs.getChainId2(config);
|
|
499
|
-
if (currentChainId === expectedChainId) return true;
|
|
500
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
501
|
-
}
|
|
502
|
-
return false;
|
|
503
|
-
},
|
|
504
|
-
[config]
|
|
505
|
-
);
|
|
506
|
-
const ensureCorrectChain = react.useCallback(
|
|
507
|
-
async (targetChainId) => {
|
|
508
|
-
const currentChainId = chunkNMRIKUDN_cjs.getChainId2(config);
|
|
509
|
-
if (currentChainId === targetChainId) return false;
|
|
510
|
-
let switchErrorMessage;
|
|
511
|
-
try {
|
|
512
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
513
|
-
setTimeout(() => reject(new Error("Chain switch timeout")), 3e3);
|
|
514
|
-
});
|
|
515
|
-
await Promise.race([switchChainAsync({ chainId: targetChainId }), timeoutPromise]);
|
|
516
|
-
} catch (error) {
|
|
517
|
-
if (error instanceof Error && error.message.includes("Unsupported Chain")) {
|
|
518
|
-
console.warn("Got 'Unsupported Chain' error, chain may have switched anyway.");
|
|
519
|
-
} else {
|
|
520
|
-
switchErrorMessage = error instanceof Error ? error.message : "Unknown chain switch error";
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
const settled = await waitUntilOnChain(targetChainId, 2e4);
|
|
524
|
-
if (settled) return true;
|
|
525
|
-
if (switchErrorMessage) {
|
|
526
|
-
throw new Error(
|
|
527
|
-
`Failed to switch to chain (Chain ID: ${targetChainId}): ${switchErrorMessage}`
|
|
528
|
-
);
|
|
529
|
-
}
|
|
530
|
-
throw new Error(`Chain switch did not settle in time (expected ${targetChainId}).`);
|
|
531
|
-
},
|
|
532
|
-
[config, switchChainAsync, waitUntilOnChain]
|
|
533
|
-
);
|
|
534
|
-
const isOnChain = react.useCallback((targetChainId) => chainId === targetChainId, [chainId]);
|
|
535
|
-
return {
|
|
536
|
-
chainId,
|
|
537
|
-
ensureCorrectChain,
|
|
538
|
-
isOnChain
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// src/sdk/hooks/use-deposit.ts
|
|
543
296
|
var STALE_MS = 30 * 60 * 1e3;
|
|
544
297
|
function storageKey(address) {
|
|
545
298
|
return `privana:pending-deposit:${address.toLowerCase()}`;
|
|
546
299
|
}
|
|
547
300
|
function savePendingDeposit(address, data) {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
301
|
+
const stored = chunk4IW4V7YJ_cjs.setBrowserStorageItem(storageKey(address), JSON.stringify(data));
|
|
302
|
+
if (!stored && data.signedLock) {
|
|
303
|
+
throw new Error("Unable to persist pending locked deposit for recovery");
|
|
551
304
|
}
|
|
552
305
|
}
|
|
553
306
|
function loadPendingDeposit(address) {
|
|
554
307
|
try {
|
|
555
|
-
const raw =
|
|
308
|
+
const raw = chunk4IW4V7YJ_cjs.getBrowserStorageItem(storageKey(address));
|
|
556
309
|
if (!raw) return null;
|
|
557
310
|
const data = JSON.parse(raw);
|
|
558
|
-
if (Date.now() - data.savedAt > STALE_MS) {
|
|
311
|
+
if (Date.now() - data.savedAt > STALE_MS && !(data.signedLock && chunk4IW4V7YJ_cjs.isSignedLockUsable(data.signedLock))) {
|
|
559
312
|
clearPendingDeposit(address);
|
|
560
313
|
return null;
|
|
561
314
|
}
|
|
@@ -564,19 +317,24 @@ function loadPendingDeposit(address) {
|
|
|
564
317
|
return null;
|
|
565
318
|
}
|
|
566
319
|
}
|
|
567
|
-
function clearPendingDeposit(address) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
320
|
+
function clearPendingDeposit(address, onlyForTxHash) {
|
|
321
|
+
if (onlyForTxHash) {
|
|
322
|
+
try {
|
|
323
|
+
const raw = chunk4IW4V7YJ_cjs.getBrowserStorageItem(storageKey(address));
|
|
324
|
+
const recordTxHash = raw ? JSON.parse(raw).txHash : void 0;
|
|
325
|
+
if (recordTxHash && recordTxHash !== onlyForTxHash) return;
|
|
326
|
+
} catch {
|
|
327
|
+
}
|
|
571
328
|
}
|
|
329
|
+
chunk4IW4V7YJ_cjs.removeBrowserStorageItem(storageKey(address));
|
|
572
330
|
}
|
|
573
331
|
function useDeposit(options = {}) {
|
|
574
332
|
const { address } = wagmi.useAccount();
|
|
575
|
-
const { client, enabledTokens, getChainById: getChainById2 } =
|
|
333
|
+
const { client, enabledTokens, getChainById: getChainById2, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
576
334
|
const { data: walletClient } = wagmi.useWalletClient();
|
|
577
335
|
const queryClient = reactQuery.useQueryClient();
|
|
578
336
|
const config = wagmi.useConfig();
|
|
579
|
-
const { executePrivateRead } =
|
|
337
|
+
const { executePrivateRead } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
580
338
|
const confirmations = options.confirmations ?? 15;
|
|
581
339
|
const [depositAddress, setDepositAddress] = react.useState(null);
|
|
582
340
|
const [txHash, setTxHash] = react.useState();
|
|
@@ -589,21 +347,54 @@ function useDeposit(options = {}) {
|
|
|
589
347
|
const onDepositAddressReceivedRef = react.useRef(options.onDepositAddressReceived);
|
|
590
348
|
const onDepositSuccessRef = react.useRef(options.onDepositSuccess);
|
|
591
349
|
const onCreditedRef = react.useRef(options.onCredited);
|
|
350
|
+
const onLockSubmittedRef = react.useRef(options.onLockSubmitted);
|
|
351
|
+
const onLockFailedRef = react.useRef(options.onLockFailed);
|
|
592
352
|
const onCheckTimeoutRef = react.useRef(options.onCheckTimeout);
|
|
593
353
|
const onErrorRef = react.useRef(options.onError);
|
|
594
354
|
react.useEffect(() => {
|
|
595
355
|
onDepositAddressReceivedRef.current = options.onDepositAddressReceived;
|
|
596
356
|
onDepositSuccessRef.current = options.onDepositSuccess;
|
|
597
357
|
onCreditedRef.current = options.onCredited;
|
|
358
|
+
onLockSubmittedRef.current = options.onLockSubmitted;
|
|
359
|
+
onLockFailedRef.current = options.onLockFailed;
|
|
598
360
|
onCheckTimeoutRef.current = options.onCheckTimeout;
|
|
599
361
|
onErrorRef.current = options.onError;
|
|
600
362
|
}, [
|
|
601
363
|
options.onDepositAddressReceived,
|
|
602
364
|
options.onDepositSuccess,
|
|
603
365
|
options.onCredited,
|
|
366
|
+
options.onLockSubmitted,
|
|
367
|
+
options.onLockFailed,
|
|
604
368
|
options.onCheckTimeout,
|
|
605
369
|
options.onError
|
|
606
370
|
]);
|
|
371
|
+
const pendingLockRef = react.useRef(null);
|
|
372
|
+
const submitPendingLockAfterCredit = react.useCallback(
|
|
373
|
+
async (signedLock, response) => {
|
|
374
|
+
try {
|
|
375
|
+
const result = await chunk4IW4V7YJ_cjs.submitPendingLock({
|
|
376
|
+
client,
|
|
377
|
+
payload: signedLock,
|
|
378
|
+
creditedAmount: response.amount != null ? BigInt(response.amount) : void 0
|
|
379
|
+
});
|
|
380
|
+
queryClient.invalidateQueries({ queryKey: ["accounting-balance"] });
|
|
381
|
+
queryClient.invalidateQueries({ queryKey: ["accounting-locked-funds"] });
|
|
382
|
+
queryClient.invalidateQueries({ queryKey: ["accounting-total-locked-balance"] });
|
|
383
|
+
queryClient.invalidateQueries({ queryKey: ["accounting-history"] });
|
|
384
|
+
onLockSubmittedRef.current?.(result);
|
|
385
|
+
} catch (err) {
|
|
386
|
+
const error2 = err instanceof chunk4IW4V7YJ_cjs.PostDepositLockError ? err : new chunk4IW4V7YJ_cjs.PostDepositLockError(
|
|
387
|
+
err instanceof Error ? err.message : "Lock submission failed",
|
|
388
|
+
"submission-failed",
|
|
389
|
+
BigInt(signedLock.amount),
|
|
390
|
+
void 0,
|
|
391
|
+
{ cause: err }
|
|
392
|
+
);
|
|
393
|
+
(onLockFailedRef.current ?? onErrorRef.current)?.(error2);
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
[client, queryClient]
|
|
397
|
+
);
|
|
607
398
|
const {
|
|
608
399
|
isVerifying,
|
|
609
400
|
didTimeout,
|
|
@@ -611,13 +402,21 @@ function useDeposit(options = {}) {
|
|
|
611
402
|
error: verificationError,
|
|
612
403
|
verify,
|
|
613
404
|
reset: resetVerification
|
|
614
|
-
} =
|
|
405
|
+
} = chunk4IW4V7YJ_cjs.useDepositVerification({
|
|
615
406
|
pollInterval: options.pollInterval,
|
|
616
407
|
pollTimeout: options.pollTimeout,
|
|
617
408
|
onCredited: (hash, response) => {
|
|
618
409
|
verificationContextRef.current = null;
|
|
619
|
-
|
|
620
|
-
|
|
410
|
+
const signedLock = pendingLockRef.current;
|
|
411
|
+
pendingLockRef.current = null;
|
|
412
|
+
if (signedLock) {
|
|
413
|
+
void submitPendingLockAfterCredit(signedLock, response).finally(() => {
|
|
414
|
+
if (address) clearPendingDeposit(address, hash);
|
|
415
|
+
});
|
|
416
|
+
} else if (address) {
|
|
417
|
+
clearPendingDeposit(address);
|
|
418
|
+
}
|
|
419
|
+
onCreditedRef.current?.(hash, response, signedLock !== null);
|
|
621
420
|
},
|
|
622
421
|
onCheckTimeout: (hash) => {
|
|
623
422
|
onCheckTimeoutRef.current?.(hash);
|
|
@@ -653,7 +452,7 @@ function useDeposit(options = {}) {
|
|
|
653
452
|
} = wagmi.useSendTransaction();
|
|
654
453
|
const isSendingTx = isWritingContract || isSendingNative;
|
|
655
454
|
const sendError = writeError ?? sendNativeError;
|
|
656
|
-
const { ensureCorrectChain } = useEnsureCorrectChain();
|
|
455
|
+
const { ensureCorrectChain } = chunk4IW4V7YJ_cjs.useEnsureCorrectChain();
|
|
657
456
|
const invalidateGeneration = react.useCallback(() => {
|
|
658
457
|
generationRef.current++;
|
|
659
458
|
}, []);
|
|
@@ -668,6 +467,7 @@ function useDeposit(options = {}) {
|
|
|
668
467
|
resetVerification();
|
|
669
468
|
if (address) clearPendingDeposit(address);
|
|
670
469
|
verificationContextRef.current = null;
|
|
470
|
+
pendingLockRef.current = null;
|
|
671
471
|
setDepositAddress(null);
|
|
672
472
|
setTxHash(void 0);
|
|
673
473
|
setIsSwitchingChain(false);
|
|
@@ -687,6 +487,7 @@ function useDeposit(options = {}) {
|
|
|
687
487
|
setTxHash(hash);
|
|
688
488
|
setDepositAddress(persisted.depositAddress);
|
|
689
489
|
setIsWaitingForConfirmation(true);
|
|
490
|
+
pendingLockRef.current = persisted.signedLock ?? null;
|
|
690
491
|
const ctx = {
|
|
691
492
|
hash,
|
|
692
493
|
chainId: persisted.chainId,
|
|
@@ -699,12 +500,12 @@ function useDeposit(options = {}) {
|
|
|
699
500
|
try {
|
|
700
501
|
let confirmed = false;
|
|
701
502
|
try {
|
|
702
|
-
await
|
|
503
|
+
await chunk4IW4V7YJ_cjs.getTransactionReceipt(config, { hash, chainId: persisted.chainId });
|
|
703
504
|
confirmed = true;
|
|
704
505
|
} catch {
|
|
705
506
|
}
|
|
706
507
|
if (!confirmed) {
|
|
707
|
-
await
|
|
508
|
+
await chunk4IW4V7YJ_cjs.waitForTransactionReceipt(config, {
|
|
708
509
|
hash,
|
|
709
510
|
chainId: persisted.chainId,
|
|
710
511
|
confirmations
|
|
@@ -743,13 +544,6 @@ function useDeposit(options = {}) {
|
|
|
743
544
|
if (!sourceChain) throw new Error(`Chain ${token.chainId} not configured`);
|
|
744
545
|
const addrResponse = await addressMutation.mutateAsync();
|
|
745
546
|
if (isStale()) return;
|
|
746
|
-
setIsSwitchingChain(true);
|
|
747
|
-
try {
|
|
748
|
-
await ensureCorrectChain(sourceChain.id);
|
|
749
|
-
} finally {
|
|
750
|
-
if (!isStale()) setIsSwitchingChain(false);
|
|
751
|
-
}
|
|
752
|
-
if (isStale()) return;
|
|
753
547
|
const depositAddr = addrResponse.deposit_address;
|
|
754
548
|
if (!depositAddr || depositAddr === viem.zeroAddress) {
|
|
755
549
|
throw new Error("Invalid deposit address received from API");
|
|
@@ -762,6 +556,43 @@ function useDeposit(options = {}) {
|
|
|
762
556
|
`Amount is below the minimum deposit (${minAmountStr}) for ${isNative ? "native" : "ERC-20"} on chain ${sourceChain.id}`
|
|
763
557
|
);
|
|
764
558
|
}
|
|
559
|
+
if (params.postDepositLock && !chunk4IW4V7YJ_cjs.canUseBrowserStorage()) {
|
|
560
|
+
throw new Error("Browser storage is required for locked deposit recovery");
|
|
561
|
+
}
|
|
562
|
+
const lockAmount = chunk4IW4V7YJ_cjs.clampLockAmount(params.amount, params.postDepositLock?.maxAmount);
|
|
563
|
+
let signedLock;
|
|
564
|
+
if (params.postDepositLock) {
|
|
565
|
+
setIsSwitchingChain(true);
|
|
566
|
+
try {
|
|
567
|
+
await ensureCorrectChain(networkConfig.chainId);
|
|
568
|
+
} finally {
|
|
569
|
+
if (!isStale()) setIsSwitchingChain(false);
|
|
570
|
+
}
|
|
571
|
+
if (isStale()) return;
|
|
572
|
+
const signingWalletClient = await chunk4IW4V7YJ_cjs.getWalletClient(config, {
|
|
573
|
+
chainId: networkConfig.chainId
|
|
574
|
+
});
|
|
575
|
+
signedLock = await chunk4IW4V7YJ_cjs.createSignedLockRequest({
|
|
576
|
+
client,
|
|
577
|
+
walletClient: signingWalletClient,
|
|
578
|
+
userAddress: address,
|
|
579
|
+
networkConfig,
|
|
580
|
+
serviceAddress: requireServiceAddress(
|
|
581
|
+
params.postDepositLock.serviceAddress ?? serviceAddress
|
|
582
|
+
),
|
|
583
|
+
tokenId: params.tokenId,
|
|
584
|
+
amount: lockAmount,
|
|
585
|
+
lockDuration: params.postDepositLock.lockDuration
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (isStale()) return;
|
|
589
|
+
setIsSwitchingChain(true);
|
|
590
|
+
try {
|
|
591
|
+
await ensureCorrectChain(sourceChain.id);
|
|
592
|
+
} finally {
|
|
593
|
+
if (!isStale()) setIsSwitchingChain(false);
|
|
594
|
+
}
|
|
595
|
+
if (isStale()) return;
|
|
765
596
|
const hash = token.contract === viem.zeroAddress ? await sendTransactionAsync({
|
|
766
597
|
to: depositAddr,
|
|
767
598
|
value: params.amount,
|
|
@@ -781,17 +612,23 @@ function useDeposit(options = {}) {
|
|
|
781
612
|
amount: params.amount
|
|
782
613
|
};
|
|
783
614
|
verificationContextRef.current = ctx;
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
615
|
+
pendingLockRef.current = signedLock ?? null;
|
|
616
|
+
try {
|
|
617
|
+
savePendingDeposit(address, {
|
|
618
|
+
txHash: hash,
|
|
619
|
+
chainId: sourceChain.id,
|
|
620
|
+
amount: params.amount.toString(),
|
|
621
|
+
depositAddress: addrResponse,
|
|
622
|
+
signedLock,
|
|
623
|
+
savedAt: Date.now()
|
|
624
|
+
});
|
|
625
|
+
} catch (err) {
|
|
626
|
+
console.warn("Failed to persist pending deposit after transfer broadcast:", err);
|
|
627
|
+
}
|
|
791
628
|
try {
|
|
792
629
|
setIsWaitingForConfirmation(true);
|
|
793
630
|
try {
|
|
794
|
-
await
|
|
631
|
+
await chunk4IW4V7YJ_cjs.waitForTransactionReceipt(config, {
|
|
795
632
|
hash,
|
|
796
633
|
chainId: sourceChain.id,
|
|
797
634
|
confirmations
|
|
@@ -822,12 +659,15 @@ function useDeposit(options = {}) {
|
|
|
822
659
|
address,
|
|
823
660
|
walletClient,
|
|
824
661
|
addressMutation,
|
|
662
|
+
client,
|
|
825
663
|
getChainById2,
|
|
826
664
|
config,
|
|
827
665
|
confirmations,
|
|
828
666
|
enabledTokens,
|
|
829
667
|
ensureCorrectChain,
|
|
668
|
+
networkConfig,
|
|
830
669
|
queryClient,
|
|
670
|
+
serviceAddress,
|
|
831
671
|
writeContractAsync,
|
|
832
672
|
sendTransactionAsync,
|
|
833
673
|
reset,
|
|
@@ -862,12 +702,43 @@ function useDeposit(options = {}) {
|
|
|
862
702
|
reset
|
|
863
703
|
};
|
|
864
704
|
}
|
|
705
|
+
function requireServiceAddress(serviceAddress) {
|
|
706
|
+
if (!serviceAddress) {
|
|
707
|
+
throw new Error("Service address not configured");
|
|
708
|
+
}
|
|
709
|
+
return serviceAddress;
|
|
710
|
+
}
|
|
711
|
+
function useDepositAddress(options = {}) {
|
|
712
|
+
const queryClient = react.useContext(reactQuery.QueryClientContext);
|
|
713
|
+
const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
|
|
714
|
+
const hasProviders = !!queryClient && !!accountingContext;
|
|
715
|
+
const client = accountingContext?.client;
|
|
716
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
717
|
+
const isReady = hasProviders && privateReadReady && !!privateReadAddress && !!client;
|
|
718
|
+
const query = reactQuery.useQuery({
|
|
719
|
+
queryKey: ["accounting-deposit-address", ...privateReadQueryScope],
|
|
720
|
+
queryFn: async () => {
|
|
721
|
+
if (!privateReadAddress) throw new Error("No authenticated account available");
|
|
722
|
+
if (!client) throw new Error("No accounting client");
|
|
723
|
+
return executePrivateRead(() => client.getDepositAddress());
|
|
724
|
+
},
|
|
725
|
+
enabled: isReady && (options.enabled ?? true)
|
|
726
|
+
});
|
|
727
|
+
return {
|
|
728
|
+
depositAddress: query.data?.deposit_address ?? null,
|
|
729
|
+
isReady,
|
|
730
|
+
isLoading: query.isLoading,
|
|
731
|
+
isError: query.isError,
|
|
732
|
+
error: query.error,
|
|
733
|
+
refetch: query.refetch
|
|
734
|
+
};
|
|
735
|
+
}
|
|
865
736
|
function useWithdraw(options = {}) {
|
|
866
737
|
const { address } = wagmi.useAccount();
|
|
867
738
|
const { data: walletClient } = wagmi.useWalletClient();
|
|
868
|
-
const { client, networkConfig } =
|
|
739
|
+
const { client, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
869
740
|
const queryClient = reactQuery.useQueryClient();
|
|
870
|
-
const { chainId, ensureCorrectChain } = useEnsureCorrectChain();
|
|
741
|
+
const { chainId, ensureCorrectChain } = chunk4IW4V7YJ_cjs.useEnsureCorrectChain();
|
|
871
742
|
const pollInterval = options.pollInterval ?? 3e3;
|
|
872
743
|
const pollTimeout = options.pollTimeout ?? 18e4;
|
|
873
744
|
const [currentStep, setCurrentStep] = react.useState("idle");
|
|
@@ -935,7 +806,7 @@ function useWithdraw(options = {}) {
|
|
|
935
806
|
if (isStale()) return void 0;
|
|
936
807
|
const nonce = BigInt(nonceResponse.nonce);
|
|
937
808
|
setCurrentStep("signing");
|
|
938
|
-
const signature = await signWithdrawMessage({
|
|
809
|
+
const signature = await chunk4IW4V7YJ_cjs.signWithdrawMessage({
|
|
939
810
|
walletClient,
|
|
940
811
|
chainId: signingChainId,
|
|
941
812
|
verifyingContract: networkConfig.accountingContract,
|
|
@@ -1064,7 +935,7 @@ function useWithdraw(options = {}) {
|
|
|
1064
935
|
function useLockFunds(options = {}) {
|
|
1065
936
|
const { address } = wagmi.useAccount();
|
|
1066
937
|
const { data: walletClient } = wagmi.useWalletClient();
|
|
1067
|
-
const { client, networkConfig, serviceAddress } =
|
|
938
|
+
const { client, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1068
939
|
const queryClient = reactQuery.useQueryClient();
|
|
1069
940
|
const mutation = reactQuery.useMutation({
|
|
1070
941
|
mutationFn: async (params) => {
|
|
@@ -1075,7 +946,7 @@ function useLockFunds(options = {}) {
|
|
|
1075
946
|
throw new Error("Service address not configured");
|
|
1076
947
|
}
|
|
1077
948
|
const { nonce } = await client.getLockNonce(address);
|
|
1078
|
-
const signature = await signLockMessage({
|
|
949
|
+
const signature = await chunk4IW4V7YJ_cjs.signLockMessage({
|
|
1079
950
|
walletClient,
|
|
1080
951
|
chainId: networkConfig.chainId,
|
|
1081
952
|
verifyingContract: networkConfig.accountingContract,
|
|
@@ -1123,7 +994,7 @@ function useLockFunds(options = {}) {
|
|
|
1123
994
|
}
|
|
1124
995
|
function useUnlockFunds(options = {}) {
|
|
1125
996
|
const { address } = wagmi.useAccount();
|
|
1126
|
-
const { client } =
|
|
997
|
+
const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1127
998
|
const queryClient = reactQuery.useQueryClient();
|
|
1128
999
|
const unlockMutation = reactQuery.useMutation({
|
|
1129
1000
|
mutationFn: async (params) => {
|
|
@@ -1193,7 +1064,7 @@ function useUnlockFunds(options = {}) {
|
|
|
1193
1064
|
function useTransfer(options = {}) {
|
|
1194
1065
|
const { address } = wagmi.useAccount();
|
|
1195
1066
|
const { data: walletClient } = wagmi.useWalletClient();
|
|
1196
|
-
const { client, networkConfig, serviceAddress } =
|
|
1067
|
+
const { client, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1197
1068
|
const queryClient = reactQuery.useQueryClient();
|
|
1198
1069
|
const transferMutation = reactQuery.useMutation({
|
|
1199
1070
|
mutationFn: async (params) => {
|
|
@@ -1201,7 +1072,7 @@ function useTransfer(options = {}) {
|
|
|
1201
1072
|
throw new Error("Wallet not connected");
|
|
1202
1073
|
}
|
|
1203
1074
|
const { nonce } = await client.getTransferNonce(address);
|
|
1204
|
-
const signature = await signTransferMessage({
|
|
1075
|
+
const signature = await chunk4IW4V7YJ_cjs.signTransferMessage({
|
|
1205
1076
|
walletClient,
|
|
1206
1077
|
chainId: networkConfig.chainId,
|
|
1207
1078
|
verifyingContract: networkConfig.accountingContract,
|
|
@@ -1238,7 +1109,7 @@ function useTransfer(options = {}) {
|
|
|
1238
1109
|
throw new Error("Service address not configured");
|
|
1239
1110
|
}
|
|
1240
1111
|
const { nonce } = await client.getTransferLockedNonce(serviceAddress);
|
|
1241
|
-
const signature = await signTransferLockedMessage({
|
|
1112
|
+
const signature = await chunk4IW4V7YJ_cjs.signTransferLockedMessage({
|
|
1242
1113
|
walletClient,
|
|
1243
1114
|
chainId: networkConfig.chainId,
|
|
1244
1115
|
verifyingContract: networkConfig.accountingContract,
|
|
@@ -1298,8 +1169,8 @@ function useTransfer(options = {}) {
|
|
|
1298
1169
|
};
|
|
1299
1170
|
}
|
|
1300
1171
|
function useLockedFunds(options = {}) {
|
|
1301
|
-
const { client, pollingInterval, serviceAddress } =
|
|
1302
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
1172
|
+
const { client, pollingInterval, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1173
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
1303
1174
|
const query = reactQuery.useQuery({
|
|
1304
1175
|
queryKey: ["accounting-locked-funds", ...privateReadQueryScope, serviceAddress ?? null],
|
|
1305
1176
|
queryFn: async () => {
|
|
@@ -1321,8 +1192,8 @@ function useLockedFunds(options = {}) {
|
|
|
1321
1192
|
};
|
|
1322
1193
|
}
|
|
1323
1194
|
function useTotalLockedBalance(options = {}) {
|
|
1324
|
-
const { client, pollingInterval, defaultToken } =
|
|
1325
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
1195
|
+
const { client, pollingInterval, defaultToken } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1196
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
1326
1197
|
const tokenId = options.tokenId ?? defaultToken?.id;
|
|
1327
1198
|
const query = reactQuery.useQuery({
|
|
1328
1199
|
queryKey: ["accounting-total-locked-balance", ...privateReadQueryScope, tokenId],
|
|
@@ -1343,8 +1214,8 @@ function useTotalLockedBalance(options = {}) {
|
|
|
1343
1214
|
};
|
|
1344
1215
|
}
|
|
1345
1216
|
function useExpiredLocks(options = {}) {
|
|
1346
|
-
const { client, pollingInterval } =
|
|
1347
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
1217
|
+
const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1218
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
1348
1219
|
const query = reactQuery.useQuery({
|
|
1349
1220
|
queryKey: ["accounting-expired-locks", ...privateReadQueryScope],
|
|
1350
1221
|
queryFn: async () => {
|
|
@@ -1364,9 +1235,62 @@ function useExpiredLocks(options = {}) {
|
|
|
1364
1235
|
refetch: query.refetch
|
|
1365
1236
|
};
|
|
1366
1237
|
}
|
|
1238
|
+
function statusCodeOf(error) {
|
|
1239
|
+
return error instanceof chunk4IW4V7YJ_cjs.AccountingApiError ? error.statusCode : void 0;
|
|
1240
|
+
}
|
|
1241
|
+
function usePendingDeposits(options = {}) {
|
|
1242
|
+
const queryClient = react.useContext(reactQuery.QueryClientContext);
|
|
1243
|
+
const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
|
|
1244
|
+
const hasProviders = !!queryClient && !!accountingContext;
|
|
1245
|
+
const client = accountingContext?.client;
|
|
1246
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
1247
|
+
const { chainId, tokenAddress, lookbackBlocks } = options;
|
|
1248
|
+
const query = reactQuery.useQuery({
|
|
1249
|
+
queryKey: ["accounting-pending-deposits", ...privateReadQueryScope, chainId, tokenAddress],
|
|
1250
|
+
queryFn: async () => {
|
|
1251
|
+
if (!privateReadAddress) throw new Error("No authenticated account available");
|
|
1252
|
+
if (!chainId) throw new Error("No chain ID provided");
|
|
1253
|
+
if (!client) throw new Error("No accounting client");
|
|
1254
|
+
try {
|
|
1255
|
+
return await executePrivateRead(
|
|
1256
|
+
() => client.getPendingDeposits({
|
|
1257
|
+
chain_id: chainId,
|
|
1258
|
+
token_address: tokenAddress,
|
|
1259
|
+
lookback_blocks: lookbackBlocks
|
|
1260
|
+
})
|
|
1261
|
+
);
|
|
1262
|
+
} catch (error) {
|
|
1263
|
+
if (statusCodeOf(error) === 404) {
|
|
1264
|
+
return { pending: [], scanned_from_block: 0, scanned_to_block: 0 };
|
|
1265
|
+
}
|
|
1266
|
+
throw error;
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
enabled: hasProviders && (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!chainId && !!client,
|
|
1270
|
+
// A 503 means discovery is not configured for this chain server-side —
|
|
1271
|
+
// polling can't fix that, so stop until a manual refetch succeeds.
|
|
1272
|
+
refetchInterval: (query2) => statusCodeOf(query2.state.error) === 503 ? false : options.refetchInterval ?? 3e4,
|
|
1273
|
+
staleTime: 25e3,
|
|
1274
|
+
retry: (failureCount, error) => {
|
|
1275
|
+
const status = statusCodeOf(error);
|
|
1276
|
+
if (status === 429 || status === 404 || status === 503) return false;
|
|
1277
|
+
return failureCount < 2;
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
return {
|
|
1281
|
+
pending: query.data?.pending ?? [],
|
|
1282
|
+
scannedToBlock: query.data?.scanned_to_block,
|
|
1283
|
+
isFetching: query.isFetching,
|
|
1284
|
+
isError: query.isError,
|
|
1285
|
+
error: query.error,
|
|
1286
|
+
isRateLimited: statusCodeOf(query.error) === 429,
|
|
1287
|
+
isUnavailable: statusCodeOf(query.error) === 503,
|
|
1288
|
+
refetch: async () => (await query.refetch()).data
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1367
1291
|
function usePendingWithdrawals(options = {}) {
|
|
1368
1292
|
const { address, isConnected } = wagmi.useAccount();
|
|
1369
|
-
const { client, pollingInterval } =
|
|
1293
|
+
const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1370
1294
|
const query = reactQuery.useQuery({
|
|
1371
1295
|
queryKey: ["accounting-pending-withdrawals", address],
|
|
1372
1296
|
queryFn: async () => {
|
|
@@ -1402,8 +1326,8 @@ function usePendingWithdrawals(options = {}) {
|
|
|
1402
1326
|
};
|
|
1403
1327
|
}
|
|
1404
1328
|
function useHistory(options = {}) {
|
|
1405
|
-
const { client, pollingInterval } =
|
|
1406
|
-
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } =
|
|
1329
|
+
const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1330
|
+
const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
|
|
1407
1331
|
const offset = options.offset ?? -1;
|
|
1408
1332
|
const limit = options.limit ?? 50;
|
|
1409
1333
|
const query = reactQuery.useQuery({
|
|
@@ -1427,7 +1351,7 @@ function useHistory(options = {}) {
|
|
|
1427
1351
|
};
|
|
1428
1352
|
}
|
|
1429
1353
|
function useTokenInfo(options = {}) {
|
|
1430
|
-
const { client } =
|
|
1354
|
+
const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1431
1355
|
const { tokenId } = options;
|
|
1432
1356
|
const query = reactQuery.useQuery({
|
|
1433
1357
|
queryKey: ["accounting-token-info", tokenId],
|
|
@@ -1447,7 +1371,7 @@ function useTokenInfo(options = {}) {
|
|
|
1447
1371
|
};
|
|
1448
1372
|
}
|
|
1449
1373
|
function useTokenList(options = {}) {
|
|
1450
|
-
const { client } =
|
|
1374
|
+
const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1451
1375
|
const query = reactQuery.useQuery({
|
|
1452
1376
|
queryKey: ["accounting-token-list"],
|
|
1453
1377
|
queryFn: () => client.listTokens(),
|
|
@@ -1465,7 +1389,7 @@ function useTokenList(options = {}) {
|
|
|
1465
1389
|
function useModifyLock(options = {}) {
|
|
1466
1390
|
const { address } = wagmi.useAccount();
|
|
1467
1391
|
const { data: walletClient } = wagmi.useWalletClient();
|
|
1468
|
-
const { client, networkConfig } =
|
|
1392
|
+
const { client, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1469
1393
|
const queryClient = reactQuery.useQueryClient();
|
|
1470
1394
|
const mutation = reactQuery.useMutation({
|
|
1471
1395
|
mutationFn: async (params) => {
|
|
@@ -1473,7 +1397,7 @@ function useModifyLock(options = {}) {
|
|
|
1473
1397
|
throw new Error("Wallet not connected");
|
|
1474
1398
|
}
|
|
1475
1399
|
const { nonce } = await client.getModifyLockNonce(address);
|
|
1476
|
-
const signature = await signModifyLockMessage({
|
|
1400
|
+
const signature = await chunk4IW4V7YJ_cjs.signModifyLockMessage({
|
|
1477
1401
|
walletClient,
|
|
1478
1402
|
chainId: networkConfig.chainId,
|
|
1479
1403
|
verifyingContract: networkConfig.accountingContract,
|
|
@@ -1532,7 +1456,7 @@ function DialogOverlay({
|
|
|
1532
1456
|
{
|
|
1533
1457
|
"data-slot": "dialog-overlay",
|
|
1534
1458
|
"data-privana": true,
|
|
1535
|
-
className:
|
|
1459
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
1536
1460
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
1537
1461
|
className
|
|
1538
1462
|
),
|
|
@@ -1554,7 +1478,7 @@ function DialogContent({
|
|
|
1554
1478
|
{
|
|
1555
1479
|
"data-slot": "dialog-content",
|
|
1556
1480
|
"data-privana": true,
|
|
1557
|
-
className:
|
|
1481
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
1558
1482
|
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
|
|
1559
1483
|
className
|
|
1560
1484
|
),
|
|
@@ -1582,7 +1506,7 @@ function DialogHeader({ className, ...props }) {
|
|
|
1582
1506
|
"div",
|
|
1583
1507
|
{
|
|
1584
1508
|
"data-slot": "dialog-header",
|
|
1585
|
-
className:
|
|
1509
|
+
className: chunk4IW4V7YJ_cjs.cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
1586
1510
|
...props
|
|
1587
1511
|
}
|
|
1588
1512
|
);
|
|
@@ -1592,7 +1516,7 @@ function DialogTitle({ className, ...props }) {
|
|
|
1592
1516
|
DialogPrimitive__namespace.Title,
|
|
1593
1517
|
{
|
|
1594
1518
|
"data-slot": "dialog-title",
|
|
1595
|
-
className:
|
|
1519
|
+
className: chunk4IW4V7YJ_cjs.cn("text-lg leading-none font-semibold", className),
|
|
1596
1520
|
...props
|
|
1597
1521
|
}
|
|
1598
1522
|
);
|
|
@@ -1605,24 +1529,11 @@ function DialogDescription({
|
|
|
1605
1529
|
DialogPrimitive__namespace.Description,
|
|
1606
1530
|
{
|
|
1607
1531
|
"data-slot": "dialog-description",
|
|
1608
|
-
className:
|
|
1532
|
+
className: chunk4IW4V7YJ_cjs.cn("text-muted-foreground text-sm", className),
|
|
1609
1533
|
...props
|
|
1610
1534
|
}
|
|
1611
1535
|
);
|
|
1612
1536
|
}
|
|
1613
|
-
function ChevronRightIcon() {
|
|
1614
|
-
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "5", viewBox: "0 0 12 6", className: "-rotate-90", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1615
|
-
"path",
|
|
1616
|
-
{
|
|
1617
|
-
d: "M0 0l6 6 6-6",
|
|
1618
|
-
stroke: "currentColor",
|
|
1619
|
-
strokeWidth: "1.5",
|
|
1620
|
-
strokeLinecap: "round",
|
|
1621
|
-
strokeLinejoin: "round",
|
|
1622
|
-
fill: "none"
|
|
1623
|
-
}
|
|
1624
|
-
) });
|
|
1625
|
-
}
|
|
1626
1537
|
function USDCIcon({ className, size = 24 }) {
|
|
1627
1538
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1628
1539
|
"svg",
|
|
@@ -1764,6 +1675,135 @@ function getChainIcon(chainId, size) {
|
|
|
1764
1675
|
);
|
|
1765
1676
|
}
|
|
1766
1677
|
}
|
|
1678
|
+
function CloseIcon() {
|
|
1679
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1680
|
+
"path",
|
|
1681
|
+
{
|
|
1682
|
+
d: "M11.99997 11.99997l-5.99995-5.99995-6.00002-6.00002m6.00002 6.00002l6.00001-6.00002m-12.00003 12.00003l6.00002-6.00001",
|
|
1683
|
+
stroke: "currentColor",
|
|
1684
|
+
strokeWidth: "1.5",
|
|
1685
|
+
strokeLinecap: "round",
|
|
1686
|
+
strokeLinejoin: "round"
|
|
1687
|
+
}
|
|
1688
|
+
) });
|
|
1689
|
+
}
|
|
1690
|
+
function ChevronRightIcon() {
|
|
1691
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "5", viewBox: "0 0 12 6", className: "-rotate-90", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1692
|
+
"path",
|
|
1693
|
+
{
|
|
1694
|
+
d: "M0 0l6 6 6-6",
|
|
1695
|
+
stroke: "currentColor",
|
|
1696
|
+
strokeWidth: "1.5",
|
|
1697
|
+
strokeLinecap: "round",
|
|
1698
|
+
strokeLinejoin: "round",
|
|
1699
|
+
fill: "none"
|
|
1700
|
+
}
|
|
1701
|
+
) });
|
|
1702
|
+
}
|
|
1703
|
+
function ChevronLeftIcon() {
|
|
1704
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "5", viewBox: "0 0 12 6", className: "rotate-90", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1705
|
+
"path",
|
|
1706
|
+
{
|
|
1707
|
+
d: "M0 0l6 6 6-6",
|
|
1708
|
+
stroke: "currentColor",
|
|
1709
|
+
strokeWidth: "1.5",
|
|
1710
|
+
strokeLinecap: "round",
|
|
1711
|
+
strokeLinejoin: "round",
|
|
1712
|
+
fill: "none"
|
|
1713
|
+
}
|
|
1714
|
+
) });
|
|
1715
|
+
}
|
|
1716
|
+
function ChevronDownIcon({
|
|
1717
|
+
direction = "down",
|
|
1718
|
+
className
|
|
1719
|
+
}) {
|
|
1720
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1721
|
+
"svg",
|
|
1722
|
+
{
|
|
1723
|
+
width: "16",
|
|
1724
|
+
height: "16",
|
|
1725
|
+
viewBox: "0 0 16 16",
|
|
1726
|
+
fill: "none",
|
|
1727
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
1728
|
+
"transition-transform",
|
|
1729
|
+
direction === "right" && "-rotate-90",
|
|
1730
|
+
direction === "up" && "rotate-180",
|
|
1731
|
+
className
|
|
1732
|
+
),
|
|
1733
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1734
|
+
"path",
|
|
1735
|
+
{
|
|
1736
|
+
d: "M4 6l4 4 4-4",
|
|
1737
|
+
stroke: "currentColor",
|
|
1738
|
+
strokeWidth: "1.5",
|
|
1739
|
+
strokeLinecap: "round",
|
|
1740
|
+
strokeLinejoin: "round"
|
|
1741
|
+
}
|
|
1742
|
+
)
|
|
1743
|
+
}
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
function CopyIcon() {
|
|
1747
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1748
|
+
"svg",
|
|
1749
|
+
{
|
|
1750
|
+
width: "16",
|
|
1751
|
+
height: "16",
|
|
1752
|
+
viewBox: "0 0 24 24",
|
|
1753
|
+
fill: "none",
|
|
1754
|
+
stroke: "currentColor",
|
|
1755
|
+
strokeWidth: "2",
|
|
1756
|
+
strokeLinecap: "round",
|
|
1757
|
+
strokeLinejoin: "round",
|
|
1758
|
+
children: [
|
|
1759
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
1760
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
1761
|
+
]
|
|
1762
|
+
}
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
function CircleCheckIcon() {
|
|
1766
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
|
|
1767
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1768
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1769
|
+
"path",
|
|
1770
|
+
{
|
|
1771
|
+
d: "M6 10l2.5 2.5L14 7.5",
|
|
1772
|
+
stroke: "currentColor",
|
|
1773
|
+
strokeWidth: "1.5",
|
|
1774
|
+
strokeLinecap: "round",
|
|
1775
|
+
strokeLinejoin: "round"
|
|
1776
|
+
}
|
|
1777
|
+
)
|
|
1778
|
+
] });
|
|
1779
|
+
}
|
|
1780
|
+
function CircleXIcon() {
|
|
1781
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
|
|
1782
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1783
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1784
|
+
"path",
|
|
1785
|
+
{
|
|
1786
|
+
d: "M7 7l6 6M13 7l-6 6",
|
|
1787
|
+
stroke: "currentColor",
|
|
1788
|
+
strokeWidth: "1.5",
|
|
1789
|
+
strokeLinecap: "round",
|
|
1790
|
+
strokeLinejoin: "round"
|
|
1791
|
+
}
|
|
1792
|
+
)
|
|
1793
|
+
] });
|
|
1794
|
+
}
|
|
1795
|
+
function ArrowRightIcon({ className }) {
|
|
1796
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "8", viewBox: "0 0 24 8", fill: "none", className, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1797
|
+
"path",
|
|
1798
|
+
{
|
|
1799
|
+
d: "M0 4h22m0 0l-4-4m4 4l-4 4",
|
|
1800
|
+
stroke: "currentColor",
|
|
1801
|
+
strokeWidth: "1.5",
|
|
1802
|
+
strokeLinecap: "round",
|
|
1803
|
+
strokeLinejoin: "round"
|
|
1804
|
+
}
|
|
1805
|
+
) });
|
|
1806
|
+
}
|
|
1767
1807
|
function CheckIcon() {
|
|
1768
1808
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1769
1809
|
"path",
|
|
@@ -1960,7 +2000,7 @@ function DepositForm({
|
|
|
1960
2000
|
onSuccess
|
|
1961
2001
|
}) {
|
|
1962
2002
|
const { isConnected, address } = wagmi.useAccount();
|
|
1963
|
-
const { chains, getChainById: getChainById2 } =
|
|
2003
|
+
const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
1964
2004
|
const [amount, setAmount] = react.useState("");
|
|
1965
2005
|
const [showSuccess, setShowSuccess] = react.useState(false);
|
|
1966
2006
|
const [showTimeout, setShowTimeout] = react.useState(false);
|
|
@@ -1985,7 +2025,7 @@ function DepositForm({
|
|
|
1985
2025
|
}
|
|
1986
2026
|
});
|
|
1987
2027
|
const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
|
|
1988
|
-
const formattedWalletBalance = walletBalance ?
|
|
2028
|
+
const formattedWalletBalance = walletBalance ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
|
|
1989
2029
|
const handleMaxClick = () => {
|
|
1990
2030
|
if (formattedWalletBalance && parseFloat(formattedWalletBalance) > 0) {
|
|
1991
2031
|
setAmount(formattedWalletBalance.replace(/[\s\u2009]/g, ""));
|
|
@@ -1993,7 +2033,7 @@ function DepositForm({
|
|
|
1993
2033
|
};
|
|
1994
2034
|
const hasValidAmount = amount && parseFloat(amount) > 0;
|
|
1995
2035
|
const tooManyDecimals = hasValidAmount && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
|
|
1996
|
-
const exceedsBalance = hasValidAmount && !tooManyDecimals && walletBalance != null &&
|
|
2036
|
+
const exceedsBalance = hasValidAmount && !tooManyDecimals && walletBalance != null && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
|
|
1997
2037
|
const {
|
|
1998
2038
|
txHash,
|
|
1999
2039
|
isGettingAddress,
|
|
@@ -2078,7 +2118,7 @@ function DepositForm({
|
|
|
2078
2118
|
const handleSubmit = async () => {
|
|
2079
2119
|
if (!amount || !selectedToken || exceedsBalance) return;
|
|
2080
2120
|
setCancelled(false);
|
|
2081
|
-
const amountInWei =
|
|
2121
|
+
const amountInWei = chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals);
|
|
2082
2122
|
await deposit({
|
|
2083
2123
|
tokenId: selectedToken.id,
|
|
2084
2124
|
amount: amountInWei
|
|
@@ -2181,7 +2221,7 @@ function DepositForm({
|
|
|
2181
2221
|
setAmount(value);
|
|
2182
2222
|
}
|
|
2183
2223
|
},
|
|
2184
|
-
className:
|
|
2224
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2185
2225
|
"text-foreground flex-1 bg-transparent text-sm outline-none",
|
|
2186
2226
|
"placeholder:text-muted-foreground/50"
|
|
2187
2227
|
)
|
|
@@ -2208,7 +2248,7 @@ function DepositForm({
|
|
|
2208
2248
|
{
|
|
2209
2249
|
onClick: handleSubmit,
|
|
2210
2250
|
disabled: !isConnected || !hasValidAmount || tooManyDecimals || !!exceedsBalance || isPending,
|
|
2211
|
-
className:
|
|
2251
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2212
2252
|
"flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors",
|
|
2213
2253
|
"bg-primary text-primary-foreground hover:bg-primary/90",
|
|
2214
2254
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
@@ -2225,7 +2265,7 @@ function WithdrawForm({
|
|
|
2225
2265
|
onUnsafeToCloseChange
|
|
2226
2266
|
}) {
|
|
2227
2267
|
const { isConnected, address } = wagmi.useAccount();
|
|
2228
|
-
const { chains, getChainById: getChainById2 } =
|
|
2268
|
+
const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
2229
2269
|
const [amount, setAmount] = react.useState("");
|
|
2230
2270
|
const [showSuccess, setShowSuccess] = react.useState(false);
|
|
2231
2271
|
const [showTimeout, setShowTimeout] = react.useState(false);
|
|
@@ -2238,7 +2278,7 @@ function WithdrawForm({
|
|
|
2238
2278
|
} = useBalance({
|
|
2239
2279
|
tokenId: selectedToken.id
|
|
2240
2280
|
});
|
|
2241
|
-
const formattedBalance =
|
|
2281
|
+
const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
|
|
2242
2282
|
const { withdraw, isPending, currentStep, error, reset } = useWithdraw({
|
|
2243
2283
|
onProcessingSuccess: () => {
|
|
2244
2284
|
setAmount("");
|
|
@@ -2249,7 +2289,7 @@ function WithdrawForm({
|
|
|
2249
2289
|
setShowTimeout(true);
|
|
2250
2290
|
}
|
|
2251
2291
|
});
|
|
2252
|
-
const explorerUrl = address && targetChain ?
|
|
2292
|
+
const explorerUrl = address && targetChain ? chunk4IW4V7YJ_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
|
|
2253
2293
|
const getStepStatus = (step, after) => {
|
|
2254
2294
|
if (currentStep === step) return "active";
|
|
2255
2295
|
if (after.includes(currentStep)) return "completed";
|
|
@@ -2293,7 +2333,7 @@ function WithdrawForm({
|
|
|
2293
2333
|
const handleWithdraw = async () => {
|
|
2294
2334
|
if (!amount || !selectedToken || exceedsBalance) return;
|
|
2295
2335
|
setCancelled(false);
|
|
2296
|
-
const amountInWei =
|
|
2336
|
+
const amountInWei = chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals);
|
|
2297
2337
|
await withdraw({
|
|
2298
2338
|
tokenId: selectedToken.id,
|
|
2299
2339
|
amount: amountInWei
|
|
@@ -2306,7 +2346,7 @@ function WithdrawForm({
|
|
|
2306
2346
|
};
|
|
2307
2347
|
const hasValidAmount = amount && parseFloat(amount) > 0;
|
|
2308
2348
|
const tooManyDecimals = hasValidAmount && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
|
|
2309
|
-
const exceedsBalance = hasValidAmount && !tooManyDecimals && !isBalanceLoading && !isBalanceError &&
|
|
2349
|
+
const exceedsBalance = hasValidAmount && !tooManyDecimals && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
|
|
2310
2350
|
const getButtonText = () => {
|
|
2311
2351
|
if (!isConnected) return "Connect Wallet";
|
|
2312
2352
|
return "Withdraw";
|
|
@@ -2318,7 +2358,7 @@ function WithdrawForm({
|
|
|
2318
2358
|
title: "Withdrawal Complete",
|
|
2319
2359
|
message: `Your ${selectedToken.symbol} withdrawal has been processed. Funds should appear in your wallet shortly.`,
|
|
2320
2360
|
explorerUrl,
|
|
2321
|
-
explorerLabel:
|
|
2361
|
+
explorerLabel: targetChain ? chunk4IW4V7YJ_cjs.getExplorerLabel(targetChain.id) : void 0,
|
|
2322
2362
|
onDone: handleDone
|
|
2323
2363
|
}
|
|
2324
2364
|
);
|
|
@@ -2389,7 +2429,7 @@ function WithdrawForm({
|
|
|
2389
2429
|
setAmount(value);
|
|
2390
2430
|
}
|
|
2391
2431
|
},
|
|
2392
|
-
className:
|
|
2432
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2393
2433
|
"text-foreground flex-1 bg-transparent text-sm outline-none",
|
|
2394
2434
|
"placeholder:text-muted-foreground/50"
|
|
2395
2435
|
)
|
|
@@ -2416,7 +2456,7 @@ function WithdrawForm({
|
|
|
2416
2456
|
{
|
|
2417
2457
|
onClick: handleWithdraw,
|
|
2418
2458
|
disabled: !isConnected || !hasValidAmount || tooManyDecimals || !!exceedsBalance || isPending,
|
|
2419
|
-
className:
|
|
2459
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2420
2460
|
"flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors",
|
|
2421
2461
|
"bg-primary text-primary-foreground hover:bg-primary/90",
|
|
2422
2462
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
@@ -2426,66 +2466,6 @@ function WithdrawForm({
|
|
|
2426
2466
|
)
|
|
2427
2467
|
] });
|
|
2428
2468
|
}
|
|
2429
|
-
function CloseIcon() {
|
|
2430
|
-
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2431
|
-
"path",
|
|
2432
|
-
{
|
|
2433
|
-
d: "M11.99997 11.99997l-5.99995-5.99995-6.00002-6.00002m6.00002 6.00002l6.00001-6.00002m-12.00003 12.00003l6.00002-6.00001",
|
|
2434
|
-
stroke: "currentColor",
|
|
2435
|
-
strokeWidth: "1.5",
|
|
2436
|
-
strokeLinecap: "round",
|
|
2437
|
-
strokeLinejoin: "round"
|
|
2438
|
-
}
|
|
2439
|
-
) });
|
|
2440
|
-
}
|
|
2441
|
-
function ChevronRight() {
|
|
2442
|
-
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "5", viewBox: "0 0 12 6", className: "-rotate-90", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2443
|
-
"path",
|
|
2444
|
-
{
|
|
2445
|
-
d: "M0 0l6 6 6-6",
|
|
2446
|
-
stroke: "currentColor",
|
|
2447
|
-
strokeWidth: "1.5",
|
|
2448
|
-
strokeLinecap: "round",
|
|
2449
|
-
strokeLinejoin: "round",
|
|
2450
|
-
fill: "none"
|
|
2451
|
-
}
|
|
2452
|
-
) });
|
|
2453
|
-
}
|
|
2454
|
-
function ChevronLeft() {
|
|
2455
|
-
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "5", viewBox: "0 0 12 6", className: "rotate-90", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2456
|
-
"path",
|
|
2457
|
-
{
|
|
2458
|
-
d: "M0 0l6 6 6-6",
|
|
2459
|
-
stroke: "currentColor",
|
|
2460
|
-
strokeWidth: "1.5",
|
|
2461
|
-
strokeLinecap: "round",
|
|
2462
|
-
strokeLinejoin: "round",
|
|
2463
|
-
fill: "none"
|
|
2464
|
-
}
|
|
2465
|
-
) });
|
|
2466
|
-
}
|
|
2467
|
-
function ChevronDown({ collapsed }) {
|
|
2468
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2469
|
-
"svg",
|
|
2470
|
-
{
|
|
2471
|
-
width: "12",
|
|
2472
|
-
height: "6",
|
|
2473
|
-
viewBox: "0 0 12 6",
|
|
2474
|
-
className: chunkNMRIKUDN_cjs.cn("transition-transform", collapsed && "-rotate-90"),
|
|
2475
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2476
|
-
"path",
|
|
2477
|
-
{
|
|
2478
|
-
d: "M0 0l6 6 6-6",
|
|
2479
|
-
stroke: "currentColor",
|
|
2480
|
-
strokeWidth: "1.5",
|
|
2481
|
-
strokeLinecap: "round",
|
|
2482
|
-
strokeLinejoin: "round",
|
|
2483
|
-
fill: "none"
|
|
2484
|
-
}
|
|
2485
|
-
)
|
|
2486
|
-
}
|
|
2487
|
-
);
|
|
2488
|
-
}
|
|
2489
2469
|
function BalanceCards({
|
|
2490
2470
|
selectedToken,
|
|
2491
2471
|
onLockedFundsClick,
|
|
@@ -2497,15 +2477,15 @@ function BalanceCards({
|
|
|
2497
2477
|
tokenId: selectedToken.id
|
|
2498
2478
|
});
|
|
2499
2479
|
const { totalLocked, isLoading: lockedLoading } = useLockedFunds({ enabled: showLockedFunds });
|
|
2500
|
-
const formattedBalance =
|
|
2501
|
-
const formattedLocked = showLockedFunds ?
|
|
2502
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
2480
|
+
const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
|
|
2481
|
+
const formattedLocked = showLockedFunds ? chunk4IW4V7YJ_cjs.formatTokenAmount(String(totalLocked), selectedToken.decimals) : "0.00";
|
|
2482
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunk4IW4V7YJ_cjs.cn("flex gap-2", disabled && "opacity-50"), children: [
|
|
2503
2483
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2504
2484
|
"button",
|
|
2505
2485
|
{
|
|
2506
2486
|
onClick: onBalanceClick,
|
|
2507
2487
|
disabled,
|
|
2508
|
-
className:
|
|
2488
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2509
2489
|
"bg-muted flex flex-1 flex-col gap-2 rounded-[10px] p-5 text-left transition-colors",
|
|
2510
2490
|
disabled ? "cursor-not-allowed" : "hover:bg-muted/80 cursor-pointer"
|
|
2511
2491
|
),
|
|
@@ -2515,7 +2495,7 @@ function BalanceCards({
|
|
|
2515
2495
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "Balance" }),
|
|
2516
2496
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary text-muted-foreground rounded-full px-2 py-[5px] text-[10px] font-bold", children: selectedToken.symbol })
|
|
2517
2497
|
] }),
|
|
2518
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-6 w-6 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2498
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-6 w-6 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {}) })
|
|
2519
2499
|
] }),
|
|
2520
2500
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground text-xl font-medium", children: balanceLoading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary inline-block h-6 w-24 animate-pulse rounded" }) : formattedBalance })
|
|
2521
2501
|
]
|
|
@@ -2526,7 +2506,7 @@ function BalanceCards({
|
|
|
2526
2506
|
{
|
|
2527
2507
|
onClick: onLockedFundsClick,
|
|
2528
2508
|
disabled,
|
|
2529
|
-
className:
|
|
2509
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2530
2510
|
"bg-muted flex flex-1 flex-col gap-2 rounded-[10px] p-5 text-left transition-colors",
|
|
2531
2511
|
disabled ? "cursor-not-allowed" : "hover:bg-muted/80 cursor-pointer"
|
|
2532
2512
|
),
|
|
@@ -2536,7 +2516,7 @@ function BalanceCards({
|
|
|
2536
2516
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "Locked Funds" }),
|
|
2537
2517
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary text-muted-foreground rounded-full px-2 py-[5px] text-[10px] font-bold", children: selectedToken.symbol })
|
|
2538
2518
|
] }),
|
|
2539
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-6 w-6 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-6 w-6 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {}) })
|
|
2540
2520
|
] }),
|
|
2541
2521
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground text-xl font-medium", children: lockedLoading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary inline-block h-6 w-20 animate-pulse rounded" }) : formattedLocked })
|
|
2542
2522
|
]
|
|
@@ -2552,7 +2532,7 @@ function Tabs({
|
|
|
2552
2532
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2553
2533
|
"div",
|
|
2554
2534
|
{
|
|
2555
|
-
className:
|
|
2535
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2556
2536
|
"bg-muted relative flex gap-2 overflow-hidden rounded-[10px] p-1",
|
|
2557
2537
|
disabled && "opacity-50"
|
|
2558
2538
|
),
|
|
@@ -2560,7 +2540,7 @@ function Tabs({
|
|
|
2560
2540
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2561
2541
|
"div",
|
|
2562
2542
|
{
|
|
2563
|
-
className:
|
|
2543
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2564
2544
|
"bg-input absolute top-1 bottom-1 left-1 w-[calc(50%-8px)] rounded-md transition-transform duration-200",
|
|
2565
2545
|
activeTab === "withdraw" && "translate-x-[calc(100%+8px)]"
|
|
2566
2546
|
)
|
|
@@ -2571,7 +2551,7 @@ function Tabs({
|
|
|
2571
2551
|
{
|
|
2572
2552
|
onClick: () => !disabled && onTabChange("deposit"),
|
|
2573
2553
|
disabled,
|
|
2574
|
-
className:
|
|
2554
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2575
2555
|
"relative z-10 flex-1 rounded-md px-3 py-[9px] text-sm transition-colors",
|
|
2576
2556
|
activeTab === "deposit" ? "text-foreground" : "text-muted-foreground",
|
|
2577
2557
|
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
@@ -2584,7 +2564,7 @@ function Tabs({
|
|
|
2584
2564
|
{
|
|
2585
2565
|
onClick: () => !disabled && onTabChange("withdraw"),
|
|
2586
2566
|
disabled,
|
|
2587
|
-
className:
|
|
2567
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2588
2568
|
"relative z-10 flex-1 rounded-md px-3 py-[9px] text-sm transition-colors",
|
|
2589
2569
|
activeTab === "withdraw" ? "text-foreground" : "text-muted-foreground",
|
|
2590
2570
|
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
@@ -2597,14 +2577,14 @@ function Tabs({
|
|
|
2597
2577
|
);
|
|
2598
2578
|
}
|
|
2599
2579
|
function LockedFundsView({ onBack }) {
|
|
2600
|
-
const { getTokenById } =
|
|
2580
|
+
const { getTokenById } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
2601
2581
|
const { locks, isLoading } = useLockedFunds();
|
|
2602
2582
|
const { unlockFunds, unlockAllExpired, isPending } = useUnlockFunds();
|
|
2603
2583
|
const [collapsedSections, setCollapsedSections] = react.useState({});
|
|
2604
2584
|
const sections = react.useMemo(() => {
|
|
2605
2585
|
const sectionMap = {};
|
|
2606
2586
|
locks.forEach((lock) => {
|
|
2607
|
-
const serviceName =
|
|
2587
|
+
const serviceName = chunk4IW4V7YJ_cjs.shortenAddress(lock.service_address);
|
|
2608
2588
|
if (!sectionMap[lock.service_address]) {
|
|
2609
2589
|
sectionMap[lock.service_address] = {
|
|
2610
2590
|
title: `Service ${serviceName}`,
|
|
@@ -2613,9 +2593,9 @@ function LockedFundsView({ onBack }) {
|
|
|
2613
2593
|
}
|
|
2614
2594
|
sectionMap[lock.service_address].items.push({
|
|
2615
2595
|
lockId: lock.lock_id,
|
|
2616
|
-
amount:
|
|
2596
|
+
amount: chunk4IW4V7YJ_cjs.formatTokenAmount(String(lock.amount), getTokenById(lock.token_id)?.decimals ?? 18),
|
|
2617
2597
|
serviceAddress: lock.service_address,
|
|
2618
|
-
time: lock.is_expired ? "Click to unlock" :
|
|
2598
|
+
time: lock.is_expired ? "Click to unlock" : chunk4IW4V7YJ_cjs.formatTimeRemaining(lock.expiry),
|
|
2619
2599
|
isExpired: lock.is_expired
|
|
2620
2600
|
});
|
|
2621
2601
|
});
|
|
@@ -2635,7 +2615,7 @@ function LockedFundsView({ onBack }) {
|
|
|
2635
2615
|
{
|
|
2636
2616
|
onClick: onBack,
|
|
2637
2617
|
className: "text-muted-foreground hover:text-foreground -ml-2 flex h-6 w-6 cursor-pointer items-center justify-center transition-colors",
|
|
2638
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2618
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
2639
2619
|
}
|
|
2640
2620
|
),
|
|
2641
2621
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-6 font-medium", children: "Locked Funds" })
|
|
@@ -2655,14 +2635,19 @@ function LockedFundsView({ onBack }) {
|
|
|
2655
2635
|
className: "text-muted-foreground hover:bg-secondary flex w-full cursor-pointer items-center justify-between rounded-lg px-4 py-4 transition-colors",
|
|
2656
2636
|
children: [
|
|
2657
2637
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: section.title }),
|
|
2658
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2638
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2639
|
+
ChevronDownIcon,
|
|
2640
|
+
{
|
|
2641
|
+
direction: collapsedSections[section.title] ? "right" : "down"
|
|
2642
|
+
}
|
|
2643
|
+
)
|
|
2659
2644
|
]
|
|
2660
2645
|
}
|
|
2661
2646
|
),
|
|
2662
2647
|
!collapsedSections[section.title] && section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2663
2648
|
"div",
|
|
2664
2649
|
{
|
|
2665
|
-
className:
|
|
2650
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2666
2651
|
"flex items-center justify-between gap-3 rounded-lg p-3",
|
|
2667
2652
|
item.isExpired && "bg-secondary"
|
|
2668
2653
|
),
|
|
@@ -2676,7 +2661,7 @@ function LockedFundsView({ onBack }) {
|
|
|
2676
2661
|
] }),
|
|
2677
2662
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
|
|
2678
2663
|
"Service: ",
|
|
2679
|
-
|
|
2664
|
+
chunk4IW4V7YJ_cjs.shortenAddress(item.serviceAddress)
|
|
2680
2665
|
] })
|
|
2681
2666
|
] })
|
|
2682
2667
|
] }),
|
|
@@ -2717,7 +2702,7 @@ function BalanceTokenRow({ token }) {
|
|
|
2717
2702
|
const { balanceWei, isLoading } = useBalance({
|
|
2718
2703
|
tokenId: token.id
|
|
2719
2704
|
});
|
|
2720
|
-
const formattedBalance =
|
|
2705
|
+
const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, token.decimals);
|
|
2721
2706
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2 rounded-lg px-3 py-2.5", children: [
|
|
2722
2707
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[18px] w-[18px] overflow-hidden rounded-full", children: getTokenIcon(token.symbol, 18) }),
|
|
2723
2708
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground flex-1 text-sm", children: token.symbol }),
|
|
@@ -2725,7 +2710,7 @@ function BalanceTokenRow({ token }) {
|
|
|
2725
2710
|
] });
|
|
2726
2711
|
}
|
|
2727
2712
|
function BalanceDetailsView({ onBack }) {
|
|
2728
|
-
const { enabledTokens, chains } =
|
|
2713
|
+
const { enabledTokens, chains } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
2729
2714
|
const [selectedChainId, setSelectedChainId] = react.useState(chains[0]?.id ?? 84532);
|
|
2730
2715
|
const chainTokens = react.useMemo(() => {
|
|
2731
2716
|
return enabledTokens.filter((t) => t.chainId === selectedChainId);
|
|
@@ -2737,7 +2722,7 @@ function BalanceDetailsView({ onBack }) {
|
|
|
2737
2722
|
{
|
|
2738
2723
|
onClick: onBack,
|
|
2739
2724
|
className: "text-muted-foreground hover:text-foreground -ml-2 flex h-6 w-6 cursor-pointer items-center justify-center transition-colors",
|
|
2740
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2725
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
2741
2726
|
}
|
|
2742
2727
|
),
|
|
2743
2728
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-6 font-medium", children: "Token Balances" })
|
|
@@ -2751,7 +2736,7 @@ function BalanceDetailsView({ onBack }) {
|
|
|
2751
2736
|
"button",
|
|
2752
2737
|
{
|
|
2753
2738
|
onClick: () => setSelectedChainId(chain.id),
|
|
2754
|
-
className:
|
|
2739
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2755
2740
|
"hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
|
|
2756
2741
|
isSelected && "bg-secondary"
|
|
2757
2742
|
),
|
|
@@ -2792,12 +2777,12 @@ function TokenRow({
|
|
|
2792
2777
|
query: { enabled: !!address && !isNative }
|
|
2793
2778
|
});
|
|
2794
2779
|
const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
|
|
2795
|
-
const formattedBalance = walletBalance ?
|
|
2780
|
+
const formattedBalance = walletBalance ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), token.decimals) : "0.00";
|
|
2796
2781
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2797
2782
|
"button",
|
|
2798
2783
|
{
|
|
2799
2784
|
onClick,
|
|
2800
|
-
className:
|
|
2785
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2801
2786
|
"hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
|
|
2802
2787
|
isSelected && "bg-secondary"
|
|
2803
2788
|
),
|
|
@@ -2814,7 +2799,7 @@ function TokenSelectorView({
|
|
|
2814
2799
|
onSelect,
|
|
2815
2800
|
selectedTokenId
|
|
2816
2801
|
}) {
|
|
2817
|
-
const { enabledTokens, chains } =
|
|
2802
|
+
const { enabledTokens, chains } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
2818
2803
|
const [selectedChainId, setSelectedChainId] = react.useState(chains[0]?.id ?? 84532);
|
|
2819
2804
|
const chainTokens = react.useMemo(() => {
|
|
2820
2805
|
return enabledTokens.filter((t) => t.chainId === selectedChainId);
|
|
@@ -2830,7 +2815,7 @@ function TokenSelectorView({
|
|
|
2830
2815
|
{
|
|
2831
2816
|
onClick: onBack,
|
|
2832
2817
|
className: "text-muted-foreground hover:text-foreground -ml-2 flex h-6 w-6 cursor-pointer items-center justify-center transition-colors",
|
|
2833
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2818
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
2834
2819
|
}
|
|
2835
2820
|
),
|
|
2836
2821
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-6 font-medium", children: "Select Token" })
|
|
@@ -2844,7 +2829,7 @@ function TokenSelectorView({
|
|
|
2844
2829
|
"button",
|
|
2845
2830
|
{
|
|
2846
2831
|
onClick: () => setSelectedChainId(chain.id),
|
|
2847
|
-
className:
|
|
2832
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
2848
2833
|
"hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
|
|
2849
2834
|
isSelected && "bg-secondary"
|
|
2850
2835
|
),
|
|
@@ -2879,7 +2864,7 @@ function ModalBody({
|
|
|
2879
2864
|
defaultTab = "deposit",
|
|
2880
2865
|
onDepositSuccess
|
|
2881
2866
|
}) {
|
|
2882
|
-
const { defaultToken, tokensStatus } =
|
|
2867
|
+
const { defaultToken, tokensStatus } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
2883
2868
|
const [selectedToken, setSelectedToken] = react.useState(defaultToken);
|
|
2884
2869
|
const [activeTab, setActiveTab] = react.useState(defaultTab);
|
|
2885
2870
|
const [currentView, setCurrentView] = react.useState("main");
|
|
@@ -2937,7 +2922,7 @@ function ModalBody({
|
|
|
2937
2922
|
);
|
|
2938
2923
|
}
|
|
2939
2924
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 pb-4", children: [
|
|
2940
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
2925
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk4IW4V7YJ_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2941
2926
|
BalanceCards,
|
|
2942
2927
|
{
|
|
2943
2928
|
selectedToken,
|
|
@@ -2947,7 +2932,7 @@ function ModalBody({
|
|
|
2947
2932
|
disabled: isInteractionPending
|
|
2948
2933
|
}
|
|
2949
2934
|
) }),
|
|
2950
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
2935
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk4IW4V7YJ_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(Tabs, { activeTab, onTabChange: setActiveTab, disabled: isInteractionPending }) }),
|
|
2951
2936
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted rounded-[10px] p-5", children: activeTab === "deposit" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2952
2937
|
DepositForm,
|
|
2953
2938
|
{
|
|
@@ -3008,7 +2993,7 @@ function PrivanaModal({
|
|
|
3008
2993
|
onClick: handleClose,
|
|
3009
2994
|
disabled: isCloseBlocked,
|
|
3010
2995
|
"aria-label": "Close",
|
|
3011
|
-
className:
|
|
2996
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3012
2997
|
"absolute top-6 right-5 z-20 flex h-6 w-6 items-center justify-center transition-colors",
|
|
3013
2998
|
isCloseBlocked ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
|
|
3014
2999
|
),
|
|
@@ -3064,7 +3049,7 @@ function PrivanaInlineModal({
|
|
|
3064
3049
|
"div",
|
|
3065
3050
|
{
|
|
3066
3051
|
"data-privana": true,
|
|
3067
|
-
className:
|
|
3052
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3068
3053
|
"bg-card flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
|
|
3069
3054
|
className
|
|
3070
3055
|
),
|
|
@@ -3099,12 +3084,12 @@ function PrivanaButton({
|
|
|
3099
3084
|
}
|
|
3100
3085
|
const handleClick = () => setModalOpen(true);
|
|
3101
3086
|
const buttonElement = renderButton ? renderButton({ onClick: handleClick, isOpen: modalOpen }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3102
|
-
|
|
3087
|
+
chunk4IW4V7YJ_cjs.Button,
|
|
3103
3088
|
{
|
|
3104
3089
|
variant,
|
|
3105
3090
|
size,
|
|
3106
3091
|
asChild,
|
|
3107
|
-
className:
|
|
3092
|
+
className: chunk4IW4V7YJ_cjs.cn(className),
|
|
3108
3093
|
onClick: handleClick,
|
|
3109
3094
|
disabled: !isConnected,
|
|
3110
3095
|
...buttonProps,
|
|
@@ -3125,215 +3110,2122 @@ function PrivanaButton({
|
|
|
3125
3110
|
)
|
|
3126
3111
|
] });
|
|
3127
3112
|
}
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
});
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
});
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
}
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
}
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
})
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
});
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
});
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
})
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3113
|
+
var DEFAULT_MOONPAY_API_URL = "https://api.moonpay.com/v3";
|
|
3114
|
+
function useMoonpayLimits({
|
|
3115
|
+
currencyCode,
|
|
3116
|
+
baseCurrencyCode = "usd",
|
|
3117
|
+
paymentMethod = "credit_debit_card",
|
|
3118
|
+
apiBaseUrl = DEFAULT_MOONPAY_API_URL,
|
|
3119
|
+
enabled = true
|
|
3120
|
+
}) {
|
|
3121
|
+
const { apiKey } = react.useContext(moonpayReact.MoonPayContext) ?? {};
|
|
3122
|
+
const canFetch = enabled && !!apiKey && !!currencyCode;
|
|
3123
|
+
const query = reactQuery.useQuery({
|
|
3124
|
+
queryKey: ["moonpay-limits", apiBaseUrl, currencyCode, baseCurrencyCode, paymentMethod, apiKey],
|
|
3125
|
+
enabled: canFetch,
|
|
3126
|
+
staleTime: 5 * 6e4,
|
|
3127
|
+
queryFn: async () => {
|
|
3128
|
+
const params = new URLSearchParams({
|
|
3129
|
+
apiKey,
|
|
3130
|
+
baseCurrencyCode,
|
|
3131
|
+
paymentMethod,
|
|
3132
|
+
areFeesIncluded: "true"
|
|
3133
|
+
});
|
|
3134
|
+
const res = await fetch(
|
|
3135
|
+
`${apiBaseUrl}/currencies/${currencyCode}/limits?${params.toString()}`
|
|
3136
|
+
);
|
|
3137
|
+
if (!res.ok) {
|
|
3138
|
+
throw new Error(`MoonPay limits request failed: ${res.status}`);
|
|
3139
|
+
}
|
|
3140
|
+
const data = await res.json();
|
|
3141
|
+
const asNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3142
|
+
return {
|
|
3143
|
+
minBuyAmount: asNumber(data.baseCurrency?.minBuyAmount),
|
|
3144
|
+
maxBuyAmount: asNumber(data.baseCurrency?.maxBuyAmount)
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
});
|
|
3148
|
+
return {
|
|
3149
|
+
minBuyAmount: query.data?.minBuyAmount,
|
|
3150
|
+
maxBuyAmount: query.data?.maxBuyAmount,
|
|
3151
|
+
isLoading: query.isLoading,
|
|
3152
|
+
error: query.error ?? null
|
|
3153
|
+
};
|
|
3154
|
+
}
|
|
3155
|
+
function TokenSelectorView2({ selectedTokenId, onSelect }) {
|
|
3156
|
+
const { enabledTokens } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
3157
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col rounded-[10px] p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-h-72 flex-col gap-1 overflow-y-auto", children: [
|
|
3158
|
+
enabledTokens.map((token) => {
|
|
3159
|
+
const isSelected = selectedTokenId === token.id;
|
|
3160
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3161
|
+
"button",
|
|
3162
|
+
{
|
|
3163
|
+
type: "button",
|
|
3164
|
+
onClick: () => onSelect(token.id),
|
|
3165
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3166
|
+
"hover:bg-secondary flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-left transition-colors",
|
|
3167
|
+
isSelected && "bg-secondary"
|
|
3168
|
+
),
|
|
3169
|
+
children: [
|
|
3170
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 shrink-0 overflow-hidden rounded-full", children: getTokenIcon(token.symbol, 24) }),
|
|
3171
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3172
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground text-sm font-medium", children: token.symbol }),
|
|
3173
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground text-[11px]", children: token.name })
|
|
3174
|
+
] }),
|
|
3175
|
+
isSelected && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-primary flex h-4 w-4 shrink-0 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3176
|
+
"svg",
|
|
3177
|
+
{
|
|
3178
|
+
width: "10",
|
|
3179
|
+
height: "10",
|
|
3180
|
+
viewBox: "0 0 10 10",
|
|
3181
|
+
fill: "none",
|
|
3182
|
+
className: "text-primary-foreground",
|
|
3183
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3184
|
+
"path",
|
|
3185
|
+
{
|
|
3186
|
+
d: "M2 5L4 7L8 3",
|
|
3187
|
+
stroke: "currentColor",
|
|
3188
|
+
strokeWidth: "1.5",
|
|
3189
|
+
strokeLinecap: "round",
|
|
3190
|
+
strokeLinejoin: "round"
|
|
3191
|
+
}
|
|
3192
|
+
)
|
|
3193
|
+
}
|
|
3194
|
+
) })
|
|
3195
|
+
]
|
|
3196
|
+
},
|
|
3197
|
+
token.id
|
|
3198
|
+
);
|
|
3199
|
+
}),
|
|
3200
|
+
enabledTokens.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground px-3 py-6 text-center text-sm", children: "No tokens available" })
|
|
3201
|
+
] }) });
|
|
3202
|
+
}
|
|
3203
|
+
function CreditCardWidgetView({
|
|
3204
|
+
token,
|
|
3205
|
+
amount,
|
|
3206
|
+
allowance,
|
|
3207
|
+
onCredited,
|
|
3208
|
+
onLockSubmitted,
|
|
3209
|
+
onLockFailed
|
|
3210
|
+
}) {
|
|
3211
|
+
const moonpayCurrencyCode = token?.moonpayCurrencyCode;
|
|
3212
|
+
const containerRef = react.useRef(null);
|
|
3213
|
+
const [widgetTheme, setWidgetTheme] = react.useState();
|
|
3214
|
+
react.useEffect(() => {
|
|
3215
|
+
if (containerRef.current) setWidgetTheme(resolveSdkTheme(containerRef.current));
|
|
3216
|
+
}, []);
|
|
3217
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
3218
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Complete your purchase" }),
|
|
3219
|
+
token && moonpayCurrencyCode ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3220
|
+
chunk4IW4V7YJ_cjs.FiatOnRampForm,
|
|
3221
|
+
{
|
|
3222
|
+
tokenId: token.id,
|
|
3223
|
+
currencyCode: moonpayCurrencyCode,
|
|
3224
|
+
quoteCurrencyAmount: amount || void 0,
|
|
3225
|
+
lockAmount: true,
|
|
3226
|
+
variant: "embedded",
|
|
3227
|
+
autoStart: true,
|
|
3228
|
+
theme: widgetTheme,
|
|
3229
|
+
postDepositLock: allowance ? {
|
|
3230
|
+
maxAmount: BigInt(allowance.value),
|
|
3231
|
+
lockDuration: allowance.lockDuration
|
|
3232
|
+
} : void 0,
|
|
3233
|
+
onCredited,
|
|
3234
|
+
onLockSubmitted,
|
|
3235
|
+
onLockFailed
|
|
3236
|
+
}
|
|
3237
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground text-sm", children: [
|
|
3238
|
+
token?.symbol ?? "This token",
|
|
3239
|
+
" isn\u2019t available for card purchases yet."
|
|
3240
|
+
] })
|
|
3241
|
+
] });
|
|
3242
|
+
}
|
|
3243
|
+
function resolveSdkTheme(el) {
|
|
3244
|
+
const scheme = getComputedStyle(el).colorScheme;
|
|
3245
|
+
if (scheme === "dark") return "dark";
|
|
3246
|
+
if (scheme === "light") return "light";
|
|
3247
|
+
return el.closest(".dark") ? "dark" : "light";
|
|
3248
|
+
}
|
|
3249
|
+
function PrivanaIcon({ className, size = 32 }) {
|
|
3250
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3251
|
+
"svg",
|
|
3252
|
+
{
|
|
3253
|
+
width: size,
|
|
3254
|
+
height: size,
|
|
3255
|
+
viewBox: "0 0 32 32",
|
|
3256
|
+
fill: "none",
|
|
3257
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3258
|
+
className,
|
|
3259
|
+
children: [
|
|
3260
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "32", height: "32", rx: "3.55556", fill: "black" }),
|
|
3261
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3262
|
+
"path",
|
|
3263
|
+
{
|
|
3264
|
+
d: "M9.02789 9.05299L9.20884 7.82227H15.6221L16.1099 7.82683L16.5817 7.83825L17.0398 7.85652L17.4842 7.88163L17.9125 7.91588L18.3271 7.95698L18.7256 8.00722L19.1104 8.06202L19.4814 8.12595L19.8823 8.20815L20.2602 8.2972L20.6175 8.39538L20.9542 8.50042L21.2703 8.61687L21.5657 8.74017L21.8406 8.8726L22.0948 9.01645L22.1521 9.05299H9.02789ZM9.02789 12.0784L9.20884 10.8477H21.9505L22.1177 10.955L22.317 11.1057L22.4934 11.2633L22.6445 11.4322L22.7705 11.608L22.8713 11.793L22.9491 11.9871L22.9721 12.0784H9.02789ZM15.8167 11.0372H13.1369L13.0843 12.0784H18.8447L18.8264 12.0213L18.7645 11.9072L18.6844 11.7976L18.5836 11.6948L18.4645 11.6012L18.3271 11.5121L18.1736 11.4299L18.0041 11.3569L17.8209 11.2907L17.6193 11.2313L17.404 11.1811L17.1727 11.1354L16.9276 11.1011L16.6711 11.0737L16.3985 11.0532L16.1145 11.0418L15.8167 11.0372ZM9.02789 15.1038L9.20884 13.8731H22.7453L22.7728 13.9759L22.8003 14.1334L22.8232 14.3252L22.8163 14.5102L22.7819 14.6905L22.7178 14.8664L22.6239 15.0376L22.5735 15.1038H9.02789ZM13.1484 13.8731L13.0843 15.1038H17.5323L17.6674 15.0696L17.8644 15.0079L18.043 14.9372L18.2034 14.8618L18.3454 14.7796L18.4691 14.6883L18.5744 14.5946L18.6569 14.4942L18.721 14.3914L18.7622 14.2841L18.7828 14.1722V14.0558L18.7622 13.9348L18.7416 13.8731H13.1484ZM9.02789 18.1293L9.20884 16.8985H22.3605L22.2895 16.9899L22.1406 17.1406L21.9643 17.2867L21.7581 17.426L21.5268 17.5561L21.2703 17.6817L20.9862 17.7982L20.6747 17.9055L20.3381 18.006L19.9739 18.0996L19.8387 18.1293H9.02789ZM13.1484 16.8985L13.1392 17.0629H15.8144L16.1145 17.0607L16.3985 17.047L16.6665 17.0264L16.9207 16.999L17.1612 16.9625L17.388 16.9168L17.4658 16.8985H13.1484ZM9.02789 21.1547L9.20884 19.9217H19.7036L19.4562 19.9742L19.0989 20.0381L18.7256 20.0952L18.3316 20.1432L17.9239 20.1843L17.4956 20.2185L17.0536 20.2459L16.5932 20.2642L16.1168 20.2756L15.6243 20.2802H13.1301L13.0843 21.1547H9.02789ZM13.0843 24.1778H9.02789L9.20884 22.9471H13.1484L13.0843 24.1778Z",
|
|
3265
|
+
fill: "white"
|
|
3266
|
+
}
|
|
3267
|
+
)
|
|
3268
|
+
]
|
|
3269
|
+
}
|
|
3270
|
+
);
|
|
3271
|
+
}
|
|
3272
|
+
function PolicyTermRow({
|
|
3273
|
+
term,
|
|
3274
|
+
kind
|
|
3275
|
+
}) {
|
|
3276
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
3277
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3278
|
+
"div",
|
|
3279
|
+
{
|
|
3280
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3281
|
+
"mt-0.5 shrink-0",
|
|
3282
|
+
kind === "permission" ? "text-emerald-500" : "text-orange-500"
|
|
3283
|
+
),
|
|
3284
|
+
children: kind === "permission" ? /* @__PURE__ */ jsxRuntime.jsx(CircleCheckIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(CircleXIcon, {})
|
|
3285
|
+
}
|
|
3286
|
+
),
|
|
3287
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3288
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm leading-5 font-medium", children: term.title }),
|
|
3289
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm leading-5", children: term.description })
|
|
3290
|
+
] })
|
|
3291
|
+
] });
|
|
3292
|
+
}
|
|
3293
|
+
function AllowancePolicySection({
|
|
3294
|
+
allowance,
|
|
3295
|
+
serviceName,
|
|
3296
|
+
serviceIcon
|
|
3297
|
+
}) {
|
|
3298
|
+
const [collapsed, setCollapsed] = react.useState(false);
|
|
3299
|
+
const permissions = allowance.terms?.permissions ?? [];
|
|
3300
|
+
const restrictions = allowance.terms?.restrictions ?? [];
|
|
3301
|
+
const hasTerms = permissions.length > 0 || restrictions.length > 0;
|
|
3302
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
3303
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
3304
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 items-center justify-center overflow-hidden rounded-lg", children: serviceIcon }),
|
|
3305
|
+
/* @__PURE__ */ jsxRuntime.jsx(ArrowRightIcon, { className: "text-muted-foreground" }),
|
|
3306
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrivanaIcon, { size: 32 })
|
|
3307
|
+
] }),
|
|
3308
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm leading-5", children: [
|
|
3309
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: serviceName }),
|
|
3310
|
+
" ",
|
|
3311
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "wants a policy on your Privana account." })
|
|
3312
|
+
] }),
|
|
3313
|
+
hasTerms && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3314
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3315
|
+
"button",
|
|
3316
|
+
{
|
|
3317
|
+
type: "button",
|
|
3318
|
+
onClick: () => setCollapsed((prev) => !prev),
|
|
3319
|
+
className: "flex w-full cursor-pointer items-center gap-2",
|
|
3320
|
+
children: [
|
|
3321
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-border h-px flex-1" }),
|
|
3322
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-[10px] leading-[14px] font-medium tracking-[0.2px] whitespace-nowrap uppercase", children: collapsed ? "Show details" : "Hide details" }),
|
|
3323
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3324
|
+
ChevronDownIcon,
|
|
3325
|
+
{
|
|
3326
|
+
direction: collapsed ? "down" : "up",
|
|
3327
|
+
className: "text-foreground shrink-0"
|
|
3328
|
+
}
|
|
3329
|
+
),
|
|
3330
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-border h-px flex-1" })
|
|
3331
|
+
]
|
|
3332
|
+
}
|
|
3333
|
+
),
|
|
3334
|
+
!collapsed && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
3335
|
+
permissions.map((term, i) => /* @__PURE__ */ jsxRuntime.jsx(PolicyTermRow, { term, kind: "permission" }, `permission-${i}`)),
|
|
3336
|
+
restrictions.map((term, i) => /* @__PURE__ */ jsxRuntime.jsx(PolicyTermRow, { term, kind: "restriction" }, `restriction-${i}`))
|
|
3337
|
+
] })
|
|
3338
|
+
] })
|
|
3339
|
+
] });
|
|
3340
|
+
}
|
|
3341
|
+
function MoonPayGate({ enabled, children }) {
|
|
3342
|
+
const { networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
3343
|
+
const apiKey = networkConfig.moonpayApiKey;
|
|
3344
|
+
if (!enabled || !apiKey) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
3345
|
+
return /* @__PURE__ */ jsxRuntime.jsx(moonpayReact.MoonPayProvider, { apiKey, children });
|
|
3346
|
+
}
|
|
3347
|
+
function MethodTabs({
|
|
3348
|
+
activeTab,
|
|
3349
|
+
onTabChange
|
|
3350
|
+
}) {
|
|
3351
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-secondary relative flex gap-2 overflow-hidden rounded-[10px] p-1", children: [
|
|
3352
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3353
|
+
"div",
|
|
3354
|
+
{
|
|
3355
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3356
|
+
"bg-input absolute top-1 bottom-1 left-1 w-[calc(50%-8px)] rounded-md transition-transform duration-200",
|
|
3357
|
+
activeTab === "credit-card" && "translate-x-[calc(100%+8px)]"
|
|
3358
|
+
)
|
|
3359
|
+
}
|
|
3360
|
+
),
|
|
3361
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3362
|
+
"button",
|
|
3363
|
+
{
|
|
3364
|
+
type: "button",
|
|
3365
|
+
onClick: () => onTabChange("crypto"),
|
|
3366
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3367
|
+
"relative z-10 flex-1 cursor-pointer rounded-md px-3 py-[9px] text-sm font-medium transition-colors",
|
|
3368
|
+
activeTab === "crypto" ? "text-foreground" : "text-muted-foreground"
|
|
3369
|
+
),
|
|
3370
|
+
children: "Crypto"
|
|
3371
|
+
}
|
|
3372
|
+
),
|
|
3373
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3374
|
+
"button",
|
|
3375
|
+
{
|
|
3376
|
+
type: "button",
|
|
3377
|
+
onClick: () => onTabChange("credit-card"),
|
|
3378
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3379
|
+
"relative z-10 flex-1 cursor-pointer rounded-md px-3 py-[9px] text-sm font-medium transition-colors",
|
|
3380
|
+
activeTab === "credit-card" ? "text-foreground" : "text-muted-foreground"
|
|
3381
|
+
),
|
|
3382
|
+
children: "Credit Card"
|
|
3383
|
+
}
|
|
3384
|
+
)
|
|
3385
|
+
] });
|
|
3386
|
+
}
|
|
3387
|
+
function MethodOption({
|
|
3388
|
+
title,
|
|
3389
|
+
description,
|
|
3390
|
+
onClick
|
|
3391
|
+
}) {
|
|
3392
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3393
|
+
"button",
|
|
3394
|
+
{
|
|
3395
|
+
type: "button",
|
|
3396
|
+
onClick,
|
|
3397
|
+
className: "bg-input hover:bg-input/70 border-border flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left transition-colors",
|
|
3398
|
+
children: [
|
|
3399
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
3400
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm leading-[14px] font-medium", children: title }),
|
|
3401
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs leading-3", children: description })
|
|
3402
|
+
] }),
|
|
3403
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-5 w-5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {}) })
|
|
3404
|
+
]
|
|
3405
|
+
}
|
|
3406
|
+
);
|
|
3407
|
+
}
|
|
3408
|
+
function DepositView({
|
|
3409
|
+
source,
|
|
3410
|
+
selectedToken,
|
|
3411
|
+
amount,
|
|
3412
|
+
allowance,
|
|
3413
|
+
onAmountChange,
|
|
3414
|
+
onSelectToken,
|
|
3415
|
+
onConnectWallet,
|
|
3416
|
+
onSubmit,
|
|
3417
|
+
isSubmitting = false
|
|
3418
|
+
}) {
|
|
3419
|
+
const { getChainById: getChainById2, chains, serviceName, serviceIcon, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
3420
|
+
const { address, isConnected } = wagmi.useAccount();
|
|
3421
|
+
const appName = serviceName ?? "Privana";
|
|
3422
|
+
const chain = selectedToken ? getChainById2(selectedToken.chainId) : void 0;
|
|
3423
|
+
const targetChain = chain ?? chains[0];
|
|
3424
|
+
const sourceLabel = source === "connected" ? "Connected Wallet" : "External Wallet";
|
|
3425
|
+
const isConnectedSource = source === "connected";
|
|
3426
|
+
const isCreditCard = source === "credit-card";
|
|
3427
|
+
const isNative = selectedToken?.contract === viem.zeroAddress;
|
|
3428
|
+
const { data: nativeBalanceData } = wagmi.useBalance({
|
|
3429
|
+
address,
|
|
3430
|
+
chainId: targetChain?.id,
|
|
3431
|
+
query: { enabled: isConnectedSource && !!address && !!selectedToken && isNative }
|
|
3432
|
+
});
|
|
3433
|
+
const { data: erc20Balance } = wagmi.useReadContract({
|
|
3434
|
+
address: selectedToken?.contract,
|
|
3435
|
+
abi: viem.erc20Abi,
|
|
3436
|
+
functionName: "balanceOf",
|
|
3437
|
+
args: address ? [address] : void 0,
|
|
3438
|
+
chainId: targetChain?.id,
|
|
3439
|
+
query: { enabled: isConnectedSource && !!address && !!selectedToken && !isNative }
|
|
3440
|
+
});
|
|
3441
|
+
const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
|
|
3442
|
+
const formattedWalletBalance = walletBalance != null && selectedToken ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
|
|
3443
|
+
const {
|
|
3444
|
+
minBuyAmount: moonpayMinBuy,
|
|
3445
|
+
isLoading: moonpayLimitsLoading,
|
|
3446
|
+
error: moonpayLimitsError
|
|
3447
|
+
} = useMoonpayLimits({
|
|
3448
|
+
currencyCode: selectedToken?.moonpayCurrencyCode,
|
|
3449
|
+
apiBaseUrl: networkConfig.moonpayApiUrl,
|
|
3450
|
+
enabled: isCreditCard
|
|
3451
|
+
});
|
|
3452
|
+
const hasValidAmount = !!amount && parseFloat(amount) > 0;
|
|
3453
|
+
const maxAmountDecimals = isCreditCard ? 2 : selectedToken?.decimals;
|
|
3454
|
+
const tooManyDecimals = hasValidAmount && maxAmountDecimals != null && amount.includes(".") && amount.split(".")[1].length > maxAmountDecimals;
|
|
3455
|
+
const exceedsBalance = isConnectedSource && hasValidAmount && !tooManyDecimals && !!selectedToken && walletBalance != null && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
|
|
3456
|
+
const belowMoonpayMin = isCreditCard && hasValidAmount && moonpayMinBuy != null && parseFloat(amount) < moonpayMinBuy;
|
|
3457
|
+
const moonpayLimitsUnready = isCreditCard && !!selectedToken?.moonpayCurrencyCode && moonpayMinBuy == null;
|
|
3458
|
+
const creditCardUnavailable = isCreditCard && !!selectedToken && !selectedToken.moonpayCurrencyCode;
|
|
3459
|
+
const needsConnect = isConnectedSource && !isConnected;
|
|
3460
|
+
const canDeposit = hasValidAmount && !!selectedToken && !tooManyDecimals && !exceedsBalance && !belowMoonpayMin && !moonpayLimitsUnready && !creditCardUnavailable && !needsConnect;
|
|
3461
|
+
const handleMax = () => {
|
|
3462
|
+
const max = formattedWalletBalance.replace(/\s/g, "");
|
|
3463
|
+
if (parseFloat(max) > 0) onAmountChange(max);
|
|
3464
|
+
};
|
|
3465
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
3466
|
+
isCreditCard ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
3467
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Buy with credit card and deposit" }),
|
|
3468
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Enter your deposit amount and proceed to sign a policy." })
|
|
3469
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: [
|
|
3470
|
+
"Deposit from ",
|
|
3471
|
+
sourceLabel
|
|
3472
|
+
] }),
|
|
3473
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3474
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-muted-foreground text-sm", children: "Token" }),
|
|
3475
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3476
|
+
"button",
|
|
3477
|
+
{
|
|
3478
|
+
type: "button",
|
|
3479
|
+
onClick: onSelectToken,
|
|
3480
|
+
className: "border-border bg-input flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left",
|
|
3481
|
+
children: [
|
|
3482
|
+
selectedToken ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3483
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 shrink-0 overflow-hidden rounded-full", children: getTokenIcon(selectedToken.symbol, 32) }),
|
|
3484
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col items-start gap-1", children: [
|
|
3485
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm font-medium", children: selectedToken.symbol }),
|
|
3486
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
|
|
3487
|
+
"on ",
|
|
3488
|
+
chain?.name ?? "\u2014"
|
|
3489
|
+
] })
|
|
3490
|
+
] })
|
|
3491
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground flex-1 text-sm", children: "Select token" }),
|
|
3492
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-5 w-5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {}) })
|
|
3493
|
+
]
|
|
3494
|
+
}
|
|
3495
|
+
)
|
|
3496
|
+
] }),
|
|
3497
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3498
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3499
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-muted-foreground text-sm", children: "Amount" }),
|
|
3500
|
+
isConnectedSource && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-sm", children: [
|
|
3501
|
+
"Available ",
|
|
3502
|
+
formattedWalletBalance,
|
|
3503
|
+
" ",
|
|
3504
|
+
selectedToken?.symbol
|
|
3505
|
+
] })
|
|
3506
|
+
] }),
|
|
3507
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3508
|
+
"div",
|
|
3509
|
+
{
|
|
3510
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3511
|
+
"border-border bg-input flex items-center gap-2 rounded-[10px] border",
|
|
3512
|
+
isConnectedSource ? "py-1 pr-1 pl-3" : "px-3 py-3"
|
|
3513
|
+
),
|
|
3514
|
+
children: [
|
|
3515
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3516
|
+
"input",
|
|
3517
|
+
{
|
|
3518
|
+
type: "text",
|
|
3519
|
+
inputMode: "decimal",
|
|
3520
|
+
placeholder: "Enter Amount",
|
|
3521
|
+
value: amount,
|
|
3522
|
+
onChange: (e) => {
|
|
3523
|
+
const value = e.target.value.replace(/[^0-9.,]/g, "").replace(/,/g, ".");
|
|
3524
|
+
if (value.split(".").length <= 2) onAmountChange(value);
|
|
3525
|
+
},
|
|
3526
|
+
className: "text-foreground placeholder:text-muted-foreground/50 flex-1 bg-transparent text-sm outline-none"
|
|
3527
|
+
}
|
|
3528
|
+
),
|
|
3529
|
+
isConnectedSource ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3530
|
+
"button",
|
|
3531
|
+
{
|
|
3532
|
+
type: "button",
|
|
3533
|
+
onClick: handleMax,
|
|
3534
|
+
className: "bg-secondary text-foreground hover:bg-secondary/80 cursor-pointer rounded px-3 py-2.5 text-xs font-semibold transition-colors",
|
|
3535
|
+
children: "MAX"
|
|
3536
|
+
}
|
|
3537
|
+
) : isCreditCard ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: selectedToken?.symbol ?? "USD" }) : selectedToken && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: selectedToken.symbol })
|
|
3538
|
+
]
|
|
3539
|
+
}
|
|
3540
|
+
),
|
|
3541
|
+
tooManyDecimals && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
|
|
3542
|
+
"Too many decimal places (max: ",
|
|
3543
|
+
maxAmountDecimals,
|
|
3544
|
+
")"
|
|
3545
|
+
] }),
|
|
3546
|
+
exceedsBalance && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Insufficient balance" }),
|
|
3547
|
+
belowMoonpayMin && moonpayMinBuy != null && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
|
|
3548
|
+
"Minimum purchase is $",
|
|
3549
|
+
moonpayMinBuy,
|
|
3550
|
+
" USD."
|
|
3551
|
+
] }),
|
|
3552
|
+
isCreditCard && moonpayLimitsError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load purchase limits. Please try again." }),
|
|
3553
|
+
isCreditCard && moonpayLimitsLoading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Checking purchase limits\u2026" }),
|
|
3554
|
+
creditCardUnavailable && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
|
|
3555
|
+
selectedToken?.symbol ?? "This token",
|
|
3556
|
+
" isn\u2019t available for card purchases yet."
|
|
3557
|
+
] })
|
|
3558
|
+
] }),
|
|
3559
|
+
allowance && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3560
|
+
AllowancePolicySection,
|
|
3561
|
+
{
|
|
3562
|
+
allowance,
|
|
3563
|
+
serviceName: appName,
|
|
3564
|
+
serviceIcon
|
|
3565
|
+
}
|
|
3566
|
+
),
|
|
3567
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3568
|
+
"button",
|
|
3569
|
+
{
|
|
3570
|
+
type: "button",
|
|
3571
|
+
disabled: needsConnect ? !onConnectWallet : !canDeposit || isSubmitting,
|
|
3572
|
+
onClick: () => {
|
|
3573
|
+
if (needsConnect) {
|
|
3574
|
+
onConnectWallet?.();
|
|
3575
|
+
return;
|
|
3576
|
+
}
|
|
3577
|
+
if (selectedToken) onSubmit({ source, tokenId: selectedToken.id, amount });
|
|
3578
|
+
},
|
|
3579
|
+
className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
3580
|
+
children: needsConnect ? "Connect Wallet" : allowance ? "Sign Policy and Deposit" : "Deposit"
|
|
3581
|
+
}
|
|
3582
|
+
)
|
|
3583
|
+
] });
|
|
3584
|
+
}
|
|
3585
|
+
function SummaryRow({ value, label }) {
|
|
3586
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-sm leading-5", children: [
|
|
3587
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: value }),
|
|
3588
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label })
|
|
3589
|
+
] });
|
|
3590
|
+
}
|
|
3591
|
+
var LISTENING_WINDOW_MS = 36e5;
|
|
3592
|
+
function remainingSeconds(deadline) {
|
|
3593
|
+
return Math.max(0, Math.round((deadline - Date.now()) / 1e3));
|
|
3594
|
+
}
|
|
3595
|
+
function useCountdown(deadline) {
|
|
3596
|
+
const [secondsLeft, setSecondsLeft] = react.useState(() => remainingSeconds(deadline));
|
|
3597
|
+
react.useEffect(() => {
|
|
3598
|
+
if (remainingSeconds(deadline) <= 0) return;
|
|
3599
|
+
const id = setInterval(() => {
|
|
3600
|
+
const left = remainingSeconds(deadline);
|
|
3601
|
+
setSecondsLeft(left);
|
|
3602
|
+
if (left <= 0) clearInterval(id);
|
|
3603
|
+
}, 1e3);
|
|
3604
|
+
return () => clearInterval(id);
|
|
3605
|
+
}, [deadline]);
|
|
3606
|
+
return secondsLeft;
|
|
3607
|
+
}
|
|
3608
|
+
function AwaitingDepositStatus({
|
|
3609
|
+
title,
|
|
3610
|
+
subtitle,
|
|
3611
|
+
remaining
|
|
3612
|
+
}) {
|
|
3613
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
3614
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }) }),
|
|
3615
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
3616
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-foreground text-xl leading-6 font-medium", children: title }),
|
|
3617
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground text-sm leading-[18px]", children: [
|
|
3618
|
+
subtitle,
|
|
3619
|
+
remaining && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3620
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
3621
|
+
"Remaining time: ",
|
|
3622
|
+
remaining
|
|
3623
|
+
] })
|
|
3624
|
+
] })
|
|
3625
|
+
] })
|
|
3626
|
+
] });
|
|
3627
|
+
}
|
|
3628
|
+
function ExternalDepositView({
|
|
3629
|
+
token,
|
|
3630
|
+
amount,
|
|
3631
|
+
onCredited
|
|
3632
|
+
}) {
|
|
3633
|
+
const { getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
3634
|
+
const { depositAddress, isReady, isLoading } = useDepositAddress();
|
|
3635
|
+
const chain = token ? getChainById2(token.chainId) : void 0;
|
|
3636
|
+
const [copied, setCopied] = react.useState(false);
|
|
3637
|
+
const [deadline] = react.useState(() => Date.now() + LISTENING_WINDOW_MS);
|
|
3638
|
+
const secondsLeft = useCountdown(deadline);
|
|
3639
|
+
const listening = secondsLeft > 0;
|
|
3640
|
+
const [nothingFound, setNothingFound] = react.useState(false);
|
|
3641
|
+
const [credited, setCredited] = react.useState(null);
|
|
3642
|
+
const verification = chunk4IW4V7YJ_cjs.useDepositVerification({
|
|
3643
|
+
onCredited: (txHash) => {
|
|
3644
|
+
if (onCredited) {
|
|
3645
|
+
onCredited();
|
|
3646
|
+
return;
|
|
3647
|
+
}
|
|
3648
|
+
setCredited({ txHash });
|
|
3649
|
+
}
|
|
3650
|
+
});
|
|
3651
|
+
const { isVerifying, verificationFailed, didTimeout, verify } = verification;
|
|
3652
|
+
const scanPaused = isVerifying || verificationFailed || didTimeout || !!credited;
|
|
3653
|
+
const {
|
|
3654
|
+
pending,
|
|
3655
|
+
isFetching: isScanning,
|
|
3656
|
+
isError: isScanError,
|
|
3657
|
+
isRateLimited,
|
|
3658
|
+
isUnavailable,
|
|
3659
|
+
refetch: refetchPendingDeposits
|
|
3660
|
+
} = usePendingDeposits({
|
|
3661
|
+
chainId: token?.chainId,
|
|
3662
|
+
enabled: isReady && !!depositAddress && !!token,
|
|
3663
|
+
refetchInterval: listening && !scanPaused ? 3e4 : false
|
|
3664
|
+
});
|
|
3665
|
+
const processedRef = react.useRef(/* @__PURE__ */ new Set());
|
|
3666
|
+
react.useEffect(() => {
|
|
3667
|
+
if (scanPaused) return;
|
|
3668
|
+
const next = [...pending].sort((a, b) => a.block_number - b.block_number).find((d) => !processedRef.current.has(`${d.tx_hash}:${d.log_index}`));
|
|
3669
|
+
if (!next) return;
|
|
3670
|
+
processedRef.current.add(`${next.tx_hash}:${next.log_index}`);
|
|
3671
|
+
void verify({
|
|
3672
|
+
hash: next.tx_hash,
|
|
3673
|
+
chainId: next.chain_id,
|
|
3674
|
+
amount: BigInt(next.amount),
|
|
3675
|
+
logIndex: next.log_index
|
|
3676
|
+
});
|
|
3677
|
+
}, [pending, scanPaused, verify]);
|
|
3678
|
+
const nothingFoundTimerRef = react.useRef(void 0);
|
|
3679
|
+
react.useEffect(() => () => clearTimeout(nothingFoundTimerRef.current), []);
|
|
3680
|
+
const handleRefresh = () => {
|
|
3681
|
+
processedRef.current.clear();
|
|
3682
|
+
void refetchPendingDeposits().then((result) => {
|
|
3683
|
+
if (!result || result.pending.length === 0) {
|
|
3684
|
+
setNothingFound(true);
|
|
3685
|
+
clearTimeout(nothingFoundTimerRef.current);
|
|
3686
|
+
nothingFoundTimerRef.current = setTimeout(() => setNothingFound(false), 4e3);
|
|
3687
|
+
}
|
|
3688
|
+
});
|
|
3689
|
+
};
|
|
3690
|
+
const handleCopy = () => {
|
|
3691
|
+
if (!depositAddress) return;
|
|
3692
|
+
void navigator.clipboard.writeText(depositAddress);
|
|
3693
|
+
setCopied(true);
|
|
3694
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
3695
|
+
};
|
|
3696
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
3697
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
3698
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Deposit from an External Wallet" }),
|
|
3699
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Transfer crypto from external wallet or exchange." })
|
|
3700
|
+
] }),
|
|
3701
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
3702
|
+
/* @__PURE__ */ jsxRuntime.jsx(SummaryRow, { value: chain?.name ?? "\u2014", label: "Chain" }),
|
|
3703
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-border h-px w-full" }),
|
|
3704
|
+
/* @__PURE__ */ jsxRuntime.jsx(SummaryRow, { value: token?.symbol ?? "\u2014", label: "Currency" }),
|
|
3705
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-border h-px w-full" }),
|
|
3706
|
+
/* @__PURE__ */ jsxRuntime.jsx(SummaryRow, { value: amount || "\u2014", label: "Value" })
|
|
3707
|
+
] }),
|
|
3708
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-secondary flex h-50 items-center justify-center rounded-[10px]", children: !isReady ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground px-6 text-center text-sm", children: "Connect your wallet to generate a deposit address." }) : depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-[10px] bg-white p-3", children: /* @__PURE__ */ jsxRuntime.jsx(qrcode_react.QRCodeSVG, { value: depositAddress, size: 160 }) }) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-full w-full rounded-[10px]" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "Deposit address unavailable" }) }),
|
|
3709
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3710
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Deposit Address" }),
|
|
3711
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
3712
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-border flex h-10 min-w-0 flex-1 items-center rounded-[10px] border px-3", children: depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: depositAddress }) : isReady && isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-4 w-3/4" }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "\u2014" }) }),
|
|
3713
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3714
|
+
"button",
|
|
3715
|
+
{
|
|
3716
|
+
type: "button",
|
|
3717
|
+
onClick: handleCopy,
|
|
3718
|
+
disabled: !depositAddress,
|
|
3719
|
+
className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 shrink-0 cursor-pointer items-center gap-2 rounded-[10px] px-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
3720
|
+
children: [
|
|
3721
|
+
/* @__PURE__ */ jsxRuntime.jsx(CopyIcon, {}),
|
|
3722
|
+
copied ? "Copied" : "Copy"
|
|
3723
|
+
]
|
|
3724
|
+
}
|
|
3725
|
+
)
|
|
3726
|
+
] })
|
|
3727
|
+
] }),
|
|
3728
|
+
credited ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3729
|
+
TransactionSuccessView,
|
|
3730
|
+
{
|
|
3731
|
+
title: "Deposit Credited",
|
|
3732
|
+
message: `Transfer ${chunk4IW4V7YJ_cjs.shortenAddress(credited.txHash)} has been credited to your Privana balance.`,
|
|
3733
|
+
onDone: () => {
|
|
3734
|
+
setCredited(null);
|
|
3735
|
+
verification.reset();
|
|
3736
|
+
void refetchPendingDeposits();
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
) : verificationFailed || didTimeout ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3740
|
+
TransactionErrorView,
|
|
3741
|
+
{
|
|
3742
|
+
title: "Could not verify deposit",
|
|
3743
|
+
message: didTimeout ? "Verification timed out \u2014 your deposit may still be credited in the background." : verification.error?.message ?? "Your transfer was found but could not be verified.",
|
|
3744
|
+
onRetry: () => void verification.retryVerification(),
|
|
3745
|
+
onDismiss: () => verification.reset(),
|
|
3746
|
+
isRetrying: isVerifying
|
|
3747
|
+
}
|
|
3748
|
+
) : isVerifying ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3749
|
+
AwaitingDepositStatus,
|
|
3750
|
+
{
|
|
3751
|
+
title: "Deposit detected",
|
|
3752
|
+
subtitle: "Crediting the incoming transaction to your Privana balance..."
|
|
3753
|
+
}
|
|
3754
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3755
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3756
|
+
AwaitingDepositStatus,
|
|
3757
|
+
{
|
|
3758
|
+
title: "Awaiting Deposit",
|
|
3759
|
+
subtitle: listening ? "We are listening for your incoming transaction for the next hour." : "We've stopped listening automatically. Use the button below to check for your deposit.",
|
|
3760
|
+
remaining: listening ? chunk4IW4V7YJ_cjs.formatCountdown(secondsLeft) : void 0
|
|
3761
|
+
}
|
|
3762
|
+
),
|
|
3763
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3764
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3765
|
+
"button",
|
|
3766
|
+
{
|
|
3767
|
+
type: "button",
|
|
3768
|
+
onClick: handleRefresh,
|
|
3769
|
+
disabled: !depositAddress || isScanning,
|
|
3770
|
+
className: "bg-secondary text-foreground hover:bg-secondary/80 flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
3771
|
+
children: "Refresh deposit status"
|
|
3772
|
+
}
|
|
3773
|
+
),
|
|
3774
|
+
isRateLimited ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Checked too recently \u2014 try again in a moment." }) : isUnavailable ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Deposit discovery is unavailable for this chain." }) : isScanError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Chain temporarily unreachable \u2014 retrying automatically." }) : nothingFound ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "No incoming transaction found yet." }) : null
|
|
3775
|
+
] })
|
|
3776
|
+
] })
|
|
3777
|
+
] });
|
|
3778
|
+
}
|
|
3779
|
+
function DepositModalContent({
|
|
3780
|
+
defaultTab = "crypto",
|
|
3781
|
+
allowance,
|
|
3782
|
+
onSelectConnectedWallet,
|
|
3783
|
+
onSelectExternalWallet,
|
|
3784
|
+
onSelectCreditCard,
|
|
3785
|
+
onConnectWallet,
|
|
3786
|
+
onDeposit,
|
|
3787
|
+
onDepositSuccess,
|
|
3788
|
+
onLockFailed,
|
|
3789
|
+
onClose,
|
|
3790
|
+
onCloseBlockedChange,
|
|
3791
|
+
onExit
|
|
3792
|
+
}) {
|
|
3793
|
+
const { serviceName, enabledTokens, defaultToken, hostedAuthConfig, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
3794
|
+
const { address } = wagmi.useAccount();
|
|
3795
|
+
const appName = serviceName ?? "Privana";
|
|
3796
|
+
const [activeTab, setActiveTab] = react.useState(defaultTab);
|
|
3797
|
+
const [view, setView] = react.useState("method");
|
|
3798
|
+
const [source, setSource] = react.useState("connected");
|
|
3799
|
+
const [selectedTokenId, setSelectedTokenId] = react.useState(defaultToken?.id ?? "");
|
|
3800
|
+
const [amount, setAmount] = react.useState("");
|
|
3801
|
+
const selectedToken = enabledTokens.find((t) => t.id === selectedTokenId) ?? defaultToken;
|
|
3802
|
+
const prevAddressRef = react.useRef(address);
|
|
3803
|
+
react.useEffect(() => {
|
|
3804
|
+
const prev = prevAddressRef.current;
|
|
3805
|
+
prevAddressRef.current = address;
|
|
3806
|
+
if (hostedAuthConfig) return;
|
|
3807
|
+
if (prev && address && prev !== address) {
|
|
3808
|
+
setView("method");
|
|
3809
|
+
setAmount("");
|
|
3810
|
+
setSelectedTokenId("");
|
|
3811
|
+
}
|
|
3812
|
+
}, [address, hostedAuthConfig]);
|
|
3813
|
+
const openDeposit = (next) => {
|
|
3814
|
+
setSource(next);
|
|
3815
|
+
setView("deposit");
|
|
3816
|
+
};
|
|
3817
|
+
const [showSuccess, setShowSuccess] = react.useState(false);
|
|
3818
|
+
const [showTimeout, setShowTimeout] = react.useState(false);
|
|
3819
|
+
const [cancelled, setCancelled] = react.useState(false);
|
|
3820
|
+
const [isSubmittingLock, setIsSubmittingLock] = react.useState(false);
|
|
3821
|
+
const [lockFailedMessage, setLockFailedMessage] = react.useState(null);
|
|
3822
|
+
const finishDeposit = () => {
|
|
3823
|
+
setAmount("");
|
|
3824
|
+
if (onDepositSuccess) {
|
|
3825
|
+
resetDeposit();
|
|
3826
|
+
onDepositSuccess();
|
|
3827
|
+
} else {
|
|
3828
|
+
setShowSuccess(true);
|
|
3829
|
+
}
|
|
3830
|
+
};
|
|
3831
|
+
const finishCardPurchase = () => {
|
|
3832
|
+
setAmount("");
|
|
3833
|
+
onDepositSuccess?.();
|
|
3834
|
+
};
|
|
3835
|
+
const {
|
|
3836
|
+
txHash,
|
|
3837
|
+
isGettingAddress,
|
|
3838
|
+
isSwitchingChain,
|
|
3839
|
+
isSendingTransaction,
|
|
3840
|
+
isWaitingForConfirmation,
|
|
3841
|
+
isWaitingForProcessing,
|
|
3842
|
+
verificationFailed,
|
|
3843
|
+
isPending,
|
|
3844
|
+
error: depositError,
|
|
3845
|
+
deposit,
|
|
3846
|
+
retryVerification,
|
|
3847
|
+
reset: resetDeposit
|
|
3848
|
+
} = useDeposit({
|
|
3849
|
+
onCredited: (_txHash, _response, lockPending) => {
|
|
3850
|
+
if (lockPending) {
|
|
3851
|
+
setIsSubmittingLock(true);
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
finishDeposit();
|
|
3855
|
+
},
|
|
3856
|
+
onLockSubmitted: () => {
|
|
3857
|
+
setIsSubmittingLock(false);
|
|
3858
|
+
finishDeposit();
|
|
3859
|
+
},
|
|
3860
|
+
// The deposit credited; only the policy lock failed. Success must not
|
|
3861
|
+
// fire (the host would act on unlocked funds) — show the dedicated
|
|
3862
|
+
// error view and let the host re-prompt for a fresh lock.
|
|
3863
|
+
onLockFailed: (err) => {
|
|
3864
|
+
setIsSubmittingLock(false);
|
|
3865
|
+
setLockFailedMessage(err.message);
|
|
3866
|
+
onLockFailed?.(err);
|
|
3867
|
+
},
|
|
3868
|
+
onCheckTimeout: () => {
|
|
3869
|
+
setAmount("");
|
|
3870
|
+
setShowTimeout(true);
|
|
3871
|
+
}
|
|
3872
|
+
});
|
|
3873
|
+
const isUnsafeToClose = (isGettingAddress || isSendingTransaction) && !cancelled;
|
|
3874
|
+
react.useEffect(() => {
|
|
3875
|
+
onCloseBlockedChange?.(isUnsafeToClose);
|
|
3876
|
+
}, [isUnsafeToClose, onCloseBlockedChange]);
|
|
3877
|
+
react.useEffect(() => {
|
|
3878
|
+
if (depositError && !verificationFailed) {
|
|
3879
|
+
sonner.toast.error(
|
|
3880
|
+
depositError.message.length > 100 ? `${depositError.message.slice(0, 100)}...` : depositError.message
|
|
3881
|
+
);
|
|
3882
|
+
}
|
|
3883
|
+
}, [depositError, verificationFailed]);
|
|
3884
|
+
const handleSubmit = (args) => {
|
|
3885
|
+
if (args.source === "external") {
|
|
3886
|
+
setView("external-deposit");
|
|
3887
|
+
return;
|
|
3888
|
+
}
|
|
3889
|
+
if (args.source === "credit-card") {
|
|
3890
|
+
setView("credit-card-widget");
|
|
3891
|
+
return;
|
|
3892
|
+
}
|
|
3893
|
+
const token = enabledTokens.find((t) => t.id === args.tokenId);
|
|
3894
|
+
if (!token) return;
|
|
3895
|
+
onDeposit?.(args);
|
|
3896
|
+
setCancelled(false);
|
|
3897
|
+
deposit({
|
|
3898
|
+
tokenId: token.id,
|
|
3899
|
+
amount: chunk4IW4V7YJ_cjs.parseTokenAmount(args.amount, token.decimals),
|
|
3900
|
+
postDepositLock: allowance ? {
|
|
3901
|
+
maxAmount: BigInt(allowance.value),
|
|
3902
|
+
lockDuration: allowance.lockDuration
|
|
3903
|
+
} : void 0
|
|
3904
|
+
}).catch((err) => {
|
|
3905
|
+
sonner.toast.error(err instanceof Error ? err.message : "Deposit failed");
|
|
3906
|
+
});
|
|
3907
|
+
};
|
|
3908
|
+
const targetChain = selectedToken ? getChainById2(selectedToken.chainId) : void 0;
|
|
3909
|
+
const explorerTxUrl = txHash && targetChain?.explorerUrl ? `${targetChain.explorerUrl}/tx/${txHash}` : void 0;
|
|
3910
|
+
const depositSteps = [
|
|
3911
|
+
{
|
|
3912
|
+
label: "Getting deposit address",
|
|
3913
|
+
status: isGettingAddress ? "active" : isSwitchingChain || isSendingTransaction || isWaitingForConfirmation || isWaitingForProcessing || isSubmittingLock ? "completed" : "pending"
|
|
3914
|
+
},
|
|
3915
|
+
{
|
|
3916
|
+
label: `Switching to ${targetChain?.name ?? "deposit chain"}`,
|
|
3917
|
+
status: isSwitchingChain ? "active" : isSendingTransaction || isWaitingForConfirmation || isWaitingForProcessing || isSubmittingLock ? "completed" : "pending"
|
|
3918
|
+
},
|
|
3919
|
+
{
|
|
3920
|
+
label: "Confirm in wallet",
|
|
3921
|
+
status: isSendingTransaction ? "active" : isWaitingForConfirmation || isWaitingForProcessing || isSubmittingLock ? "completed" : "pending"
|
|
3922
|
+
},
|
|
3923
|
+
{
|
|
3924
|
+
label: "Confirming transaction",
|
|
3925
|
+
status: isWaitingForConfirmation ? "active" : isWaitingForProcessing || isSubmittingLock ? "completed" : "pending"
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
label: "Verifying deposit \u2014 may take up to a few minutes",
|
|
3929
|
+
status: isWaitingForProcessing ? "active" : isSubmittingLock ? "completed" : "pending"
|
|
3930
|
+
},
|
|
3931
|
+
...allowance ? [
|
|
3932
|
+
{
|
|
3933
|
+
label: `Locking funds for ${appName}`,
|
|
3934
|
+
status: isSubmittingLock ? "active" : "pending"
|
|
3935
|
+
}
|
|
3936
|
+
] : []
|
|
3937
|
+
];
|
|
3938
|
+
const flowView = showSuccess ? "deposit-success" : lockFailedMessage ? "lock-error" : showTimeout ? "deposit-timeout" : verificationFailed ? "deposit-error" : isPending && !cancelled || isSubmittingLock ? "depositing" : null;
|
|
3939
|
+
const activeView = flowView ?? view;
|
|
3940
|
+
const handleDepositDone = () => {
|
|
3941
|
+
setShowSuccess(false);
|
|
3942
|
+
setShowTimeout(false);
|
|
3943
|
+
setCancelled(false);
|
|
3944
|
+
resetDeposit();
|
|
3945
|
+
};
|
|
3946
|
+
const handleDepositCancel = () => {
|
|
3947
|
+
setCancelled(true);
|
|
3948
|
+
resetDeposit();
|
|
3949
|
+
};
|
|
3950
|
+
const handleLockFailedDone = () => {
|
|
3951
|
+
setLockFailedMessage(null);
|
|
3952
|
+
setAmount("");
|
|
3953
|
+
setCancelled(false);
|
|
3954
|
+
resetDeposit();
|
|
3955
|
+
};
|
|
3956
|
+
const handleDismissVerificationError = () => {
|
|
3957
|
+
setAmount("");
|
|
3958
|
+
setCancelled(false);
|
|
3959
|
+
resetDeposit();
|
|
3960
|
+
};
|
|
3961
|
+
const handleRetryVerification = () => {
|
|
3962
|
+
retryVerification().catch(() => {
|
|
3963
|
+
});
|
|
3964
|
+
};
|
|
3965
|
+
const back = view === "external-deposit" ? { to: "deposit", label: "Deposit from External Wallet" } : view === "credit-card-widget" ? { to: "deposit", label: "Buy with credit card and deposit" } : view === "select-token" ? { to: "deposit", label: "Deposit" } : { to: "method", label: "Deposit Method" };
|
|
3966
|
+
const goBack = () => {
|
|
3967
|
+
if (back.to === "method") {
|
|
3968
|
+
setAmount("");
|
|
3969
|
+
setSelectedTokenId("");
|
|
3970
|
+
}
|
|
3971
|
+
setView(back.to);
|
|
3972
|
+
};
|
|
3973
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3974
|
+
onClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3975
|
+
"button",
|
|
3976
|
+
{
|
|
3977
|
+
"data-privana-close": true,
|
|
3978
|
+
onClick: onClose,
|
|
3979
|
+
disabled: isUnsafeToClose,
|
|
3980
|
+
"aria-label": "Close",
|
|
3981
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
3982
|
+
"absolute top-6 right-5 z-20 flex h-5 w-5 items-center justify-center transition-colors",
|
|
3983
|
+
isUnsafeToClose ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
|
|
3984
|
+
),
|
|
3985
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
|
|
3986
|
+
}
|
|
3987
|
+
),
|
|
3988
|
+
flowView || activeView === "method" && !onExit ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-5 font-medium", children: appName }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3989
|
+
"button",
|
|
3990
|
+
{
|
|
3991
|
+
type: "button",
|
|
3992
|
+
onClick: activeView === "method" ? onExit : goBack,
|
|
3993
|
+
className: "text-foreground flex w-fit cursor-pointer items-center gap-2 px-5 py-4 text-sm font-medium transition-opacity hover:opacity-70",
|
|
3994
|
+
children: [
|
|
3995
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
|
|
3996
|
+
activeView === "method" ? appName : back.label
|
|
3997
|
+
]
|
|
3998
|
+
}
|
|
3999
|
+
),
|
|
4000
|
+
flowView && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
4001
|
+
activeView === "deposit-success" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4002
|
+
TransactionSuccessView,
|
|
4003
|
+
{
|
|
4004
|
+
title: "Deposit Successful",
|
|
4005
|
+
message: `Your ${selectedToken?.symbol ?? ""} deposit has been processed.`,
|
|
4006
|
+
onDone: handleDepositDone
|
|
4007
|
+
}
|
|
4008
|
+
),
|
|
4009
|
+
activeView === "lock-error" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4010
|
+
TransactionWarningView,
|
|
4011
|
+
{
|
|
4012
|
+
title: "Deposit credited, lock failed",
|
|
4013
|
+
message: `Your deposit was credited but locking the funds for ${appName} failed: ${lockFailedMessage}`,
|
|
4014
|
+
onDone: handleLockFailedDone
|
|
4015
|
+
}
|
|
4016
|
+
),
|
|
4017
|
+
activeView === "deposit-timeout" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4018
|
+
TransactionWarningView,
|
|
4019
|
+
{
|
|
4020
|
+
title: "Deposit Processing",
|
|
4021
|
+
message: "Your transaction was confirmed but the deposit is still being processed. Please check your balance - it should update shortly.",
|
|
4022
|
+
onDone: handleDepositDone
|
|
4023
|
+
}
|
|
4024
|
+
),
|
|
4025
|
+
activeView === "deposit-error" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4026
|
+
TransactionErrorView,
|
|
4027
|
+
{
|
|
4028
|
+
title: "Verification failed",
|
|
4029
|
+
message: depositError?.message ? `Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address \u2014 retry verification instead of starting a new deposit. (${depositError.message})` : "Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address \u2014 retry verification instead of starting a new deposit.",
|
|
4030
|
+
explorerUrl: explorerTxUrl,
|
|
4031
|
+
explorerLabel: "View transaction",
|
|
4032
|
+
onRetry: handleRetryVerification,
|
|
4033
|
+
onDismiss: handleDismissVerificationError
|
|
4034
|
+
}
|
|
4035
|
+
),
|
|
4036
|
+
activeView === "depositing" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4037
|
+
TransactionProgressView,
|
|
4038
|
+
{
|
|
4039
|
+
title: "Depositing...",
|
|
4040
|
+
steps: depositSteps,
|
|
4041
|
+
onCancel: isGettingAddress || isSendingTransaction ? handleDepositCancel : void 0
|
|
4042
|
+
}
|
|
4043
|
+
)
|
|
4044
|
+
] }),
|
|
4045
|
+
activeView === "method" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
4046
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
4047
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: activeTab === "crypto" ? "Choose the deposit method" : "Buy with credit card and deposit" }),
|
|
4048
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: activeTab === "crypto" ? "Choose the deposit method." : "Use credit card to buy crypto and deposit" })
|
|
4049
|
+
] }),
|
|
4050
|
+
/* @__PURE__ */ jsxRuntime.jsx(MethodTabs, { activeTab, onTabChange: setActiveTab }),
|
|
4051
|
+
activeTab === "crypto" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4052
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4053
|
+
MethodOption,
|
|
4054
|
+
{
|
|
4055
|
+
title: "Connected wallet",
|
|
4056
|
+
description: "Deposit from your connected wallet.",
|
|
4057
|
+
onClick: () => {
|
|
4058
|
+
onSelectConnectedWallet?.();
|
|
4059
|
+
openDeposit("connected");
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
),
|
|
4063
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4064
|
+
MethodOption,
|
|
4065
|
+
{
|
|
4066
|
+
title: "External Wallet",
|
|
4067
|
+
description: "Send funds from external wallet or exchange.",
|
|
4068
|
+
onClick: () => {
|
|
4069
|
+
onSelectExternalWallet?.();
|
|
4070
|
+
openDeposit("external");
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4073
|
+
)
|
|
4074
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4075
|
+
MethodOption,
|
|
4076
|
+
{
|
|
4077
|
+
title: "Moonpay",
|
|
4078
|
+
description: "on selected address",
|
|
4079
|
+
onClick: () => {
|
|
4080
|
+
onSelectCreditCard?.();
|
|
4081
|
+
openDeposit("credit-card");
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
) })
|
|
4085
|
+
] }),
|
|
4086
|
+
activeView === "deposit" && /* @__PURE__ */ jsxRuntime.jsx(MoonPayGate, { enabled: source === "credit-card", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4087
|
+
DepositView,
|
|
4088
|
+
{
|
|
4089
|
+
source,
|
|
4090
|
+
selectedToken,
|
|
4091
|
+
amount,
|
|
4092
|
+
allowance,
|
|
4093
|
+
onAmountChange: setAmount,
|
|
4094
|
+
onSelectToken: () => setView("select-token"),
|
|
4095
|
+
onConnectWallet,
|
|
4096
|
+
onSubmit: handleSubmit,
|
|
4097
|
+
isSubmitting: isPending
|
|
4098
|
+
}
|
|
4099
|
+
) }),
|
|
4100
|
+
activeView === "select-token" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4101
|
+
TokenSelectorView2,
|
|
4102
|
+
{
|
|
4103
|
+
selectedTokenId: selectedToken?.id,
|
|
4104
|
+
onSelect: (id) => {
|
|
4105
|
+
setSelectedTokenId(id);
|
|
4106
|
+
setView("deposit");
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
),
|
|
4110
|
+
activeView === "external-deposit" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4111
|
+
ExternalDepositView,
|
|
4112
|
+
{
|
|
4113
|
+
token: selectedToken,
|
|
4114
|
+
amount,
|
|
4115
|
+
onCredited: allowance ? void 0 : onDepositSuccess
|
|
4116
|
+
}
|
|
4117
|
+
),
|
|
4118
|
+
activeView === "credit-card-widget" && /* @__PURE__ */ jsxRuntime.jsx(MoonPayGate, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4119
|
+
CreditCardWidgetView,
|
|
4120
|
+
{
|
|
4121
|
+
token: selectedToken,
|
|
4122
|
+
amount,
|
|
4123
|
+
allowance,
|
|
4124
|
+
onCredited: allowance ? void 0 : finishCardPurchase,
|
|
4125
|
+
onLockSubmitted: finishCardPurchase,
|
|
4126
|
+
onLockFailed: (err) => {
|
|
4127
|
+
setLockFailedMessage(err.message);
|
|
4128
|
+
onLockFailed?.(err);
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
) })
|
|
4132
|
+
] });
|
|
4133
|
+
}
|
|
4134
|
+
function DepositModal({ open, onClose, ...handlers }) {
|
|
4135
|
+
const titleId = react.useId();
|
|
4136
|
+
const descId = react.useId();
|
|
4137
|
+
const [isCloseBlocked, setIsCloseBlocked] = react.useState(false);
|
|
4138
|
+
const handleClose = () => {
|
|
4139
|
+
if (!isCloseBlocked) onClose();
|
|
4140
|
+
};
|
|
4141
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4142
|
+
Dialog,
|
|
4143
|
+
{
|
|
4144
|
+
open,
|
|
4145
|
+
onOpenChange: (isOpen) => {
|
|
4146
|
+
if (!isOpen) handleClose();
|
|
4147
|
+
},
|
|
4148
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4149
|
+
DialogContent,
|
|
4150
|
+
{
|
|
4151
|
+
"data-privana": true,
|
|
4152
|
+
showCloseButton: false,
|
|
4153
|
+
onInteractOutside: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4154
|
+
onEscapeKeyDown: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4155
|
+
className: "bg-card flex w-[560px] max-w-[95vw] flex-col gap-2 rounded-2xl border-0 p-2",
|
|
4156
|
+
"aria-labelledby": titleId,
|
|
4157
|
+
"aria-describedby": descId,
|
|
4158
|
+
children: [
|
|
4159
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { id: titleId, className: "sr-only", children: "Deposit" }),
|
|
4160
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { id: descId, className: "sr-only", children: "Deposit funds into your account." }),
|
|
4161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4162
|
+
DepositModalContent,
|
|
4163
|
+
{
|
|
4164
|
+
onClose: handleClose,
|
|
4165
|
+
onCloseBlockedChange: setIsCloseBlocked,
|
|
4166
|
+
...handlers
|
|
4167
|
+
}
|
|
4168
|
+
)
|
|
4169
|
+
]
|
|
4170
|
+
}
|
|
4171
|
+
)
|
|
4172
|
+
}
|
|
4173
|
+
);
|
|
4174
|
+
}
|
|
4175
|
+
function DepositInlineModal({ className, ...handlers }) {
|
|
4176
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4177
|
+
"div",
|
|
4178
|
+
{
|
|
4179
|
+
"data-privana": true,
|
|
4180
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
4181
|
+
"bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
|
|
4182
|
+
className
|
|
4183
|
+
),
|
|
4184
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DepositModalContent, { ...handlers })
|
|
4185
|
+
}
|
|
4186
|
+
);
|
|
4187
|
+
}
|
|
4188
|
+
function WithdrawView({
|
|
4189
|
+
selectedToken,
|
|
4190
|
+
amount,
|
|
4191
|
+
onAmountChange,
|
|
4192
|
+
onSelectToken,
|
|
4193
|
+
onPendingChange
|
|
4194
|
+
}) {
|
|
4195
|
+
const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
4196
|
+
const { isConnected, address } = wagmi.useAccount();
|
|
4197
|
+
const [showSuccess, setShowSuccess] = react.useState(false);
|
|
4198
|
+
const [showTimeout, setShowTimeout] = react.useState(false);
|
|
4199
|
+
const [cancelled, setCancelled] = react.useState(false);
|
|
4200
|
+
const targetChain = selectedToken ? getChainById2(selectedToken.chainId) ?? chains[0] : chains[0];
|
|
4201
|
+
const {
|
|
4202
|
+
balanceWei,
|
|
4203
|
+
isLoading: isBalanceLoading,
|
|
4204
|
+
isError: isBalanceError
|
|
4205
|
+
} = useBalance({
|
|
4206
|
+
tokenId: selectedToken?.id,
|
|
4207
|
+
enabled: !!selectedToken
|
|
4208
|
+
});
|
|
4209
|
+
const formattedBalance = selectedToken ? chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals) : "0.00";
|
|
4210
|
+
const { withdraw, isPending, currentStep, error, reset } = useWithdraw({
|
|
4211
|
+
onProcessingSuccess: () => {
|
|
4212
|
+
onAmountChange("");
|
|
4213
|
+
setShowSuccess(true);
|
|
4214
|
+
},
|
|
4215
|
+
onProcessingTimeout: () => {
|
|
4216
|
+
onAmountChange("");
|
|
4217
|
+
setShowTimeout(true);
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
const explorerUrl = address && targetChain ? chunk4IW4V7YJ_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
|
|
4221
|
+
const getStepStatus = (step, after) => {
|
|
4222
|
+
if (currentStep === step) return "active";
|
|
4223
|
+
if (after.includes(currentStep)) return "completed";
|
|
4224
|
+
return "pending";
|
|
4225
|
+
};
|
|
4226
|
+
const withdrawSteps = [
|
|
4227
|
+
{
|
|
4228
|
+
label: "Switching to signing chain",
|
|
4229
|
+
status: getStepStatus("switching-chain", ["signing", "submitting", "processing"])
|
|
4230
|
+
},
|
|
4231
|
+
{ label: "Sign in wallet", status: getStepStatus("signing", ["submitting", "processing"]) },
|
|
4232
|
+
{ label: "Submitting withdrawal", status: getStepStatus("submitting", ["processing"]) },
|
|
4233
|
+
{ label: "Processing \u2014 may take a minute or two", status: getStepStatus("processing", []) }
|
|
4234
|
+
];
|
|
4235
|
+
react.useEffect(() => {
|
|
4236
|
+
if (error) {
|
|
4237
|
+
sonner.toast.error(error.message.length > 100 ? `${error.message.slice(0, 100)}...` : error.message);
|
|
4238
|
+
}
|
|
4239
|
+
}, [error]);
|
|
4240
|
+
react.useEffect(() => {
|
|
4241
|
+
onPendingChange?.(isPending && !cancelled);
|
|
4242
|
+
}, [isPending, cancelled, onPendingChange]);
|
|
4243
|
+
const hasValidAmount = !!amount && parseFloat(amount) > 0;
|
|
4244
|
+
const tooManyDecimals = !!hasValidAmount && !!selectedToken && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
|
|
4245
|
+
const exceedsBalance = !!hasValidAmount && !tooManyDecimals && !!selectedToken && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
|
|
4246
|
+
const canWithdraw = isConnected && hasValidAmount && !!selectedToken && !tooManyDecimals && !exceedsBalance;
|
|
4247
|
+
const handleMax = () => {
|
|
4248
|
+
if (!selectedToken) return;
|
|
4249
|
+
const max = formattedBalance.replace(/\s/g, "");
|
|
4250
|
+
if (parseFloat(max) > 0) onAmountChange(max);
|
|
4251
|
+
};
|
|
4252
|
+
const handleWithdraw = async () => {
|
|
4253
|
+
if (!selectedToken || !canWithdraw) return;
|
|
4254
|
+
setCancelled(false);
|
|
4255
|
+
await withdraw({
|
|
4256
|
+
tokenId: selectedToken.id,
|
|
4257
|
+
amount: chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals)
|
|
4258
|
+
});
|
|
4259
|
+
};
|
|
4260
|
+
const handleCancel = () => {
|
|
4261
|
+
setCancelled(true);
|
|
4262
|
+
reset();
|
|
4263
|
+
};
|
|
4264
|
+
const handleDone = () => {
|
|
4265
|
+
setShowSuccess(false);
|
|
4266
|
+
setShowTimeout(false);
|
|
4267
|
+
setCancelled(false);
|
|
4268
|
+
reset();
|
|
4269
|
+
};
|
|
4270
|
+
if (showSuccess && selectedToken) {
|
|
4271
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4272
|
+
TransactionSuccessView,
|
|
4273
|
+
{
|
|
4274
|
+
title: "Withdrawal Complete",
|
|
4275
|
+
message: `Your ${selectedToken.symbol} withdrawal has been processed. Funds should appear in your wallet shortly.`,
|
|
4276
|
+
explorerUrl,
|
|
4277
|
+
explorerLabel: targetChain ? chunk4IW4V7YJ_cjs.getExplorerLabel(targetChain.id) : void 0,
|
|
4278
|
+
onDone: handleDone
|
|
4279
|
+
}
|
|
4280
|
+
) });
|
|
4281
|
+
}
|
|
4282
|
+
if (showTimeout) {
|
|
4283
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4284
|
+
TransactionWarningView,
|
|
4285
|
+
{
|
|
4286
|
+
title: "Withdrawal Processing",
|
|
4287
|
+
message: "Your withdrawal is still being processed. Please check your balance \u2014 it should update shortly.",
|
|
4288
|
+
onDone: handleDone
|
|
4289
|
+
}
|
|
4290
|
+
) });
|
|
4291
|
+
}
|
|
4292
|
+
if (isPending && !cancelled) {
|
|
4293
|
+
const canCancel = currentStep === "idle" || currentStep === "switching-chain" || currentStep === "signing";
|
|
4294
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4295
|
+
TransactionProgressView,
|
|
4296
|
+
{
|
|
4297
|
+
title: "Withdrawing...",
|
|
4298
|
+
steps: withdrawSteps,
|
|
4299
|
+
onCancel: canCancel ? handleCancel : void 0
|
|
4300
|
+
}
|
|
4301
|
+
) });
|
|
4302
|
+
}
|
|
4303
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
4304
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Withdraw" }),
|
|
4305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4306
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-muted-foreground text-sm", children: "Token" }),
|
|
4307
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4308
|
+
"button",
|
|
4309
|
+
{
|
|
4310
|
+
type: "button",
|
|
4311
|
+
onClick: onSelectToken,
|
|
4312
|
+
className: "border-border bg-input flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left",
|
|
4313
|
+
children: [
|
|
4314
|
+
selectedToken ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4315
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 shrink-0 overflow-hidden rounded-full", children: getTokenIcon(selectedToken.symbol, 32) }),
|
|
4316
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col items-start gap-1", children: [
|
|
4317
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm font-medium", children: selectedToken.symbol }),
|
|
4318
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
|
|
4319
|
+
"on ",
|
|
4320
|
+
targetChain?.name ?? "\u2014"
|
|
4321
|
+
] })
|
|
4322
|
+
] })
|
|
4323
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground flex-1 text-sm", children: "Select token" }),
|
|
4324
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground flex h-5 w-5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {}) })
|
|
4325
|
+
]
|
|
4326
|
+
}
|
|
4327
|
+
)
|
|
4328
|
+
] }),
|
|
4329
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4330
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
4331
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-muted-foreground text-sm", children: "Amount" }),
|
|
4332
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-sm", children: [
|
|
4333
|
+
"Available ",
|
|
4334
|
+
formattedBalance,
|
|
4335
|
+
" ",
|
|
4336
|
+
selectedToken?.symbol
|
|
4337
|
+
] })
|
|
4338
|
+
] }),
|
|
4339
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-border bg-input flex items-center gap-2 rounded-[10px] border py-1 pr-1 pl-3", children: [
|
|
4340
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4341
|
+
"input",
|
|
4342
|
+
{
|
|
4343
|
+
type: "text",
|
|
4344
|
+
inputMode: "decimal",
|
|
4345
|
+
placeholder: "Enter Amount",
|
|
4346
|
+
value: amount,
|
|
4347
|
+
onChange: (e) => {
|
|
4348
|
+
const value = e.target.value.replace(/[^0-9.,]/g, "").replace(/,/g, ".");
|
|
4349
|
+
if (value.split(".").length <= 2) onAmountChange(value);
|
|
4350
|
+
},
|
|
4351
|
+
className: "text-foreground placeholder:text-muted-foreground/50 flex-1 bg-transparent text-sm outline-none"
|
|
4352
|
+
}
|
|
4353
|
+
),
|
|
4354
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4355
|
+
"button",
|
|
4356
|
+
{
|
|
4357
|
+
type: "button",
|
|
4358
|
+
onClick: handleMax,
|
|
4359
|
+
className: "bg-secondary text-foreground hover:bg-secondary/80 cursor-pointer rounded px-3 py-2.5 text-xs font-semibold transition-colors",
|
|
4360
|
+
children: "MAX"
|
|
4361
|
+
}
|
|
4362
|
+
)
|
|
4363
|
+
] }),
|
|
4364
|
+
tooManyDecimals && selectedToken && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
|
|
4365
|
+
"Too many decimal places (max: ",
|
|
4366
|
+
selectedToken.decimals,
|
|
4367
|
+
")"
|
|
4368
|
+
] }),
|
|
4369
|
+
exceedsBalance && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Insufficient balance" })
|
|
4370
|
+
] }),
|
|
4371
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4372
|
+
"button",
|
|
4373
|
+
{
|
|
4374
|
+
type: "button",
|
|
4375
|
+
disabled: !canWithdraw,
|
|
4376
|
+
onClick: handleWithdraw,
|
|
4377
|
+
className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
4378
|
+
children: !isConnected ? "Connect Wallet" : "Withdraw"
|
|
4379
|
+
}
|
|
4380
|
+
)
|
|
4381
|
+
] });
|
|
4382
|
+
}
|
|
4383
|
+
function WithdrawModalContent({
|
|
4384
|
+
onClose,
|
|
4385
|
+
onPendingChange,
|
|
4386
|
+
onBack
|
|
4387
|
+
}) {
|
|
4388
|
+
const { serviceName, enabledTokens, defaultToken, hostedAuthConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
4389
|
+
const { address } = wagmi.useAccount();
|
|
4390
|
+
const appName = serviceName ?? "Privana";
|
|
4391
|
+
const [view, setView] = react.useState("form");
|
|
4392
|
+
const [selectedTokenId, setSelectedTokenId] = react.useState(defaultToken?.id ?? "");
|
|
4393
|
+
const [amount, setAmount] = react.useState("");
|
|
4394
|
+
const [isPending, setIsPending] = react.useState(false);
|
|
4395
|
+
const handlePendingChange = (pending) => {
|
|
4396
|
+
setIsPending(pending);
|
|
4397
|
+
onPendingChange?.(pending);
|
|
4398
|
+
};
|
|
4399
|
+
const selectedToken = enabledTokens.find((t) => t.id === selectedTokenId) ?? defaultToken;
|
|
4400
|
+
const prevAddressRef = react.useRef(address);
|
|
4401
|
+
react.useEffect(() => {
|
|
4402
|
+
const prev = prevAddressRef.current;
|
|
4403
|
+
prevAddressRef.current = address;
|
|
4404
|
+
if (hostedAuthConfig) return;
|
|
4405
|
+
if (prev && address && prev !== address) {
|
|
4406
|
+
setView("form");
|
|
4407
|
+
setAmount("");
|
|
4408
|
+
setSelectedTokenId("");
|
|
4409
|
+
}
|
|
4410
|
+
}, [address, hostedAuthConfig]);
|
|
4411
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4412
|
+
onClose && !isPending && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4413
|
+
"button",
|
|
4414
|
+
{
|
|
4415
|
+
"data-privana-close": true,
|
|
4416
|
+
onClick: onClose,
|
|
4417
|
+
"aria-label": "Close",
|
|
4418
|
+
className: "text-muted-foreground hover:text-foreground absolute top-6 right-5 z-20 flex h-5 w-5 cursor-pointer items-center justify-center transition-colors",
|
|
4419
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
|
|
4420
|
+
}
|
|
4421
|
+
),
|
|
4422
|
+
view === "select-token" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4423
|
+
"button",
|
|
4424
|
+
{
|
|
4425
|
+
type: "button",
|
|
4426
|
+
onClick: () => setView("form"),
|
|
4427
|
+
className: "text-foreground flex w-fit cursor-pointer items-center gap-2 px-5 py-4 text-sm font-medium transition-opacity hover:opacity-70",
|
|
4428
|
+
children: [
|
|
4429
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
|
|
4430
|
+
"Withdraw"
|
|
4431
|
+
]
|
|
4432
|
+
}
|
|
4433
|
+
) : onBack && !isPending ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4434
|
+
"button",
|
|
4435
|
+
{
|
|
4436
|
+
type: "button",
|
|
4437
|
+
onClick: onBack,
|
|
4438
|
+
className: "text-foreground flex w-fit cursor-pointer items-center gap-2 px-5 py-4 text-sm font-medium transition-opacity hover:opacity-70",
|
|
4439
|
+
children: [
|
|
4440
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
|
|
4441
|
+
appName
|
|
4442
|
+
]
|
|
4443
|
+
}
|
|
4444
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-5 font-medium", children: appName }) }),
|
|
4445
|
+
view === "form" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4446
|
+
WithdrawView,
|
|
4447
|
+
{
|
|
4448
|
+
selectedToken,
|
|
4449
|
+
amount,
|
|
4450
|
+
onAmountChange: setAmount,
|
|
4451
|
+
onSelectToken: () => setView("select-token"),
|
|
4452
|
+
onPendingChange: handlePendingChange
|
|
4453
|
+
}
|
|
4454
|
+
),
|
|
4455
|
+
view === "select-token" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4456
|
+
TokenSelectorView2,
|
|
4457
|
+
{
|
|
4458
|
+
selectedTokenId: selectedToken?.id,
|
|
4459
|
+
onSelect: (id) => {
|
|
4460
|
+
setSelectedTokenId(id);
|
|
4461
|
+
setView("form");
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
)
|
|
4465
|
+
] });
|
|
4466
|
+
}
|
|
4467
|
+
function WithdrawModal({ open, onClose }) {
|
|
4468
|
+
const titleId = react.useId();
|
|
4469
|
+
const descId = react.useId();
|
|
4470
|
+
const [isCloseBlocked, setIsCloseBlocked] = react.useState(false);
|
|
4471
|
+
const handleClose = () => {
|
|
4472
|
+
if (!isCloseBlocked) onClose();
|
|
4473
|
+
};
|
|
4474
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4475
|
+
Dialog,
|
|
4476
|
+
{
|
|
4477
|
+
open,
|
|
4478
|
+
onOpenChange: (isOpen) => {
|
|
4479
|
+
if (!isOpen) handleClose();
|
|
4480
|
+
},
|
|
4481
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4482
|
+
DialogContent,
|
|
4483
|
+
{
|
|
4484
|
+
"data-privana": true,
|
|
4485
|
+
showCloseButton: false,
|
|
4486
|
+
onInteractOutside: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4487
|
+
onEscapeKeyDown: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4488
|
+
className: "bg-card flex w-[560px] max-w-[95vw] flex-col gap-2 rounded-2xl border-0 p-2",
|
|
4489
|
+
"aria-labelledby": titleId,
|
|
4490
|
+
"aria-describedby": descId,
|
|
4491
|
+
children: [
|
|
4492
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { id: titleId, className: "sr-only", children: "Withdraw" }),
|
|
4493
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { id: descId, className: "sr-only", children: "Withdraw funds from your account." }),
|
|
4494
|
+
/* @__PURE__ */ jsxRuntime.jsx(WithdrawModalContent, { onClose: handleClose, onPendingChange: setIsCloseBlocked })
|
|
4495
|
+
]
|
|
4496
|
+
}
|
|
4497
|
+
)
|
|
4498
|
+
}
|
|
4499
|
+
);
|
|
4500
|
+
}
|
|
4501
|
+
function WithdrawInlineModal({ className }) {
|
|
4502
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4503
|
+
"div",
|
|
4504
|
+
{
|
|
4505
|
+
"data-privana": true,
|
|
4506
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
4507
|
+
"bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
|
|
4508
|
+
className
|
|
4509
|
+
),
|
|
4510
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(WithdrawModalContent, {})
|
|
4511
|
+
}
|
|
4512
|
+
);
|
|
4513
|
+
}
|
|
4514
|
+
var AVAILABLE_COLOR = "bg-[#007bff]";
|
|
4515
|
+
var IN_USE_COLOR = "bg-[#4fc77f]";
|
|
4516
|
+
function toInUseWei(value) {
|
|
4517
|
+
let parsed;
|
|
4518
|
+
try {
|
|
4519
|
+
parsed = typeof value === "bigint" ? value : BigInt(value);
|
|
4520
|
+
} catch {
|
|
4521
|
+
console.warn(`[privana-sdk] Invalid session.inUse value: ${value}`);
|
|
4522
|
+
return 0n;
|
|
4523
|
+
}
|
|
4524
|
+
if (parsed < 0n) {
|
|
4525
|
+
console.warn(`[privana-sdk] Negative session.inUse value: ${value}`);
|
|
4526
|
+
return 0n;
|
|
4527
|
+
}
|
|
4528
|
+
return parsed;
|
|
4529
|
+
}
|
|
4530
|
+
function useNow(intervalMs, enabled) {
|
|
4531
|
+
const [, setTick] = react.useState(0);
|
|
4532
|
+
react.useEffect(() => {
|
|
4533
|
+
if (!enabled) return;
|
|
4534
|
+
const id = setInterval(() => setTick((t) => t + 1), intervalMs);
|
|
4535
|
+
return () => clearInterval(id);
|
|
4536
|
+
}, [intervalMs, enabled]);
|
|
4537
|
+
}
|
|
4538
|
+
function SegmentedBalanceBar({
|
|
4539
|
+
availableWei,
|
|
4540
|
+
inUseWei
|
|
4541
|
+
}) {
|
|
4542
|
+
const total = availableWei + inUseWei;
|
|
4543
|
+
const showAvailable = inUseWei === 0n || availableWei > 0n;
|
|
4544
|
+
const showInUse = inUseWei > 0n;
|
|
4545
|
+
const grow = (part) => total > 0n ? Number(part * 1000n / total) : 1;
|
|
4546
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-1.5 w-full", children: [
|
|
4547
|
+
showAvailable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4548
|
+
"div",
|
|
4549
|
+
{
|
|
4550
|
+
className: chunk4IW4V7YJ_cjs.cn(AVAILABLE_COLOR, "rounded-l-full", !showInUse && "rounded-r-full"),
|
|
4551
|
+
style: { flexGrow: grow(availableWei) }
|
|
4552
|
+
}
|
|
4553
|
+
),
|
|
4554
|
+
showInUse && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4555
|
+
"div",
|
|
4556
|
+
{
|
|
4557
|
+
className: chunk4IW4V7YJ_cjs.cn(IN_USE_COLOR, "rounded-r-full", !showAvailable && "rounded-l-full"),
|
|
4558
|
+
style: { flexGrow: grow(inUseWei) }
|
|
4559
|
+
}
|
|
4560
|
+
)
|
|
4561
|
+
] });
|
|
4562
|
+
}
|
|
4563
|
+
function BalanceLegendItem({ color, label }) {
|
|
4564
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
4565
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: chunk4IW4V7YJ_cjs.cn("h-2.5 w-2.5 rounded-full", color) }),
|
|
4566
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm leading-5", children: label })
|
|
4567
|
+
] });
|
|
4568
|
+
}
|
|
4569
|
+
function WalletBalanceView({
|
|
4570
|
+
session,
|
|
4571
|
+
allowance,
|
|
4572
|
+
amount,
|
|
4573
|
+
onAmountChange,
|
|
4574
|
+
onPlay,
|
|
4575
|
+
onAddFunds,
|
|
4576
|
+
onWithdraw
|
|
4577
|
+
}) {
|
|
4578
|
+
const { serviceName, serviceIcon, defaultToken } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
4579
|
+
const appName = serviceName ?? "Privana";
|
|
4580
|
+
const token = defaultToken;
|
|
4581
|
+
const {
|
|
4582
|
+
balanceWei,
|
|
4583
|
+
isLoading: isBalanceLoading,
|
|
4584
|
+
isError: isBalanceError
|
|
4585
|
+
} = useBalance({ tokenId: token?.id, enabled: !!token });
|
|
4586
|
+
const inUseWei = session ? toInUseWei(session.inUse) : 0n;
|
|
4587
|
+
const availableWei = BigInt(balanceWei);
|
|
4588
|
+
const variant = !session ? "idle" : inUseWei === 0n ? "session-zero" : availableWei === 0n ? "fully-in-use" : "mixed";
|
|
4589
|
+
const expiry = session?.expiry;
|
|
4590
|
+
useNow(3e4, expiry != null);
|
|
4591
|
+
const countdown = expiry != null ? chunk4IW4V7YJ_cjs.formatTimeRemaining(expiry) : null;
|
|
4592
|
+
const decimals = token?.decimals ?? 18;
|
|
4593
|
+
const totalFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount((availableWei + inUseWei).toString(), decimals);
|
|
4594
|
+
const availableFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount(availableWei.toString(), decimals);
|
|
4595
|
+
const inUseFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount(inUseWei.toString(), decimals);
|
|
4596
|
+
const hasValidAmount = !!amount && parseFloat(amount) > 0;
|
|
4597
|
+
const tooManyDecimals = hasValidAmount && !!token && amount.includes(".") && amount.split(".")[1].length > token.decimals;
|
|
4598
|
+
const exceedsBalance = hasValidAmount && !tooManyDecimals && !!token && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, token.decimals) > availableWei;
|
|
4599
|
+
const canPlay = hasValidAmount && !!token && !tooManyDecimals && !exceedsBalance && !isBalanceLoading && !isBalanceError;
|
|
4600
|
+
const handleMax = () => {
|
|
4601
|
+
const max = availableFormatted.replace(/\s/g, "");
|
|
4602
|
+
if (parseFloat(max) > 0) onAmountChange(max);
|
|
4603
|
+
};
|
|
4604
|
+
const handlePlay = () => {
|
|
4605
|
+
if (!token || !canPlay || !onPlay) return;
|
|
4606
|
+
onPlay({ tokenId: token.id, amount });
|
|
4607
|
+
onAmountChange("");
|
|
4608
|
+
};
|
|
4609
|
+
const showInput = variant !== "fully-in-use";
|
|
4610
|
+
const showInlinePlay = variant === "session-zero" || variant === "mixed";
|
|
4611
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
|
|
4612
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
4613
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
4614
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm leading-[14px]", children: "Total" }),
|
|
4615
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary text-muted-foreground rounded-full px-2 py-[5px] text-[10px] leading-[10px] font-bold", children: token?.symbol ?? "\u2014" })
|
|
4616
|
+
] }),
|
|
4617
|
+
isBalanceLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-9 w-40" }) : isBalanceError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-[32px] leading-9 font-medium", children: "\u2014" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-[32px] leading-9 font-medium", children: totalFormatted })
|
|
4618
|
+
] }),
|
|
4619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
4620
|
+
/* @__PURE__ */ jsxRuntime.jsx(SegmentedBalanceBar, { availableWei, inUseWei }),
|
|
4621
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
4622
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: variant === "fully-in-use" ? /* @__PURE__ */ jsxRuntime.jsx(BalanceLegendItem, { color: IN_USE_COLOR, label: "In use" }) : variant === "mixed" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4624
|
+
BalanceLegendItem,
|
|
4625
|
+
{
|
|
4626
|
+
color: AVAILABLE_COLOR,
|
|
4627
|
+
label: `Available (${availableFormatted})`
|
|
4628
|
+
}
|
|
4629
|
+
),
|
|
4630
|
+
/* @__PURE__ */ jsxRuntime.jsx(BalanceLegendItem, { color: IN_USE_COLOR, label: `In use (${inUseFormatted})` })
|
|
4631
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(BalanceLegendItem, { color: AVAILABLE_COLOR, label: "Available" }) }),
|
|
4632
|
+
countdown && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm leading-5 whitespace-nowrap", children: countdown })
|
|
4633
|
+
] })
|
|
4634
|
+
] }),
|
|
4635
|
+
showInput && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
4636
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
4637
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-border bg-input flex h-10 flex-1 items-center gap-2 rounded-[10px] border py-1 pr-1 pl-3", children: [
|
|
4638
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4639
|
+
"input",
|
|
4640
|
+
{
|
|
4641
|
+
type: "text",
|
|
4642
|
+
inputMode: "decimal",
|
|
4643
|
+
placeholder: "Enter Amount",
|
|
4644
|
+
value: amount,
|
|
4645
|
+
onChange: (e) => {
|
|
4646
|
+
const value = e.target.value.replace(/[^0-9.,]/g, "").replace(/,/g, ".");
|
|
4647
|
+
if (value.split(".").length <= 2) onAmountChange(value);
|
|
4648
|
+
},
|
|
4649
|
+
className: "text-foreground placeholder:text-muted-foreground/50 min-w-0 flex-1 bg-transparent text-sm outline-none"
|
|
4650
|
+
}
|
|
4651
|
+
),
|
|
4652
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4653
|
+
"button",
|
|
4654
|
+
{
|
|
4655
|
+
type: "button",
|
|
4656
|
+
onClick: handleMax,
|
|
4657
|
+
className: "text-foreground cursor-pointer rounded px-3 py-2.5 text-xs font-semibold",
|
|
4658
|
+
children: "MAX"
|
|
4659
|
+
}
|
|
4660
|
+
)
|
|
4661
|
+
] }),
|
|
4662
|
+
showInlinePlay && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4663
|
+
"button",
|
|
4664
|
+
{
|
|
4665
|
+
type: "button",
|
|
4666
|
+
disabled: !onPlay || !canPlay,
|
|
4667
|
+
onClick: handlePlay,
|
|
4668
|
+
className: "border-border flex h-10 min-w-20 cursor-pointer items-center justify-center rounded-[10px] border px-3 text-sm font-medium text-[#4fc77f] transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4669
|
+
children: "Play"
|
|
4670
|
+
}
|
|
4671
|
+
)
|
|
4672
|
+
] }),
|
|
4673
|
+
tooManyDecimals && token && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
|
|
4674
|
+
"Too many decimal places (max: ",
|
|
4675
|
+
token.decimals,
|
|
4676
|
+
")"
|
|
4677
|
+
] }),
|
|
4678
|
+
exceedsBalance && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Insufficient balance" })
|
|
4679
|
+
] }),
|
|
4680
|
+
variant === "idle" && allowance && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted rounded-[10px] p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4681
|
+
AllowancePolicySection,
|
|
4682
|
+
{
|
|
4683
|
+
allowance,
|
|
4684
|
+
serviceName: appName,
|
|
4685
|
+
serviceIcon
|
|
4686
|
+
}
|
|
4687
|
+
) }),
|
|
4688
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start gap-4", children: variant === "idle" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4689
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4690
|
+
"button",
|
|
4691
|
+
{
|
|
4692
|
+
type: "button",
|
|
4693
|
+
disabled: !onPlay || !canPlay,
|
|
4694
|
+
onClick: handlePlay,
|
|
4695
|
+
className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
4696
|
+
children: "Play"
|
|
4697
|
+
}
|
|
4698
|
+
),
|
|
4699
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4700
|
+
"button",
|
|
4701
|
+
{
|
|
4702
|
+
type: "button",
|
|
4703
|
+
disabled: !onAddFunds,
|
|
4704
|
+
onClick: onAddFunds,
|
|
4705
|
+
className: "bg-secondary text-foreground hover:bg-secondary/80 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
4706
|
+
children: "Add funds"
|
|
4707
|
+
}
|
|
4708
|
+
)
|
|
4709
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4710
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4711
|
+
"button",
|
|
4712
|
+
{
|
|
4713
|
+
type: "button",
|
|
4714
|
+
disabled: !onAddFunds,
|
|
4715
|
+
onClick: onAddFunds,
|
|
4716
|
+
className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
4717
|
+
children: "Add Funds"
|
|
4718
|
+
}
|
|
4719
|
+
),
|
|
4720
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4721
|
+
"button",
|
|
4722
|
+
{
|
|
4723
|
+
type: "button",
|
|
4724
|
+
disabled: !onWithdraw,
|
|
4725
|
+
onClick: onWithdraw,
|
|
4726
|
+
className: "bg-secondary text-foreground hover:bg-secondary/80 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
4727
|
+
children: "Withdraw"
|
|
4728
|
+
}
|
|
4729
|
+
)
|
|
4730
|
+
] }) })
|
|
4731
|
+
] });
|
|
4732
|
+
}
|
|
4733
|
+
function WalletModalContent({
|
|
4734
|
+
session,
|
|
4735
|
+
allowance,
|
|
4736
|
+
onPlay,
|
|
4737
|
+
onEndSession,
|
|
4738
|
+
onDepositSuccess,
|
|
4739
|
+
onClose,
|
|
4740
|
+
onCloseBlockedChange,
|
|
4741
|
+
...depositHandlers
|
|
4742
|
+
}) {
|
|
4743
|
+
const { serviceName, hostedAuthConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
|
|
4744
|
+
const { address } = wagmi.useAccount();
|
|
4745
|
+
const appName = serviceName ?? "Privana";
|
|
4746
|
+
const [view, setView] = react.useState("balance");
|
|
4747
|
+
const [amount, setAmount] = react.useState("");
|
|
4748
|
+
const [depositBlocked, setDepositBlocked] = react.useState(false);
|
|
4749
|
+
const [withdrawPending, setWithdrawPending] = react.useState(false);
|
|
4750
|
+
const [endSessionError, setEndSessionError] = react.useState(null);
|
|
4751
|
+
const endSessionRunRef = react.useRef(0);
|
|
4752
|
+
const prevAddressRef = react.useRef(address);
|
|
4753
|
+
react.useEffect(() => {
|
|
4754
|
+
const prev = prevAddressRef.current;
|
|
4755
|
+
prevAddressRef.current = address;
|
|
4756
|
+
if (hostedAuthConfig) return;
|
|
4757
|
+
if (prev && address && prev !== address) {
|
|
4758
|
+
setView("balance");
|
|
4759
|
+
setAmount("");
|
|
4760
|
+
setDepositBlocked(false);
|
|
4761
|
+
setWithdrawPending(false);
|
|
4762
|
+
setEndSessionError(null);
|
|
4763
|
+
endSessionRunRef.current++;
|
|
4764
|
+
}
|
|
4765
|
+
}, [address, hostedAuthConfig]);
|
|
4766
|
+
const closeBlocked = depositBlocked || withdrawPending || view === "ending-session";
|
|
4767
|
+
react.useEffect(() => {
|
|
4768
|
+
onCloseBlockedChange?.(closeBlocked);
|
|
4769
|
+
}, [closeBlocked, onCloseBlockedChange]);
|
|
4770
|
+
const exitDeposit = () => {
|
|
4771
|
+
setDepositBlocked(false);
|
|
4772
|
+
setView("balance");
|
|
4773
|
+
};
|
|
4774
|
+
const exitWithdraw = () => {
|
|
4775
|
+
setWithdrawPending(false);
|
|
4776
|
+
setView("balance");
|
|
4777
|
+
};
|
|
4778
|
+
const startEndSession = () => {
|
|
4779
|
+
if (!onEndSession) return;
|
|
4780
|
+
const run = ++endSessionRunRef.current;
|
|
4781
|
+
setEndSessionError(null);
|
|
4782
|
+
setView("ending-session");
|
|
4783
|
+
Promise.resolve().then(() => onEndSession()).then(
|
|
4784
|
+
() => {
|
|
4785
|
+
if (endSessionRunRef.current !== run) return;
|
|
4786
|
+
setView("withdraw");
|
|
4787
|
+
},
|
|
4788
|
+
(err) => {
|
|
4789
|
+
if (endSessionRunRef.current !== run) return;
|
|
4790
|
+
setEndSessionError(err instanceof Error ? err.message : null);
|
|
4791
|
+
setView("end-session-error");
|
|
4792
|
+
}
|
|
4793
|
+
);
|
|
4794
|
+
};
|
|
4795
|
+
const handleWithdraw = () => {
|
|
4796
|
+
if (session && onEndSession) {
|
|
4797
|
+
startEndSession();
|
|
4798
|
+
} else {
|
|
4799
|
+
setView("withdraw");
|
|
4800
|
+
}
|
|
4801
|
+
};
|
|
4802
|
+
const dismissEndSessionError = () => {
|
|
4803
|
+
endSessionRunRef.current++;
|
|
4804
|
+
setEndSessionError(null);
|
|
4805
|
+
setView("balance");
|
|
4806
|
+
};
|
|
4807
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4808
|
+
onClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4809
|
+
"button",
|
|
4810
|
+
{
|
|
4811
|
+
"data-privana-close": true,
|
|
4812
|
+
onClick: onClose,
|
|
4813
|
+
disabled: closeBlocked,
|
|
4814
|
+
"aria-label": "Close",
|
|
4815
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
4816
|
+
"absolute top-6 right-5 z-20 flex h-5 w-5 items-center justify-center transition-colors",
|
|
4817
|
+
closeBlocked ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
|
|
4818
|
+
),
|
|
4819
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
|
|
4820
|
+
}
|
|
4821
|
+
),
|
|
4822
|
+
(view === "balance" || view === "ending-session" || view === "end-session-error") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-5 font-medium", children: appName }) }),
|
|
4823
|
+
view === "balance" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4824
|
+
WalletBalanceView,
|
|
4825
|
+
{
|
|
4826
|
+
session,
|
|
4827
|
+
allowance,
|
|
4828
|
+
amount,
|
|
4829
|
+
onAmountChange: setAmount,
|
|
4830
|
+
onPlay,
|
|
4831
|
+
onAddFunds: () => setView("deposit"),
|
|
4832
|
+
onWithdraw: handleWithdraw
|
|
4833
|
+
}
|
|
4834
|
+
),
|
|
4835
|
+
view === "ending-session" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4836
|
+
TransactionProgressView,
|
|
4837
|
+
{
|
|
4838
|
+
title: "Ending game session...",
|
|
4839
|
+
steps: [{ label: "Waiting for the game session to settle", status: "active" }]
|
|
4840
|
+
}
|
|
4841
|
+
) }),
|
|
4842
|
+
view === "end-session-error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4843
|
+
TransactionErrorView,
|
|
4844
|
+
{
|
|
4845
|
+
title: "Could not end session",
|
|
4846
|
+
message: endSessionError ? `Your game session could not be ended, so the funds committed to it are not available to withdraw yet. (${endSessionError})` : "Your game session could not be ended, so the funds committed to it are not available to withdraw yet.",
|
|
4847
|
+
onRetry: startEndSession,
|
|
4848
|
+
onDismiss: dismissEndSessionError
|
|
4849
|
+
}
|
|
4850
|
+
) }),
|
|
4851
|
+
view === "withdraw" && /* @__PURE__ */ jsxRuntime.jsx(WithdrawModalContent, { onBack: exitWithdraw, onPendingChange: setWithdrawPending }),
|
|
4852
|
+
view === "deposit" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4853
|
+
DepositModalContent,
|
|
4854
|
+
{
|
|
4855
|
+
...depositHandlers,
|
|
4856
|
+
allowance,
|
|
4857
|
+
onExit: exitDeposit,
|
|
4858
|
+
onCloseBlockedChange: setDepositBlocked,
|
|
4859
|
+
onDepositSuccess: () => {
|
|
4860
|
+
exitDeposit();
|
|
4861
|
+
onDepositSuccess?.();
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
)
|
|
4865
|
+
] });
|
|
4866
|
+
}
|
|
4867
|
+
function WalletModal({ open, onClose, ...handlers }) {
|
|
4868
|
+
const titleId = react.useId();
|
|
4869
|
+
const descId = react.useId();
|
|
4870
|
+
const [isCloseBlocked, setIsCloseBlocked] = react.useState(false);
|
|
4871
|
+
const handleClose = () => {
|
|
4872
|
+
if (!isCloseBlocked) onClose();
|
|
4873
|
+
};
|
|
4874
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4875
|
+
Dialog,
|
|
4876
|
+
{
|
|
4877
|
+
open,
|
|
4878
|
+
onOpenChange: (isOpen) => {
|
|
4879
|
+
if (!isOpen) handleClose();
|
|
4880
|
+
},
|
|
4881
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4882
|
+
DialogContent,
|
|
4883
|
+
{
|
|
4884
|
+
"data-privana": true,
|
|
4885
|
+
showCloseButton: false,
|
|
4886
|
+
onInteractOutside: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4887
|
+
onEscapeKeyDown: isCloseBlocked ? (e) => e.preventDefault() : void 0,
|
|
4888
|
+
className: "bg-card flex w-[560px] max-w-[95vw] flex-col gap-2 rounded-2xl border-0 p-2",
|
|
4889
|
+
"aria-labelledby": titleId,
|
|
4890
|
+
"aria-describedby": descId,
|
|
4891
|
+
children: [
|
|
4892
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { id: titleId, className: "sr-only", children: "Wallet" }),
|
|
4893
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { id: descId, className: "sr-only", children: "Manage your account balance." }),
|
|
4894
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4895
|
+
WalletModalContent,
|
|
4896
|
+
{
|
|
4897
|
+
onClose: handleClose,
|
|
4898
|
+
onCloseBlockedChange: setIsCloseBlocked,
|
|
4899
|
+
...handlers
|
|
4900
|
+
}
|
|
4901
|
+
)
|
|
4902
|
+
]
|
|
4903
|
+
}
|
|
4904
|
+
)
|
|
4905
|
+
}
|
|
4906
|
+
);
|
|
4907
|
+
}
|
|
4908
|
+
function WalletInlineModal({ className, ...handlers }) {
|
|
4909
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4910
|
+
"div",
|
|
4911
|
+
{
|
|
4912
|
+
"data-privana": true,
|
|
4913
|
+
className: chunk4IW4V7YJ_cjs.cn(
|
|
4914
|
+
"bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
|
|
4915
|
+
className
|
|
4916
|
+
),
|
|
4917
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(WalletModalContent, { ...handlers })
|
|
4918
|
+
}
|
|
4919
|
+
);
|
|
4920
|
+
}
|
|
4921
|
+
|
|
4922
|
+
Object.defineProperty(exports, "AccountingApiError", {
|
|
4923
|
+
enumerable: true,
|
|
4924
|
+
get: function () { return chunk4IW4V7YJ_cjs.AccountingApiError; }
|
|
4925
|
+
});
|
|
4926
|
+
Object.defineProperty(exports, "Button", {
|
|
4927
|
+
enumerable: true,
|
|
4928
|
+
get: function () { return chunk4IW4V7YJ_cjs.Button; }
|
|
4929
|
+
});
|
|
4930
|
+
Object.defineProperty(exports, "DEFAULT_LOCK_DURATION_SECONDS", {
|
|
4931
|
+
enumerable: true,
|
|
4932
|
+
get: function () { return chunk4IW4V7YJ_cjs.DEFAULT_LOCK_DURATION_SECONDS; }
|
|
4933
|
+
});
|
|
4934
|
+
Object.defineProperty(exports, "DEFAULT_ONRAMP_LOCK_BUFFER", {
|
|
4935
|
+
enumerable: true,
|
|
4936
|
+
get: function () { return chunk4IW4V7YJ_cjs.DEFAULT_ONRAMP_LOCK_BUFFER; }
|
|
4937
|
+
});
|
|
4938
|
+
Object.defineProperty(exports, "HOSTED_AUTH_CLOCK_SKEW_MS", {
|
|
4939
|
+
enumerable: true,
|
|
4940
|
+
get: function () { return chunk4IW4V7YJ_cjs.HOSTED_AUTH_CLOCK_SKEW_MS; }
|
|
4941
|
+
});
|
|
4942
|
+
Object.defineProperty(exports, "HostedAuthError", {
|
|
4943
|
+
enumerable: true,
|
|
4944
|
+
get: function () { return chunk4IW4V7YJ_cjs.HostedAuthError; }
|
|
4945
|
+
});
|
|
4946
|
+
Object.defineProperty(exports, "HostedAuthRequiredError", {
|
|
4947
|
+
enumerable: true,
|
|
4948
|
+
get: function () { return chunk4IW4V7YJ_cjs.HostedAuthRequiredError; }
|
|
4949
|
+
});
|
|
4950
|
+
Object.defineProperty(exports, "HostedAuthStateMismatchError", {
|
|
4951
|
+
enumerable: true,
|
|
4952
|
+
get: function () { return chunk4IW4V7YJ_cjs.HostedAuthStateMismatchError; }
|
|
4953
|
+
});
|
|
4954
|
+
Object.defineProperty(exports, "HttpClient", {
|
|
4955
|
+
enumerable: true,
|
|
4956
|
+
get: function () { return chunk4IW4V7YJ_cjs.HttpClient; }
|
|
4957
|
+
});
|
|
4958
|
+
Object.defineProperty(exports, "LOCK_TYPES", {
|
|
4959
|
+
enumerable: true,
|
|
4960
|
+
get: function () { return chunk4IW4V7YJ_cjs.LOCK_TYPES; }
|
|
4961
|
+
});
|
|
4962
|
+
Object.defineProperty(exports, "MODIFY_LOCK_TYPES", {
|
|
4963
|
+
enumerable: true,
|
|
4964
|
+
get: function () { return chunk4IW4V7YJ_cjs.MODIFY_LOCK_TYPES; }
|
|
4965
|
+
});
|
|
4966
|
+
Object.defineProperty(exports, "NETWORK_CONFIG", {
|
|
4967
|
+
enumerable: true,
|
|
4968
|
+
get: function () { return chunk4IW4V7YJ_cjs.NETWORK_CONFIG; }
|
|
4969
|
+
});
|
|
4970
|
+
Object.defineProperty(exports, "NetworkError", {
|
|
4971
|
+
enumerable: true,
|
|
4972
|
+
get: function () { return chunk4IW4V7YJ_cjs.NetworkError; }
|
|
4973
|
+
});
|
|
4974
|
+
Object.defineProperty(exports, "PostDepositLockError", {
|
|
4975
|
+
enumerable: true,
|
|
4976
|
+
get: function () { return chunk4IW4V7YJ_cjs.PostDepositLockError; }
|
|
4977
|
+
});
|
|
4978
|
+
Object.defineProperty(exports, "PrivanaClient", {
|
|
4979
|
+
enumerable: true,
|
|
4980
|
+
get: function () { return chunk4IW4V7YJ_cjs.PrivanaClient; }
|
|
4981
|
+
});
|
|
4982
|
+
Object.defineProperty(exports, "PrivanaProvider", {
|
|
4983
|
+
enumerable: true,
|
|
4984
|
+
get: function () { return chunk4IW4V7YJ_cjs.PrivanaProvider; }
|
|
4985
|
+
});
|
|
4986
|
+
Object.defineProperty(exports, "SUPPORTED_CHAINS", {
|
|
4987
|
+
enumerable: true,
|
|
4988
|
+
get: function () { return chunk4IW4V7YJ_cjs.SUPPORTED_CHAINS; }
|
|
4989
|
+
});
|
|
4990
|
+
Object.defineProperty(exports, "SiweAuthProvider", {
|
|
4991
|
+
enumerable: true,
|
|
4992
|
+
get: function () { return chunk4IW4V7YJ_cjs.SiweAuthProvider; }
|
|
4993
|
+
});
|
|
4994
|
+
Object.defineProperty(exports, "Skeleton", {
|
|
4995
|
+
enumerable: true,
|
|
4996
|
+
get: function () { return chunk4IW4V7YJ_cjs.Skeleton; }
|
|
4997
|
+
});
|
|
4998
|
+
Object.defineProperty(exports, "TRANSFER_LOCKED_TYPES", {
|
|
4999
|
+
enumerable: true,
|
|
5000
|
+
get: function () { return chunk4IW4V7YJ_cjs.TRANSFER_LOCKED_TYPES; }
|
|
5001
|
+
});
|
|
5002
|
+
Object.defineProperty(exports, "TRANSFER_TYPES", {
|
|
5003
|
+
enumerable: true,
|
|
5004
|
+
get: function () { return chunk4IW4V7YJ_cjs.TRANSFER_TYPES; }
|
|
5005
|
+
});
|
|
5006
|
+
Object.defineProperty(exports, "ValidationError", {
|
|
5007
|
+
enumerable: true,
|
|
5008
|
+
get: function () { return chunk4IW4V7YJ_cjs.ValidationError; }
|
|
5009
|
+
});
|
|
5010
|
+
Object.defineProperty(exports, "WITHDRAW_FROM_LOCK_TYPES", {
|
|
5011
|
+
enumerable: true,
|
|
5012
|
+
get: function () { return chunk4IW4V7YJ_cjs.WITHDRAW_FROM_LOCK_TYPES; }
|
|
5013
|
+
});
|
|
5014
|
+
Object.defineProperty(exports, "WITHDRAW_TYPES", {
|
|
5015
|
+
enumerable: true,
|
|
5016
|
+
get: function () { return chunk4IW4V7YJ_cjs.WITHDRAW_TYPES; }
|
|
5017
|
+
});
|
|
5018
|
+
Object.defineProperty(exports, "applyLockBuffer", {
|
|
5019
|
+
enumerable: true,
|
|
5020
|
+
get: function () { return chunk4IW4V7YJ_cjs.applyLockBuffer; }
|
|
5021
|
+
});
|
|
5022
|
+
Object.defineProperty(exports, "applyRefreshResponse", {
|
|
5023
|
+
enumerable: true,
|
|
5024
|
+
get: function () { return chunk4IW4V7YJ_cjs.applyRefreshResponse; }
|
|
5025
|
+
});
|
|
5026
|
+
Object.defineProperty(exports, "buildHostedAuthSession", {
|
|
5027
|
+
enumerable: true,
|
|
5028
|
+
get: function () { return chunk4IW4V7YJ_cjs.buildHostedAuthSession; }
|
|
5029
|
+
});
|
|
5030
|
+
Object.defineProperty(exports, "buildSiweStatement", {
|
|
5031
|
+
enumerable: true,
|
|
5032
|
+
get: function () { return chunk4IW4V7YJ_cjs.buildSiweStatement; }
|
|
5033
|
+
});
|
|
5034
|
+
Object.defineProperty(exports, "buttonVariants", {
|
|
5035
|
+
enumerable: true,
|
|
5036
|
+
get: function () { return chunk4IW4V7YJ_cjs.buttonVariants; }
|
|
5037
|
+
});
|
|
5038
|
+
Object.defineProperty(exports, "clampLockAmount", {
|
|
5039
|
+
enumerable: true,
|
|
5040
|
+
get: function () { return chunk4IW4V7YJ_cjs.clampLockAmount; }
|
|
5041
|
+
});
|
|
5042
|
+
Object.defineProperty(exports, "clearHostedAuthPendingTransaction", {
|
|
5043
|
+
enumerable: true,
|
|
5044
|
+
get: function () { return chunk4IW4V7YJ_cjs.clearHostedAuthPendingTransaction; }
|
|
5045
|
+
});
|
|
5046
|
+
Object.defineProperty(exports, "clearPendingLock", {
|
|
5047
|
+
enumerable: true,
|
|
5048
|
+
get: function () { return chunk4IW4V7YJ_cjs.clearPendingLock; }
|
|
5049
|
+
});
|
|
5050
|
+
Object.defineProperty(exports, "createDomain", {
|
|
5051
|
+
enumerable: true,
|
|
5052
|
+
get: function () { return chunk4IW4V7YJ_cjs.createDomain; }
|
|
5053
|
+
});
|
|
5054
|
+
Object.defineProperty(exports, "createHostedAuthPendingStorageKey", {
|
|
5055
|
+
enumerable: true,
|
|
5056
|
+
get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthPendingStorageKey; }
|
|
5057
|
+
});
|
|
5058
|
+
Object.defineProperty(exports, "createHostedAuthState", {
|
|
5059
|
+
enumerable: true,
|
|
5060
|
+
get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthState; }
|
|
5061
|
+
});
|
|
5062
|
+
Object.defineProperty(exports, "createHostedAuthStorageKey", {
|
|
5063
|
+
enumerable: true,
|
|
5064
|
+
get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthStorageKey; }
|
|
5065
|
+
});
|
|
5066
|
+
Object.defineProperty(exports, "createLockExpiry", {
|
|
5067
|
+
enumerable: true,
|
|
5068
|
+
get: function () { return chunk4IW4V7YJ_cjs.createLockExpiry; }
|
|
5069
|
+
});
|
|
5070
|
+
Object.defineProperty(exports, "createPkceChallenge", {
|
|
5071
|
+
enumerable: true,
|
|
5072
|
+
get: function () { return chunk4IW4V7YJ_cjs.createPkceChallenge; }
|
|
5073
|
+
});
|
|
5074
|
+
Object.defineProperty(exports, "createPkceVerifier", {
|
|
5075
|
+
enumerable: true,
|
|
5076
|
+
get: function () { return chunk4IW4V7YJ_cjs.createPkceVerifier; }
|
|
5077
|
+
});
|
|
5078
|
+
Object.defineProperty(exports, "createSignedLockRequest", {
|
|
5079
|
+
enumerable: true,
|
|
5080
|
+
get: function () { return chunk4IW4V7YJ_cjs.createSignedLockRequest; }
|
|
5081
|
+
});
|
|
5082
|
+
Object.defineProperty(exports, "getAccountingContract", {
|
|
5083
|
+
enumerable: true,
|
|
5084
|
+
get: function () { return chunk4IW4V7YJ_cjs.getAccountingContract; }
|
|
5085
|
+
});
|
|
5086
|
+
Object.defineProperty(exports, "getApiUrl", {
|
|
5087
|
+
enumerable: true,
|
|
5088
|
+
get: function () { return chunk4IW4V7YJ_cjs.getApiUrl; }
|
|
5089
|
+
});
|
|
5090
|
+
Object.defineProperty(exports, "getChainById", {
|
|
5091
|
+
enumerable: true,
|
|
5092
|
+
get: function () { return chunk4IW4V7YJ_cjs.getChainById; }
|
|
5093
|
+
});
|
|
5094
|
+
Object.defineProperty(exports, "getChainId", {
|
|
5095
|
+
enumerable: true,
|
|
5096
|
+
get: function () { return chunk4IW4V7YJ_cjs.getChainId; }
|
|
5097
|
+
});
|
|
5098
|
+
Object.defineProperty(exports, "getExplorerAddressUrl", {
|
|
5099
|
+
enumerable: true,
|
|
5100
|
+
get: function () { return chunk4IW4V7YJ_cjs.getExplorerAddressUrl; }
|
|
5101
|
+
});
|
|
5102
|
+
Object.defineProperty(exports, "getExplorerLabel", {
|
|
5103
|
+
enumerable: true,
|
|
5104
|
+
get: function () { return chunk4IW4V7YJ_cjs.getExplorerLabel; }
|
|
5105
|
+
});
|
|
5106
|
+
Object.defineProperty(exports, "isHostedAuthRefreshActive", {
|
|
5107
|
+
enumerable: true,
|
|
5108
|
+
get: function () { return chunk4IW4V7YJ_cjs.isHostedAuthRefreshActive; }
|
|
5109
|
+
});
|
|
5110
|
+
Object.defineProperty(exports, "isHostedAuthSessionActive", {
|
|
5111
|
+
enumerable: true,
|
|
5112
|
+
get: function () { return chunk4IW4V7YJ_cjs.isHostedAuthSessionActive; }
|
|
5113
|
+
});
|
|
5114
|
+
Object.defineProperty(exports, "isSignedLockUsable", {
|
|
5115
|
+
enumerable: true,
|
|
5116
|
+
get: function () { return chunk4IW4V7YJ_cjs.isSignedLockUsable; }
|
|
5117
|
+
});
|
|
5118
|
+
Object.defineProperty(exports, "loadPendingLock", {
|
|
5119
|
+
enumerable: true,
|
|
5120
|
+
get: function () { return chunk4IW4V7YJ_cjs.loadPendingLock; }
|
|
5121
|
+
});
|
|
5122
|
+
Object.defineProperty(exports, "normalizeAddress", {
|
|
5123
|
+
enumerable: true,
|
|
5124
|
+
get: function () { return chunk4IW4V7YJ_cjs.normalizeAddress; }
|
|
5125
|
+
});
|
|
5126
|
+
Object.defineProperty(exports, "normalizeHex", {
|
|
5127
|
+
enumerable: true,
|
|
5128
|
+
get: function () { return chunk4IW4V7YJ_cjs.normalizeHex; }
|
|
5129
|
+
});
|
|
5130
|
+
Object.defineProperty(exports, "parseHostedAuthCallback", {
|
|
5131
|
+
enumerable: true,
|
|
5132
|
+
get: function () { return chunk4IW4V7YJ_cjs.parseHostedAuthCallback; }
|
|
5133
|
+
});
|
|
5134
|
+
Object.defineProperty(exports, "persistHostedAuthPendingTransaction", {
|
|
5135
|
+
enumerable: true,
|
|
5136
|
+
get: function () { return chunk4IW4V7YJ_cjs.persistHostedAuthPendingTransaction; }
|
|
5137
|
+
});
|
|
5138
|
+
Object.defineProperty(exports, "readHostedAuthPendingTransaction", {
|
|
5139
|
+
enumerable: true,
|
|
5140
|
+
get: function () { return chunk4IW4V7YJ_cjs.readHostedAuthPendingTransaction; }
|
|
5141
|
+
});
|
|
5142
|
+
Object.defineProperty(exports, "readStoredHostedAuthSession", {
|
|
5143
|
+
enumerable: true,
|
|
5144
|
+
get: function () { return chunk4IW4V7YJ_cjs.readStoredHostedAuthSession; }
|
|
5145
|
+
});
|
|
5146
|
+
Object.defineProperty(exports, "savePendingLock", {
|
|
5147
|
+
enumerable: true,
|
|
5148
|
+
get: function () { return chunk4IW4V7YJ_cjs.savePendingLock; }
|
|
5149
|
+
});
|
|
5150
|
+
Object.defineProperty(exports, "signLockMessage", {
|
|
5151
|
+
enumerable: true,
|
|
5152
|
+
get: function () { return chunk4IW4V7YJ_cjs.signLockMessage; }
|
|
5153
|
+
});
|
|
5154
|
+
Object.defineProperty(exports, "signModifyLockMessage", {
|
|
5155
|
+
enumerable: true,
|
|
5156
|
+
get: function () { return chunk4IW4V7YJ_cjs.signModifyLockMessage; }
|
|
5157
|
+
});
|
|
5158
|
+
Object.defineProperty(exports, "signTransferLockedMessage", {
|
|
5159
|
+
enumerable: true,
|
|
5160
|
+
get: function () { return chunk4IW4V7YJ_cjs.signTransferLockedMessage; }
|
|
5161
|
+
});
|
|
5162
|
+
Object.defineProperty(exports, "signTransferMessage", {
|
|
5163
|
+
enumerable: true,
|
|
5164
|
+
get: function () { return chunk4IW4V7YJ_cjs.signTransferMessage; }
|
|
5165
|
+
});
|
|
5166
|
+
Object.defineProperty(exports, "signWithdrawFromLockMessage", {
|
|
5167
|
+
enumerable: true,
|
|
5168
|
+
get: function () { return chunk4IW4V7YJ_cjs.signWithdrawFromLockMessage; }
|
|
5169
|
+
});
|
|
5170
|
+
Object.defineProperty(exports, "signWithdrawMessage", {
|
|
5171
|
+
enumerable: true,
|
|
5172
|
+
get: function () { return chunk4IW4V7YJ_cjs.signWithdrawMessage; }
|
|
5173
|
+
});
|
|
5174
|
+
Object.defineProperty(exports, "stripHostedAuthCallbackParams", {
|
|
5175
|
+
enumerable: true,
|
|
5176
|
+
get: function () { return chunk4IW4V7YJ_cjs.stripHostedAuthCallbackParams; }
|
|
5177
|
+
});
|
|
5178
|
+
Object.defineProperty(exports, "submitPendingLock", {
|
|
3282
5179
|
enumerable: true,
|
|
3283
|
-
get: function () { return
|
|
5180
|
+
get: function () { return chunk4IW4V7YJ_cjs.submitPendingLock; }
|
|
3284
5181
|
});
|
|
3285
5182
|
Object.defineProperty(exports, "syncHostedAuthSessionToClient", {
|
|
3286
5183
|
enumerable: true,
|
|
3287
|
-
get: function () { return
|
|
5184
|
+
get: function () { return chunk4IW4V7YJ_cjs.syncHostedAuthSessionToClient; }
|
|
3288
5185
|
});
|
|
3289
5186
|
Object.defineProperty(exports, "useDepositVerification", {
|
|
3290
5187
|
enumerable: true,
|
|
3291
|
-
get: function () { return
|
|
5188
|
+
get: function () { return chunk4IW4V7YJ_cjs.useDepositVerification; }
|
|
3292
5189
|
});
|
|
3293
5190
|
Object.defineProperty(exports, "usePrivanaContext", {
|
|
3294
5191
|
enumerable: true,
|
|
3295
|
-
get: function () { return
|
|
5192
|
+
get: function () { return chunk4IW4V7YJ_cjs.usePrivanaContext; }
|
|
3296
5193
|
});
|
|
3297
5194
|
Object.defineProperty(exports, "useSafeAccount", {
|
|
3298
5195
|
enumerable: true,
|
|
3299
|
-
get: function () { return
|
|
5196
|
+
get: function () { return chunk4IW4V7YJ_cjs.useSafeAccount; }
|
|
3300
5197
|
});
|
|
3301
5198
|
Object.defineProperty(exports, "useSafePrivanaContext", {
|
|
3302
5199
|
enumerable: true,
|
|
3303
|
-
get: function () { return
|
|
5200
|
+
get: function () { return chunk4IW4V7YJ_cjs.useSafePrivanaContext; }
|
|
3304
5201
|
});
|
|
3305
5202
|
Object.defineProperty(exports, "useSiweAuth", {
|
|
3306
5203
|
enumerable: true,
|
|
3307
|
-
get: function () { return
|
|
5204
|
+
get: function () { return chunk4IW4V7YJ_cjs.useSiweAuth; }
|
|
3308
5205
|
});
|
|
3309
|
-
exports.
|
|
3310
|
-
exports.
|
|
5206
|
+
exports.DepositInlineModal = DepositInlineModal;
|
|
5207
|
+
exports.DepositModal = DepositModal;
|
|
3311
5208
|
exports.PrivanaButton = PrivanaButton;
|
|
5209
|
+
exports.PrivanaIcon = PrivanaIcon;
|
|
3312
5210
|
exports.PrivanaInlineModal = PrivanaInlineModal;
|
|
3313
5211
|
exports.PrivanaModal = PrivanaModal;
|
|
3314
|
-
exports.
|
|
3315
|
-
exports.
|
|
3316
|
-
exports.
|
|
3317
|
-
exports.
|
|
3318
|
-
exports.createDomain = createDomain;
|
|
3319
|
-
exports.createLockExpiry = createLockExpiry;
|
|
5212
|
+
exports.WalletInlineModal = WalletInlineModal;
|
|
5213
|
+
exports.WalletModal = WalletModal;
|
|
5214
|
+
exports.WithdrawInlineModal = WithdrawInlineModal;
|
|
5215
|
+
exports.WithdrawModal = WithdrawModal;
|
|
3320
5216
|
exports.getChainIcon = getChainIcon;
|
|
3321
5217
|
exports.getTokenIcon = getTokenIcon;
|
|
3322
|
-
exports.signLockMessage = signLockMessage;
|
|
3323
|
-
exports.signModifyLockMessage = signModifyLockMessage;
|
|
3324
|
-
exports.signTransferLockedMessage = signTransferLockedMessage;
|
|
3325
|
-
exports.signTransferMessage = signTransferMessage;
|
|
3326
|
-
exports.signWithdrawFromLockMessage = signWithdrawFromLockMessage;
|
|
3327
|
-
exports.signWithdrawMessage = signWithdrawMessage;
|
|
3328
5218
|
exports.useBalance = useBalance;
|
|
3329
5219
|
exports.useBatchBalances = useBatchBalances;
|
|
3330
5220
|
exports.useDeposit = useDeposit;
|
|
5221
|
+
exports.useDepositAddress = useDepositAddress;
|
|
3331
5222
|
exports.useExpiredLocks = useExpiredLocks;
|
|
3332
5223
|
exports.useHistory = useHistory;
|
|
3333
5224
|
exports.useHostedRedirectAuth = useHostedRedirectAuth;
|
|
3334
5225
|
exports.useLockFunds = useLockFunds;
|
|
3335
5226
|
exports.useLockedFunds = useLockedFunds;
|
|
3336
5227
|
exports.useModifyLock = useModifyLock;
|
|
5228
|
+
exports.usePendingDeposits = usePendingDeposits;
|
|
3337
5229
|
exports.usePendingWithdrawals = usePendingWithdrawals;
|
|
3338
5230
|
exports.usePrivanaClient = usePrivanaClient;
|
|
3339
5231
|
exports.useTokenInfo = useTokenInfo;
|