@defuse-protocol/intents-sdk 0.43.3 → 0.45.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.
Files changed (94) hide show
  1. package/README.md +143 -21
  2. package/dist/index.cjs +19 -18
  3. package/dist/index.d.cts +5 -3
  4. package/dist/index.d.ts +5 -3
  5. package/dist/index.js +7 -5
  6. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.cjs +5 -5
  7. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.cjs +24 -12
  8. package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.js +19 -7
  9. package/dist/src/bridges/direct-bridge/direct-bridge-utils.cjs +5 -5
  10. package/dist/src/bridges/direct-bridge/direct-bridge.cjs +22 -10
  11. package/dist/src/bridges/direct-bridge/direct-bridge.js +16 -4
  12. package/dist/src/bridges/direct-bridge/error.cjs +2 -2
  13. package/dist/src/bridges/hot-bridge/error.cjs +4 -26
  14. package/dist/src/bridges/hot-bridge/error.d.cts +1 -17
  15. package/dist/src/bridges/hot-bridge/error.d.ts +1 -17
  16. package/dist/src/bridges/hot-bridge/error.js +1 -21
  17. package/dist/src/bridges/hot-bridge/hot-bridge-chains.cjs +3 -1
  18. package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.cts +1 -1
  19. package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.ts +1 -1
  20. package/dist/src/bridges/hot-bridge/hot-bridge-chains.js +3 -1
  21. package/dist/src/bridges/hot-bridge/hot-bridge-utils.cjs +17 -12
  22. package/dist/src/bridges/hot-bridge/hot-bridge-utils.js +7 -2
  23. package/dist/src/bridges/hot-bridge/hot-bridge.cjs +46 -32
  24. package/dist/src/bridges/hot-bridge/hot-bridge.js +38 -24
  25. package/dist/src/bridges/intents-bridge/intents-bridge.cjs +18 -4
  26. package/dist/src/bridges/intents-bridge/intents-bridge.js +18 -4
  27. package/dist/src/bridges/omni-bridge/error.cjs +6 -27
  28. package/dist/src/bridges/omni-bridge/error.d.cts +1 -16
  29. package/dist/src/bridges/omni-bridge/error.d.ts +1 -16
  30. package/dist/src/bridges/omni-bridge/error.js +1 -20
  31. package/dist/src/bridges/omni-bridge/omni-bridge-utils.cjs +12 -7
  32. package/dist/src/bridges/omni-bridge/omni-bridge-utils.js +5 -1
  33. package/dist/src/bridges/omni-bridge/omni-bridge.cjs +72 -54
  34. package/dist/src/bridges/omni-bridge/omni-bridge.js +47 -29
  35. package/dist/src/bridges/poa-bridge/poa-bridge-utils.cjs +2 -2
  36. package/dist/src/bridges/poa-bridge/poa-bridge.cjs +79 -26
  37. package/dist/src/bridges/poa-bridge/poa-bridge.js +66 -13
  38. package/dist/src/classes/errors.cjs +7 -7
  39. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.cjs +17 -0
  40. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.cts +12 -0
  41. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.ts +12 -0
  42. package/dist/src/constants/poa-tokens-routable-through-omni-bridge.js +16 -0
  43. package/dist/src/constants/public-rpc-urls.cjs +3 -1
  44. package/dist/src/constants/public-rpc-urls.js +3 -1
  45. package/dist/src/constants/withdrawal-timing.cjs +57 -0
  46. package/dist/src/constants/withdrawal-timing.js +56 -0
  47. package/dist/src/core/withdrawal-watcher.cjs +83 -0
  48. package/dist/src/core/withdrawal-watcher.d.cts +18 -0
  49. package/dist/src/core/withdrawal-watcher.d.ts +18 -0
  50. package/dist/src/core/withdrawal-watcher.js +79 -0
  51. package/dist/src/intents/expirable-nonce.cjs +3 -3
  52. package/dist/src/intents/intent-executer-impl/intent-executer.cjs +7 -4
  53. package/dist/src/intents/intent-executer-impl/intent-executer.js +5 -2
  54. package/dist/src/intents/intent-hash.cjs +2 -2
  55. package/dist/src/intents/intent-hashes/erc191.cjs +2 -2
  56. package/dist/src/intents/intent-hashes/nep413.cjs +2 -2
  57. package/dist/src/intents/intent-hashes/raw-ed25519.cjs +2 -2
  58. package/dist/src/intents/intent-hashes/sep53.cjs +4 -4
  59. package/dist/src/intents/intent-hashes/tip191.cjs +2 -2
  60. package/dist/src/intents/intent-hashes/ton-connect.cjs +2 -2
  61. package/dist/src/intents/intent-hashes/webauthn.cjs +2 -2
  62. package/dist/src/intents/intent-payload-builder.cjs +4 -4
  63. package/dist/src/intents/intent-relayer-impl/intent-relayer-public.cjs +7 -7
  64. package/dist/src/intents/intent-relayer-impl/intent-relayer-public.js +1 -1
  65. package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.cjs +2 -2
  66. package/dist/src/intents/intent-signer-impl/intent-signer-nep413.cjs +3 -3
  67. package/dist/src/intents/intent-signer-impl/intent-signer-viem.cjs +3 -3
  68. package/dist/src/intents/interfaces/intent-relayer.d.cts +2 -1
  69. package/dist/src/intents/interfaces/intent-relayer.d.ts +2 -1
  70. package/dist/src/intents/salt-manager.cjs +5 -5
  71. package/dist/src/lib/array.cjs +2 -2
  72. package/dist/src/lib/caip2.cjs +7 -5
  73. package/dist/src/lib/caip2.d.cts +2 -0
  74. package/dist/src/lib/caip2.d.ts +2 -0
  75. package/dist/src/lib/caip2.js +3 -1
  76. package/dist/src/lib/configure-rpc-config.cjs +3 -3
  77. package/dist/src/lib/estimate-fee.cjs +6 -6
  78. package/dist/src/lib/parse-defuse-asset-id.cjs +2 -2
  79. package/dist/src/lib/route-config-factory.cjs +2 -5
  80. package/dist/src/lib/route-config-factory.d.cts +1 -1
  81. package/dist/src/lib/route-config-factory.d.ts +1 -1
  82. package/dist/src/lib/route-config-factory.js +2 -5
  83. package/dist/src/lib/tokensUsdPricesHttpClient/apis.cjs +3 -3
  84. package/dist/src/lib/validateAddress.cjs +21 -19
  85. package/dist/src/lib/validateAddress.js +3 -1
  86. package/dist/src/sdk.cjs +96 -47
  87. package/dist/src/sdk.d.cts +72 -11
  88. package/dist/src/sdk.d.ts +72 -11
  89. package/dist/src/sdk.js +85 -36
  90. package/dist/src/shared-types.d.cts +49 -15
  91. package/dist/src/shared-types.d.ts +49 -15
  92. package/package.json +3 -5
  93. package/dist/src/lib/route-config.cjs +0 -19
  94. package/dist/src/lib/route-config.js +0 -19
@@ -1,26 +1,31 @@
1
+ import { InvalidDestinationAddressForWithdrawalError, MinWithdrawalAmountError, UnsupportedAssetIdError } from "../../classes/errors.js";
1
2
  import { RouteEnum } from "../../constants/route-enum.js";
2
3
  import { getUnderlyingFee } from "../../lib/estimate-fee.js";
3
- import { InvalidDestinationAddressForWithdrawalError, MinWithdrawalAmountError, UnsupportedAssetIdError } from "../../classes/errors.js";
4
4
  import { parseDefuseAssetId } from "../../lib/parse-defuse-asset-id.js";
5
5
  import { validateAddress } from "../../lib/validateAddress.js";
6
6
  import { BridgeNameEnum } from "../../constants/bridge-name-enum.js";
7
+ import { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE } from "../../constants/poa-tokens-routable-through-omni-bridge.js";
7
8
  import { contractIdToCaip2, createWithdrawIntentPrimitive, toPoaNetwork } from "./poa-bridge-utils.js";
8
- import { assert, configsByEnvironment, poaBridge, utils } from "@defuse-protocol/internal-utils";
9
+ import { RpcRequestError, assert, configsByEnvironment, poaBridge, utils } from "@defuse-protocol/internal-utils";
9
10
  import TTLCache from "@isaacs/ttlcache";
10
11
 
11
12
  //#region src/bridges/poa-bridge/poa-bridge.ts
12
13
  var PoaBridge = class {
13
- constructor({ env }) {
14
+ constructor({ env, routeMigratedPoaTokensThroughOmniBridge }) {
15
+ this.route = RouteEnum.PoaBridge;
14
16
  this.supportedTokensCache = new TTLCache({ ttl: 30 * 1e3 });
15
17
  this.env = env;
18
+ this.routeMigratedPoaTokensThroughOmniBridge = routeMigratedPoaTokensThroughOmniBridge ?? false;
16
19
  }
17
20
  is(routeConfig) {
18
21
  return routeConfig.route === RouteEnum.PoaBridge;
19
22
  }
20
23
  async supports(params) {
21
24
  if (params.routeConfig != null && !this.is(params.routeConfig)) return false;
22
- const isValid = this.parseAssetId(params.assetId) != null;
25
+ const assetInfo = this.parseAssetId(params.assetId);
26
+ const isValid = assetInfo != null;
23
27
  if (!isValid && params.routeConfig != null) throw new UnsupportedAssetIdError(params.assetId, "`assetId` does not match `routeConfig`.");
28
+ if (this.routeMigratedPoaTokensThroughOmniBridge && assetInfo != null && POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE[assetInfo.contractId] !== void 0 && params.routeConfig === void 0) return false;
24
29
  return isValid;
25
30
  }
26
31
  parseAssetId(assetId) {
@@ -84,15 +89,42 @@ var PoaBridge = class {
84
89
  underlyingFees: { [RouteEnum.PoaBridge]: { relayerFee } }
85
90
  };
86
91
  }
87
- async waitForWithdrawalCompletion(args) {
88
- return { hash: (await poaBridge.waitForWithdrawalCompletion({
89
- txHash: args.tx.hash,
90
- withdrawalCriteria: { assetId: args.withdrawalParams.assetId },
91
- signal: args.signal ?? new AbortController().signal,
92
- retryOptions: args.retryOptions,
93
- baseURL: configsByEnvironment[this.env].poaBridgeBaseURL,
94
- logger: args.logger
95
- })).destinationTxHash };
92
+ createWithdrawalIdentifier(args) {
93
+ const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
94
+ assert(assetInfo != null, "Asset is not supported");
95
+ return {
96
+ landingChain: assetInfo.blockchain,
97
+ index: args.index,
98
+ withdrawalParams: args.withdrawalParams,
99
+ tx: args.tx
100
+ };
101
+ }
102
+ async describeWithdrawal(args) {
103
+ const withdrawal = findMatchingWithdrawal((await this.getWithdrawalStatusWithRetry(args)).withdrawals, args.withdrawalParams.assetId);
104
+ if (withdrawal == null) return { status: "pending" };
105
+ if (withdrawal.status === "PENDING") return { status: "pending" };
106
+ if (withdrawal.status === "COMPLETED") return {
107
+ status: "completed",
108
+ txHash: withdrawal.data.transfer_tx_hash
109
+ };
110
+ return {
111
+ status: "failed",
112
+ reason: withdrawal.status
113
+ };
114
+ }
115
+ async getWithdrawalStatusWithRetry(args) {
116
+ const startTime = Date.now();
117
+ while (true) try {
118
+ return await poaBridge.httpClient.getWithdrawalStatus({ withdrawal_hash: args.tx.hash }, {
119
+ baseURL: configsByEnvironment[this.env].poaBridgeBaseURL,
120
+ logger: args.logger
121
+ });
122
+ } catch (err) {
123
+ if (!isWithdrawalNotFoundError(err)) throw err;
124
+ if (Date.now() - startTime >= NOT_FOUND_RETRY_TIMEOUT_MS) return { withdrawals: [] };
125
+ args.logger?.warn("Withdrawal not indexed yet, retrying...");
126
+ await sleep(NOT_FOUND_RETRY_INTERVAL_MS);
127
+ }
96
128
  }
97
129
  /**
98
130
  * Gets supported tokens with caching to avoid frequent API calls.
@@ -110,6 +142,27 @@ var PoaBridge = class {
110
142
  return data;
111
143
  }
112
144
  };
145
+ /**
146
+ * Finds a withdrawal matching the given assetId.
147
+ *
148
+ * NOTE: Currently only matches by assetId. This means multiple withdrawals
149
+ * of the same token in a single transaction are not supported.
150
+ * POA API doesn't currently support this case either. When support is added,
151
+ * matching could be done by sorting both API results and withdrawal params by
152
+ * amount (fees are equal for same token, so relative ordering is preserved).
153
+ */
154
+ function findMatchingWithdrawal(withdrawals, assetId) {
155
+ return withdrawals.find((w) => `nep141:${w.data.near_token_id}` === assetId);
156
+ }
157
+ const NOT_FOUND_RETRY_TIMEOUT_MS = 3 * 1e3;
158
+ const NOT_FOUND_RETRY_INTERVAL_MS = 1e3;
159
+ const RPC_ERR_MSG_WITHDRAWALS_NOT_FOUND = "Withdrawals not found";
160
+ function isWithdrawalNotFoundError(err) {
161
+ return err instanceof RpcRequestError && err.details === RPC_ERR_MSG_WITHDRAWALS_NOT_FOUND;
162
+ }
163
+ function sleep(ms) {
164
+ return new Promise((resolve) => setTimeout(resolve, ms));
165
+ }
113
166
 
114
167
  //#endregion
115
168
  export { PoaBridge };
@@ -1,8 +1,8 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- let __defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
2
+ let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
3
3
 
4
4
  //#region src/classes/errors.ts
5
- var FeeExceedsAmountError = class extends __defuse_protocol_internal_utils.BaseError {
5
+ var FeeExceedsAmountError = class extends _defuse_protocol_internal_utils.BaseError {
6
6
  constructor(feeEstimation, amount) {
7
7
  super("Amount too small to pay fee.", {
8
8
  metaMessages: [`Required fee: ${feeEstimation.amount}`, `Withdrawal amount: ${amount}`],
@@ -12,7 +12,7 @@ var FeeExceedsAmountError = class extends __defuse_protocol_internal_utils.BaseE
12
12
  this.amount = amount;
13
13
  }
14
14
  };
15
- var MinWithdrawalAmountError = class extends __defuse_protocol_internal_utils.BaseError {
15
+ var MinWithdrawalAmountError = class extends _defuse_protocol_internal_utils.BaseError {
16
16
  constructor(minAmount, requestedAmount, assetId) {
17
17
  super("Withdrawal amount is below minimum required by the bridge.", {
18
18
  metaMessages: [
@@ -27,7 +27,7 @@ var MinWithdrawalAmountError = class extends __defuse_protocol_internal_utils.Ba
27
27
  this.assetId = assetId;
28
28
  }
29
29
  };
30
- var UnsupportedDestinationMemoError = class extends __defuse_protocol_internal_utils.BaseError {
30
+ var UnsupportedDestinationMemoError = class extends _defuse_protocol_internal_utils.BaseError {
31
31
  constructor(blockchain, assetId) {
32
32
  super("Destination memo is not supported for this blockchain.", {
33
33
  details: "Destination memo is only supported for XRP Ledger withdrawals.",
@@ -38,7 +38,7 @@ var UnsupportedDestinationMemoError = class extends __defuse_protocol_internal_u
38
38
  this.assetId = assetId;
39
39
  }
40
40
  };
41
- var TrustlineNotFoundError = class extends __defuse_protocol_internal_utils.BaseError {
41
+ var TrustlineNotFoundError = class extends _defuse_protocol_internal_utils.BaseError {
42
42
  constructor(destinationAddress, assetId, blockchain, tokenAddress) {
43
43
  super("Destination address does not have a trustline for this asset.", {
44
44
  details: "The destination address must establish a trustline before receiving this asset.",
@@ -56,7 +56,7 @@ var TrustlineNotFoundError = class extends __defuse_protocol_internal_utils.Base
56
56
  this.tokenAddress = tokenAddress;
57
57
  }
58
58
  };
59
- var UnsupportedAssetIdError = class extends __defuse_protocol_internal_utils.BaseError {
59
+ var UnsupportedAssetIdError = class extends _defuse_protocol_internal_utils.BaseError {
60
60
  constructor(assetId, details) {
61
61
  super("Asset ID is not supported.", {
62
62
  details,
@@ -66,7 +66,7 @@ var UnsupportedAssetIdError = class extends __defuse_protocol_internal_utils.Bas
66
66
  this.assetId = assetId;
67
67
  }
68
68
  };
69
- var InvalidDestinationAddressForWithdrawalError = class extends __defuse_protocol_internal_utils.BaseError {
69
+ var InvalidDestinationAddressForWithdrawalError = class extends _defuse_protocol_internal_utils.BaseError {
70
70
  constructor(destinationAddress, destinationChain) {
71
71
  super(`Invalid destination address.`, {
72
72
  metaMessages: [`Destination address: ${destinationAddress}`, `Destination chain: ${destinationChain}`],
@@ -0,0 +1,17 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ let omni_bridge_sdk = require("omni-bridge-sdk");
3
+
4
+ //#region src/constants/poa-tokens-routable-through-omni-bridge.ts
5
+ /**
6
+ * These tokens can be routed through either PoA Bridge or Omni Bridge
7
+ * depending on the SDK configuration. Use the `routeMigratedPoaTokensThroughOmniBridge`
8
+ * feature flag to enable Omni Bridge routing for these tokens.
9
+ */
10
+ const POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE = {
11
+ "sol-57d087fd8c460f612f8701f5499ad8b2eec5ab68.omft.near": omni_bridge_sdk.ChainKind.Sol,
12
+ "sol-c58e6539c2f2e097c251f8edf11f9c03e581f8d4.omft.near": omni_bridge_sdk.ChainKind.Sol,
13
+ "sol-b9c68f94ec8fd160137af8cdfe5e61cd68e2afba.omft.near": omni_bridge_sdk.ChainKind.Sol
14
+ };
15
+
16
+ //#endregion
17
+ exports.POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE = POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE;
@@ -0,0 +1,12 @@
1
+ import { ChainKind } from "omni-bridge-sdk";
2
+
3
+ //#region src/constants/poa-tokens-routable-through-omni-bridge.d.ts
4
+
5
+ /**
6
+ * These tokens can be routed through either PoA Bridge or Omni Bridge
7
+ * depending on the SDK configuration. Use the `routeMigratedPoaTokensThroughOmniBridge`
8
+ * feature flag to enable Omni Bridge routing for these tokens.
9
+ */
10
+ declare const POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE: Record<string, ChainKind>;
11
+ //#endregion
12
+ export { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE };
@@ -0,0 +1,12 @@
1
+ import { ChainKind } from "omni-bridge-sdk";
2
+
3
+ //#region src/constants/poa-tokens-routable-through-omni-bridge.d.ts
4
+
5
+ /**
6
+ * These tokens can be routed through either PoA Bridge or Omni Bridge
7
+ * depending on the SDK configuration. Use the `routeMigratedPoaTokensThroughOmniBridge`
8
+ * feature flag to enable Omni Bridge routing for these tokens.
9
+ */
10
+ declare const POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE: Record<string, ChainKind>;
11
+ //#endregion
12
+ export { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE };
@@ -0,0 +1,16 @@
1
+ import { ChainKind } from "omni-bridge-sdk";
2
+
3
+ //#region src/constants/poa-tokens-routable-through-omni-bridge.ts
4
+ /**
5
+ * These tokens can be routed through either PoA Bridge or Omni Bridge
6
+ * depending on the SDK configuration. Use the `routeMigratedPoaTokensThroughOmniBridge`
7
+ * feature flag to enable Omni Bridge routing for these tokens.
8
+ */
9
+ const POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE = {
10
+ "sol-57d087fd8c460f612f8701f5499ad8b2eec5ab68.omft.near": ChainKind.Sol,
11
+ "sol-c58e6539c2f2e097c251f8edf11f9c03e581f8d4.omft.near": ChainKind.Sol,
12
+ "sol-b9c68f94ec8fd160137af8cdfe5e61cd68e2afba.omft.near": ChainKind.Sol
13
+ };
14
+
15
+ //#endregion
16
+ export { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE };
@@ -11,7 +11,9 @@ const PUBLIC_EVM_RPC_URLS = {
11
11
  [require_caip2.Chains.Optimism]: ["https://optimism-rpc.publicnode.com"],
12
12
  [require_caip2.Chains.Avalanche]: ["https://avalanche-c-chain-rpc.publicnode.com"],
13
13
  [require_caip2.Chains.LayerX]: ["https://rpc.xlayer.tech"],
14
- [require_caip2.Chains.Adi]: ["https://rpc.adifoundation.ai"]
14
+ [require_caip2.Chains.Adi]: ["https://rpc.adifoundation.ai"],
15
+ [require_caip2.Chains.Plasma]: ["https://rpc.plasma.to"],
16
+ [require_caip2.Chains.Scroll]: ["https://rpc.scroll.io"]
15
17
  };
16
18
  const PUBLIC_STELLAR_RPC_URLS = {
17
19
  soroban: ["https://mainnet.sorobanrpc.com"],
@@ -11,7 +11,9 @@ const PUBLIC_EVM_RPC_URLS = {
11
11
  [Chains.Optimism]: ["https://optimism-rpc.publicnode.com"],
12
12
  [Chains.Avalanche]: ["https://avalanche-c-chain-rpc.publicnode.com"],
13
13
  [Chains.LayerX]: ["https://rpc.xlayer.tech"],
14
- [Chains.Adi]: ["https://rpc.adifoundation.ai"]
14
+ [Chains.Adi]: ["https://rpc.adifoundation.ai"],
15
+ [Chains.Plasma]: ["https://rpc.plasma.to"],
16
+ [Chains.Scroll]: ["https://rpc.scroll.io"]
15
17
  };
16
18
  const PUBLIC_STELLAR_RPC_URLS = {
17
19
  soroban: ["https://mainnet.sorobanrpc.com"],
@@ -0,0 +1,57 @@
1
+
2
+ //#region src/constants/withdrawal-timing.ts
3
+ /**
4
+ * Withdrawal timing p99 values (in seconds) by CAIP-2 chain identifier.
5
+ * Used to derive CompletionStats for chain-aware polling.
6
+ */
7
+ const WITHDRAWAL_P99_BY_CHAIN = {
8
+ "eip155:1": 1852,
9
+ "eip155:56": 36,
10
+ "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": 1387,
11
+ "eip155:8453": 651,
12
+ "tron:27Lqcw": 2358,
13
+ "eip155:42161": 928,
14
+ "bip122:000000000019d6689c085ae165831e93": 3656,
15
+ "eip155:137": 410,
16
+ "xrpl:0": 2276,
17
+ "bip122:00040fe8ec8471911baa1db1266ea15d": 2093,
18
+ "tvm:-239": 53,
19
+ "near:mainnet": 356,
20
+ "bip122:12a765e31ffd4059bada1e25190f6e98": 2385,
21
+ "eip155:143": 22,
22
+ "eip155:43114": 657,
23
+ "stellar:pubnet": 50,
24
+ "eip155:10": 23,
25
+ "bip122:1a91e3dace36e2be3bf030a65679fe82": 1970,
26
+ "sui:mainnet": 752,
27
+ "eip155:80085": 579,
28
+ "eip155:100": 3308,
29
+ "aptos:mainnet": 394,
30
+ "cip34:1-764824073": 807
31
+ };
32
+ /**
33
+ * Default stats for chains without timing data.
34
+ * Conservative 2-hour timeout with gradual phase transitions.
35
+ */
36
+ const DEFAULT_WITHDRAWAL_STATS = {
37
+ p50: 6e4,
38
+ p90: 6e5,
39
+ p99: 72e5
40
+ };
41
+ /**
42
+ * Returns CompletionStats for the given chain.
43
+ * Derives p50/p90 from p99 using reasonable ratios with minimum floors.
44
+ */
45
+ function getWithdrawalStatsForChain(caip2) {
46
+ const p99Seconds = WITHDRAWAL_P99_BY_CHAIN[caip2];
47
+ if (p99Seconds == null) return DEFAULT_WITHDRAWAL_STATS;
48
+ const p99 = p99Seconds * 1e3;
49
+ return {
50
+ p50: Math.max(5e3, p99 * .15),
51
+ p90: Math.max(3e4, p99 * .5),
52
+ p99
53
+ };
54
+ }
55
+
56
+ //#endregion
57
+ exports.getWithdrawalStatsForChain = getWithdrawalStatsForChain;
@@ -0,0 +1,56 @@
1
+ //#region src/constants/withdrawal-timing.ts
2
+ /**
3
+ * Withdrawal timing p99 values (in seconds) by CAIP-2 chain identifier.
4
+ * Used to derive CompletionStats for chain-aware polling.
5
+ */
6
+ const WITHDRAWAL_P99_BY_CHAIN = {
7
+ "eip155:1": 1852,
8
+ "eip155:56": 36,
9
+ "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": 1387,
10
+ "eip155:8453": 651,
11
+ "tron:27Lqcw": 2358,
12
+ "eip155:42161": 928,
13
+ "bip122:000000000019d6689c085ae165831e93": 3656,
14
+ "eip155:137": 410,
15
+ "xrpl:0": 2276,
16
+ "bip122:00040fe8ec8471911baa1db1266ea15d": 2093,
17
+ "tvm:-239": 53,
18
+ "near:mainnet": 356,
19
+ "bip122:12a765e31ffd4059bada1e25190f6e98": 2385,
20
+ "eip155:143": 22,
21
+ "eip155:43114": 657,
22
+ "stellar:pubnet": 50,
23
+ "eip155:10": 23,
24
+ "bip122:1a91e3dace36e2be3bf030a65679fe82": 1970,
25
+ "sui:mainnet": 752,
26
+ "eip155:80085": 579,
27
+ "eip155:100": 3308,
28
+ "aptos:mainnet": 394,
29
+ "cip34:1-764824073": 807
30
+ };
31
+ /**
32
+ * Default stats for chains without timing data.
33
+ * Conservative 2-hour timeout with gradual phase transitions.
34
+ */
35
+ const DEFAULT_WITHDRAWAL_STATS = {
36
+ p50: 6e4,
37
+ p90: 6e5,
38
+ p99: 72e5
39
+ };
40
+ /**
41
+ * Returns CompletionStats for the given chain.
42
+ * Derives p50/p90 from p99 using reasonable ratios with minimum floors.
43
+ */
44
+ function getWithdrawalStatsForChain(caip2) {
45
+ const p99Seconds = WITHDRAWAL_P99_BY_CHAIN[caip2];
46
+ if (p99Seconds == null) return DEFAULT_WITHDRAWAL_STATS;
47
+ const p99 = p99Seconds * 1e3;
48
+ return {
49
+ p50: Math.max(5e3, p99 * .15),
50
+ p90: Math.max(3e4, p99 * .5),
51
+ p99
52
+ };
53
+ }
54
+
55
+ //#endregion
56
+ export { getWithdrawalStatsForChain };
@@ -0,0 +1,83 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ const require_withdrawal_timing = require('../constants/withdrawal-timing.cjs');
3
+ let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
4
+
5
+ //#region src/core/withdrawal-watcher.ts
6
+ const MAX_CONSECUTIVE_ERRORS = 3;
7
+ async function watchWithdrawal(args) {
8
+ const stats = require_withdrawal_timing.getWithdrawalStatsForChain(args.wid.landingChain);
9
+ let consecutiveErrors = 0;
10
+ try {
11
+ return await (0, _defuse_protocol_internal_utils.poll)(async () => {
12
+ try {
13
+ const status = await args.bridge.describeWithdrawal({
14
+ ...args.wid,
15
+ logger: args.logger
16
+ });
17
+ consecutiveErrors = 0;
18
+ if (status.status === "completed") return status.txHash != null ? { hash: status.txHash } : { hash: null };
19
+ if (status.status === "failed") throw new WithdrawalFailedError(status.reason);
20
+ return _defuse_protocol_internal_utils.POLL_PENDING;
21
+ } catch (err) {
22
+ if (err instanceof WithdrawalFailedError) throw err;
23
+ consecutiveErrors++;
24
+ if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) throw new WithdrawalWatchError(err);
25
+ args.logger?.warn(`Transient error (${consecutiveErrors}/${MAX_CONSECUTIVE_ERRORS}): ${err}`);
26
+ return _defuse_protocol_internal_utils.POLL_PENDING;
27
+ }
28
+ }, {
29
+ stats,
30
+ signal: args.signal
31
+ });
32
+ } catch (err) {
33
+ if (err instanceof _defuse_protocol_internal_utils.PollTimeoutError) throw new WithdrawalWatchError(err);
34
+ throw err;
35
+ }
36
+ }
37
+ async function createWithdrawalIdentifiers(args) {
38
+ const indexes = /* @__PURE__ */ new Map();
39
+ const results = [];
40
+ for (const w of args.withdrawalParams) {
41
+ const bridge = await findBridgeForWithdrawal(args.bridges, w);
42
+ if (bridge == null) throw new BridgeNotFoundError();
43
+ const currentIndex = indexes.get(bridge.route) ?? 0;
44
+ indexes.set(bridge.route, currentIndex + 1);
45
+ const wid = bridge.createWithdrawalIdentifier({
46
+ withdrawalParams: w,
47
+ index: currentIndex,
48
+ tx: args.intentTx
49
+ });
50
+ results.push({
51
+ bridge,
52
+ wid
53
+ });
54
+ }
55
+ return results;
56
+ }
57
+ async function findBridgeForWithdrawal(bridges, params) {
58
+ for (const bridge of bridges) if (await bridge.supports(params)) return bridge;
59
+ }
60
+ var BridgeNotFoundError = class extends _defuse_protocol_internal_utils.BaseError {
61
+ constructor() {
62
+ super("Bridge adapter not found", { name: "BridgeNotFoundError" });
63
+ }
64
+ };
65
+ var WithdrawalFailedError = class extends _defuse_protocol_internal_utils.BaseError {
66
+ constructor(reason) {
67
+ super(`Withdrawal failed: ${reason}`, { name: "WithdrawalFailedError" });
68
+ }
69
+ };
70
+ var WithdrawalWatchError = class extends _defuse_protocol_internal_utils.BaseError {
71
+ constructor(cause) {
72
+ super("Withdrawal watch failed", {
73
+ name: "WithdrawalWatchError",
74
+ cause
75
+ });
76
+ }
77
+ };
78
+
79
+ //#endregion
80
+ exports.WithdrawalFailedError = WithdrawalFailedError;
81
+ exports.WithdrawalWatchError = WithdrawalWatchError;
82
+ exports.createWithdrawalIdentifiers = createWithdrawalIdentifiers;
83
+ exports.watchWithdrawal = watchWithdrawal;
@@ -0,0 +1,18 @@
1
+ import { BaseError, ILogger } from "@defuse-protocol/internal-utils";
2
+
3
+ //#region src/core/withdrawal-watcher.d.ts
4
+
5
+ type WithdrawalFailedErrorType = WithdrawalFailedError & {
6
+ name: "WithdrawalFailedError";
7
+ };
8
+ declare class WithdrawalFailedError extends BaseError {
9
+ constructor(reason: string);
10
+ }
11
+ type WithdrawalWatchErrorType = WithdrawalWatchError & {
12
+ name: "WithdrawalWatchError";
13
+ };
14
+ declare class WithdrawalWatchError extends BaseError {
15
+ constructor(cause: unknown);
16
+ }
17
+ //#endregion
18
+ export { WithdrawalFailedError, WithdrawalFailedErrorType, WithdrawalWatchError, WithdrawalWatchErrorType };
@@ -0,0 +1,18 @@
1
+ import { BaseError, ILogger } from "@defuse-protocol/internal-utils";
2
+
3
+ //#region src/core/withdrawal-watcher.d.ts
4
+
5
+ type WithdrawalFailedErrorType = WithdrawalFailedError & {
6
+ name: "WithdrawalFailedError";
7
+ };
8
+ declare class WithdrawalFailedError extends BaseError {
9
+ constructor(reason: string);
10
+ }
11
+ type WithdrawalWatchErrorType = WithdrawalWatchError & {
12
+ name: "WithdrawalWatchError";
13
+ };
14
+ declare class WithdrawalWatchError extends BaseError {
15
+ constructor(cause: unknown);
16
+ }
17
+ //#endregion
18
+ export { WithdrawalFailedError, WithdrawalFailedErrorType, WithdrawalWatchError, WithdrawalWatchErrorType };
@@ -0,0 +1,79 @@
1
+ import { getWithdrawalStatsForChain } from "../constants/withdrawal-timing.js";
2
+ import { BaseError, POLL_PENDING, PollTimeoutError, poll } from "@defuse-protocol/internal-utils";
3
+
4
+ //#region src/core/withdrawal-watcher.ts
5
+ const MAX_CONSECUTIVE_ERRORS = 3;
6
+ async function watchWithdrawal(args) {
7
+ const stats = getWithdrawalStatsForChain(args.wid.landingChain);
8
+ let consecutiveErrors = 0;
9
+ try {
10
+ return await poll(async () => {
11
+ try {
12
+ const status = await args.bridge.describeWithdrawal({
13
+ ...args.wid,
14
+ logger: args.logger
15
+ });
16
+ consecutiveErrors = 0;
17
+ if (status.status === "completed") return status.txHash != null ? { hash: status.txHash } : { hash: null };
18
+ if (status.status === "failed") throw new WithdrawalFailedError(status.reason);
19
+ return POLL_PENDING;
20
+ } catch (err) {
21
+ if (err instanceof WithdrawalFailedError) throw err;
22
+ consecutiveErrors++;
23
+ if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) throw new WithdrawalWatchError(err);
24
+ args.logger?.warn(`Transient error (${consecutiveErrors}/${MAX_CONSECUTIVE_ERRORS}): ${err}`);
25
+ return POLL_PENDING;
26
+ }
27
+ }, {
28
+ stats,
29
+ signal: args.signal
30
+ });
31
+ } catch (err) {
32
+ if (err instanceof PollTimeoutError) throw new WithdrawalWatchError(err);
33
+ throw err;
34
+ }
35
+ }
36
+ async function createWithdrawalIdentifiers(args) {
37
+ const indexes = /* @__PURE__ */ new Map();
38
+ const results = [];
39
+ for (const w of args.withdrawalParams) {
40
+ const bridge = await findBridgeForWithdrawal(args.bridges, w);
41
+ if (bridge == null) throw new BridgeNotFoundError();
42
+ const currentIndex = indexes.get(bridge.route) ?? 0;
43
+ indexes.set(bridge.route, currentIndex + 1);
44
+ const wid = bridge.createWithdrawalIdentifier({
45
+ withdrawalParams: w,
46
+ index: currentIndex,
47
+ tx: args.intentTx
48
+ });
49
+ results.push({
50
+ bridge,
51
+ wid
52
+ });
53
+ }
54
+ return results;
55
+ }
56
+ async function findBridgeForWithdrawal(bridges, params) {
57
+ for (const bridge of bridges) if (await bridge.supports(params)) return bridge;
58
+ }
59
+ var BridgeNotFoundError = class extends BaseError {
60
+ constructor() {
61
+ super("Bridge adapter not found", { name: "BridgeNotFoundError" });
62
+ }
63
+ };
64
+ var WithdrawalFailedError = class extends BaseError {
65
+ constructor(reason) {
66
+ super(`Withdrawal failed: ${reason}`, { name: "WithdrawalFailedError" });
67
+ }
68
+ };
69
+ var WithdrawalWatchError = class extends BaseError {
70
+ constructor(cause) {
71
+ super("Withdrawal watch failed", {
72
+ name: "WithdrawalWatchError",
73
+ cause
74
+ });
75
+ }
76
+ };
77
+
78
+ //#endregion
79
+ export { WithdrawalFailedError, WithdrawalWatchError, createWithdrawalIdentifiers, watchWithdrawal };
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- let __scure_base = require("@scure/base");
2
+ let _scure_base = require("@scure/base");
3
3
  let valibot = require("valibot");
4
4
  valibot = require_rolldown_runtime.__toESM(valibot);
5
5
  let near_api_js_lib_utils_serialize = require("near-api-js/lib/utils/serialize");
@@ -65,11 +65,11 @@ let VersionedNonceBuilder;
65
65
  result.set(VERSIONED_MAGIC_PREFIX, 0);
66
66
  result.set([LATEST_VERSION], 4);
67
67
  result.set(borshBytes, 5);
68
- return __scure_base.base64.encode(result);
68
+ return _scure_base.base64.encode(result);
69
69
  }
70
70
  _VersionedNonceBuilder.encodeNonce = encodeNonce;
71
71
  function decodeNonce(encoded) {
72
- const bytes = __scure_base.base64.decode(encoded);
72
+ const bytes = _scure_base.base64.decode(encoded);
73
73
  if (bytes.length !== 32) throw new Error("Nonce too short");
74
74
  const prefix = bytes.slice(0, 4);
75
75
  const version = bytes[4];
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
2
2
  const require_intent_hash = require('../intent-hash.cjs');
3
3
  const require_intent_payload_factory = require('../intent-payload-factory.cjs');
4
- let __defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
4
+ let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
5
5
 
6
6
  //#region src/intents/intent-executer-impl/intent-executer.ts
7
7
  var IntentExecuter = class {
@@ -14,7 +14,7 @@ var IntentExecuter = class {
14
14
  this.onBeforePublishIntent = args.onBeforePublishIntent;
15
15
  }
16
16
  async signAndSendIntent({ relayParams: relayParamsFactory, salt, signedIntents, ...intentParams }) {
17
- const verifyingContract = __defuse_protocol_internal_utils.configsByEnvironment[this.env].contractID;
17
+ const verifyingContract = _defuse_protocol_internal_utils.configsByEnvironment[this.env].contractID;
18
18
  let intentPayload = require_intent_payload_factory.defaultIntentPayloadFactory(salt, {
19
19
  verifying_contract: verifyingContract,
20
20
  ...intentParams
@@ -44,8 +44,11 @@ var IntentExecuter = class {
44
44
  ...relayParams
45
45
  }, { logger: this.logger }) };
46
46
  }
47
- async waitForSettlement(ticket) {
48
- return this.intentRelayer.waitForSettlement(ticket, { logger: this.logger });
47
+ async waitForSettlement(ticket, ctx) {
48
+ return this.intentRelayer.waitForSettlement(ticket, {
49
+ logger: this.logger,
50
+ signal: ctx?.signal
51
+ });
49
52
  }
50
53
  };
51
54
  async function mergeIntentPayloads(defaultPayload, intentPayloadFactory, salt) {
@@ -43,8 +43,11 @@ var IntentExecuter = class {
43
43
  ...relayParams
44
44
  }, { logger: this.logger }) };
45
45
  }
46
- async waitForSettlement(ticket) {
47
- return this.intentRelayer.waitForSettlement(ticket, { logger: this.logger });
46
+ async waitForSettlement(ticket, ctx) {
47
+ return this.intentRelayer.waitForSettlement(ticket, {
48
+ logger: this.logger,
49
+ signal: ctx?.signal
50
+ });
48
51
  }
49
52
  };
50
53
  async function mergeIntentPayloads(defaultPayload, intentPayloadFactory, salt) {
@@ -6,7 +6,7 @@ const require_raw_ed25519 = require('./intent-hashes/raw-ed25519.cjs');
6
6
  const require_webauthn = require('./intent-hashes/webauthn.cjs');
7
7
  const require_ton_connect = require('./intent-hashes/ton-connect.cjs');
8
8
  const require_sep53 = require('./intent-hashes/sep53.cjs');
9
- let __scure_base = require("@scure/base");
9
+ let _scure_base = require("@scure/base");
10
10
 
11
11
  //#region src/intents/intent-hash.ts
12
12
  /**
@@ -41,7 +41,7 @@ async function computeIntentHashHashBytes(signed) {
41
41
  }
42
42
  async function computeIntentHash(multiPayload) {
43
43
  const hashBytes = await computeIntentHashHashBytes(multiPayload);
44
- return __scure_base.base58.encode(hashBytes);
44
+ return _scure_base.base58.encode(hashBytes);
45
45
  }
46
46
 
47
47
  //#endregion