Skip to content

Commit 4a65069

Browse files
committed
manual route axelar transceiver
1 parent 3aef7d5 commit 4a65069

File tree

11 files changed

+348
-261
lines changed

11 files changed

+348
-261
lines changed

evm/ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"test": "jest --config ./jest.config.ts"
4545
},
4646
"dependencies": {
47-
"@axelar-network/axelarjs-sdk": "^0.17.4",
47+
"@axelar-network/axelarjs-sdk": "^0.17.6-alpha.2",
4848
"@wormhole-foundation/sdk-definitions-ntt": "1.0.0",
4949
"ethers": "^6.5.1"
5050
},

evm/ts/src/axelar.ts

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import { Chain, Network } from "@wormhole-foundation/sdk-base";
22
import {
3-
AxelarQueryAPI,
3+
AxelarGMPRecoveryAPI,
44
Environment,
5-
EvmChain,
5+
GMPStatusResponse,
66
} from "@axelar-network/axelarjs-sdk";
77

8-
export const axelarChains: Partial<Record<Chain, EvmChain>> = {
9-
Sepolia: EvmChain.SEPOLIA,
10-
// Monad: EvmChain.MONAD,
11-
Ethereum: EvmChain.ETHEREUM,
8+
// See: https://github.com/axelarnetwork/axelarjs-sdk/blob/main/src/constants/EvmChain.ts
9+
export const axelarChains: Partial<Record<Chain, string>> = {
10+
Ethereum: "ethereum",
11+
Monad: "monad",
12+
Sepolia: "ethereum-sepolia",
1213
// add more as needed
1314
};
1415

1516
export async function getAxelarGasFee(
1617
network: Network,
1718
sourceChain: Chain,
1819
destinationChain: Chain,
19-
gasLimit: bigint
20+
gasLimit: bigint,
21+
timeoutMs = 10000
2022
): Promise<bigint> {
21-
const api = new AxelarQueryAPI({
22-
environment:
23-
network === "Mainnet" ? Environment.MAINNET : Environment.TESTNET,
24-
});
23+
const baseUrl =
24+
network === "Mainnet"
25+
? "https://api.axelarscan.io/gmp/estimateGasFee"
26+
: "https://testnet.api.axelarscan.io/gmp/estimateGasFee";
2527

2628
const axelarSourceChain = axelarChains[sourceChain];
2729
if (!axelarSourceChain) {
@@ -33,15 +35,54 @@ export async function getAxelarGasFee(
3335
throw new Error(`Unsupported destination chain: ${destinationChain}`);
3436
}
3537

36-
const response = await api.estimateGasFee(
37-
axelarSourceChain,
38-
axelarDestinationChain,
39-
gasLimit
40-
);
38+
const controller = new AbortController();
39+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
40+
41+
try {
42+
const response = await fetch(baseUrl, {
43+
method: "POST",
44+
headers: {
45+
"Content-Type": "application/json",
46+
},
47+
body: JSON.stringify({
48+
sourceChain: axelarSourceChain,
49+
destinationChain: axelarDestinationChain,
50+
sourceTokenAddress: "0x0000000000000000000000000000000000000000",
51+
gasMultiplier: "auto",
52+
gasLimit: gasLimit.toString(),
53+
}),
54+
signal: controller.signal,
55+
});
4156

42-
if (typeof response !== "string") {
43-
throw new Error(`Unexpected response type: ${typeof response}`);
57+
if (!response.ok) {
58+
const errorText = await response.text();
59+
throw new Error(
60+
`Failed to estimate gas fee: ${response.status} ${errorText}`
61+
);
62+
}
63+
64+
const result = await response.json();
65+
66+
return BigInt(result);
67+
} finally {
68+
clearTimeout(timeoutId);
4469
}
70+
}
71+
72+
export async function getAxelarTransactionStatus(
73+
network: Network,
74+
txHash: string
75+
): Promise<GMPStatusResponse> {
76+
const api = new AxelarGMPRecoveryAPI({
77+
environment:
78+
network === "Mainnet" ? Environment.MAINNET : Environment.TESTNET,
79+
});
80+
const status = await api.queryTransactionStatus(txHash);
81+
return status;
82+
}
4583

46-
return BigInt(response);
84+
export function getAxelarExplorerUrl(network: Network, txHash: string): string {
85+
return network === "Mainnet"
86+
? `https://axelarscan.io/gmp/${txHash}`
87+
: `https://testnet.axelarscan.io/gmp/${txHash}`;
4788
}

evm/ts/src/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import "@wormhole-foundation/sdk-definitions-ntt";
99
registerProtocol(_platform, "Ntt", EvmNtt);
1010
registerProtocol(_platform, "NttWithExecutor", EvmNttWithExecutor);
1111
registerProtocol(_platform, "MultiTokenNtt", EvmMultiTokenNtt);
12-
registerProtocol(_platform, "MultiTokenNttWithExecutor", EvmMultiTokenNttWithExecutor);
12+
registerProtocol(
13+
_platform,
14+
"MultiTokenNttWithExecutor",
15+
EvmMultiTokenNttWithExecutor
16+
);
1317

1418
export * as ethers_contracts from "./ethers-contracts/index.js";
1519
export * from "./ntt.js";
1620
export * from "./nttWithExecutor.js";
1721
export * from "./multiTokenNtt.js";
1822
export * from "./multiTokenNttWithExecutor.js";
19-
export * from "./trimmedAmount.js";
20-
23+
export * from "./axelar.js";

evm/ts/src/multiTokenNtt.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ import {
2929
import "@wormhole-foundation/sdk-evm-core";
3030

3131
import {
32+
decodeTrimmedAmount,
33+
EncodedTrimmedAmount,
3234
MultiTokenNtt,
3335
Ntt,
3436
TrimmedAmount,
37+
untrim,
3538
} from "@wormhole-foundation/sdk-definitions-ntt";
3639
import { Contract, ethers, Interface, type Provider } from "ethers";
3740
import {
@@ -40,11 +43,6 @@ import {
4043
MultiTokenNttBindings,
4144
MultiTokenNttManagerBindings,
4245
} from "./multiTokenNttBindings.js";
43-
import {
44-
decodeTrimmedAmount,
45-
EncodedTrimmedAmount,
46-
untrim,
47-
} from "./trimmedAmount.js";
4846
import { getAxelarGasFee } from "./axelar.js";
4947
import { encoding } from "@wormhole-foundation/sdk-base";
5048

@@ -213,6 +211,17 @@ export class EvmMultiTokenNtt<N extends Network, C extends EvmChains>
213211
);
214212
}
215213

214+
async transceiverAttestedToMessage(
215+
fromChain: Chain,
216+
transceiverMessage: MultiTokenNtt.Message,
217+
index: number
218+
): Promise<boolean> {
219+
return await this.gmpManager.transceiverAttestedToMessage(
220+
MultiTokenNtt.messageDigest(fromChain, transceiverMessage),
221+
index
222+
);
223+
}
224+
216225
private async getTransceiverType(
217226
transceiverAddress: string
218227
): Promise<string> {
@@ -254,12 +263,12 @@ export class EvmMultiTokenNtt<N extends Network, C extends EvmChains>
254263
dstChain,
255264
gasLimit
256265
);
266+
console.log(`Fetched axelar gas fee: ${gasFee} wei`);
257267
} catch (e) {
258268
// If we fail to fetch the gas fee, then use 0 as a fallback.
259269
// The Axelar relay should fail and the track() method will
260-
// surface a RelayFailedError that a UI can use to inform the user.
261-
// We don't want to block the transfer entirely just because
262-
// of a failure to fetch the gas fee.
270+
// surface a RelayFailedError. We don't want to fail the entire
271+
// transfer just because we couldn't fetch the gas fee quote.
263272
gasFee = 100000000000000n; // 0.0001 ETH
264273
console.error(`Failed to fetch axelar gas fee: ${e}`);
265274
}

evm/ts/src/ntt.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ import {
3030
import "@wormhole-foundation/sdk-evm-core";
3131

3232
import {
33+
decodeTrimmedAmount,
34+
EncodedTrimmedAmount,
3335
EvmNttTransceiver,
3436
Ntt,
3537
NttTransceiver,
38+
untrim,
3639
WormholeNttTransceiver,
3740
} from "@wormhole-foundation/sdk-definitions-ntt";
3841
import { Contract, type Provider, type TransactionRequest } from "ethers";
@@ -42,12 +45,6 @@ import {
4245
NttTransceiverBindings,
4346
loadAbiVersion,
4447
} from "./bindings.js";
45-
import {
46-
decodeTrimmedAmount,
47-
EncodedTrimmedAmount,
48-
TrimmedAmount,
49-
untrim,
50-
} from "./trimmedAmount.js";
5148

5249
export class EvmNttWormholeTranceiver<N extends Network, C extends EvmChains>
5350
implements
@@ -438,7 +435,9 @@ export class EvmNtt<N extends Network, C extends EvmChains>
438435
return abiVersion;
439436
} catch (e) {
440437
console.error(
441-
`Failed to get NTT_MANAGER_VERSION from contract ${contracts.ntt?.manager} on ${(await provider.getNetwork()).name}`
438+
`Failed to get NTT_MANAGER_VERSION from contract ${
439+
contracts.ntt?.manager
440+
} on ${(await provider.getNetwork()).name}`
442441
);
443442
throw e;
444443
}
@@ -590,7 +589,7 @@ export class EvmNtt<N extends Network, C extends EvmChains>
590589
const encoded: EncodedTrimmedAmount = (
591590
await this.manager.getOutboundLimitParams()
592591
).limit;
593-
const trimmedAmount: TrimmedAmount = decodeTrimmedAmount(encoded);
592+
const trimmedAmount = decodeTrimmedAmount(encoded);
594593
const tokenDecimals = await this.getTokenDecimals();
595594

596595
return untrim(trimmedAmount, tokenDecimals);
@@ -609,7 +608,7 @@ export class EvmNtt<N extends Network, C extends EvmChains>
609608
const encoded: EncodedTrimmedAmount = (
610609
await this.manager.getInboundLimitParams(toChainId(fromChain))
611610
).limit;
612-
const trimmedAmount: TrimmedAmount = decodeTrimmedAmount(encoded);
611+
const trimmedAmount = decodeTrimmedAmount(encoded);
613612
const tokenDecimals = await this.getTokenDecimals();
614613

615614
return untrim(trimmedAmount, tokenDecimals);

0 commit comments

Comments
 (0)