1
- import { AxelarQueryAPI , Environment } from '@axelar-network/axelarjs-sdk ' ;
1
+ import { buildGMPPayload } from '@agoric/orchestration/src/utils/gmp.js ' ;
2
2
import { ethers } from 'ethers' ;
3
- import { fromHex } from '@cosmjs/encoding' ;
4
- import { encodeAbiParameters } from 'viem' ;
5
- import createKeccakHash from 'keccak' ;
6
- import { encode } from '@metamask/abi-utils' ;
7
3
8
4
const GAS_ESTIMATOR_CONTRACT = '0x0010F196F5CD0314f68FF665b8c8eD93531112Fe' ;
5
+ const COMMAND_ID =
6
+ '0xddea323337dfb73c82df7393d76b2f38835d5c2bda0123c47d1a2fc06527d19f' ;
9
7
10
- const hexToBytes = ( hex : string ) => fromHex ( hex . slice ( 2 ) ) ;
8
+ const bytesToHex = ( bytes : number [ ] ) : string =>
9
+ '0x' + bytes . map ( n => n . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ;
11
10
12
- const uint8ArrayToHex = ( uint8Array : Uint8Array ) : string => {
13
- return `0x${ Array . from ( uint8Array )
14
- . map ( byte => byte . toString ( 16 ) . padStart ( 2 , '0' ) )
15
- . join ( '' ) } `;
11
+ const vars = {
12
+ mainnet : {
13
+ AXELAR_GAS_API : 'https://api.axelarscan.io/gmp/estimateGasFee' ,
14
+ RPC : {
15
+ Avalanche : 'https://api.avax.network/ext/bc/C/rpc' ,
16
+ } ,
17
+ } ,
18
+ testnet : {
19
+ AXELAR_GAS_API : 'https://testnet.api.axelarscan.io/gmp/estimateGasFee' ,
20
+ RPC : {
21
+ Avalanche : 'https://api.avax-test.network/ext/bc/C/rpc' ,
22
+ } ,
23
+ } ,
16
24
} ;
17
25
18
- const pack = (
19
- functionSignature : string ,
20
- paramTypes : Array < string > ,
21
- params : Array < string > ,
22
- ) : `0x${string } ` => {
23
- const functionHash = createKeccakHash ( 'keccak256' )
24
- . update ( functionSignature )
25
- . digest ( ) ;
26
- return uint8ArrayToHex (
27
- Uint8Array . from ( [
28
- ...Uint8Array . from ( functionHash . subarray ( 0 , 4 ) ) ,
29
- ...encode ( paramTypes , params ) ,
30
- ] ) ,
31
- ) as `0x${string } `;
32
- } ;
26
+ const params = vars [ 'testnet' ] ;
33
27
34
- const generatePayload = (
35
- id : string ,
36
- contractAddress : string ,
37
- payment : string ,
38
- ) => {
39
- const abiEncodedContractCalls = [
28
+ const generatePayload = ( contractAddress : string , payment : string ) => {
29
+ const contractCalls = [
40
30
{
41
31
target : '0x5425890298aed601595a70AB815c96711a31Bc65' as `0x${string } `,
42
- data : pack (
43
- 'approve(address,uint256)' ,
44
- [ 'address' , 'uint256' ] ,
45
- [ '0x8B9b2AF4afB389b4a70A474dfD4AdCD4a302bb40' , payment ] ,
46
- ) ,
32
+ functionSignature : 'approve(address,uint256)' ,
33
+ args : [ '0x8B9b2AF4afB389b4a70A474dfD4AdCD4a302bb40' , payment ] ,
47
34
} ,
48
35
{
49
36
target : '0x8B9b2AF4afB389b4a70A474dfD4AdCD4a302bb40' as `0x${string } `,
50
- data : pack (
51
- 'supply(address,uint256,address,uint16)' ,
52
- [ 'address' , 'uint256' , 'address' , 'uint16' ] ,
53
- [
54
- '0x5425890298aed601595a70AB815c96711a31Bc65' ,
55
- payment ,
56
- contractAddress ,
57
- '0' ,
58
- ] ,
59
- ) ,
37
+ functionSignature : 'supply(address,uint256,address,uint16)' ,
38
+ args : [
39
+ '0x5425890298aed601595a70AB815c96711a31Bc65' ,
40
+ payment ,
41
+ contractAddress ,
42
+ '0' ,
43
+ ] ,
60
44
} ,
61
45
] ;
62
- const payload = encodeAbiParameters (
63
- [
64
- {
65
- type : 'tuple' ,
66
- name : 'callMessage' ,
67
- components : [
68
- { name : 'id' , type : 'string' } ,
69
- {
70
- name : 'calls' ,
71
- type : 'tuple[]' ,
72
- components : [
73
- { name : 'target' , type : 'address' } ,
74
- { name : 'data' , type : 'bytes' } ,
75
- ] ,
76
- } ,
77
- ] ,
78
- } ,
79
- ] ,
80
- [ { id, calls : abiEncodedContractCalls } ] ,
81
- ) ;
82
- return payload ;
46
+ return bytesToHex ( buildGMPPayload ( contractCalls ) ) ;
83
47
} ;
84
48
85
49
const queryAxelarGasAPI = async (
@@ -88,18 +52,26 @@ const queryAxelarGasAPI = async (
88
52
gasLimit : bigint ,
89
53
gasToken ?: string ,
90
54
) => {
91
- const api = new AxelarQueryAPI ( { environment : Environment . TESTNET } ) ;
92
-
93
- const GAS_MULTIPLIER = 1 ;
94
-
95
- const feeQuote = await api . estimateGasFee (
96
- sourceChain ,
97
- destinationChain , // mayber lowercase?
98
- gasLimit ,
99
- GAS_MULTIPLIER ,
100
- gasToken ,
101
- ) ;
102
- return feeQuote ;
55
+ const response = await fetch ( params . AXELAR_GAS_API , {
56
+ method : 'POST' ,
57
+ headers : {
58
+ 'Content-Type' : 'application/json' ,
59
+ } ,
60
+ body : JSON . stringify ( {
61
+ sourceChain,
62
+ destinationChain,
63
+ gasLimit : gasLimit . toString ( ) ,
64
+ sourceTokenSymbol : gasToken ,
65
+ gasMultiplier : '1' ,
66
+ } ) ,
67
+ } ) ;
68
+
69
+ if ( ! response . ok ) {
70
+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
71
+ }
72
+
73
+ const data = await response . json ( ) ;
74
+ return data ;
103
75
} ;
104
76
105
77
export const getReturnFeeEstimate = async ( chainName : string ) => {
@@ -151,22 +123,15 @@ const createGasEstimator = (rpcUrl: string, contractAddress: string) => {
151
123
} ;
152
124
153
125
const estimateContracts = {
154
- Avalanche : createGasEstimator (
155
- 'https://api.avax-test.network/ext/bc/C/rpc' ,
156
- GAS_ESTIMATOR_CONTRACT ,
157
- ) ,
126
+ Avalanche : createGasEstimator ( params . RPC . Avalanche , GAS_ESTIMATOR_CONTRACT ) ,
158
127
} ;
159
128
160
129
export const getWalletEstimate = async ( chainName : string ) => {
161
130
const estimateContract = estimateContracts [ chainName ] ;
162
- const txId = 'tx0' ;
163
- const payloadString = generatePayload ( txId , GAS_ESTIMATOR_CONTRACT , '5' ) ;
164
- const payload = Array . from ( hexToBytes ( payloadString ) ) ;
165
- const commandId =
166
- '0xddea323337dfb73c82df7393d76b2f38835d5c2bda0123c47d1a2fc06527d19f' ;
131
+ const payload = generatePayload ( GAS_ESTIMATOR_CONTRACT , '5' ) ;
167
132
168
- const gasLimit = await estimateContract ( 'executeFactory ' , [
169
- commandId ,
133
+ const gasLimit = await estimateContract ( 'executeWallet ' , [
134
+ COMMAND_ID ,
170
135
'agoric' ,
171
136
'agoric1owner' ,
172
137
payload ,
@@ -180,15 +145,14 @@ export const getWalletEstimate = async (chainName: string) => {
180
145
) ) as string ;
181
146
return BigInt ( estimate ) ;
182
147
} ;
148
+
183
149
export const getFactoryContractEstimate = async ( chainName : string ) => {
184
150
const estimateContract = estimateContracts [ chainName ] ;
185
151
186
152
const payload = ethers . AbiCoder . defaultAbiCoder ( ) . encode ( [ 'uint256' ] , [ 0 ] ) ;
187
- const commandId =
188
- '0xddea323337dfb73c82df7393d76b2f38835d5c2bda0123c47d1a2fc06527d19f' ;
189
153
190
154
const gasLimit = await estimateContract ( 'executeFactory' , [
191
- commandId ,
155
+ COMMAND_ID ,
192
156
'agoric' ,
193
157
'agoric1owner' ,
194
158
payload ,
0 commit comments