@defuse-protocol/intents-sdk 0.81.0 → 0.82.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.
@@ -6,39 +6,28 @@ let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils")
6
6
  let valibot = require("valibot");
7
7
  valibot = require_rolldown_runtime.__toESM(valibot);
8
8
  let _omni_bridge_core = require("@omni-bridge/core");
9
- let _omni_bridge_near = require("@omni-bridge/near");
10
9
 
11
10
  //#region src/bridges/omni-bridge/omni-bridge-utils.ts
12
- function createWithdrawIntentsPrimitive(params) {
13
- const { contractId: tokenAccountId, standard } = _defuse_protocol_internal_utils.utils.parseDefuseAssetId(params.assetId);
14
- (0, _defuse_protocol_internal_utils.assert)(standard === "nep141", "Only NEP-141 is supported");
15
- const recipient = (0, _omni_bridge_core.omniAddress)(params.omniChainKind, params.destinationAddress);
16
- let msg = "";
11
+ /**
12
+ * Lays a calculated withdrawal out as intents.
13
+ *
14
+ * It takes the result of `deriveOmniWithdrawIntentParams` rather than the inputs to it, so
15
+ * there is one calculation and no way to hand it a value that was worked out some other way.
16
+ * That matters most for the amount: a UTXO chain has already added its fees to it, and doing
17
+ * that twice would send more than the caller asked for.
18
+ */
19
+ function createWithdrawIntentsPrimitive({ tokenAccountId, recipient, msg, externalId, storageDepositAccountId, amount, nativeFee, storageDepositAmount }) {
17
20
  const ftWithdrawPayload = {
18
21
  recipient,
19
22
  fee: "0",
20
- native_token_fee: params.nativeFee.toString(),
21
- external_id: crypto.randomUUID()
23
+ native_token_fee: nativeFee.toString(),
24
+ external_id: externalId
22
25
  };
23
- if (isUtxoChain(params.omniChainKind)) {
24
- (0, _defuse_protocol_internal_utils.assert)(params.utxoMaxGasFee !== null && params.utxoMaxGasFee > 0n, `Invalid utxo max gas fee: expected > 0, got ${params.utxoMaxGasFee}`);
25
- msg = JSON.stringify({ MaxGasFee: params.utxoMaxGasFee.toString() });
26
- ftWithdrawPayload.msg = msg;
27
- }
26
+ if (msg !== "") ftWithdrawPayload.msg = msg;
28
27
  const intents = [];
29
- if (params.nativeFee > 0n) intents.push({
30
- deposit_for_account_id: (0, _omni_bridge_near.calculateStorageAccountId)({
31
- token: `near:${tokenAccountId}`,
32
- amount: params.amount,
33
- recipient,
34
- fee: {
35
- fee: 0n,
36
- native_fee: params.nativeFee
37
- },
38
- sender: `near:${params.intentsContract}`,
39
- msg
40
- }, ftWithdrawPayload.external_id),
41
- amount: params.nativeFee.toString(),
28
+ if (storageDepositAccountId !== null) intents.push({
29
+ deposit_for_account_id: storageDepositAccountId,
30
+ amount: nativeFee.toString(),
42
31
  contract_id: require_omni_bridge_constants.OMNI_BRIDGE_CONTRACT,
43
32
  intent: "storage_deposit"
44
33
  });
@@ -46,8 +35,8 @@ function createWithdrawIntentsPrimitive(params) {
46
35
  intent: "ft_withdraw",
47
36
  token: tokenAccountId,
48
37
  receiver_id: require_omni_bridge_constants.OMNI_BRIDGE_CONTRACT,
49
- amount: params.amount.toString(),
50
- storage_deposit: params.storageDepositAmount > 0n ? params.storageDepositAmount.toString() : void 0,
38
+ amount: amount.toString(),
39
+ storage_deposit: storageDepositAmount > 0n ? storageDepositAmount.toString() : void 0,
51
40
  msg: JSON.stringify(ftWithdrawPayload),
52
41
  min_gas: require_omni_bridge_constants.MIN_GAS_AMOUNT
53
42
  });
@@ -71,16 +60,9 @@ const CHAIN_MAPPINGS = [
71
60
  [require_caip2.Chains.Aptos, _omni_bridge_core.ChainKind.Aptos],
72
61
  [require_caip2.Chains.HyperEvm, _omni_bridge_core.ChainKind.HlEvm]
73
62
  ];
74
- function caip2ToChainKind(network) {
75
- return CHAIN_MAPPINGS.find(([chain]) => chain === network)?.[1] ?? null;
76
- }
77
63
  function chainKindToCaip2(network) {
78
64
  return CHAIN_MAPPINGS.find(([_, kind]) => kind === network)?.[0] ?? null;
79
65
  }
80
- const UTXO_CHAINS = [_omni_bridge_core.ChainKind.Btc];
81
- function isUtxoChain(network) {
82
- return UTXO_CHAINS.includes(network);
83
- }
84
66
  function poaContractIdToChainKind(contractId) {
85
67
  return require_poa_tokens_migrated_to_omni_bridge.POA_TOKENS_MIGRATED_TO_OMNI_BRIDGE[contractId] ?? null;
86
68
  }
@@ -149,12 +131,11 @@ async function getTokenDecimals(nearProvider, tokenAddress) {
149
131
  }
150
132
 
151
133
  //#endregion
152
- exports.caip2ToChainKind = caip2ToChainKind;
134
+ exports.CHAIN_MAPPINGS = CHAIN_MAPPINGS;
153
135
  exports.chainKindToCaip2 = chainKindToCaip2;
154
136
  exports.createWithdrawIntentsPrimitive = createWithdrawIntentsPrimitive;
155
137
  exports.getAccountOmniStorageBalance = getAccountOmniStorageBalance;
156
138
  exports.getBridgedToken = getBridgedToken;
157
139
  exports.getTokenDecimals = getTokenDecimals;
158
- exports.isUtxoChain = isUtxoChain;
159
140
  exports.poaContractIdToChainKind = poaContractIdToChainKind;
160
141
  exports.validateOmniToken = validateOmniToken;
@@ -1,42 +1,31 @@
1
1
  import { Chains } from "../../lib/caip2.js";
2
2
  import { MIN_GAS_AMOUNT, OMNI_BRIDGE_CONTRACT } from "./omni-bridge-constants.js";
3
3
  import { POA_TOKENS_MIGRATED_TO_OMNI_BRIDGE } from "../../constants/poa-tokens-migrated-to-omni-bridge.js";
4
- import { assert, utils } from "@defuse-protocol/internal-utils";
4
+ import { utils } from "@defuse-protocol/internal-utils";
5
5
  import * as v from "valibot";
6
- import { ChainKind, getChain, isBridgeToken, omniAddress } from "@omni-bridge/core";
7
- import { calculateStorageAccountId } from "@omni-bridge/near";
6
+ import { ChainKind, getChain, isBridgeToken } from "@omni-bridge/core";
8
7
 
9
8
  //#region src/bridges/omni-bridge/omni-bridge-utils.ts
10
- function createWithdrawIntentsPrimitive(params) {
11
- const { contractId: tokenAccountId, standard } = utils.parseDefuseAssetId(params.assetId);
12
- assert(standard === "nep141", "Only NEP-141 is supported");
13
- const recipient = omniAddress(params.omniChainKind, params.destinationAddress);
14
- let msg = "";
9
+ /**
10
+ * Lays a calculated withdrawal out as intents.
11
+ *
12
+ * It takes the result of `deriveOmniWithdrawIntentParams` rather than the inputs to it, so
13
+ * there is one calculation and no way to hand it a value that was worked out some other way.
14
+ * That matters most for the amount: a UTXO chain has already added its fees to it, and doing
15
+ * that twice would send more than the caller asked for.
16
+ */
17
+ function createWithdrawIntentsPrimitive({ tokenAccountId, recipient, msg, externalId, storageDepositAccountId, amount, nativeFee, storageDepositAmount }) {
15
18
  const ftWithdrawPayload = {
16
19
  recipient,
17
20
  fee: "0",
18
- native_token_fee: params.nativeFee.toString(),
19
- external_id: crypto.randomUUID()
21
+ native_token_fee: nativeFee.toString(),
22
+ external_id: externalId
20
23
  };
21
- if (isUtxoChain(params.omniChainKind)) {
22
- assert(params.utxoMaxGasFee !== null && params.utxoMaxGasFee > 0n, `Invalid utxo max gas fee: expected > 0, got ${params.utxoMaxGasFee}`);
23
- msg = JSON.stringify({ MaxGasFee: params.utxoMaxGasFee.toString() });
24
- ftWithdrawPayload.msg = msg;
25
- }
24
+ if (msg !== "") ftWithdrawPayload.msg = msg;
26
25
  const intents = [];
27
- if (params.nativeFee > 0n) intents.push({
28
- deposit_for_account_id: calculateStorageAccountId({
29
- token: `near:${tokenAccountId}`,
30
- amount: params.amount,
31
- recipient,
32
- fee: {
33
- fee: 0n,
34
- native_fee: params.nativeFee
35
- },
36
- sender: `near:${params.intentsContract}`,
37
- msg
38
- }, ftWithdrawPayload.external_id),
39
- amount: params.nativeFee.toString(),
26
+ if (storageDepositAccountId !== null) intents.push({
27
+ deposit_for_account_id: storageDepositAccountId,
28
+ amount: nativeFee.toString(),
40
29
  contract_id: OMNI_BRIDGE_CONTRACT,
41
30
  intent: "storage_deposit"
42
31
  });
@@ -44,8 +33,8 @@ function createWithdrawIntentsPrimitive(params) {
44
33
  intent: "ft_withdraw",
45
34
  token: tokenAccountId,
46
35
  receiver_id: OMNI_BRIDGE_CONTRACT,
47
- amount: params.amount.toString(),
48
- storage_deposit: params.storageDepositAmount > 0n ? params.storageDepositAmount.toString() : void 0,
36
+ amount: amount.toString(),
37
+ storage_deposit: storageDepositAmount > 0n ? storageDepositAmount.toString() : void 0,
49
38
  msg: JSON.stringify(ftWithdrawPayload),
50
39
  min_gas: MIN_GAS_AMOUNT
51
40
  });
@@ -69,16 +58,9 @@ const CHAIN_MAPPINGS = [
69
58
  [Chains.Aptos, ChainKind.Aptos],
70
59
  [Chains.HyperEvm, ChainKind.HlEvm]
71
60
  ];
72
- function caip2ToChainKind(network) {
73
- return CHAIN_MAPPINGS.find(([chain]) => chain === network)?.[1] ?? null;
74
- }
75
61
  function chainKindToCaip2(network) {
76
62
  return CHAIN_MAPPINGS.find(([_, kind]) => kind === network)?.[0] ?? null;
77
63
  }
78
- const UTXO_CHAINS = [ChainKind.Btc];
79
- function isUtxoChain(network) {
80
- return UTXO_CHAINS.includes(network);
81
- }
82
64
  function poaContractIdToChainKind(contractId) {
83
65
  return POA_TOKENS_MIGRATED_TO_OMNI_BRIDGE[contractId] ?? null;
84
66
  }
@@ -147,4 +129,4 @@ async function getTokenDecimals(nearProvider, tokenAddress) {
147
129
  }
148
130
 
149
131
  //#endregion
150
- export { caip2ToChainKind, chainKindToCaip2, createWithdrawIntentsPrimitive, getAccountOmniStorageBalance, getBridgedToken, getTokenDecimals, isUtxoChain, poaContractIdToChainKind, validateOmniToken };
132
+ export { CHAIN_MAPPINGS, chainKindToCaip2, createWithdrawIntentsPrimitive, getAccountOmniStorageBalance, getBridgedToken, getTokenDecimals, poaContractIdToChainKind, validateOmniToken };
@@ -1,7 +1,6 @@
1
1
  const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
2
2
  const require_errors = require('../../classes/errors.cjs');
3
3
  const require_route_enum = require('../../constants/route-enum.cjs');
4
- const require_caip2 = require('../../lib/caip2.cjs');
5
4
  const require_estimate_fee = require('../../lib/estimate-fee.cjs');
6
5
  const require_parse_defuse_asset_id = require('../../lib/parse-defuse-asset-id.cjs');
7
6
  const require_validateAddress = require('../../lib/validateAddress.cjs');
@@ -11,6 +10,7 @@ const require_error = require('./error.cjs');
11
10
  const require_omni_bridge_constants = require('./omni-bridge-constants.cjs');
12
11
  const require_poa_tokens_migrated_to_omni_bridge = require('../../constants/poa-tokens-migrated-to-omni-bridge.cjs');
13
12
  const require_omni_bridge_utils = require('./omni-bridge-utils.cjs');
13
+ const require_src_bridges_omni_bridge_omni_withdraw_params = require('./omni-withdraw-params.cjs');
14
14
  let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
15
15
  let lru_cache = require("lru-cache");
16
16
  let _isaacs_ttlcache = require("@isaacs/ttlcache");
@@ -55,7 +55,7 @@ var OmniBridge = class {
55
55
  let omniChainKind = null;
56
56
  let caip2Chain = null;
57
57
  if (this.targetChainSpecified(params.routeConfig)) {
58
- omniChainKind = require_omni_bridge_utils.caip2ToChainKind(params.routeConfig.chain);
58
+ omniChainKind = require_src_bridges_omni_bridge_omni_withdraw_params.caip2ToChainKind(params.routeConfig.chain);
59
59
  if (omniChainKind === null) throw new require_errors.UnsupportedAssetIdError(params.assetId, `Chain ${params.routeConfig.chain} is not supported in Omni Bridge.`);
60
60
  caip2Chain = params.routeConfig.chain;
61
61
  } else {
@@ -89,7 +89,7 @@ var OmniBridge = class {
89
89
  let omniChainKind = null;
90
90
  let blockchain = null;
91
91
  if (this.targetChainSpecified(routeConfig)) {
92
- omniChainKind = require_omni_bridge_utils.caip2ToChainKind(routeConfig.chain);
92
+ omniChainKind = require_src_bridges_omni_bridge_omni_withdraw_params.caip2ToChainKind(routeConfig.chain);
93
93
  blockchain = routeConfig.chain;
94
94
  } else {
95
95
  omniChainKind = this.isPoaTokenMigratedToOmniBridge(parsed.contractId) ? require_omni_bridge_utils.poaContractIdToChainKind(parsed.contractId) : (0, _omni_bridge_core.parseOriginChain)(parsed.contractId);
@@ -106,7 +106,7 @@ var OmniBridge = class {
106
106
  async createWithdrawalIntents(args) {
107
107
  const assetInfo = this.makeAssetInfo(args.withdrawalParams.assetId, args.withdrawalParams.routeConfig);
108
108
  (0, _defuse_protocol_internal_utils.assert)(assetInfo !== null, `Asset ${args.withdrawalParams.assetId} is not supported by Omni Bridge`);
109
- const omniChainKind = require_omni_bridge_utils.caip2ToChainKind(assetInfo.blockchain);
109
+ const omniChainKind = require_src_bridges_omni_bridge_omni_withdraw_params.caip2ToChainKind(assetInfo.blockchain);
110
110
  (0, _defuse_protocol_internal_utils.assert)(omniChainKind !== null, `Chain ${assetInfo.blockchain} is not supported by Omni Bridge`);
111
111
  const intents = [];
112
112
  if (args.feeEstimation.quote !== null) intents.push({
@@ -117,42 +117,14 @@ var OmniBridge = class {
117
117
  },
118
118
  referral: args.referral
119
119
  });
120
- const relayerFee = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "relayerFee");
121
- (0, _defuse_protocol_internal_utils.assert)(relayerFee >= 0n, `Invalid Omni bridge relayer fee: expected >= 0, got ${relayerFee}`);
122
- let amount = args.withdrawalParams.amount;
123
- let utxoMaxGasFee = null;
124
- /**
125
- * UTXO withdrawals add protocol + max gas fees to the intent amount since they're paid
126
- * from the withdrawn asset, not wrap.near.
127
- *
128
- * Example with nep141:nbtc.bridge.near (made-up values):
129
- * utxoFees = 50 + 50 = 100, relayerFee = 2 (excluded; paid in wrap.near)
130
- *
131
- * feeInclusive=false:
132
- * - amount = 4000 → intent = 4000 + 100 = 4100 → user receives 4000
133
- *
134
- * feeInclusive=true:
135
- * - amount = 3898 (4000 − 102) → intent = 3898 + 100 = 3998 → user receives 3898
136
- **/
137
- if (require_omni_bridge_utils.isUtxoChain(omniChainKind)) {
138
- utxoMaxGasFee = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "utxoMaxGasFee");
139
- const utxoProtocolFee = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "utxoProtocolFee");
140
- (0, _defuse_protocol_internal_utils.assert)(utxoMaxGasFee !== void 0 && utxoMaxGasFee > 0n, `Invalid Omni Bridge utxo max gas fee: expected > 0, got ${utxoMaxGasFee}`);
141
- (0, _defuse_protocol_internal_utils.assert)(utxoProtocolFee !== void 0 && utxoProtocolFee > 0n, `Invalid Omni Bridge utxo protocol fee: expected > 0, got ${utxoProtocolFee}`);
142
- amount += utxoMaxGasFee + utxoProtocolFee;
143
- }
144
- let destinationAddress = args.withdrawalParams.destinationAddress;
145
- if (assetInfo.blockchain === require_caip2.Chains.Bitcoin && /^bc1/i.test(destinationAddress)) destinationAddress = destinationAddress.toLowerCase();
146
- intents.push(...require_omni_bridge_utils.createWithdrawIntentsPrimitive({
120
+ intents.push(...require_omni_bridge_utils.createWithdrawIntentsPrimitive(require_src_bridges_omni_bridge_omni_withdraw_params.deriveOmniWithdrawIntentParams({
147
121
  assetId: args.withdrawalParams.assetId,
148
- destinationAddress,
149
- amount,
122
+ destinationAddress: args.withdrawalParams.destinationAddress,
123
+ actualAmount: args.withdrawalParams.amount,
150
124
  omniChainKind,
151
125
  intentsContract: this.envConfig.contractID,
152
- nativeFee: relayerFee,
153
- storageDepositAmount: require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "storageDepositFee"),
154
- utxoMaxGasFee
155
- }));
126
+ feeEstimation: args.feeEstimation
127
+ })));
156
128
  return Promise.resolve(intents);
157
129
  }
158
130
  async validateWithdrawal(args) {
@@ -162,7 +134,7 @@ var OmniBridge = class {
162
134
  const assetInfo = this.makeAssetInfo(args.assetId, args.routeConfig);
163
135
  (0, _defuse_protocol_internal_utils.assert)(assetInfo !== null, `Asset ${args.assetId} is not supported by Omni Bridge`);
164
136
  if (require_validateAddress.validateAddress(args.destinationAddress, assetInfo.blockchain) === false) throw new require_errors.InvalidDestinationAddressForWithdrawalError(args.destinationAddress, assetInfo.blockchain);
165
- const omniChainKind = require_omni_bridge_utils.caip2ToChainKind(assetInfo.blockchain);
137
+ const omniChainKind = require_src_bridges_omni_bridge_omni_withdraw_params.caip2ToChainKind(assetInfo.blockchain);
166
138
  (0, _defuse_protocol_internal_utils.assert)(omniChainKind !== null, `Chain ${assetInfo.blockchain} is not supported by Omni Bridge`);
167
139
  const destTokenOmniAddress = await this.getCachedDestinationTokenAddress(assetInfo.contractId, omniChainKind);
168
140
  if (destTokenOmniAddress === null) throw new require_error.TokenNotFoundInDestinationChainError(args.assetId, assetInfo.blockchain);
@@ -176,7 +148,7 @@ var OmniBridge = class {
176
148
  }
177
149
  const intentsStorageBalance = await this.getCachedIntentsStorageBalance();
178
150
  if (intentsStorageBalance <= require_omni_bridge_constants.MIN_STORAGE_BALANCE_FOR_INTENTS_NEAR) throw new require_error.IntentsNearOmniAvailableBalanceTooLowError(intentsStorageBalance.toString());
179
- const utxoChainWithdrawal = require_omni_bridge_utils.isUtxoChain(omniChainKind);
151
+ const utxoChainWithdrawal = require_src_bridges_omni_bridge_omni_withdraw_params.isUtxoChain(omniChainKind);
180
152
  if (!utxoChainWithdrawal && !isFeeSubsidized) {
181
153
  const relayerFee = require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "relayerFee");
182
154
  (0, _defuse_protocol_internal_utils.assert)(require_estimate_fee.getUnderlyingFee(args.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "relayerFee") > 0n, `Invalid Omni Bridge relayer fee for non UTXO chain withdrawal: expected > 0, got ${relayerFee}`);
@@ -202,7 +174,7 @@ var OmniBridge = class {
202
174
  async estimateWithdrawalFee(args) {
203
175
  const assetInfo = this.makeAssetInfo(args.withdrawalParams.assetId, args.withdrawalParams.routeConfig);
204
176
  (0, _defuse_protocol_internal_utils.assert)(assetInfo !== null, `Asset ${args.withdrawalParams.assetId} is not supported by Omni Bridge`);
205
- const omniChainKind = require_omni_bridge_utils.caip2ToChainKind(assetInfo.blockchain);
177
+ const omniChainKind = require_src_bridges_omni_bridge_omni_withdraw_params.caip2ToChainKind(assetInfo.blockchain);
206
178
  (0, _defuse_protocol_internal_utils.assert)(omniChainKind !== null, `Chain ${assetInfo.blockchain} is not supported by Omni Bridge`);
207
179
  const fee = await (0, _defuse_protocol_internal_utils.withTimeout)(() => this.omniBridgeAPI.getFee((0, _omni_bridge_core.omniAddress)(_omni_bridge_core.ChainKind.Near, this.envConfig.contractID), (0, _omni_bridge_core.omniAddress)(omniChainKind, args.withdrawalParams.destinationAddress), (0, _omni_bridge_core.omniAddress)(_omni_bridge_core.ChainKind.Near, assetInfo.contractId), args.withdrawalParams.amount), {
208
180
  timeout: typeof window !== "undefined" ? 1e4 : 3e3,
@@ -240,7 +212,7 @@ var OmniBridge = class {
240
212
  });
241
213
  amount += BigInt(quote.amount_in);
242
214
  }
243
- if (require_omni_bridge_utils.isUtxoChain(omniChainKind)) {
215
+ if (require_src_bridges_omni_bridge_omni_withdraw_params.isUtxoChain(omniChainKind)) {
244
216
  (0, _defuse_protocol_internal_utils.assert)(fee.gas_fee !== null && fee.gas_fee !== void 0 && fee.gas_fee > 0n, `Invalid Omni Bridge utxo gas fee: expected > 0, got ${fee.gas_fee}`);
245
217
  (0, _defuse_protocol_internal_utils.assert)(fee.protocol_fee !== null && fee.protocol_fee !== void 0 && fee.protocol_fee > 0n, `Invalid Omni Bridge utxo protocol fee: expected > 0, got ${fee.protocol_fee}`);
246
218
  amount += fee.gas_fee + fee.protocol_fee;
@@ -269,7 +241,7 @@ var OmniBridge = class {
269
241
  const destinationChain = (0, _omni_bridge_core.getChain)(transfer.recipient);
270
242
  let txHash = null;
271
243
  if ((0, _omni_bridge_core.isEvmChain)(destinationChain) || destinationChain === _omni_bridge_core.ChainKind.Sol || destinationChain === _omni_bridge_core.ChainKind.Fogo || destinationChain === _omni_bridge_core.ChainKind.Strk || destinationChain === _omni_bridge_core.ChainKind.Aptos) txHash = transfer.finalised?.transaction_hash;
272
- else if (require_omni_bridge_utils.isUtxoChain(destinationChain)) txHash = typeof window !== "undefined" ? transfer.utxo_meta?.pending_sign_id : transfer.finalised?.transaction_hash;
244
+ else if (require_src_bridges_omni_bridge_omni_withdraw_params.isUtxoChain(destinationChain)) txHash = typeof window !== "undefined" ? transfer.utxo_meta?.pending_sign_id : transfer.finalised?.transaction_hash;
273
245
  else return {
274
246
  status: "completed",
275
247
  txHash: null
@@ -1,6 +1,5 @@
1
1
  import { DestinationAddressMatchesTokenAddressError, InvalidDestinationAddressForWithdrawalError, MinWithdrawalAmountError, UnsupportedAssetIdError } from "../../classes/errors.js";
2
2
  import { RouteEnum } from "../../constants/route-enum.js";
3
- import { Chains } from "../../lib/caip2.js";
4
3
  import { getFeeQuote, getUnderlyingFee } from "../../lib/estimate-fee.js";
5
4
  import { parseDefuseAssetId } from "../../lib/parse-defuse-asset-id.js";
6
5
  import { validateAddress } from "../../lib/validateAddress.js";
@@ -9,7 +8,8 @@ import { compareAddresses } from "../../lib/compareAddresses.js";
9
8
  import { InsufficientUtxoForOmniBridgeWithdrawalError, IntentsNearOmniAvailableBalanceTooLowError, InvalidFeeValueError, OmniWithdrawalApiFeeRequestTimeoutError, TokenNotFoundInDestinationChainError } from "./error.js";
10
9
  import { FEE_SUBSIDIZED_TOKENS, INTENTS_STORAGE_BALANCE_CACHE_KEY, MIN_AMOUNT_SOL_OMNI_WITHDRAWAL, MIN_STORAGE_BALANCE_FOR_INTENTS_NEAR, NEAR_NATIVE_ASSET_ID, OMNI_BRIDGE_CONTRACT, SOL_OMNI_CONTRACT_ID } from "./omni-bridge-constants.js";
11
10
  import { POA_TOKENS_MIGRATED_TO_OMNI_BRIDGE } from "../../constants/poa-tokens-migrated-to-omni-bridge.js";
12
- import { caip2ToChainKind, chainKindToCaip2, createWithdrawIntentsPrimitive, getAccountOmniStorageBalance, getBridgedToken, getTokenDecimals, isUtxoChain, poaContractIdToChainKind, validateOmniToken } from "./omni-bridge-utils.js";
11
+ import { chainKindToCaip2, createWithdrawIntentsPrimitive, getAccountOmniStorageBalance, getBridgedToken, getTokenDecimals, poaContractIdToChainKind, validateOmniToken } from "./omni-bridge-utils.js";
12
+ import { caip2ToChainKind, deriveOmniWithdrawIntentParams, isUtxoChain } from "./omni-withdraw-params.js";
13
13
  import { assert, getNearNep141MinStorageBalance, getNearNep141StorageBalance, withTimeout } from "@defuse-protocol/internal-utils";
14
14
  import { LRUCache } from "lru-cache";
15
15
  import TTLCache from "@isaacs/ttlcache";
@@ -115,42 +115,14 @@ var OmniBridge = class {
115
115
  },
116
116
  referral: args.referral
117
117
  });
118
- const relayerFee = getUnderlyingFee(args.feeEstimation, RouteEnum.OmniBridge, "relayerFee");
119
- assert(relayerFee >= 0n, `Invalid Omni bridge relayer fee: expected >= 0, got ${relayerFee}`);
120
- let amount = args.withdrawalParams.amount;
121
- let utxoMaxGasFee = null;
122
- /**
123
- * UTXO withdrawals add protocol + max gas fees to the intent amount since they're paid
124
- * from the withdrawn asset, not wrap.near.
125
- *
126
- * Example with nep141:nbtc.bridge.near (made-up values):
127
- * utxoFees = 50 + 50 = 100, relayerFee = 2 (excluded; paid in wrap.near)
128
- *
129
- * feeInclusive=false:
130
- * - amount = 4000 → intent = 4000 + 100 = 4100 → user receives 4000
131
- *
132
- * feeInclusive=true:
133
- * - amount = 3898 (4000 − 102) → intent = 3898 + 100 = 3998 → user receives 3898
134
- **/
135
- if (isUtxoChain(omniChainKind)) {
136
- utxoMaxGasFee = getUnderlyingFee(args.feeEstimation, RouteEnum.OmniBridge, "utxoMaxGasFee");
137
- const utxoProtocolFee = getUnderlyingFee(args.feeEstimation, RouteEnum.OmniBridge, "utxoProtocolFee");
138
- assert(utxoMaxGasFee !== void 0 && utxoMaxGasFee > 0n, `Invalid Omni Bridge utxo max gas fee: expected > 0, got ${utxoMaxGasFee}`);
139
- assert(utxoProtocolFee !== void 0 && utxoProtocolFee > 0n, `Invalid Omni Bridge utxo protocol fee: expected > 0, got ${utxoProtocolFee}`);
140
- amount += utxoMaxGasFee + utxoProtocolFee;
141
- }
142
- let destinationAddress = args.withdrawalParams.destinationAddress;
143
- if (assetInfo.blockchain === Chains.Bitcoin && /^bc1/i.test(destinationAddress)) destinationAddress = destinationAddress.toLowerCase();
144
- intents.push(...createWithdrawIntentsPrimitive({
118
+ intents.push(...createWithdrawIntentsPrimitive(deriveOmniWithdrawIntentParams({
145
119
  assetId: args.withdrawalParams.assetId,
146
- destinationAddress,
147
- amount,
120
+ destinationAddress: args.withdrawalParams.destinationAddress,
121
+ actualAmount: args.withdrawalParams.amount,
148
122
  omniChainKind,
149
123
  intentsContract: this.envConfig.contractID,
150
- nativeFee: relayerFee,
151
- storageDepositAmount: getUnderlyingFee(args.feeEstimation, RouteEnum.OmniBridge, "storageDepositFee"),
152
- utxoMaxGasFee
153
- }));
124
+ feeEstimation: args.feeEstimation
125
+ })));
154
126
  return Promise.resolve(intents);
155
127
  }
156
128
  async validateWithdrawal(args) {
@@ -0,0 +1,72 @@
1
+ const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
2
+ const require_route_enum = require('../../constants/route-enum.cjs');
3
+ const require_estimate_fee = require('../../lib/estimate-fee.cjs');
4
+ const require_omni_bridge_utils = require('./omni-bridge-utils.cjs');
5
+ let _defuse_protocol_internal_utils = require("@defuse-protocol/internal-utils");
6
+ let _omni_bridge_core = require("@omni-bridge/core");
7
+ let _omni_bridge_near = require("@omni-bridge/near");
8
+
9
+ //#region src/bridges/omni-bridge/omni-withdraw-params.ts
10
+ /**
11
+ * Computes the values of an Omni withdrawal without building the intents. `OmniBridge` calls
12
+ * it too, so a caller that signs the payload elsewhere gets the same numbers.
13
+ * @param params.actualAmount Net of `feeEstimation.amount`. `IntentsSDK` subtracts it for a
14
+ * fee-inclusive withdrawal, so a caller that builds the payload itself has to do the same
15
+ * @param params.feeEstimation Read for every fee of the route, one of which raises the amount
16
+ * @param params.externalId Supply one to repeat an earlier call.
17
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes. Omit it and the function draws a
18
+ * random one
19
+ * @returns The values the `ft_withdraw` carries
20
+ */
21
+ function deriveOmniWithdrawIntentParams(params) {
22
+ const { contractId: tokenAccountId, standard } = _defuse_protocol_internal_utils.utils.parseDefuseAssetId(params.assetId);
23
+ (0, _defuse_protocol_internal_utils.assert)(standard === "nep141", "Only NEP-141 is supported");
24
+ const nativeFee = require_estimate_fee.getUnderlyingFee(params.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "relayerFee");
25
+ (0, _defuse_protocol_internal_utils.assert)(nativeFee >= 0n, `Invalid Omni bridge relayer fee: expected >= 0, got ${nativeFee}`);
26
+ const storageDepositAmount = require_estimate_fee.getUnderlyingFee(params.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "storageDepositFee");
27
+ let amount = params.actualAmount;
28
+ let msg = "";
29
+ if (isUtxoChain(params.omniChainKind)) {
30
+ const utxoMaxGasFee = require_estimate_fee.getUnderlyingFee(params.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "utxoMaxGasFee");
31
+ const utxoProtocolFee = require_estimate_fee.getUnderlyingFee(params.feeEstimation, require_route_enum.RouteEnum.OmniBridge, "utxoProtocolFee");
32
+ (0, _defuse_protocol_internal_utils.assert)(utxoMaxGasFee !== void 0 && utxoMaxGasFee > 0n, `Invalid Omni Bridge utxo max gas fee: expected > 0, got ${utxoMaxGasFee}`);
33
+ (0, _defuse_protocol_internal_utils.assert)(utxoProtocolFee !== void 0 && utxoProtocolFee > 0n, `Invalid Omni Bridge utxo protocol fee: expected > 0, got ${utxoProtocolFee}`);
34
+ amount += utxoMaxGasFee + utxoProtocolFee;
35
+ msg = JSON.stringify({ MaxGasFee: utxoMaxGasFee.toString() });
36
+ }
37
+ const destinationAddress = params.omniChainKind === _omni_bridge_core.ChainKind.Btc && /^bc1/i.test(params.destinationAddress) ? params.destinationAddress.toLowerCase() : params.destinationAddress;
38
+ const recipient = (0, _omni_bridge_core.omniAddress)(params.omniChainKind, destinationAddress);
39
+ const externalId = params.externalId ?? crypto.randomUUID();
40
+ return {
41
+ tokenAccountId,
42
+ recipient,
43
+ msg,
44
+ externalId,
45
+ amount,
46
+ nativeFee,
47
+ storageDepositAmount,
48
+ storageDepositAccountId: nativeFee > 0n ? (0, _omni_bridge_near.calculateStorageAccountId)({
49
+ token: `near:${tokenAccountId}`,
50
+ amount,
51
+ recipient,
52
+ fee: {
53
+ fee: 0n,
54
+ native_fee: nativeFee
55
+ },
56
+ sender: `near:${params.intentsContract}`,
57
+ msg
58
+ }, externalId) : null
59
+ };
60
+ }
61
+ function caip2ToChainKind(network) {
62
+ return require_omni_bridge_utils.CHAIN_MAPPINGS.find(([chain]) => chain === network)?.[1] ?? null;
63
+ }
64
+ const UTXO_CHAINS = [_omni_bridge_core.ChainKind.Btc];
65
+ function isUtxoChain(network) {
66
+ return UTXO_CHAINS.includes(network);
67
+ }
68
+
69
+ //#endregion
70
+ exports.caip2ToChainKind = caip2ToChainKind;
71
+ exports.deriveOmniWithdrawIntentParams = deriveOmniWithdrawIntentParams;
72
+ exports.isUtxoChain = isUtxoChain;
@@ -0,0 +1,60 @@
1
+ import { Chain } from "../../lib/caip2.cjs";
2
+ import { FeeEstimation } from "../../shared-types.cjs";
3
+ import { ChainKind, OmniAddress } from "@omni-bridge/core";
4
+
5
+ //#region src/bridges/omni-bridge/omni-withdraw-params.d.ts
6
+
7
+ /**
8
+ * The values an Omni withdrawal computes before it builds the intents.
9
+ *
10
+ * `storageDepositAccountId` is derived from `externalId`, and letter case takes part in that
11
+ * derivation, so recomputing any of these sends the native fee to a different account.
12
+ */
13
+ type OmniWithdrawIntentParams = {
14
+ /** The NEP-141 account of the asset. */
15
+ tokenAccountId: string;
16
+ recipient: OmniAddress;
17
+ /** Empty, except for a UTXO chain. Then it contains `MaxGasFee`. */
18
+ msg: string;
19
+ /**
20
+ * This value makes the storage account unique. The hash covers the rest of the transfer,
21
+ * so two withdrawals that match on every field would otherwise land on one account.
22
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes.
23
+ */
24
+ externalId: string;
25
+ /** The account that gets the native fee. Null if there is no native fee. */
26
+ storageDepositAccountId: string | null;
27
+ /**
28
+ * The amount the `ft_withdraw` carries. A UTXO chain adds its own fees to the amount the
29
+ * caller asked for, because they are paid from the asset and not from wrap.near.
30
+ */
31
+ amount: bigint;
32
+ /** The relayer fee. It goes in `native_token_fee`, and the storage deposit transfers it. */
33
+ nativeFee: bigint;
34
+ /** The `storage_deposit` of the `ft_withdraw`. Zero leaves the field out. */
35
+ storageDepositAmount: bigint;
36
+ };
37
+ /**
38
+ * Computes the values of an Omni withdrawal without building the intents. `OmniBridge` calls
39
+ * it too, so a caller that signs the payload elsewhere gets the same numbers.
40
+ * @param params.actualAmount Net of `feeEstimation.amount`. `IntentsSDK` subtracts it for a
41
+ * fee-inclusive withdrawal, so a caller that builds the payload itself has to do the same
42
+ * @param params.feeEstimation Read for every fee of the route, one of which raises the amount
43
+ * @param params.externalId Supply one to repeat an earlier call.
44
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes. Omit it and the function draws a
45
+ * random one
46
+ * @returns The values the `ft_withdraw` carries
47
+ */
48
+ declare function deriveOmniWithdrawIntentParams(params: {
49
+ assetId: string;
50
+ destinationAddress: string;
51
+ actualAmount: bigint;
52
+ omniChainKind: ChainKind;
53
+ intentsContract: string;
54
+ feeEstimation: FeeEstimation;
55
+ externalId?: string;
56
+ }): OmniWithdrawIntentParams;
57
+ declare function caip2ToChainKind(network: Chain): ChainKind | null;
58
+ declare function isUtxoChain(network: ChainKind): boolean;
59
+ //#endregion
60
+ export { OmniWithdrawIntentParams, caip2ToChainKind, deriveOmniWithdrawIntentParams, isUtxoChain };
@@ -0,0 +1,60 @@
1
+ import { Chain } from "../../lib/caip2.js";
2
+ import { FeeEstimation } from "../../shared-types.js";
3
+ import { ChainKind, OmniAddress } from "@omni-bridge/core";
4
+
5
+ //#region src/bridges/omni-bridge/omni-withdraw-params.d.ts
6
+
7
+ /**
8
+ * The values an Omni withdrawal computes before it builds the intents.
9
+ *
10
+ * `storageDepositAccountId` is derived from `externalId`, and letter case takes part in that
11
+ * derivation, so recomputing any of these sends the native fee to a different account.
12
+ */
13
+ type OmniWithdrawIntentParams = {
14
+ /** The NEP-141 account of the asset. */
15
+ tokenAccountId: string;
16
+ recipient: OmniAddress;
17
+ /** Empty, except for a UTXO chain. Then it contains `MaxGasFee`. */
18
+ msg: string;
19
+ /**
20
+ * This value makes the storage account unique. The hash covers the rest of the transfer,
21
+ * so two withdrawals that match on every field would otherwise land on one account.
22
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes.
23
+ */
24
+ externalId: string;
25
+ /** The account that gets the native fee. Null if there is no native fee. */
26
+ storageDepositAccountId: string | null;
27
+ /**
28
+ * The amount the `ft_withdraw` carries. A UTXO chain adds its own fees to the amount the
29
+ * caller asked for, because they are paid from the asset and not from wrap.near.
30
+ */
31
+ amount: bigint;
32
+ /** The relayer fee. It goes in `native_token_fee`, and the storage deposit transfers it. */
33
+ nativeFee: bigint;
34
+ /** The `storage_deposit` of the `ft_withdraw`. Zero leaves the field out. */
35
+ storageDepositAmount: bigint;
36
+ };
37
+ /**
38
+ * Computes the values of an Omni withdrawal without building the intents. `OmniBridge` calls
39
+ * it too, so a caller that signs the payload elsewhere gets the same numbers.
40
+ * @param params.actualAmount Net of `feeEstimation.amount`. `IntentsSDK` subtracts it for a
41
+ * fee-inclusive withdrawal, so a caller that builds the payload itself has to do the same
42
+ * @param params.feeEstimation Read for every fee of the route, one of which raises the amount
43
+ * @param params.externalId Supply one to repeat an earlier call.
44
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes. Omit it and the function draws a
45
+ * random one
46
+ * @returns The values the `ft_withdraw` carries
47
+ */
48
+ declare function deriveOmniWithdrawIntentParams(params: {
49
+ assetId: string;
50
+ destinationAddress: string;
51
+ actualAmount: bigint;
52
+ omniChainKind: ChainKind;
53
+ intentsContract: string;
54
+ feeEstimation: FeeEstimation;
55
+ externalId?: string;
56
+ }): OmniWithdrawIntentParams;
57
+ declare function caip2ToChainKind(network: Chain): ChainKind | null;
58
+ declare function isUtxoChain(network: ChainKind): boolean;
59
+ //#endregion
60
+ export { OmniWithdrawIntentParams, caip2ToChainKind, deriveOmniWithdrawIntentParams, isUtxoChain };
@@ -0,0 +1,69 @@
1
+ import { RouteEnum } from "../../constants/route-enum.js";
2
+ import { getUnderlyingFee } from "../../lib/estimate-fee.js";
3
+ import { CHAIN_MAPPINGS } from "./omni-bridge-utils.js";
4
+ import { assert, utils } from "@defuse-protocol/internal-utils";
5
+ import { ChainKind, omniAddress } from "@omni-bridge/core";
6
+ import { calculateStorageAccountId } from "@omni-bridge/near";
7
+
8
+ //#region src/bridges/omni-bridge/omni-withdraw-params.ts
9
+ /**
10
+ * Computes the values of an Omni withdrawal without building the intents. `OmniBridge` calls
11
+ * it too, so a caller that signs the payload elsewhere gets the same numbers.
12
+ * @param params.actualAmount Net of `feeEstimation.amount`. `IntentsSDK` subtracts it for a
13
+ * fee-inclusive withdrawal, so a caller that builds the payload itself has to do the same
14
+ * @param params.feeEstimation Read for every fee of the route, one of which raises the amount
15
+ * @param params.externalId Supply one to repeat an earlier call.
16
+ * `calculateStorageAccountId` throws above 64 UTF-8 bytes. Omit it and the function draws a
17
+ * random one
18
+ * @returns The values the `ft_withdraw` carries
19
+ */
20
+ function deriveOmniWithdrawIntentParams(params) {
21
+ const { contractId: tokenAccountId, standard } = utils.parseDefuseAssetId(params.assetId);
22
+ assert(standard === "nep141", "Only NEP-141 is supported");
23
+ const nativeFee = getUnderlyingFee(params.feeEstimation, RouteEnum.OmniBridge, "relayerFee");
24
+ assert(nativeFee >= 0n, `Invalid Omni bridge relayer fee: expected >= 0, got ${nativeFee}`);
25
+ const storageDepositAmount = getUnderlyingFee(params.feeEstimation, RouteEnum.OmniBridge, "storageDepositFee");
26
+ let amount = params.actualAmount;
27
+ let msg = "";
28
+ if (isUtxoChain(params.omniChainKind)) {
29
+ const utxoMaxGasFee = getUnderlyingFee(params.feeEstimation, RouteEnum.OmniBridge, "utxoMaxGasFee");
30
+ const utxoProtocolFee = getUnderlyingFee(params.feeEstimation, RouteEnum.OmniBridge, "utxoProtocolFee");
31
+ assert(utxoMaxGasFee !== void 0 && utxoMaxGasFee > 0n, `Invalid Omni Bridge utxo max gas fee: expected > 0, got ${utxoMaxGasFee}`);
32
+ assert(utxoProtocolFee !== void 0 && utxoProtocolFee > 0n, `Invalid Omni Bridge utxo protocol fee: expected > 0, got ${utxoProtocolFee}`);
33
+ amount += utxoMaxGasFee + utxoProtocolFee;
34
+ msg = JSON.stringify({ MaxGasFee: utxoMaxGasFee.toString() });
35
+ }
36
+ const destinationAddress = params.omniChainKind === ChainKind.Btc && /^bc1/i.test(params.destinationAddress) ? params.destinationAddress.toLowerCase() : params.destinationAddress;
37
+ const recipient = omniAddress(params.omniChainKind, destinationAddress);
38
+ const externalId = params.externalId ?? crypto.randomUUID();
39
+ return {
40
+ tokenAccountId,
41
+ recipient,
42
+ msg,
43
+ externalId,
44
+ amount,
45
+ nativeFee,
46
+ storageDepositAmount,
47
+ storageDepositAccountId: nativeFee > 0n ? calculateStorageAccountId({
48
+ token: `near:${tokenAccountId}`,
49
+ amount,
50
+ recipient,
51
+ fee: {
52
+ fee: 0n,
53
+ native_fee: nativeFee
54
+ },
55
+ sender: `near:${params.intentsContract}`,
56
+ msg
57
+ }, externalId) : null
58
+ };
59
+ }
60
+ function caip2ToChainKind(network) {
61
+ return CHAIN_MAPPINGS.find(([chain]) => chain === network)?.[1] ?? null;
62
+ }
63
+ const UTXO_CHAINS = [ChainKind.Btc];
64
+ function isUtxoChain(network) {
65
+ return UTXO_CHAINS.includes(network);
66
+ }
67
+
68
+ //#endregion
69
+ export { caip2ToChainKind, deriveOmniWithdrawIntentParams, isUtxoChain };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defuse-protocol/intents-sdk",
3
- "version": "0.81.0",
3
+ "version": "0.82.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -26,6 +26,16 @@
26
26
  "types": "./dist/index.d.cts",
27
27
  "default": "./dist/index.cjs"
28
28
  }
29
+ },
30
+ "./omni-bridge": {
31
+ "import": {
32
+ "types": "./dist/src/bridges/omni-bridge/omni-withdraw-params.d.ts",
33
+ "default": "./dist/src/bridges/omni-bridge/omni-withdraw-params.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/src/bridges/omni-bridge/omni-withdraw-params.d.cts",
37
+ "default": "./dist/src/bridges/omni-bridge/omni-withdraw-params.cjs"
38
+ }
29
39
  }
30
40
  },
31
41
  "files": [