@paraspell/sdk-core 12.7.0 → 12.8.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.d.ts CHANGED
@@ -810,7 +810,10 @@ type TCreateBaseTransferXcmOptions<TRes> = {
810
810
  feeAssetInfo?: TAssetInfo;
811
811
  fees: TTransferFeeEstimates;
812
812
  recipientAddress: string;
813
+ senderAddress?: string;
813
814
  version: Version;
815
+ useJitWithdraw?: boolean;
816
+ useFeeAssetOnHops?: boolean;
814
817
  paraIdTo?: number;
815
818
  transactOptions?: TTransactOptions<TRes>;
816
819
  };
@@ -822,12 +825,14 @@ type TCreateBaseSwapXcmOptions = {
822
825
  assetInfoFrom: WithAmount<TAssetInfo>;
823
826
  assetInfoTo: WithAmount<TAssetInfo>;
824
827
  currencyTo: TCurrencyInput;
828
+ feeAssetInfo?: TAssetInfo;
825
829
  senderAddress: string;
826
830
  recipientAddress: string;
827
831
  calculateMinAmountOut: (amountIn: bigint, assetTo?: TAssetInfo) => Promise<bigint>;
828
832
  };
829
833
  type TCreateSwapXcmOptions<TApi, TRes, TSigner> = WithApi<TCreateBaseSwapXcmOptions, TApi, TRes, TSigner>;
830
834
  type TSwapFeeEstimates = {
835
+ originFee: bigint;
831
836
  originReserveFee: bigint;
832
837
  exchangeFee: bigint;
833
838
  destReserveFee: bigint;
@@ -837,6 +842,14 @@ type TCreateSwapXcmInternalOptions<TApi, TRes, TSigner> = WithApi<TCreateBaseSwa
837
842
  fees: TSwapFeeEstimates;
838
843
  paraIdTo?: number;
839
844
  };
845
+ type TCreateEthBridgeInstructionsOptions<TApi, TRes, TSigner> = {
846
+ api: IPolkadotApi<TApi, TRes, TSigner>;
847
+ address: TAddress;
848
+ assetInfo: TAssetInfo;
849
+ senderAddress: string;
850
+ ahAddress?: string;
851
+ version: Version;
852
+ };
840
853
 
841
854
  type TAssetClaimOptionsBase = {
842
855
  chain: TSubstrateChain;
@@ -2139,7 +2152,7 @@ declare const wrapTxBypass: <TApi, TRes, TSigner>(dryRunOptions: TDryRunBypassOp
2139
2152
 
2140
2153
  declare const getParaEthTransferFees: <TApi, TRes, TSigner>(ahApi: IPolkadotApi<TApi, TRes, TSigner>, shouldDisconnect?: boolean) => Promise<[bigint, bigint]>;
2141
2154
 
2142
- declare const transferMoonbeamEvm: <TApi, TRes, TSigner>({ api, from, to, signer, address, currency }: TEvmBuilderOptions<TApi, TRes, TSigner>) => Promise<string>;
2155
+ declare const transferMoonbeamEvm: <TApi, TRes, TSigner>(options: TEvmBuilderOptions<TApi, TRes, TSigner>) => Promise<string>;
2143
2156
 
2144
2157
  declare const transferMoonbeamToEth: <TApi, TRes, TSigner>(from: TSubstrateChain, { api, to, signer, address, ahAddress, currency }: TEvmBuilderOptions<TApi, TRes, TSigner>) => Promise<`0x${string}`>;
2145
2158
 
@@ -2363,4 +2376,4 @@ declare const pickCompatibleXcmVersion: (origin: TSubstrateChain, destination: T
2363
2376
  declare const pickRouterCompatibleXcmVersion: (origin: TSubstrateChain | undefined, exchangeChain: TSubstrateChain, destination: TChain | undefined) => Version;
2364
2377
 
2365
2378
  export { AmountTooLowError, AssetClaimBuilder, BaseAssetsPallet, BatchMode, BatchValidationError, BridgeHaltedError, Builder, DRY_RUN_CLIENT_TIMEOUT_MS, DryRunFailedError, ETH_MAINNET_CHAIN_ID, ETH_TESTNET_CHAIN_ID, FeatureTemporarilyDisabledError, GeneralBuilder, InvalidAddressError, MissingChainApiError, MissingParameterError, NoXCMSupportImplementedError, NumberFormatError, OverrideConflictError, PolkadotXcmError, PolkadotXcmExecutionError, ProviderUnavailableError, RELAY_LOCATION, RoutingResolutionError, RuntimeApiUnavailableError, ScenarioNotSupportedError, TRANSACT_ORIGINS, TX_CLIENT_TIMEOUT_MS, TransferToAhNotSupported, TypeAndThenUnavailableError, UnableToComputeError, UnsupportedOperationError, ValidationError, XTokensError, abstractDecimals, addEthereumBridgeFees, addXcmVersionHeader, applyDecimalAbstraction, assertAddressIsString, assertHasId, assertSender, assertSenderAddress, assertToIsString, blake2b256, blake2b512, calcPreviewMintAmount, claimAssets, compareAddresses, computeFeeFromDryRun, computeFeeFromDryRunPjs, computeOverridenAmount, constructTypeAndThenCall, convertSs58, createAsset, createAssetsFilter, createBaseExecuteXcm, createBeneficiaryLocXTokens, createBeneficiaryLocation, createChainClient, createClientCache, createClientPoolHelpers, createDestination, createDirectExecuteXcm, createExecuteCall, createExecuteExchangeXcm, createId, createTx, createTypeAndThenCall, createTypeThenAutoReserve, createVersionedAssets, createVersionedDestination, createX1Payload, deriveAccountId, dryRun, dryRunInternal, dryRunOrigin, encodeSs58, formatAssetIdToERC20, formatUnits, getAssetBalanceInternal, getAssetReserveChain, getBalance, getBalanceInternal, getBridgeStatus, getChain, getChainConfig, getChainLocation, getChainProviders, getChainVersion, getEthErc20Balance, getEvmPrivateKeyHex, getFailureInfo, getLocalTransferAmount, getMinTransferableAmount, getMinTransferableAmountInternal, getMoonbeamErc20Balance, getOriginXcmFee, getOriginXcmFeeEstimate, getOriginXcmFeeInternal, getParaEthTransferFees, getParaId, getRelayChainOf, getTChain, getTransferInfo, getTransferableAmount, getTransferableAmountInternal, getXcmFee, getXcmFeeEstimate, getXcmFeeInternal, getXcmFeeOnce, handleExecuteTransfer, handleSwapExecuteTransfer, handleToAhTeleport, isConfig, isSenderSigner, keyFromWs, localizeLocation, maybeOverrideAsset, maybeOverrideAssets, normalizeAmount, overrideTxAmount, padFee, padValueBy, parseUnits, pickCompatibleXcmVersion, pickRouterCompatibleXcmVersion, resolveDestChain, resolveModuleError, resolveParaId, resolveSendParams, reverseTransformLocation, selectXcmVersion, send, sortAssets, throwUnsupportedCurrency, transferMoonbeamEvm, transferMoonbeamToEth, traverseXcmHops, validateAddress, validateAssetSpecifiers, validateCurrency, validateDestination, validateDestinationAddress, validateTransact, verifyEdOnDestination, wrapTxBypass };
2366
- export type { BuildHopInfoOptions, ClientCache, HopProcessParams, HopTraversalConfig, HopTraversalResult, IPolkadotApi, IPolkadotXCMTransfer, IXTokensTransfer, OneKey, TAddress, TApiOrUrl, TAssetClaimInternalOptions, TAssetClaimOptions, TAssetClaimOptionsBase, TBatchOptions, TBatchedSendOptions, TBifrostToken, TBridgeStatus, TBuildDestInfoOptions, TBuildInternalRes, TBuilderConfig, TBuilderInternalOptions, TBuilderOptions, TBypassOptions, TCacheItem, TChainConfig, TChainConfigMap, TChainEndpoint, TChainWithApi, TClientEntry, TClientKey, TConditionalXcmFeeDetail, TConditionalXcmFeeHopInfo, TCreateBaseSwapXcmOptions, TCreateBaseTransferXcmOptions, TCreateBeneficiaryOptions, TCreateBeneficiaryXTokensOptions, TCreateSwapXcmInternalOptions, TCreateSwapXcmOptions, TCreateTransferXcmOptions, TCreateTxsOptions, TDestWeight, TDestXcmFeeDetail, TDestination, TDryRunBaseOptions, TDryRunBypassOptions, TDryRunCallBaseOptions, TDryRunCallOptions, TDryRunChainFailure, TDryRunChainResult, TDryRunChainSuccess, TDryRunError, TDryRunOptions, TDryRunPreviewOptions, TDryRunResBase, TDryRunResult, TDryRunXcmBaseOptions, TDryRunXcmOptions, TEvmBuilderOptions, TEvmBuilderOptionsBase, TEvmChainFrom, TFeeType, TForeignAssetId, TForeignOrNativeAsset, TForeignOrTokenAsset, TGetAssetBalanceOptions, TGetAssetBalanceOptionsBase, TGetBalanceCommonOptions, TGetBalanceOptions, TGetBalanceOptionsBase, TGetFeeForDestChainBaseOptions, TGetFeeForDestChainOptions, TGetMinTransferableAmountOptions, TGetOriginXcmFeeBaseOptions, TGetOriginXcmFeeEstimateOptions, TGetOriginXcmFeeInternalOptions, TGetOriginXcmFeeOptions, TGetReverseTxFeeOptions, TGetTransferInfoOptions, TGetTransferInfoOptionsBase, TGetTransferableAmountOptions, TGetTransferableAmountOptionsBase, TGetXcmFeeBaseOptions, TGetXcmFeeBuilderOptions, TGetXcmFeeEstimateDetail, TGetXcmFeeEstimateOptions, TGetXcmFeeEstimateResult, TGetXcmFeeInternalOptions, TGetXcmFeeOptions, TGetXcmFeeResult, THopInfo, THopTransferInfo, TMantaAsset, TModuleError, TNativeTokenAsset, TNodleAsset, TOriginFeeDetails, TOtherReserveAsset, TPaymentInfo, TPolkadotXCMTransferOptions, TPolkadotXcmMethod, TProviderEntry, TReserveAsset, TResolveHopParams, TScenario, TSelfReserveAsset, TSendBaseOptions, TSendBaseOptionsWithSenderAddress, TSendInternalOptions, TSendOptions, TSender, TSerializeEthTransferOptions, TSerializedEthTransfer, TSerializedExtrinsics, TSerializedRuntimeApiQuery, TSerializedStateQuery, TSetBalanceRes, TSwapConfig, TSwapFeeEstimates, TTransactOptions, TTransactOrigin, TTransferFeeEstimates, TTransferInfo, TTransferLocalOptions, TTxFactory, TTypeAndThenCallContext, TTypeAndThenFees, TTypeAndThenOverrides, TUrl, TVerifyEdOnDestinationOptions, TVerifyEdOnDestinationOptionsBase, TWeight, TXTokensCurrencySelection, TXTokensMethod, TXTokensTransferOptions, TXcmAsset, TXcmFeeBase, TXcmFeeDetail, TXcmFeeDetailError, TXcmFeeDetailSuccess, TXcmFeeDetailWithFallback, TXcmFeeHopInfo, TXcmFeeHopResult, TXcmFeeSwapConfig, TXcmForeignAsset, TXcmPalletMethod, TXcmVersioned, TZeitgeistAsset, WithApi, WithRequiredSenderAddress };
2379
+ export type { BuildHopInfoOptions, ClientCache, HopProcessParams, HopTraversalConfig, HopTraversalResult, IPolkadotApi, IPolkadotXCMTransfer, IXTokensTransfer, OneKey, TAddress, TApiOrUrl, TAssetClaimInternalOptions, TAssetClaimOptions, TAssetClaimOptionsBase, TBatchOptions, TBatchedSendOptions, TBifrostToken, TBridgeStatus, TBuildDestInfoOptions, TBuildInternalRes, TBuilderConfig, TBuilderInternalOptions, TBuilderOptions, TBypassOptions, TCacheItem, TChainConfig, TChainConfigMap, TChainEndpoint, TChainWithApi, TClientEntry, TClientKey, TConditionalXcmFeeDetail, TConditionalXcmFeeHopInfo, TCreateBaseSwapXcmOptions, TCreateBaseTransferXcmOptions, TCreateBeneficiaryOptions, TCreateBeneficiaryXTokensOptions, TCreateEthBridgeInstructionsOptions, TCreateSwapXcmInternalOptions, TCreateSwapXcmOptions, TCreateTransferXcmOptions, TCreateTxsOptions, TDestWeight, TDestXcmFeeDetail, TDestination, TDryRunBaseOptions, TDryRunBypassOptions, TDryRunCallBaseOptions, TDryRunCallOptions, TDryRunChainFailure, TDryRunChainResult, TDryRunChainSuccess, TDryRunError, TDryRunOptions, TDryRunPreviewOptions, TDryRunResBase, TDryRunResult, TDryRunXcmBaseOptions, TDryRunXcmOptions, TEvmBuilderOptions, TEvmBuilderOptionsBase, TEvmChainFrom, TFeeType, TForeignAssetId, TForeignOrNativeAsset, TForeignOrTokenAsset, TGetAssetBalanceOptions, TGetAssetBalanceOptionsBase, TGetBalanceCommonOptions, TGetBalanceOptions, TGetBalanceOptionsBase, TGetFeeForDestChainBaseOptions, TGetFeeForDestChainOptions, TGetMinTransferableAmountOptions, TGetOriginXcmFeeBaseOptions, TGetOriginXcmFeeEstimateOptions, TGetOriginXcmFeeInternalOptions, TGetOriginXcmFeeOptions, TGetReverseTxFeeOptions, TGetTransferInfoOptions, TGetTransferInfoOptionsBase, TGetTransferableAmountOptions, TGetTransferableAmountOptionsBase, TGetXcmFeeBaseOptions, TGetXcmFeeBuilderOptions, TGetXcmFeeEstimateDetail, TGetXcmFeeEstimateOptions, TGetXcmFeeEstimateResult, TGetXcmFeeInternalOptions, TGetXcmFeeOptions, TGetXcmFeeResult, THopInfo, THopTransferInfo, TMantaAsset, TModuleError, TNativeTokenAsset, TNodleAsset, TOriginFeeDetails, TOtherReserveAsset, TPaymentInfo, TPolkadotXCMTransferOptions, TPolkadotXcmMethod, TProviderEntry, TReserveAsset, TResolveHopParams, TScenario, TSelfReserveAsset, TSendBaseOptions, TSendBaseOptionsWithSenderAddress, TSendInternalOptions, TSendOptions, TSender, TSerializeEthTransferOptions, TSerializedEthTransfer, TSerializedExtrinsics, TSerializedRuntimeApiQuery, TSerializedStateQuery, TSetBalanceRes, TSwapConfig, TSwapFeeEstimates, TTransactOptions, TTransactOrigin, TTransferFeeEstimates, TTransferInfo, TTransferLocalOptions, TTxFactory, TTypeAndThenCallContext, TTypeAndThenFees, TTypeAndThenOverrides, TUrl, TVerifyEdOnDestinationOptions, TVerifyEdOnDestinationOptionsBase, TWeight, TXTokensCurrencySelection, TXTokensMethod, TXTokensTransferOptions, TXcmAsset, TXcmFeeBase, TXcmFeeDetail, TXcmFeeDetailError, TXcmFeeDetailSuccess, TXcmFeeDetailWithFallback, TXcmFeeHopInfo, TXcmFeeHopResult, TXcmFeeSwapConfig, TXcmForeignAsset, TXcmPalletMethod, TXcmVersioned, TZeitgeistAsset, WithApi, WithRequiredSenderAddress };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { blake2b } from '@noble/hashes/blake2.js';
2
- import { isChainEvm, getAssetsObject, InvalidCurrencyError, isTAsset, findAssetInfoOrThrow, findNativeAssetInfoOrThrow, findAssetInfo, getExistentialDepositOrThrow, isSymbolMatch, getNativeAssetSymbol, getEdFromAssetOrThrow, hasDryRunSupport, findAssetOnDestOrThrow, findAssetInfoOnDest, isAssetEqual, isStableCoinAsset, isOverrideLocationSpecifier, extractAssetLocation, getRelayChainSymbol, isSymbolSpecifier, findNativeAssetInfo, isAssetXcEqual, normalizeLocation, normalizeSymbol, Native, hasXcmPaymentApiSupport, getOtherAssets } from '@paraspell/assets';
2
+ import { isChainEvm, getAssetsObject, InvalidCurrencyError, isTAsset, findAssetInfoOrThrow, findNativeAssetInfoOrThrow, findAssetInfo, getExistentialDepositOrThrow, isSymbolMatch, getNativeAssetSymbol, getEdFromAssetOrThrow, hasDryRunSupport, findAssetOnDestOrThrow, findAssetInfoOnDest, isAssetEqual, isStableCoinAsset, isBridgedSystemAsset, isOverrideLocationSpecifier, extractAssetLocation, getRelayChainSymbol, isSymbolSpecifier, findNativeAssetInfo, isAssetXcEqual, normalizeLocation, normalizeSymbol, Native, hasXcmPaymentApiSupport, getOtherAssets } from '@paraspell/assets';
3
3
  export * from '@paraspell/assets';
4
4
  import { base58 } from '@scure/base';
5
5
  import { isAddress, isHex, getContract, createPublicClient, http, parseUnits as parseUnits$1, formatUnits as formatUnits$1, pad, toHex, getAddress, concat, keccak256 } from 'viem';
@@ -1138,26 +1138,19 @@ var getAssetReserveChain = function getAssetReserveChain(chain, assetLocation) {
1138
1138
  return chain;
1139
1139
  };
1140
1140
 
1141
- var createPayFees = function createPayFees(version, asset, weight) {
1142
- if (version < Version.V5) {
1143
- return [{
1144
- BuyExecution: {
1145
- fees: asset,
1146
- weight_limit: weight ? {
1147
- Limited: {
1148
- ref_time: weight.refTime,
1149
- proof_size: weight.proofSize
1150
- }
1151
- } : 'Unlimited'
1152
- }
1153
- }];
1154
- }
1141
+ // PayFees instruction is removed temporarily in favor of BuyExecution everywhere,
1142
+ // but we keep this function for now in case we need to add it back in the future
1143
+ var createPayFees = function createPayFees(_version, asset, weight) {
1155
1144
  return [{
1156
- PayFees: {
1157
- asset: asset
1145
+ BuyExecution: {
1146
+ fees: asset,
1147
+ weight_limit: weight ? {
1148
+ Limited: {
1149
+ ref_time: weight.refTime,
1150
+ proof_size: weight.proofSize
1151
+ }
1152
+ } : 'Unlimited'
1158
1153
  }
1159
- }, {
1160
- RefundSurplus: undefined
1161
1154
  }];
1162
1155
  };
1163
1156
 
@@ -4710,10 +4703,8 @@ var validateBridgeAsset = function validateBridgeAsset(origin, destination, asse
4710
4703
  }
4711
4704
  var nativeAsset = findNativeAssetInfoOrThrow(origin);
4712
4705
  var isNativeAsset = isAssetEqual(asset, nativeAsset);
4713
- var ecosystem = getRelayChainOf(destination).toLowerCase();
4714
- var isBridgedSystemAsset = asset.location.parents === Parents.TWO && deepEqual(getJunctionValue(asset.location, 'GlobalConsensus'), _defineProperty({}, ecosystem, null));
4715
4706
  var isBridgedStablecoin = isStableCoinAsset(asset);
4716
- if (!(isNativeAsset || isBridgedSystemAsset || isBridgedStablecoin)) {
4707
+ if (!(isNativeAsset || isBridgedSystemAsset(asset, [getRelayChainOf(destination)]) || isBridgedStablecoin)) {
4717
4708
  throw new InvalidCurrencyError("Substrate bridge does not support currency ".concat(JSON.stringify(currency, replaceBigInt), "."));
4718
4709
  }
4719
4710
  };
@@ -5020,7 +5011,7 @@ var getParaEthTransferFees = /*#__PURE__*/function () {
5020
5011
  };
5021
5012
  }();
5022
5013
 
5023
- var abi$1 = [
5014
+ var abi$2 = [
5024
5015
  {
5025
5016
  inputs: [
5026
5017
  {
@@ -5130,18 +5121,62 @@ var getDestinationLocation = function getDestinationLocation(api, address, desti
5130
5121
  return [1, paraId ? ["0x0000000".concat(paraId.toString(16)), acc] : [acc]];
5131
5122
  };
5132
5123
 
5124
+ var abi$1 = [{
5125
+ inputs: [{
5126
+ internalType: 'address',
5127
+ name: 'recipient_',
5128
+ type: 'address'
5129
+ }, {
5130
+ internalType: 'uint256',
5131
+ name: 'amount_',
5132
+ type: 'uint256'
5133
+ }],
5134
+ name: 'transfer',
5135
+ outputs: [{
5136
+ internalType: 'bool',
5137
+ name: '',
5138
+ type: 'bool'
5139
+ }],
5140
+ stateMutability: 'nonpayable',
5141
+ type: 'function'
5142
+ }];
5143
+ var transferMoonbeamLocal = /*#__PURE__*/function () {
5144
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(client, assetInfo, _ref) {
5145
+ var signer, address, contract;
5146
+ return _regenerator().w(function (_context) {
5147
+ while (1) switch (_context.n) {
5148
+ case 0:
5149
+ signer = _ref.signer, address = _ref.address;
5150
+ assertHasId(assetInfo);
5151
+ contract = getContract({
5152
+ abi: abi$1,
5153
+ address: assetInfo.assetId,
5154
+ client: {
5155
+ "public": client,
5156
+ wallet: signer
5157
+ }
5158
+ });
5159
+ return _context.a(2, contract.write.transfer([address, assetInfo.amount]));
5160
+ }
5161
+ }, _callee);
5162
+ }));
5163
+ return function transferMoonbeamLocal(_x, _x2, _x3) {
5164
+ return _ref2.apply(this, arguments);
5165
+ };
5166
+ }();
5167
+
5133
5168
  var U_64_MAX = 18446744073709551615n;
5134
5169
  var CONTRACT_ADDRESS = '0x0000000000000000000000000000000000000804';
5135
5170
  var NATIVE_ASSET_ID = '0x0000000000000000000000000000000000000802';
5136
5171
  // Partially inspired by Moonbeam XCM-SDK
5137
5172
  var transferMoonbeamEvm = /*#__PURE__*/function () {
5138
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(_ref) {
5173
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(options) {
5139
5174
  var _usdtAsset$assetId;
5140
- var api, from, to, signer, address, currency, contract, foundAsset, amount, asset, destLocation, weight, createTx, multiCurrencySymbols, useMultiAssets, usdtAsset, tx, _t;
5175
+ var api, from, to, signer, address, currency, foundAsset, amount, client, contract, asset, destLocation, weight, createTx, multiCurrencySymbols, useMultiAssets, usdtAsset, tx, _t;
5141
5176
  return _regenerator().w(function (_context) {
5142
5177
  while (1) switch (_context.n) {
5143
5178
  case 0:
5144
- api = _ref.api, from = _ref.from, to = _ref.to, signer = _ref.signer, address = _ref.address, currency = _ref.currency;
5179
+ api = options.api, from = options.from, to = options.to, signer = options.signer, address = options.address, currency = options.currency;
5145
5180
  if (!Array.isArray(currency)) {
5146
5181
  _context.n = 1;
5147
5182
  break;
@@ -5154,35 +5189,44 @@ var transferMoonbeamEvm = /*#__PURE__*/function () {
5154
5189
  }
5155
5190
  throw new UnsupportedOperationError('Override location is not supported for EVM transfers');
5156
5191
  case 2:
5192
+ foundAsset = findAssetInfoOrThrow(from, currency, to);
5193
+ amount = abstractDecimals(currency.amount, foundAsset.decimals, api);
5194
+ client = createPublicClient({
5195
+ chain: signer.chain,
5196
+ transport: http()
5197
+ });
5198
+ if (!(from === to)) {
5199
+ _context.n = 3;
5200
+ break;
5201
+ }
5202
+ return _context.a(2, transferMoonbeamLocal(client, _objectSpread2(_objectSpread2({}, foundAsset), {}, {
5203
+ amount: amount
5204
+ }), options));
5205
+ case 3:
5157
5206
  contract = getContract({
5158
- abi: abi$1,
5207
+ abi: abi$2,
5159
5208
  address: CONTRACT_ADDRESS,
5160
5209
  client: {
5161
- "public": createPublicClient({
5162
- chain: signer.chain,
5163
- transport: http()
5164
- }),
5210
+ "public": client,
5165
5211
  wallet: signer
5166
5212
  }
5167
5213
  });
5168
- foundAsset = findAssetInfoOrThrow(from, currency, to);
5169
- amount = abstractDecimals(currency.amount, foundAsset.decimals, api);
5170
5214
  if (!(foundAsset.symbol === getNativeAssetSymbol(from))) {
5171
- _context.n = 3;
5215
+ _context.n = 4;
5172
5216
  break;
5173
5217
  }
5174
5218
  asset = NATIVE_ASSET_ID;
5175
- _context.n = 5;
5219
+ _context.n = 6;
5176
5220
  break;
5177
- case 3:
5221
+ case 4:
5178
5222
  if (!(foundAsset.assetId === undefined)) {
5179
- _context.n = 4;
5223
+ _context.n = 5;
5180
5224
  break;
5181
5225
  }
5182
5226
  throw new InvalidCurrencyError('Currency must be a foreign asset with valid assetId');
5183
- case 4:
5184
- asset = formatAssetIdToERC20(foundAsset.assetId);
5185
5227
  case 5:
5228
+ asset = formatAssetIdToERC20(foundAsset.assetId);
5229
+ case 6:
5186
5230
  destLocation = getDestinationLocation(api, address, to);
5187
5231
  weight = U_64_MAX; // Partially inspired by Moonbeam XCM-SDK
5188
5232
  // https://github.com/moonbeam-foundation/xcm-sdk/blob/ab835c15bf41612604b1c858d956a9f07705ed65/packages/sdk/src/contract/contracts/Xtokens/Xtokens.ts#L53
@@ -5197,30 +5241,30 @@ var transferMoonbeamEvm = /*#__PURE__*/function () {
5197
5241
  }, to);
5198
5242
  assertHasId(usdtAsset);
5199
5243
  if (!useMultiAssets) {
5200
- _context.n = 7;
5244
+ _context.n = 8;
5201
5245
  break;
5202
5246
  }
5203
- _context.n = 6;
5247
+ _context.n = 7;
5204
5248
  return createTx('transferMultiCurrencies', [[[asset, amount.toString()], [formatAssetIdToERC20((_usdtAsset$assetId = usdtAsset.assetId) !== null && _usdtAsset$assetId !== void 0 ? _usdtAsset$assetId : ''), '200000']], 1,
5205
5249
  // index of the fee asset
5206
5250
  destLocation, weight]);
5207
- case 6:
5251
+ case 7:
5208
5252
  _t = _context.v;
5209
- _context.n = 9;
5253
+ _context.n = 10;
5210
5254
  break;
5211
- case 7:
5212
- _context.n = 8;
5213
- return createTx('transfer', [asset, amount.toString(), destLocation, weight]);
5214
5255
  case 8:
5215
- _t = _context.v;
5256
+ _context.n = 9;
5257
+ return createTx('transfer', [asset, amount.toString(), destLocation, weight]);
5216
5258
  case 9:
5259
+ _t = _context.v;
5260
+ case 10:
5217
5261
  tx = _t;
5218
5262
  return _context.a(2, tx);
5219
5263
  }
5220
5264
  }, _callee);
5221
5265
  }));
5222
5266
  return function transferMoonbeamEvm(_x) {
5223
- return _ref2.apply(this, arguments);
5267
+ return _ref.apply(this, arguments);
5224
5268
  };
5225
5269
  }();
5226
5270
 
@@ -5573,7 +5617,7 @@ var createMainInstruction = function createMainInstruction(origin, asset, ethAss
5573
5617
  }
5574
5618
  };
5575
5619
  };
5576
- var createCustomXcmOnDest = function createCustomXcmOnDest(_ref, origin, messageId, ethAsset) {
5620
+ var createEthereumBridgeInstructions = function createEthereumBridgeInstructions(_ref, origin, messageId, ethAsset) {
5577
5621
  var api = _ref.api,
5578
5622
  address = _ref.address,
5579
5623
  assetInfo = _ref.assetInfo,
@@ -5584,7 +5628,7 @@ var createCustomXcmOnDest = function createCustomXcmOnDest(_ref, origin, message
5584
5628
  if (isChainEvm(origin) && !ahAddress) {
5585
5629
  throw new MissingParameterError('ahAddress');
5586
5630
  }
5587
- return _defineProperty({}, version, [{
5631
+ return [{
5588
5632
  SetAppendix: origin === 'Mythos' ? [] : [{
5589
5633
  DepositAsset: {
5590
5634
  assets: {
@@ -5599,7 +5643,24 @@ var createCustomXcmOnDest = function createCustomXcmOnDest(_ref, origin, message
5599
5643
  }]
5600
5644
  }, createMainInstruction(origin, assetInfo, ethAsset, address, messageId), {
5601
5645
  SetTopic: messageId
5602
- }]);
5646
+ }];
5647
+ };
5648
+ var createCustomXcmOnDest = function createCustomXcmOnDest(options, origin, messageId, ethAsset) {
5649
+ var api = options.api,
5650
+ address = options.address,
5651
+ assetInfo = options.assetInfo,
5652
+ senderAddress = options.senderAddress,
5653
+ ahAddress = options.ahAddress,
5654
+ version = options.version;
5655
+ var instructions = createEthereumBridgeInstructions({
5656
+ api: api,
5657
+ address: address,
5658
+ assetInfo: assetInfo,
5659
+ senderAddress: senderAddress,
5660
+ ahAddress: ahAddress,
5661
+ version: version
5662
+ }, origin, messageId, ethAsset);
5663
+ return _defineProperty({}, version, instructions);
5603
5664
  };
5604
5665
 
5605
5666
  var generateMessageId = /*#__PURE__*/function () {
@@ -8975,6 +9036,8 @@ var prepareExecuteContext = function prepareExecuteContext(_ref) {
8975
9036
  var assetLocalizedToReserve = createAsset(version, amount, localizeLocation(reserveChain !== null && reserveChain !== void 0 ? reserveChain : chain, assetInfo.location));
8976
9037
  var feeAsset = feeAssetInfo && !isAssetEqual(assetInfo, feeAssetInfo) ? createAsset(version, originFee, feeAssetInfo.location) : undefined;
8977
9038
  var feeAssetLocalized = feeAssetInfo && !isAssetEqual(assetInfo, feeAssetInfo) ? createAsset(version, originFee, localizeLocation(chain, feeAssetInfo.location)) : undefined;
9039
+ var feeAssetLocalizedToDest = feeAssetInfo && !isAssetEqual(assetInfo, feeAssetInfo) ? createAsset(version, originFee, localizeLocation(destChain, feeAssetInfo.location)) : undefined;
9040
+ var feeAssetLocalizedToReserve = feeAssetInfo && !isAssetEqual(assetInfo, feeAssetInfo) ? createAsset(version, originFee, localizeLocation(reserveChain !== null && reserveChain !== void 0 ? reserveChain : chain, feeAssetInfo.location)) : undefined;
8978
9041
  return {
8979
9042
  amount: amount,
8980
9043
  asset: asset,
@@ -8983,6 +9046,8 @@ var prepareExecuteContext = function prepareExecuteContext(_ref) {
8983
9046
  assetLocalizedToReserve: assetLocalizedToReserve,
8984
9047
  feeAsset: feeAsset,
8985
9048
  feeAssetLocalized: feeAssetLocalized,
9049
+ feeAssetLocalizedToDest: feeAssetLocalizedToDest,
9050
+ feeAssetLocalizedToReserve: feeAssetLocalizedToReserve,
8986
9051
  reserveChain: reserveChain
8987
9052
  };
8988
9053
  };
@@ -9028,6 +9093,7 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9028
9093
  version = options.version,
9029
9094
  paraIdTo = options.paraIdTo,
9030
9095
  transactOptions = options.transactOptions,
9096
+ useFeeAssetOnHops = options.useFeeAssetOnHops,
9031
9097
  _options$suffixXcm = options.suffixXcm,
9032
9098
  suffixXcm = _options$suffixXcm === void 0 ? [] : _options$suffixXcm;
9033
9099
  var _prepareExecuteContex = prepareExecuteContext(options),
@@ -9036,18 +9102,30 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9036
9102
  assetLocalizedToReserve = _prepareExecuteContex.assetLocalizedToReserve,
9037
9103
  assetLocalizedToDest = _prepareExecuteContex.assetLocalizedToDest,
9038
9104
  feeAsset = _prepareExecuteContex.feeAsset,
9105
+ feeAssetLocalizedToReserve = _prepareExecuteContex.feeAssetLocalizedToReserve,
9106
+ feeAssetLocalizedToDest = _prepareExecuteContex.feeAssetLocalizedToDest,
9039
9107
  reserveChain = _prepareExecuteContex.reserveChain;
9108
+ var hopFeeAssetToReserve = useFeeAssetOnHops ? feeAssetLocalizedToReserve : undefined;
9109
+ var hopFeeAssetToDest = useFeeAssetOnHops ? feeAssetLocalizedToDest : undefined;
9110
+ // When fees are paid in a separate asset, originFee is denominated in that asset's
9111
+ // currency and must not be subtracted from the transfer amount.
9112
+ var originFeeDeduction = feeAsset ? 0n : originFee;
9040
9113
  var destLocation = createDestination(version, chain, destChain, paraIdTo);
9041
9114
  if (chain !== 'AssetHubPolkadot' && reserveChain === undefined) {
9042
9115
  throw new UnsupportedOperationError('Sending local reserve assets with custom fee asset is not yet supported for this chain.');
9043
9116
  }
9044
9117
  var transferType = getInstructionType(version, chain, destChain, reserveChain, transactOptions);
9118
+ var routingAssetsFilter = feeAsset ? {
9119
+ Wild: {
9120
+ AllCounted: 2
9121
+ }
9122
+ } : createAssetsFilter(assetLocalized, version);
9045
9123
  var isReserveDest = reserveChain === destChain;
9046
9124
  var resolvedDepositInstruction = isReserveDest ? suffixXcm : [{
9047
9125
  DepositReserveAsset: {
9048
9126
  assets: createAssetsFilter(assetLocalizedToReserve, version),
9049
9127
  dest: createDestination(version, reserveChain !== null && reserveChain !== void 0 ? reserveChain : chain, destChain, paraIdTo),
9050
- xcm: [].concat(_toConsumableArray(createPayFees(version, updateAsset(assetLocalizedToDest, reserveFee === 1000n ? amount / 2n : amount - (feeAsset ? reserveFee : originFee + reserveFee)))), _toConsumableArray(suffixXcm))
9128
+ xcm: [].concat(_toConsumableArray(createPayFees(version, hopFeeAssetToDest !== null && hopFeeAssetToDest !== void 0 ? hopFeeAssetToDest : updateAsset(assetLocalizedToDest, reserveFee === 1000n ? amount / 2n : amount - originFeeDeduction - reserveFee))), _toConsumableArray(suffixXcm))
9051
9129
  }
9052
9130
  }];
9053
9131
  var mainInstructions;
@@ -9058,9 +9136,9 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9058
9136
  mainInstructions = [{
9059
9137
  InitiateTransfer: {
9060
9138
  destination: destLocation,
9061
- remote_fees: _defineProperty({}, transferFilter, createAssetsFilter(assetLocalized, version)),
9139
+ remote_fees: _defineProperty({}, transferFilter, routingAssetsFilter),
9062
9140
  preserve_origin: true,
9063
- assets: [_defineProperty({}, transferFilter, createAssetsFilter(assetLocalized, version))],
9141
+ assets: [_defineProperty({}, transferFilter, routingAssetsFilter)],
9064
9142
  remote_xcm: [{
9065
9143
  RefundSurplus: undefined
9066
9144
  }].concat(_toConsumableArray(suffixXcm))
@@ -9072,9 +9150,9 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9072
9150
  // Use teleport for trusted chains
9073
9151
  mainInstructions = [{
9074
9152
  InitiateTeleport: {
9075
- assets: createAssetsFilter(assetLocalized, version),
9153
+ assets: routingAssetsFilter,
9076
9154
  dest: destLocation,
9077
- xcm: [].concat(_toConsumableArray(createPayFees(version, updateAsset(assetLocalizedToDest, feeAsset ? amount : amount - originFee))), _toConsumableArray(suffixXcm))
9155
+ xcm: [].concat(_toConsumableArray(createPayFees(version, hopFeeAssetToDest !== null && hopFeeAssetToDest !== void 0 ? hopFeeAssetToDest : updateAsset(assetLocalizedToDest, amount - originFeeDeduction))), _toConsumableArray(suffixXcm))
9078
9156
  }
9079
9157
  }];
9080
9158
  break;
@@ -9082,9 +9160,9 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9082
9160
  // Teleport to reserve chain first
9083
9161
  mainInstructions = [{
9084
9162
  InitiateTeleport: {
9085
- assets: createAssetsFilter(assetLocalized, version),
9163
+ assets: routingAssetsFilter,
9086
9164
  dest: getChainLocation(chain, reserveChain),
9087
- xcm: [].concat(_toConsumableArray(createPayFees(version, updateAsset(assetLocalizedToReserve, feeAsset ? amount : amount - originFee))), _toConsumableArray(resolvedDepositInstruction))
9165
+ xcm: [].concat(_toConsumableArray(createPayFees(version, hopFeeAssetToReserve !== null && hopFeeAssetToReserve !== void 0 ? hopFeeAssetToReserve : updateAsset(assetLocalizedToReserve, amount - originFeeDeduction))), _toConsumableArray(resolvedDepositInstruction))
9088
9166
  }
9089
9167
  }];
9090
9168
  break;
@@ -9092,12 +9170,11 @@ var createBaseExecuteXcm = function createBaseExecuteXcm(options) {
9092
9170
  // For non-trusted chains
9093
9171
  mainInstructions = [{
9094
9172
  InitiateReserveWithdraw: {
9095
- assets: createAssetsFilter(assetLocalized, version),
9173
+ assets: routingAssetsFilter,
9096
9174
  reserve: getChainLocation(chain, reserveChain),
9097
- xcm: [].concat(_toConsumableArray(createPayFees(version,
9098
- // Decrease amount by 2 units becuase for some reason polkadot withdraws 2 units less
9175
+ xcm: [].concat(_toConsumableArray(createPayFees(version, // Decrease amount by 2 units because for some reason polkadot withdraws 2 units less
9099
9176
  // than requested, so we need to account for that
9100
- updateAsset(assetLocalizedToReserve, amount - 2n))), _toConsumableArray(resolvedDepositInstruction))
9177
+ hopFeeAssetToReserve !== null && hopFeeAssetToReserve !== void 0 ? hopFeeAssetToReserve : updateAsset(assetLocalizedToReserve, amount - 2n))), _toConsumableArray(resolvedDepositInstruction))
9101
9178
  }
9102
9179
  }];
9103
9180
  break;
@@ -9215,6 +9292,7 @@ var createExecuteExchangeXcm = function createExecuteExchangeXcm(input, origin,
9215
9292
  var prepareCommonExecuteXcm = function prepareCommonExecuteXcm(options, assetToDeposit) {
9216
9293
  var api = options.api,
9217
9294
  feeAsset = options.feeAssetInfo,
9295
+ useJitWithdraw = options.useJitWithdraw,
9218
9296
  recipientAddress = options.recipientAddress,
9219
9297
  version = options.version;
9220
9298
  var context = prepareExecuteContext(options);
@@ -9226,7 +9304,7 @@ var prepareCommonExecuteXcm = function prepareCommonExecuteXcm(options, assetToD
9226
9304
  prefix.push({
9227
9305
  WithdrawAsset: withdrawAssets
9228
9306
  });
9229
- if (feeAsset) {
9307
+ if (feeAsset && !useJitWithdraw) {
9230
9308
  prefix.push.apply(prefix, _toConsumableArray(createPayFees(version, feeAssetLocalized !== null && feeAssetLocalized !== void 0 ? feeAssetLocalized : assetLocalized, {
9231
9309
  refTime: 450n,
9232
9310
  proofSize: 0n
@@ -9399,7 +9477,7 @@ var isMultiHopSwap = function isMultiHopSwap(exchangeChain, assetFrom, assetTo)
9399
9477
  };
9400
9478
 
9401
9479
  var createExchangeInstructions = /*#__PURE__*/function () {
9402
- var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(options, assetFrom, assetTo) {
9480
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(options, assetFrom, assetTo, hasSeparateFeeAsset) {
9403
9481
  var chain, exchangeChain, assetInfoFrom, assetInfoTo, version, calculateMinAmountOut, _options$fees, originReserveFee, exchangeFee, nativeSymbol, needsMultiHop, nativeAsset, nativeAmountOut, assetNative;
9404
9482
  return _regenerator().w(function (_context) {
9405
9483
  while (1) switch (_context.n) {
@@ -9418,7 +9496,7 @@ var createExchangeInstructions = /*#__PURE__*/function () {
9418
9496
  ExchangeAsset: {
9419
9497
  give: createAssetsFilter(assetFrom, version),
9420
9498
  want: [assetTo],
9421
- maximal: false
9499
+ maximal: hasSeparateFeeAsset
9422
9500
  }
9423
9501
  }]);
9424
9502
  case 1:
@@ -9443,60 +9521,133 @@ var createExchangeInstructions = /*#__PURE__*/function () {
9443
9521
  }
9444
9522
  }, _callee);
9445
9523
  }));
9446
- return function createExchangeInstructions(_x, _x2, _x3) {
9524
+ return function createExchangeInstructions(_x, _x2, _x3, _x4) {
9447
9525
  return _ref.apply(this, arguments);
9448
9526
  };
9449
9527
  }();
9450
9528
  var createSwapExecuteXcm = /*#__PURE__*/function () {
9451
9529
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(options) {
9452
- var api, chain, exchangeChain, destChain, assetInfoFrom, assetInfoTo, _options$fees2, originReserveFee, destReserveFee, recipientAddress, version, paraIdTo, assetFrom, amountOut, assetTo, assetToLocalizedToDest, _prepareCommonExecute, prefix, depositInstruction, exchangeInstructions, exchangeToDestXcm, finalXcm, fullXcm;
9530
+ var _ref3, _ref4;
9531
+ var api, chain, exchangeChain, destChain, assetInfoFrom, assetInfoTo, feeAssetInfo, _options$fees2, originFee, originReserveFee, destReserveFee, senderAddress, recipientAddress, version, paraIdTo, isEthereumDest, resolvedDestChain, assetFrom, amountOut, assetTo, assetToLocalizedToDest, ethFeeAssetInfo, ethBridgeFee, isMainAssetDot, nativeFeeAssetInfo, ahApi, _yield$getParaEthTran, _yield$getParaEthTran2, bridgeFee, executionFee, resolvedFeeAssetInfo, hasSeparateFeeAsset, _prepareCommonExecute, prefix, depositInstruction, exchangeInstructions, exchangeToDestXcm, ethAsset, messageId, snowbridgeInstructions, finalXcm, fullXcm;
9453
9532
  return _regenerator().w(function (_context2) {
9454
9533
  while (1) switch (_context2.n) {
9455
9534
  case 0:
9456
- api = options.api, chain = options.chain, exchangeChain = options.exchangeChain, destChain = options.destChain, assetInfoFrom = options.assetInfoFrom, assetInfoTo = options.assetInfoTo, _options$fees2 = options.fees, originReserveFee = _options$fees2.originReserveFee, destReserveFee = _options$fees2.destReserveFee, recipientAddress = options.recipientAddress, version = options.version, paraIdTo = options.paraIdTo;
9535
+ api = options.api, chain = options.chain, exchangeChain = options.exchangeChain, destChain = options.destChain, assetInfoFrom = options.assetInfoFrom, assetInfoTo = options.assetInfoTo, feeAssetInfo = options.feeAssetInfo, _options$fees2 = options.fees, originFee = _options$fees2.originFee, originReserveFee = _options$fees2.originReserveFee, destReserveFee = _options$fees2.destReserveFee, senderAddress = options.senderAddress, recipientAddress = options.recipientAddress, version = options.version, paraIdTo = options.paraIdTo;
9536
+ isEthereumDest = destChain !== undefined && isExternalChain(destChain); // For Ethereum destination, the actual hop target is AssetHub (bridge hub)
9537
+ resolvedDestChain = isEthereumDest ? "AssetHub".concat(getRelayChainOf(chain !== null && chain !== void 0 ? chain : exchangeChain)) : undefined;
9457
9538
  assetFrom = createAsset(version, assetInfoFrom.amount, localizeLocation(exchangeChain, assetInfoFrom.location));
9458
9539
  amountOut = assetInfoTo.amount;
9459
- assetTo = createAsset(version, amountOut, localizeLocation(exchangeChain, assetInfoTo.location));
9460
- assetToLocalizedToDest = createAsset(version, amountOut, localizeLocation(destChain !== null && destChain !== void 0 ? destChain : exchangeChain, assetInfoTo.location));
9540
+ assetTo = createAsset(version, amountOut, localizeLocation(exchangeChain, assetInfoTo.location)); // For Ethereum, localize to AssetHub since that's where instructions execute
9541
+ assetToLocalizedToDest = createAsset(version, amountOut, localizeLocation((_ref3 = resolvedDestChain !== null && resolvedDestChain !== void 0 ? resolvedDestChain : destChain) !== null && _ref3 !== void 0 ? _ref3 : exchangeChain, assetInfoTo.location)); // For Ethereum destination, use DOT as feeAsset for bridge fees
9542
+ ethBridgeFee = 0n; // Whether main asset IS DOT — no separate fee asset needed
9543
+ isMainAssetDot = false;
9544
+ if (!isEthereumDest) {
9545
+ _context2.n = 3;
9546
+ break;
9547
+ }
9548
+ nativeFeeAssetInfo = findNativeAssetInfoOrThrow(getRelayChainOf(chain !== null && chain !== void 0 ? chain : exchangeChain));
9549
+ _context2.n = 1;
9550
+ return api.createApiForChain('AssetHubPolkadot');
9551
+ case 1:
9552
+ ahApi = _context2.v;
9553
+ _context2.n = 2;
9554
+ return getParaEthTransferFees(ahApi);
9555
+ case 2:
9556
+ _yield$getParaEthTran = _context2.v;
9557
+ _yield$getParaEthTran2 = _slicedToArray(_yield$getParaEthTran, 2);
9558
+ bridgeFee = _yield$getParaEthTran2[0];
9559
+ executionFee = _yield$getParaEthTran2[1];
9560
+ ethBridgeFee = bridgeFee + executionFee;
9561
+ isMainAssetDot = isAssetEqual(assetInfoFrom, nativeFeeAssetInfo);
9562
+ if (!isMainAssetDot) {
9563
+ ethFeeAssetInfo = nativeFeeAssetInfo;
9564
+ }
9565
+ case 3:
9566
+ // Ethereum fee asset takes precedence over user-provided feeAssetInfo
9567
+ resolvedFeeAssetInfo = ethFeeAssetInfo !== null && ethFeeAssetInfo !== void 0 ? ethFeeAssetInfo : feeAssetInfo;
9568
+ hasSeparateFeeAsset = isEthereumDest && !isMainAssetDot || !!feeAssetInfo;
9461
9569
  _prepareCommonExecute = prepareCommonExecuteXcm({
9462
9570
  api: api,
9463
9571
  chain: chain !== null && chain !== void 0 ? chain : exchangeChain,
9464
- destChain: destChain !== null && destChain !== void 0 ? destChain : exchangeChain,
9572
+ destChain: (_ref4 = resolvedDestChain !== null && resolvedDestChain !== void 0 ? resolvedDestChain : destChain) !== null && _ref4 !== void 0 ? _ref4 : exchangeChain,
9465
9573
  assetInfo: assetInfoFrom,
9574
+ feeAssetInfo: resolvedFeeAssetInfo,
9575
+ useJitWithdraw: isEthereumDest,
9466
9576
  recipientAddress: recipientAddress,
9467
- // Deal with this after feeAsset for swaps is supported
9468
9577
  fees: {
9469
- originFee: 0n,
9578
+ originFee: hasSeparateFeeAsset ? ethBridgeFee || originFee : originFee,
9470
9579
  reserveFee: originReserveFee
9471
9580
  },
9472
9581
  version: version
9473
9582
  }, assetToLocalizedToDest), prefix = _prepareCommonExecute.prefix, depositInstruction = _prepareCommonExecute.depositInstruction;
9474
- _context2.n = 1;
9475
- return createExchangeInstructions(options, assetFrom, assetTo);
9476
- case 1:
9583
+ _context2.n = 4;
9584
+ return createExchangeInstructions(options, assetFrom, assetTo, isEthereumDest && hasSeparateFeeAsset);
9585
+ case 4:
9477
9586
  exchangeInstructions = _context2.v;
9478
- exchangeToDestXcm = destChain ? createBaseExecuteXcm({
9587
+ if (!isEthereumDest) {
9588
+ _context2.n = 6;
9589
+ break;
9590
+ }
9591
+ ethAsset = findAssetInfoOrThrow('Ethereum', {
9592
+ symbol: assetInfoTo.symbol
9593
+ }, null);
9594
+ _context2.n = 5;
9595
+ return generateMessageId(api, senderAddress, getParaId(chain !== null && chain !== void 0 ? chain : exchangeChain), ethAsset.assetId, recipientAddress, amountOut);
9596
+ case 5:
9597
+ messageId = _context2.v;
9598
+ snowbridgeInstructions = createEthereumBridgeInstructions({
9599
+ api: api,
9600
+ address: recipientAddress,
9601
+ assetInfo: assetInfoTo,
9602
+ senderAddress: senderAddress,
9603
+ version: version
9604
+ }, chain !== null && chain !== void 0 ? chain : exchangeChain, messageId, ethAsset); // If exchange chain is already AssetHub, instructions run directly there
9605
+ // Otherwise, route from exchange chain to AssetHub with bridge instructions as suffix
9606
+ exchangeToDestXcm = exchangeChain === resolvedDestChain ? snowbridgeInstructions : createBaseExecuteXcm({
9479
9607
  chain: exchangeChain,
9480
- destChain: destChain,
9608
+ destChain: resolvedDestChain,
9481
9609
  assetInfo: assetInfoTo,
9482
- paraIdTo: paraIdTo,
9610
+ feeAssetInfo: ethFeeAssetInfo,
9611
+ useFeeAssetOnHops: hasSeparateFeeAsset,
9612
+ paraIdTo: getParaId(resolvedDestChain),
9483
9613
  version: version,
9484
- // Deal with this after feeAsset is supported
9485
9614
  fees: {
9486
- originFee: 0n,
9615
+ originFee: hasSeparateFeeAsset ? ethBridgeFee : 0n,
9487
9616
  reserveFee: destReserveFee
9488
9617
  },
9489
- suffixXcm: [depositInstruction]
9490
- }) : [depositInstruction];
9618
+ suffixXcm: snowbridgeInstructions
9619
+ });
9620
+ _context2.n = 7;
9621
+ break;
9622
+ case 6:
9623
+ if (destChain) {
9624
+ exchangeToDestXcm = createBaseExecuteXcm({
9625
+ chain: exchangeChain,
9626
+ destChain: destChain,
9627
+ assetInfo: assetInfoTo,
9628
+ paraIdTo: paraIdTo,
9629
+ version: version,
9630
+ // Deal with this after feeAsset is supported
9631
+ fees: {
9632
+ originFee: 0n,
9633
+ reserveFee: destReserveFee
9634
+ },
9635
+ suffixXcm: [depositInstruction]
9636
+ });
9637
+ } else {
9638
+ exchangeToDestXcm = [depositInstruction];
9639
+ }
9640
+ case 7:
9491
9641
  finalXcm = chain ? createBaseExecuteXcm({
9492
9642
  chain: chain,
9493
9643
  destChain: exchangeChain,
9494
9644
  assetInfo: assetInfoFrom,
9645
+ feeAssetInfo: ethFeeAssetInfo,
9646
+ useFeeAssetOnHops: hasSeparateFeeAsset,
9495
9647
  paraIdTo: getParaId(exchangeChain),
9496
9648
  version: version,
9497
- // Deal with this after feeAsset is supported
9498
9649
  fees: {
9499
- originFee: 0n,
9650
+ originFee: hasSeparateFeeAsset ? ethBridgeFee : 0n,
9500
9651
  reserveFee: originReserveFee
9501
9652
  },
9502
9653
  suffixXcm: [].concat(_toConsumableArray(exchangeInstructions), _toConsumableArray(exchangeToDestXcm))
@@ -9506,7 +9657,7 @@ var createSwapExecuteXcm = /*#__PURE__*/function () {
9506
9657
  }
9507
9658
  }, _callee2);
9508
9659
  }));
9509
- return function createSwapExecuteXcm(_x4) {
9660
+ return function createSwapExecuteXcm(_x5) {
9510
9661
  return _ref2.apply(this, arguments);
9511
9662
  };
9512
9663
  }();
@@ -9563,6 +9714,7 @@ var findExchangeHopIndex = function findExchangeHopIndex(chain, dryRunResult, ex
9563
9714
  var extractFeesFromDryRun = function extractFeesFromDryRun(chain, dryRunResult, exchangeHopIndex, destChain) {
9564
9715
  var requireHopsSuccess = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
9565
9716
  var fees = {
9717
+ originFee: 0n,
9566
9718
  originReserveFee: 0n,
9567
9719
  exchangeFee: 0n,
9568
9720
  destReserveFee: 0n
@@ -9670,16 +9822,19 @@ var createXcmAndCall = /*#__PURE__*/function () {
9670
9822
  }();
9671
9823
  var handleSwapExecuteTransfer = /*#__PURE__*/function () {
9672
9824
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(options) {
9673
- var api, chain, exchangeChain, destChain, assetFrom, assetTo, currencyTo, senderAddress, recipientAddress, calculateMinAmountOut, version, internalOptions, dryRunParams, fees, totalFeesPre, _yield$createXcmAndCa, initialCall, firstDryRunResult, exchangeHopIndex, extractedFees, totalFees, updatedAssetTo, amountAvailableForSwap, recalculatedMinAmountOut, _yield$createXcmAndCa2, finalCall;
9825
+ var api, chain, exchangeChain, destChain, assetFrom, assetTo, currencyTo, feeAssetInfo, senderAddress, recipientAddress, calculateMinAmountOut, version, isEthereumDest, hasSeparateFeeAsset, internalOptions, dryRunParams, FEE_ASSET_AMOUNT, dummyOriginFee, fees, totalFeesPre, _yield$createXcmAndCa, initialCall, firstDryRunResult, exchangeHopIndex, extractedFees, totalFees, updatedAssetTo, amountAvailableForSwap, recalculatedMinAmountOut, _yield$createXcmAndCa2, finalCall;
9674
9826
  return _regenerator().w(function (_context3) {
9675
9827
  while (1) switch (_context3.n) {
9676
9828
  case 0:
9677
- api = options.api, chain = options.chain, exchangeChain = options.exchangeChain, destChain = options.destChain, assetFrom = options.assetInfoFrom, assetTo = options.assetInfoTo, currencyTo = options.currencyTo, senderAddress = options.senderAddress, recipientAddress = options.recipientAddress, calculateMinAmountOut = options.calculateMinAmountOut;
9829
+ api = options.api, chain = options.chain, exchangeChain = options.exchangeChain, destChain = options.destChain, assetFrom = options.assetInfoFrom, assetTo = options.assetInfoTo, currencyTo = options.currencyTo, feeAssetInfo = options.feeAssetInfo, senderAddress = options.senderAddress, recipientAddress = options.recipientAddress, calculateMinAmountOut = options.calculateMinAmountOut;
9678
9830
  _context3.n = 1;
9679
9831
  return api.init(chain !== null && chain !== void 0 ? chain : exchangeChain);
9680
9832
  case 1:
9681
9833
  validateAmount(assetFrom.amount, MIN_FEE);
9682
9834
  version = pickRouterCompatibleXcmVersion(chain, exchangeChain, destChain);
9835
+ isEthereumDest = destChain !== undefined && isExternalChain(destChain); // When main asset is DOT and dest is Ethereum, fees come from the same asset
9836
+ // (no separate fee asset needed). Only skip fee validation when currencies differ.
9837
+ hasSeparateFeeAsset = isEthereumDest && !isAssetEqual(assetFrom, findNativeAssetInfoOrThrow(getRelayChainOf(chain !== null && chain !== void 0 ? chain : exchangeChain)));
9683
9838
  internalOptions = _objectSpread2(_objectSpread2({}, options), {}, {
9684
9839
  version: version,
9685
9840
  paraIdTo: getParaId(destChain !== null && destChain !== void 0 ? destChain : exchangeChain)
@@ -9695,6 +9850,9 @@ var handleSwapExecuteTransfer = /*#__PURE__*/function () {
9695
9850
  location: assetFrom.location,
9696
9851
  amount: assetFrom.amount
9697
9852
  },
9853
+ feeAsset: feeAssetInfo ? {
9854
+ location: feeAssetInfo.location
9855
+ } : undefined,
9698
9856
  swapConfig: {
9699
9857
  currencyTo: currencyTo,
9700
9858
  exchangeChain: exchangeChain,
@@ -9702,13 +9860,18 @@ var handleSwapExecuteTransfer = /*#__PURE__*/function () {
9702
9860
  },
9703
9861
  useRootOrigin: true
9704
9862
  };
9863
+ FEE_ASSET_AMOUNT = 100;
9864
+ dummyOriginFee = feeAssetInfo ? parseUnits(FEE_ASSET_AMOUNT.toString(), feeAssetInfo.decimals) : 0n;
9705
9865
  fees = {
9866
+ originFee: dummyOriginFee,
9706
9867
  originReserveFee: MIN_FEE,
9707
9868
  exchangeFee: 0n,
9708
9869
  destReserveFee: MIN_FEE
9709
9870
  };
9710
9871
  totalFeesPre = calculateTotalFees(chain, fees);
9711
- validateAmount(assetFrom.amount, totalFeesPre);
9872
+ if (!hasSeparateFeeAsset) {
9873
+ validateAmount(assetFrom.amount, totalFeesPre);
9874
+ }
9712
9875
  // First dry run with dummy fees to extract actual fees
9713
9876
  _context3.n = 2;
9714
9877
  return createXcmAndCall(_objectSpread2(_objectSpread2({}, internalOptions), {}, {
@@ -9734,19 +9897,24 @@ var handleSwapExecuteTransfer = /*#__PURE__*/function () {
9734
9897
  throw new AmountTooLowError("Asset amount is too low to cover the fees, please increase the amount.");
9735
9898
  case 4:
9736
9899
  exchangeHopIndex = findExchangeHopIndex(chain, firstDryRunResult, exchangeChain, destChain);
9737
- extractedFees = extractFeesFromDryRun(chain, firstDryRunResult, exchangeHopIndex, destChain, false);
9900
+ extractedFees = extractFeesFromDryRun(chain, firstDryRunResult, exchangeHopIndex, destChain, false); // Set originFee from dry run origin fee (padded), same as handleExecuteTransfer
9901
+ extractedFees.originFee = feeAssetInfo && firstDryRunResult.origin.success ? padValueBy(firstDryRunResult.origin.fee, FEE_PADDING_PERCENTAGE) : 0n;
9738
9902
  if (extractedFees.exchangeFee === 0n) {
9739
9903
  // We set the exchange fee to non-zero value to prevent creating dummy tx
9740
9904
  extractedFees.exchangeFee = MIN_FEE;
9741
9905
  }
9742
9906
  totalFees = calculateTotalFees(chain, extractedFees);
9743
- validateAmount(assetFrom.amount, totalFees);
9907
+ if (!hasSeparateFeeAsset) {
9908
+ validateAmount(assetFrom.amount, totalFees);
9909
+ }
9744
9910
  updatedAssetTo = assetTo;
9745
9911
  if (!chain) {
9746
9912
  _context3.n = 6;
9747
9913
  break;
9748
9914
  }
9749
- amountAvailableForSwap = assetFrom.amount - totalFees;
9915
+ // When fees are paid from a separate asset (e.g. DOT for Ethereum),
9916
+ // the full main asset amount is available for the swap
9917
+ amountAvailableForSwap = hasSeparateFeeAsset ? assetFrom.amount : assetFrom.amount - totalFees;
9750
9918
  _context3.n = 5;
9751
9919
  return calculateMinAmountOut(amountAvailableForSwap);
9752
9920
  case 5:
@@ -11141,11 +11309,11 @@ var Hydration = /*#__PURE__*/function (_Chain) {
11141
11309
  key: "transferPolkadotXCM",
11142
11310
  value: function () {
11143
11311
  var _transferPolkadotXCM = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(input) {
11144
- var api, destination, feeAsset, asset, overriddenAsset, isMoonbeamWhAsset, isNativeAsset, isNativeFeeAsset, _t;
11312
+ var destination, asset, isMoonbeamWhAsset;
11145
11313
  return _regenerator().w(function (_context) {
11146
11314
  while (1) switch (_context.n) {
11147
11315
  case 0:
11148
- api = input.api, destination = input.destination, feeAsset = input.feeAssetInfo, asset = input.assetInfo, overriddenAsset = input.overriddenAsset;
11316
+ destination = input.destination, asset = input.assetInfo;
11149
11317
  if (!(destination === 'Ethereum')) {
11150
11318
  _context.n = 1;
11151
11319
  break;
@@ -11159,28 +11327,6 @@ var Hydration = /*#__PURE__*/function (_Chain) {
11159
11327
  }
11160
11328
  return _context.a(2, this.transferMoonbeamWhAsset(input));
11161
11329
  case 2:
11162
- if (!feeAsset) {
11163
- _context.n = 5;
11164
- break;
11165
- }
11166
- if (!overriddenAsset) {
11167
- _context.n = 3;
11168
- break;
11169
- }
11170
- throw new InvalidCurrencyError('Cannot use overridden assets with XCM execute');
11171
- case 3:
11172
- isNativeAsset = isSymbolMatch(asset.symbol, this.getNativeAssetSymbol());
11173
- isNativeFeeAsset = isSymbolMatch(feeAsset.symbol, this.getNativeAssetSymbol());
11174
- if (!(!isNativeAsset || !isNativeFeeAsset)) {
11175
- _context.n = 5;
11176
- break;
11177
- }
11178
- _t = api;
11179
- _context.n = 4;
11180
- return handleExecuteTransfer(input);
11181
- case 4:
11182
- return _context.a(2, _t.deserializeExtrinsics.call(_t, _context.v));
11183
- case 5:
11184
11330
  return _context.a(2, transferPolkadotXcm(input));
11185
11331
  }
11186
11332
  }, _callee, this);
@@ -12296,7 +12442,7 @@ var Moonbeam = /*#__PURE__*/function (_Chain) {
12296
12442
  }, {
12297
12443
  key: "transferLocalNonNativeAsset",
12298
12444
  value: function transferLocalNonNativeAsset(_options) {
12299
- throw new ScenarioNotSupportedError("".concat(this.chain, " local transfers are temporarily disabled"));
12445
+ throw new ScenarioNotSupportedError("".concat(this.chain, " local transfers are supported only from EVM Builder"));
12300
12446
  }
12301
12447
  }, {
12302
12448
  key: "getBalanceForeign",
@@ -13862,12 +14008,14 @@ var FungiblesPallet = /*#__PURE__*/function (_AssetsPallet) {
13862
14008
 
13863
14009
  var SIZE = 32;
13864
14010
  var BALANCE_SLOT = 0;
13865
- var calculateMappingSlot = function calculateMappingSlot(key) {
14011
+ var BALANCE_SLOT_WORMHOLE = 5;
14012
+ var calculateMappingSlot = function calculateMappingSlot(key, assetId) {
13866
14013
  var normalizedKey = getAddress(key);
13867
14014
  var keyPadded = pad(normalizedKey, {
13868
14015
  size: SIZE
13869
14016
  });
13870
- var slotHex = pad(toHex(BALANCE_SLOT), {
14017
+ var resolvedSlot = assetId !== null && assetId !== void 0 && assetId.startsWith('0x') ? BALANCE_SLOT_WORMHOLE : BALANCE_SLOT;
14018
+ var slotHex = pad(toHex(resolvedSlot), {
13871
14019
  size: SIZE
13872
14020
  });
13873
14021
  var encoded = concat([keyPadded, slotHex]);
@@ -13889,7 +14037,7 @@ var SystemPallet = /*#__PURE__*/function (_BaseAssetsPallet) {
13889
14037
  case 0:
13890
14038
  assertHasId(assetInfo);
13891
14039
  contractAddr = formatAssetIdToERC20(assetInfo.assetId);
13892
- slot = calculateMappingSlot(address);
14040
+ slot = calculateMappingSlot(address, assetInfo.assetId);
13893
14041
  amountEncoded = pad(toHex(assetInfo.amount + balance), {
13894
14042
  size: SIZE
13895
14043
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paraspell/sdk-core",
3
- "version": "12.7.0",
3
+ "version": "12.8.0",
4
4
  "description": "SDK core for ParaSpell XCM/XCMP tool for developers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,9 +26,9 @@
26
26
  "@noble/hashes": "^2.0.1",
27
27
  "@scure/base": "^2.0.0",
28
28
  "viem": "2.45.0",
29
- "@paraspell/pallets": "12.7.0",
30
- "@paraspell/sdk-common": "12.7.0",
31
- "@paraspell/assets": "12.7.0"
29
+ "@paraspell/pallets": "12.8.0",
30
+ "@paraspell/sdk-common": "12.8.0",
31
+ "@paraspell/assets": "12.8.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@babel/plugin-syntax-import-attributes": "^7.28.6",