-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathbaseClient.ts
More file actions
200 lines (173 loc) · 5.94 KB
/
baseClient.ts
File metadata and controls
200 lines (173 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/**
* This file was automatically generated by @cosmwasm/ts-codegen@latest.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
*/
import { StdFee, Coin } from '@interchainjs/types';
import { DirectSigner } from '@interchainjs/cosmos';
import { getSmartContractState } from 'interchainjs/cosmwasm/wasm/v1/query.rpc.func';
import { executeContract } from 'interchainjs/cosmwasm/wasm/v1/tx.rpc.func';
import { QuerySmartContractStateRequest, QuerySmartContractStateResponse } from 'interchainjs/cosmwasm/wasm/v1/query';
import { MsgExecuteContract } from 'interchainjs/cosmwasm/wasm/v1/tx';
import { Chain } from '@chain-registry/v2-types';
// Encoding utility functions
const fromUint8Array = <T>(uint8Array: Uint8Array): T => {
const text = new TextDecoder().decode(uint8Array);
return JSON.parse(text);
};
const toUint8Array = (obj: any): Uint8Array => {
const text = JSON.stringify(obj);
return new TextEncoder().encode(text);
};
// Chain registry configuration
// The amount under gasPrice represents gas price per unit
export interface ChainConfig {
chain?: Chain;
gasPrice?: {
denom: string;
amount: string;
};
}
// Gas fee calculation utilities
export const calculateGasFromChain = (chain: Chain, gasAmount: string): StdFee => {
try {
const feeTokens = chain.fees?.feeTokens;
if (feeTokens && feeTokens.length > 0) {
const primaryToken = feeTokens[0];
// v2 chain-registry uses camelCase: averageGasPrice, lowGasPrice, fixedMinGasPrice
const gasPrice = primaryToken.averageGasPrice || primaryToken.lowGasPrice || primaryToken.fixedMinGasPrice || 0.025;
const gasAmountNum = parseInt(gasAmount);
const feeAmount = Math.ceil(gasAmountNum * gasPrice).toString();
return {
amount: [{
denom: primaryToken.denom,
amount: feeAmount
}],
gas: gasAmount
};
}
} catch (error) {
console.warn('Failed to calculate gas from chain registry:', error);
}
// Fallback to default
return { amount: [], gas: gasAmount };
};
// Default gas amount - users can easily change this
export let DEFAULT_GAS_AMOUNT = '200000';
// Allow users to set their preferred default gas amount
export const setDefaultGasAmount = (gasAmount: string): void => {
DEFAULT_GAS_AMOUNT = gasAmount;
};
// Get current default gas amount
export const getDefaultGasAmount = (): string => DEFAULT_GAS_AMOUNT;
export const getAutoGasFee = (chainConfig?: ChainConfig): StdFee => {
const gasAmount = DEFAULT_GAS_AMOUNT;
if (chainConfig?.chain) {
return calculateGasFromChain(chainConfig.chain, gasAmount);
}
if (chainConfig?.gasPrice) {
const gasAmountNum = parseInt(gasAmount);
const gasPriceNum = parseFloat(chainConfig.gasPrice.amount);
const feeAmount = Math.ceil(gasAmountNum * gasPriceNum).toString();
return {
amount: [{
denom: chainConfig.gasPrice.denom,
amount: feeAmount
}],
gas: gasAmount
};
}
// Fallback: no fee tokens, just gas amount
return { amount: [], gas: gasAmount };
};
// InterchainJS interfaces for CosmWasm clients
export interface ICosmWasmClient {
queryContractSmart(contractAddr: string, query: any): Promise<any>;
}
export interface ISigningCosmWasmClient extends ICosmWasmClient {
execute(
sender: string,
contractAddress: string,
msg: any,
fee?: number | StdFee | "auto",
memo?: string,
funds?: Coin[],
chainConfig?: ChainConfig
): Promise<any>;
}
export interface ISigningClient {
signAndBroadcast(
signerAddress: string,
messages: any[],
fee: number | StdFee | "auto",
memo?: string
): Promise<any>;
}
// Helper functions to create InterchainJS clients
export function getCosmWasmClient(rpcEndpoint: string): ICosmWasmClient {
return {
queryContractSmart: async (contractAddr: string, query: any) => {
// Create the request object
const request: QuerySmartContractStateRequest = {
address: contractAddr,
queryData: toUint8Array(query)
};
// Execute the query using InterchainJS
const response: QuerySmartContractStateResponse = await getSmartContractState(rpcEndpoint, request);
// Parse and return the result
return fromUint8Array(response.data);
},
};
}
export function getSigningCosmWasmClient(signingClient: DirectSigner, rpcEndpoint?: string): ISigningCosmWasmClient {
return {
queryContractSmart: async (contractAddr: string, query: any) => {
if (!rpcEndpoint) {
throw new Error('rpcEndpoint is required for queryContractSmart in signing client');
}
const request: QuerySmartContractStateRequest = {
address: contractAddr,
queryData: toUint8Array(query)
};
const response: QuerySmartContractStateResponse = await getSmartContractState(rpcEndpoint, request);
return fromUint8Array(response.data);
},
execute: async (
sender: string,
contractAddress: string,
msg: any,
fee?: number | StdFee | "auto",
memo?: string,
funds?: Coin[],
chainConfig?: ChainConfig
) => {
// Handle fee conversion
let finalFee: StdFee;
if (typeof fee === 'number') {
finalFee = { amount: [], gas: fee.toString() };
} else if (fee === 'auto') {
finalFee = getAutoGasFee(chainConfig);
} else if (fee) {
finalFee = fee;
} else {
finalFee = getAutoGasFee(chainConfig);
}
// Create the message object
const message: MsgExecuteContract = {
sender,
contract: contractAddress,
msg: toUint8Array(msg),
funds: funds || []
};
// Execute the transaction using InterchainJS
const result = await executeContract(
signingClient as any,
sender,
message,
finalFee,
memo || ''
);
return result;
},
};
}