@defuse-protocol/intents-sdk 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +452 -345
- package/dist/index.cjs +472 -66
- package/dist/index.d.cts +18 -10
- package/dist/index.d.ts +18 -10
- package/dist/index.js +477 -55
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/sdk.ts
|
|
2
2
|
import {
|
|
3
|
-
assert as
|
|
3
|
+
assert as assert13,
|
|
4
4
|
PUBLIC_NEAR_RPC_URLS,
|
|
5
|
-
RETRY_CONFIGS as
|
|
6
|
-
configsByEnvironment as
|
|
5
|
+
RETRY_CONFIGS as RETRY_CONFIGS3,
|
|
6
|
+
configsByEnvironment as configsByEnvironment8,
|
|
7
7
|
nearFailoverRpcProvider,
|
|
8
|
-
solverRelay as
|
|
8
|
+
solverRelay as solverRelay6
|
|
9
9
|
} from "@defuse-protocol/internal-utils";
|
|
10
10
|
import hotOmniSdk from "@hot-labs/omni-sdk";
|
|
11
11
|
import { stringify } from "viem";
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
var RouteEnum = {
|
|
25
25
|
HotBridge: "hot_bridge",
|
|
26
26
|
PoaBridge: "poa_bridge",
|
|
27
|
+
OmniBridge: "omni_bridge",
|
|
27
28
|
NearWithdrawal: "near_withdrawal",
|
|
28
29
|
VirtualChain: "virtual_chain",
|
|
29
30
|
InternalTransfer: "internal_transfer"
|
|
@@ -184,6 +185,7 @@ import {
|
|
|
184
185
|
var BridgeNameEnum = {
|
|
185
186
|
Hot: "hot",
|
|
186
187
|
Poa: "poa",
|
|
188
|
+
Omni: "omni",
|
|
187
189
|
None: null
|
|
188
190
|
};
|
|
189
191
|
|
|
@@ -191,22 +193,22 @@ var BridgeNameEnum = {
|
|
|
191
193
|
import { assert as assert3 } from "@defuse-protocol/internal-utils";
|
|
192
194
|
var Chains = {
|
|
193
195
|
Bitcoin: "bip122:000000000019d6689c085ae165831e93",
|
|
196
|
+
Zcash: "bip122:00040fe8ec8471911baa1db1266ea15d",
|
|
197
|
+
Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82",
|
|
194
198
|
Ethereum: "eip155:1",
|
|
195
|
-
|
|
196
|
-
Arbitrum: "eip155:42161",
|
|
199
|
+
Optimism: "eip155:10",
|
|
197
200
|
BNB: "eip155:56",
|
|
201
|
+
Gnosis: "eip155:100",
|
|
198
202
|
Polygon: "eip155:137",
|
|
203
|
+
Base: "eip155:8453",
|
|
204
|
+
Arbitrum: "eip155:42161",
|
|
205
|
+
Avalanche: "eip155:43114",
|
|
206
|
+
Berachain: "eip155:80085",
|
|
199
207
|
Near: "near:mainnet",
|
|
200
208
|
Solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
201
209
|
Tron: "tron:27Lqcw",
|
|
202
|
-
Gnosis: "eip155:100",
|
|
203
210
|
XRPL: "xrpl:0",
|
|
204
|
-
Dogecoin: "bip122:1a91e3dace36e2be3bf030a65679fe82",
|
|
205
|
-
Zcash: "zcash:0",
|
|
206
|
-
Berachain: "eip155:80085",
|
|
207
211
|
TON: "tvm:-239",
|
|
208
|
-
Optimism: "eip155:10",
|
|
209
|
-
Avalanche: "eip155:43114",
|
|
210
212
|
Sui: "sui:mainnet",
|
|
211
213
|
Aptos: "aptos:mainnet",
|
|
212
214
|
Stellar: "stellar:pubnet",
|
|
@@ -710,7 +712,7 @@ var HotBridge = class {
|
|
|
710
712
|
}
|
|
711
713
|
if (typeof status === "string") {
|
|
712
714
|
return {
|
|
713
|
-
hash: "chain" in args.routeConfig ? formatTxHash(status, args.routeConfig.chain) : status
|
|
715
|
+
hash: "chain" in args.routeConfig && args.routeConfig.chain !== void 0 ? formatTxHash(status, args.routeConfig.chain) : status
|
|
714
716
|
};
|
|
715
717
|
}
|
|
716
718
|
throw new HotWithdrawalPendingError(args.tx.hash, args.index);
|
|
@@ -770,19 +772,428 @@ var IntentsBridge = class {
|
|
|
770
772
|
}
|
|
771
773
|
};
|
|
772
774
|
|
|
773
|
-
// src/bridges/
|
|
775
|
+
// src/bridges/omni-bridge/omni-bridge.ts
|
|
774
776
|
import {
|
|
775
|
-
assert as
|
|
777
|
+
assert as assert9,
|
|
778
|
+
RETRY_CONFIGS as RETRY_CONFIGS2,
|
|
776
779
|
configsByEnvironment as configsByEnvironment4,
|
|
777
|
-
|
|
780
|
+
getNearNep141MinStorageBalance as getNearNep141MinStorageBalance3,
|
|
781
|
+
getNearNep141StorageBalance as getNearNep141StorageBalance3,
|
|
782
|
+
solverRelay as solverRelay4,
|
|
778
783
|
utils as utils7
|
|
779
784
|
} from "@defuse-protocol/internal-utils";
|
|
780
785
|
import TTLCache from "@isaacs/ttlcache";
|
|
786
|
+
import { retry as retry2 } from "@lifeomic/attempt";
|
|
787
|
+
import {
|
|
788
|
+
ChainKind as ChainKind2,
|
|
789
|
+
OmniBridgeAPI,
|
|
790
|
+
getBridgedToken,
|
|
791
|
+
getChain,
|
|
792
|
+
isEvmChain,
|
|
793
|
+
omniAddress as omniAddress2,
|
|
794
|
+
parseOriginChain
|
|
795
|
+
} from "omni-bridge-sdk";
|
|
781
796
|
|
|
782
|
-
// src/bridges/
|
|
783
|
-
import {
|
|
797
|
+
// src/bridges/omni-bridge/error.ts
|
|
798
|
+
import { BaseError as BaseError3 } from "@defuse-protocol/internal-utils";
|
|
799
|
+
var OmniTransferNotFoundError = class extends BaseError3 {
|
|
800
|
+
constructor(txHash) {
|
|
801
|
+
super("Omni transfer with given hash is not found in the relayer.", {
|
|
802
|
+
metaMessages: [`OriginTxHash: ${txHash}`],
|
|
803
|
+
name: "OmniTransferNotFoundError"
|
|
804
|
+
});
|
|
805
|
+
this.txHash = txHash;
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
var OmniTransferDestinationChainHashNotFoundError = class extends BaseError3 {
|
|
809
|
+
constructor(txHash, destinationChain) {
|
|
810
|
+
super("Relayer did not return destination chain hash for a transfer.", {
|
|
811
|
+
metaMessages: [
|
|
812
|
+
`OriginTxHash: ${txHash}`,
|
|
813
|
+
`DestinationChain: ${destinationChain}`
|
|
814
|
+
],
|
|
815
|
+
name: "OmniTransferDestinationChainHashNotFoundError"
|
|
816
|
+
});
|
|
817
|
+
this.txHash = txHash;
|
|
818
|
+
this.destinationChain = destinationChain;
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
var TokenNotSupportedByOmniRelayerError = class extends BaseError3 {
|
|
822
|
+
constructor(token) {
|
|
823
|
+
super(`Omni Relayer doesn't accept fee in the transferred token ${token}`, {
|
|
824
|
+
metaMessages: [`Token: ${token}`],
|
|
825
|
+
name: "TokenNotSupportedByOmniRelayerError"
|
|
826
|
+
});
|
|
827
|
+
this.token = token;
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
var TokenNotFoundInDestinationChainError = class extends BaseError3 {
|
|
831
|
+
constructor(token, chainKind) {
|
|
832
|
+
super(
|
|
833
|
+
`The token ${token} doesn't exist in destination network ${chainKind}`,
|
|
834
|
+
{
|
|
835
|
+
metaMessages: [`Token: ${token}`, `Destination Chain: ${chainKind}`],
|
|
836
|
+
name: "TokenNotFoundInDestinationChainError"
|
|
837
|
+
}
|
|
838
|
+
);
|
|
839
|
+
this.token = token;
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// src/bridges/omni-bridge/omni-bridge-constants.ts
|
|
844
|
+
var NEAR_NATIVE_ASSET_ID3 = "nep141:wrap.near";
|
|
845
|
+
var OMNI_BRIDGE_CONTRACT = "omni.bridge.near";
|
|
846
|
+
|
|
847
|
+
// src/bridges/omni-bridge/omni-bridge-utils.ts
|
|
848
|
+
import { assert as assert8, utils as utils6 } from "@defuse-protocol/internal-utils";
|
|
849
|
+
import { ChainKind, omniAddress } from "omni-bridge-sdk";
|
|
784
850
|
function createWithdrawIntentPrimitive3(params) {
|
|
785
|
-
const { contractId: tokenAccountId } = utils6.parseDefuseAssetId(
|
|
851
|
+
const { contractId: tokenAccountId, standard } = utils6.parseDefuseAssetId(
|
|
852
|
+
params.assetId
|
|
853
|
+
);
|
|
854
|
+
assert8(standard === "nep141", "Only NEP-141 is supported");
|
|
855
|
+
return {
|
|
856
|
+
intent: "ft_withdraw",
|
|
857
|
+
token: tokenAccountId,
|
|
858
|
+
receiver_id: OMNI_BRIDGE_CONTRACT,
|
|
859
|
+
amount: params.amount.toString(),
|
|
860
|
+
storage_deposit: params.storageDeposit > 0n ? params.storageDeposit.toString() : null,
|
|
861
|
+
msg: JSON.stringify({
|
|
862
|
+
recipient: omniAddress(
|
|
863
|
+
caip2ToChainKind(params.origin),
|
|
864
|
+
params.destinationAddress
|
|
865
|
+
),
|
|
866
|
+
fee: params.transferredTokenFee.toString(),
|
|
867
|
+
native_token_fee: "0"
|
|
868
|
+
})
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
function targetChainSupportedByOmniBridge(network) {
|
|
872
|
+
switch (network) {
|
|
873
|
+
case Chains.Ethereum:
|
|
874
|
+
return true;
|
|
875
|
+
case Chains.Base:
|
|
876
|
+
return true;
|
|
877
|
+
case Chains.Arbitrum:
|
|
878
|
+
return true;
|
|
879
|
+
case Chains.Solana:
|
|
880
|
+
return true;
|
|
881
|
+
case Chains.Bitcoin:
|
|
882
|
+
return true;
|
|
883
|
+
default:
|
|
884
|
+
return false;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function caip2ToChainKind(network) {
|
|
888
|
+
switch (network) {
|
|
889
|
+
case Chains.Ethereum:
|
|
890
|
+
return ChainKind.Eth;
|
|
891
|
+
case Chains.Base:
|
|
892
|
+
return ChainKind.Base;
|
|
893
|
+
case Chains.Arbitrum:
|
|
894
|
+
return ChainKind.Arb;
|
|
895
|
+
case Chains.Solana:
|
|
896
|
+
return ChainKind.Sol;
|
|
897
|
+
case Chains.Bitcoin:
|
|
898
|
+
return ChainKind.Btc;
|
|
899
|
+
default:
|
|
900
|
+
throw new Error(`Unsupported Omni network = ${network}`);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function chainKindToCaip2(network) {
|
|
904
|
+
switch (network) {
|
|
905
|
+
case ChainKind.Eth:
|
|
906
|
+
return Chains.Ethereum;
|
|
907
|
+
case ChainKind.Base:
|
|
908
|
+
return Chains.Base;
|
|
909
|
+
case ChainKind.Arb:
|
|
910
|
+
return Chains.Arbitrum;
|
|
911
|
+
case ChainKind.Sol:
|
|
912
|
+
return Chains.Solana;
|
|
913
|
+
case ChainKind.Btc:
|
|
914
|
+
return Chains.Bitcoin;
|
|
915
|
+
default:
|
|
916
|
+
throw new Error(`Unsupported Caip2 network = ${network}`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// src/bridges/omni-bridge/omni-bridge.ts
|
|
921
|
+
var _OmniBridge = class _OmniBridge {
|
|
922
|
+
// 86400000 - 1 day
|
|
923
|
+
constructor({
|
|
924
|
+
env,
|
|
925
|
+
nearProvider
|
|
926
|
+
}) {
|
|
927
|
+
this.storageDepositCache = new TTLCache({ ttl: 864e5 });
|
|
928
|
+
// TTL cache for supported tokens with 30-second TTL
|
|
929
|
+
this.supportedTokensCache = new TTLCache({ ttl: 864e5 });
|
|
930
|
+
// 86400000 - 1 day
|
|
931
|
+
this.destinationChainAddressCache = new TTLCache({ ttl: 864e5 });
|
|
932
|
+
this.env = env;
|
|
933
|
+
this.nearProvider = nearProvider;
|
|
934
|
+
this.omniBridgeAPI = new OmniBridgeAPI();
|
|
935
|
+
}
|
|
936
|
+
is(routeConfig) {
|
|
937
|
+
return routeConfig.route === RouteEnum.OmniBridge;
|
|
938
|
+
}
|
|
939
|
+
supports(params) {
|
|
940
|
+
try {
|
|
941
|
+
if (this.targetChainSpecified(params.routeConfig)) {
|
|
942
|
+
return targetChainSupportedByOmniBridge(params.routeConfig.chain);
|
|
943
|
+
}
|
|
944
|
+
return this.parseAssetId(params.assetId) !== null;
|
|
945
|
+
} catch {
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
targetChainSpecified(routeConfig) {
|
|
950
|
+
return Boolean(
|
|
951
|
+
routeConfig?.route && routeConfig.route === RouteEnum.OmniBridge && routeConfig.chain
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
parseAssetId(assetId) {
|
|
955
|
+
const parsed = utils7.parseDefuseAssetId(assetId);
|
|
956
|
+
if (parsed.standard !== "nep141") return null;
|
|
957
|
+
const chain = parseOriginChain(parsed.contractId);
|
|
958
|
+
if (chain === null) return null;
|
|
959
|
+
return Object.assign(parsed, {
|
|
960
|
+
blockchain: chainKindToCaip2(chain),
|
|
961
|
+
bridgeName: BridgeNameEnum.Omni,
|
|
962
|
+
address: parsed.contractId
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
async tokenSupported(assetId, routeConfig) {
|
|
966
|
+
const parsed = utils7.parseDefuseAssetId(assetId);
|
|
967
|
+
if (parsed.standard !== "nep141") return null;
|
|
968
|
+
if (this.targetChainSpecified(routeConfig)) {
|
|
969
|
+
const tokenOnDestinationNetwork = await this.getCachedDestinationTokenAddress(
|
|
970
|
+
parsed.contractId,
|
|
971
|
+
routeConfig.chain
|
|
972
|
+
);
|
|
973
|
+
if (tokenOnDestinationNetwork === null) {
|
|
974
|
+
throw new TokenNotFoundInDestinationChainError(
|
|
975
|
+
assetId,
|
|
976
|
+
routeConfig.chain
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
return Object.assign(parsed, {
|
|
980
|
+
blockchain: routeConfig.chain,
|
|
981
|
+
bridgeName: BridgeNameEnum.Omni,
|
|
982
|
+
address: parsed.contractId
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
const chain = parseOriginChain(parsed.contractId);
|
|
986
|
+
if (chain === null) return null;
|
|
987
|
+
return Object.assign(parsed, {
|
|
988
|
+
blockchain: chainKindToCaip2(chain),
|
|
989
|
+
bridgeName: BridgeNameEnum.Omni,
|
|
990
|
+
address: parsed.contractId
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
async createWithdrawalIntents(args) {
|
|
994
|
+
const assetInfo = await this.tokenSupported(
|
|
995
|
+
args.withdrawalParams.assetId,
|
|
996
|
+
args.withdrawalParams.routeConfig
|
|
997
|
+
);
|
|
998
|
+
assert9(
|
|
999
|
+
assetInfo !== null,
|
|
1000
|
+
`Asset ${args.withdrawalParams.assetId} is not supported`
|
|
1001
|
+
);
|
|
1002
|
+
const intents = [];
|
|
1003
|
+
if (args.feeEstimation.quote !== null) {
|
|
1004
|
+
intents.push({
|
|
1005
|
+
intent: "token_diff",
|
|
1006
|
+
diff: {
|
|
1007
|
+
[args.feeEstimation.quote.defuse_asset_identifier_in]: `-${args.feeEstimation.quote.amount_in}`,
|
|
1008
|
+
[args.feeEstimation.quote.defuse_asset_identifier_out]: args.feeEstimation.quote.amount_out
|
|
1009
|
+
},
|
|
1010
|
+
referral: args.referral
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
const intent = createWithdrawIntentPrimitive3({
|
|
1014
|
+
assetId: args.withdrawalParams.assetId,
|
|
1015
|
+
destinationAddress: args.withdrawalParams.destinationAddress,
|
|
1016
|
+
amount: args.withdrawalParams.amount + args.feeEstimation.amount,
|
|
1017
|
+
origin: assetInfo.blockchain,
|
|
1018
|
+
storageDeposit: args.feeEstimation.quote ? BigInt(args.feeEstimation.quote.amount_out) : 0n,
|
|
1019
|
+
transferredTokenFee: args.feeEstimation.amount
|
|
1020
|
+
});
|
|
1021
|
+
intents.push(intent);
|
|
1022
|
+
return Promise.resolve(intents);
|
|
1023
|
+
}
|
|
1024
|
+
async validateWithdrawal(args) {
|
|
1025
|
+
const assetInfo = await this.tokenSupported(args.assetId, args.routeConfig);
|
|
1026
|
+
assert9(assetInfo !== null, `Asset ${args.assetId} is not supported`);
|
|
1027
|
+
const supportedTokens = await this.getCachedSupportedTokens();
|
|
1028
|
+
if (!supportedTokens[assetInfo.contractId]) {
|
|
1029
|
+
throw new TokenNotSupportedByOmniRelayerError(args.assetId);
|
|
1030
|
+
}
|
|
1031
|
+
assert9(
|
|
1032
|
+
args.feeEstimation.amount > 0n,
|
|
1033
|
+
`Fee must be greater than zero. Current fee is ${args.feeEstimation.amount}.`
|
|
1034
|
+
);
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
async estimateWithdrawalFee(args) {
|
|
1038
|
+
const assetInfo = await this.tokenSupported(
|
|
1039
|
+
args.withdrawalParams.assetId,
|
|
1040
|
+
args.withdrawalParams.routeConfig
|
|
1041
|
+
);
|
|
1042
|
+
assert9(
|
|
1043
|
+
assetInfo !== null,
|
|
1044
|
+
`Asset ${args.withdrawalParams.assetId} is not supported`
|
|
1045
|
+
);
|
|
1046
|
+
const fee = await this.omniBridgeAPI.getFee(
|
|
1047
|
+
omniAddress2(ChainKind2.Near, configsByEnvironment4[this.env].contractID),
|
|
1048
|
+
omniAddress2(
|
|
1049
|
+
caip2ToChainKind(assetInfo.blockchain),
|
|
1050
|
+
args.withdrawalParams.destinationAddress
|
|
1051
|
+
),
|
|
1052
|
+
omniAddress2(ChainKind2.Near, assetInfo.contractId)
|
|
1053
|
+
);
|
|
1054
|
+
assert9(
|
|
1055
|
+
fee.transferred_token_fee !== null,
|
|
1056
|
+
`Asset ${args.withdrawalParams.assetId} is not supported by the relayer`
|
|
1057
|
+
);
|
|
1058
|
+
const [minStorageBalance, userStorageBalance] = await this.getCachedStorageDepositValue(assetInfo.contractId);
|
|
1059
|
+
if (minStorageBalance <= userStorageBalance) {
|
|
1060
|
+
return {
|
|
1061
|
+
amount: BigInt(fee.transferred_token_fee),
|
|
1062
|
+
quote: null
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
const feeAmount = minStorageBalance - userStorageBalance;
|
|
1066
|
+
const feeQuote = await solverRelay4.getQuote({
|
|
1067
|
+
quoteParams: {
|
|
1068
|
+
defuse_asset_identifier_in: args.withdrawalParams.assetId,
|
|
1069
|
+
defuse_asset_identifier_out: NEAR_NATIVE_ASSET_ID3,
|
|
1070
|
+
exact_amount_out: feeAmount.toString(),
|
|
1071
|
+
wait_ms: args.quoteOptions?.waitMs
|
|
1072
|
+
},
|
|
1073
|
+
config: {
|
|
1074
|
+
baseURL: configsByEnvironment4[this.env].solverRelayBaseURL,
|
|
1075
|
+
logBalanceSufficient: false,
|
|
1076
|
+
logger: args.logger
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
return {
|
|
1080
|
+
amount: BigInt(fee.transferred_token_fee) + BigInt(feeQuote.amount_in),
|
|
1081
|
+
quote: feeQuote
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
async waitForWithdrawalCompletion(args) {
|
|
1085
|
+
return retry2(
|
|
1086
|
+
async () => {
|
|
1087
|
+
if (args.signal?.aborted) {
|
|
1088
|
+
throw args.signal.reason;
|
|
1089
|
+
}
|
|
1090
|
+
const transfer = (await this.omniBridgeAPI.findOmniTransfers({
|
|
1091
|
+
transaction_id: args.tx.hash,
|
|
1092
|
+
offset: args.index,
|
|
1093
|
+
limit: 1
|
|
1094
|
+
}))[0];
|
|
1095
|
+
if (!transfer) throw new OmniTransferNotFoundError(args.tx.hash);
|
|
1096
|
+
const destinationChain = getChain(
|
|
1097
|
+
transfer.transfer_message.recipient
|
|
1098
|
+
);
|
|
1099
|
+
let txHash = null;
|
|
1100
|
+
if (isEvmChain(destinationChain)) {
|
|
1101
|
+
txHash = transfer.finalised?.EVMLog?.transaction_hash;
|
|
1102
|
+
} else if (destinationChain === ChainKind2.Sol) {
|
|
1103
|
+
txHash = transfer.finalised?.Solana?.signature;
|
|
1104
|
+
} else {
|
|
1105
|
+
return { hash: null };
|
|
1106
|
+
}
|
|
1107
|
+
if (!txHash)
|
|
1108
|
+
throw new OmniTransferDestinationChainHashNotFoundError(
|
|
1109
|
+
args.tx.hash,
|
|
1110
|
+
ChainKind2[destinationChain].toLowerCase()
|
|
1111
|
+
);
|
|
1112
|
+
return { hash: txHash };
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
...args.retryOptions ?? RETRY_CONFIGS2.TWO_MINS_GRADUAL,
|
|
1116
|
+
handleError: (err, ctx) => {
|
|
1117
|
+
if (err instanceof OmniTransferNotFoundError || err === args.signal?.reason) {
|
|
1118
|
+
ctx.abort();
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Gets storage deposit for a token to avoid frequent RPC calls.
|
|
1126
|
+
* Cache expires after one day using TTL cache.
|
|
1127
|
+
*/
|
|
1128
|
+
async getCachedStorageDepositValue(contractId) {
|
|
1129
|
+
const cached = this.storageDepositCache.get(contractId);
|
|
1130
|
+
if (cached != null) {
|
|
1131
|
+
return cached;
|
|
1132
|
+
}
|
|
1133
|
+
const data = await Promise.all([
|
|
1134
|
+
getNearNep141MinStorageBalance3({
|
|
1135
|
+
contractId,
|
|
1136
|
+
nearProvider: this.nearProvider
|
|
1137
|
+
}),
|
|
1138
|
+
getNearNep141StorageBalance3({
|
|
1139
|
+
contractId,
|
|
1140
|
+
accountId: OMNI_BRIDGE_CONTRACT,
|
|
1141
|
+
nearProvider: this.nearProvider
|
|
1142
|
+
})
|
|
1143
|
+
]);
|
|
1144
|
+
this.storageDepositCache.set(contractId, data);
|
|
1145
|
+
return data;
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Gets cached tokens supported by the omni relayer, tokens not listed there can't be transferred.
|
|
1149
|
+
* Cache expires after one day using TTL cache.
|
|
1150
|
+
*/
|
|
1151
|
+
async getCachedSupportedTokens() {
|
|
1152
|
+
const cached = this.supportedTokensCache.get(
|
|
1153
|
+
_OmniBridge.SUPPORTED_TOKENS_CACHE_KEY
|
|
1154
|
+
);
|
|
1155
|
+
if (cached != null) {
|
|
1156
|
+
return cached;
|
|
1157
|
+
}
|
|
1158
|
+
const data = await this.omniBridgeAPI.getAllowlistedTokens();
|
|
1159
|
+
this.supportedTokensCache.set(_OmniBridge.SUPPORTED_TOKENS_CACHE_KEY, data);
|
|
1160
|
+
return data;
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Gets cached token address on destination chain.
|
|
1164
|
+
* Cache expires after one day using TTL cache.
|
|
1165
|
+
*/
|
|
1166
|
+
async getCachedDestinationTokenAddress(contractId, chain) {
|
|
1167
|
+
const key = `${chain}:${contractId}`;
|
|
1168
|
+
const cached = this.destinationChainAddressCache.get(key);
|
|
1169
|
+
if (cached != null) {
|
|
1170
|
+
return cached;
|
|
1171
|
+
}
|
|
1172
|
+
const tokenOnDestinationNetwork = await getBridgedToken(
|
|
1173
|
+
omniAddress2(ChainKind2.Near, contractId),
|
|
1174
|
+
caip2ToChainKind(chain)
|
|
1175
|
+
);
|
|
1176
|
+
this.destinationChainAddressCache.set(key, tokenOnDestinationNetwork);
|
|
1177
|
+
return tokenOnDestinationNetwork;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
// 86400000 - 1 day
|
|
1181
|
+
_OmniBridge.SUPPORTED_TOKENS_CACHE_KEY = "SUPPORTED_TOKENS_CACHE_KEY";
|
|
1182
|
+
var OmniBridge = _OmniBridge;
|
|
1183
|
+
|
|
1184
|
+
// src/bridges/poa-bridge/poa-bridge.ts
|
|
1185
|
+
import {
|
|
1186
|
+
assert as assert10,
|
|
1187
|
+
configsByEnvironment as configsByEnvironment5,
|
|
1188
|
+
poaBridge,
|
|
1189
|
+
utils as utils9
|
|
1190
|
+
} from "@defuse-protocol/internal-utils";
|
|
1191
|
+
import TTLCache2 from "@isaacs/ttlcache";
|
|
1192
|
+
|
|
1193
|
+
// src/bridges/poa-bridge/poa-bridge-utils.ts
|
|
1194
|
+
import { utils as utils8 } from "@defuse-protocol/internal-utils";
|
|
1195
|
+
function createWithdrawIntentPrimitive4(params) {
|
|
1196
|
+
const { contractId: tokenAccountId } = utils8.parseDefuseAssetId(
|
|
786
1197
|
params.assetId
|
|
787
1198
|
);
|
|
788
1199
|
return {
|
|
@@ -857,7 +1268,7 @@ function contractIdToCaip2(contractId) {
|
|
|
857
1268
|
var PoaBridge = class {
|
|
858
1269
|
constructor({ env }) {
|
|
859
1270
|
// TTL cache for supported tokens with 30-second TTL
|
|
860
|
-
this.supportedTokensCache = new
|
|
1271
|
+
this.supportedTokensCache = new TTLCache2({ ttl: 30 * 1e3 });
|
|
861
1272
|
this.env = env;
|
|
862
1273
|
}
|
|
863
1274
|
is(routeConfig) {
|
|
@@ -875,9 +1286,9 @@ var PoaBridge = class {
|
|
|
875
1286
|
}
|
|
876
1287
|
}
|
|
877
1288
|
parseAssetId(assetId) {
|
|
878
|
-
const parsed =
|
|
1289
|
+
const parsed = utils9.parseDefuseAssetId(assetId);
|
|
879
1290
|
if (parsed.contractId.endsWith(
|
|
880
|
-
`.${
|
|
1291
|
+
`.${configsByEnvironment5[this.env].poaTokenFactoryContractID}`
|
|
881
1292
|
)) {
|
|
882
1293
|
return Object.assign(parsed, {
|
|
883
1294
|
blockchain: contractIdToCaip2(parsed.contractId),
|
|
@@ -889,7 +1300,7 @@ var PoaBridge = class {
|
|
|
889
1300
|
return null;
|
|
890
1301
|
}
|
|
891
1302
|
createWithdrawalIntents(args) {
|
|
892
|
-
const intent =
|
|
1303
|
+
const intent = createWithdrawIntentPrimitive4({
|
|
893
1304
|
...args.withdrawalParams,
|
|
894
1305
|
amount: args.withdrawalParams.amount + args.feeEstimation.amount,
|
|
895
1306
|
destinationMemo: args.withdrawalParams.destinationMemo
|
|
@@ -904,7 +1315,7 @@ var PoaBridge = class {
|
|
|
904
1315
|
*/
|
|
905
1316
|
async validateWithdrawal(args) {
|
|
906
1317
|
const assetInfo = this.parseAssetId(args.assetId);
|
|
907
|
-
|
|
1318
|
+
assert10(assetInfo != null, "Asset is not supported");
|
|
908
1319
|
const { tokens } = await this.getCachedSupportedTokens(
|
|
909
1320
|
[toPoaNetwork(assetInfo.blockchain)],
|
|
910
1321
|
args.logger
|
|
@@ -925,16 +1336,16 @@ var PoaBridge = class {
|
|
|
925
1336
|
}
|
|
926
1337
|
async estimateWithdrawalFee(args) {
|
|
927
1338
|
const assetInfo = this.parseAssetId(args.withdrawalParams.assetId);
|
|
928
|
-
|
|
1339
|
+
assert10(assetInfo != null, "Asset is not supported");
|
|
929
1340
|
const estimation = await poaBridge.httpClient.getWithdrawalEstimate(
|
|
930
1341
|
{
|
|
931
|
-
token:
|
|
1342
|
+
token: utils9.getTokenAccountId(args.withdrawalParams.assetId),
|
|
932
1343
|
address: args.withdrawalParams.destinationAddress,
|
|
933
1344
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
934
1345
|
chain: toPoaNetwork(assetInfo.blockchain)
|
|
935
1346
|
},
|
|
936
1347
|
{
|
|
937
|
-
baseURL:
|
|
1348
|
+
baseURL: configsByEnvironment5[this.env].poaBridgeBaseURL,
|
|
938
1349
|
logger: args.logger
|
|
939
1350
|
}
|
|
940
1351
|
);
|
|
@@ -949,7 +1360,7 @@ var PoaBridge = class {
|
|
|
949
1360
|
index: args.index,
|
|
950
1361
|
signal: args.signal ?? new AbortController().signal,
|
|
951
1362
|
retryOptions: args.retryOptions,
|
|
952
|
-
baseURL:
|
|
1363
|
+
baseURL: configsByEnvironment5[this.env].poaBridgeBaseURL,
|
|
953
1364
|
logger: args.logger
|
|
954
1365
|
});
|
|
955
1366
|
return { hash: withdrawalStatus.destinationTxHash };
|
|
@@ -967,7 +1378,7 @@ var PoaBridge = class {
|
|
|
967
1378
|
const data = await poaBridge.httpClient.getSupportedTokens(
|
|
968
1379
|
{ chains },
|
|
969
1380
|
{
|
|
970
|
-
baseURL:
|
|
1381
|
+
baseURL: configsByEnvironment5[this.env].poaBridgeBaseURL,
|
|
971
1382
|
logger
|
|
972
1383
|
}
|
|
973
1384
|
);
|
|
@@ -990,7 +1401,7 @@ var PUBLIC_STELLAR_RPC_URLS = {
|
|
|
990
1401
|
|
|
991
1402
|
// src/intents/intent-executer-impl/intent-executer.ts
|
|
992
1403
|
import {
|
|
993
|
-
configsByEnvironment as
|
|
1404
|
+
configsByEnvironment as configsByEnvironment6
|
|
994
1405
|
} from "@defuse-protocol/internal-utils";
|
|
995
1406
|
|
|
996
1407
|
// ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_u64.js
|
|
@@ -1372,7 +1783,7 @@ var IntentExecuter = class {
|
|
|
1372
1783
|
relayParams: relayParamsFactory,
|
|
1373
1784
|
...intentParams
|
|
1374
1785
|
}) {
|
|
1375
|
-
const verifyingContract =
|
|
1786
|
+
const verifyingContract = configsByEnvironment6[this.env].contractID;
|
|
1376
1787
|
let intentPayload = defaultIntentPayloadFactory({
|
|
1377
1788
|
verifying_contract: verifyingContract,
|
|
1378
1789
|
...intentParams
|
|
@@ -1423,8 +1834,8 @@ async function mergeIntentPayloads(basePayload, intentPayloadFactory) {
|
|
|
1423
1834
|
|
|
1424
1835
|
// src/intents/intent-relayer-impl/intent-relayer-public.ts
|
|
1425
1836
|
import {
|
|
1426
|
-
configsByEnvironment as
|
|
1427
|
-
solverRelay as
|
|
1837
|
+
configsByEnvironment as configsByEnvironment7,
|
|
1838
|
+
solverRelay as solverRelay5
|
|
1428
1839
|
} from "@defuse-protocol/internal-utils";
|
|
1429
1840
|
var IntentRelayerPublic = class {
|
|
1430
1841
|
constructor({ env }) {
|
|
@@ -1447,13 +1858,13 @@ var IntentRelayerPublic = class {
|
|
|
1447
1858
|
multiPayloads,
|
|
1448
1859
|
quoteHashes
|
|
1449
1860
|
}, ctx = {}) {
|
|
1450
|
-
const a = await
|
|
1861
|
+
const a = await solverRelay5.publishIntents(
|
|
1451
1862
|
{
|
|
1452
1863
|
quote_hashes: quoteHashes,
|
|
1453
1864
|
signed_datas: multiPayloads
|
|
1454
1865
|
},
|
|
1455
1866
|
{
|
|
1456
|
-
baseURL:
|
|
1867
|
+
baseURL: configsByEnvironment7[this.env].solverRelayBaseURL,
|
|
1457
1868
|
logger: ctx.logger
|
|
1458
1869
|
}
|
|
1459
1870
|
);
|
|
@@ -1463,10 +1874,10 @@ var IntentRelayerPublic = class {
|
|
|
1463
1874
|
throw a.unwrapErr();
|
|
1464
1875
|
}
|
|
1465
1876
|
async waitForSettlement(ticket, ctx = {}) {
|
|
1466
|
-
const result = await
|
|
1877
|
+
const result = await solverRelay5.waitForIntentSettlement({
|
|
1467
1878
|
intentHash: ticket,
|
|
1468
1879
|
signal: new AbortController().signal,
|
|
1469
|
-
baseURL:
|
|
1880
|
+
baseURL: configsByEnvironment7[this.env].solverRelayBaseURL,
|
|
1470
1881
|
logger: ctx.logger
|
|
1471
1882
|
});
|
|
1472
1883
|
return {
|
|
@@ -1474,7 +1885,7 @@ var IntentRelayerPublic = class {
|
|
|
1474
1885
|
hash: result.txHash,
|
|
1475
1886
|
// Usually relayer's account id is the verifying contract (`intents.near`),
|
|
1476
1887
|
// but it is not set in stone and may change in the future.
|
|
1477
|
-
accountId:
|
|
1888
|
+
accountId: configsByEnvironment7[this.env].contractID
|
|
1478
1889
|
}
|
|
1479
1890
|
};
|
|
1480
1891
|
}
|
|
@@ -1488,14 +1899,14 @@ var noopIntentSigner = {
|
|
|
1488
1899
|
};
|
|
1489
1900
|
|
|
1490
1901
|
// src/lib/array.ts
|
|
1491
|
-
import { assert as
|
|
1902
|
+
import { assert as assert11 } from "@defuse-protocol/internal-utils";
|
|
1492
1903
|
function zip(arr1, arr2) {
|
|
1493
|
-
|
|
1904
|
+
assert11(arr1.length === arr2.length, "Arrays must have the same length");
|
|
1494
1905
|
return arr1.map((v, i) => [v, arr2[i]]);
|
|
1495
1906
|
}
|
|
1496
1907
|
|
|
1497
1908
|
// src/lib/configure-rpc-config.ts
|
|
1498
|
-
import { assert as
|
|
1909
|
+
import { assert as assert12 } from "@defuse-protocol/internal-utils";
|
|
1499
1910
|
|
|
1500
1911
|
// src/lib/object.ts
|
|
1501
1912
|
function pick(obj, keys) {
|
|
@@ -1519,7 +1930,7 @@ function configureEvmRpcUrls(defaultRpcUrls, userRpcUrls, supportedChains) {
|
|
|
1519
1930
|
).map(([caip2, urls]) => [getEIP155ChainId(caip2), urls])
|
|
1520
1931
|
);
|
|
1521
1932
|
for (const [chainId, urls] of Object.entries(evmRpcUrls)) {
|
|
1522
|
-
|
|
1933
|
+
assert12(
|
|
1523
1934
|
urls.length > 0,
|
|
1524
1935
|
`EVM RPC URLs for chain ${chainId} are not provided`
|
|
1525
1936
|
);
|
|
@@ -1533,7 +1944,7 @@ function configureStellarRpcUrls(defaultRpcUrls, userRpcUrls) {
|
|
|
1533
1944
|
userRpcUrls?.[Chains.Stellar] ?? {}
|
|
1534
1945
|
);
|
|
1535
1946
|
for (const [key, value] of Object.entries(stellarRpcUrls)) {
|
|
1536
|
-
|
|
1947
|
+
assert12(value.length > 0, `Stellar RPC URL for ${key} is not provided`);
|
|
1537
1948
|
}
|
|
1538
1949
|
return stellarRpcUrls;
|
|
1539
1950
|
}
|
|
@@ -1545,6 +1956,9 @@ function createInternalTransferRoute() {
|
|
|
1545
1956
|
function createNearWithdrawalRoute(msg) {
|
|
1546
1957
|
return { route: RouteEnum.NearWithdrawal, msg };
|
|
1547
1958
|
}
|
|
1959
|
+
function createOmniWithdrawalRoute() {
|
|
1960
|
+
return { route: RouteEnum.OmniBridge };
|
|
1961
|
+
}
|
|
1548
1962
|
function createVirtualChainRoute(auroraEngineContractId, proxyTokenContractId) {
|
|
1549
1963
|
return {
|
|
1550
1964
|
route: RouteEnum.VirtualChain,
|
|
@@ -1585,6 +1999,8 @@ function determineRouteConfig(sdk, withdrawalParams) {
|
|
|
1585
1999
|
route: RouteEnum.PoaBridge,
|
|
1586
2000
|
chain: parseAssetId.blockchain
|
|
1587
2001
|
};
|
|
2002
|
+
case BridgeNameEnum.Omni:
|
|
2003
|
+
return createOmniWithdrawalRoute();
|
|
1588
2004
|
case BridgeNameEnum.None:
|
|
1589
2005
|
return createNearWithdrawalRoute();
|
|
1590
2006
|
default:
|
|
@@ -1599,7 +2015,7 @@ var IntentsSDK = class {
|
|
|
1599
2015
|
this.env = args.env ?? "production";
|
|
1600
2016
|
this.referral = args.referral;
|
|
1601
2017
|
const nearRpcUrls = args.rpc?.[Chains.Near] ?? PUBLIC_NEAR_RPC_URLS;
|
|
1602
|
-
|
|
2018
|
+
assert13(nearRpcUrls.length > 0, "NEAR RPC URLs are not provided");
|
|
1603
2019
|
const nearProvider = nearFailoverRpcProvider({ urls: nearRpcUrls });
|
|
1604
2020
|
const stellarRpcUrls = configureStellarRpcUrls(
|
|
1605
2021
|
PUBLIC_STELLAR_RPC_URLS,
|
|
@@ -1632,6 +2048,10 @@ var IntentsSDK = class {
|
|
|
1632
2048
|
}
|
|
1633
2049
|
})
|
|
1634
2050
|
}),
|
|
2051
|
+
new OmniBridge({
|
|
2052
|
+
env: this.env,
|
|
2053
|
+
nearProvider
|
|
2054
|
+
}),
|
|
1635
2055
|
new DirectBridge({
|
|
1636
2056
|
env: this.env,
|
|
1637
2057
|
nearProvider
|
|
@@ -1651,6 +2071,8 @@ var IntentsSDK = class {
|
|
|
1651
2071
|
assetId: args.withdrawalParams.assetId,
|
|
1652
2072
|
amount: actualAmount,
|
|
1653
2073
|
destinationAddress: args.withdrawalParams.destinationAddress,
|
|
2074
|
+
feeEstimation: args.feeEstimation,
|
|
2075
|
+
routeConfig: args.withdrawalParams.routeConfig,
|
|
1654
2076
|
logger: args.logger
|
|
1655
2077
|
});
|
|
1656
2078
|
return bridge.createWithdrawalIntents({
|
|
@@ -1720,7 +2142,7 @@ var IntentsSDK = class {
|
|
|
1720
2142
|
const routeConfig = determineRouteConfig(this, w);
|
|
1721
2143
|
const route = routeConfig.route;
|
|
1722
2144
|
const index = indexes.get(route);
|
|
1723
|
-
|
|
2145
|
+
assert13(index != null, "Index is not found for route");
|
|
1724
2146
|
indexes.set(route, index + 1);
|
|
1725
2147
|
return {
|
|
1726
2148
|
routeConfig,
|
|
@@ -1754,7 +2176,7 @@ var IntentsSDK = class {
|
|
|
1754
2176
|
if (Array.isArray(args.withdrawalParams)) {
|
|
1755
2177
|
return result;
|
|
1756
2178
|
}
|
|
1757
|
-
|
|
2179
|
+
assert13(result.length === 1, "Unexpected result length");
|
|
1758
2180
|
return result[0];
|
|
1759
2181
|
}
|
|
1760
2182
|
parseAssetId(assetId) {
|
|
@@ -1768,7 +2190,7 @@ var IntentsSDK = class {
|
|
|
1768
2190
|
}
|
|
1769
2191
|
async signAndSendIntent(args) {
|
|
1770
2192
|
const intentSigner = args.signer ?? this.intentSigner;
|
|
1771
|
-
|
|
2193
|
+
assert13(intentSigner != null, "Intent signer is not provided");
|
|
1772
2194
|
const intentExecuter = new IntentExecuter({
|
|
1773
2195
|
env: this.env,
|
|
1774
2196
|
logger: args.logger,
|
|
@@ -1837,12 +2259,12 @@ var IntentsSDK = class {
|
|
|
1837
2259
|
intentHash,
|
|
1838
2260
|
logger
|
|
1839
2261
|
}) {
|
|
1840
|
-
return
|
|
2262
|
+
return solverRelay6.getStatus(
|
|
1841
2263
|
{
|
|
1842
2264
|
intent_hash: intentHash
|
|
1843
2265
|
},
|
|
1844
2266
|
{
|
|
1845
|
-
baseURL:
|
|
2267
|
+
baseURL: configsByEnvironment8[this.env].solverRelayBaseURL,
|
|
1846
2268
|
logger
|
|
1847
2269
|
}
|
|
1848
2270
|
);
|
|
@@ -1873,7 +2295,7 @@ var IntentsSDK = class {
|
|
|
1873
2295
|
withdrawalParams,
|
|
1874
2296
|
intentTx,
|
|
1875
2297
|
logger: args.logger,
|
|
1876
|
-
retryOptions:
|
|
2298
|
+
retryOptions: RETRY_CONFIGS3.FIVE_MINS_STEADY
|
|
1877
2299
|
});
|
|
1878
2300
|
if (!Array.isArray(args.withdrawalParams)) {
|
|
1879
2301
|
return {
|
|
@@ -1952,14 +2374,14 @@ var IntentSignerNearKeypair = class extends IntentSignerNEP413 {
|
|
|
1952
2374
|
};
|
|
1953
2375
|
|
|
1954
2376
|
// src/intents/intent-signer-impl/intent-signer-viem.ts
|
|
1955
|
-
import { utils as
|
|
2377
|
+
import { utils as utils10 } from "@defuse-protocol/internal-utils";
|
|
1956
2378
|
var IntentSignerViem = class {
|
|
1957
2379
|
constructor(account) {
|
|
1958
2380
|
this.account = account;
|
|
1959
2381
|
}
|
|
1960
2382
|
async signIntent(intent) {
|
|
1961
2383
|
const payload = JSON.stringify({
|
|
1962
|
-
signer_id: intent.signer_id ??
|
|
2384
|
+
signer_id: intent.signer_id ?? utils10.authHandleToIntentsUserId({
|
|
1963
2385
|
identifier: this.account.address,
|
|
1964
2386
|
method: "evm"
|
|
1965
2387
|
}),
|
|
@@ -1977,7 +2399,7 @@ var IntentSignerViem = class {
|
|
|
1977
2399
|
return {
|
|
1978
2400
|
standard: "erc191",
|
|
1979
2401
|
payload,
|
|
1980
|
-
signature:
|
|
2402
|
+
signature: utils10.transformERC191Signature(signature)
|
|
1981
2403
|
};
|
|
1982
2404
|
}
|
|
1983
2405
|
};
|
|
@@ -1995,7 +2417,7 @@ function createIntentSignerViem(config) {
|
|
|
1995
2417
|
|
|
1996
2418
|
// index.ts
|
|
1997
2419
|
import {
|
|
1998
|
-
BaseError as
|
|
2420
|
+
BaseError as BaseError4
|
|
1999
2421
|
} from "@defuse-protocol/internal-utils";
|
|
2000
2422
|
import {
|
|
2001
2423
|
PoaWithdrawalInvariantError,
|
|
@@ -2017,7 +2439,7 @@ import {
|
|
|
2017
2439
|
} from "@defuse-protocol/internal-utils";
|
|
2018
2440
|
export {
|
|
2019
2441
|
AssertionError,
|
|
2020
|
-
|
|
2442
|
+
BaseError4 as BaseError,
|
|
2021
2443
|
BridgeNameEnum,
|
|
2022
2444
|
Chains,
|
|
2023
2445
|
FeeExceedsAmountError,
|