@trustware/sdk-staging 1.1.9-staging.7 → 1.1.10-staging.0

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/widget.cjs CHANGED
@@ -585,7 +585,7 @@ var init_constants = __esm({
585
585
  "src/constants.ts"() {
586
586
  "use strict";
587
587
  SDK_NAME = "@trustware/sdk";
588
- SDK_VERSION = "1.1.9-staging.7";
588
+ SDK_VERSION = "1.1.10-staging.0";
589
589
  API_ROOT = "https://bv-staging-api.trustware.io";
590
590
  GTM_ID = "GTM-TZDGNCXB";
591
591
  API_PREFIX = "/api";
@@ -2464,6 +2464,27 @@ var init_balances = __esm({
2464
2464
  });
2465
2465
 
2466
2466
  // src/core/routes.ts
2467
+ function assertValidPostHook(hooks) {
2468
+ const postHook = hooks?.postHook;
2469
+ if (!postHook) return;
2470
+ if (!postHook.target?.trim()) {
2471
+ throw new Error("hooks.postHook.target is required.");
2472
+ }
2473
+ if (!postHook.callData?.trim()) {
2474
+ throw new Error("hooks.postHook.callData is required.");
2475
+ }
2476
+ if (postHook.fullAmount) {
2477
+ if (postHook.amountInputPos === void 0) {
2478
+ throw new Error(
2479
+ "hooks.postHook.amountInputPos is required when fullAmount is true."
2480
+ );
2481
+ }
2482
+ } else if (!postHook.fundAmount?.trim()) {
2483
+ throw new Error(
2484
+ "hooks.postHook.fundAmount is required unless fullAmount is set."
2485
+ );
2486
+ }
2487
+ }
2467
2488
  function isEvmTxRequest(txReq) {
2468
2489
  return Boolean(txReq?.data && (txReq.to || txReq.target));
2469
2490
  }
@@ -2482,6 +2503,7 @@ async function buildRoute(body, signal) {
2482
2503
  if (!addressValidation.isValid) {
2483
2504
  throw new Error(addressValidation.error || "Invalid route addresses.");
2484
2505
  }
2506
+ assertValidPostHook(body.hooks);
2485
2507
  const cfg = TrustwareConfigStore.get();
2486
2508
  const url = `${apiBase()}/v1/routes/route`;
2487
2509
  const payload = {
@@ -2520,6 +2542,7 @@ async function buildRoute(body, signal) {
2520
2542
  return { intentId, txReq, actions, finalExchangeRate, route, sponsorship };
2521
2543
  }
2522
2544
  async function buildDepositAddress(body, signal) {
2545
+ assertValidPostHook(body.hooks);
2523
2546
  const cfg = TrustwareConfigStore.get();
2524
2547
  const url = `${apiBase()}/v1/routes/deposit-address`;
2525
2548
  const payload = {
@@ -9024,6 +9047,87 @@ function backendChainId(chain, fallback) {
9024
9047
  const preferred = chain?.networkIdentifier ?? chain?.chainId ?? chain?.id;
9025
9048
  return String(preferred ?? fallback ?? "");
9026
9049
  }
9050
+ function sleep2(ms) {
9051
+ return new Promise((resolve) => setTimeout(resolve, ms));
9052
+ }
9053
+ async function sendEvmTx(w, tx) {
9054
+ if (w.type === "eip1193") {
9055
+ const from = await w.getAddress();
9056
+ const params = {
9057
+ from,
9058
+ to: tx.to,
9059
+ data: tx.data,
9060
+ value: tx.value ? `0x${tx.value.toString(16)}` : "0x0"
9061
+ };
9062
+ if (tx.chainId !== void 0) {
9063
+ params.chainId = `0x${tx.chainId.toString(16)}`;
9064
+ }
9065
+ const hash = await w.request({
9066
+ method: "eth_sendTransaction",
9067
+ params: [params]
9068
+ });
9069
+ return hash;
9070
+ }
9071
+ const response = await w.sendTransaction({
9072
+ to: tx.to,
9073
+ data: tx.data,
9074
+ value: tx.value,
9075
+ chainId: tx.chainId
9076
+ });
9077
+ return response.hash;
9078
+ }
9079
+ async function waitForTxConfirmation(chainId, txHash) {
9080
+ const timeoutMs = 12e4;
9081
+ const intervalMs = 2e3;
9082
+ const started = Date.now();
9083
+ while (Date.now() - started < timeoutMs) {
9084
+ const status = await getEVMTxStatus({ chainId, txHash });
9085
+ if (status.status === "success") return;
9086
+ if (status.status === "reverted") {
9087
+ throw new Error("Approval transaction reverted");
9088
+ }
9089
+ await sleep2(intervalMs);
9090
+ }
9091
+ throw new Error("Timed out waiting for approval confirmation");
9092
+ }
9093
+ async function ensureApprovals(w, approvals, fallbackChainId) {
9094
+ if (!approvals || approvals.length === 0) return;
9095
+ const owner = await w.getAddress();
9096
+ for (const approval of approvals) {
9097
+ const spender = approval.spender;
9098
+ const tokenAddress = approval.tokenAddress;
9099
+ const amount = approval.amount;
9100
+ if (!spender || !tokenAddress || !amount) continue;
9101
+ const chainId = approval.chainId || String(fallbackChainId ?? "");
9102
+ if (!chainId) continue;
9103
+ const amountWei = BigInt(amount);
9104
+ if (amountWei === 0n) continue;
9105
+ let currentAllowance = 0n;
9106
+ try {
9107
+ const { allowance } = await getEVMAllowance({
9108
+ chainId,
9109
+ tokenAddress,
9110
+ ownerAddress: owner,
9111
+ spenderAddress: spender
9112
+ });
9113
+ currentAllowance = BigInt(allowance || "0");
9114
+ } catch {
9115
+ }
9116
+ if (currentAllowance >= amountWei) continue;
9117
+ const data = (0, import_viem2.encodeFunctionData)({
9118
+ abi: erc20ApproveAbi,
9119
+ functionName: "approve",
9120
+ args: [spender, amountWei]
9121
+ });
9122
+ const hash = await sendEvmTx(w, {
9123
+ to: tokenAddress,
9124
+ data,
9125
+ value: 0n,
9126
+ chainId: Number.isFinite(Number(chainId)) ? Number(chainId) : void 0
9127
+ });
9128
+ await waitForTxConfirmation(chainId, hash);
9129
+ }
9130
+ }
9027
9131
  function isUserRejected(e2) {
9028
9132
  const code = e2?.code ?? e2?.data?.code;
9029
9133
  if (code === 4001) return true;
@@ -9057,6 +9161,13 @@ async function sendRouteTransaction(b, fallbackChainId) {
9057
9161
  }
9058
9162
  }
9059
9163
  }
9164
+ if (!validatedSponsorship) {
9165
+ await ensureApprovals(
9166
+ w,
9167
+ b.route?.execution?.approvals,
9168
+ Number.isFinite(target) ? target : void 0
9169
+ );
9170
+ }
9060
9171
  if (w.type === "eip1193") {
9061
9172
  const from = await w.getAddress();
9062
9173
  const hexValue = value ? `0x${value.toString(16)}` : "0x0";
@@ -9153,13 +9264,17 @@ async function runTopUp(params) {
9153
9264
  }
9154
9265
  }
9155
9266
  }
9156
- var import_viem2;
9267
+ var import_viem2, erc20ApproveAbi;
9157
9268
  var init_tx = __esm({
9158
9269
  "src/core/tx.ts"() {
9159
9270
  "use strict";
9160
9271
  init_wallets();
9161
9272
  init_routes();
9273
+ init_sdkRpc();
9162
9274
  import_viem2 = require("viem");
9275
+ erc20ApproveAbi = (0, import_viem2.parseAbi)([
9276
+ "function approve(address spender, uint256 amount) returns (bool)"
9277
+ ]);
9163
9278
  }
9164
9279
  });
9165
9280
 
@@ -31517,7 +31632,7 @@ function normalizeTokenAddressForCompare(chain, addr) {
31517
31632
  if (chainType === "solana") return value;
31518
31633
  return value.toLowerCase();
31519
31634
  }
31520
- function sleep2(ms) {
31635
+ function sleep3(ms) {
31521
31636
  return new Promise((resolve) => setTimeout(resolve, ms));
31522
31637
  }
31523
31638
  function useTransactionActionModel({
@@ -31635,7 +31750,7 @@ function useTransactionActionModel({
31635
31750
  if (status.status === "reverted") {
31636
31751
  throw new Error("Approval transaction reverted");
31637
31752
  }
31638
- await sleep2(intervalMs);
31753
+ await sleep3(intervalMs);
31639
31754
  }
31640
31755
  throw new Error("Timed out waiting for approval confirmation");
31641
31756
  },
@@ -33300,7 +33415,7 @@ function normalizeTx(raw) {
33300
33415
  toChainTxUrl: r.toChainTxUrl || r.to_chain_tx_url || void 0
33301
33416
  };
33302
33417
  }
33303
- function sleep3(ms) {
33418
+ function sleep4(ms) {
33304
33419
  return new Promise((resolve) => setTimeout(resolve, ms));
33305
33420
  }
33306
33421
  function isUserRejection(err) {
@@ -33318,7 +33433,7 @@ async function waitForApprovalConfirmation(chainId, txHash) {
33318
33433
  if (status.status === "success") return;
33319
33434
  if (status.status === "reverted")
33320
33435
  throw new Error("Approval transaction reverted");
33321
- await sleep3(2e3);
33436
+ await sleep4(2e3);
33322
33437
  }
33323
33438
  throw new Error("Timed out waiting for approval confirmation");
33324
33439
  }