@paraspell/sdk-core 10.0.2 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { blake2b } from '@noble/hashes/blake2';
2
- import { isNodeEvm, getAssetsObject, InvalidCurrencyError, getNativeAssetSymbol, getOtherAssets, getRelayChainSymbol, isForeignAsset, findAsset, isTMultiAsset, hasDryRunSupport, findAssetForNodeOrThrow, isOverrideMultiLocationSpecifier, findAssetByMultiLocation, hasSupportForAsset, extractMultiAssetLoc, isAssetEqual, isSymbolSpecifier, getAssetId, getExistentialDeposit, findAssetOnDestOrThrow, normalizeSymbol } from '@paraspell/assets';
2
+ import { isNodeEvm, getAssetsObject, InvalidCurrencyError, getNativeAssetSymbol, getOtherAssets, getRelayChainSymbol, isForeignAsset, findAssetForNodeOrThrow, findAsset, isOverrideMultiLocationSpecifier, findAssetByMultiLocation, isTMultiAsset, hasDryRunSupport, hasSupportForAsset, extractMultiAssetLoc, isAssetEqual, isSymbolSpecifier, getAssetId, getExistentialDeposit, findAssetOnDestOrThrow, normalizeSymbol } from '@paraspell/assets';
3
3
  export * from '@paraspell/assets';
4
4
  import { base58 } from '@scure/base';
5
5
  import { ethers, Contract } from 'ethers';
6
- import { Parents, isTMultiLocation, NODE_NAMES_DOT_KSM, isRelayChain, hasJunction, deepEqual } from '@paraspell/sdk-common';
6
+ import { Parents, isTMultiLocation, NODE_NAMES_DOT_KSM, isRelayChain, hasJunction, deepEqual, isDotKsmBridge } from '@paraspell/sdk-common';
7
7
  export * from '@paraspell/sdk-common';
8
8
  import { getSupportedPalletsDetails, getDefaultPallet } from '@paraspell/pallets';
9
9
  export * from '@paraspell/pallets';
@@ -184,7 +184,10 @@ function _iterableToArrayLimit(r, l) {
184
184
  f = true,
185
185
  o = false;
186
186
  try {
187
- if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
187
+ if (i = (t = t.call(r)).next, 0 === l) {
188
+ if (Object(t) !== t) return;
189
+ f = !1;
190
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
188
191
  } catch (r) {
189
192
  o = true, n = r;
190
193
  } finally {
@@ -2961,652 +2964,310 @@ var getTNode = function getTNode(paraId, ecosystem) {
2961
2964
  })) !== null && _NODE_NAMES_DOT_KSM$f !== void 0 ? _NODE_NAMES_DOT_KSM$f : null;
2962
2965
  };
2963
2966
 
2964
- var resolveFeeAsset = function resolveFeeAsset(feeAsset, origin, destination, currency) {
2965
- var asset = findAsset(origin, feeAsset, !isTMultiLocation(destination) ? destination : null);
2966
- var usesRawOverriddenMultiAssets = 'multiasset' in currency && currency.multiasset.every(isTMultiAsset);
2967
- if (!asset && !usesRawOverriddenMultiAssets) {
2968
- throwUnsupportedCurrency(feeAsset, origin);
2967
+ var getParaEthTransferFees = /*#__PURE__*/function () {
2968
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(ahApi) {
2969
+ var DEFAULT_FEE, feeStorageItem, leFeeHex, bytes, reversedHex, validReversedHex, leFee, transferBridgeFee, finalBridgeFee, finalAssethubExecutionFee;
2970
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
2971
+ while (1) switch (_context.prev = _context.next) {
2972
+ case 0:
2973
+ DEFAULT_FEE = 2750872500000n;
2974
+ _context.next = 3;
2975
+ return ahApi.getFromRpc('state', 'getStorage', '0x5fbc5c7ba58845ad1f1a9a7c5bc12fad');
2976
+ case 3:
2977
+ feeStorageItem = _context.sent;
2978
+ leFeeHex = feeStorageItem.replace('0x', '');
2979
+ _context.next = 7;
2980
+ return ahApi.disconnect();
2981
+ case 7:
2982
+ bytes = leFeeHex.match(/.{1,2}/g) || [];
2983
+ reversedHex = bytes.reverse().join('');
2984
+ validReversedHex = reversedHex === '' ? '0' : reversedHex;
2985
+ leFee = BigInt('0x' + validReversedHex);
2986
+ transferBridgeFee = leFee === 0n ? DEFAULT_FEE : BigInt(leFee.toString());
2987
+ finalBridgeFee = transferBridgeFee * 110n / 100n;
2988
+ finalAssethubExecutionFee = ASSET_HUB_EXECUTION_FEE * 110n / 100n;
2989
+ return _context.abrupt("return", [finalBridgeFee, finalAssethubExecutionFee]);
2990
+ case 15:
2991
+ case "end":
2992
+ return _context.stop();
2993
+ }
2994
+ }, _callee);
2995
+ }));
2996
+ return function getParaEthTransferFees(_x) {
2997
+ return _ref.apply(this, arguments);
2998
+ };
2999
+ }();
3000
+
3001
+ // Inspired by Moonbeam XCM-SDK
3002
+ // https://github.com/moonbeam-foundation/xcm-sdk/blob/ab835c15bf41612604b1c858d956a9f07705ed65/packages/utils/src/format/asset.ts#L1
3003
+ var formatAssetIdToERC20 = function formatAssetIdToERC20(id) {
3004
+ if (id.startsWith('0x')) {
3005
+ return id;
2969
3006
  }
2970
- return asset !== null && asset !== void 0 ? asset : undefined;
3007
+ if (!(/^\d{38,39}$/.test(id) || /^\d{4}$/.test(id))) {
3008
+ throw new InvalidParameterError("Asset id: ".concat(id, " must be a string and have either 4 digits or 38-39 digits"));
3009
+ }
3010
+ return "0xffffffff".concat(BigInt(id).toString(16).padStart(32, '0'));
2971
3011
  };
2972
3012
 
2973
- var isAssetHub = function isAssetHub(chain) {
2974
- return chain === 'AssetHubPolkadot' || chain === 'AssetHubKusama';
2975
- };
2976
- var isBridgeHub = function isBridgeHub(chain) {
2977
- return chain === 'BridgeHubPolkadot' || chain === 'BridgeHubKusama';
2978
- };
2979
- var isPeople = function isPeople(chain) {
2980
- return chain === 'PeoplePolkadot' || chain === 'PeopleKusama';
2981
- };
2982
- var isSystemPara = function isSystemPara(chain) {
2983
- return isAssetHub(chain) || isBridgeHub(chain) || isPeople(chain);
2984
- };
2985
- var mul = function mul(v, num) {
2986
- var den = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1n;
2987
- return v * num / den;
2988
- };
2989
- var padFee = function padFee(raw, origin, dest, side) {
2990
- var relayOrigin = isRelayChain(origin);
2991
- var relayDest = isRelayChain(dest);
2992
- var sysParaOrigin = isSystemPara(origin);
2993
- var sysParaDest = isSystemPara(dest);
2994
- var relayToPara = relayOrigin && !relayDest;
2995
- var sysParaToPara = sysParaOrigin && !sysParaDest;
2996
- var paraToPara = !relayOrigin && !sysParaOrigin;
2997
- if (sysParaToPara) return raw * 40n;
2998
- if (relayToPara) return side === 'origin' ? mul(raw, 320n, 100n) : mul(raw, 3000n, 100n);
2999
- if (paraToPara) return mul(raw, 130n, 100n);
3000
- // apply default 30% padding
3001
- return mul(raw, 130n, 100n);
3002
- };
3013
+ var MOONBEAM_RPC = 'https://rpc.api.moonbeam.network';
3014
+ var MOONBEAM_ID = 1284;
3015
+ var MOONRIVER_RPC = 'https://rpc.api.moonriver.moonbeam.network';
3016
+ var MOONRIVER_ID = 1285;
3017
+ var ERC20_ABI$1 = ['function balanceOf(address) view returns (uint256)'];
3018
+ function getMoonbeamErc20Balance(_x, _x2, _x3) {
3019
+ return _getMoonbeamErc20Balance.apply(this, arguments);
3020
+ }
3021
+ function _getMoonbeamErc20Balance() {
3022
+ _getMoonbeamErc20Balance = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(node, assetId, address) {
3023
+ var _ref, rpc, id, provider, addr, token;
3024
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
3025
+ while (1) switch (_context.prev = _context.next) {
3026
+ case 0:
3027
+ _ref = node === 'Moonbeam' ? {
3028
+ rpc: MOONBEAM_RPC,
3029
+ id: MOONBEAM_ID
3030
+ } : {
3031
+ rpc: MOONRIVER_RPC,
3032
+ id: MOONRIVER_ID
3033
+ }, rpc = _ref.rpc, id = _ref.id;
3034
+ provider = new ethers.JsonRpcProvider(rpc, id);
3035
+ addr = formatAssetIdToERC20(assetId);
3036
+ token = new ethers.Contract(addr, ERC20_ABI$1, provider);
3037
+ _context.next = 6;
3038
+ return token.balanceOf(address);
3039
+ case 6:
3040
+ return _context.abrupt("return", _context.sent);
3041
+ case 7:
3042
+ case "end":
3043
+ return _context.stop();
3044
+ }
3045
+ }, _callee);
3046
+ }));
3047
+ return _getMoonbeamErc20Balance.apply(this, arguments);
3048
+ }
3003
3049
 
3004
- var getReverseTxFee = /*#__PURE__*/function () {
3005
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref, currencyInput) {
3006
- var api, origin, destination, senderAddress, address, currency, tx, rawFee;
3050
+ var getBalanceForeignPolkadotXcm = /*#__PURE__*/function () {
3051
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(api, node, address, asset) {
3052
+ var ASSETS_PALLET_ID, hasRequiredJunctions;
3007
3053
  return _regeneratorRuntime().wrap(function _callee$(_context) {
3008
3054
  while (1) switch (_context.prev = _context.next) {
3009
3055
  case 0:
3010
- api = _ref.api, origin = _ref.origin, destination = _ref.destination, senderAddress = _ref.senderAddress, address = _ref.address, currency = _ref.currency;
3011
- if (!('multiasset' in currency)) {
3056
+ if (!(node === 'Moonbeam' || node === 'Moonriver')) {
3057
+ _context.next = 6;
3058
+ break;
3059
+ }
3060
+ if (!(!isForeignAsset(asset) || !asset.assetId)) {
3012
3061
  _context.next = 3;
3013
3062
  break;
3014
3063
  }
3015
- throw new InvalidCurrencyError('Multi-assets are not yet supported for XCM fee calculation.');
3064
+ throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no assetId"));
3016
3065
  case 3:
3017
- _context.next = 5;
3018
- return Builder(api).from(destination).to(origin).address(senderAddress).senderAddress(address).currency(_objectSpread2(_objectSpread2({}, currencyInput), {}, {
3019
- amount: currency.amount
3020
- })).build();
3066
+ if (!(asset.multiLocation && hasJunction(asset.multiLocation, 'GlobalConsensus'))) {
3067
+ _context.next = 5;
3068
+ break;
3069
+ }
3070
+ return _context.abrupt("return", getMoonbeamErc20Balance(node, asset.assetId, address));
3021
3071
  case 5:
3022
- tx = _context.sent;
3023
- _context.next = 8;
3024
- return api.calculateTransactionFee(tx, address);
3072
+ return _context.abrupt("return", api.getBalanceAssetsPallet(address, BigInt(asset.assetId)));
3073
+ case 6:
3074
+ if (!(node === 'Mythos')) {
3075
+ _context.next = 8;
3076
+ break;
3077
+ }
3078
+ return _context.abrupt("return", api.getMythosForeignBalance(address));
3025
3079
  case 8:
3026
- rawFee = _context.sent;
3027
- return _context.abrupt("return", padFee(rawFee, origin, destination, 'destination'));
3080
+ if (isForeignAsset(asset)) {
3081
+ _context.next = 10;
3082
+ break;
3083
+ }
3084
+ throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " is not a foreign asset"));
3028
3085
  case 10:
3086
+ if (!(node === 'Polimec')) {
3087
+ _context.next = 14;
3088
+ break;
3089
+ }
3090
+ if (!(asset.multiLocation === undefined)) {
3091
+ _context.next = 13;
3092
+ break;
3093
+ }
3094
+ throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no multi-location"));
3095
+ case 13:
3096
+ return _context.abrupt("return", api.getBalanceForeignAssetsPallet(address, asset.multiLocation));
3097
+ case 14:
3098
+ if (!(node === 'AssetHubPolkadot')) {
3099
+ _context.next = 20;
3100
+ break;
3101
+ }
3102
+ ASSETS_PALLET_ID = 50;
3103
+ hasRequiredJunctions = asset.multiLocation && hasJunction(asset.multiLocation, 'PalletInstance', ASSETS_PALLET_ID) && hasJunction(asset.multiLocation, 'GeneralIndex');
3104
+ if (!(!asset.multiLocation || hasRequiredJunctions)) {
3105
+ _context.next = 19;
3106
+ break;
3107
+ }
3108
+ return _context.abrupt("return", api.getBalanceAssetsPallet(address, Number(asset.assetId)));
3109
+ case 19:
3110
+ return _context.abrupt("return", api.getBalanceForeignAssetsPallet(address, asset.multiLocation));
3111
+ case 20:
3112
+ return _context.abrupt("return", api.getBalanceForeignPolkadotXcm(address, asset.assetId));
3113
+ case 21:
3029
3114
  case "end":
3030
3115
  return _context.stop();
3031
3116
  }
3032
3117
  }, _callee);
3033
3118
  }));
3034
- return function getReverseTxFee(_x, _x2) {
3035
- return _ref2.apply(this, arguments);
3119
+ return function getBalanceForeignPolkadotXcm(_x, _x2, _x3, _x4) {
3120
+ return _ref.apply(this, arguments);
3036
3121
  };
3037
3122
  }();
3038
3123
 
3039
- var createOriginLocation = function createOriginLocation(origin, destination) {
3040
- if (isRelayChain(origin)) return DOT_MULTILOCATION;
3041
- return {
3042
- parents: isRelayChain(destination) ? Parents.ZERO : Parents.ONE,
3043
- interior: {
3044
- X1: [{
3045
- Parachain: getParaId(origin)
3046
- }]
3047
- }
3048
- };
3049
- };
3050
- var getDestXcmFee = /*#__PURE__*/function () {
3051
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
3052
- var api, origin, destination, currency, forwardedXcms, asset, feeAsset, originFee, disableFallback, resolvedFeeAsset, calcPaymentInfoFee, dryRunResult, fee, newForwardedXcms, destParaId;
3053
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
3054
- while (1) switch (_context2.prev = _context2.next) {
3124
+ var getBalanceForeignXTokens = /*#__PURE__*/function () {
3125
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(api, node, address, asset) {
3126
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
3127
+ while (1) switch (_context.prev = _context.next) {
3055
3128
  case 0:
3056
- api = options.api, origin = options.origin, destination = options.destination, currency = options.currency, forwardedXcms = options.forwardedXcms, asset = options.asset, feeAsset = options.feeAsset, originFee = options.originFee, disableFallback = options.disableFallback;
3057
- resolvedFeeAsset = feeAsset ? resolveFeeAsset(feeAsset, origin, destination, currency) : undefined;
3058
- calcPaymentInfoFee = /*#__PURE__*/function () {
3059
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
3060
- var originAsset;
3061
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3062
- while (1) switch (_context.prev = _context.next) {
3063
- case 0:
3064
- originAsset = findAsset(origin, currency, destination);
3065
- if (originAsset) {
3066
- _context.next = 3;
3067
- break;
3068
- }
3069
- throw new InvalidCurrencyError("Currency ".concat(JSON.stringify(currency), " not found in ").concat(origin));
3070
- case 3:
3071
- if (!originAsset.multiLocation) {
3072
- _context.next = 17;
3073
- break;
3074
- }
3075
- _context.prev = 4;
3076
- _context.next = 7;
3077
- return getReverseTxFee(options, {
3078
- multilocation: originAsset.multiLocation
3079
- });
3080
- case 7:
3081
- return _context.abrupt("return", _context.sent);
3082
- case 10:
3083
- _context.prev = 10;
3084
- _context.t0 = _context["catch"](4);
3085
- if (!(_context.t0 instanceof InvalidCurrencyError)) {
3086
- _context.next = 16;
3087
- break;
3088
- }
3089
- _context.next = 15;
3090
- return getReverseTxFee(options, {
3091
- symbol: originAsset.symbol
3092
- });
3093
- case 15:
3094
- return _context.abrupt("return", _context.sent);
3095
- case 16:
3096
- throw _context.t0;
3097
- case 17:
3098
- _context.next = 19;
3099
- return getReverseTxFee(options, {
3100
- symbol: originAsset.symbol
3101
- });
3102
- case 19:
3103
- return _context.abrupt("return", _context.sent);
3104
- case 20:
3105
- case "end":
3106
- return _context.stop();
3107
- }
3108
- }, _callee, null, [[4, 10]]);
3109
- }));
3110
- return function calcPaymentInfoFee() {
3111
- return _ref2.apply(this, arguments);
3112
- };
3113
- }();
3114
- if (!(!hasDryRunSupport(destination) || !forwardedXcms)) {
3115
- _context2.next = 8;
3129
+ if (!(node === 'Astar' || node === 'Shiden')) {
3130
+ _context.next = 4;
3116
3131
  break;
3117
3132
  }
3118
- _context2.next = 6;
3119
- return calcPaymentInfoFee();
3120
- case 6:
3121
- _context2.t0 = _context2.sent;
3122
- return _context2.abrupt("return", {
3123
- fee: _context2.t0,
3124
- feeType: 'paymentInfo'
3125
- });
3126
- case 8:
3127
- _context2.next = 10;
3128
- return api.getDryRunXcm({
3129
- originLocation: addXcmVersionHeader(createOriginLocation(origin, destination), Version.V4),
3130
- xcm: forwardedXcms[1][0],
3131
- node: destination,
3132
- origin: origin,
3133
- asset: asset,
3134
- originFee: originFee,
3135
- feeAsset: resolvedFeeAsset,
3136
- amount: BigInt(currency.amount)
3137
- });
3138
- case 10:
3139
- dryRunResult = _context2.sent;
3140
- if (dryRunResult.success) {
3141
- _context2.next = 19;
3133
+ if (!(!isForeignAsset(asset) || !asset.assetId)) {
3134
+ _context.next = 3;
3142
3135
  break;
3143
3136
  }
3144
- if (!disableFallback) {
3145
- _context2.next = 14;
3137
+ throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no assetId"));
3138
+ case 3:
3139
+ return _context.abrupt("return", api.getBalanceAssetsPallet(address, BigInt(asset.assetId)));
3140
+ case 4:
3141
+ if (!(node === 'BifrostPolkadot' || node === 'BifrostKusama')) {
3142
+ _context.next = 6;
3146
3143
  break;
3147
3144
  }
3148
- return _context2.abrupt("return", {
3149
- dryRunError: dryRunResult.failureReason
3150
- });
3151
- case 14:
3152
- _context2.next = 16;
3153
- return calcPaymentInfoFee();
3154
- case 16:
3155
- _context2.t1 = _context2.sent;
3156
- _context2.t2 = dryRunResult.failureReason;
3157
- return _context2.abrupt("return", {
3158
- fee: _context2.t1,
3159
- feeType: 'paymentInfo',
3160
- dryRunError: _context2.t2
3161
- });
3162
- case 19:
3163
- fee = dryRunResult.fee, newForwardedXcms = dryRunResult.forwardedXcms, destParaId = dryRunResult.destParaId;
3164
- return _context2.abrupt("return", {
3165
- fee: fee,
3166
- feeType: 'dryRun',
3167
- forwardedXcms: newForwardedXcms,
3168
- destParaId: destParaId
3169
- });
3170
- case 21:
3145
+ return _context.abrupt("return", api.getBalanceForeignBifrost(address, asset));
3146
+ case 6:
3147
+ return _context.abrupt("return", api.getBalanceForeignXTokens(node, address, asset));
3148
+ case 7:
3171
3149
  case "end":
3172
- return _context2.stop();
3150
+ return _context.stop();
3173
3151
  }
3174
- }, _callee2);
3152
+ }, _callee);
3175
3153
  }));
3176
- return function getDestXcmFee(_x) {
3154
+ return function getBalanceForeignXTokens(_x, _x2, _x3, _x4) {
3177
3155
  return _ref.apply(this, arguments);
3178
3156
  };
3179
3157
  }();
3180
3158
 
3181
- var dryRunInternal = /*#__PURE__*/function () {
3182
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
3183
- var _intermediateFees$ass, _intermediateFees$bri, _destinationDryRun;
3184
- var origin, destination, currency, api, tx, senderAddress, feeAsset, resolvedFeeAsset, asset, originDryRun, initialForwardedXcms, initialDestParaId, currentOrigin, forwardedXcms, nextParaId, intermediateFees, destinationDryRun, nextChain, hopApi, hopDryRun, newXcms, destParaId;
3159
+ var getBalanceForeignInternal = /*#__PURE__*/function () {
3160
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3161
+ var address, node, currency, api, asset, defaultPallet;
3185
3162
  return _regeneratorRuntime().wrap(function _callee$(_context) {
3186
3163
  while (1) switch (_context.prev = _context.next) {
3187
3164
  case 0:
3188
- origin = options.origin, destination = options.destination, currency = options.currency, api = options.api, tx = options.tx, senderAddress = options.senderAddress, feeAsset = options.feeAsset;
3189
- resolvedFeeAsset = feeAsset && origin === 'AssetHubPolkadot' ? resolveFeeAsset(feeAsset, origin, destination, currency) : undefined;
3190
- asset = findAssetForNodeOrThrow(origin, currency, destination);
3191
- _context.next = 5;
3192
- return api.getDryRunCall({
3193
- tx: tx,
3194
- node: origin,
3195
- address: senderAddress,
3196
- isFeeAsset: !!resolvedFeeAsset
3197
- });
3198
- case 5:
3199
- originDryRun = _context.sent;
3200
- if (originDryRun.success) {
3201
- _context.next = 8;
3202
- break;
3203
- }
3204
- return _context.abrupt("return", {
3205
- origin: originDryRun
3206
- });
3207
- case 8:
3208
- initialForwardedXcms = originDryRun.forwardedXcms, initialDestParaId = originDryRun.destParaId;
3209
- currentOrigin = origin;
3210
- forwardedXcms = initialForwardedXcms;
3211
- nextParaId = initialDestParaId;
3212
- intermediateFees = {};
3213
- case 13:
3214
- if (!(Array.isArray(forwardedXcms) && forwardedXcms.length && forwardedXcms[1].length && ('disconnect' in api.getApi() ? Object.values(forwardedXcms[1][0]).length : forwardedXcms[1][0].value.length) > 0 && nextParaId !== undefined)) {
3215
- _context.next = 40;
3216
- break;
3217
- }
3218
- nextChain = getTNode(nextParaId, determineRelayChain(origin) === 'Polkadot' ? 'polkadot' : 'kusama');
3219
- if (nextChain) {
3220
- _context.next = 17;
3221
- break;
3222
- }
3223
- throw new InvalidParameterError("Unable to find TNode for paraId ".concat(nextParaId));
3224
- case 17:
3225
- hopApi = api.clone();
3226
- _context.prev = 18;
3227
- if (hasDryRunSupport(nextChain)) {
3228
- _context.next = 22;
3165
+ address = _ref.address, node = _ref.node, currency = _ref.currency, api = _ref.api;
3166
+ _context.next = 3;
3167
+ return api.init(node);
3168
+ case 3:
3169
+ asset = findAssetForNodeOrThrow(node, currency, null);
3170
+ defaultPallet = getDefaultPallet(node);
3171
+ if (!(defaultPallet === 'XTokens')) {
3172
+ _context.next = 9;
3229
3173
  break;
3230
3174
  }
3231
- if (nextChain === destination) {
3232
- destinationDryRun = {
3233
- success: false,
3234
- failureReason: "DryRunApi is not available on node ".concat(nextChain)
3235
- };
3236
- }
3237
- return _context.abrupt("break", 40);
3238
- case 22:
3239
- _context.next = 24;
3240
- return hopApi.init(nextChain, DRY_RUN_CLIENT_TIMEOUT_MS);
3241
- case 24:
3242
- _context.next = 26;
3243
- return hopApi.getDryRunXcm({
3244
- originLocation: addXcmVersionHeader(createOriginLocation(currentOrigin, nextChain), Version.V4),
3245
- xcm: forwardedXcms[1][0],
3246
- node: nextChain,
3247
- origin: currentOrigin,
3248
- asset: asset,
3249
- feeAsset: resolvedFeeAsset,
3250
- originFee: originDryRun.fee,
3251
- amount: BigInt(currency.amount)
3252
- });
3253
- case 26:
3254
- hopDryRun = _context.sent;
3255
- if (nextChain === destination || isRelayChain(nextChain) && !isRelayChain(destination)) {
3256
- destinationDryRun = hopDryRun;
3257
- } else if (nextChain === 'AssetHubPolkadot') {
3258
- intermediateFees.assetHub = hopDryRun;
3259
- } else if (nextChain === 'BridgeHubPolkadot') {
3260
- intermediateFees.bridgeHub = hopDryRun;
3261
- }
3262
- if (hopDryRun.success) {
3263
- _context.next = 30;
3175
+ return _context.abrupt("return", getBalanceForeignXTokens(api, node, address, asset));
3176
+ case 9:
3177
+ if (!(defaultPallet === 'PolkadotXcm')) {
3178
+ _context.next = 11;
3264
3179
  break;
3265
3180
  }
3266
- return _context.abrupt("break", 40);
3267
- case 30:
3268
- newXcms = hopDryRun.forwardedXcms, destParaId = hopDryRun.destParaId;
3269
- forwardedXcms = newXcms;
3270
- nextParaId = destParaId;
3271
- currentOrigin = nextChain;
3272
- case 34:
3273
- _context.prev = 34;
3274
- _context.next = 37;
3275
- return hopApi.disconnect();
3276
- case 37:
3277
- return _context.finish(34);
3278
- case 38:
3279
- _context.next = 13;
3280
- break;
3281
- case 40:
3282
- return _context.abrupt("return", {
3283
- origin: originDryRun.success ? _objectSpread2(_objectSpread2({}, originDryRun), {}, {
3284
- currency: resolvedFeeAsset ? resolvedFeeAsset.symbol : getNativeAssetSymbol(origin)
3285
- }) : originDryRun,
3286
- assetHub: (_intermediateFees$ass = intermediateFees.assetHub) !== null && _intermediateFees$ass !== void 0 && _intermediateFees$ass.success ? _objectSpread2(_objectSpread2({}, intermediateFees.assetHub), {}, {
3287
- currency: getNativeAssetSymbol('AssetHubPolkadot')
3288
- }) : intermediateFees.assetHub,
3289
- bridgeHub: (_intermediateFees$bri = intermediateFees.bridgeHub) !== null && _intermediateFees$bri !== void 0 && _intermediateFees$bri.success ? _objectSpread2(_objectSpread2({}, intermediateFees.bridgeHub), {}, {
3290
- currency: getNativeAssetSymbol('BridgeHubPolkadot')
3291
- }) : intermediateFees.bridgeHub,
3292
- destination: (_destinationDryRun = destinationDryRun) !== null && _destinationDryRun !== void 0 && _destinationDryRun.success ? _objectSpread2(_objectSpread2({}, destinationDryRun), {}, {
3293
- currency: asset.symbol
3294
- }) : destinationDryRun
3295
- });
3296
- case 41:
3181
+ return _context.abrupt("return", getBalanceForeignPolkadotXcm(api, node, address, asset));
3182
+ case 11:
3183
+ throw new InvalidParameterError('Unsupported pallet');
3184
+ case 12:
3297
3185
  case "end":
3298
3186
  return _context.stop();
3299
3187
  }
3300
- }, _callee, null, [[18,, 34, 38]]);
3188
+ }, _callee);
3301
3189
  }));
3302
- return function dryRunInternal(_x) {
3303
- return _ref.apply(this, arguments);
3190
+ return function getBalanceForeignInternal(_x) {
3191
+ return _ref2.apply(this, arguments);
3304
3192
  };
3305
3193
  }();
3306
-
3307
- var dryRun = /*#__PURE__*/function () {
3308
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
3309
- var api, senderAddress, origin;
3310
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3311
- while (1) switch (_context.prev = _context.next) {
3194
+ var getBalanceForeign = /*#__PURE__*/function () {
3195
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
3196
+ var api;
3197
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
3198
+ while (1) switch (_context2.prev = _context2.next) {
3312
3199
  case 0:
3313
- api = options.api, senderAddress = options.senderAddress, origin = options.origin;
3314
- validateAddress(senderAddress, origin, false);
3315
- _context.next = 4;
3316
- return api.init(origin, DRY_RUN_CLIENT_TIMEOUT_MS);
3200
+ api = options.api;
3201
+ _context2.prev = 1;
3202
+ _context2.next = 4;
3203
+ return getBalanceForeignInternal(options);
3317
3204
  case 4:
3318
- _context.prev = 4;
3319
- _context.next = 7;
3320
- return dryRunInternal(options);
3321
- case 7:
3322
- return _context.abrupt("return", _context.sent);
3323
- case 8:
3324
- _context.prev = 8;
3325
- _context.next = 11;
3205
+ return _context2.abrupt("return", _context2.sent);
3206
+ case 5:
3207
+ _context2.prev = 5;
3208
+ _context2.next = 8;
3326
3209
  return api.disconnect();
3327
- case 11:
3328
- return _context.finish(8);
3329
- case 12:
3210
+ case 8:
3211
+ return _context2.finish(5);
3212
+ case 9:
3330
3213
  case "end":
3331
- return _context.stop();
3214
+ return _context2.stop();
3332
3215
  }
3333
- }, _callee, null, [[4,, 8, 12]]);
3216
+ }, _callee2, null, [[1,, 5, 9]]);
3334
3217
  }));
3335
- return function dryRun(_x) {
3336
- return _ref.apply(this, arguments);
3218
+ return function getBalanceForeign(_x2) {
3219
+ return _ref3.apply(this, arguments);
3337
3220
  };
3338
3221
  }();
3339
3222
 
3340
- var dryRunOrigin = /*#__PURE__*/function () {
3341
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
3342
- var api, node, address, result;
3223
+ var getBalanceNativeInternal = /*#__PURE__*/function () {
3224
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3225
+ var address, node, api, currency, symbol;
3343
3226
  return _regeneratorRuntime().wrap(function _callee$(_context) {
3344
3227
  while (1) switch (_context.prev = _context.next) {
3345
3228
  case 0:
3346
- api = options.api, node = options.node, address = options.address;
3347
- validateAddress(address, node, false);
3348
- _context.next = 4;
3349
- return api.init(node, DRY_RUN_CLIENT_TIMEOUT_MS);
3350
- case 4:
3351
- _context.prev = 4;
3352
- _context.next = 7;
3353
- return api.getDryRunCall(options);
3354
- case 7:
3355
- result = _context.sent;
3356
- if (!result.success) {
3357
- _context.next = 12;
3229
+ address = _ref.address, node = _ref.node, api = _ref.api, currency = _ref.currency;
3230
+ _context.next = 3;
3231
+ return api.init(node);
3232
+ case 3:
3233
+ if (!(node === 'Interlay' || node === 'Kintsugi')) {
3234
+ _context.next = 5;
3358
3235
  break;
3359
3236
  }
3360
- return _context.abrupt("return", _objectSpread2(_objectSpread2({}, result), {}, {
3361
- currency: getNativeAssetSymbol(node)
3237
+ return _context.abrupt("return", getBalanceForeignInternal({
3238
+ address: address,
3239
+ node: node,
3240
+ api: api,
3241
+ currency: {
3242
+ symbol: currency ? currency.symbol : getAssetsObject(node).nativeAssetSymbol
3243
+ }
3362
3244
  }));
3363
- case 12:
3364
- return _context.abrupt("return", result);
3365
- case 13:
3366
- _context.prev = 13;
3367
- _context.next = 16;
3368
- return api.disconnect();
3369
- case 16:
3370
- return _context.finish(13);
3371
- case 17:
3372
- case "end":
3373
- return _context.stop();
3374
- }
3375
- }, _callee, null, [[4,, 13, 17]]);
3376
- }));
3377
- return function dryRunOrigin(_x) {
3378
- return _ref.apply(this, arguments);
3379
- };
3380
- }();
3381
-
3382
- var getParaEthTransferFees = /*#__PURE__*/function () {
3383
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(ahApi) {
3384
- var DEFAULT_FEE, feeStorageItem, leFeeHex, bytes, reversedHex, validReversedHex, leFee, transferBridgeFee, finalBridgeFee, finalAssethubExecutionFee;
3385
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3386
- while (1) switch (_context.prev = _context.next) {
3387
- case 0:
3388
- DEFAULT_FEE = 2750872500000n;
3389
- _context.next = 3;
3390
- return ahApi.getFromRpc('state', 'getStorage', '0x5fbc5c7ba58845ad1f1a9a7c5bc12fad');
3391
- case 3:
3392
- feeStorageItem = _context.sent;
3393
- leFeeHex = feeStorageItem.replace('0x', '');
3394
- _context.next = 7;
3395
- return ahApi.disconnect();
3396
- case 7:
3397
- bytes = leFeeHex.match(/.{1,2}/g) || [];
3398
- reversedHex = bytes.reverse().join('');
3399
- validReversedHex = reversedHex === '' ? '0' : reversedHex;
3400
- leFee = BigInt('0x' + validReversedHex);
3401
- transferBridgeFee = leFee === 0n ? DEFAULT_FEE : BigInt(leFee.toString());
3402
- finalBridgeFee = transferBridgeFee * 110n / 100n;
3403
- finalAssethubExecutionFee = ASSET_HUB_EXECUTION_FEE * 110n / 100n;
3404
- return _context.abrupt("return", [finalBridgeFee, finalAssethubExecutionFee]);
3405
- case 15:
3406
- case "end":
3407
- return _context.stop();
3408
- }
3409
- }, _callee);
3410
- }));
3411
- return function getParaEthTransferFees(_x) {
3412
- return _ref.apply(this, arguments);
3413
- };
3414
- }();
3415
-
3416
- // Inspired by Moonbeam XCM-SDK
3417
- // https://github.com/moonbeam-foundation/xcm-sdk/blob/ab835c15bf41612604b1c858d956a9f07705ed65/packages/utils/src/format/asset.ts#L1
3418
- var formatAssetIdToERC20 = function formatAssetIdToERC20(id) {
3419
- if (id.startsWith('0x')) {
3420
- return id;
3421
- }
3422
- if (!(/^\d{38,39}$/.test(id) || /^\d{4}$/.test(id))) {
3423
- throw new InvalidParameterError("Asset id: ".concat(id, " must be a string and have either 4 digits or 38-39 digits"));
3424
- }
3425
- return "0xffffffff".concat(BigInt(id).toString(16).padStart(32, '0'));
3426
- };
3427
-
3428
- var MOONBEAM_RPC = 'https://rpc.api.moonbeam.network';
3429
- var MOONBEAM_ID = 1284;
3430
- var MOONRIVER_RPC = 'https://rpc.api.moonriver.moonbeam.network';
3431
- var MOONRIVER_ID = 1285;
3432
- var ERC20_ABI = ['function balanceOf(address) view returns (uint256)'];
3433
- function getMoonbeamErc20Balance(_x, _x2, _x3) {
3434
- return _getMoonbeamErc20Balance.apply(this, arguments);
3435
- }
3436
- function _getMoonbeamErc20Balance() {
3437
- _getMoonbeamErc20Balance = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(node, assetId, address) {
3438
- var _ref, rpc, id, provider, addr, token;
3439
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3440
- while (1) switch (_context.prev = _context.next) {
3441
- case 0:
3442
- _ref = node === 'Moonbeam' ? {
3443
- rpc: MOONBEAM_RPC,
3444
- id: MOONBEAM_ID
3445
- } : {
3446
- rpc: MOONRIVER_RPC,
3447
- id: MOONRIVER_ID
3448
- }, rpc = _ref.rpc, id = _ref.id;
3449
- provider = new ethers.JsonRpcProvider(rpc, id);
3450
- addr = formatAssetIdToERC20(assetId);
3451
- token = new ethers.Contract(addr, ERC20_ABI, provider);
3452
- _context.next = 6;
3453
- return token.balanceOf(address);
3454
- case 6:
3455
- return _context.abrupt("return", _context.sent);
3456
- case 7:
3457
- case "end":
3458
- return _context.stop();
3459
- }
3460
- }, _callee);
3461
- }));
3462
- return _getMoonbeamErc20Balance.apply(this, arguments);
3463
- }
3464
-
3465
- var getBalanceForeignPolkadotXcm = /*#__PURE__*/function () {
3466
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(api, node, address, asset) {
3467
- var ASSETS_PALLET_ID, hasRequiredJunctions;
3468
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3469
- while (1) switch (_context.prev = _context.next) {
3470
- case 0:
3471
- if (!(node === 'Moonbeam' || node === 'Moonriver')) {
3472
- _context.next = 6;
3473
- break;
3474
- }
3475
- if (!(!isForeignAsset(asset) || !asset.assetId)) {
3476
- _context.next = 3;
3477
- break;
3478
- }
3479
- throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no assetId"));
3480
- case 3:
3481
- if (!(asset.multiLocation && hasJunction(asset.multiLocation, 'GlobalConsensus'))) {
3482
- _context.next = 5;
3483
- break;
3484
- }
3485
- return _context.abrupt("return", getMoonbeamErc20Balance(node, asset.assetId, address));
3486
3245
  case 5:
3487
- return _context.abrupt("return", api.getBalanceAssetsPallet(address, BigInt(asset.assetId)));
3488
- case 6:
3489
- if (!(node === 'Mythos')) {
3490
- _context.next = 8;
3491
- break;
3492
- }
3493
- return _context.abrupt("return", api.getMythosForeignBalance(address));
3494
- case 8:
3495
- if (isForeignAsset(asset)) {
3246
+ if (!(currency && currency.symbol !== getNativeAssetSymbol(node) && (node === 'Acala' || node === 'Karura'))) {
3496
3247
  _context.next = 10;
3497
3248
  break;
3498
3249
  }
3499
- throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " is not a foreign asset"));
3500
- case 10:
3501
- if (!(node === 'Polimec')) {
3502
- _context.next = 14;
3503
- break;
3504
- }
3505
- if (!(asset.multiLocation === undefined)) {
3506
- _context.next = 13;
3507
- break;
3508
- }
3509
- throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no multi-location"));
3510
- case 13:
3511
- return _context.abrupt("return", api.getBalanceForeignAssetsPallet(address, asset.multiLocation));
3512
- case 14:
3513
- if (!(node === 'AssetHubPolkadot')) {
3514
- _context.next = 20;
3515
- break;
3516
- }
3517
- ASSETS_PALLET_ID = 50;
3518
- hasRequiredJunctions = asset.multiLocation && hasJunction(asset.multiLocation, 'PalletInstance', ASSETS_PALLET_ID) && hasJunction(asset.multiLocation, 'GeneralIndex');
3519
- if (!(!asset.multiLocation || hasRequiredJunctions)) {
3520
- _context.next = 19;
3521
- break;
3522
- }
3523
- return _context.abrupt("return", api.getBalanceAssetsPallet(address, Number(asset.assetId)));
3524
- case 19:
3525
- return _context.abrupt("return", api.getBalanceForeignAssetsPallet(address, asset.multiLocation));
3526
- case 20:
3527
- return _context.abrupt("return", api.getBalanceForeignPolkadotXcm(address, asset.assetId));
3528
- case 21:
3529
- case "end":
3530
- return _context.stop();
3531
- }
3532
- }, _callee);
3533
- }));
3534
- return function getBalanceForeignPolkadotXcm(_x, _x2, _x3, _x4) {
3535
- return _ref.apply(this, arguments);
3536
- };
3537
- }();
3538
-
3539
- var getBalanceForeignXTokens = /*#__PURE__*/function () {
3540
- var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(api, node, address, asset) {
3541
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3542
- while (1) switch (_context.prev = _context.next) {
3543
- case 0:
3544
- if (!(node === 'Astar' || node === 'Shiden')) {
3545
- _context.next = 4;
3546
- break;
3547
- }
3548
- if (!(!isForeignAsset(asset) || !asset.assetId)) {
3549
- _context.next = 3;
3550
- break;
3551
- }
3552
- throw new InvalidCurrencyError("Asset ".concat(JSON.stringify(asset), " has no assetId"));
3553
- case 3:
3554
- return _context.abrupt("return", api.getBalanceAssetsPallet(address, BigInt(asset.assetId)));
3555
- case 4:
3556
- if (!(node === 'BifrostPolkadot' || node === 'BifrostKusama')) {
3557
- _context.next = 6;
3558
- break;
3559
- }
3560
- return _context.abrupt("return", api.getBalanceForeignBifrost(address, asset));
3561
- case 6:
3562
- return _context.abrupt("return", api.getBalanceForeignXTokens(node, address, asset));
3563
- case 7:
3564
- case "end":
3565
- return _context.stop();
3566
- }
3567
- }, _callee);
3568
- }));
3569
- return function getBalanceForeignXTokens(_x, _x2, _x3, _x4) {
3570
- return _ref.apply(this, arguments);
3571
- };
3572
- }();
3573
-
3574
- var getBalanceForeignInternal = /*#__PURE__*/function () {
3575
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3576
- var address, node, currency, api, asset, defaultPallet;
3577
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3578
- while (1) switch (_context.prev = _context.next) {
3579
- case 0:
3580
- address = _ref.address, node = _ref.node, currency = _ref.currency, api = _ref.api;
3581
- _context.next = 3;
3582
- return api.init(node);
3583
- case 3:
3584
- asset = findAssetForNodeOrThrow(node, currency, null);
3585
- defaultPallet = getDefaultPallet(node);
3586
- if (!(defaultPallet === 'XTokens')) {
3250
+ symbol = currency.symbol === 'aSEED' ? 'AUSD' : currency.symbol;
3251
+ if (!(symbol.toLowerCase() === 'lcdot')) {
3587
3252
  _context.next = 9;
3588
3253
  break;
3589
3254
  }
3590
- return _context.abrupt("return", getBalanceForeignXTokens(api, node, address, asset));
3255
+ throw new InvalidCurrencyError('LcDOT balance is not supported');
3591
3256
  case 9:
3592
- if (!(defaultPallet === 'PolkadotXcm')) {
3593
- _context.next = 11;
3594
- break;
3595
- }
3596
- return _context.abrupt("return", getBalanceForeignPolkadotXcm(api, node, address, asset));
3257
+ return _context.abrupt("return", api.getBalanceNativeAcala(address, symbol));
3258
+ case 10:
3259
+ return _context.abrupt("return", api.getBalanceNative(address));
3597
3260
  case 11:
3598
- throw new InvalidParameterError('Unsupported pallet');
3599
- case 12:
3600
3261
  case "end":
3601
3262
  return _context.stop();
3602
3263
  }
3603
3264
  }, _callee);
3604
3265
  }));
3605
- return function getBalanceForeignInternal(_x) {
3266
+ return function getBalanceNativeInternal(_x) {
3606
3267
  return _ref2.apply(this, arguments);
3607
3268
  };
3608
3269
  }();
3609
- var getBalanceForeign = /*#__PURE__*/function () {
3270
+ var getBalanceNative = /*#__PURE__*/function () {
3610
3271
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
3611
3272
  var api;
3612
3273
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
@@ -3615,7 +3276,7 @@ var getBalanceForeign = /*#__PURE__*/function () {
3615
3276
  api = options.api;
3616
3277
  _context2.prev = 1;
3617
3278
  _context2.next = 4;
3618
- return getBalanceForeignInternal(options);
3279
+ return getBalanceNativeInternal(options);
3619
3280
  case 4:
3620
3281
  return _context2.abrupt("return", _context2.sent);
3621
3282
  case 5:
@@ -3630,106 +3291,30 @@ var getBalanceForeign = /*#__PURE__*/function () {
3630
3291
  }
3631
3292
  }, _callee2, null, [[1,, 5, 9]]);
3632
3293
  }));
3633
- return function getBalanceForeign(_x2) {
3294
+ return function getBalanceNative(_x2) {
3634
3295
  return _ref3.apply(this, arguments);
3635
3296
  };
3636
3297
  }();
3637
3298
 
3638
- var getBalanceNativeInternal = /*#__PURE__*/function () {
3299
+ var getAssetBalanceInternal = /*#__PURE__*/function () {
3639
3300
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3640
- var address, node, api, currency, symbol;
3301
+ var _yield$getBalanceFore;
3302
+ var address, node, currency, api, asset, isNativeSymbol;
3641
3303
  return _regeneratorRuntime().wrap(function _callee$(_context) {
3642
3304
  while (1) switch (_context.prev = _context.next) {
3643
3305
  case 0:
3644
- address = _ref.address, node = _ref.node, api = _ref.api, currency = _ref.currency;
3306
+ address = _ref.address, node = _ref.node, currency = _ref.currency, api = _ref.api;
3645
3307
  _context.next = 3;
3646
3308
  return api.init(node);
3647
3309
  case 3:
3648
- if (!(node === 'Interlay' || node === 'Kintsugi')) {
3649
- _context.next = 5;
3310
+ asset = findAssetForNodeOrThrow(node, currency, null);
3311
+ isNativeSymbol = asset.symbol === getNativeAssetSymbol(node);
3312
+ if (!(isNativeSymbol && node !== 'Interlay' && node !== 'Kintsugi')) {
3313
+ _context.next = 11;
3650
3314
  break;
3651
3315
  }
3652
- return _context.abrupt("return", getBalanceForeignInternal({
3653
- address: address,
3654
- node: node,
3655
- api: api,
3656
- currency: {
3657
- symbol: currency ? currency.symbol : getAssetsObject(node).nativeAssetSymbol
3658
- }
3659
- }));
3660
- case 5:
3661
- if (!(currency && currency.symbol !== getNativeAssetSymbol(node) && (node === 'Acala' || node === 'Karura'))) {
3662
- _context.next = 10;
3663
- break;
3664
- }
3665
- symbol = currency.symbol === 'aSEED' ? 'AUSD' : currency.symbol;
3666
- if (!(symbol.toLowerCase() === 'lcdot')) {
3667
- _context.next = 9;
3668
- break;
3669
- }
3670
- throw new InvalidCurrencyError('LcDOT balance is not supported');
3671
- case 9:
3672
- return _context.abrupt("return", api.getBalanceNativeAcala(address, symbol));
3673
- case 10:
3674
- return _context.abrupt("return", api.getBalanceNative(address));
3675
- case 11:
3676
- case "end":
3677
- return _context.stop();
3678
- }
3679
- }, _callee);
3680
- }));
3681
- return function getBalanceNativeInternal(_x) {
3682
- return _ref2.apply(this, arguments);
3683
- };
3684
- }();
3685
- var getBalanceNative = /*#__PURE__*/function () {
3686
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
3687
- var api;
3688
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
3689
- while (1) switch (_context2.prev = _context2.next) {
3690
- case 0:
3691
- api = options.api;
3692
- _context2.prev = 1;
3693
- _context2.next = 4;
3694
- return getBalanceNativeInternal(options);
3695
- case 4:
3696
- return _context2.abrupt("return", _context2.sent);
3697
- case 5:
3698
- _context2.prev = 5;
3699
- _context2.next = 8;
3700
- return api.disconnect();
3701
- case 8:
3702
- return _context2.finish(5);
3703
- case 9:
3704
- case "end":
3705
- return _context2.stop();
3706
- }
3707
- }, _callee2, null, [[1,, 5, 9]]);
3708
- }));
3709
- return function getBalanceNative(_x2) {
3710
- return _ref3.apply(this, arguments);
3711
- };
3712
- }();
3713
-
3714
- var getAssetBalanceInternal = /*#__PURE__*/function () {
3715
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3716
- var _yield$getBalanceFore;
3717
- var address, node, currency, api, asset, isNativeSymbol;
3718
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3719
- while (1) switch (_context.prev = _context.next) {
3720
- case 0:
3721
- address = _ref.address, node = _ref.node, currency = _ref.currency, api = _ref.api;
3722
- _context.next = 3;
3723
- return api.init(node);
3724
- case 3:
3725
- asset = findAssetForNodeOrThrow(node, currency, null);
3726
- isNativeSymbol = asset.symbol === getNativeAssetSymbol(node);
3727
- if (!(isNativeSymbol && node !== 'Interlay' && node !== 'Kintsugi')) {
3728
- _context.next = 11;
3729
- break;
3730
- }
3731
- _context.next = 8;
3732
- return getBalanceNativeInternal({
3316
+ _context.next = 8;
3317
+ return getBalanceNativeInternal({
3733
3318
  address: address,
3734
3319
  node: node,
3735
3320
  api: api
@@ -4252,163 +3837,614 @@ var abi = [
4252
3837
  }
4253
3838
  ];
4254
3839
 
4255
- // https://github.com/moonbeam-foundation/moonbeam/blob/b2b1bde7ced13aad4bd2928effc415c521fd48cb/runtime/moonbeam/src/precompiles.rs#L281
4256
- var xcmInterfacePrecompile = '0x000000000000000000000000000000000000081A';
4257
- var XCDOT = '0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080';
4258
- var transferMoonbeamToEth = /*#__PURE__*/function () {
4259
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
4260
- var _signer$account;
4261
- var api, from, to, signer, address, ahAddress, currency, bridgeStatus, foundAsset, ethAsset, contract, senderAddress, messageId, customXcm, customXcmOnDest, assetHubApi, _yield$getParaEthTran, _yield$getParaEthTran2, bridgeFee, executionFee, transferFee, createTx, numberToHex32, tx;
3840
+ // https://github.com/moonbeam-foundation/moonbeam/blob/b2b1bde7ced13aad4bd2928effc415c521fd48cb/runtime/moonbeam/src/precompiles.rs#L281
3841
+ var xcmInterfacePrecompile = '0x000000000000000000000000000000000000081A';
3842
+ var XCDOT = '0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080';
3843
+ var transferMoonbeamToEth = /*#__PURE__*/function () {
3844
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3845
+ var _signer$account;
3846
+ var api, from, to, signer, address, ahAddress, currency, bridgeStatus, foundAsset, ethAsset, contract, senderAddress, messageId, customXcm, customXcmOnDest, assetHubApi, _yield$getParaEthTran, _yield$getParaEthTran2, bridgeFee, executionFee, transferFee, createTx, numberToHex32, tx;
3847
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
3848
+ while (1) switch (_context.prev = _context.next) {
3849
+ case 0:
3850
+ api = _ref.api, from = _ref.from, to = _ref.to, signer = _ref.signer, address = _ref.address, ahAddress = _ref.ahAddress, currency = _ref.currency;
3851
+ if (ahAddress) {
3852
+ _context.next = 3;
3853
+ break;
3854
+ }
3855
+ throw new InvalidParameterError('AssetHub address is required');
3856
+ case 3:
3857
+ _context.next = 5;
3858
+ return getBridgeStatus(api.clone());
3859
+ case 5:
3860
+ bridgeStatus = _context.sent;
3861
+ if (!(bridgeStatus !== 'Normal')) {
3862
+ _context.next = 8;
3863
+ break;
3864
+ }
3865
+ throw new BridgeHaltedError();
3866
+ case 8:
3867
+ if (!('multiasset' in currency)) {
3868
+ _context.next = 10;
3869
+ break;
3870
+ }
3871
+ throw new InvalidParameterError('Multiassets syntax is not supported for Evm transfers');
3872
+ case 10:
3873
+ if (!('multilocation' in currency && isOverrideMultiLocationSpecifier(currency.multilocation))) {
3874
+ _context.next = 12;
3875
+ break;
3876
+ }
3877
+ throw new InvalidParameterError('Override multilocation is not supported for Evm transfers');
3878
+ case 12:
3879
+ foundAsset = findAsset(from, currency, to);
3880
+ if (!(foundAsset === null)) {
3881
+ _context.next = 15;
3882
+ break;
3883
+ }
3884
+ throw new InvalidCurrencyError("Origin node ".concat(from, " does not support currency ").concat(JSON.stringify(currency), "."));
3885
+ case 15:
3886
+ if (!(!isForeignAsset(foundAsset) || !foundAsset.multiLocation)) {
3887
+ _context.next = 17;
3888
+ break;
3889
+ }
3890
+ throw new InvalidCurrencyError('Currency must be a foreign asset with valid multi-location');
3891
+ case 17:
3892
+ ethAsset = findAssetByMultiLocation(getOtherAssets('Ethereum'), foundAsset.multiLocation);
3893
+ if (!(!ethAsset || !ethAsset.assetId)) {
3894
+ _context.next = 20;
3895
+ break;
3896
+ }
3897
+ throw new InvalidCurrencyError("Could not obtain Ethereum asset address for ".concat(JSON.stringify(foundAsset)));
3898
+ case 20:
3899
+ contract = isEthersSigner(signer) ? new Contract(xcmInterfacePrecompile, abi, signer) : getContract({
3900
+ abi: abi,
3901
+ address: xcmInterfacePrecompile,
3902
+ client: {
3903
+ "public": createPublicClient({
3904
+ chain: signer.chain,
3905
+ transport: http()
3906
+ }),
3907
+ wallet: signer
3908
+ }
3909
+ });
3910
+ if (!isEthersSigner(signer)) {
3911
+ _context.next = 27;
3912
+ break;
3913
+ }
3914
+ _context.next = 24;
3915
+ return signer.getAddress();
3916
+ case 24:
3917
+ _context.t0 = _context.sent;
3918
+ _context.next = 28;
3919
+ break;
3920
+ case 27:
3921
+ _context.t0 = (_signer$account = signer.account) === null || _signer$account === void 0 ? void 0 : _signer$account.address;
3922
+ case 28:
3923
+ senderAddress = _context.t0;
3924
+ if (senderAddress) {
3925
+ _context.next = 31;
3926
+ break;
3927
+ }
3928
+ throw new InvalidParameterError('Unable to get sender address');
3929
+ case 31:
3930
+ _context.next = 33;
3931
+ return api.init(from, TX_CLIENT_TIMEOUT_MS);
3932
+ case 33:
3933
+ _context.next = 35;
3934
+ return generateMessageId(api, senderAddress, getParaId(from), ethAsset.assetId, address, currency.amount);
3935
+ case 35:
3936
+ messageId = _context.sent;
3937
+ customXcm = createCustomXcmOnDest({
3938
+ api: api,
3939
+ address: address,
3940
+ scenario: 'ParaToPara',
3941
+ senderAddress: senderAddress,
3942
+ ahAddress: ahAddress,
3943
+ asset: _objectSpread2(_objectSpread2({}, foundAsset), {}, {
3944
+ amount: currency.amount
3945
+ })}, from, Version.V4, messageId);
3946
+ _context.next = 39;
3947
+ return api.objectToHex(customXcm, 'XcmVersionedXcm');
3948
+ case 39:
3949
+ customXcmOnDest = _context.sent;
3950
+ _context.next = 42;
3951
+ return api.createApiForNode('AssetHubPolkadot');
3952
+ case 42:
3953
+ assetHubApi = _context.sent;
3954
+ _context.next = 45;
3955
+ return getParaEthTransferFees(assetHubApi);
3956
+ case 45:
3957
+ _yield$getParaEthTran = _context.sent;
3958
+ _yield$getParaEthTran2 = _slicedToArray(_yield$getParaEthTran, 2);
3959
+ bridgeFee = _yield$getParaEthTran2[0];
3960
+ executionFee = _yield$getParaEthTran2[1];
3961
+ transferFee = (bridgeFee + executionFee).toString(); // Partially inspired by Moonbeam XCM-SDK
3962
+ // https://github.com/moonbeam-foundation/xcm-sdk/blob/ab835c15bf41612604b1c858d956a9f07705ed65/packages/sdk/src/contract/contracts/Xtokens/Xtokens.ts#L53
3963
+ createTx = function createTx(func, args) {
3964
+ if (isEthersContract(contract)) {
3965
+ return contract[func].apply(contract, _toConsumableArray(args));
3966
+ }
3967
+ return contract.write[func](args);
3968
+ };
3969
+ numberToHex32 = function numberToHex32(num) {
3970
+ return typeof num !== 'number' || isNaN(num) ? function () {
3971
+ throw new InvalidParameterError('Input must be a valid number');
3972
+ }() : "0x".concat((num >>> 0).toString(16).padStart(8, '0'));
3973
+ }; // Execute the custom XCM message with the precompile
3974
+ _context.next = 54;
3975
+ return createTx(isEthersSigner(signer) ? 'transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)' : 'transferAssetsUsingTypeAndThenAddress', [
3976
+ // This represents (1,X1(Parachain(1000)))
3977
+ [1, ['0x00' + numberToHex32(getParaId('AssetHubPolkadot')).slice(2)]],
3978
+ // Assets including fee and the ERC20 asset, with fee be the first
3979
+ [[XCDOT, transferFee], [ethAsset.assetId, currency.amount.toString()]],
3980
+ // The TransferType corresponding to asset being sent, 2 represents `DestinationReserve`
3981
+ 2,
3982
+ // index for the fee
3983
+ 0,
3984
+ // The TransferType corresponding to fee asset
3985
+ 2, customXcmOnDest]);
3986
+ case 54:
3987
+ tx = _context.sent;
3988
+ return _context.abrupt("return", _typeof(tx) === 'object' ? tx.hash : tx);
3989
+ case 56:
3990
+ case "end":
3991
+ return _context.stop();
3992
+ }
3993
+ }, _callee);
3994
+ }));
3995
+ return function transferMoonbeamToEth(_x) {
3996
+ return _ref2.apply(this, arguments);
3997
+ };
3998
+ }();
3999
+
4000
+ var resolveFeeAsset = function resolveFeeAsset(feeAsset, origin, destination, currency) {
4001
+ var asset = findAsset(origin, feeAsset, !isTMultiLocation(destination) ? destination : null);
4002
+ var usesRawOverriddenMultiAssets = 'multiasset' in currency && currency.multiasset.every(isTMultiAsset);
4003
+ if (!asset && !usesRawOverriddenMultiAssets) {
4004
+ throwUnsupportedCurrency(feeAsset, origin);
4005
+ }
4006
+ return asset !== null && asset !== void 0 ? asset : undefined;
4007
+ };
4008
+
4009
+ var isAssetHub = function isAssetHub(chain) {
4010
+ return chain === 'AssetHubPolkadot' || chain === 'AssetHubKusama';
4011
+ };
4012
+ var isBridgeHub = function isBridgeHub(chain) {
4013
+ return chain === 'BridgeHubPolkadot' || chain === 'BridgeHubKusama';
4014
+ };
4015
+ var isPeople = function isPeople(chain) {
4016
+ return chain === 'PeoplePolkadot' || chain === 'PeopleKusama';
4017
+ };
4018
+ var isSystemPara = function isSystemPara(chain) {
4019
+ return isAssetHub(chain) || isBridgeHub(chain) || isPeople(chain);
4020
+ };
4021
+ var mul = function mul(v, num) {
4022
+ var den = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1n;
4023
+ return v * num / den;
4024
+ };
4025
+ var padFee = function padFee(raw, origin, dest, side) {
4026
+ var relayOrigin = isRelayChain(origin);
4027
+ var relayDest = isRelayChain(dest);
4028
+ var sysParaOrigin = isSystemPara(origin);
4029
+ var sysParaDest = isSystemPara(dest);
4030
+ var relayToPara = relayOrigin && !relayDest;
4031
+ var sysParaToPara = sysParaOrigin && !sysParaDest;
4032
+ var paraToPara = !relayOrigin && !sysParaOrigin;
4033
+ if (sysParaToPara) return raw * 40n;
4034
+ if (relayToPara) return side === 'origin' ? mul(raw, 320n, 100n) : mul(raw, 3000n, 100n);
4035
+ if (paraToPara) return mul(raw, 130n, 100n);
4036
+ // apply default 30% padding
4037
+ return mul(raw, 130n, 100n);
4038
+ };
4039
+
4040
+ var getReverseTxFee = /*#__PURE__*/function () {
4041
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref, currencyInput) {
4042
+ var api, origin, destination, senderAddress, address, currency, tx, rawFee;
4043
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
4044
+ while (1) switch (_context.prev = _context.next) {
4045
+ case 0:
4046
+ api = _ref.api, origin = _ref.origin, destination = _ref.destination, senderAddress = _ref.senderAddress, address = _ref.address, currency = _ref.currency;
4047
+ if (!('multiasset' in currency)) {
4048
+ _context.next = 3;
4049
+ break;
4050
+ }
4051
+ throw new InvalidCurrencyError('Multi-assets are not yet supported for XCM fee calculation.');
4052
+ case 3:
4053
+ _context.next = 5;
4054
+ return Builder(api).from(destination).to(origin).address(senderAddress).senderAddress(address).currency(_objectSpread2(_objectSpread2({}, currencyInput), {}, {
4055
+ amount: currency.amount
4056
+ })).build();
4057
+ case 5:
4058
+ tx = _context.sent;
4059
+ _context.next = 8;
4060
+ return api.calculateTransactionFee(tx, address);
4061
+ case 8:
4062
+ rawFee = _context.sent;
4063
+ return _context.abrupt("return", padFee(rawFee, origin, destination, 'destination'));
4064
+ case 10:
4065
+ case "end":
4066
+ return _context.stop();
4067
+ }
4068
+ }, _callee);
4069
+ }));
4070
+ return function getReverseTxFee(_x, _x2) {
4071
+ return _ref2.apply(this, arguments);
4072
+ };
4073
+ }();
4074
+
4075
+ var createOriginLocation = function createOriginLocation(origin, destination) {
4076
+ if (isRelayChain(origin)) return DOT_MULTILOCATION;
4077
+ return {
4078
+ parents: isRelayChain(destination) ? Parents.ZERO : Parents.ONE,
4079
+ interior: {
4080
+ X1: [{
4081
+ Parachain: getParaId(origin)
4082
+ }]
4083
+ }
4084
+ };
4085
+ };
4086
+ var getDestXcmFee = /*#__PURE__*/function () {
4087
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
4088
+ var api, origin, destination, currency, forwardedXcms, asset, feeAsset, originFee, disableFallback, resolvedFeeAsset, calcPaymentInfoFee, dryRunResult, fee, newForwardedXcms, destParaId;
4089
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
4090
+ while (1) switch (_context2.prev = _context2.next) {
4091
+ case 0:
4092
+ api = options.api, origin = options.origin, destination = options.destination, currency = options.currency, forwardedXcms = options.forwardedXcms, asset = options.asset, feeAsset = options.feeAsset, originFee = options.originFee, disableFallback = options.disableFallback;
4093
+ resolvedFeeAsset = feeAsset ? resolveFeeAsset(feeAsset, origin, destination, currency) : undefined;
4094
+ calcPaymentInfoFee = /*#__PURE__*/function () {
4095
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
4096
+ var originAsset;
4097
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
4098
+ while (1) switch (_context.prev = _context.next) {
4099
+ case 0:
4100
+ if (!(destination === 'Ethereum')) {
4101
+ _context.next = 2;
4102
+ break;
4103
+ }
4104
+ return _context.abrupt("return", 0n);
4105
+ case 2:
4106
+ originAsset = findAsset(origin, currency, destination);
4107
+ if (originAsset) {
4108
+ _context.next = 5;
4109
+ break;
4110
+ }
4111
+ throw new InvalidCurrencyError("Currency ".concat(JSON.stringify(currency), " not found in ").concat(origin));
4112
+ case 5:
4113
+ if (!originAsset.multiLocation) {
4114
+ _context.next = 19;
4115
+ break;
4116
+ }
4117
+ _context.prev = 6;
4118
+ _context.next = 9;
4119
+ return getReverseTxFee(_objectSpread2(_objectSpread2({}, options), {}, {
4120
+ destination: destination
4121
+ }), {
4122
+ multilocation: originAsset.multiLocation
4123
+ });
4124
+ case 9:
4125
+ return _context.abrupt("return", _context.sent);
4126
+ case 12:
4127
+ _context.prev = 12;
4128
+ _context.t0 = _context["catch"](6);
4129
+ if (!(_context.t0 instanceof InvalidCurrencyError)) {
4130
+ _context.next = 18;
4131
+ break;
4132
+ }
4133
+ _context.next = 17;
4134
+ return getReverseTxFee(_objectSpread2(_objectSpread2({}, options), {}, {
4135
+ destination: destination
4136
+ }), {
4137
+ symbol: originAsset.symbol
4138
+ });
4139
+ case 17:
4140
+ return _context.abrupt("return", _context.sent);
4141
+ case 18:
4142
+ throw _context.t0;
4143
+ case 19:
4144
+ _context.next = 21;
4145
+ return getReverseTxFee(_objectSpread2(_objectSpread2({}, options), {}, {
4146
+ destination: destination
4147
+ }), {
4148
+ symbol: originAsset.symbol
4149
+ });
4150
+ case 21:
4151
+ return _context.abrupt("return", _context.sent);
4152
+ case 22:
4153
+ case "end":
4154
+ return _context.stop();
4155
+ }
4156
+ }, _callee, null, [[6, 12]]);
4157
+ }));
4158
+ return function calcPaymentInfoFee() {
4159
+ return _ref2.apply(this, arguments);
4160
+ };
4161
+ }();
4162
+ if (!(!hasDryRunSupport(destination) || !forwardedXcms || destination === 'Ethereum')) {
4163
+ _context2.next = 8;
4164
+ break;
4165
+ }
4166
+ _context2.next = 6;
4167
+ return calcPaymentInfoFee();
4168
+ case 6:
4169
+ _context2.t0 = _context2.sent;
4170
+ return _context2.abrupt("return", {
4171
+ fee: _context2.t0,
4172
+ feeType: 'paymentInfo'
4173
+ });
4174
+ case 8:
4175
+ _context2.next = 10;
4176
+ return api.getDryRunXcm({
4177
+ originLocation: addXcmVersionHeader(createOriginLocation(origin, destination), Version.V4),
4178
+ xcm: forwardedXcms[1][0],
4179
+ node: destination,
4180
+ origin: origin,
4181
+ asset: asset,
4182
+ originFee: originFee,
4183
+ feeAsset: resolvedFeeAsset,
4184
+ amount: BigInt(currency.amount)
4185
+ });
4186
+ case 10:
4187
+ dryRunResult = _context2.sent;
4188
+ if (dryRunResult.success) {
4189
+ _context2.next = 19;
4190
+ break;
4191
+ }
4192
+ if (!disableFallback) {
4193
+ _context2.next = 14;
4194
+ break;
4195
+ }
4196
+ return _context2.abrupt("return", {
4197
+ dryRunError: dryRunResult.failureReason
4198
+ });
4199
+ case 14:
4200
+ _context2.next = 16;
4201
+ return calcPaymentInfoFee();
4202
+ case 16:
4203
+ _context2.t1 = _context2.sent;
4204
+ _context2.t2 = dryRunResult.failureReason;
4205
+ return _context2.abrupt("return", {
4206
+ fee: _context2.t1,
4207
+ feeType: 'paymentInfo',
4208
+ dryRunError: _context2.t2
4209
+ });
4210
+ case 19:
4211
+ fee = dryRunResult.fee, newForwardedXcms = dryRunResult.forwardedXcms, destParaId = dryRunResult.destParaId;
4212
+ return _context2.abrupt("return", {
4213
+ fee: fee,
4214
+ feeType: 'dryRun',
4215
+ forwardedXcms: newForwardedXcms,
4216
+ destParaId: destParaId
4217
+ });
4218
+ case 21:
4219
+ case "end":
4220
+ return _context2.stop();
4221
+ }
4222
+ }, _callee2);
4223
+ }));
4224
+ return function getDestXcmFee(_x) {
4225
+ return _ref.apply(this, arguments);
4226
+ };
4227
+ }();
4228
+
4229
+ var dryRunInternal = /*#__PURE__*/function () {
4230
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
4231
+ var _intermediateFees$bri, _intermediateFees$ass, _processedBridgeHubDa, _destinationDryRun;
4232
+ var origin, destination, currency, api, tx, senderAddress, feeAsset, resolvedFeeAsset, asset, originDryRun, initialForwardedXcms, initialDestParaId, assetHubNode, bridgeHubNode, currentOrigin, forwardedXcms, nextParaId, intermediateFees, destinationDryRun, nextChain, hopApi, hopDryRun, newXcms, destParaId, processedBridgeHubData, ahApi, _yield$getParaEthTran, _yield$getParaEthTran2, bridgeFee;
4262
4233
  return _regeneratorRuntime().wrap(function _callee$(_context) {
4263
4234
  while (1) switch (_context.prev = _context.next) {
4264
4235
  case 0:
4265
- api = _ref.api, from = _ref.from, to = _ref.to, signer = _ref.signer, address = _ref.address, ahAddress = _ref.ahAddress, currency = _ref.currency;
4266
- if (ahAddress) {
4267
- _context.next = 3;
4268
- break;
4269
- }
4270
- throw new InvalidParameterError('AssetHub address is required');
4271
- case 3:
4236
+ origin = options.origin, destination = options.destination, currency = options.currency, api = options.api, tx = options.tx, senderAddress = options.senderAddress, feeAsset = options.feeAsset;
4237
+ resolvedFeeAsset = feeAsset && origin === 'AssetHubPolkadot' ? resolveFeeAsset(feeAsset, origin, destination, currency) : undefined;
4238
+ asset = 'multiasset' in currency ? null : findAssetForNodeOrThrow(origin, currency, destination);
4272
4239
  _context.next = 5;
4273
- return getBridgeStatus(api.clone());
4240
+ return api.getDryRunCall({
4241
+ tx: tx,
4242
+ node: origin,
4243
+ address: senderAddress,
4244
+ isFeeAsset: !!resolvedFeeAsset
4245
+ });
4274
4246
  case 5:
4275
- bridgeStatus = _context.sent;
4276
- if (!(bridgeStatus !== 'Normal')) {
4247
+ originDryRun = _context.sent;
4248
+ if (originDryRun.success) {
4277
4249
  _context.next = 8;
4278
4250
  break;
4279
4251
  }
4280
- throw new BridgeHaltedError();
4252
+ return _context.abrupt("return", {
4253
+ origin: originDryRun
4254
+ });
4281
4255
  case 8:
4282
- if (!('multiasset' in currency)) {
4283
- _context.next = 10;
4284
- break;
4285
- }
4286
- throw new InvalidParameterError('Multiassets syntax is not supported for Evm transfers');
4287
- case 10:
4288
- if (!('multilocation' in currency && isOverrideMultiLocationSpecifier(currency.multilocation))) {
4289
- _context.next = 12;
4290
- break;
4291
- }
4292
- throw new InvalidParameterError('Override multilocation is not supported for Evm transfers');
4293
- case 12:
4294
- foundAsset = findAsset(from, currency, to);
4295
- if (!(foundAsset === null)) {
4296
- _context.next = 15;
4297
- break;
4298
- }
4299
- throw new InvalidCurrencyError("Origin node ".concat(from, " does not support currency ").concat(JSON.stringify(currency), "."));
4256
+ initialForwardedXcms = originDryRun.forwardedXcms, initialDestParaId = originDryRun.destParaId;
4257
+ assetHubNode = determineRelayChain(origin) === 'Polkadot' ? 'AssetHubPolkadot' : 'AssetHubKusama';
4258
+ bridgeHubNode = determineRelayChain(origin) === 'Polkadot' ? 'BridgeHubPolkadot' : 'BridgeHubKusama';
4259
+ currentOrigin = origin;
4260
+ forwardedXcms = initialForwardedXcms;
4261
+ nextParaId = initialDestParaId;
4262
+ intermediateFees = {};
4300
4263
  case 15:
4301
- if (!(!isForeignAsset(foundAsset) || !foundAsset.multiLocation)) {
4302
- _context.next = 17;
4264
+ if (!(Array.isArray(forwardedXcms) && forwardedXcms.length && forwardedXcms[1].length && ('disconnect' in api.getApi() ? Object.values(forwardedXcms[1][0]).length : forwardedXcms[1][0].value.length) > 0 && nextParaId !== undefined)) {
4265
+ _context.next = 42;
4303
4266
  break;
4304
4267
  }
4305
- throw new InvalidCurrencyError('Currency must be a foreign asset with valid multi-location');
4306
- case 17:
4307
- ethAsset = findAssetByMultiLocation(getOtherAssets('Ethereum'), foundAsset.multiLocation);
4308
- if (!(!ethAsset || !ethAsset.assetId)) {
4309
- _context.next = 20;
4268
+ nextChain = getTNode(nextParaId, determineRelayChain(origin) === 'Polkadot' ? 'polkadot' : 'kusama');
4269
+ if (nextChain) {
4270
+ _context.next = 19;
4310
4271
  break;
4311
4272
  }
4312
- throw new InvalidCurrencyError("Could not obtain Ethereum asset address for ".concat(JSON.stringify(foundAsset)));
4313
- case 20:
4314
- contract = isEthersSigner(signer) ? new Contract(xcmInterfacePrecompile, abi, signer) : getContract({
4315
- abi: abi,
4316
- address: xcmInterfacePrecompile,
4317
- client: {
4318
- "public": createPublicClient({
4319
- chain: signer.chain,
4320
- transport: http()
4321
- }),
4322
- wallet: signer
4323
- }
4324
- });
4325
- if (!isEthersSigner(signer)) {
4326
- _context.next = 27;
4273
+ throw new InvalidParameterError("Unable to find TNode for paraId ".concat(nextParaId));
4274
+ case 19:
4275
+ hopApi = api.clone();
4276
+ _context.prev = 20;
4277
+ if (hasDryRunSupport(nextChain)) {
4278
+ _context.next = 24;
4327
4279
  break;
4328
4280
  }
4329
- _context.next = 24;
4330
- return signer.getAddress();
4281
+ if (nextChain === destination) {
4282
+ destinationDryRun = {
4283
+ success: false,
4284
+ failureReason: "DryRunApi is not available on node ".concat(nextChain)
4285
+ };
4286
+ }
4287
+ return _context.abrupt("break", 42);
4331
4288
  case 24:
4332
- _context.t0 = _context.sent;
4289
+ _context.next = 26;
4290
+ return hopApi.init(nextChain, DRY_RUN_CLIENT_TIMEOUT_MS);
4291
+ case 26:
4333
4292
  _context.next = 28;
4334
- break;
4335
- case 27:
4336
- _context.t0 = (_signer$account = signer.account) === null || _signer$account === void 0 ? void 0 : _signer$account.address;
4293
+ return hopApi.getDryRunXcm({
4294
+ originLocation: addXcmVersionHeader(createOriginLocation(currentOrigin, nextChain), Version.V4),
4295
+ xcm: forwardedXcms[1][0],
4296
+ node: nextChain,
4297
+ origin: currentOrigin,
4298
+ asset: asset,
4299
+ feeAsset: resolvedFeeAsset,
4300
+ originFee: originDryRun.fee,
4301
+ amount: BigInt(currency.amount)
4302
+ });
4337
4303
  case 28:
4338
- senderAddress = _context.t0;
4339
- if (senderAddress) {
4340
- _context.next = 31;
4304
+ hopDryRun = _context.sent;
4305
+ if (nextChain === destination || isRelayChain(nextChain) && !isRelayChain(destination)) {
4306
+ destinationDryRun = hopDryRun;
4307
+ } else if (nextChain === assetHubNode) {
4308
+ intermediateFees.assetHub = hopDryRun;
4309
+ } else if (nextChain === bridgeHubNode) {
4310
+ intermediateFees.bridgeHub = hopDryRun;
4311
+ }
4312
+ if (hopDryRun.success) {
4313
+ _context.next = 32;
4341
4314
  break;
4342
4315
  }
4343
- throw new InvalidParameterError('Unable to get sender address');
4344
- case 31:
4345
- _context.next = 33;
4346
- return api.init(from, TX_CLIENT_TIMEOUT_MS);
4347
- case 33:
4348
- _context.next = 35;
4349
- return generateMessageId(api, senderAddress, getParaId(from), ethAsset.assetId, address, currency.amount);
4350
- case 35:
4351
- messageId = _context.sent;
4352
- customXcm = createCustomXcmOnDest({
4353
- api: api,
4354
- address: address,
4355
- scenario: 'ParaToPara',
4356
- senderAddress: senderAddress,
4357
- ahAddress: ahAddress,
4358
- asset: _objectSpread2(_objectSpread2({}, foundAsset), {}, {
4359
- amount: currency.amount
4360
- })}, from, Version.V4, messageId);
4316
+ return _context.abrupt("break", 42);
4317
+ case 32:
4318
+ newXcms = hopDryRun.forwardedXcms, destParaId = hopDryRun.destParaId;
4319
+ forwardedXcms = newXcms;
4320
+ nextParaId = destParaId;
4321
+ currentOrigin = nextChain;
4322
+ case 36:
4323
+ _context.prev = 36;
4361
4324
  _context.next = 39;
4362
- return api.objectToHex(customXcm, 'XcmVersionedXcm');
4325
+ return hopApi.disconnect();
4363
4326
  case 39:
4364
- customXcmOnDest = _context.sent;
4365
- _context.next = 42;
4366
- return api.createApiForNode('AssetHubPolkadot');
4327
+ return _context.finish(36);
4328
+ case 40:
4329
+ _context.next = 15;
4330
+ break;
4367
4331
  case 42:
4368
- assetHubApi = _context.sent;
4369
- _context.next = 45;
4370
- return getParaEthTransferFees(assetHubApi);
4371
- case 45:
4332
+ processedBridgeHubData = intermediateFees.bridgeHub;
4333
+ if (!((_intermediateFees$bri = intermediateFees.bridgeHub) !== null && _intermediateFees$bri !== void 0 && _intermediateFees$bri.success && destination === 'Ethereum')) {
4334
+ _context.next = 53;
4335
+ break;
4336
+ }
4337
+ ahApi = api.clone();
4338
+ _context.next = 47;
4339
+ return ahApi.init(assetHubNode, DRY_RUN_CLIENT_TIMEOUT_MS);
4340
+ case 47:
4341
+ _context.next = 49;
4342
+ return getParaEthTransferFees(ahApi);
4343
+ case 49:
4372
4344
  _yield$getParaEthTran = _context.sent;
4373
- _yield$getParaEthTran2 = _slicedToArray(_yield$getParaEthTran, 2);
4345
+ _yield$getParaEthTran2 = _slicedToArray(_yield$getParaEthTran, 1);
4374
4346
  bridgeFee = _yield$getParaEthTran2[0];
4375
- executionFee = _yield$getParaEthTran2[1];
4376
- transferFee = (bridgeFee + executionFee).toString(); // Partially inspired by Moonbeam XCM-SDK
4377
- // https://github.com/moonbeam-foundation/xcm-sdk/blob/ab835c15bf41612604b1c858d956a9f07705ed65/packages/sdk/src/contract/contracts/Xtokens/Xtokens.ts#L53
4378
- createTx = function createTx(func, args) {
4379
- if (isEthersContract(contract)) {
4380
- return contract[func].apply(contract, _toConsumableArray(args));
4381
- }
4382
- return contract.write[func](args);
4383
- };
4384
- numberToHex32 = function numberToHex32(num) {
4385
- return typeof num !== 'number' || isNaN(num) ? function () {
4386
- throw new InvalidParameterError('Input must be a valid number');
4387
- }() : "0x".concat((num >>> 0).toString(16).padStart(8, '0'));
4388
- }; // Execute the custom XCM message with the precompile
4389
- _context.next = 54;
4390
- return createTx(isEthersSigner(signer) ? 'transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)' : 'transferAssetsUsingTypeAndThenAddress', [
4391
- // This represents (1,X1(Parachain(1000)))
4392
- [1, ['0x00' + numberToHex32(getParaId('AssetHubPolkadot')).slice(2)]],
4393
- // Assets including fee and the ERC20 asset, with fee be the first
4394
- [[XCDOT, transferFee], [ethAsset.assetId, currency.amount.toString()]],
4395
- // The TransferType corresponding to asset being sent, 2 represents `DestinationReserve`
4396
- 2,
4397
- // index for the fee
4398
- 0,
4399
- // The TransferType corresponding to fee asset
4400
- 2, customXcmOnDest]);
4347
+ processedBridgeHubData = _objectSpread2(_objectSpread2({}, intermediateFees.bridgeHub), {}, {
4348
+ fee: intermediateFees.bridgeHub.fee + bridgeFee
4349
+ });
4350
+ case 53:
4351
+ return _context.abrupt("return", {
4352
+ origin: originDryRun.success ? _objectSpread2(_objectSpread2({}, originDryRun), {}, {
4353
+ currency: resolvedFeeAsset ? resolvedFeeAsset.symbol : getNativeAssetSymbol(origin)
4354
+ }) : originDryRun,
4355
+ assetHub: (_intermediateFees$ass = intermediateFees.assetHub) !== null && _intermediateFees$ass !== void 0 && _intermediateFees$ass.success ? _objectSpread2(_objectSpread2({}, intermediateFees.assetHub), {}, {
4356
+ currency: getNativeAssetSymbol(assetHubNode)
4357
+ }) : intermediateFees.assetHub,
4358
+ bridgeHub: (_processedBridgeHubDa = processedBridgeHubData) !== null && _processedBridgeHubDa !== void 0 && _processedBridgeHubDa.success ? _objectSpread2(_objectSpread2({}, processedBridgeHubData), {}, {
4359
+ currency: getNativeAssetSymbol(bridgeHubNode)
4360
+ }) : processedBridgeHubData,
4361
+ destination: (_destinationDryRun = destinationDryRun) !== null && _destinationDryRun !== void 0 && _destinationDryRun.success ? _objectSpread2(_objectSpread2({}, destinationDryRun), {}, {
4362
+ currency: asset === null || asset === void 0 ? void 0 : asset.symbol
4363
+ }) : destinationDryRun
4364
+ });
4401
4365
  case 54:
4402
- tx = _context.sent;
4403
- return _context.abrupt("return", _typeof(tx) === 'object' ? tx.hash : tx);
4404
- case 56:
4405
4366
  case "end":
4406
4367
  return _context.stop();
4407
4368
  }
4408
- }, _callee);
4369
+ }, _callee, null, [[20,, 36, 40]]);
4370
+ }));
4371
+ return function dryRunInternal(_x) {
4372
+ return _ref.apply(this, arguments);
4373
+ };
4374
+ }();
4375
+
4376
+ var dryRun = /*#__PURE__*/function () {
4377
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
4378
+ var api, senderAddress, origin;
4379
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
4380
+ while (1) switch (_context.prev = _context.next) {
4381
+ case 0:
4382
+ api = options.api, senderAddress = options.senderAddress, origin = options.origin;
4383
+ validateAddress(senderAddress, origin, false);
4384
+ _context.next = 4;
4385
+ return api.init(origin, DRY_RUN_CLIENT_TIMEOUT_MS);
4386
+ case 4:
4387
+ _context.prev = 4;
4388
+ _context.next = 7;
4389
+ return dryRunInternal(options);
4390
+ case 7:
4391
+ return _context.abrupt("return", _context.sent);
4392
+ case 8:
4393
+ _context.prev = 8;
4394
+ _context.next = 11;
4395
+ return api.disconnect();
4396
+ case 11:
4397
+ return _context.finish(8);
4398
+ case 12:
4399
+ case "end":
4400
+ return _context.stop();
4401
+ }
4402
+ }, _callee, null, [[4,, 8, 12]]);
4403
+ }));
4404
+ return function dryRun(_x) {
4405
+ return _ref.apply(this, arguments);
4406
+ };
4407
+ }();
4408
+
4409
+ var dryRunOrigin = /*#__PURE__*/function () {
4410
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
4411
+ var api, node, address, result;
4412
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
4413
+ while (1) switch (_context.prev = _context.next) {
4414
+ case 0:
4415
+ api = options.api, node = options.node, address = options.address;
4416
+ validateAddress(address, node, false);
4417
+ _context.next = 4;
4418
+ return api.init(node, DRY_RUN_CLIENT_TIMEOUT_MS);
4419
+ case 4:
4420
+ _context.prev = 4;
4421
+ _context.next = 7;
4422
+ return api.getDryRunCall(options);
4423
+ case 7:
4424
+ result = _context.sent;
4425
+ if (!result.success) {
4426
+ _context.next = 12;
4427
+ break;
4428
+ }
4429
+ return _context.abrupt("return", _objectSpread2(_objectSpread2({}, result), {}, {
4430
+ currency: getNativeAssetSymbol(node)
4431
+ }));
4432
+ case 12:
4433
+ return _context.abrupt("return", result);
4434
+ case 13:
4435
+ _context.prev = 13;
4436
+ _context.next = 16;
4437
+ return api.disconnect();
4438
+ case 16:
4439
+ return _context.finish(13);
4440
+ case 17:
4441
+ case "end":
4442
+ return _context.stop();
4443
+ }
4444
+ }, _callee, null, [[4,, 13, 17]]);
4409
4445
  }));
4410
- return function transferMoonbeamToEth(_x) {
4411
- return _ref2.apply(this, arguments);
4446
+ return function dryRunOrigin(_x) {
4447
+ return _ref.apply(this, arguments);
4412
4448
  };
4413
4449
  }();
4414
4450
 
@@ -4518,7 +4554,7 @@ var getOriginXcmFeeEstimate = /*#__PURE__*/function () {
4518
4554
 
4519
4555
  var getXcmFee = /*#__PURE__*/function () {
4520
4556
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
4521
- var api, tx, origin, destination, senderAddress, address, currency, feeAsset, disableFallback, asset, _yield$getOriginXcmFe, originFee, originCurrency, originFeeType, originDryRunError, initialForwardedXcm, initialDestParaId, destApi, destFeeRes, currentOrigin, forwardedXcms, nextParaId, intermediateFees, destinationFee, destinationFeeType, destinationDryRunError, nextChain, hopApi, hopResult, failingRecord, hopIsDestination, destFallback;
4557
+ var api, tx, origin, destination, senderAddress, address, currency, feeAsset, disableFallback, asset, _yield$getOriginXcmFe, originFee, originCurrency, originFeeType, originDryRunError, initialForwardedXcm, initialDestParaId, destApi, destFeeRes, assetHubNode, bridgeHubNode, currentOrigin, forwardedXcms, nextParaId, intermediateFees, destinationFee, destinationFeeType, destinationDryRunError, nextChain, hopApi, hopResult, failingRecord, hopIsDestination, destFallback, processedBridgeHubData, ahApi, _yield$getParaEthTran, _yield$getParaEthTran2, bridgeFee;
4522
4558
  return _regeneratorRuntime().wrap(function _callee$(_context) {
4523
4559
  while (1) switch (_context.prev = _context.next) {
4524
4560
  case 0:
@@ -4548,16 +4584,20 @@ var getXcmFee = /*#__PURE__*/function () {
4548
4584
  return api.disconnect();
4549
4585
  case 14:
4550
4586
  if (!(originDryRunError || originFeeType === 'paymentInfo')) {
4551
- _context.next = 29;
4587
+ _context.next = 30;
4552
4588
  break;
4553
4589
  }
4554
4590
  destApi = api.clone();
4555
4591
  _context.prev = 16;
4556
- _context.next = 19;
4592
+ if (!(destination !== 'Ethereum')) {
4593
+ _context.next = 20;
4594
+ break;
4595
+ }
4596
+ _context.next = 20;
4557
4597
  return destApi.init(destination, DRY_RUN_CLIENT_TIMEOUT_MS);
4558
- case 19:
4598
+ case 20:
4559
4599
  destApi.setDisconnectAllowed(false);
4560
- _context.next = 22;
4600
+ _context.next = 23;
4561
4601
  return getDestXcmFee({
4562
4602
  api: destApi,
4563
4603
  forwardedXcms: undefined,
@@ -4571,7 +4611,7 @@ var getXcmFee = /*#__PURE__*/function () {
4571
4611
  senderAddress: senderAddress,
4572
4612
  disableFallback: disableFallback
4573
4613
  });
4574
- case 22:
4614
+ case 23:
4575
4615
  destFeeRes = _context.sent;
4576
4616
  return _context.abrupt("return", {
4577
4617
  origin: _objectSpread2(_objectSpread2(_objectSpread2({}, originFee && {
@@ -4583,46 +4623,50 @@ var getXcmFee = /*#__PURE__*/function () {
4583
4623
  }, originDryRunError && {
4584
4624
  dryRunError: originDryRunError
4585
4625
  }),
4586
- destination: _objectSpread2(_objectSpread2(_objectSpread2({}, destFeeRes.fee && {
4626
+ destination: _objectSpread2(_objectSpread2(_objectSpread2({}, destFeeRes.fee ? {
4587
4627
  fee: destFeeRes.fee
4628
+ } : {
4629
+ fee: 0n
4588
4630
  }), destFeeRes.feeType && {
4589
4631
  feeType: destFeeRes.feeType
4590
4632
  }), {}, {
4591
4633
  currency: getNativeAssetSymbol(destination)
4592
4634
  })
4593
4635
  });
4594
- case 24:
4595
- _context.prev = 24;
4636
+ case 25:
4637
+ _context.prev = 25;
4596
4638
  destApi.setDisconnectAllowed(true);
4597
- _context.next = 28;
4639
+ _context.next = 29;
4598
4640
  return destApi.disconnect();
4599
- case 28:
4600
- return _context.finish(24);
4601
4641
  case 29:
4642
+ return _context.finish(25);
4643
+ case 30:
4644
+ assetHubNode = determineRelayChain(origin) === 'Polkadot' ? 'AssetHubPolkadot' : 'AssetHubKusama';
4645
+ bridgeHubNode = determineRelayChain(origin) === 'Polkadot' ? 'BridgeHubPolkadot' : 'BridgeHubKusama';
4602
4646
  currentOrigin = origin;
4603
4647
  forwardedXcms = initialForwardedXcm;
4604
4648
  nextParaId = initialDestParaId;
4605
4649
  intermediateFees = {};
4606
4650
  destinationFee = 0n;
4607
- destinationFeeType = 'paymentInfo';
4608
- case 35:
4651
+ destinationFeeType = destination === 'Ethereum' ? 'noFeeRequired' : 'paymentInfo';
4652
+ case 38:
4609
4653
  if (!(Array.isArray(forwardedXcms) && forwardedXcms.length > 0 && forwardedXcms[1].length > 0 && ('disconnect' in api.getApi() ? Object.values(forwardedXcms[1][0]).length : forwardedXcms[1][0].value.length) > 0 && nextParaId !== undefined)) {
4610
- _context.next = 67;
4654
+ _context.next = 70;
4611
4655
  break;
4612
4656
  }
4613
4657
  nextChain = getTNode(nextParaId, determineRelayChain(origin) === 'Polkadot' ? 'polkadot' : 'kusama');
4614
4658
  if (!(nextChain === null)) {
4615
- _context.next = 39;
4659
+ _context.next = 42;
4616
4660
  break;
4617
4661
  }
4618
4662
  throw new InvalidParameterError("Unable to find TNode for paraId ".concat(nextParaId));
4619
- case 39:
4663
+ case 42:
4620
4664
  hopApi = api.clone();
4621
- _context.prev = 40;
4622
- _context.next = 43;
4665
+ _context.prev = 43;
4666
+ _context.next = 46;
4623
4667
  return hopApi.init(nextChain, DRY_RUN_CLIENT_TIMEOUT_MS);
4624
- case 43:
4625
- _context.next = 45;
4668
+ case 46:
4669
+ _context.next = 48;
4626
4670
  return getDestXcmFee({
4627
4671
  api: hopApi,
4628
4672
  forwardedXcms: forwardedXcms,
@@ -4636,10 +4680,10 @@ var getXcmFee = /*#__PURE__*/function () {
4636
4680
  originFee: originFee !== null && originFee !== void 0 ? originFee : 0n,
4637
4681
  disableFallback: disableFallback
4638
4682
  });
4639
- case 45:
4683
+ case 48:
4640
4684
  hopResult = _context.sent;
4641
4685
  if (!hopResult.dryRunError) {
4642
- _context.next = 57;
4686
+ _context.next = 60;
4643
4687
  break;
4644
4688
  }
4645
4689
  failingRecord = {
@@ -4653,17 +4697,17 @@ var getXcmFee = /*#__PURE__*/function () {
4653
4697
  destinationFee = hopResult.fee;
4654
4698
  destinationFeeType = hopResult.feeType; // paymentInfo
4655
4699
  destinationDryRunError = hopResult.dryRunError;
4656
- } else if (nextChain === 'AssetHubPolkadot') {
4700
+ } else if (nextChain === assetHubNode) {
4657
4701
  intermediateFees.assetHub = failingRecord;
4658
- } else if (nextChain === 'BridgeHubPolkadot') {
4702
+ } else if (nextChain === bridgeHubNode) {
4659
4703
  intermediateFees.bridgeHub = failingRecord;
4660
4704
  }
4661
4705
  // We failed before the true destination, use fallback via paymentInfo.
4662
4706
  if (hopIsDestination) {
4663
- _context.next = 56;
4707
+ _context.next = 59;
4664
4708
  break;
4665
4709
  }
4666
- _context.next = 53;
4710
+ _context.next = 56;
4667
4711
  return getDestXcmFee({
4668
4712
  api: hopApi,
4669
4713
  forwardedXcms: undefined,
@@ -4676,23 +4720,23 @@ var getXcmFee = /*#__PURE__*/function () {
4676
4720
  senderAddress: senderAddress,
4677
4721
  disableFallback: disableFallback
4678
4722
  });
4679
- case 53:
4723
+ case 56:
4680
4724
  destFallback = _context.sent;
4681
4725
  destinationFee = destFallback.fee;
4682
4726
  destinationFeeType = destFallback.feeType;
4683
- case 56:
4684
- return _context.abrupt("break", 67);
4685
- case 57:
4727
+ case 59:
4728
+ return _context.abrupt("break", 70);
4729
+ case 60:
4686
4730
  if (nextChain === destination || isRelayChain(nextChain) && !isRelayChain(destination)) {
4687
4731
  destinationFee = hopResult.fee;
4688
4732
  destinationFeeType = hopResult.feeType;
4689
- } else if (nextChain === 'AssetHubPolkadot') {
4733
+ } else if (nextChain === assetHubNode) {
4690
4734
  intermediateFees.assetHub = {
4691
4735
  fee: hopResult.fee,
4692
4736
  feeType: hopResult.feeType,
4693
4737
  currency: getNativeAssetSymbol(nextChain)
4694
4738
  };
4695
- } else if (nextChain === 'BridgeHubPolkadot') {
4739
+ } else if (nextChain === bridgeHubNode) {
4696
4740
  intermediateFees.bridgeHub = {
4697
4741
  fee: hopResult.fee,
4698
4742
  feeType: hopResult.feeType,
@@ -4702,16 +4746,36 @@ var getXcmFee = /*#__PURE__*/function () {
4702
4746
  forwardedXcms = hopResult.forwardedXcms;
4703
4747
  nextParaId = hopResult.destParaId;
4704
4748
  currentOrigin = nextChain;
4705
- case 61:
4706
- _context.prev = 61;
4707
- _context.next = 64;
4708
- return hopApi.disconnect();
4709
4749
  case 64:
4710
- return _context.finish(61);
4711
- case 65:
4712
- _context.next = 35;
4713
- break;
4750
+ _context.prev = 64;
4751
+ _context.next = 67;
4752
+ return hopApi.disconnect();
4714
4753
  case 67:
4754
+ return _context.finish(64);
4755
+ case 68:
4756
+ _context.next = 38;
4757
+ break;
4758
+ case 70:
4759
+ processedBridgeHubData = intermediateFees.bridgeHub;
4760
+ if (!(intermediateFees.bridgeHub && !intermediateFees.bridgeHub.dryRunError && destination === 'Ethereum')) {
4761
+ _context.next = 81;
4762
+ break;
4763
+ }
4764
+ ahApi = api.clone();
4765
+ _context.next = 75;
4766
+ return ahApi.init(assetHubNode, DRY_RUN_CLIENT_TIMEOUT_MS);
4767
+ case 75:
4768
+ _context.next = 77;
4769
+ return getParaEthTransferFees(ahApi);
4770
+ case 77:
4771
+ _yield$getParaEthTran = _context.sent;
4772
+ _yield$getParaEthTran2 = _slicedToArray(_yield$getParaEthTran, 1);
4773
+ bridgeFee = _yield$getParaEthTran2[0];
4774
+ processedBridgeHubData = _objectSpread2(_objectSpread2({}, intermediateFees.bridgeHub), {}, {
4775
+ fee: intermediateFees.bridgeHub.fee + bridgeFee
4776
+ });
4777
+ case 81:
4778
+ intermediateFees.bridgeHub = processedBridgeHubData;
4715
4779
  return _context.abrupt("return", _objectSpread2(_objectSpread2({
4716
4780
  origin: _objectSpread2(_objectSpread2(_objectSpread2({}, originFee && {
4717
4781
  fee: originFee
@@ -4723,7 +4787,7 @@ var getXcmFee = /*#__PURE__*/function () {
4723
4787
  dryRunError: originDryRunError
4724
4788
  })
4725
4789
  }, intermediateFees), {}, {
4726
- destination: _objectSpread2(_objectSpread2(_objectSpread2({}, destinationFee && {
4790
+ destination: _objectSpread2(_objectSpread2(_objectSpread2({}, destinationFee !== undefined && {
4727
4791
  fee: destinationFee
4728
4792
  }), destinationFeeType && {
4729
4793
  feeType: destinationFeeType
@@ -4733,11 +4797,11 @@ var getXcmFee = /*#__PURE__*/function () {
4733
4797
  dryRunError: destinationDryRunError
4734
4798
  })
4735
4799
  }));
4736
- case 68:
4800
+ case 83:
4737
4801
  case "end":
4738
4802
  return _context.stop();
4739
4803
  }
4740
- }, _callee, null, [[16,, 24, 29], [40,, 61, 65]]);
4804
+ }, _callee, null, [[16,, 25, 30], [43,, 64, 68]]);
4741
4805
  }));
4742
4806
  return function getXcmFee(_x) {
4743
4807
  return _ref2.apply(this, arguments);
@@ -4748,11 +4812,11 @@ var BRIDGE_FEE_DOT = 682395810n; // 0.068239581 DOT
4748
4812
  var BRIDGE_FEE_KSM = 12016807000n; // 0.012016807 KSM
4749
4813
  var getXcmFeeEstimate = /*#__PURE__*/function () {
4750
4814
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
4751
- var api, origin, destination, address, senderAddress, currency, originFeeDetails, destApi, originAsset, currencyInput, flippedTx, rawDestFee, destinationFee, destFeeDetails;
4815
+ var api, origin, destination, currency, originFeeDetails, destApi, originAsset, currencyInput, destinationFee, destFeeDetails;
4752
4816
  return _regeneratorRuntime().wrap(function _callee$(_context) {
4753
4817
  while (1) switch (_context.prev = _context.next) {
4754
4818
  case 0:
4755
- api = options.api, origin = options.origin, destination = options.destination, address = options.address, senderAddress = options.senderAddress, currency = options.currency;
4819
+ api = options.api, origin = options.origin, destination = options.destination, currency = options.currency;
4756
4820
  if (!(origin === 'AssetHubPolkadot' && destination === 'AssetHubKusama')) {
4757
4821
  _context.next = 3;
4758
4822
  break;
@@ -4788,32 +4852,35 @@ var getXcmFeeEstimate = /*#__PURE__*/function () {
4788
4852
  case 7:
4789
4853
  originFeeDetails = _context.sent;
4790
4854
  destApi = api.clone();
4791
- _context.next = 11;
4792
- return destApi.init(destination, DRY_RUN_CLIENT_TIMEOUT_MS);
4793
- case 11:
4794
- if (!('multiasset' in currency)) {
4795
- _context.next = 13;
4855
+ if (!(destination !== 'Ethereum')) {
4856
+ _context.next = 12;
4796
4857
  break;
4797
4858
  }
4798
- throw new InvalidCurrencyError('Multi-assets are not yet supported for simple XCM fee estimation.');
4799
- case 13:
4859
+ _context.next = 12;
4860
+ return destApi.init(destination, DRY_RUN_CLIENT_TIMEOUT_MS);
4861
+ case 12:
4800
4862
  originAsset = findAssetForNodeOrThrow(origin, currency, destination);
4801
4863
  currencyInput = originAsset.multiLocation ? {
4802
4864
  multilocation: originAsset.multiLocation
4803
4865
  } : {
4804
4866
  symbol: originAsset.symbol
4805
4867
  };
4806
- _context.next = 17;
4807
- return Builder(destApi).from(destination).to(origin).address(senderAddress).senderAddress(address).currency(_objectSpread2(_objectSpread2({}, currencyInput), {}, {
4808
- amount: currency.amount
4809
- })).build();
4810
- case 17:
4811
- flippedTx = _context.sent;
4868
+ if (!(destination === 'Ethereum')) {
4869
+ _context.next = 18;
4870
+ break;
4871
+ }
4872
+ _context.t0 = 0n;
4873
+ _context.next = 21;
4874
+ break;
4875
+ case 18:
4812
4876
  _context.next = 20;
4813
- return destApi.calculateTransactionFee(flippedTx, address);
4877
+ return getReverseTxFee(_objectSpread2(_objectSpread2({}, options), {}, {
4878
+ destination: destination
4879
+ }), currencyInput);
4814
4880
  case 20:
4815
- rawDestFee = _context.sent;
4816
- destinationFee = padFee(rawDestFee, origin, destination, 'destination');
4881
+ _context.t0 = _context.sent;
4882
+ case 21:
4883
+ destinationFee = _context.t0;
4817
4884
  destFeeDetails = {
4818
4885
  fee: destinationFee,
4819
4886
  currency: getNativeAssetSymbol(destination)
@@ -4879,10 +4946,6 @@ var determineAssetCheckEnabled = function determineAssetCheckEnabled(origin, cur
4879
4946
  return 'multiasset' in currency || 'multilocation' in currency && isOverrideMultiLocationSpecifier(currency.multilocation) ? false : originNode.assetCheckEnabled;
4880
4947
  };
4881
4948
 
4882
- var isBridgeTransfer = function isBridgeTransfer(origin, destination) {
4883
- return origin === 'AssetHubPolkadot' && destination === 'AssetHubKusama' || origin === 'AssetHubKusama' && destination === 'AssetHubPolkadot';
4884
- };
4885
-
4886
4949
  var resolveAsset = function resolveAsset(currency, origin, destination, assetCheckEnabled) {
4887
4950
  return assetCheckEnabled ? findAsset(origin, currency, !isTMultiLocation(destination) ? destination : null) : null;
4888
4951
  };
@@ -5001,7 +5064,7 @@ var validateDestination = function validateDestination(origin, destination) {
5001
5064
  throw new IncompatibleNodesError("Transfers to Ethereum are only supported from: ".concat(allowedChainsToEthereum.join(', ')));
5002
5065
  }
5003
5066
  var isMultiLocationDestination = _typeof(destination) === 'object';
5004
- var isBridge = isBridgeTransfer(origin, destination);
5067
+ var isBridge = !isTMultiLocation(destination) && isDotKsmBridge(origin, destination);
5005
5068
  var isRelayDestination = !isTMultiLocation(destination) && isRelayChain(destination);
5006
5069
  if (!isRelayDestination && !isMultiLocationDestination) {
5007
5070
  var originRelayChainSymbol = getRelayChainSymbol(origin);
@@ -5022,7 +5085,7 @@ var validateAssetSpecifiers = function validateAssetSpecifiers(assetCheckEnabled
5022
5085
 
5023
5086
  var send = /*#__PURE__*/function () {
5024
5087
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
5025
- var api, origin, currency, feeAsset, address, destination, paraIdTo, version, senderAddress, ahAddress, pallet, method, isBridge, assetCheckEnabled, asset, resolvedFeeAsset, isLocalTransfer, overriddenAsset, resolvedAsset, originNode;
5088
+ var api, origin, currency, feeAsset, address, destination, paraIdTo, version, senderAddress, ahAddress, pallet, method, isBridge, assetCheckEnabled, asset, resolvedFeeAsset, isLocalTransfer, overriddenAsset, resolvedAsset, originNode, finalAsset;
5026
5089
  return _regeneratorRuntime().wrap(function _callee$(_context) {
5027
5090
  while (1) switch (_context.prev = _context.next) {
5028
5091
  case 0:
@@ -5031,7 +5094,7 @@ var send = /*#__PURE__*/function () {
5031
5094
  validateDestination(origin, destination);
5032
5095
  validateDestinationAddress(address, destination);
5033
5096
  if (senderAddress) validateAddress(senderAddress, origin, false);
5034
- isBridge = isBridgeTransfer(origin, destination);
5097
+ isBridge = !isTMultiLocation(destination) && isDotKsmBridge(origin, destination);
5035
5098
  assetCheckEnabled = determineAssetCheckEnabled(origin, currency);
5036
5099
  validateAssetSpecifiers(assetCheckEnabled, currency);
5037
5100
  asset = resolveAsset(currency, origin, destination, assetCheckEnabled);
@@ -5101,11 +5164,15 @@ var send = /*#__PURE__*/function () {
5101
5164
  symbol: 'symbol' in currency ? currency.symbol : undefined
5102
5165
  };
5103
5166
  originNode = getNode(origin);
5167
+ finalAsset = 'multiasset' in currency ? _objectSpread2(_objectSpread2({}, resolvedAsset), {}, {
5168
+ amount: 0,
5169
+ assetId: '1'
5170
+ }) : _objectSpread2(_objectSpread2({}, resolvedAsset), {}, {
5171
+ amount: currency.amount
5172
+ });
5104
5173
  return _context.abrupt("return", originNode.transfer({
5105
5174
  api: api,
5106
- asset: _objectSpread2(_objectSpread2({}, resolvedAsset), {}, {
5107
- amount: 'multiasset' in currency ? 0 : currency.amount
5108
- }),
5175
+ asset: finalAsset,
5109
5176
  feeAsset: resolvedFeeAsset,
5110
5177
  address: address,
5111
5178
  to: destination,
@@ -5117,7 +5184,7 @@ var send = /*#__PURE__*/function () {
5117
5184
  pallet: pallet,
5118
5185
  method: method
5119
5186
  }));
5120
- case 30:
5187
+ case 31:
5121
5188
  case "end":
5122
5189
  return _context.stop();
5123
5190
  }
@@ -8823,145 +8890,399 @@ var getTransferableAmountInternal = /*#__PURE__*/function () {
8823
8890
  currency: currency,
8824
8891
  disableFallback: false
8825
8892
  });
8826
- case 17:
8827
- _yield$getOriginXcmFe = _context.sent;
8828
- fee = _yield$getOriginXcmFe.fee;
8829
- if (!(fee === undefined)) {
8830
- _context.next = 21;
8831
- break;
8832
- }
8833
- throw new InvalidParameterError("Cannot get origin xcm fee for currency ".concat(JSON.stringify(currency), " on node ").concat(node, "."));
8834
- case 21:
8835
- feeToSubtract = fee;
8836
- case 22:
8837
- transferable = balance - edBN - feeToSubtract;
8838
- return _context.abrupt("return", transferable > 0n ? transferable : 0n);
8839
- case 24:
8893
+ case 17:
8894
+ _yield$getOriginXcmFe = _context.sent;
8895
+ fee = _yield$getOriginXcmFe.fee;
8896
+ if (!(fee === undefined)) {
8897
+ _context.next = 21;
8898
+ break;
8899
+ }
8900
+ throw new InvalidParameterError("Cannot get origin xcm fee for currency ".concat(JSON.stringify(currency), " on node ").concat(node, "."));
8901
+ case 21:
8902
+ feeToSubtract = fee;
8903
+ case 22:
8904
+ transferable = balance - edBN - feeToSubtract;
8905
+ return _context.abrupt("return", transferable > 0n ? transferable : 0n);
8906
+ case 24:
8907
+ case "end":
8908
+ return _context.stop();
8909
+ }
8910
+ }, _callee);
8911
+ }));
8912
+ return function getTransferableAmountInternal(_x) {
8913
+ return _ref2.apply(this, arguments);
8914
+ };
8915
+ }();
8916
+ var getTransferableAmount = /*#__PURE__*/function () {
8917
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
8918
+ var api;
8919
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
8920
+ while (1) switch (_context2.prev = _context2.next) {
8921
+ case 0:
8922
+ api = options.api;
8923
+ api.setDisconnectAllowed(false);
8924
+ _context2.prev = 2;
8925
+ _context2.next = 5;
8926
+ return getTransferableAmountInternal(options);
8927
+ case 5:
8928
+ return _context2.abrupt("return", _context2.sent);
8929
+ case 6:
8930
+ _context2.prev = 6;
8931
+ api.setDisconnectAllowed(true);
8932
+ _context2.next = 10;
8933
+ return api.disconnect();
8934
+ case 10:
8935
+ return _context2.finish(6);
8936
+ case 11:
8937
+ case "end":
8938
+ return _context2.stop();
8939
+ }
8940
+ }, _callee2, null, [[2,, 6, 11]]);
8941
+ }));
8942
+ return function getTransferableAmount(_x2) {
8943
+ return _ref3.apply(this, arguments);
8944
+ };
8945
+ }();
8946
+
8947
+ var ETH_RPC = 'https://ethereum.publicnode.com/';
8948
+ var ETH_ID = 1;
8949
+ var ERC20_ABI = ['function balanceOf(address) view returns (uint256)'];
8950
+ function getEthErc20Balance(_x, _x2) {
8951
+ return _getEthErc20Balance.apply(this, arguments);
8952
+ }
8953
+ function _getEthErc20Balance() {
8954
+ _getEthErc20Balance = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(currency, address) {
8955
+ var _rpc$id, rpc, id, asset, provider, tokenAddress, token;
8956
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
8957
+ while (1) switch (_context.prev = _context.next) {
8958
+ case 0:
8959
+ _rpc$id = {
8960
+ rpc: ETH_RPC,
8961
+ id: ETH_ID
8962
+ }, rpc = _rpc$id.rpc, id = _rpc$id.id;
8963
+ asset = findAssetForNodeOrThrow('Ethereum', currency, null);
8964
+ if (!(!isForeignAsset(asset) || !asset.assetId)) {
8965
+ _context.next = 4;
8966
+ break;
8967
+ }
8968
+ throw new InvalidParameterError("Asset ".concat(JSON.stringify(asset), " is not a foreign asset."));
8969
+ case 4:
8970
+ provider = new ethers.JsonRpcProvider(rpc, id);
8971
+ if (!(asset.symbol === 'ETH')) {
8972
+ _context.next = 9;
8973
+ break;
8974
+ }
8975
+ _context.next = 8;
8976
+ return provider.getBalance(address);
8977
+ case 8:
8978
+ return _context.abrupt("return", _context.sent);
8979
+ case 9:
8980
+ tokenAddress = asset.assetId;
8981
+ token = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
8982
+ _context.next = 13;
8983
+ return token.balanceOf(address);
8984
+ case 13:
8985
+ return _context.abrupt("return", _context.sent);
8986
+ case 14:
8987
+ case "end":
8988
+ return _context.stop();
8989
+ }
8990
+ }, _callee);
8991
+ }));
8992
+ return _getEthErc20Balance.apply(this, arguments);
8993
+ }
8994
+
8995
+ var buildDestInfo = /*#__PURE__*/function () {
8996
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
8997
+ var api, origin, destination, address, currency, originFee, destAsset, isFeeAssetAh, destFeeDetail, assetHubFee, bridgeFee, destApi, destCurrency, edDest, edDestBn, destBalance, destAmount, destBalanceSufficient, destBalanceSufficientResult, destBalanceAfter, destbalanceAfterResult, receivedAmount, isAssetHubToAssetHubRoute, nativeAssetOfOriginSymbol, isOriginAssetNative, destXcmFeeBalance, isDestFeeInNativeCurrency, destRecipientNativeBalance, destXcmFeeBalanceAfter;
8998
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
8999
+ while (1) switch (_context.prev = _context.next) {
9000
+ case 0:
9001
+ api = _ref.api, origin = _ref.origin, destination = _ref.destination, address = _ref.address, currency = _ref.currency, originFee = _ref.originFee, destAsset = _ref.destAsset, isFeeAssetAh = _ref.isFeeAssetAh, destFeeDetail = _ref.destFeeDetail, assetHubFee = _ref.assetHubFee, bridgeFee = _ref.bridgeFee;
9002
+ destApi = api.clone();
9003
+ if (!(destination !== 'Ethereum')) {
9004
+ _context.next = 5;
9005
+ break;
9006
+ }
9007
+ _context.next = 5;
9008
+ return destApi.init(destination);
9009
+ case 5:
9010
+ destCurrency = destAsset.multiLocation ? {
9011
+ multilocation: destAsset.multiLocation
9012
+ } : {
9013
+ symbol: destAsset.symbol
9014
+ };
9015
+ edDest = getExistentialDeposit(destination, destCurrency);
9016
+ if (edDest) {
9017
+ _context.next = 9;
9018
+ break;
9019
+ }
9020
+ throw new InvalidParameterError("Existential deposit not found for ".concat(destination, " with currency ").concat(JSON.stringify(currency)));
9021
+ case 9:
9022
+ edDestBn = BigInt(edDest);
9023
+ if (!(destination === 'Ethereum')) {
9024
+ _context.next = 16;
9025
+ break;
9026
+ }
9027
+ _context.next = 13;
9028
+ return getEthErc20Balance(destCurrency, address);
9029
+ case 13:
9030
+ _context.t0 = _context.sent;
9031
+ _context.next = 19;
9032
+ break;
9033
+ case 16:
9034
+ _context.next = 18;
9035
+ return getAssetBalanceInternal({
9036
+ api: destApi,
9037
+ address: address,
9038
+ node: destination,
9039
+ currency: destCurrency
9040
+ });
9041
+ case 18:
9042
+ _context.t0 = _context.sent;
9043
+ case 19:
9044
+ destBalance = _context.t0;
9045
+ destAmount = isFeeAssetAh ? BigInt(currency.amount) - originFee : BigInt(currency.amount);
9046
+ destBalanceSufficient = destAmount - destFeeDetail.fee > (destBalance < edDestBn ? edDestBn : 0);
9047
+ destBalanceSufficientResult = destFeeDetail.currency !== destAsset.symbol && destination !== 'Ethereum' ? new UnableToComputeError('Unable to compute if dest balance will be sufficient. Fee currency is not the same') : destBalanceSufficient;
9048
+ destBalanceAfter = destBalance - (destFeeDetail.currency === destAsset.symbol ? destFeeDetail.fee : 0n) + destAmount;
9049
+ destbalanceAfterResult = destFeeDetail.currency !== destAsset.symbol && destination !== 'Ethereum' ? new UnableToComputeError('Unable to compute if dest balance will be sufficient. Fee currency is not the same') : destBalanceAfter;
9050
+ isAssetHubToAssetHubRoute = origin === 'AssetHubKusama' && destination === 'AssetHubPolkadot' || origin === 'AssetHubPolkadot' && destination === 'AssetHubKusama';
9051
+ if (isAssetHubToAssetHubRoute) {
9052
+ nativeAssetOfOriginSymbol = getNativeAssetSymbol(origin);
9053
+ isOriginAssetNative = false;
9054
+ if (destAsset.symbol === nativeAssetOfOriginSymbol) {
9055
+ isOriginAssetNative = true;
9056
+ }
9057
+ if (isOriginAssetNative) {
9058
+ if (bridgeFee === undefined) {
9059
+ receivedAmount = new UnableToComputeError("bridgeFee is required for native asset transfer from ".concat(origin, " to ").concat(destination, " but was not provided."));
9060
+ } else {
9061
+ receivedAmount = BigInt(currency.amount) - originFee - bridgeFee;
9062
+ }
9063
+ } else {
9064
+ receivedAmount = new UnableToComputeError("Unable to compute received amount: The transferred asset (".concat(destAsset.symbol, ") is not the native asset (").concat(nativeAssetOfOriginSymbol, ") of origin ").concat(origin, " for the ").concat(origin, "->").concat(destination, " route."));
9065
+ }
9066
+ } else {
9067
+ if (destbalanceAfterResult instanceof UnableToComputeError) {
9068
+ receivedAmount = destbalanceAfterResult;
9069
+ } else {
9070
+ receivedAmount = destbalanceAfterResult - destBalance;
9071
+ }
9072
+ }
9073
+ if (destination === 'Ethereum' && assetHubFee && !(receivedAmount instanceof UnableToComputeError)) {
9074
+ receivedAmount -= assetHubFee;
9075
+ }
9076
+ isDestFeeInNativeCurrency = destFeeDetail.currency === getNativeAssetSymbol(destination);
9077
+ if (!isDestFeeInNativeCurrency) {
9078
+ _context.next = 43;
9079
+ break;
9080
+ }
9081
+ if (!(destination === 'Ethereum')) {
9082
+ _context.next = 36;
9083
+ break;
9084
+ }
9085
+ _context.next = 33;
9086
+ return getEthErc20Balance({
9087
+ symbol: getNativeAssetSymbol(destination)
9088
+ }, address);
9089
+ case 33:
9090
+ _context.t1 = _context.sent;
9091
+ _context.next = 39;
9092
+ break;
9093
+ case 36:
9094
+ _context.next = 38;
9095
+ return getBalanceNativeInternal({
9096
+ address: address,
9097
+ node: destination,
9098
+ api: destApi
9099
+ });
9100
+ case 38:
9101
+ _context.t1 = _context.sent;
9102
+ case 39:
9103
+ destRecipientNativeBalance = _context.t1;
9104
+ destXcmFeeBalance = destRecipientNativeBalance;
9105
+ _context.next = 44;
9106
+ break;
9107
+ case 43:
9108
+ destXcmFeeBalance = destBalance;
9109
+ case 44:
9110
+ destXcmFeeBalanceAfter = isFeeAssetAh ? destBalanceAfter : destXcmFeeBalance - destFeeDetail.fee + (destFeeDetail.currency === destAsset.symbol ? BigInt(currency.amount) : 0n);
9111
+ return _context.abrupt("return", {
9112
+ receivedCurrency: {
9113
+ sufficient: destBalanceSufficientResult,
9114
+ receivedAmount: receivedAmount,
9115
+ balance: destBalance,
9116
+ balanceAfter: destbalanceAfterResult,
9117
+ currencySymbol: destAsset.symbol,
9118
+ existentialDeposit: edDestBn
9119
+ },
9120
+ xcmFee: {
9121
+ fee: destFeeDetail.fee,
9122
+ balance: destXcmFeeBalance,
9123
+ balanceAfter: destXcmFeeBalanceAfter,
9124
+ currencySymbol: destFeeDetail.currency
9125
+ }
9126
+ });
9127
+ case 46:
8840
9128
  case "end":
8841
9129
  return _context.stop();
8842
9130
  }
8843
9131
  }, _callee);
8844
9132
  }));
8845
- return function getTransferableAmountInternal(_x) {
9133
+ return function buildDestInfo(_x) {
8846
9134
  return _ref2.apply(this, arguments);
8847
9135
  };
8848
9136
  }();
8849
- var getTransferableAmount = /*#__PURE__*/function () {
8850
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) {
8851
- var api;
8852
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
8853
- while (1) switch (_context2.prev = _context2.next) {
9137
+
9138
+ var buildHopInfo = /*#__PURE__*/function () {
9139
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
9140
+ var api, node, feeData, originNode, currency, senderAddress, ahAddress, hopApi, resolvedAddress, nativeBalanceOnHop, nativeAssetSymbolOnHop, xcmFeeDetails, isBridgeHubNode, hopAsset, hopCurrencyPayload, balance, ed;
9141
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
9142
+ while (1) switch (_context.prev = _context.next) {
8854
9143
  case 0:
8855
- api = options.api;
8856
- api.setDisconnectAllowed(false);
8857
- _context2.prev = 2;
8858
- _context2.next = 5;
8859
- return getTransferableAmountInternal(options);
8860
- case 5:
8861
- return _context2.abrupt("return", _context2.sent);
8862
- case 6:
8863
- _context2.prev = 6;
8864
- api.setDisconnectAllowed(true);
8865
- _context2.next = 10;
8866
- return api.disconnect();
8867
- case 10:
8868
- return _context2.finish(6);
8869
- case 11:
9144
+ api = _ref.api, node = _ref.node, feeData = _ref.feeData, originNode = _ref.originNode, currency = _ref.currency, senderAddress = _ref.senderAddress, ahAddress = _ref.ahAddress;
9145
+ hopApi = api.clone();
9146
+ _context.next = 4;
9147
+ return hopApi.init(node);
9148
+ case 4:
9149
+ hopApi.setDisconnectAllowed(false);
9150
+ _context.prev = 5;
9151
+ resolvedAddress = isNodeEvm(originNode) && ahAddress ? ahAddress : senderAddress;
9152
+ _context.next = 9;
9153
+ return getBalanceNativeInternal({
9154
+ api: hopApi,
9155
+ address: resolvedAddress,
9156
+ node: node
9157
+ });
9158
+ case 9:
9159
+ nativeBalanceOnHop = _context.sent;
9160
+ nativeAssetSymbolOnHop = getNativeAssetSymbol(node);
9161
+ xcmFeeDetails = {
9162
+ fee: feeData.fee,
9163
+ balance: nativeBalanceOnHop,
9164
+ currencySymbol: nativeAssetSymbolOnHop
9165
+ };
9166
+ isBridgeHubNode = node.includes('BridgeHub');
9167
+ if (!isBridgeHubNode) {
9168
+ _context.next = 17;
9169
+ break;
9170
+ }
9171
+ return _context.abrupt("return", {
9172
+ currencySymbol: getNativeAssetSymbol(node),
9173
+ xcmFee: xcmFeeDetails
9174
+ });
9175
+ case 17:
9176
+ hopAsset = findAssetOnDestOrThrow(originNode, node, currency);
9177
+ hopCurrencyPayload = hopAsset.multiLocation ? {
9178
+ multilocation: hopAsset.multiLocation
9179
+ } : {
9180
+ symbol: hopAsset.symbol
9181
+ };
9182
+ _context.next = 21;
9183
+ return getAssetBalanceInternal({
9184
+ api: hopApi,
9185
+ address: resolvedAddress,
9186
+ node: node,
9187
+ currency: hopCurrencyPayload
9188
+ });
9189
+ case 21:
9190
+ balance = _context.sent;
9191
+ ed = getExistentialDeposit(node, hopCurrencyPayload);
9192
+ if (ed) {
9193
+ _context.next = 25;
9194
+ break;
9195
+ }
9196
+ throw new InvalidParameterError("Existential deposit not found for node ".concat(node, " with currency ").concat(JSON.stringify(hopCurrencyPayload)));
9197
+ case 25:
9198
+ return _context.abrupt("return", {
9199
+ balance: balance,
9200
+ currencySymbol: hopAsset.symbol,
9201
+ existentialDeposit: BigInt(ed),
9202
+ xcmFee: xcmFeeDetails
9203
+ });
9204
+ case 26:
9205
+ _context.prev = 26;
9206
+ hopApi.setDisconnectAllowed(true);
9207
+ _context.next = 30;
9208
+ return hopApi.disconnect();
9209
+ case 30:
9210
+ return _context.finish(26);
9211
+ case 31:
8870
9212
  case "end":
8871
- return _context2.stop();
9213
+ return _context.stop();
8872
9214
  }
8873
- }, _callee2, null, [[2,, 6, 11]]);
9215
+ }, _callee, null, [[5,, 26, 31]]);
8874
9216
  }));
8875
- return function getTransferableAmount(_x2) {
8876
- return _ref3.apply(this, arguments);
9217
+ return function buildHopInfo(_x) {
9218
+ return _ref2.apply(this, arguments);
8877
9219
  };
8878
9220
  }();
8879
9221
 
8880
9222
  var getTransferInfo = /*#__PURE__*/function () {
8881
9223
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
8882
- var api, tx, origin, destination, senderAddress, address, currency, feeAsset, resolvedFeeAsset, destApi, destAsset, destCurrency, originBalanceFee, originBalance, destBalance, edOrigin, edOriginBn, edDest, edDestBn, _yield$getXcmFee, _yield$getXcmFee$orig, originFee, originFeeCurrency, _yield$getXcmFee$dest, destFee, destFeeCurrency, destXcmFeeBalance, isDestFeeInNativeCurrency, destRecipientNativeBalance, isFeeAssetAh, originBalanceAfter, originBalanceFeeAfter, originBalanceNativeSufficient, originBalanceSufficient, destAmount, destBalanceSufficient, destBalanceSufficientResult, destBalanceAfter, destbalanceAfterResult, receivedAmount, destXcmFeeBalanceAfter;
9224
+ var api, tx, origin, destination, senderAddress, ahAddress, address, currency, feeAsset, resolvedFeeAsset, destAsset, originBalanceFee, originBalance, edOrigin, edOriginBn, _yield$getXcmFee, _yield$getXcmFee$orig, originFee, originFeeCurrency, assetHubFeeResult, bridgeHubFeeResult, destFeeDetail, isFeeAssetAh, originBalanceAfter, originBalanceFeeAfter, originBalanceNativeSufficient, originBalanceSufficient, assetHub, bridgeHub, bridgeHubNode, destinationInfo;
8883
9225
  return _regeneratorRuntime().wrap(function _callee$(_context) {
8884
9226
  while (1) switch (_context.prev = _context.next) {
8885
9227
  case 0:
8886
- api = _ref.api, tx = _ref.tx, origin = _ref.origin, destination = _ref.destination, senderAddress = _ref.senderAddress, address = _ref.address, currency = _ref.currency, feeAsset = _ref.feeAsset;
9228
+ api = _ref.api, tx = _ref.tx, origin = _ref.origin, destination = _ref.destination, senderAddress = _ref.senderAddress, ahAddress = _ref.ahAddress, address = _ref.address, currency = _ref.currency, feeAsset = _ref.feeAsset;
9229
+ if (!(isNodeEvm(origin) && !ahAddress)) {
9230
+ _context.next = 3;
9231
+ break;
9232
+ }
9233
+ throw new InvalidParameterError("ahAddress is required for EVM origin ".concat(origin, "."));
9234
+ case 3:
8887
9235
  resolvedFeeAsset = feeAsset ? resolveFeeAsset(feeAsset, origin, destination, currency) : undefined;
8888
- _context.next = 4;
9236
+ _context.next = 6;
8889
9237
  return api.init(origin);
8890
- case 4:
9238
+ case 6:
8891
9239
  api.setDisconnectAllowed(false);
8892
- destApi = api.clone();
8893
- _context.next = 8;
8894
- return destApi.init(destination);
8895
- case 8:
8896
- destApi.setDisconnectAllowed(false);
8897
- _context.prev = 9;
9240
+ _context.prev = 7;
8898
9241
  destAsset = findAssetOnDestOrThrow(origin, destination, currency);
8899
- destCurrency = destAsset.multiLocation ? {
8900
- multilocation: destAsset.multiLocation
8901
- } : {
8902
- symbol: destAsset.symbol
8903
- };
8904
9242
  if (!(feeAsset && resolvedFeeAsset)) {
8905
- _context.next = 18;
9243
+ _context.next = 15;
8906
9244
  break;
8907
9245
  }
8908
- _context.next = 15;
9246
+ _context.next = 12;
8909
9247
  return getAssetBalanceInternal({
8910
9248
  api: api,
8911
9249
  address: senderAddress,
8912
9250
  node: origin,
8913
9251
  currency: feeAsset
8914
9252
  });
8915
- case 15:
9253
+ case 12:
8916
9254
  _context.t0 = _context.sent;
8917
- _context.next = 21;
9255
+ _context.next = 18;
8918
9256
  break;
8919
- case 18:
8920
- _context.next = 20;
9257
+ case 15:
9258
+ _context.next = 17;
8921
9259
  return getBalanceNativeInternal({
8922
9260
  api: api,
8923
9261
  address: senderAddress,
8924
9262
  node: origin
8925
9263
  });
8926
- case 20:
9264
+ case 17:
8927
9265
  _context.t0 = _context.sent;
8928
- case 21:
9266
+ case 18:
8929
9267
  originBalanceFee = _context.t0;
8930
- _context.next = 24;
9268
+ _context.next = 21;
8931
9269
  return getAssetBalanceInternal({
8932
9270
  api: api,
8933
9271
  address: senderAddress,
8934
9272
  node: origin,
8935
9273
  currency: currency
8936
9274
  });
8937
- case 24:
9275
+ case 21:
8938
9276
  originBalance = _context.sent;
8939
- _context.next = 27;
8940
- return getAssetBalanceInternal({
8941
- api: destApi,
8942
- address: address,
8943
- node: destination,
8944
- currency: destCurrency
8945
- });
8946
- case 27:
8947
- destBalance = _context.sent;
8948
9277
  edOrigin = getExistentialDeposit(origin, currency);
8949
9278
  if (edOrigin) {
8950
- _context.next = 31;
9279
+ _context.next = 25;
8951
9280
  break;
8952
9281
  }
8953
9282
  throw new InvalidParameterError("Existential deposit not found for ".concat(origin, " with currency ").concat(JSON.stringify(currency)));
8954
- case 31:
9283
+ case 25:
8955
9284
  edOriginBn = BigInt(edOrigin);
8956
- edDest = getExistentialDeposit(destination, destCurrency);
8957
- if (edDest) {
8958
- _context.next = 35;
8959
- break;
8960
- }
8961
- throw new InvalidParameterError("Existential deposit not found for ".concat(destination, " with currency ").concat(JSON.stringify(currency)));
8962
- case 35:
8963
- edDestBn = BigInt(edDest);
8964
- _context.next = 38;
9285
+ _context.next = 28;
8965
9286
  return getXcmFee({
8966
9287
  api: api,
8967
9288
  tx: tx,
@@ -8973,51 +9294,76 @@ var getTransferInfo = /*#__PURE__*/function () {
8973
9294
  feeAsset: feeAsset,
8974
9295
  disableFallback: false
8975
9296
  });
8976
- case 38:
9297
+ case 28:
8977
9298
  _yield$getXcmFee = _context.sent;
8978
9299
  _yield$getXcmFee$orig = _yield$getXcmFee.origin;
8979
9300
  originFee = _yield$getXcmFee$orig.fee;
8980
9301
  originFeeCurrency = _yield$getXcmFee$orig.currency;
8981
- _yield$getXcmFee$dest = _yield$getXcmFee.destination;
8982
- destFee = _yield$getXcmFee$dest.fee;
8983
- destFeeCurrency = _yield$getXcmFee$dest.currency;
9302
+ assetHubFeeResult = _yield$getXcmFee.assetHub;
9303
+ bridgeHubFeeResult = _yield$getXcmFee.bridgeHub;
9304
+ destFeeDetail = _yield$getXcmFee.destination;
8984
9305
  if (!(originFee === undefined)) {
8985
- _context.next = 47;
9306
+ _context.next = 37;
8986
9307
  break;
8987
9308
  }
8988
9309
  throw new InvalidParameterError("Cannot get origin xcm fee for currency ".concat(JSON.stringify(currency), " on node ").concat(origin, "."));
8989
- case 47:
8990
- isDestFeeInNativeCurrency = destFeeCurrency === getNativeAssetSymbol(destination);
8991
- if (!isDestFeeInNativeCurrency) {
8992
- _context.next = 55;
8993
- break;
8994
- }
8995
- _context.next = 51;
8996
- return getBalanceNativeInternal({
8997
- address: address,
8998
- node: destination,
8999
- api: destApi
9000
- });
9001
- case 51:
9002
- destRecipientNativeBalance = _context.sent;
9003
- destXcmFeeBalance = destRecipientNativeBalance;
9004
- _context.next = 56;
9005
- break;
9006
- case 55:
9007
- destXcmFeeBalance = destBalance;
9008
- case 56:
9310
+ case 37:
9009
9311
  isFeeAssetAh = origin === 'AssetHubPolkadot' && resolvedFeeAsset && isAssetEqual(resolvedFeeAsset, destAsset);
9010
9312
  originBalanceAfter = originBalance - BigInt(currency.amount);
9011
9313
  originBalanceFeeAfter = isFeeAssetAh ? originBalanceFee - BigInt(currency.amount) : originBalanceFee - originFee;
9012
9314
  originBalanceNativeSufficient = originBalanceFee >= originFee;
9013
9315
  originBalanceSufficient = originBalanceAfter >= edOriginBn;
9014
- destAmount = isFeeAssetAh ? BigInt(currency.amount) - originFee : BigInt(currency.amount);
9015
- destBalanceSufficient = destAmount - destFee > (destBalance < edDestBn ? edDestBn : 0);
9016
- destBalanceSufficientResult = destFeeCurrency !== destAsset.symbol ? new UnableToComputeError('Unable to compute if dest balance will be sufficient. Fee currency is not the same') : destBalanceSufficient;
9017
- destBalanceAfter = destBalance - (destFeeCurrency === destAsset.symbol ? destFee : 0n) + destAmount;
9018
- destbalanceAfterResult = destFeeCurrency !== destAsset.symbol ? new UnableToComputeError('Unable to compute if dest balance will be sufficient. Fee currency is not the same') : destBalanceAfter;
9019
- receivedAmount = destbalanceAfterResult instanceof UnableToComputeError ? destbalanceAfterResult : destbalanceAfterResult - destBalance;
9020
- destXcmFeeBalanceAfter = isFeeAssetAh ? destBalanceAfter : destXcmFeeBalance - destFee + (destFeeCurrency === destAsset.symbol ? BigInt(currency.amount) : 0n);
9316
+ if (!assetHubFeeResult) {
9317
+ _context.next = 46;
9318
+ break;
9319
+ }
9320
+ _context.next = 45;
9321
+ return buildHopInfo({
9322
+ api: api,
9323
+ node: determineRelayChain(origin) === 'Polkadot' ? 'AssetHubPolkadot' : 'AssetHubKusama',
9324
+ feeData: assetHubFeeResult,
9325
+ originNode: origin,
9326
+ currency: currency,
9327
+ senderAddress: senderAddress,
9328
+ ahAddress: ahAddress
9329
+ });
9330
+ case 45:
9331
+ assetHub = _context.sent;
9332
+ case 46:
9333
+ if (!bridgeHubFeeResult) {
9334
+ _context.next = 51;
9335
+ break;
9336
+ }
9337
+ bridgeHubNode = determineRelayChain(origin) === 'Polkadot' ? 'BridgeHubPolkadot' : 'BridgeHubKusama';
9338
+ _context.next = 50;
9339
+ return buildHopInfo({
9340
+ api: api,
9341
+ node: bridgeHubNode,
9342
+ feeData: bridgeHubFeeResult,
9343
+ originNode: origin,
9344
+ currency: currency,
9345
+ senderAddress: senderAddress,
9346
+ ahAddress: ahAddress
9347
+ });
9348
+ case 50:
9349
+ bridgeHub = _context.sent;
9350
+ case 51:
9351
+ _context.next = 53;
9352
+ return buildDestInfo({
9353
+ api: api,
9354
+ origin: origin,
9355
+ destination: destination,
9356
+ address: address,
9357
+ currency: currency,
9358
+ destAsset: destAsset,
9359
+ originFee: originFee,
9360
+ isFeeAssetAh: !!isFeeAssetAh,
9361
+ destFeeDetail: destFeeDetail,
9362
+ assetHubFee: assetHubFeeResult === null || assetHubFeeResult === void 0 ? void 0 : assetHubFeeResult.fee,
9363
+ bridgeFee: bridgeHubFeeResult === null || bridgeHubFeeResult === void 0 ? void 0 : bridgeHubFeeResult.fee
9364
+ });
9365
+ case 53:
9366
+ destinationInfo = _context.sent;
9021
9367
  return _context.abrupt("return", {
9022
9368
  chain: {
9023
9369
  origin: origin,
@@ -9040,57 +9386,69 @@ var getTransferInfo = /*#__PURE__*/function () {
9040
9386
  currencySymbol: originFeeCurrency
9041
9387
  }
9042
9388
  },
9043
- destination: {
9044
- receivedCurrency: {
9045
- sufficient: destBalanceSufficientResult,
9046
- receivedAmount: receivedAmount,
9047
- balance: destBalance,
9048
- balanceAfter: destbalanceAfterResult,
9049
- currencySymbol: destAsset.symbol,
9050
- existentialDeposit: edDestBn
9051
- },
9052
- xcmFee: {
9053
- fee: destFee,
9054
- balance: destXcmFeeBalance,
9055
- balanceAfter: destXcmFeeBalanceAfter,
9056
- currencySymbol: destFeeCurrency
9057
- }
9058
- }
9389
+ assetHub: assetHub,
9390
+ bridgeHub: bridgeHub,
9391
+ destination: destinationInfo
9059
9392
  });
9060
- case 69:
9061
- _context.prev = 69;
9393
+ case 55:
9394
+ _context.prev = 55;
9062
9395
  api.setDisconnectAllowed(true);
9063
- destApi.setDisconnectAllowed(true);
9064
- _context.next = 74;
9396
+ _context.next = 59;
9065
9397
  return api.disconnect();
9066
- case 74:
9067
- _context.next = 76;
9068
- return destApi.disconnect();
9069
- case 76:
9070
- return _context.finish(69);
9071
- case 77:
9398
+ case 59:
9399
+ return _context.finish(55);
9400
+ case 60:
9072
9401
  case "end":
9073
9402
  return _context.stop();
9074
9403
  }
9075
- }, _callee, null, [[9,, 69, 77]]);
9404
+ }, _callee, null, [[7,, 55, 60]]);
9076
9405
  }));
9077
9406
  return function getTransferInfo(_x) {
9078
9407
  return _ref2.apply(this, arguments);
9079
9408
  };
9080
9409
  }();
9081
9410
 
9411
+ var calculateTotalXcmFee = function calculateTotalXcmFee(feeResult) {
9412
+ var _feeResult$assetHub;
9413
+ var totalFee = 0n;
9414
+ if (((_feeResult$assetHub = feeResult.assetHub) === null || _feeResult$assetHub === void 0 ? void 0 : _feeResult$assetHub.fee) !== undefined) {
9415
+ totalFee += feeResult.assetHub.fee;
9416
+ }
9417
+ if (feeResult.destination.fee !== undefined) {
9418
+ totalFee += feeResult.destination.fee;
9419
+ }
9420
+ return totalFee;
9421
+ };
9082
9422
  var verifyEdOnDestinationInternal = /*#__PURE__*/function () {
9083
9423
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
9084
- var api, tx, origin, destination, address, senderAddress, feeAsset, currency, destApi, asset, destCurrency, ed, edBN, balance, _yield$getXcmFee, dryRunError, _yield$getXcmFee$dest, destFee, destFeeCurrency, destDryRunError;
9424
+ var api, tx, origin, destination, address, senderAddress, feeAsset, currency, destApi, asset, destCurrency, ed, edBN, balance, xcmFeeResult, dryRunError, _xcmFeeResult$destina, destFee, destFeeCurrency, destDryRunError, totalFee, method, feeToSubtract;
9085
9425
  return _regeneratorRuntime().wrap(function _callee$(_context) {
9086
9426
  while (1) switch (_context.prev = _context.next) {
9087
9427
  case 0:
9088
9428
  api = _ref.api, tx = _ref.tx, origin = _ref.origin, destination = _ref.destination, address = _ref.address, senderAddress = _ref.senderAddress, feeAsset = _ref.feeAsset, currency = _ref.currency;
9429
+ if (!(destination === 'Ethereum')) {
9430
+ _context.next = 3;
9431
+ break;
9432
+ }
9433
+ return _context.abrupt("return", true);
9434
+ case 3:
9089
9435
  validateAddress(address, destination);
9436
+ if (!(origin === 'AssetHubPolkadot' && destination === 'AssetHubKusama')) {
9437
+ _context.next = 6;
9438
+ break;
9439
+ }
9440
+ throw new InvalidParameterError('Kusama is outside of Polkadot ecosystem, thus function is unable to verify the existential deposit for it.');
9441
+ case 6:
9442
+ if (!(origin === 'AssetHubKusama' && destination === 'AssetHubPolkadot')) {
9443
+ _context.next = 8;
9444
+ break;
9445
+ }
9446
+ throw new InvalidParameterError('Polkadot is outside of Kusama ecosystem, thus function is unable to verify the existential deposit for it.');
9447
+ case 8:
9090
9448
  destApi = api.clone();
9091
- _context.next = 5;
9449
+ _context.next = 11;
9092
9450
  return destApi.init(destination);
9093
- case 5:
9451
+ case 11:
9094
9452
  asset = findAssetOnDestOrThrow(origin, destination, currency);
9095
9453
  destCurrency = asset.multiLocation ? {
9096
9454
  multilocation: asset.multiLocation
@@ -9099,22 +9457,22 @@ var verifyEdOnDestinationInternal = /*#__PURE__*/function () {
9099
9457
  };
9100
9458
  ed = getExistentialDeposit(destination, destCurrency);
9101
9459
  if (!(ed === null)) {
9102
- _context.next = 10;
9460
+ _context.next = 16;
9103
9461
  break;
9104
9462
  }
9105
9463
  throw new InvalidParameterError("Cannot get existential deposit for currency ".concat(JSON.stringify(currency)));
9106
- case 10:
9464
+ case 16:
9107
9465
  edBN = BigInt(ed);
9108
- _context.next = 13;
9466
+ _context.next = 19;
9109
9467
  return getAssetBalanceInternal({
9110
9468
  address: address,
9111
9469
  node: destination,
9112
9470
  api: destApi,
9113
9471
  currency: destCurrency
9114
9472
  });
9115
- case 13:
9473
+ case 19:
9116
9474
  balance = _context.sent;
9117
- _context.next = 16;
9475
+ _context.next = 22;
9118
9476
  return getXcmFee({
9119
9477
  api: api,
9120
9478
  tx: tx,
@@ -9126,39 +9484,42 @@ var verifyEdOnDestinationInternal = /*#__PURE__*/function () {
9126
9484
  feeAsset: feeAsset,
9127
9485
  disableFallback: false
9128
9486
  });
9129
- case 16:
9130
- _yield$getXcmFee = _context.sent;
9131
- dryRunError = _yield$getXcmFee.origin.dryRunError;
9132
- _yield$getXcmFee$dest = _yield$getXcmFee.destination;
9133
- destFee = _yield$getXcmFee$dest.fee;
9134
- destFeeCurrency = _yield$getXcmFee$dest.currency;
9135
- destDryRunError = _yield$getXcmFee$dest.dryRunError;
9487
+ case 22:
9488
+ xcmFeeResult = _context.sent;
9489
+ dryRunError = xcmFeeResult.origin.dryRunError, _xcmFeeResult$destina = xcmFeeResult.destination, destFee = _xcmFeeResult$destina.fee, destFeeCurrency = _xcmFeeResult$destina.currency, destDryRunError = _xcmFeeResult$destina.dryRunError;
9136
9490
  if (!(destFee === undefined)) {
9137
- _context.next = 24;
9491
+ _context.next = 26;
9138
9492
  break;
9139
9493
  }
9140
9494
  throw new InvalidParameterError("Cannot get destination xcm fee for currency ".concat(JSON.stringify(currency), " on node ").concat(destination, "."));
9141
- case 24:
9495
+ case 26:
9142
9496
  if (!dryRunError) {
9143
- _context.next = 26;
9497
+ _context.next = 28;
9144
9498
  break;
9145
9499
  }
9146
9500
  throw new DryRunFailedError(dryRunError, 'origin');
9147
- case 26:
9501
+ case 28:
9148
9502
  if (!destDryRunError) {
9149
- _context.next = 28;
9503
+ _context.next = 30;
9150
9504
  break;
9151
9505
  }
9152
9506
  throw new UnableToComputeError("Unable to compute fee for the destination asset. Destination dry run error: ".concat(destDryRunError));
9153
- case 28:
9507
+ case 30:
9154
9508
  if (!(normalizeSymbol(asset.symbol) !== normalizeSymbol(destFeeCurrency))) {
9155
- _context.next = 30;
9509
+ _context.next = 32;
9156
9510
  break;
9157
9511
  }
9158
9512
  throw new UnableToComputeError("The XCM fee could not be calculated because the origin or destination chain does not support DryRun.\n As a result, fee estimation is only available through PaymentInfo, which provides the cost in the native asset.\n This limitation restricts support to transfers involving the native asset of the Destination chain only.");
9159
- case 30:
9160
- return _context.abrupt("return", BigInt(currency.amount) - destFee > (balance < edBN ? edBN : 0));
9161
- case 31:
9513
+ case 32:
9514
+ totalFee = calculateTotalXcmFee(xcmFeeResult);
9515
+ method = api.getMethod(tx);
9516
+ if (method === 'transfer_assets_using_type_and_then' || method === 'transferAssetsUsingTypeAndThen') {
9517
+ feeToSubtract = totalFee;
9518
+ } else {
9519
+ feeToSubtract = destFee;
9520
+ }
9521
+ return _context.abrupt("return", BigInt(currency.amount) - feeToSubtract > (balance < edBN ? edBN : 0));
9522
+ case 36:
9162
9523
  case "end":
9163
9524
  return _context.stop();
9164
9525
  }
@@ -9198,13 +9559,10 @@ var verifyEdOnDestination = /*#__PURE__*/function () {
9198
9559
  };
9199
9560
  }();
9200
9561
 
9201
- var assertToIsStringAndNoEthereum = function assertToIsStringAndNoEthereum(to) {
9562
+ var assertToIsString = function assertToIsString(to) {
9202
9563
  if (isTMultiLocation(to)) {
9203
9564
  throw new InvalidParameterError('Multi-Location destination is not supported for XCM fee calculation.');
9204
9565
  }
9205
- if (to === 'Ethereum') {
9206
- throw new InvalidParameterError('Ethereum destination is not yet supported for XCM fee calculation.');
9207
- }
9208
9566
  };
9209
9567
  var assertAddressIsString = function assertAddressIsString(address) {
9210
9568
  if (isTMultiLocation(address)) {
@@ -9536,12 +9894,6 @@ var GeneralBuilder = /*#__PURE__*/function () {
9536
9894
  }
9537
9895
  throw new InvalidParameterError('Multi-Location address is not supported for XCM fee calculation.');
9538
9896
  case 8:
9539
- if (!(to === 'Ethereum')) {
9540
- _context3.next = 10;
9541
- break;
9542
- }
9543
- throw new InvalidParameterError('Ethereum destination is not yet supported for XCM fee calculation.');
9544
- case 10:
9545
9897
  return _context3.abrupt("return", dryRun({
9546
9898
  api: this.api,
9547
9899
  tx: tx,
@@ -9552,7 +9904,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9552
9904
  senderAddress: this._options.senderAddress,
9553
9905
  feeAsset: feeAsset
9554
9906
  }));
9555
- case 11:
9907
+ case 9:
9556
9908
  case "end":
9557
9909
  return _context3.stop();
9558
9910
  }
@@ -9589,7 +9941,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9589
9941
  disableFallback: false
9590
9942
  }, disableFallback = _ref.disableFallback;
9591
9943
  _this$_options3 = this._options, from = _this$_options3.from, to = _this$_options3.to, address = _this$_options3.address, senderAddress = _this$_options3.senderAddress, feeAsset = _this$_options3.feeAsset;
9592
- assertToIsStringAndNoEthereum(to);
9944
+ assertToIsString(to);
9593
9945
  assertAddressIsString(address);
9594
9946
  _context4.next = 6;
9595
9947
  return this.build();
@@ -9654,7 +10006,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9654
10006
  disableFallback: false
9655
10007
  }, disableFallback = _ref2.disableFallback;
9656
10008
  _this$_options4 = this._options, from = _this$_options4.from, to = _this$_options4.to, senderAddress = _this$_options4.senderAddress, currency = _this$_options4.currency, feeAsset = _this$_options4.feeAsset;
9657
- assertToIsStringAndNoEthereum(to);
10009
+ assertToIsString(to);
9658
10010
  _context5.next = 5;
9659
10011
  return this.build();
9660
10012
  case 5:
@@ -9705,7 +10057,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9705
10057
  while (1) switch (_context6.prev = _context6.next) {
9706
10058
  case 0:
9707
10059
  _this$_options5 = this._options, from = _this$_options5.from, to = _this$_options5.to, address = _this$_options5.address, senderAddress = _this$_options5.senderAddress;
9708
- assertToIsStringAndNoEthereum(to);
10060
+ assertToIsString(to);
9709
10061
  assertAddressIsString(address);
9710
10062
  _context6.next = 5;
9711
10063
  return this.build();
@@ -9756,7 +10108,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9756
10108
  while (1) switch (_context7.prev = _context7.next) {
9757
10109
  case 0:
9758
10110
  _this$_options6 = this._options, from = _this$_options6.from, to = _this$_options6.to, senderAddress = _this$_options6.senderAddress;
9759
- assertToIsStringAndNoEthereum(to);
10111
+ assertToIsString(to);
9760
10112
  _context7.next = 4;
9761
10113
  return this.build();
9762
10114
  case 4:
@@ -9804,7 +10156,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9804
10156
  while (1) switch (_context8.prev = _context8.next) {
9805
10157
  case 0:
9806
10158
  _this$_options7 = this._options, from = _this$_options7.from, to = _this$_options7.to, senderAddress = _this$_options7.senderAddress, currency = _this$_options7.currency, feeAsset = _this$_options7.feeAsset;
9807
- assertToIsStringAndNoEthereum(to);
10159
+ assertToIsString(to);
9808
10160
  _context8.next = 4;
9809
10161
  return this.build();
9810
10162
  case 4:
@@ -9847,7 +10199,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9847
10199
  while (1) switch (_context9.prev = _context9.next) {
9848
10200
  case 0:
9849
10201
  _this$_options8 = this._options, from = _this$_options8.from, to = _this$_options8.to, address = _this$_options8.address, currency = _this$_options8.currency, senderAddress = _this$_options8.senderAddress, feeAsset = _this$_options8.feeAsset;
9850
- assertToIsStringAndNoEthereum(to);
10202
+ assertToIsString(to);
9851
10203
  assertAddressIsString(address);
9852
10204
  _context9.next = 5;
9853
10205
  return this.build();
@@ -9889,7 +10241,7 @@ var GeneralBuilder = /*#__PURE__*/function () {
9889
10241
  while (1) switch (_context0.prev = _context0.next) {
9890
10242
  case 0:
9891
10243
  _this$_options9 = this._options, from = _this$_options9.from, to = _this$_options9.to, address = _this$_options9.address, currency = _this$_options9.currency, senderAddress = _this$_options9.senderAddress, feeAsset = _this$_options9.feeAsset;
9892
- assertToIsStringAndNoEthereum(to);
10244
+ assertToIsString(to);
9893
10245
  assertAddressIsString(address);
9894
10246
  _context0.next = 5;
9895
10247
  return this.build();