lampamazaza-new-intents-sdk 0.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1083 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/index.cjs +124 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +19 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.cjs +10 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-constants.js +7 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.cjs +44 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge-utils.js +42 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.cjs +111 -0
- package/dist/src/bridges/aurora-engine-bridge/aurora-engine-bridge.js +110 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-constants.cjs +8 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-constants.js +6 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-utils.cjs +47 -0
- package/dist/src/bridges/direct-bridge/direct-bridge-utils.js +44 -0
- package/dist/src/bridges/direct-bridge/direct-bridge.cjs +155 -0
- package/dist/src/bridges/direct-bridge/direct-bridge.js +154 -0
- package/dist/src/bridges/direct-bridge/error.cjs +16 -0
- package/dist/src/bridges/direct-bridge/error.d.cts +12 -0
- package/dist/src/bridges/direct-bridge/error.d.ts +12 -0
- package/dist/src/bridges/direct-bridge/error.js +15 -0
- package/dist/src/bridges/hot-bridge/error.cjs +23 -0
- package/dist/src/bridges/hot-bridge/error.d.cts +19 -0
- package/dist/src/bridges/hot-bridge/error.d.ts +19 -0
- package/dist/src/bridges/hot-bridge/error.js +21 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.cjs +21 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.cts +6 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.d.ts +6 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-chains.js +20 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-constants.cjs +11 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-constants.js +9 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-utils.cjs +66 -0
- package/dist/src/bridges/hot-bridge/hot-bridge-utils.js +61 -0
- package/dist/src/bridges/hot-bridge/hot-bridge.cjs +241 -0
- package/dist/src/bridges/hot-bridge/hot-bridge.js +239 -0
- package/dist/src/bridges/intents-bridge/intents-bridge.cjs +59 -0
- package/dist/src/bridges/intents-bridge/intents-bridge.js +59 -0
- package/dist/src/bridges/omni-bridge/error.cjs +54 -0
- package/dist/src/bridges/omni-bridge/error.d.cts +41 -0
- package/dist/src/bridges/omni-bridge/error.d.ts +41 -0
- package/dist/src/bridges/omni-bridge/error.js +49 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-constants.cjs +12 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-constants.js +8 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.cjs +153 -0
- package/dist/src/bridges/omni-bridge/omni-bridge-utils.js +143 -0
- package/dist/src/bridges/omni-bridge/omni-bridge.cjs +316 -0
- package/dist/src/bridges/omni-bridge/omni-bridge.js +314 -0
- package/dist/src/bridges/poa-bridge/poa-bridge-utils.cjs +76 -0
- package/dist/src/bridges/poa-bridge/poa-bridge-utils.js +73 -0
- package/dist/src/bridges/poa-bridge/poa-bridge.cjs +175 -0
- package/dist/src/bridges/poa-bridge/poa-bridge.js +173 -0
- package/dist/src/bridges/poa-bridge/poa-constants.cjs +6 -0
- package/dist/src/bridges/poa-bridge/poa-constants.js +5 -0
- package/dist/src/classes/errors.cjs +87 -0
- package/dist/src/classes/errors.d.cts +48 -0
- package/dist/src/classes/errors.d.ts +48 -0
- package/dist/src/classes/errors.js +81 -0
- package/dist/src/constants/bridge-name-enum.cjs +11 -0
- package/dist/src/constants/bridge-name-enum.d.cts +11 -0
- package/dist/src/constants/bridge-name-enum.d.ts +11 -0
- package/dist/src/constants/bridge-name-enum.js +10 -0
- 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/public-rpc-urls.cjs +25 -0
- package/dist/src/constants/public-rpc-urls.js +24 -0
- package/dist/src/constants/route-enum.cjs +13 -0
- package/dist/src/constants/route-enum.d.cts +13 -0
- package/dist/src/constants/route-enum.d.ts +13 -0
- package/dist/src/constants/route-enum.js +12 -0
- package/dist/src/constants/withdrawal-timing.cjs +68 -0
- package/dist/src/constants/withdrawal-timing.js +68 -0
- package/dist/src/core/withdrawal-watcher.cjs +86 -0
- package/dist/src/core/withdrawal-watcher.d.cts +18 -0
- package/dist/src/core/withdrawal-watcher.d.ts +19 -0
- package/dist/src/core/withdrawal-watcher.js +82 -0
- package/dist/src/intents/expirable-nonce.cjs +90 -0
- package/dist/src/intents/expirable-nonce.d.cts +44 -0
- package/dist/src/intents/expirable-nonce.d.ts +45 -0
- package/dist/src/intents/expirable-nonce.js +82 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.cjs +85 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.d.cts +20 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.d.ts +24 -0
- package/dist/src/intents/intent-executer-impl/intent-executer.js +85 -0
- package/dist/src/intents/intent-hash.cjs +48 -0
- package/dist/src/intents/intent-hash.d.cts +8 -0
- package/dist/src/intents/intent-hash.d.ts +8 -0
- package/dist/src/intents/intent-hash.js +47 -0
- package/dist/src/intents/intent-hashes/erc191.cjs +38 -0
- package/dist/src/intents/intent-hashes/erc191.js +37 -0
- package/dist/src/intents/intent-hashes/nep413.cjs +23 -0
- package/dist/src/intents/intent-hashes/nep413.js +22 -0
- package/dist/src/intents/intent-hashes/raw-ed25519.cjs +26 -0
- package/dist/src/intents/intent-hashes/raw-ed25519.js +25 -0
- package/dist/src/intents/intent-hashes/sep53.cjs +36 -0
- package/dist/src/intents/intent-hashes/sep53.js +35 -0
- package/dist/src/intents/intent-hashes/tip191.cjs +39 -0
- package/dist/src/intents/intent-hashes/tip191.js +38 -0
- package/dist/src/intents/intent-hashes/ton-connect.cjs +105 -0
- package/dist/src/intents/intent-hashes/ton-connect.js +104 -0
- package/dist/src/intents/intent-hashes/webauthn.cjs +26 -0
- package/dist/src/intents/intent-hashes/webauthn.js +25 -0
- package/dist/src/intents/intent-payload-builder.cjs +208 -0
- package/dist/src/intents/intent-payload-builder.d.cts +161 -0
- package/dist/src/intents/intent-payload-builder.d.ts +161 -0
- package/dist/src/intents/intent-payload-builder.js +207 -0
- package/dist/src/intents/intent-payload-factory.cjs +23 -0
- package/dist/src/intents/intent-payload-factory.js +21 -0
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.cjs +43 -0
- package/dist/src/intents/intent-relayer-impl/intent-relayer-public.js +42 -0
- package/dist/src/intents/intent-signer-impl/factories.cjs +19 -0
- package/dist/src/intents/intent-signer-impl/factories.d.cts +11 -0
- package/dist/src/intents/intent-signer-impl/factories.d.ts +11 -0
- package/dist/src/intents/intent-signer-impl/factories.js +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.cjs +22 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.cts +15 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.d.ts +16 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-near-keypair.js +21 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.cjs +37 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.cts +14 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.d.ts +14 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-nep413.js +36 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-noop.cjs +8 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-noop.js +7 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.cjs +31 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.cts +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.d.ts +17 -0
- package/dist/src/intents/intent-signer-impl/intent-signer-viem.js +30 -0
- package/dist/src/intents/interfaces/intent-executer.d.ts +2 -0
- package/dist/src/intents/interfaces/intent-relayer.d.cts +43 -0
- package/dist/src/intents/interfaces/intent-relayer.d.ts +43 -0
- package/dist/src/intents/interfaces/intent-signer.d.cts +8 -0
- package/dist/src/intents/interfaces/intent-signer.d.ts +8 -0
- package/dist/src/intents/interfaces/salt-manager.d.cts +9 -0
- package/dist/src/intents/interfaces/salt-manager.d.ts +9 -0
- package/dist/src/intents/salt-manager.cjs +74 -0
- package/dist/src/intents/salt-manager.js +72 -0
- package/dist/src/intents/shared-types.d.cts +20 -0
- package/dist/src/intents/shared-types.d.ts +20 -0
- package/dist/src/lib/array.cjs +11 -0
- package/dist/src/lib/array.js +10 -0
- package/dist/src/lib/caip2.cjs +50 -0
- package/dist/src/lib/caip2.d.cts +38 -0
- package/dist/src/lib/caip2.d.ts +38 -0
- package/dist/src/lib/caip2.js +48 -0
- package/dist/src/lib/configure-rpc-config.cjs +20 -0
- package/dist/src/lib/configure-rpc-config.js +18 -0
- package/dist/src/lib/estimate-fee.cjs +96 -0
- package/dist/src/lib/estimate-fee.js +94 -0
- package/dist/src/lib/hex.cjs +11 -0
- package/dist/src/lib/hex.js +10 -0
- package/dist/src/lib/nep413.cjs +42 -0
- package/dist/src/lib/nep413.d.cts +14 -0
- package/dist/src/lib/nep413.d.ts +14 -0
- package/dist/src/lib/nep413.js +41 -0
- package/dist/src/lib/object.cjs +10 -0
- package/dist/src/lib/object.js +9 -0
- package/dist/src/lib/parse-defuse-asset-id.cjs +15 -0
- package/dist/src/lib/parse-defuse-asset-id.js +14 -0
- package/dist/src/lib/route-config-factory.cjs +43 -0
- package/dist/src/lib/route-config-factory.d.cts +13 -0
- package/dist/src/lib/route-config-factory.d.ts +13 -0
- package/dist/src/lib/route-config-factory.js +37 -0
- package/dist/src/lib/tokensUsdPricesHttpClient/apis.cjs +17 -0
- package/dist/src/lib/tokensUsdPricesHttpClient/apis.js +16 -0
- package/dist/src/lib/validateAddress.cjs +271 -0
- package/dist/src/lib/validateAddress.d.cts +14 -0
- package/dist/src/lib/validateAddress.d.ts +14 -0
- package/dist/src/lib/validateAddress.js +270 -0
- package/dist/src/sdk.cjs +435 -0
- package/dist/src/sdk.d.cts +231 -0
- package/dist/src/sdk.d.ts +231 -0
- package/dist/src/sdk.js +433 -0
- package/dist/src/shared-types.d.cts +378 -0
- package/dist/src/shared-types.d.ts +378 -0
- package/package.json +62 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Chains } from "../../lib/caip2.js";
|
|
2
|
+
import { HotBridgeChains } from "./hot-bridge-chains.js";
|
|
3
|
+
import { assert } from "lampamazaza-internal-utils";
|
|
4
|
+
import { Network } from "@hot-labs/omni-sdk";
|
|
5
|
+
|
|
6
|
+
//#region src/bridges/hot-bridge/hot-bridge-utils.ts
|
|
7
|
+
const MONAD_MAINNET_NETWORK_ID = 143;
|
|
8
|
+
const ADI_NETWORK_ID = 36900;
|
|
9
|
+
const PLASMA_NETWORK_ID = 9745;
|
|
10
|
+
const nativeTokenMapping = {
|
|
11
|
+
[Chains.BNB]: "nep245:v2_1.omni.hot.tg:56_11111111111111111111",
|
|
12
|
+
[Chains.Polygon]: "nep245:v2_1.omni.hot.tg:137_11111111111111111111",
|
|
13
|
+
[Chains.Monad]: "nep245:v2_1.omni.hot.tg:143_11111111111111111111",
|
|
14
|
+
[Chains.TON]: "nep245:v2_1.omni.hot.tg:1117_",
|
|
15
|
+
[Chains.Optimism]: "nep245:v2_1.omni.hot.tg:10_11111111111111111111",
|
|
16
|
+
[Chains.Avalanche]: "nep245:v2_1.omni.hot.tg:43114_11111111111111111111",
|
|
17
|
+
[Chains.Stellar]: "nep245:v2_1.omni.hot.tg:1100_111bzQBB5v7AhLyPMDwS8uJgQV24KaAPXtwyVWu2KXbbfQU6NXRCz",
|
|
18
|
+
[Chains.LayerX]: "nep245:v2_1.omni.hot.tg:196_11111111111111111111",
|
|
19
|
+
[Chains.Adi]: "nep245:v2_1.omni.hot.tg:36900_11111111111111111111",
|
|
20
|
+
[Chains.Scroll]: "nep245:v2_1.omni.hot.tg:534352_11111111111111111111",
|
|
21
|
+
[Chains.Plasma]: "nep245:v2_1.omni.hot.tg:9745_11111111111111111111"
|
|
22
|
+
};
|
|
23
|
+
const caip2NetworkIdMapping = {
|
|
24
|
+
[Chains.BNB]: Network.Bnb,
|
|
25
|
+
[Chains.Polygon]: Network.Polygon,
|
|
26
|
+
[Chains.Monad]: MONAD_MAINNET_NETWORK_ID,
|
|
27
|
+
[Chains.TON]: Network.Ton,
|
|
28
|
+
[Chains.Optimism]: Network.Optimism,
|
|
29
|
+
[Chains.Avalanche]: Network.Avalanche,
|
|
30
|
+
[Chains.Stellar]: Network.Stellar,
|
|
31
|
+
[Chains.LayerX]: Network.Xlayer,
|
|
32
|
+
[Chains.Adi]: ADI_NETWORK_ID,
|
|
33
|
+
[Chains.Scroll]: Network.Scroll,
|
|
34
|
+
[Chains.Plasma]: PLASMA_NETWORK_ID
|
|
35
|
+
};
|
|
36
|
+
const networkIdCAIP2Mapping = Object.fromEntries(Object.entries(caip2NetworkIdMapping).map(([k, v]) => [v, k]));
|
|
37
|
+
function getFeeAssetIdForChain(caip2) {
|
|
38
|
+
return nativeTokenMapping[caip2];
|
|
39
|
+
}
|
|
40
|
+
function toHotNetworkId(caip2) {
|
|
41
|
+
hotBlockchainInvariant(caip2);
|
|
42
|
+
return caip2NetworkIdMapping[caip2];
|
|
43
|
+
}
|
|
44
|
+
function hotNetworkIdToCAIP2(network) {
|
|
45
|
+
const mappedChain = networkIdCAIP2Mapping[network];
|
|
46
|
+
if (mappedChain != null) return mappedChain;
|
|
47
|
+
throw new Error(`Unsupported HOT Bridge chain = ${network}`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* HOT returns hexified raw bytes. So we need to return more friendly/common string.
|
|
51
|
+
*/
|
|
52
|
+
function formatTxHash(txHash, caip2) {
|
|
53
|
+
if (caip2.startsWith("eip155:")) return `0x${txHash}`;
|
|
54
|
+
return txHash;
|
|
55
|
+
}
|
|
56
|
+
function hotBlockchainInvariant(blockchain) {
|
|
57
|
+
assert(HotBridgeChains.includes(blockchain), `${blockchain} is not a valid HOT Bridge blockchain. Supported values: ${HotBridgeChains.join()}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { formatTxHash, getFeeAssetIdForChain, hotBlockchainInvariant, hotNetworkIdToCAIP2, toHotNetworkId };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_errors = require('../../classes/errors.cjs');
|
|
3
|
+
const require_route_enum = require('../../constants/route-enum.cjs');
|
|
4
|
+
const require_caip2 = require('../../lib/caip2.cjs');
|
|
5
|
+
const require_estimate_fee = require('../../lib/estimate-fee.cjs');
|
|
6
|
+
const require_parse_defuse_asset_id = require('../../lib/parse-defuse-asset-id.cjs');
|
|
7
|
+
const require_validateAddress = require('../../lib/validateAddress.cjs');
|
|
8
|
+
const require_bridge_name_enum = require('../../constants/bridge-name-enum.cjs');
|
|
9
|
+
const require_error = require('./error.cjs');
|
|
10
|
+
const require_hot_bridge_constants = require('./hot-bridge-constants.cjs');
|
|
11
|
+
const require_hot_bridge_utils = require('./hot-bridge-utils.cjs');
|
|
12
|
+
const require_hex = require('../../lib/hex.cjs');
|
|
13
|
+
let lampamazaza_internal_utils = require("lampamazaza-internal-utils");
|
|
14
|
+
let _hot_labs_omni_sdk = require("@hot-labs/omni-sdk");
|
|
15
|
+
let lru_cache = require("lru-cache");
|
|
16
|
+
let valibot = require("valibot");
|
|
17
|
+
valibot = require_rolldown_runtime.__toESM(valibot);
|
|
18
|
+
|
|
19
|
+
//#region src/bridges/hot-bridge/hot-bridge.ts
|
|
20
|
+
const HotApiWithdrawalSchema = valibot.object({
|
|
21
|
+
hash: valibot.nullable(valibot.string()),
|
|
22
|
+
nonce: valibot.string(),
|
|
23
|
+
near_trx: valibot.string(),
|
|
24
|
+
verified_withdraw: valibot.boolean(),
|
|
25
|
+
chain_id: valibot.number()
|
|
26
|
+
});
|
|
27
|
+
const HotApiWithdrawalResponseSchema = valibot.object({
|
|
28
|
+
hash: valibot.nullable(valibot.string()),
|
|
29
|
+
nonce: valibot.string(),
|
|
30
|
+
near_trx: valibot.string(),
|
|
31
|
+
withdrawals: valibot.array(HotApiWithdrawalSchema)
|
|
32
|
+
});
|
|
33
|
+
var HotBridge = class HotBridge {
|
|
34
|
+
static {
|
|
35
|
+
this.API_FALLBACK_TIMEOUT_MS = 5e3;
|
|
36
|
+
}
|
|
37
|
+
static {
|
|
38
|
+
this.NEAR_RPC_TIMEOUT_MS = 1e4;
|
|
39
|
+
}
|
|
40
|
+
constructor({ envConfig, hotSdk, solverRelayApiKey }) {
|
|
41
|
+
this.route = require_route_enum.RouteEnum.HotBridge;
|
|
42
|
+
this.envConfig = envConfig;
|
|
43
|
+
this.hotSdk = hotSdk;
|
|
44
|
+
this.solverRelayApiKey = solverRelayApiKey;
|
|
45
|
+
this.noncesCache = new lru_cache.LRUCache({
|
|
46
|
+
max: 50,
|
|
47
|
+
ttl: 3600 * 1e3,
|
|
48
|
+
fetchMethod: async (_key, _staleValue, { context: tx }) => {
|
|
49
|
+
return (0, lampamazaza_internal_utils.withTimeout)(() => this.hotSdk.near.parseWithdrawalNonces(tx.hash, tx.accountId), { timeout: HotBridge.NEAR_RPC_TIMEOUT_MS });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
getNoncesCacheKey(tx) {
|
|
54
|
+
return `${tx.hash}:${tx.accountId}`;
|
|
55
|
+
}
|
|
56
|
+
is(routeConfig) {
|
|
57
|
+
return routeConfig.route === require_route_enum.RouteEnum.HotBridge;
|
|
58
|
+
}
|
|
59
|
+
async supports(params) {
|
|
60
|
+
if (params.routeConfig != null && !this.is(params.routeConfig)) return false;
|
|
61
|
+
const isValid = this.parseAssetId(params.assetId) != null;
|
|
62
|
+
if (!isValid && params.routeConfig != null) throw new require_errors.UnsupportedAssetIdError(params.assetId, "`assetId` does not match `routeConfig`.");
|
|
63
|
+
return isValid;
|
|
64
|
+
}
|
|
65
|
+
parseAssetId(assetId) {
|
|
66
|
+
const parsed = require_parse_defuse_asset_id.parseDefuseAssetId(assetId);
|
|
67
|
+
if (!(parsed.contractId === _hot_labs_omni_sdk.OMNI_HOT_V2)) return null;
|
|
68
|
+
if (parsed.standard !== "nep245") throw new require_errors.UnsupportedAssetIdError(assetId, "Should start with \"nep245:\".");
|
|
69
|
+
const [chainId, address] = _hot_labs_omni_sdk.utils.fromOmni(parsed.tokenId).split(":");
|
|
70
|
+
if (chainId == null || address == null) throw new require_errors.UnsupportedAssetIdError(assetId, "Asset has invalid token id format.");
|
|
71
|
+
let blockchain;
|
|
72
|
+
try {
|
|
73
|
+
blockchain = require_hot_bridge_utils.hotNetworkIdToCAIP2(chainId);
|
|
74
|
+
} catch {
|
|
75
|
+
throw new require_errors.UnsupportedAssetIdError(assetId, "Asset belongs to unknown blockchain.");
|
|
76
|
+
}
|
|
77
|
+
return Object.assign(parsed, {
|
|
78
|
+
blockchain,
|
|
79
|
+
bridgeName: require_bridge_name_enum.BridgeNameEnum.Hot
|
|
80
|
+
}, address === "native" ? { native: true } : { address });
|
|
81
|
+
}
|
|
82
|
+
async createWithdrawalIntents(args) {
|
|
83
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
84
|
+
(0, lampamazaza_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
85
|
+
if (args.withdrawalParams.destinationMemo != null && args.withdrawalParams.destinationMemo !== "") throw new require_errors.UnsupportedDestinationMemoError(assetInfo.blockchain, args.withdrawalParams.assetId);
|
|
86
|
+
const intents = [];
|
|
87
|
+
const feeAmount = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.HotBridge, "relayerFee");
|
|
88
|
+
const blockNumber = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.HotBridge, "blockNumber");
|
|
89
|
+
if (args.feeEstimation.quote !== null) intents.push({
|
|
90
|
+
intent: "token_diff",
|
|
91
|
+
diff: {
|
|
92
|
+
[args.feeEstimation.quote.defuse_asset_identifier_in]: `-${args.feeEstimation.quote.amount_in}`,
|
|
93
|
+
[args.feeEstimation.quote.defuse_asset_identifier_out]: args.feeEstimation.quote.amount_out
|
|
94
|
+
},
|
|
95
|
+
referral: args.referral
|
|
96
|
+
});
|
|
97
|
+
const isNative = "native" in assetInfo;
|
|
98
|
+
const amount = args.withdrawalParams.amount + (isNative ? feeAmount : 0n);
|
|
99
|
+
const intent = await this.hotSdk.buildGaslessWithdrawIntent({
|
|
100
|
+
feeToken: "native",
|
|
101
|
+
feeAmount,
|
|
102
|
+
blockNumber,
|
|
103
|
+
chain: require_hot_bridge_utils.toHotNetworkId(assetInfo.blockchain),
|
|
104
|
+
token: isNative ? "native" : assetInfo.address,
|
|
105
|
+
amount,
|
|
106
|
+
receiver: args.withdrawalParams.destinationAddress
|
|
107
|
+
});
|
|
108
|
+
(0, lampamazaza_internal_utils.assert)(intent.amounts[0] === amount.toString(), "Amount is not correct");
|
|
109
|
+
if (intent.amounts.length === 2) (0, lampamazaza_internal_utils.assert)(intent.amounts[1] === feeAmount.toString(), "Amount is not correct");
|
|
110
|
+
const mtWithdrawIntent = intent;
|
|
111
|
+
mtWithdrawIntent.min_gas = require_hot_bridge_constants.MIN_GAS_AMOUNT;
|
|
112
|
+
intents.push(mtWithdrawIntent);
|
|
113
|
+
return intents;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Hot bridge validates trustlines for Stellar addresses.
|
|
117
|
+
* For Stellar chains, checks if the destination address has the required trustline.
|
|
118
|
+
* @throws {TrustlineNotFoundError} If Stellar destination address lacks required trustline
|
|
119
|
+
*/
|
|
120
|
+
async validateWithdrawal(args) {
|
|
121
|
+
const assetInfo = this.parseAssetId(args.assetId);
|
|
122
|
+
(0, lampamazaza_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
123
|
+
require_hot_bridge_utils.hotBlockchainInvariant(assetInfo.blockchain);
|
|
124
|
+
if (require_validateAddress.validateAddress(args.destinationAddress, assetInfo.blockchain) === false) throw new require_errors.InvalidDestinationAddressForWithdrawalError(args.destinationAddress, assetInfo.blockchain);
|
|
125
|
+
if (assetInfo.blockchain === require_caip2.Chains.Stellar) {
|
|
126
|
+
const token = "native" in assetInfo ? "native" : assetInfo.address;
|
|
127
|
+
if (!await this.hotSdk.stellar.isTrustlineExists(args.destinationAddress, token)) throw new require_errors.TrustlineNotFoundError(args.destinationAddress, args.assetId, assetInfo.blockchain, token);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async estimateWithdrawalFee(args) {
|
|
131
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
132
|
+
(0, lampamazaza_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
133
|
+
require_hot_bridge_utils.hotBlockchainInvariant(assetInfo.blockchain);
|
|
134
|
+
const feeAssetId = require_hot_bridge_utils.getFeeAssetIdForChain(assetInfo.blockchain);
|
|
135
|
+
const { gasPrice: feeAmount, blockNumber } = await (0, lampamazaza_internal_utils.withTimeout)(async () => {
|
|
136
|
+
const result = await this.hotSdk.getGaslessWithdrawFee({
|
|
137
|
+
chain: require_hot_bridge_utils.toHotNetworkId(assetInfo.blockchain),
|
|
138
|
+
token: "native" in assetInfo ? "native" : assetInfo.address,
|
|
139
|
+
receiver: args.withdrawalParams.destinationAddress
|
|
140
|
+
});
|
|
141
|
+
if (assetInfo.blockchain === require_caip2.Chains.Plasma && args.withdrawalParams.assetId !== feeAssetId) result.gasPrice *= 20n;
|
|
142
|
+
return result;
|
|
143
|
+
}, {
|
|
144
|
+
errorInstance: new require_error.HotWithdrawalApiFeeRequestTimeoutError(),
|
|
145
|
+
timeout: typeof window !== "undefined" ? 1e4 : 3e3
|
|
146
|
+
});
|
|
147
|
+
const feeQuote = args.withdrawalParams.assetId === feeAssetId || feeAmount === 0n ? null : await require_estimate_fee.getFeeQuote({
|
|
148
|
+
feeAmount,
|
|
149
|
+
feeAssetId,
|
|
150
|
+
tokenAssetId: args.withdrawalParams.assetId,
|
|
151
|
+
logger: args.logger,
|
|
152
|
+
envConfig: this.envConfig,
|
|
153
|
+
quoteOptions: args.quoteOptions,
|
|
154
|
+
solverRelayApiKey: this.solverRelayApiKey
|
|
155
|
+
});
|
|
156
|
+
return {
|
|
157
|
+
amount: feeQuote ? BigInt(feeQuote.amount_in) : feeAmount,
|
|
158
|
+
quote: feeQuote,
|
|
159
|
+
underlyingFees: { [require_route_enum.RouteEnum.HotBridge]: {
|
|
160
|
+
relayerFee: feeAmount,
|
|
161
|
+
blockNumber
|
|
162
|
+
} }
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
createWithdrawalIdentifier(args) {
|
|
166
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
167
|
+
(0, lampamazaza_internal_utils.assert)(assetInfo != null, "Asset is not supported");
|
|
168
|
+
return {
|
|
169
|
+
landingChain: assetInfo.blockchain,
|
|
170
|
+
index: args.index,
|
|
171
|
+
withdrawalParams: args.withdrawalParams,
|
|
172
|
+
tx: args.tx
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
async describeWithdrawal(args) {
|
|
176
|
+
const cacheKey = this.getNoncesCacheKey(args.tx);
|
|
177
|
+
const nonces = await this.noncesCache.fetch(cacheKey, { context: args.tx });
|
|
178
|
+
if (nonces == null) throw new require_error.HotWithdrawalNotFoundError(args.tx.hash, args.index);
|
|
179
|
+
const nonce = nonces[args.index];
|
|
180
|
+
if (nonce == null) throw new require_error.HotWithdrawalNotFoundError(args.tx.hash, args.index);
|
|
181
|
+
const status = await this.hotSdk.getGaslessWithdrawStatus(nonce.toString());
|
|
182
|
+
if (status === require_hot_bridge_constants.HotWithdrawStatus.Canceled) return {
|
|
183
|
+
status: "failed",
|
|
184
|
+
reason: "Withdrawal was cancelled"
|
|
185
|
+
};
|
|
186
|
+
if (status === require_hot_bridge_constants.HotWithdrawStatus.Completed) return {
|
|
187
|
+
status: "completed",
|
|
188
|
+
txHash: null
|
|
189
|
+
};
|
|
190
|
+
if (typeof status === "string") {
|
|
191
|
+
if (!require_hex.default(status)) {
|
|
192
|
+
args.logger?.warn("HOT Bridge incorrect destination tx hash detected", { value: status });
|
|
193
|
+
return {
|
|
194
|
+
status: "completed",
|
|
195
|
+
txHash: null
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
status: "completed",
|
|
200
|
+
txHash: require_hot_bridge_utils.formatTxHash(status, args.landingChain)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const apiHash = await this.fetchWithdrawalHashFromApi(args.tx.hash, nonce, args.logger);
|
|
204
|
+
if (apiHash != null) return {
|
|
205
|
+
status: "completed",
|
|
206
|
+
txHash: require_hot_bridge_utils.formatTxHash(apiHash, args.landingChain)
|
|
207
|
+
};
|
|
208
|
+
return { status: "pending" };
|
|
209
|
+
}
|
|
210
|
+
async fetchWithdrawalHashFromApi(nearTxHash, nonce, logger) {
|
|
211
|
+
try {
|
|
212
|
+
const data = await (await (0, lampamazaza_internal_utils.withTimeout)(() => this.hotSdk.api.requestApi(`/api/v1/evm/bridge_withdrawal_hash?near_trx=${nearTxHash}`, { method: "GET" }), { timeout: HotBridge.API_FALLBACK_TIMEOUT_MS })).json();
|
|
213
|
+
const parseResult = valibot.safeParse(HotApiWithdrawalResponseSchema, data);
|
|
214
|
+
if (!parseResult.success) {
|
|
215
|
+
logger?.debug("HOT API response parse failed", { issues: parseResult.issues });
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const withdrawal = parseResult.output.withdrawals.find((w) => w.nonce === nonce.toString());
|
|
219
|
+
if (withdrawal?.hash) {
|
|
220
|
+
const hash = withdrawal.hash.replace(/^0x/, "");
|
|
221
|
+
if (require_hex.default(hash)) {
|
|
222
|
+
logger?.info("HOT withdrawal hash found via API fallback", {
|
|
223
|
+
nearTxHash,
|
|
224
|
+
nonce: nonce.toString()
|
|
225
|
+
});
|
|
226
|
+
return hash;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
logger?.debug("HOT API fallback failed", {
|
|
232
|
+
error,
|
|
233
|
+
nearTxHash
|
|
234
|
+
});
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
exports.HotBridge = HotBridge;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { InvalidDestinationAddressForWithdrawalError, TrustlineNotFoundError, UnsupportedAssetIdError, UnsupportedDestinationMemoError } from "../../classes/errors.js";
|
|
2
|
+
import { RouteEnum } from "../../constants/route-enum.js";
|
|
3
|
+
import { Chains } from "../../lib/caip2.js";
|
|
4
|
+
import { getFeeQuote, getUnderlyingFee } from "../../lib/estimate-fee.js";
|
|
5
|
+
import { parseDefuseAssetId } from "../../lib/parse-defuse-asset-id.js";
|
|
6
|
+
import { validateAddress } from "../../lib/validateAddress.js";
|
|
7
|
+
import { BridgeNameEnum } from "../../constants/bridge-name-enum.js";
|
|
8
|
+
import { HotWithdrawalApiFeeRequestTimeoutError, HotWithdrawalNotFoundError } from "./error.js";
|
|
9
|
+
import { HotWithdrawStatus, MIN_GAS_AMOUNT } from "./hot-bridge-constants.js";
|
|
10
|
+
import { formatTxHash, getFeeAssetIdForChain, hotBlockchainInvariant, hotNetworkIdToCAIP2, toHotNetworkId } from "./hot-bridge-utils.js";
|
|
11
|
+
import isHex from "../../lib/hex.js";
|
|
12
|
+
import { assert, withTimeout } from "lampamazaza-internal-utils";
|
|
13
|
+
import { OMNI_HOT_V2, utils as utils$1 } from "@hot-labs/omni-sdk";
|
|
14
|
+
import { LRUCache } from "lru-cache";
|
|
15
|
+
import * as v from "valibot";
|
|
16
|
+
|
|
17
|
+
//#region src/bridges/hot-bridge/hot-bridge.ts
|
|
18
|
+
const HotApiWithdrawalSchema = v.object({
|
|
19
|
+
hash: v.nullable(v.string()),
|
|
20
|
+
nonce: v.string(),
|
|
21
|
+
near_trx: v.string(),
|
|
22
|
+
verified_withdraw: v.boolean(),
|
|
23
|
+
chain_id: v.number()
|
|
24
|
+
});
|
|
25
|
+
const HotApiWithdrawalResponseSchema = v.object({
|
|
26
|
+
hash: v.nullable(v.string()),
|
|
27
|
+
nonce: v.string(),
|
|
28
|
+
near_trx: v.string(),
|
|
29
|
+
withdrawals: v.array(HotApiWithdrawalSchema)
|
|
30
|
+
});
|
|
31
|
+
var HotBridge$1 = class HotBridge$1 {
|
|
32
|
+
static {
|
|
33
|
+
this.API_FALLBACK_TIMEOUT_MS = 5e3;
|
|
34
|
+
}
|
|
35
|
+
static {
|
|
36
|
+
this.NEAR_RPC_TIMEOUT_MS = 1e4;
|
|
37
|
+
}
|
|
38
|
+
constructor({ envConfig, hotSdk, solverRelayApiKey }) {
|
|
39
|
+
this.route = RouteEnum.HotBridge;
|
|
40
|
+
this.envConfig = envConfig;
|
|
41
|
+
this.hotSdk = hotSdk;
|
|
42
|
+
this.solverRelayApiKey = solverRelayApiKey;
|
|
43
|
+
this.noncesCache = new LRUCache({
|
|
44
|
+
max: 50,
|
|
45
|
+
ttl: 3600 * 1e3,
|
|
46
|
+
fetchMethod: async (_key, _staleValue, { context: tx }) => {
|
|
47
|
+
return withTimeout(() => this.hotSdk.near.parseWithdrawalNonces(tx.hash, tx.accountId), { timeout: HotBridge$1.NEAR_RPC_TIMEOUT_MS });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
getNoncesCacheKey(tx) {
|
|
52
|
+
return `${tx.hash}:${tx.accountId}`;
|
|
53
|
+
}
|
|
54
|
+
is(routeConfig) {
|
|
55
|
+
return routeConfig.route === RouteEnum.HotBridge;
|
|
56
|
+
}
|
|
57
|
+
async supports(params) {
|
|
58
|
+
if (params.routeConfig != null && !this.is(params.routeConfig)) return false;
|
|
59
|
+
const isValid = this.parseAssetId(params.assetId) != null;
|
|
60
|
+
if (!isValid && params.routeConfig != null) throw new UnsupportedAssetIdError(params.assetId, "`assetId` does not match `routeConfig`.");
|
|
61
|
+
return isValid;
|
|
62
|
+
}
|
|
63
|
+
parseAssetId(assetId) {
|
|
64
|
+
const parsed = parseDefuseAssetId(assetId);
|
|
65
|
+
if (!(parsed.contractId === OMNI_HOT_V2)) return null;
|
|
66
|
+
if (parsed.standard !== "nep245") throw new UnsupportedAssetIdError(assetId, "Should start with \"nep245:\".");
|
|
67
|
+
const [chainId, address] = utils$1.fromOmni(parsed.tokenId).split(":");
|
|
68
|
+
if (chainId == null || address == null) throw new UnsupportedAssetIdError(assetId, "Asset has invalid token id format.");
|
|
69
|
+
let blockchain;
|
|
70
|
+
try {
|
|
71
|
+
blockchain = hotNetworkIdToCAIP2(chainId);
|
|
72
|
+
} catch {
|
|
73
|
+
throw new UnsupportedAssetIdError(assetId, "Asset belongs to unknown blockchain.");
|
|
74
|
+
}
|
|
75
|
+
return Object.assign(parsed, {
|
|
76
|
+
blockchain,
|
|
77
|
+
bridgeName: BridgeNameEnum.Hot
|
|
78
|
+
}, address === "native" ? { native: true } : { address });
|
|
79
|
+
}
|
|
80
|
+
async createWithdrawalIntents(args) {
|
|
81
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
82
|
+
assert(assetInfo != null, "Asset is not supported");
|
|
83
|
+
if (args.withdrawalParams.destinationMemo != null && args.withdrawalParams.destinationMemo !== "") throw new UnsupportedDestinationMemoError(assetInfo.blockchain, args.withdrawalParams.assetId);
|
|
84
|
+
const intents = [];
|
|
85
|
+
const feeAmount = getUnderlyingFee(args.feeEstimation, RouteEnum.HotBridge, "relayerFee");
|
|
86
|
+
const blockNumber = getUnderlyingFee(args.feeEstimation, RouteEnum.HotBridge, "blockNumber");
|
|
87
|
+
if (args.feeEstimation.quote !== null) intents.push({
|
|
88
|
+
intent: "token_diff",
|
|
89
|
+
diff: {
|
|
90
|
+
[args.feeEstimation.quote.defuse_asset_identifier_in]: `-${args.feeEstimation.quote.amount_in}`,
|
|
91
|
+
[args.feeEstimation.quote.defuse_asset_identifier_out]: args.feeEstimation.quote.amount_out
|
|
92
|
+
},
|
|
93
|
+
referral: args.referral
|
|
94
|
+
});
|
|
95
|
+
const isNative = "native" in assetInfo;
|
|
96
|
+
const amount = args.withdrawalParams.amount + (isNative ? feeAmount : 0n);
|
|
97
|
+
const intent = await this.hotSdk.buildGaslessWithdrawIntent({
|
|
98
|
+
feeToken: "native",
|
|
99
|
+
feeAmount,
|
|
100
|
+
blockNumber,
|
|
101
|
+
chain: toHotNetworkId(assetInfo.blockchain),
|
|
102
|
+
token: isNative ? "native" : assetInfo.address,
|
|
103
|
+
amount,
|
|
104
|
+
receiver: args.withdrawalParams.destinationAddress
|
|
105
|
+
});
|
|
106
|
+
assert(intent.amounts[0] === amount.toString(), "Amount is not correct");
|
|
107
|
+
if (intent.amounts.length === 2) assert(intent.amounts[1] === feeAmount.toString(), "Amount is not correct");
|
|
108
|
+
const mtWithdrawIntent = intent;
|
|
109
|
+
mtWithdrawIntent.min_gas = MIN_GAS_AMOUNT;
|
|
110
|
+
intents.push(mtWithdrawIntent);
|
|
111
|
+
return intents;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Hot bridge validates trustlines for Stellar addresses.
|
|
115
|
+
* For Stellar chains, checks if the destination address has the required trustline.
|
|
116
|
+
* @throws {TrustlineNotFoundError} If Stellar destination address lacks required trustline
|
|
117
|
+
*/
|
|
118
|
+
async validateWithdrawal(args) {
|
|
119
|
+
const assetInfo = this.parseAssetId(args.assetId);
|
|
120
|
+
assert(assetInfo != null, "Asset is not supported");
|
|
121
|
+
hotBlockchainInvariant(assetInfo.blockchain);
|
|
122
|
+
if (validateAddress(args.destinationAddress, assetInfo.blockchain) === false) throw new InvalidDestinationAddressForWithdrawalError(args.destinationAddress, assetInfo.blockchain);
|
|
123
|
+
if (assetInfo.blockchain === Chains.Stellar) {
|
|
124
|
+
const token = "native" in assetInfo ? "native" : assetInfo.address;
|
|
125
|
+
if (!await this.hotSdk.stellar.isTrustlineExists(args.destinationAddress, token)) throw new TrustlineNotFoundError(args.destinationAddress, args.assetId, assetInfo.blockchain, token);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async estimateWithdrawalFee(args) {
|
|
129
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
130
|
+
assert(assetInfo != null, "Asset is not supported");
|
|
131
|
+
hotBlockchainInvariant(assetInfo.blockchain);
|
|
132
|
+
const feeAssetId = getFeeAssetIdForChain(assetInfo.blockchain);
|
|
133
|
+
const { gasPrice: feeAmount, blockNumber } = await withTimeout(async () => {
|
|
134
|
+
const result = await this.hotSdk.getGaslessWithdrawFee({
|
|
135
|
+
chain: toHotNetworkId(assetInfo.blockchain),
|
|
136
|
+
token: "native" in assetInfo ? "native" : assetInfo.address,
|
|
137
|
+
receiver: args.withdrawalParams.destinationAddress
|
|
138
|
+
});
|
|
139
|
+
if (assetInfo.blockchain === Chains.Plasma && args.withdrawalParams.assetId !== feeAssetId) result.gasPrice *= 20n;
|
|
140
|
+
return result;
|
|
141
|
+
}, {
|
|
142
|
+
errorInstance: new HotWithdrawalApiFeeRequestTimeoutError(),
|
|
143
|
+
timeout: typeof window !== "undefined" ? 1e4 : 3e3
|
|
144
|
+
});
|
|
145
|
+
const feeQuote = args.withdrawalParams.assetId === feeAssetId || feeAmount === 0n ? null : await getFeeQuote({
|
|
146
|
+
feeAmount,
|
|
147
|
+
feeAssetId,
|
|
148
|
+
tokenAssetId: args.withdrawalParams.assetId,
|
|
149
|
+
logger: args.logger,
|
|
150
|
+
envConfig: this.envConfig,
|
|
151
|
+
quoteOptions: args.quoteOptions,
|
|
152
|
+
solverRelayApiKey: this.solverRelayApiKey
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
amount: feeQuote ? BigInt(feeQuote.amount_in) : feeAmount,
|
|
156
|
+
quote: feeQuote,
|
|
157
|
+
underlyingFees: { [RouteEnum.HotBridge]: {
|
|
158
|
+
relayerFee: feeAmount,
|
|
159
|
+
blockNumber
|
|
160
|
+
} }
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
createWithdrawalIdentifier(args) {
|
|
164
|
+
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
165
|
+
assert(assetInfo != null, "Asset is not supported");
|
|
166
|
+
return {
|
|
167
|
+
landingChain: assetInfo.blockchain,
|
|
168
|
+
index: args.index,
|
|
169
|
+
withdrawalParams: args.withdrawalParams,
|
|
170
|
+
tx: args.tx
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async describeWithdrawal(args) {
|
|
174
|
+
const cacheKey = this.getNoncesCacheKey(args.tx);
|
|
175
|
+
const nonces = await this.noncesCache.fetch(cacheKey, { context: args.tx });
|
|
176
|
+
if (nonces == null) throw new HotWithdrawalNotFoundError(args.tx.hash, args.index);
|
|
177
|
+
const nonce = nonces[args.index];
|
|
178
|
+
if (nonce == null) throw new HotWithdrawalNotFoundError(args.tx.hash, args.index);
|
|
179
|
+
const status = await this.hotSdk.getGaslessWithdrawStatus(nonce.toString());
|
|
180
|
+
if (status === HotWithdrawStatus.Canceled) return {
|
|
181
|
+
status: "failed",
|
|
182
|
+
reason: "Withdrawal was cancelled"
|
|
183
|
+
};
|
|
184
|
+
if (status === HotWithdrawStatus.Completed) return {
|
|
185
|
+
status: "completed",
|
|
186
|
+
txHash: null
|
|
187
|
+
};
|
|
188
|
+
if (typeof status === "string") {
|
|
189
|
+
if (!isHex(status)) {
|
|
190
|
+
args.logger?.warn("HOT Bridge incorrect destination tx hash detected", { value: status });
|
|
191
|
+
return {
|
|
192
|
+
status: "completed",
|
|
193
|
+
txHash: null
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
status: "completed",
|
|
198
|
+
txHash: formatTxHash(status, args.landingChain)
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const apiHash = await this.fetchWithdrawalHashFromApi(args.tx.hash, nonce, args.logger);
|
|
202
|
+
if (apiHash != null) return {
|
|
203
|
+
status: "completed",
|
|
204
|
+
txHash: formatTxHash(apiHash, args.landingChain)
|
|
205
|
+
};
|
|
206
|
+
return { status: "pending" };
|
|
207
|
+
}
|
|
208
|
+
async fetchWithdrawalHashFromApi(nearTxHash, nonce, logger) {
|
|
209
|
+
try {
|
|
210
|
+
const data = await (await withTimeout(() => this.hotSdk.api.requestApi(`/api/v1/evm/bridge_withdrawal_hash?near_trx=${nearTxHash}`, { method: "GET" }), { timeout: HotBridge$1.API_FALLBACK_TIMEOUT_MS })).json();
|
|
211
|
+
const parseResult = v.safeParse(HotApiWithdrawalResponseSchema, data);
|
|
212
|
+
if (!parseResult.success) {
|
|
213
|
+
logger?.debug("HOT API response parse failed", { issues: parseResult.issues });
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
const withdrawal = parseResult.output.withdrawals.find((w) => w.nonce === nonce.toString());
|
|
217
|
+
if (withdrawal?.hash) {
|
|
218
|
+
const hash = withdrawal.hash.replace(/^0x/, "");
|
|
219
|
+
if (isHex(hash)) {
|
|
220
|
+
logger?.info("HOT withdrawal hash found via API fallback", {
|
|
221
|
+
nearTxHash,
|
|
222
|
+
nonce: nonce.toString()
|
|
223
|
+
});
|
|
224
|
+
return hash;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
logger?.debug("HOT API fallback failed", {
|
|
230
|
+
error,
|
|
231
|
+
nearTxHash
|
|
232
|
+
});
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
//#endregion
|
|
239
|
+
export { HotBridge$1 as HotBridge };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const require_errors = require('../../classes/errors.cjs');
|
|
2
|
+
const require_route_enum = require('../../constants/route-enum.cjs');
|
|
3
|
+
const require_caip2 = require('../../lib/caip2.cjs');
|
|
4
|
+
const require_validateAddress = require('../../lib/validateAddress.cjs');
|
|
5
|
+
|
|
6
|
+
//#region src/bridges/intents-bridge/intents-bridge.ts
|
|
7
|
+
var IntentsBridge = class {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.route = require_route_enum.RouteEnum.InternalTransfer;
|
|
10
|
+
}
|
|
11
|
+
is(routeConfig) {
|
|
12
|
+
return routeConfig.route === this.route;
|
|
13
|
+
}
|
|
14
|
+
async supports(params) {
|
|
15
|
+
if ("routeConfig" in params && params.routeConfig != null) return this.is(params.routeConfig);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
parseAssetId() {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
createWithdrawalIntents(args) {
|
|
22
|
+
const intents = [{
|
|
23
|
+
intent: "transfer",
|
|
24
|
+
receiver_id: args.withdrawalParams.destinationAddress,
|
|
25
|
+
tokens: { [args.withdrawalParams.assetId]: args.withdrawalParams.amount.toString() }
|
|
26
|
+
}];
|
|
27
|
+
return Promise.resolve(intents);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Intents bridge doesn't have withdrawal restrictions.
|
|
31
|
+
*/
|
|
32
|
+
async validateWithdrawal(args) {
|
|
33
|
+
if (require_validateAddress.validateAddress(args.destinationAddress, require_caip2.Chains.Near) === false) throw new require_errors.InvalidDestinationAddressForWithdrawalError(args.destinationAddress, "near-intents");
|
|
34
|
+
}
|
|
35
|
+
async estimateWithdrawalFee() {
|
|
36
|
+
return {
|
|
37
|
+
amount: 0n,
|
|
38
|
+
quote: null,
|
|
39
|
+
underlyingFees: { [require_route_enum.RouteEnum.InternalTransfer]: null }
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
createWithdrawalIdentifier(args) {
|
|
43
|
+
return {
|
|
44
|
+
landingChain: require_caip2.Chains.Near,
|
|
45
|
+
index: args.index,
|
|
46
|
+
withdrawalParams: args.withdrawalParams,
|
|
47
|
+
tx: args.tx
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async describeWithdrawal(args) {
|
|
51
|
+
return {
|
|
52
|
+
status: "completed",
|
|
53
|
+
txHash: args.tx.hash
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
exports.IntentsBridge = IntentsBridge;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { InvalidDestinationAddressForWithdrawalError } from "../../classes/errors.js";
|
|
2
|
+
import { RouteEnum } from "../../constants/route-enum.js";
|
|
3
|
+
import { Chains } from "../../lib/caip2.js";
|
|
4
|
+
import { validateAddress } from "../../lib/validateAddress.js";
|
|
5
|
+
|
|
6
|
+
//#region src/bridges/intents-bridge/intents-bridge.ts
|
|
7
|
+
var IntentsBridge = class {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.route = RouteEnum.InternalTransfer;
|
|
10
|
+
}
|
|
11
|
+
is(routeConfig) {
|
|
12
|
+
return routeConfig.route === this.route;
|
|
13
|
+
}
|
|
14
|
+
async supports(params) {
|
|
15
|
+
if ("routeConfig" in params && params.routeConfig != null) return this.is(params.routeConfig);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
parseAssetId() {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
createWithdrawalIntents(args) {
|
|
22
|
+
const intents = [{
|
|
23
|
+
intent: "transfer",
|
|
24
|
+
receiver_id: args.withdrawalParams.destinationAddress,
|
|
25
|
+
tokens: { [args.withdrawalParams.assetId]: args.withdrawalParams.amount.toString() }
|
|
26
|
+
}];
|
|
27
|
+
return Promise.resolve(intents);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Intents bridge doesn't have withdrawal restrictions.
|
|
31
|
+
*/
|
|
32
|
+
async validateWithdrawal(args) {
|
|
33
|
+
if (validateAddress(args.destinationAddress, Chains.Near) === false) throw new InvalidDestinationAddressForWithdrawalError(args.destinationAddress, "near-intents");
|
|
34
|
+
}
|
|
35
|
+
async estimateWithdrawalFee() {
|
|
36
|
+
return {
|
|
37
|
+
amount: 0n,
|
|
38
|
+
quote: null,
|
|
39
|
+
underlyingFees: { [RouteEnum.InternalTransfer]: null }
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
createWithdrawalIdentifier(args) {
|
|
43
|
+
return {
|
|
44
|
+
landingChain: Chains.Near,
|
|
45
|
+
index: args.index,
|
|
46
|
+
withdrawalParams: args.withdrawalParams,
|
|
47
|
+
tx: args.tx
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async describeWithdrawal(args) {
|
|
51
|
+
return {
|
|
52
|
+
status: "completed",
|
|
53
|
+
txHash: args.tx.hash
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { IntentsBridge };
|