@defuse-protocol/intents-sdk 0.43.2 → 0.44.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/README.md +143 -21
- package/dist/index.cjs +19 -18
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +7 -5
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.cjs +5 -5
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.cjs +24 -12
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.js +19 -7
- package/dist/src/bridges/direct-bridge/direct-bridge-utils.cjs +5 -5
- package/dist/src/bridges/direct-bridge/direct-bridge.cjs +22 -10
- package/dist/src/bridges/direct-bridge/direct-bridge.js +16 -4
- package/dist/src/bridges/direct-bridge/error.cjs +2 -2
- package/dist/src/bridges/hot-bridge/error.cjs +4 -26
- package/dist/src/bridges/hot-bridge/error.d.cts +1 -17
- package/dist/src/bridges/hot-bridge/error.d.ts +1 -17
- package/dist/src/bridges/hot-bridge/error.js +1 -21
- package/dist/src/bridges/hot-bridge/hot-bridge-utils.cjs +10 -10
- package/dist/src/bridges/hot-bridge/hot-bridge.cjs +46 -32
- package/dist/src/bridges/hot-bridge/hot-bridge.js +38 -24
- package/dist/src/bridges/intents-bridge/intents-bridge.cjs +18 -4
- package/dist/src/bridges/intents-bridge/intents-bridge.js +18 -4
- package/dist/src/bridges/omni-bridge/error.cjs +6 -27
- package/dist/src/bridges/omni-bridge/error.d.cts +1 -16
- package/dist/src/bridges/omni-bridge/error.d.ts +1 -16
- package/dist/src/bridges/omni-bridge/error.js +1 -20
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.cjs +12 -7
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.js +5 -1
- package/dist/src/bridges/omni-bridge/omni-bridge.cjs +72 -54
- package/dist/src/bridges/omni-bridge/omni-bridge.js +47 -29
- package/dist/src/bridges/poa-bridge/poa-bridge-utils.cjs +2 -2
- package/dist/src/bridges/poa-bridge/poa-bridge.cjs +79 -26
- package/dist/src/bridges/poa-bridge/poa-bridge.js +66 -13
- package/dist/src/classes/errors.cjs +7 -7
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.cjs +17 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.cts +12 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.d.ts +12 -0
- package/dist/src/constants/poa-tokens-routable-through-omni-bridge.js +16 -0
- package/dist/src/constants/withdrawal-timing.cjs +57 -0
- package/dist/src/constants/withdrawal-timing.js +56 -0
- package/dist/src/core/withdrawal-watcher.cjs +83 -0
- package/dist/src/core/withdrawal-watcher.d.cts +18 -0
- package/dist/src/core/withdrawal-watcher.d.ts +18 -0
- package/dist/src/core/withdrawal-watcher.js +79 -0
- package/dist/src/intents/expirable-nonce.cjs +3 -3
- package/dist/src/intents/intent-executer-impl/intent-executer.cjs +7 -4
- package/dist/src/intents/intent-executer-impl/intent-executer.js +5 -2
- package/dist/src/intents/intent-hash.cjs +2 -2
- package/dist/src/intents/intent-hashes/erc191.cjs +2 -2
- package/dist/src/intents/intent-hashes/nep413.cjs +2 -2
- package/dist/src/intents/intent-hashes/raw-ed25519.cjs +2 -2
- package/dist/src/intents/intent-hashes/sep53.cjs +4 -4
- package/dist/src/intents/intent-hashes/tip191.cjs +2 -2
- package/dist/src/intents/intent-hashes/ton-connect.cjs +2 -2
- package/dist/src/intents/intent-hashes/webauthn.cjs +2 -2
- package/dist/src/intents/intent-payload-builder.cjs +4 -4
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.cjs +7 -7
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.js +1 -1
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.cjs +2 -2
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.cjs +3 -3
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.cjs +3 -3
- package/dist/src/intents/interfaces/intent-relayer.d.cts +2 -1
- package/dist/src/intents/interfaces/intent-relayer.d.ts +2 -1
- package/dist/src/intents/salt-manager.cjs +5 -5
- package/dist/src/lib/array.cjs +2 -2
- package/dist/src/lib/caip2.cjs +4 -4
- package/dist/src/lib/configure-rpc-config.cjs +3 -3
- package/dist/src/lib/estimate-fee.cjs +6 -6
- package/dist/src/lib/parse-defuse-asset-id.cjs +2 -2
- package/dist/src/lib/route-config-factory.cjs +2 -5
- package/dist/src/lib/route-config-factory.d.cts +1 -1
- package/dist/src/lib/route-config-factory.d.ts +1 -1
- package/dist/src/lib/route-config-factory.js +2 -5
- package/dist/src/lib/tokensUsdPricesHttpClient/apis.cjs +3 -3
- package/dist/src/lib/validateAddress.cjs +18 -18
- package/dist/src/sdk.cjs +96 -47
- package/dist/src/sdk.d.cts +72 -11
- package/dist/src/sdk.d.ts +72 -11
- package/dist/src/sdk.js +85 -36
- package/dist/src/shared-types.d.cts +49 -15
- package/dist/src/shared-types.d.ts +49 -15
- package/package.json +5 -7
- package/dist/src/lib/route-config.cjs +0 -19
- package/dist/src/lib/route-config.js +0 -19
|
@@ -1,21 +1,22 @@
|
|
|
1
|
+
import { InvalidDestinationAddressForWithdrawalError, MinWithdrawalAmountError, UnsupportedAssetIdError } from "../../classes/errors.js";
|
|
1
2
|
import { RouteEnum } from "../../constants/route-enum.js";
|
|
2
3
|
import { getFeeQuote, 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 { InsufficientUtxoForOmniBridgeWithdrawalError, IntentsNearOmniAvailableBalanceTooLowError, InvalidFeeValueError,
|
|
7
|
+
import { InsufficientUtxoForOmniBridgeWithdrawalError, IntentsNearOmniAvailableBalanceTooLowError, InvalidFeeValueError, OmniWithdrawalApiFeeRequestTimeoutError, TokenNotFoundInDestinationChainError } from "./error.js";
|
|
8
8
|
import { MIN_ALLOWED_STORAGE_BALANCE_FOR_INTENTS_NEAR, NEAR_NATIVE_ASSET_ID, OMNI_BRIDGE_CONTRACT } from "./omni-bridge-constants.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE } from "../../constants/poa-tokens-routable-through-omni-bridge.js";
|
|
10
|
+
import { caip2ToChainKind, chainKindToCaip2, createWithdrawIntentsPrimitive, getAccountOmniStorageBalance, getBridgedToken, getTokenDecimals, isUtxoChain, poaContractIdToChainKind, validateOmniToken } from "./omni-bridge-utils.js";
|
|
11
|
+
import { assert, configsByEnvironment, getNearNep141MinStorageBalance, getNearNep141StorageBalance, withTimeout } from "@defuse-protocol/internal-utils";
|
|
11
12
|
import { LRUCache } from "lru-cache";
|
|
12
|
-
import { retry } from "@lifeomic/attempt";
|
|
13
13
|
import TTLCache from "@isaacs/ttlcache";
|
|
14
14
|
import { ChainKind, OmniBridgeAPI, getChain, getMinimumTransferableAmount, isEvmChain, omniAddress, parseOriginChain, verifyTransferAmount } from "omni-bridge-sdk";
|
|
15
15
|
|
|
16
16
|
//#region src/bridges/omni-bridge/omni-bridge.ts
|
|
17
17
|
var OmniBridge = class {
|
|
18
|
-
constructor({ env, nearProvider, solverRelayApiKey }) {
|
|
18
|
+
constructor({ env, nearProvider, solverRelayApiKey, routeMigratedPoaTokensThroughOmniBridge }) {
|
|
19
|
+
this.route = RouteEnum.OmniBridge;
|
|
19
20
|
this.storageDepositCache = new LRUCache({
|
|
20
21
|
max: 100,
|
|
21
22
|
ttl: 36e5
|
|
@@ -26,6 +27,7 @@ var OmniBridge = class {
|
|
|
26
27
|
this.nearProvider = nearProvider;
|
|
27
28
|
this.omniBridgeAPI = new OmniBridgeAPI();
|
|
28
29
|
this.solverRelayApiKey = solverRelayApiKey;
|
|
30
|
+
this.routeMigratedPoaTokensThroughOmniBridge = routeMigratedPoaTokensThroughOmniBridge ?? false;
|
|
29
31
|
}
|
|
30
32
|
is(routeConfig) {
|
|
31
33
|
return routeConfig.route === RouteEnum.OmniBridge;
|
|
@@ -38,7 +40,8 @@ var OmniBridge = class {
|
|
|
38
40
|
const nonValidStandard = parsed.standard !== "nep141";
|
|
39
41
|
if (nonValidStandard && (omniBridgeSetWithNoChain || targetChainSpecified)) throw new UnsupportedAssetIdError(params.assetId, `Only NEP-141 tokens are supported by Omni Bridge.`);
|
|
40
42
|
if (nonValidStandard) return false;
|
|
41
|
-
const
|
|
43
|
+
const poaTokenRoutedThroughOmniBridge = this.isPoaTokenRoutedThroughOmniBridge(parsed.contractId);
|
|
44
|
+
const nonValidToken = !poaTokenRoutedThroughOmniBridge && validateOmniToken(parsed.contractId) === false;
|
|
42
45
|
if (nonValidToken && omniBridgeSetWithNoChain) throw new UnsupportedAssetIdError(params.assetId, `Non valid omni contract id ${parsed.contractId}`);
|
|
43
46
|
if (!targetChainSpecified && nonValidToken) return false;
|
|
44
47
|
let omniChainKind = null;
|
|
@@ -48,7 +51,7 @@ var OmniBridge = class {
|
|
|
48
51
|
if (omniChainKind === null) throw new UnsupportedAssetIdError(params.assetId, `Chain ${params.routeConfig.chain} is not supported in Omni Bridge.`);
|
|
49
52
|
caip2Chain = params.routeConfig.chain;
|
|
50
53
|
} else {
|
|
51
|
-
omniChainKind = parseOriginChain(parsed.contractId);
|
|
54
|
+
omniChainKind = poaTokenRoutedThroughOmniBridge ? poaContractIdToChainKind(parsed.contractId) : parseOriginChain(parsed.contractId);
|
|
52
55
|
if (omniChainKind === null) throw new UnsupportedAssetIdError(params.assetId, `Withdrawal of ${parsed.contractId} to its origin chain is not supported in Omni Bridge.`);
|
|
53
56
|
caip2Chain = chainKindToCaip2(omniChainKind);
|
|
54
57
|
if (caip2Chain === null) throw new UnsupportedAssetIdError(params.assetId, `Withdrawal of ${parsed.contractId} to its origin chain is not supported in Omni Bridge.`);
|
|
@@ -62,7 +65,7 @@ var OmniBridge = class {
|
|
|
62
65
|
parseAssetId(assetId) {
|
|
63
66
|
const parsed = parseDefuseAssetId(assetId);
|
|
64
67
|
if (parsed.standard !== "nep141") return null;
|
|
65
|
-
const omniChainKind = parseOriginChain(parsed.contractId);
|
|
68
|
+
const omniChainKind = this.isPoaTokenRoutedThroughOmniBridge(parsed.contractId) ? poaContractIdToChainKind(parsed.contractId) : parseOriginChain(parsed.contractId);
|
|
66
69
|
if (omniChainKind === null) return null;
|
|
67
70
|
const blockchain = chainKindToCaip2(omniChainKind);
|
|
68
71
|
if (blockchain === null) return null;
|
|
@@ -81,7 +84,7 @@ var OmniBridge = class {
|
|
|
81
84
|
omniChainKind = caip2ToChainKind(routeConfig.chain);
|
|
82
85
|
blockchain = routeConfig.chain;
|
|
83
86
|
} else {
|
|
84
|
-
omniChainKind = parseOriginChain(parsed.contractId);
|
|
87
|
+
omniChainKind = this.isPoaTokenRoutedThroughOmniBridge(parsed.contractId) ? poaContractIdToChainKind(parsed.contractId) : parseOriginChain(parsed.contractId);
|
|
85
88
|
if (omniChainKind === null) return null;
|
|
86
89
|
blockchain = chainKindToCaip2(omniChainKind);
|
|
87
90
|
}
|
|
@@ -232,25 +235,33 @@ var OmniBridge = class {
|
|
|
232
235
|
underlyingFees: { [RouteEnum.OmniBridge]: underlyingFees }
|
|
233
236
|
};
|
|
234
237
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
238
|
+
createWithdrawalIdentifier(args) {
|
|
239
|
+
const assetInfo = this.makeAssetInfo(args.withdrawalParams.assetId, args.withdrawalParams.routeConfig);
|
|
240
|
+
assert(assetInfo !== null, `Asset ${args.withdrawalParams.assetId} is not supported by Omni Bridge`);
|
|
241
|
+
return {
|
|
242
|
+
landingChain: args.withdrawalParams.routeConfig != null && "chain" in args.withdrawalParams.routeConfig && args.withdrawalParams.routeConfig.chain !== void 0 ? args.withdrawalParams.routeConfig.chain : assetInfo.blockchain,
|
|
243
|
+
index: args.index,
|
|
244
|
+
withdrawalParams: args.withdrawalParams,
|
|
245
|
+
tx: args.tx
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
async describeWithdrawal(args) {
|
|
249
|
+
const transfer = (await this.omniBridgeAPI.getTransfer({ transactionHash: args.tx.hash }))[args.index];
|
|
250
|
+
if (transfer == null || transfer.transfer_message == null) return { status: "pending" };
|
|
251
|
+
const destinationChain = getChain(transfer.transfer_message.recipient);
|
|
252
|
+
let txHash = null;
|
|
253
|
+
if (isEvmChain(destinationChain)) txHash = transfer.finalised?.EVMLog?.transaction_hash;
|
|
254
|
+
else if (destinationChain === ChainKind.Sol) txHash = transfer.finalised?.Solana?.signature;
|
|
255
|
+
else if (destinationChain === ChainKind.Btc) txHash = typeof window !== "undefined" ? transfer.utxo_transfer?.btc_pending_id : transfer.finalised?.UtxoLog?.transaction_hash;
|
|
256
|
+
else return {
|
|
257
|
+
status: "completed",
|
|
258
|
+
txHash: null
|
|
259
|
+
};
|
|
260
|
+
if (!txHash) return { status: "pending" };
|
|
261
|
+
return {
|
|
262
|
+
status: "completed",
|
|
263
|
+
txHash
|
|
264
|
+
};
|
|
254
265
|
}
|
|
255
266
|
/**
|
|
256
267
|
* Gets storage deposit for a token to avoid frequent RPC calls.
|
|
@@ -290,6 +301,13 @@ var OmniBridge = class {
|
|
|
290
301
|
if (tokenDecimals !== null) this.tokenDecimalsCache.set(omniAddress$1, tokenDecimals);
|
|
291
302
|
return tokenDecimals;
|
|
292
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Checks if passed token contract id is an allowlisted PoA token that should be routed via OmniBridge.
|
|
306
|
+
* Always return false when feature flag routeMigratedPoaTokensThroughOmniBridge = false.
|
|
307
|
+
*/
|
|
308
|
+
isPoaTokenRoutedThroughOmniBridge(nearAddress) {
|
|
309
|
+
return this.routeMigratedPoaTokensThroughOmniBridge ? POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE[nearAddress] !== void 0 : false;
|
|
310
|
+
}
|
|
293
311
|
};
|
|
294
312
|
|
|
295
313
|
//#endregion
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
2
|
const require_caip2 = require('../../lib/caip2.cjs');
|
|
3
3
|
const require_poa_constants = require('./poa-constants.cjs');
|
|
4
|
-
let
|
|
4
|
+
let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
|
|
5
5
|
|
|
6
6
|
//#region src/bridges/poa-bridge/poa-bridge-utils.ts
|
|
7
7
|
function createWithdrawIntentPrimitive(params) {
|
|
8
|
-
const { contractId: tokenAccountId } =
|
|
8
|
+
const { contractId: tokenAccountId } = _defuse_protocol_internal_utils.utils.parseDefuseAssetId(params.assetId);
|
|
9
9
|
return {
|
|
10
10
|
intent: "ft_withdraw",
|
|
11
11
|
token: tokenAccountId,
|
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_errors = require('../../classes/errors.cjs');
|
|
2
3
|
const require_route_enum = require('../../constants/route-enum.cjs');
|
|
3
4
|
const require_estimate_fee = require('../../lib/estimate-fee.cjs');
|
|
4
|
-
const require_errors = require('../../classes/errors.cjs');
|
|
5
5
|
const require_parse_defuse_asset_id = require('../../lib/parse-defuse-asset-id.cjs');
|
|
6
6
|
const require_validateAddress = require('../../lib/validateAddress.cjs');
|
|
7
7
|
const require_bridge_name_enum = require('../../constants/bridge-name-enum.cjs');
|
|
8
|
+
const require_poa_tokens_routable_through_omni_bridge = require('../../constants/poa-tokens-routable-through-omni-bridge.cjs');
|
|
8
9
|
const require_poa_bridge_utils = require('./poa-bridge-utils.cjs');
|
|
9
|
-
let
|
|
10
|
-
let
|
|
11
|
-
|
|
10
|
+
let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
|
|
11
|
+
let _isaacs_ttlcache = require("@isaacs/ttlcache");
|
|
12
|
+
_isaacs_ttlcache = require_rolldown_runtime.__toESM(_isaacs_ttlcache);
|
|
12
13
|
|
|
13
14
|
//#region src/bridges/poa-bridge/poa-bridge.ts
|
|
14
15
|
var PoaBridge = class {
|
|
15
|
-
constructor({ env }) {
|
|
16
|
-
this.
|
|
16
|
+
constructor({ env, routeMigratedPoaTokensThroughOmniBridge }) {
|
|
17
|
+
this.route = require_route_enum.RouteEnum.PoaBridge;
|
|
18
|
+
this.supportedTokensCache = new _isaacs_ttlcache.default({ ttl: 30 * 1e3 });
|
|
17
19
|
this.env = env;
|
|
20
|
+
this.routeMigratedPoaTokensThroughOmniBridge = routeMigratedPoaTokensThroughOmniBridge ?? false;
|
|
18
21
|
}
|
|
19
22
|
is(routeConfig) {
|
|
20
23
|
return routeConfig.route === require_route_enum.RouteEnum.PoaBridge;
|
|
21
24
|
}
|
|
22
25
|
async supports(params) {
|
|
23
26
|
if (params.routeConfig != null && !this.is(params.routeConfig)) return false;
|
|
24
|
-
const
|
|
27
|
+
const assetInfo = this.parseAssetId(params.assetId);
|
|
28
|
+
const isValid = assetInfo != null;
|
|
25
29
|
if (!isValid && params.routeConfig != null) throw new require_errors.UnsupportedAssetIdError(params.assetId, "`assetId` does not match `routeConfig`.");
|
|
30
|
+
if (this.routeMigratedPoaTokensThroughOmniBridge && assetInfo != null && require_poa_tokens_routable_through_omni_bridge.POA_TOKENS_ROUTABLE_THROUGH_OMNI_BRIDGE[assetInfo.contractId] !== void 0 && params.routeConfig === void 0) return false;
|
|
26
31
|
return isValid;
|
|
27
32
|
}
|
|
28
33
|
parseAssetId(assetId) {
|
|
29
34
|
const parsed = require_parse_defuse_asset_id.parseDefuseAssetId(assetId);
|
|
30
|
-
if (!parsed.contractId.endsWith(`.${
|
|
35
|
+
if (!parsed.contractId.endsWith(`.${_defuse_protocol_internal_utils.configsByEnvironment[this.env].poaTokenFactoryContractID}`)) return null;
|
|
31
36
|
let blockchain;
|
|
32
37
|
try {
|
|
33
38
|
blockchain = require_poa_bridge_utils.contractIdToCaip2(parsed.contractId);
|
|
@@ -42,7 +47,7 @@ var PoaBridge = class {
|
|
|
42
47
|
}
|
|
43
48
|
createWithdrawalIntents(args) {
|
|
44
49
|
const relayerFee = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.PoaBridge, "relayerFee");
|
|
45
|
-
(0,
|
|
50
|
+
(0, _defuse_protocol_internal_utils.assert)(relayerFee > 0n, `Invalid POA bridge relayer fee: expected > 0, got ${relayerFee}`);
|
|
46
51
|
const intent = require_poa_bridge_utils.createWithdrawIntentPrimitive({
|
|
47
52
|
...args.withdrawalParams,
|
|
48
53
|
amount: args.withdrawalParams.amount + relayerFee,
|
|
@@ -58,7 +63,7 @@ var PoaBridge = class {
|
|
|
58
63
|
*/
|
|
59
64
|
async validateWithdrawal(args) {
|
|
60
65
|
const assetInfo = this.parseAssetId(args.assetId);
|
|
61
|
-
(0,
|
|
66
|
+
(0, _defuse_protocol_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
62
67
|
if (require_validateAddress.validateAddress(args.destinationAddress, assetInfo.blockchain) === false) throw new require_errors.InvalidDestinationAddressForWithdrawalError(args.destinationAddress, assetInfo.blockchain);
|
|
63
68
|
const { tokens } = await this.getCachedSupportedTokens([require_poa_bridge_utils.toPoaNetwork(assetInfo.blockchain)], args.logger);
|
|
64
69
|
const tokenInfo = tokens.find((token) => token.intents_token_id === args.assetId);
|
|
@@ -69,32 +74,59 @@ var PoaBridge = class {
|
|
|
69
74
|
}
|
|
70
75
|
async estimateWithdrawalFee(args) {
|
|
71
76
|
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
72
|
-
(0,
|
|
73
|
-
const estimation = await
|
|
74
|
-
token:
|
|
77
|
+
(0, _defuse_protocol_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
78
|
+
const estimation = await _defuse_protocol_internal_utils.poaBridge.httpClient.getWithdrawalEstimate({
|
|
79
|
+
token: _defuse_protocol_internal_utils.utils.getTokenAccountId(args.withdrawalParams.assetId),
|
|
75
80
|
address: args.withdrawalParams.destinationAddress,
|
|
76
81
|
chain: require_poa_bridge_utils.toPoaNetwork(assetInfo.blockchain)
|
|
77
82
|
}, {
|
|
78
|
-
baseURL:
|
|
83
|
+
baseURL: _defuse_protocol_internal_utils.configsByEnvironment[this.env].poaBridgeBaseURL,
|
|
79
84
|
logger: args.logger
|
|
80
85
|
});
|
|
81
86
|
const relayerFee = BigInt(estimation.withdrawalFee);
|
|
82
|
-
(0,
|
|
87
|
+
(0, _defuse_protocol_internal_utils.assert)(relayerFee > 0n, `Invalid POA bridge relayer fee: expected > 0, got ${relayerFee}`);
|
|
83
88
|
return {
|
|
84
89
|
amount: relayerFee,
|
|
85
90
|
quote: null,
|
|
86
91
|
underlyingFees: { [require_route_enum.RouteEnum.PoaBridge]: { relayerFee } }
|
|
87
92
|
};
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
94
|
+
createWithdrawalIdentifier(args) {
|
|
95
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
96
|
+
(0, _defuse_protocol_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
97
|
+
return {
|
|
98
|
+
landingChain: assetInfo.blockchain,
|
|
99
|
+
index: args.index,
|
|
100
|
+
withdrawalParams: args.withdrawalParams,
|
|
101
|
+
tx: args.tx
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async describeWithdrawal(args) {
|
|
105
|
+
const withdrawal = findMatchingWithdrawal((await this.getWithdrawalStatusWithRetry(args)).withdrawals, args.withdrawalParams.assetId);
|
|
106
|
+
if (withdrawal == null) return { status: "pending" };
|
|
107
|
+
if (withdrawal.status === "PENDING") return { status: "pending" };
|
|
108
|
+
if (withdrawal.status === "COMPLETED") return {
|
|
109
|
+
status: "completed",
|
|
110
|
+
txHash: withdrawal.data.transfer_tx_hash
|
|
111
|
+
};
|
|
112
|
+
return {
|
|
113
|
+
status: "failed",
|
|
114
|
+
reason: withdrawal.status
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async getWithdrawalStatusWithRetry(args) {
|
|
118
|
+
const startTime = Date.now();
|
|
119
|
+
while (true) try {
|
|
120
|
+
return await _defuse_protocol_internal_utils.poaBridge.httpClient.getWithdrawalStatus({ withdrawal_hash: args.tx.hash }, {
|
|
121
|
+
baseURL: _defuse_protocol_internal_utils.configsByEnvironment[this.env].poaBridgeBaseURL,
|
|
122
|
+
logger: args.logger
|
|
123
|
+
});
|
|
124
|
+
} catch (err) {
|
|
125
|
+
if (!isWithdrawalNotFoundError(err)) throw err;
|
|
126
|
+
if (Date.now() - startTime >= NOT_FOUND_RETRY_TIMEOUT_MS) return { withdrawals: [] };
|
|
127
|
+
args.logger?.warn("Withdrawal not indexed yet, retrying...");
|
|
128
|
+
await sleep(NOT_FOUND_RETRY_INTERVAL_MS);
|
|
129
|
+
}
|
|
98
130
|
}
|
|
99
131
|
/**
|
|
100
132
|
* Gets supported tokens with caching to avoid frequent API calls.
|
|
@@ -104,14 +136,35 @@ var PoaBridge = class {
|
|
|
104
136
|
const cacheKey = chains.sort().join(",");
|
|
105
137
|
const cached = this.supportedTokensCache.get(cacheKey);
|
|
106
138
|
if (cached != null) return cached;
|
|
107
|
-
const data = await
|
|
108
|
-
baseURL:
|
|
139
|
+
const data = await _defuse_protocol_internal_utils.poaBridge.httpClient.getSupportedTokens({ chains }, {
|
|
140
|
+
baseURL: _defuse_protocol_internal_utils.configsByEnvironment[this.env].poaBridgeBaseURL,
|
|
109
141
|
logger
|
|
110
142
|
});
|
|
111
143
|
this.supportedTokensCache.set(cacheKey, data);
|
|
112
144
|
return data;
|
|
113
145
|
}
|
|
114
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Finds a withdrawal matching the given assetId.
|
|
149
|
+
*
|
|
150
|
+
* NOTE: Currently only matches by assetId. This means multiple withdrawals
|
|
151
|
+
* of the same token in a single transaction are not supported.
|
|
152
|
+
* POA API doesn't currently support this case either. When support is added,
|
|
153
|
+
* matching could be done by sorting both API results and withdrawal params by
|
|
154
|
+
* amount (fees are equal for same token, so relative ordering is preserved).
|
|
155
|
+
*/
|
|
156
|
+
function findMatchingWithdrawal(withdrawals, assetId) {
|
|
157
|
+
return withdrawals.find((w) => `nep141:${w.data.near_token_id}` === assetId);
|
|
158
|
+
}
|
|
159
|
+
const NOT_FOUND_RETRY_TIMEOUT_MS = 3 * 1e3;
|
|
160
|
+
const NOT_FOUND_RETRY_INTERVAL_MS = 1e3;
|
|
161
|
+
const RPC_ERR_MSG_WITHDRAWALS_NOT_FOUND = "Withdrawals not found";
|
|
162
|
+
function isWithdrawalNotFoundError(err) {
|
|
163
|
+
return err instanceof _defuse_protocol_internal_utils.RpcRequestError && err.details === RPC_ERR_MSG_WITHDRAWALS_NOT_FOUND;
|
|
164
|
+
}
|
|
165
|
+
function sleep(ms) {
|
|
166
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
167
|
+
}
|
|
115
168
|
|
|
116
169
|
//#endregion
|
|
117
170
|
exports.PoaBridge = PoaBridge;
|
|
@@ -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
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 };
|
|
@@ -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;
|