@trustware/sdk-staging 1.1.10-staging.0 → 1.1.11-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -21
- package/dist/constants.cjs +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/{core-BPLiD1UG.d.ts → core-B1WCJfDI.d.ts} +15 -2
- package/dist/{core-B7Ez-5-r.d.cts → core-CeNTuqPz.d.cts} +15 -2
- package/dist/core.cjs +365 -279
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.mjs +363 -278
- package/dist/core.mjs.map +1 -1
- package/dist/index.cjs +375 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.mjs +373 -169
- package/dist/index.mjs.map +1 -1
- package/dist/{manager-B6NNV-E_.d.ts → manager-Bw8b1wSD.d.ts} +136 -21
- package/dist/{manager-BwjyFjjz.d.cts → manager-DNGk1YkR.d.cts} +136 -21
- package/dist/{metadata-BiTMMvlY.d.ts → metadata-C__KMeuz.d.ts} +1 -1
- package/dist/{metadata-HCflXcsF.d.cts → metadata-Dk4R8_-T.d.cts} +1 -1
- package/dist/smart-account.cjs +49 -44
- package/dist/smart-account.cjs.map +1 -1
- package/dist/smart-account.d.cts +17 -12
- package/dist/smart-account.d.ts +17 -12
- package/dist/smart-account.mjs +49 -44
- package/dist/smart-account.mjs.map +1 -1
- package/dist/wallet.cjs +54 -39
- package/dist/wallet.cjs.map +1 -1
- package/dist/wallet.d.cts +3 -3
- package/dist/wallet.d.ts +3 -3
- package/dist/wallet.mjs +54 -39
- package/dist/wallet.mjs.map +1 -1
- package/dist/widget.cjs +369 -170
- package/dist/widget.cjs.map +1 -1
- package/dist/widget.mjs +369 -169
- package/dist/widget.mjs.map +1 -1
- package/package.json +73 -5
package/dist/index.mjs
CHANGED
|
@@ -25,18 +25,16 @@ var init_defaults = __esm({
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
// src/types/config.ts
|
|
28
|
-
var DEFAULT_SLIPPAGE2, DEFAULT_AUTO_DETECT_PROVIDER2, DEFAULT_RETRY_CONFIG, DEFAULT_FEATURE_FLAGS;
|
|
28
|
+
var DEFAULT_SLIPPAGE2, DEFAULT_AUTO_DETECT_PROVIDER2, DEFAULT_RETRY_CONFIG, RATE_LIMIT_WAIT_BUDGET_MS, DEFAULT_FEATURE_FLAGS;
|
|
29
29
|
var init_config = __esm({
|
|
30
30
|
"src/types/config.ts"() {
|
|
31
31
|
"use strict";
|
|
32
32
|
DEFAULT_SLIPPAGE2 = 1;
|
|
33
33
|
DEFAULT_AUTO_DETECT_PROVIDER2 = false;
|
|
34
34
|
DEFAULT_RETRY_CONFIG = {
|
|
35
|
-
autoRetry: true,
|
|
36
|
-
maxRetries: 3,
|
|
37
|
-
baseDelayMs: 1e3,
|
|
38
35
|
approachingThreshold: 5
|
|
39
36
|
};
|
|
37
|
+
RATE_LIMIT_WAIT_BUDGET_MS = 1e4;
|
|
40
38
|
DEFAULT_FEATURE_FLAGS = {
|
|
41
39
|
tokensPagination: true,
|
|
42
40
|
balanceStreaming: false,
|
|
@@ -173,9 +171,6 @@ function resolveConfig(input) {
|
|
|
173
171
|
const theme = input.theme ?? "system";
|
|
174
172
|
const messages = deepMerge(DEFAULT_MESSAGES, input.messages);
|
|
175
173
|
const retry = {
|
|
176
|
-
autoRetry: input.retry?.autoRetry ?? DEFAULT_RETRY_CONFIG.autoRetry,
|
|
177
|
-
maxRetries: input.retry?.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
|
|
178
|
-
baseDelayMs: input.retry?.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
|
|
179
174
|
approachingThreshold: input.retry?.approachingThreshold ?? DEFAULT_RETRY_CONFIG.approachingThreshold,
|
|
180
175
|
onRateLimitInfo: input.retry?.onRateLimitInfo,
|
|
181
176
|
onRateLimited: input.retry?.onRateLimited,
|
|
@@ -442,6 +437,20 @@ var init_eipWallets = __esm({
|
|
|
442
437
|
"src/wallets/eipWallets.ts"() {
|
|
443
438
|
"use strict";
|
|
444
439
|
CHAIN_PARAMS = {
|
|
440
|
+
1: {
|
|
441
|
+
chainIdHex: "0x1",
|
|
442
|
+
chainName: "Ethereum",
|
|
443
|
+
rpcUrls: ["https://eth.llamarpc.com"],
|
|
444
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
445
|
+
blockExplorerUrls: ["https://etherscan.io"]
|
|
446
|
+
},
|
|
447
|
+
137: {
|
|
448
|
+
chainIdHex: "0x89",
|
|
449
|
+
chainName: "Polygon",
|
|
450
|
+
rpcUrls: ["https://polygon-rpc.com"],
|
|
451
|
+
nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
|
|
452
|
+
blockExplorerUrls: ["https://polygonscan.com"]
|
|
453
|
+
},
|
|
445
454
|
8453: {
|
|
446
455
|
chainIdHex: "0x2105",
|
|
447
456
|
chainName: "Base",
|
|
@@ -473,7 +482,7 @@ var init_constants = __esm({
|
|
|
473
482
|
"src/constants.ts"() {
|
|
474
483
|
"use strict";
|
|
475
484
|
SDK_NAME = "@trustware/sdk";
|
|
476
|
-
SDK_VERSION = "1.1.
|
|
485
|
+
SDK_VERSION = "1.1.11-staging.2";
|
|
477
486
|
API_ROOT = "https://bv-staging-api.trustware.io";
|
|
478
487
|
GTM_ID = "GTM-TZDGNCXB";
|
|
479
488
|
API_PREFIX = "/api";
|
|
@@ -517,6 +526,9 @@ async function assertOK(r) {
|
|
|
517
526
|
}
|
|
518
527
|
throw new Error(`HTTP ${r.status}: ${msg}`);
|
|
519
528
|
}
|
|
529
|
+
function isNotFoundError(err) {
|
|
530
|
+
return err instanceof Error && err.message.startsWith("HTTP 404");
|
|
531
|
+
}
|
|
520
532
|
async function validateSdkAccess() {
|
|
521
533
|
const r = await fetch(`${apiBase()}/sdk/validate`, {
|
|
522
534
|
method: "GET",
|
|
@@ -557,50 +569,54 @@ function notifyRateLimitCallbacks(info, isRateLimited, retryCount) {
|
|
|
557
569
|
retry.onRateLimitApproaching(info, retry.approachingThreshold);
|
|
558
570
|
}
|
|
559
571
|
}
|
|
560
|
-
function
|
|
561
|
-
if (
|
|
562
|
-
|
|
572
|
+
function serverDirectedWaitMs(info) {
|
|
573
|
+
if (!info) return null;
|
|
574
|
+
if (typeof info.retryAfter === "number" && info.retryAfter > 0) {
|
|
575
|
+
return info.retryAfter * 1e3;
|
|
563
576
|
}
|
|
564
|
-
|
|
577
|
+
if (typeof info.reset === "number" && info.reset > 0) {
|
|
578
|
+
const untilReset = info.reset * 1e3 - Date.now();
|
|
579
|
+
if (untilReset > 0) return untilReset;
|
|
580
|
+
}
|
|
581
|
+
return null;
|
|
565
582
|
}
|
|
566
583
|
function sleep(ms) {
|
|
567
584
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
568
585
|
}
|
|
569
|
-
async function
|
|
570
|
-
|
|
571
|
-
const cfg = TrustwareConfigStore.get();
|
|
572
|
-
if (!cfg.retry.autoRetry || skipRateLimit) {
|
|
573
|
-
return fetch(url, fetchOptions);
|
|
574
|
-
}
|
|
575
|
-
const { maxRetries, baseDelayMs } = cfg.retry;
|
|
586
|
+
async function withRateLimitRetry(attempt) {
|
|
587
|
+
let waitedMs = 0;
|
|
576
588
|
let retryCount = 0;
|
|
577
589
|
while (true) {
|
|
578
|
-
const response = await
|
|
590
|
+
const response = await attempt();
|
|
579
591
|
const rateLimitInfo = parseRateLimitHeaders(response);
|
|
580
|
-
if (response.status
|
|
592
|
+
if (response.status !== 429) {
|
|
581
593
|
if (rateLimitInfo) {
|
|
582
|
-
notifyRateLimitCallbacks(rateLimitInfo,
|
|
594
|
+
notifyRateLimitCallbacks(rateLimitInfo, false, 0);
|
|
583
595
|
}
|
|
584
|
-
|
|
585
|
-
throw new RateLimitError(
|
|
586
|
-
rateLimitInfo || { limit: 0, remaining: 0, reset: 0 },
|
|
587
|
-
true
|
|
588
|
-
);
|
|
589
|
-
}
|
|
590
|
-
const delay = calculateBackoffDelay(
|
|
591
|
-
baseDelayMs,
|
|
592
|
-
retryCount,
|
|
593
|
-
rateLimitInfo?.retryAfter
|
|
594
|
-
);
|
|
595
|
-
await sleep(delay);
|
|
596
|
-
retryCount++;
|
|
597
|
-
continue;
|
|
596
|
+
return response;
|
|
598
597
|
}
|
|
599
598
|
if (rateLimitInfo) {
|
|
600
|
-
notifyRateLimitCallbacks(rateLimitInfo,
|
|
599
|
+
notifyRateLimitCallbacks(rateLimitInfo, true, retryCount);
|
|
601
600
|
}
|
|
602
|
-
|
|
601
|
+
const waitMs = serverDirectedWaitMs(rateLimitInfo);
|
|
602
|
+
const info = rateLimitInfo || { limit: 0, remaining: 0, reset: 0 };
|
|
603
|
+
if (waitMs === null) {
|
|
604
|
+
throw new RateLimitError(info, true);
|
|
605
|
+
}
|
|
606
|
+
if (waitedMs + waitMs > RATE_LIMIT_WAIT_BUDGET_MS) {
|
|
607
|
+
throw new RateLimitError(info, false);
|
|
608
|
+
}
|
|
609
|
+
await sleep(waitMs);
|
|
610
|
+
waitedMs += waitMs;
|
|
611
|
+
retryCount++;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
async function rateLimitedFetch(url, options = {}) {
|
|
615
|
+
const { skipRateLimit, ...fetchOptions } = options;
|
|
616
|
+
if (skipRateLimit) {
|
|
617
|
+
return fetch(url, fetchOptions);
|
|
603
618
|
}
|
|
619
|
+
return withRateLimitRetry(() => fetch(url, fetchOptions));
|
|
604
620
|
}
|
|
605
621
|
var RateLimitError;
|
|
606
622
|
var init_http = __esm({
|
|
@@ -608,9 +624,11 @@ var init_http = __esm({
|
|
|
608
624
|
"use strict";
|
|
609
625
|
init_constants();
|
|
610
626
|
init_config2();
|
|
627
|
+
init_config();
|
|
611
628
|
RateLimitError = class extends Error {
|
|
612
629
|
constructor(info, retriesExhausted) {
|
|
613
|
-
const
|
|
630
|
+
const seconds = info.retryAfter ?? (info.reset > 0 ? Math.max(0, Math.ceil((info.reset * 1e3 - Date.now()) / 1e3)) : null);
|
|
631
|
+
const message = seconds === null ? "Rate limit exceeded. The server did not say when to retry." : `Rate limit exceeded. Try again in ${seconds} seconds.`;
|
|
614
632
|
super(message);
|
|
615
633
|
this.name = "RateLimitError";
|
|
616
634
|
this.rateLimitInfo = info;
|
|
@@ -4514,6 +4532,19 @@ async function submitReceipt(intentId, txHash, sponsorshipRequestId, eoaAddress)
|
|
|
4514
4532
|
const j = await r.json();
|
|
4515
4533
|
return j.data;
|
|
4516
4534
|
}
|
|
4535
|
+
async function submitStepReceipt(intentId, stepIndex, txHash) {
|
|
4536
|
+
const r = await rateLimitedFetch(
|
|
4537
|
+
`${apiBase()}/v1/route-intent/${intentId}/steps/${stepIndex}/receipt`,
|
|
4538
|
+
{
|
|
4539
|
+
method: "POST",
|
|
4540
|
+
headers: jsonHeaders({ "Idempotency-Key": txHash }),
|
|
4541
|
+
body: JSON.stringify({ txHash })
|
|
4542
|
+
}
|
|
4543
|
+
);
|
|
4544
|
+
await assertOK(r);
|
|
4545
|
+
const j = await r.json();
|
|
4546
|
+
return j.data;
|
|
4547
|
+
}
|
|
4517
4548
|
async function getStatus(intentId) {
|
|
4518
4549
|
const r = await rateLimitedFetch(
|
|
4519
4550
|
`${apiBase()}/v1/route-intent/${intentId}/status`,
|
|
@@ -4523,7 +4554,18 @@ async function getStatus(intentId) {
|
|
|
4523
4554
|
);
|
|
4524
4555
|
await assertOK(r);
|
|
4525
4556
|
const j = await r.json();
|
|
4526
|
-
return j.data;
|
|
4557
|
+
return normalizeStatusPayload(j.data);
|
|
4558
|
+
}
|
|
4559
|
+
function normalizeStatusPayload(raw) {
|
|
4560
|
+
if (!raw || typeof raw !== "object") return raw;
|
|
4561
|
+
const wire = raw;
|
|
4562
|
+
const out = { ...wire };
|
|
4563
|
+
for (const [snake, camel] of Object.entries(STATUS_WIRE_TO_CAMEL)) {
|
|
4564
|
+
if (out[camel] !== void 0) continue;
|
|
4565
|
+
if (!(snake in wire)) continue;
|
|
4566
|
+
out[camel] = wire[snake];
|
|
4567
|
+
}
|
|
4568
|
+
return out;
|
|
4527
4569
|
}
|
|
4528
4570
|
async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } = {}) {
|
|
4529
4571
|
const t0 = Date.now();
|
|
@@ -4534,12 +4576,39 @@ async function pollStatus(intentId, { intervalMs = 2e3, timeoutMs = 5 * 6e4 } =
|
|
|
4534
4576
|
await new Promise((r) => setTimeout(r, intervalMs));
|
|
4535
4577
|
}
|
|
4536
4578
|
}
|
|
4579
|
+
var STATUS_WIRE_TO_CAMEL;
|
|
4537
4580
|
var init_routes = __esm({
|
|
4538
4581
|
"src/core/routes.ts"() {
|
|
4539
4582
|
"use strict";
|
|
4540
4583
|
init_http();
|
|
4541
4584
|
init_store();
|
|
4542
4585
|
init_address();
|
|
4586
|
+
STATUS_WIRE_TO_CAMEL = {
|
|
4587
|
+
intent_id: "intentId",
|
|
4588
|
+
from_address: "fromAddress",
|
|
4589
|
+
to_address: "toAddress",
|
|
4590
|
+
from_chain_id: "fromChainId",
|
|
4591
|
+
to_chain_id: "toChainId",
|
|
4592
|
+
source_tx_hash: "sourceTxHash",
|
|
4593
|
+
dest_tx_hash: "destTxHash",
|
|
4594
|
+
request_id: "requestId",
|
|
4595
|
+
provider_request_id: "providerRequestId",
|
|
4596
|
+
transaction_request: "transactionRequest",
|
|
4597
|
+
status_raw: "statusRaw",
|
|
4598
|
+
route_path: "routePath",
|
|
4599
|
+
route_status: "routeStatus",
|
|
4600
|
+
to_amount_wei: "toAmountWei",
|
|
4601
|
+
from_chain_block: "fromChainBlock",
|
|
4602
|
+
to_chain_block: "toChainBlock",
|
|
4603
|
+
from_chain_tx_url: "fromChainTxUrl",
|
|
4604
|
+
to_chain_tx_url: "toChainTxUrl",
|
|
4605
|
+
gas_status: "gasStatus",
|
|
4606
|
+
is_gmp_transaction: "isGMPTransaction",
|
|
4607
|
+
axelar_transaction_url: "axelarTransactionUrl",
|
|
4608
|
+
create_date: "createdDate",
|
|
4609
|
+
update_date: "updatedDate",
|
|
4610
|
+
time_spent_ms: "timeSpentMs"
|
|
4611
|
+
};
|
|
4543
4612
|
}
|
|
4544
4613
|
});
|
|
4545
4614
|
|
|
@@ -5088,7 +5157,7 @@ async function getBalances(chainRef, address, opts) {
|
|
|
5088
5157
|
if (cached) return cached;
|
|
5089
5158
|
}
|
|
5090
5159
|
const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
|
|
5091
|
-
const response = await
|
|
5160
|
+
const response = await rateLimitedFetch(url, {
|
|
5092
5161
|
method: "GET",
|
|
5093
5162
|
credentials: "omit",
|
|
5094
5163
|
headers: jsonHeaders()
|
|
@@ -5252,18 +5321,27 @@ async function waitForTxConfirmation(chainId, txHash) {
|
|
|
5252
5321
|
}
|
|
5253
5322
|
throw new Error("Timed out waiting for approval confirmation");
|
|
5254
5323
|
}
|
|
5255
|
-
|
|
5324
|
+
function requiredApprovalAmount(planAmountWei, routeAmountWei) {
|
|
5325
|
+
if (planAmountWei >= UNLIMITED_APPROVAL_FLOOR && routeAmountWei !== void 0 && routeAmountWei > 0n) {
|
|
5326
|
+
return routeAmountWei;
|
|
5327
|
+
}
|
|
5328
|
+
return planAmountWei;
|
|
5329
|
+
}
|
|
5330
|
+
function approvalSatisfied(currentAllowance, requiredWei) {
|
|
5331
|
+
if (requiredWei === 0n) return currentAllowance === 0n;
|
|
5332
|
+
return currentAllowance >= requiredWei;
|
|
5333
|
+
}
|
|
5334
|
+
async function ensureApprovals(w, approvals, fallbackChainId, intentId, routeAmountWei) {
|
|
5256
5335
|
if (!approvals || approvals.length === 0) return;
|
|
5257
5336
|
const owner = await w.getAddress();
|
|
5258
|
-
for (const approval of approvals) {
|
|
5337
|
+
for (const [stepIndex, approval] of approvals.entries()) {
|
|
5259
5338
|
const spender = approval.spender;
|
|
5260
5339
|
const tokenAddress = approval.tokenAddress;
|
|
5261
5340
|
const amount = approval.amount;
|
|
5262
5341
|
if (!spender || !tokenAddress || !amount) continue;
|
|
5263
5342
|
const chainId = approval.chainId || String(fallbackChainId ?? "");
|
|
5264
5343
|
if (!chainId) continue;
|
|
5265
|
-
const amountWei = BigInt(amount);
|
|
5266
|
-
if (amountWei === 0n) continue;
|
|
5344
|
+
const amountWei = requiredApprovalAmount(BigInt(amount), routeAmountWei);
|
|
5267
5345
|
let currentAllowance = 0n;
|
|
5268
5346
|
try {
|
|
5269
5347
|
const { allowance } = await getEVMAllowance({
|
|
@@ -5275,7 +5353,7 @@ async function ensureApprovals(w, approvals, fallbackChainId) {
|
|
|
5275
5353
|
currentAllowance = BigInt(allowance || "0");
|
|
5276
5354
|
} catch {
|
|
5277
5355
|
}
|
|
5278
|
-
if (currentAllowance
|
|
5356
|
+
if (approvalSatisfied(currentAllowance, amountWei)) continue;
|
|
5279
5357
|
const data = encodeFunctionData({
|
|
5280
5358
|
abi: erc20ApproveAbi,
|
|
5281
5359
|
functionName: "approve",
|
|
@@ -5287,6 +5365,10 @@ async function ensureApprovals(w, approvals, fallbackChainId) {
|
|
|
5287
5365
|
value: 0n,
|
|
5288
5366
|
chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
|
|
5289
5367
|
});
|
|
5368
|
+
if (intentId) {
|
|
5369
|
+
void submitStepReceipt(intentId, stepIndex, hash).catch(() => {
|
|
5370
|
+
});
|
|
5371
|
+
}
|
|
5290
5372
|
await waitForTxConfirmation(chainId, hash);
|
|
5291
5373
|
}
|
|
5292
5374
|
}
|
|
@@ -5296,7 +5378,7 @@ function isUserRejected(e2) {
|
|
|
5296
5378
|
const msg = String(e2?.message || e2)?.toLowerCase?.() || "";
|
|
5297
5379
|
return msg.includes("user rejected") || msg.includes("user denied");
|
|
5298
5380
|
}
|
|
5299
|
-
async function sendRouteTransaction(b, fallbackChainId) {
|
|
5381
|
+
async function sendRouteTransaction(b, fallbackChainId, options) {
|
|
5300
5382
|
const w = walletManager.wallet;
|
|
5301
5383
|
if (!w) throw new Error("Trustware.wallet not configured");
|
|
5302
5384
|
const txReq = b.txReq;
|
|
@@ -5323,11 +5405,13 @@ async function sendRouteTransaction(b, fallbackChainId) {
|
|
|
5323
5405
|
}
|
|
5324
5406
|
}
|
|
5325
5407
|
}
|
|
5326
|
-
if (!validatedSponsorship) {
|
|
5408
|
+
if (!validatedSponsorship && !options?.approvalsEnsured) {
|
|
5327
5409
|
await ensureApprovals(
|
|
5328
5410
|
w,
|
|
5329
5411
|
b.route?.execution?.approvals,
|
|
5330
|
-
Number.isFinite(target) ? target : void 0
|
|
5412
|
+
Number.isFinite(target) ? target : void 0,
|
|
5413
|
+
b.intentId,
|
|
5414
|
+
BigInt(b.route?.estimate?.fromAmount ?? "0")
|
|
5331
5415
|
);
|
|
5332
5416
|
}
|
|
5333
5417
|
if (w.type === "eip1193") {
|
|
@@ -5426,7 +5510,7 @@ async function runTopUp(params) {
|
|
|
5426
5510
|
}
|
|
5427
5511
|
}
|
|
5428
5512
|
}
|
|
5429
|
-
var erc20ApproveAbi;
|
|
5513
|
+
var erc20ApproveAbi, UNLIMITED_APPROVAL_FLOOR;
|
|
5430
5514
|
var init_tx = __esm({
|
|
5431
5515
|
"src/core/tx.ts"() {
|
|
5432
5516
|
"use strict";
|
|
@@ -5436,6 +5520,7 @@ var init_tx = __esm({
|
|
|
5436
5520
|
erc20ApproveAbi = parseAbi([
|
|
5437
5521
|
"function approve(address spender, uint256 amount) returns (bool)"
|
|
5438
5522
|
]);
|
|
5523
|
+
UNLIMITED_APPROVAL_FLOOR = 1n << 255n;
|
|
5439
5524
|
}
|
|
5440
5525
|
});
|
|
5441
5526
|
|
|
@@ -7575,6 +7660,7 @@ var init_core = __esm({
|
|
|
7575
7660
|
init_store();
|
|
7576
7661
|
init_wallets();
|
|
7577
7662
|
init_routes();
|
|
7663
|
+
init_routes();
|
|
7578
7664
|
init_balances();
|
|
7579
7665
|
init_tx();
|
|
7580
7666
|
init_http();
|
|
@@ -7709,6 +7795,7 @@ var init_core = __esm({
|
|
|
7709
7795
|
buildRoute,
|
|
7710
7796
|
buildDepositAddress,
|
|
7711
7797
|
submitReceipt,
|
|
7798
|
+
submitStepReceipt,
|
|
7712
7799
|
getStatus,
|
|
7713
7800
|
pollStatus,
|
|
7714
7801
|
getBalances,
|
|
@@ -8182,12 +8269,9 @@ function useTrustwareConfig() {
|
|
|
8182
8269
|
title: "Trustware SDK",
|
|
8183
8270
|
description: "Seamlessly bridge assets across chains with Trustware."
|
|
8184
8271
|
},
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
baseDelayMs: 1e3,
|
|
8189
|
-
approachingThreshold: 5
|
|
8190
|
-
},
|
|
8272
|
+
// Shared with the resolver rather than restated, so this placeholder
|
|
8273
|
+
// can't drift from the real defaults.
|
|
8274
|
+
retry: { ...DEFAULT_RETRY_CONFIG },
|
|
8191
8275
|
features: {
|
|
8192
8276
|
tokensPagination: true,
|
|
8193
8277
|
balanceStreaming: false,
|
|
@@ -8212,6 +8296,7 @@ var init_useTrustwareConfig = __esm({
|
|
|
8212
8296
|
"src/hooks/useTrustwareConfig.ts"() {
|
|
8213
8297
|
"use strict";
|
|
8214
8298
|
"use client";
|
|
8299
|
+
init_config();
|
|
8215
8300
|
init_store();
|
|
8216
8301
|
}
|
|
8217
8302
|
});
|
|
@@ -8939,75 +9024,17 @@ var init_useTransactionSubmit = __esm({
|
|
|
8939
9024
|
|
|
8940
9025
|
// src/hooks/useGTM.ts
|
|
8941
9026
|
import { useEffect as useEffect11, useRef as useRef3, useCallback as useCallback8 } from "react";
|
|
8942
|
-
function
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
}
|
|
8951
|
-
}, []);
|
|
8952
|
-
useEffect11(() => {
|
|
8953
|
-
if (!isGA4Allowed()) {
|
|
8954
|
-
console.warn(
|
|
8955
|
-
"useGTM: GA4 tracking is disabled or Trustware config not initialized."
|
|
8956
|
-
);
|
|
8957
|
-
return;
|
|
8958
|
-
}
|
|
8959
|
-
if (!gtmId || typeof gtmId !== "string") {
|
|
8960
|
-
console.error(
|
|
8961
|
-
"useGTM: A valid GTM Container ID is required (format: GTM-XXXXX)."
|
|
8962
|
-
);
|
|
8963
|
-
return;
|
|
8964
|
-
}
|
|
8965
|
-
if (isInitialized.current) return;
|
|
8966
|
-
const alreadyLoaded = document.querySelector(
|
|
8967
|
-
`script[src*="googletagmanager.com/gtm.js?id=${gtmId}"]`
|
|
8968
|
-
);
|
|
8969
|
-
if (alreadyLoaded) {
|
|
8970
|
-
window.dataLayer = window.dataLayer || [];
|
|
8971
|
-
isInitialized.current = true;
|
|
8972
|
-
return;
|
|
8973
|
-
}
|
|
8974
|
-
window.dataLayer = window.dataLayer || [];
|
|
8975
|
-
window.dataLayer.push({
|
|
8976
|
-
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
8977
|
-
event: "gtm.js"
|
|
8978
|
-
});
|
|
8979
|
-
const firstScript = document.getElementsByTagName("script")[0];
|
|
8980
|
-
const script = document.createElement("script");
|
|
8981
|
-
script.async = true;
|
|
8982
|
-
script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
8983
|
-
firstScript.parentNode?.insertBefore(script, firstScript);
|
|
8984
|
-
scriptRef.current = script;
|
|
8985
|
-
isInitialized.current = true;
|
|
8986
|
-
return () => {
|
|
8987
|
-
if (scriptRef.current) {
|
|
8988
|
-
scriptRef.current.parentNode?.removeChild(scriptRef.current);
|
|
8989
|
-
scriptRef.current = null;
|
|
8990
|
-
}
|
|
8991
|
-
isInitialized.current = false;
|
|
8992
|
-
};
|
|
8993
|
-
}, [gtmId, isGA4Allowed]);
|
|
8994
|
-
const addNoscriptIframe = useCallback8(() => {
|
|
8995
|
-
if (!isGA4Allowed()) return;
|
|
8996
|
-
if (document.querySelector('iframe[src*="googletagmanager.com/ns.html"]'))
|
|
8997
|
-
return;
|
|
8998
|
-
const noscript = document.createElement("noscript");
|
|
8999
|
-
const iframe = document.createElement("iframe");
|
|
9000
|
-
iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;
|
|
9001
|
-
iframe.height = "0";
|
|
9002
|
-
iframe.width = "0";
|
|
9003
|
-
iframe.style.display = "none";
|
|
9004
|
-
iframe.style.visibility = "hidden";
|
|
9005
|
-
noscript.appendChild(iframe);
|
|
9006
|
-
document.body.insertBefore(noscript, document.body.firstChild);
|
|
9007
|
-
}, [gtmId, isGA4Allowed]);
|
|
9027
|
+
function isGA4Allowed() {
|
|
9028
|
+
try {
|
|
9029
|
+
return Trustware.getConfig().features.shouldAllowGA4;
|
|
9030
|
+
} catch {
|
|
9031
|
+
return false;
|
|
9032
|
+
}
|
|
9033
|
+
}
|
|
9034
|
+
function useGTMTracker() {
|
|
9008
9035
|
const trackEvent = useCallback8(
|
|
9009
9036
|
(eventName, eventParams = {}) => {
|
|
9010
|
-
if (!
|
|
9037
|
+
if (!isContainerInitialized) {
|
|
9011
9038
|
console.warn(
|
|
9012
9039
|
"useGTM: Not initialized. Ensure a valid GTM Container ID was provided."
|
|
9013
9040
|
);
|
|
@@ -9034,7 +9061,7 @@ function useGTM(gtmId) {
|
|
|
9034
9061
|
);
|
|
9035
9062
|
const setUserProperty = useCallback8(
|
|
9036
9063
|
(propertyName, value) => {
|
|
9037
|
-
if (!
|
|
9064
|
+
if (!isContainerInitialized) {
|
|
9038
9065
|
console.warn(
|
|
9039
9066
|
"useGTM: Not initialized. Ensure a valid GTM Container ID was provided."
|
|
9040
9067
|
);
|
|
@@ -9060,20 +9087,77 @@ function useGTM(gtmId) {
|
|
|
9060
9087
|
}
|
|
9061
9088
|
window.gtag(command, ...args);
|
|
9062
9089
|
},
|
|
9063
|
-
[
|
|
9090
|
+
[]
|
|
9064
9091
|
);
|
|
9065
|
-
return {
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9092
|
+
return { trackEvent, trackPageView, setUserProperty, directGtag };
|
|
9093
|
+
}
|
|
9094
|
+
function useGTM(gtmId) {
|
|
9095
|
+
const scriptRef = useRef3(null);
|
|
9096
|
+
const tracker = useGTMTracker();
|
|
9097
|
+
useEffect11(() => {
|
|
9098
|
+
if (!isGA4Allowed()) {
|
|
9099
|
+
console.warn(
|
|
9100
|
+
"useGTM: GA4 tracking is disabled or Trustware config not initialized."
|
|
9101
|
+
);
|
|
9102
|
+
return;
|
|
9103
|
+
}
|
|
9104
|
+
if (!gtmId || typeof gtmId !== "string") {
|
|
9105
|
+
console.error(
|
|
9106
|
+
"useGTM: A valid GTM Container ID is required (format: GTM-XXXXX)."
|
|
9107
|
+
);
|
|
9108
|
+
return;
|
|
9109
|
+
}
|
|
9110
|
+
if (isContainerInitialized) return;
|
|
9111
|
+
const alreadyLoaded = document.querySelector(
|
|
9112
|
+
`script[src*="googletagmanager.com/gtm.js?id=${gtmId}"]`
|
|
9113
|
+
);
|
|
9114
|
+
if (alreadyLoaded) {
|
|
9115
|
+
window.dataLayer = window.dataLayer || [];
|
|
9116
|
+
isContainerInitialized = true;
|
|
9117
|
+
return;
|
|
9118
|
+
}
|
|
9119
|
+
window.dataLayer = window.dataLayer || [];
|
|
9120
|
+
window.dataLayer.push({
|
|
9121
|
+
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
9122
|
+
event: "gtm.js"
|
|
9123
|
+
});
|
|
9124
|
+
const firstScript = document.getElementsByTagName("script")[0];
|
|
9125
|
+
const script = document.createElement("script");
|
|
9126
|
+
script.async = true;
|
|
9127
|
+
script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
9128
|
+
firstScript.parentNode?.insertBefore(script, firstScript);
|
|
9129
|
+
scriptRef.current = script;
|
|
9130
|
+
isContainerInitialized = true;
|
|
9131
|
+
return () => {
|
|
9132
|
+
if (scriptRef.current) {
|
|
9133
|
+
scriptRef.current.parentNode?.removeChild(scriptRef.current);
|
|
9134
|
+
scriptRef.current = null;
|
|
9135
|
+
}
|
|
9136
|
+
isContainerInitialized = false;
|
|
9137
|
+
};
|
|
9138
|
+
}, [gtmId]);
|
|
9139
|
+
const addNoscriptIframe = useCallback8(() => {
|
|
9140
|
+
if (!isGA4Allowed()) return;
|
|
9141
|
+
if (document.querySelector('iframe[src*="googletagmanager.com/ns.html"]'))
|
|
9142
|
+
return;
|
|
9143
|
+
const noscript = document.createElement("noscript");
|
|
9144
|
+
const iframe = document.createElement("iframe");
|
|
9145
|
+
iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;
|
|
9146
|
+
iframe.height = "0";
|
|
9147
|
+
iframe.width = "0";
|
|
9148
|
+
iframe.style.display = "none";
|
|
9149
|
+
iframe.style.visibility = "hidden";
|
|
9150
|
+
noscript.appendChild(iframe);
|
|
9151
|
+
document.body.insertBefore(noscript, document.body.firstChild);
|
|
9152
|
+
}, [gtmId]);
|
|
9153
|
+
return { ...tracker, addNoscriptIframe };
|
|
9072
9154
|
}
|
|
9155
|
+
var isContainerInitialized;
|
|
9073
9156
|
var init_useGTM = __esm({
|
|
9074
9157
|
"src/hooks/useGTM.ts"() {
|
|
9075
9158
|
"use strict";
|
|
9076
9159
|
init_core2();
|
|
9160
|
+
isContainerInitialized = false;
|
|
9077
9161
|
}
|
|
9078
9162
|
});
|
|
9079
9163
|
|
|
@@ -9100,7 +9184,7 @@ function useTransactionPolling() {
|
|
|
9100
9184
|
return void 0;
|
|
9101
9185
|
}
|
|
9102
9186
|
})();
|
|
9103
|
-
const { trackEvent } =
|
|
9187
|
+
const { trackEvent } = useGTMTracker();
|
|
9104
9188
|
const [state, setState] = useState13({
|
|
9105
9189
|
isPolling: false,
|
|
9106
9190
|
apiStatus: null,
|
|
@@ -9200,8 +9284,21 @@ function useTransactionPolling() {
|
|
|
9200
9284
|
pollCountRef.current += 1;
|
|
9201
9285
|
const pollInterval = pollCountRef.current <= 10 ? FAST_POLL_INTERVAL_MS : NORMAL_POLL_INTERVAL_MS;
|
|
9202
9286
|
pollingRef.current = setTimeout(poll, pollInterval);
|
|
9203
|
-
} catch {
|
|
9287
|
+
} catch (err) {
|
|
9204
9288
|
if (abortRef.current) return;
|
|
9289
|
+
if (isNotFoundError(err)) {
|
|
9290
|
+
clearPolling();
|
|
9291
|
+
const notFoundError = "Transaction session expired. Please try again.";
|
|
9292
|
+
setState((prev) => ({
|
|
9293
|
+
...prev,
|
|
9294
|
+
isPolling: false,
|
|
9295
|
+
error: notFoundError
|
|
9296
|
+
}));
|
|
9297
|
+
setErrorMessage(notFoundError);
|
|
9298
|
+
setTransactionStatus("error");
|
|
9299
|
+
setCurrentStep("error");
|
|
9300
|
+
return;
|
|
9301
|
+
}
|
|
9205
9302
|
const elapsed = Date.now() - startTimeRef.current;
|
|
9206
9303
|
if (elapsed > POLL_TIMEOUT_MS) {
|
|
9207
9304
|
clearPolling();
|
|
@@ -9337,10 +9434,10 @@ var init_useTransactionPolling = __esm({
|
|
|
9337
9434
|
"use strict";
|
|
9338
9435
|
"use client";
|
|
9339
9436
|
init_routes();
|
|
9437
|
+
init_http();
|
|
9340
9438
|
init_DepositContext();
|
|
9341
9439
|
init_provider();
|
|
9342
9440
|
init_core2();
|
|
9343
|
-
init_constants();
|
|
9344
9441
|
init_hooks();
|
|
9345
9442
|
FAST_POLL_INTERVAL_MS = 1500;
|
|
9346
9443
|
NORMAL_POLL_INTERVAL_MS = 2500;
|
|
@@ -30710,7 +30807,7 @@ import {
|
|
|
30710
30807
|
keccak256 as keccak2566,
|
|
30711
30808
|
stringToHex
|
|
30712
30809
|
} from "viem";
|
|
30713
|
-
async function
|
|
30810
|
+
async function fetchOnceWithTimeout(url, init) {
|
|
30714
30811
|
const controller = new AbortController();
|
|
30715
30812
|
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
30716
30813
|
try {
|
|
@@ -30731,6 +30828,9 @@ async function fetchWithTimeout(url, init) {
|
|
|
30731
30828
|
clearTimeout(timer);
|
|
30732
30829
|
}
|
|
30733
30830
|
}
|
|
30831
|
+
async function fetchWithTimeout(url, init) {
|
|
30832
|
+
return withRateLimitRetry(() => fetchOnceWithTimeout(url, init));
|
|
30833
|
+
}
|
|
30734
30834
|
function extractRevertHex(err) {
|
|
30735
30835
|
if (typeof err.data === "string" && err.data.startsWith("0x"))
|
|
30736
30836
|
return err.data;
|
|
@@ -31230,7 +31330,7 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
|
|
|
31230
31330
|
tokenUnitsPerDollar = Number(fromAmountWei) / fromUSD;
|
|
31231
31331
|
} else if (fromToken && fromDecimals !== void 0) {
|
|
31232
31332
|
try {
|
|
31233
|
-
const resp = await
|
|
31333
|
+
const resp = await rateLimitedFetch(
|
|
31234
31334
|
`${apiBase()}/v1/price/token?chainId=${cid}&address=${fromToken}`,
|
|
31235
31335
|
{ headers: jsonHeaders() }
|
|
31236
31336
|
);
|
|
@@ -31246,9 +31346,10 @@ async function estimateRelayFeeInToken(valueWei, fromAmountWei, fromAmountUSD, c
|
|
|
31246
31346
|
return 0n;
|
|
31247
31347
|
}
|
|
31248
31348
|
try {
|
|
31249
|
-
const resp = await
|
|
31250
|
-
|
|
31251
|
-
|
|
31349
|
+
const resp = await rateLimitedFetch(
|
|
31350
|
+
`${apiBase()}/v1/price/native?chainId=${cid}`,
|
|
31351
|
+
{ headers: jsonHeaders() }
|
|
31352
|
+
);
|
|
31252
31353
|
if (!resp.ok) throw new Error(`native price HTTP ${resp.status}`);
|
|
31253
31354
|
const json = await resp.json();
|
|
31254
31355
|
const ethPriceUSD = parseFloat(json.data?.priceUSD ?? "0");
|
|
@@ -31756,7 +31857,7 @@ function useTransactionActionModel({
|
|
|
31756
31857
|
}) {
|
|
31757
31858
|
const feeDataCacheRef = useRef13({});
|
|
31758
31859
|
const { isSubmitting, submitTransaction } = useTransactionSubmit();
|
|
31759
|
-
const { trackEvent } =
|
|
31860
|
+
const { trackEvent } = useGTMTracker();
|
|
31760
31861
|
const destinationConfig = (() => {
|
|
31761
31862
|
try {
|
|
31762
31863
|
return Trustware.getConfig();
|
|
@@ -32189,7 +32290,6 @@ var init_useTransactionActionModel = __esm({
|
|
|
32189
32290
|
init_chainHelpers();
|
|
32190
32291
|
init_utils();
|
|
32191
32292
|
init_hooks();
|
|
32192
|
-
init_constants();
|
|
32193
32293
|
}
|
|
32194
32294
|
});
|
|
32195
32295
|
|
|
@@ -33541,6 +33641,16 @@ async function waitForApprovalConfirmation(chainId, txHash) {
|
|
|
33541
33641
|
}
|
|
33542
33642
|
throw new Error("Timed out waiting for approval confirmation");
|
|
33543
33643
|
}
|
|
33644
|
+
async function requireActiveAddress(wallet, plannedFor) {
|
|
33645
|
+
if (!wallet) throw new Error("Wallet not connected. Please reconnect.");
|
|
33646
|
+
const active = await wallet.getAddress();
|
|
33647
|
+
if (active?.toLowerCase() !== plannedFor?.toLowerCase()) {
|
|
33648
|
+
throw new Error(
|
|
33649
|
+
"Wallet account changed. Please review and confirm the swap again."
|
|
33650
|
+
);
|
|
33651
|
+
}
|
|
33652
|
+
return active;
|
|
33653
|
+
}
|
|
33544
33654
|
function useSwapExecution(fromChain) {
|
|
33545
33655
|
const [state, setState] = useState29({
|
|
33546
33656
|
txStatus: "idle",
|
|
@@ -33597,7 +33707,15 @@ function useSwapExecution(fromChain) {
|
|
|
33597
33707
|
if (tx.status === "bridging") {
|
|
33598
33708
|
setState((p) => ({ ...p, txStatus: "bridging" }));
|
|
33599
33709
|
}
|
|
33600
|
-
} catch {
|
|
33710
|
+
} catch (err) {
|
|
33711
|
+
if (abortRef.current) return;
|
|
33712
|
+
if (isNotFoundError(err)) {
|
|
33713
|
+
clearPolling();
|
|
33714
|
+
const msg = "Transaction session expired. Please try again.";
|
|
33715
|
+
setState((p) => ({ ...p, txStatus: "error", errorMessage: msg }));
|
|
33716
|
+
onError(msg);
|
|
33717
|
+
return;
|
|
33718
|
+
}
|
|
33601
33719
|
}
|
|
33602
33720
|
if (abortRef.current) return;
|
|
33603
33721
|
pollCountRef.current += 1;
|
|
@@ -33623,24 +33741,55 @@ function useSwapExecution(fromChain) {
|
|
|
33623
33741
|
}
|
|
33624
33742
|
const txReq = routeResult.txReq;
|
|
33625
33743
|
const chainIdStr = String(txReq?.chainId ?? fromChain?.chainId ?? "");
|
|
33626
|
-
const spender = txReq?.to ?? txReq?.target;
|
|
33627
33744
|
const amountWei = BigInt(routeResult.route?.estimate?.fromAmount ?? "0");
|
|
33628
|
-
|
|
33745
|
+
const plannedApprovals = routeResult.route?.execution?.approvals ?? [];
|
|
33746
|
+
const toCheck = plannedApprovals.length ? plannedApprovals.flatMap((a) => {
|
|
33747
|
+
const token = a.tokenAddress ?? fromTokenAddress;
|
|
33748
|
+
const required = requiredApprovalAmount(
|
|
33749
|
+
BigInt(a.amount || "0"),
|
|
33750
|
+
amountWei
|
|
33751
|
+
);
|
|
33752
|
+
if (!token || !a.spender) return [];
|
|
33753
|
+
return [
|
|
33754
|
+
{
|
|
33755
|
+
chainId: a.chainId || chainIdStr,
|
|
33756
|
+
token,
|
|
33757
|
+
spender: a.spender,
|
|
33758
|
+
required
|
|
33759
|
+
}
|
|
33760
|
+
];
|
|
33761
|
+
}) : (() => {
|
|
33762
|
+
const spender = txReq?.to ?? txReq?.target;
|
|
33763
|
+
if (!spender) return [];
|
|
33764
|
+
return [
|
|
33765
|
+
{
|
|
33766
|
+
chainId: chainIdStr,
|
|
33767
|
+
token: fromTokenAddress,
|
|
33768
|
+
spender,
|
|
33769
|
+
required: amountWei
|
|
33770
|
+
}
|
|
33771
|
+
];
|
|
33772
|
+
})();
|
|
33773
|
+
if (toCheck.length === 0 || !chainIdStr || amountWei === 0n) {
|
|
33629
33774
|
setState((p) => ({ ...p, allowanceStatus: "unknown" }));
|
|
33630
33775
|
return;
|
|
33631
33776
|
}
|
|
33632
33777
|
setState((p) => ({ ...p, allowanceStatus: "checking" }));
|
|
33633
33778
|
try {
|
|
33634
|
-
const
|
|
33635
|
-
|
|
33636
|
-
|
|
33637
|
-
|
|
33638
|
-
|
|
33639
|
-
|
|
33640
|
-
|
|
33779
|
+
const results = await Promise.all(
|
|
33780
|
+
toCheck.map(async (c) => {
|
|
33781
|
+
const { allowance } = await getEVMAllowance({
|
|
33782
|
+
chainId: c.chainId,
|
|
33783
|
+
tokenAddress: c.token,
|
|
33784
|
+
ownerAddress: walletAddress,
|
|
33785
|
+
spenderAddress: c.spender
|
|
33786
|
+
});
|
|
33787
|
+
return approvalSatisfied(BigInt(allowance || "0"), c.required);
|
|
33788
|
+
})
|
|
33789
|
+
);
|
|
33641
33790
|
setState((p) => ({
|
|
33642
33791
|
...p,
|
|
33643
|
-
allowanceStatus:
|
|
33792
|
+
allowanceStatus: results.every(Boolean) ? "sufficient" : "needed"
|
|
33644
33793
|
}));
|
|
33645
33794
|
} catch {
|
|
33646
33795
|
setState((p) => ({ ...p, allowanceStatus: "needed" }));
|
|
@@ -33744,19 +33893,49 @@ function useSwapExecution(fromChain) {
|
|
|
33744
33893
|
}
|
|
33745
33894
|
}
|
|
33746
33895
|
try {
|
|
33747
|
-
|
|
33896
|
+
const plannedApprovals = routeResult.route?.execution?.approvals ?? [];
|
|
33897
|
+
const requiredApprovals = plannedApprovals.length ? plannedApprovals.flatMap((a, index) => {
|
|
33898
|
+
const token = a.tokenAddress ?? fromTokenAddress;
|
|
33899
|
+
const approvalSpender = a.spender;
|
|
33900
|
+
if (!token || !approvalSpender) return [];
|
|
33901
|
+
const amountWei = requiredApprovalAmount(
|
|
33902
|
+
BigInt(a.amount || "0"),
|
|
33903
|
+
fromAmountWei
|
|
33904
|
+
);
|
|
33905
|
+
return [
|
|
33906
|
+
{
|
|
33907
|
+
stepIndex: index,
|
|
33908
|
+
token,
|
|
33909
|
+
spender: approvalSpender,
|
|
33910
|
+
amountWei,
|
|
33911
|
+
chainId: a.chainId || chainIdStr
|
|
33912
|
+
}
|
|
33913
|
+
];
|
|
33914
|
+
}) : spender && fromTokenAddress ? [
|
|
33915
|
+
{
|
|
33916
|
+
stepIndex: null,
|
|
33917
|
+
token: fromTokenAddress,
|
|
33918
|
+
spender,
|
|
33919
|
+
amountWei: fromAmountWei,
|
|
33920
|
+
chainId: chainIdStr
|
|
33921
|
+
}
|
|
33922
|
+
] : [];
|
|
33923
|
+
const ownsApprovals = !isNative && !!walletAddress && !!chainIdStr;
|
|
33924
|
+
const activeAddress = ownsApprovals ? await requireActiveAddress(wallet, walletAddress) : void 0;
|
|
33925
|
+
for (const required of requiredApprovals) {
|
|
33926
|
+
if (!ownsApprovals) break;
|
|
33748
33927
|
let allowanceWei = 0n;
|
|
33749
33928
|
try {
|
|
33750
33929
|
const { allowance } = await getEVMAllowance({
|
|
33751
|
-
chainId:
|
|
33752
|
-
tokenAddress:
|
|
33753
|
-
ownerAddress:
|
|
33754
|
-
spenderAddress: spender
|
|
33930
|
+
chainId: required.chainId,
|
|
33931
|
+
tokenAddress: required.token,
|
|
33932
|
+
ownerAddress: activeAddress,
|
|
33933
|
+
spenderAddress: required.spender
|
|
33755
33934
|
});
|
|
33756
33935
|
allowanceWei = BigInt(allowance || "0");
|
|
33757
33936
|
} catch {
|
|
33758
33937
|
}
|
|
33759
|
-
if (allowanceWei
|
|
33938
|
+
if (!approvalSatisfied(allowanceWei, required.amountWei)) {
|
|
33760
33939
|
setState((p) => ({ ...p, txStatus: "approving" }));
|
|
33761
33940
|
if (!wallet || wallet.ecosystem !== "evm") {
|
|
33762
33941
|
throw new Error("EVM wallet required for token approval");
|
|
@@ -33764,7 +33943,7 @@ function useSwapExecution(fromChain) {
|
|
|
33764
33943
|
if (!chainIdStr || chainIdStr === "0") {
|
|
33765
33944
|
throw new Error("Invalid chain ID for token approval");
|
|
33766
33945
|
}
|
|
33767
|
-
const targetChain = Number(
|
|
33946
|
+
const targetChain = Number(required.chainId ?? txReq.chainId);
|
|
33768
33947
|
if (Number.isFinite(targetChain)) {
|
|
33769
33948
|
const current = await wallet.getChainId();
|
|
33770
33949
|
if (current !== targetChain) {
|
|
@@ -33776,18 +33955,18 @@ function useSwapExecution(fromChain) {
|
|
|
33776
33955
|
}
|
|
33777
33956
|
const approveAmount = maxApproval ? BigInt(
|
|
33778
33957
|
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
33779
|
-
) :
|
|
33958
|
+
) : required.amountWei;
|
|
33780
33959
|
const data = encodeFunctionData10({
|
|
33781
33960
|
abi: erc20Abi2,
|
|
33782
33961
|
functionName: "approve",
|
|
33783
|
-
args: [spender, approveAmount]
|
|
33962
|
+
args: [required.spender, approveAmount]
|
|
33784
33963
|
});
|
|
33785
33964
|
let approvalHash;
|
|
33786
33965
|
if (wallet.type === "eip1193") {
|
|
33787
33966
|
const from = await wallet.getAddress();
|
|
33788
33967
|
const params = {
|
|
33789
33968
|
from,
|
|
33790
|
-
to:
|
|
33969
|
+
to: required.token,
|
|
33791
33970
|
data,
|
|
33792
33971
|
value: "0x0"
|
|
33793
33972
|
};
|
|
@@ -33800,14 +33979,22 @@ function useSwapExecution(fromChain) {
|
|
|
33800
33979
|
});
|
|
33801
33980
|
} else {
|
|
33802
33981
|
const response = await wallet.sendTransaction({
|
|
33803
|
-
to:
|
|
33982
|
+
to: required.token,
|
|
33804
33983
|
data,
|
|
33805
33984
|
value: 0n,
|
|
33806
33985
|
chainId: Number.isFinite(targetChain) ? targetChain : void 0
|
|
33807
33986
|
});
|
|
33808
33987
|
approvalHash = response.hash;
|
|
33809
33988
|
}
|
|
33810
|
-
|
|
33989
|
+
if (required.stepIndex !== null) {
|
|
33990
|
+
void submitStepReceipt(
|
|
33991
|
+
routeResult.intentId,
|
|
33992
|
+
required.stepIndex,
|
|
33993
|
+
approvalHash
|
|
33994
|
+
).catch(() => {
|
|
33995
|
+
});
|
|
33996
|
+
}
|
|
33997
|
+
await waitForApprovalConfirmation(required.chainId, approvalHash);
|
|
33811
33998
|
setState((p) => ({
|
|
33812
33999
|
...p,
|
|
33813
34000
|
txStatus: "confirming",
|
|
@@ -33815,9 +34002,13 @@ function useSwapExecution(fromChain) {
|
|
|
33815
34002
|
}));
|
|
33816
34003
|
}
|
|
33817
34004
|
}
|
|
34005
|
+
if (ownsApprovals) {
|
|
34006
|
+
await requireActiveAddress(wallet, walletAddress);
|
|
34007
|
+
}
|
|
33818
34008
|
const hash = await Trustware.sendRouteTransaction(
|
|
33819
34009
|
routeResult,
|
|
33820
|
-
numericChainId
|
|
34010
|
+
numericChainId,
|
|
34011
|
+
{ approvalsEnsured: ownsApprovals }
|
|
33821
34012
|
);
|
|
33822
34013
|
try {
|
|
33823
34014
|
await submitReceipt(routeResult.intentId, hash);
|
|
@@ -33885,6 +34076,8 @@ var init_useSwapExecution = __esm({
|
|
|
33885
34076
|
"use client";
|
|
33886
34077
|
init_core2();
|
|
33887
34078
|
init_routes();
|
|
34079
|
+
init_http();
|
|
34080
|
+
init_tx();
|
|
33888
34081
|
init_sdkRpc();
|
|
33889
34082
|
init_chainHelpers();
|
|
33890
34083
|
FAST_POLL_MS = 1500;
|
|
@@ -33896,9 +34089,14 @@ var init_useSwapExecution = __esm({
|
|
|
33896
34089
|
|
|
33897
34090
|
// src/core/forex.ts
|
|
33898
34091
|
async function fetchForexRates(base2 = "USD") {
|
|
33899
|
-
|
|
33900
|
-
|
|
33901
|
-
|
|
34092
|
+
let r;
|
|
34093
|
+
try {
|
|
34094
|
+
r = await rateLimitedFetch(`${apiBase()}/v1/forex?base=${base2}`, {
|
|
34095
|
+
headers: jsonHeaders()
|
|
34096
|
+
});
|
|
34097
|
+
} catch {
|
|
34098
|
+
return {};
|
|
34099
|
+
}
|
|
33902
34100
|
if (!r.ok) return {};
|
|
33903
34101
|
const j = await r.json();
|
|
33904
34102
|
const rates = j?.data?.rates ?? j?.rates ?? j?.data ?? {};
|
|
@@ -39849,6 +40047,7 @@ function WidgetInner({
|
|
|
39849
40047
|
const { resolvedTheme } = useDepositUi();
|
|
39850
40048
|
const { status, revalidate, errors } = useTrustware();
|
|
39851
40049
|
const [showConfirmDialog, setShowConfirmDialog] = useState35(false);
|
|
40050
|
+
useGTM(GTM_ID);
|
|
39852
40051
|
const handleCloseRequest = useCallback23(() => {
|
|
39853
40052
|
if (ACTIVE_TRANSACTION_STATUSES.includes(transactionStatus)) {
|
|
39854
40053
|
setShowConfirmDialog(true);
|
|
@@ -39922,6 +40121,8 @@ var init_TrustwareWidgetV2 = __esm({
|
|
|
39922
40121
|
init_provider();
|
|
39923
40122
|
init_manager();
|
|
39924
40123
|
init_useTrustwareConfig();
|
|
40124
|
+
init_hooks();
|
|
40125
|
+
init_constants();
|
|
39925
40126
|
init_swap();
|
|
39926
40127
|
widgetContentContainerStyle = {
|
|
39927
40128
|
position: "relative",
|
|
@@ -40059,6 +40260,7 @@ var init_index = __esm({
|
|
|
40059
40260
|
"src/index.ts"() {
|
|
40060
40261
|
init_core2();
|
|
40061
40262
|
init_http();
|
|
40263
|
+
init_core2();
|
|
40062
40264
|
init_useWalletTokenState();
|
|
40063
40265
|
init_wallets();
|
|
40064
40266
|
init_widget();
|
|
@@ -40083,6 +40285,7 @@ export {
|
|
|
40083
40285
|
GTM_ID,
|
|
40084
40286
|
IdentityStore,
|
|
40085
40287
|
POPULAR_ORDER,
|
|
40288
|
+
RATE_LIMIT_WAIT_BUDGET_MS,
|
|
40086
40289
|
RateLimitError,
|
|
40087
40290
|
SDK_NAME,
|
|
40088
40291
|
SDK_VERSION,
|
|
@@ -40092,6 +40295,7 @@ export {
|
|
|
40092
40295
|
TrustwareWidgetV2 as TrustwareWidget,
|
|
40093
40296
|
WALLETCONNECT_PROJECT_ID,
|
|
40094
40297
|
WALLETS,
|
|
40298
|
+
assertValidPostHook,
|
|
40095
40299
|
buildWalletIdentityAddress,
|
|
40096
40300
|
connectDetectedWallet,
|
|
40097
40301
|
createWalletIdentity,
|