Skip to content

Commit 2a9da85

Browse files
Gefei HouGefei Hou
authored andcommitted
Interchainjs migration
1 parent bbc6af3 commit 2a9da85

File tree

126 files changed

+3331
-9980
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+3331
-9980
lines changed

README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,44 @@ Typescript types and interfaces are generated in separate files so they can be i
126126
| `types.aliasExecuteMsg` | generate a type alias based on the contract name |
127127
| `types.aliasEntryPoints` | generate type aliases for the entry points based on the contract name |
128128

129+
### BaseClient
130+
The `baseClient.ts` will be generated as dependency for most files. It includes the base client for interchainjs.
131+
132+
#### Gas Configuration
133+
134+
The generated client provides flexible gas fee configuration options to handle different blockchain networks and fee settings.
135+
136+
##### Default Gas Settings
137+
138+
By default, the client uses a gas limit of `200000` for all transactions. You can customize this behavior through the `setDefaultGasAmount`.
139+
140+
##### ChainConfig Options
141+
142+
The `ChainConfig` interface supports two approaches for gas configuration:
143+
144+
1. Chain Registry Integration (Recommended)
145+
146+
When you provide chain information, the client automatically fetches gas prices from the chain registry:
147+
148+
```typescript
149+
import { useChain } from '@interchain-kit/react';
150+
151+
const { chain } = useChain('osmosistestnet');
152+
const chainConfig: ChainConfig = { chain: chain };
153+
```
154+
155+
2. Manual Gas Price Configuration
156+
You can explicitly set gas prices for more control:
157+
158+
```typescript
159+
const chainConfig: ChainConfig = {
160+
gasPrice: {
161+
denom: 'uosmo',
162+
amount: '0.025'
163+
}
164+
};
165+
```
166+
129167
### Client
130168

131169
The `client` plugin will generate TS client classes for your contracts. This option generates a `QueryClient` for queries as well as a `Client` for queries and mutations.
@@ -173,7 +211,7 @@ Generate [recoil](https://recoiljs.org/) bindings for your contracts with the `r
173211

174212
### Message Composer
175213

176-
Generate pure message objects with the proper `utf8` encoding and `typeUrl` configured that you can broadcast yourself via `cosmjs` with the `message-composer` command.
214+
Generate pure message objects with the proper `utf8` encoding and `typeUrl` configured that you can broadcast yourself via `interchainjs` with the `message-composer` command.
177215

178216
[see example output code](https://github.com/hyperweb-io/ts-codegen/blob/main/__output__/sg721/Sg721.message-composer.ts)
179217

__fixtures__/issues/98/out/98.client.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
55
*/
66

7-
import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
8-
import { StdFee } from "@cosmjs/amino";
7+
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
8+
import { DeliverTxResponse, StdFee } from "@interchainjs/types";
99
import { Uint128, InstantiateMsg, Coin, ExecuteMsg, InstallableExecMsg, Binary, ExecMsg, QueryMsg, InstallableQueryMsg, QueryMsg1, ConfigResponse, NullablePlugin, CanonicalAddr, Plugin, PluginsResponse } from "./98.types";
1010
export interface 98ReadOnlyInterface {
1111
contractAddress: string;
@@ -24,9 +24,9 @@ export interface 98ReadOnlyInterface {
2424
}) => Promise<NullablePlugin>;
2525
}
2626
export class 98QueryClient implements 98ReadOnlyInterface {
27-
client: CosmWasmClient;
27+
client: ICosmWasmClient;
2828
contractAddress: string;
29-
constructor(client: CosmWasmClient, contractAddress: string) {
29+
constructor(client: ICosmWasmClient, contractAddress: string) {
3030
this.client = client;
3131
this.contractAddress = contractAddress;
3232
this.getConfig = this.getConfig.bind(this);
@@ -73,7 +73,7 @@ export interface 98Interface extends 98ReadOnlyInterface {
7373
}: {
7474
id: number;
7575
instantiateMsg: Binary;
76-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
76+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
7777
registerPlugin: ({
7878
checksum,
7979
codeId,
@@ -88,12 +88,12 @@ export interface 98Interface extends 98ReadOnlyInterface {
8888
ipfsHash: string;
8989
name: string;
9090
version: string;
91-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
91+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
9292
unregisterPlugin: ({
9393
id
9494
}: {
9595
id: number;
96-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
96+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
9797
updatePlugin: ({
9898
checksum,
9999
codeId,
@@ -110,23 +110,23 @@ export interface 98Interface extends 98ReadOnlyInterface {
110110
ipfsHash?: string;
111111
name?: string;
112112
version?: string;
113-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
113+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
114114
updateRegistryFee: ({
115115
newFee
116116
}: {
117117
newFee: Coin;
118-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
118+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
119119
updateDaoAddr: ({
120120
newAddr
121121
}: {
122122
newAddr: string;
123-
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<ExecuteResult>;
123+
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<DeliverTxResponse>;
124124
}
125125
export class 98Client extends 98QueryClient implements 98Interface {
126-
client: SigningCosmWasmClient;
126+
client: ISigningCosmWasmClient;
127127
sender: string;
128128
contractAddress: string;
129-
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
129+
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
130130
super(client, contractAddress);
131131
this.client = client;
132132
this.sender = sender;
@@ -144,7 +144,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
144144
}: {
145145
id: number;
146146
instantiateMsg: Binary;
147-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
147+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
148148
return await this.client.execute(this.sender, this.contractAddress, {
149149
proxy_install_plugin: {
150150
id,
@@ -166,7 +166,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
166166
ipfsHash: string;
167167
name: string;
168168
version: string;
169-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
169+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
170170
return await this.client.execute(this.sender, this.contractAddress, {
171171
register_plugin: {
172172
checksum,
@@ -182,7 +182,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
182182
id
183183
}: {
184184
id: number;
185-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
185+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
186186
return await this.client.execute(this.sender, this.contractAddress, {
187187
unregister_plugin: {
188188
id
@@ -205,7 +205,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
205205
ipfsHash?: string;
206206
name?: string;
207207
version?: string;
208-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
208+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
209209
return await this.client.execute(this.sender, this.contractAddress, {
210210
update_plugin: {
211211
checksum,
@@ -222,7 +222,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
222222
newFee
223223
}: {
224224
newFee: Coin;
225-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
225+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
226226
return await this.client.execute(this.sender, this.contractAddress, {
227227
update_registry_fee: {
228228
new_fee: newFee
@@ -233,7 +233,7 @@ export class 98Client extends 98QueryClient implements 98Interface {
233233
newAddr
234234
}: {
235235
newAddr: string;
236-
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<ExecuteResult> => {
236+
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<DeliverTxResponse> => {
237237
return await this.client.execute(this.sender, this.contractAddress, {
238238
update_dao_addr: {
239239
new_addr: newAddr
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/**
2+
* This file was automatically generated by @cosmwasm/ts-codegen@latest.
3+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4+
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
5+
*/
6+
7+
8+
import { StdFee, Coin, DeliverTxResponse } from '@interchainjs/types';
9+
import { SigningClient } from '@interchainjs/cosmos/signing-client';
10+
import { getSmartContractState } from 'interchainjs/cosmwasm/wasm/v1/query.rpc.func';
11+
import { executeContract } from 'interchainjs/cosmwasm/wasm/v1/tx.rpc.func';
12+
import { QuerySmartContractStateRequest, QuerySmartContractStateResponse } from 'interchainjs/cosmwasm/wasm/v1/query';
13+
import { MsgExecuteContract } from 'interchainjs/cosmwasm/wasm/v1/tx';
14+
import { Chain } from '@chain-registry/v2-types';
15+
16+
// Encoding utility functions
17+
const fromUint8Array = <T>(uint8Array: Uint8Array): T => {
18+
const text = new TextDecoder().decode(uint8Array);
19+
return JSON.parse(text);
20+
};
21+
22+
const toUint8Array = (obj: any): Uint8Array => {
23+
const text = JSON.stringify(obj);
24+
return new TextEncoder().encode(text);
25+
};
26+
27+
// Chain registry configuration
28+
// The amount under gasPrice represents gas price per unit
29+
export interface ChainConfig {
30+
chain?: Chain;
31+
gasPrice?: {
32+
denom: string;
33+
amount: string;
34+
};
35+
}
36+
37+
// Gas fee calculation utilities
38+
export const calculateGasFromChain = (chain: Chain, gasAmount: string): StdFee => {
39+
try {
40+
const feeTokens = chain.fees?.feeTokens;
41+
42+
if (feeTokens && feeTokens.length > 0) {
43+
const primaryToken = feeTokens[0];
44+
// v2 chain-registry uses camelCase: averageGasPrice, lowGasPrice, fixedMinGasPrice
45+
const gasPrice = primaryToken.averageGasPrice || primaryToken.lowGasPrice || primaryToken.fixedMinGasPrice || 0.025;
46+
const gasAmountNum = parseInt(gasAmount);
47+
const feeAmount = Math.ceil(gasAmountNum * gasPrice).toString();
48+
49+
return {
50+
amount: [{
51+
denom: primaryToken.denom,
52+
amount: feeAmount
53+
}],
54+
gas: gasAmount
55+
};
56+
}
57+
} catch (error) {
58+
console.warn('Failed to calculate gas from chain registry:', error);
59+
}
60+
61+
// Fallback to default
62+
return { amount: [], gas: gasAmount };
63+
};
64+
65+
// Default gas amount - users can easily change this
66+
export let DEFAULT_GAS_AMOUNT = '200000';
67+
68+
// Allow users to set their preferred default gas amount
69+
export const setDefaultGasAmount = (gasAmount: string): void => {
70+
DEFAULT_GAS_AMOUNT = gasAmount;
71+
};
72+
73+
// Get current default gas amount
74+
export const getDefaultGasAmount = (): string => DEFAULT_GAS_AMOUNT;
75+
76+
export const getAutoGasFee = (chainConfig?: ChainConfig): StdFee => {
77+
const gasAmount = DEFAULT_GAS_AMOUNT;
78+
79+
if (chainConfig?.chain) {
80+
return calculateGasFromChain(chainConfig.chain, gasAmount);
81+
}
82+
83+
if (chainConfig?.gasPrice) {
84+
const gasAmountNum = parseInt(gasAmount);
85+
const gasPriceNum = parseFloat(chainConfig.gasPrice.amount);
86+
const feeAmount = Math.ceil(gasAmountNum * gasPriceNum).toString();
87+
88+
return {
89+
amount: [{
90+
denom: chainConfig.gasPrice.denom,
91+
amount: feeAmount
92+
}],
93+
gas: gasAmount
94+
};
95+
}
96+
97+
// Fallback: no fee tokens, just gas amount
98+
return { amount: [], gas: gasAmount };
99+
};
100+
101+
// InterchainJS interfaces for CosmWasm clients
102+
export interface ICosmWasmClient {
103+
queryContractSmart(contractAddr: string, query: any): Promise<any>;
104+
}
105+
106+
export interface ISigningCosmWasmClient {
107+
execute(
108+
sender: string,
109+
contractAddress: string,
110+
msg: any,
111+
fee?: number | StdFee | "auto",
112+
memo?: string,
113+
funds?: Coin[],
114+
chainConfig?: ChainConfig
115+
): Promise<DeliverTxResponse>;
116+
}
117+
118+
export interface ISigningClient {
119+
signAndBroadcast(
120+
signerAddress: string,
121+
messages: any[],
122+
fee: number | StdFee | "auto",
123+
memo?: string
124+
): Promise<DeliverTxResponse>;
125+
}
126+
127+
// Helper functions to create InterchainJS clients
128+
export function getCosmWasmClient(rpcEndpoint: string): ICosmWasmClient {
129+
return {
130+
queryContractSmart: async (contractAddr: string, query: any) => {
131+
// Create the request object
132+
const request: QuerySmartContractStateRequest = {
133+
address: contractAddr,
134+
queryData: toUint8Array(query)
135+
};
136+
137+
// Execute the query using InterchainJS
138+
const response: QuerySmartContractStateResponse = await getSmartContractState(rpcEndpoint, request);
139+
140+
// Parse and return the result
141+
return fromUint8Array(response.data);
142+
},
143+
};
144+
}
145+
146+
export function getSigningCosmWasmClient(signingClient: SigningClient): ISigningCosmWasmClient {
147+
return {
148+
execute: async (
149+
sender: string,
150+
contractAddress: string,
151+
msg: any,
152+
fee?: number | StdFee | "auto",
153+
memo?: string,
154+
funds?: Coin[],
155+
chainConfig?: ChainConfig
156+
) => {
157+
// Handle fee conversion
158+
let finalFee: StdFee;
159+
if (typeof fee === 'number') {
160+
finalFee = { amount: [], gas: fee.toString() };
161+
} else if (fee === 'auto') {
162+
finalFee = getAutoGasFee(chainConfig);
163+
} else if (fee) {
164+
finalFee = fee;
165+
} else {
166+
finalFee = getAutoGasFee(chainConfig);
167+
}
168+
169+
// Create the message object
170+
const message: MsgExecuteContract = {
171+
sender,
172+
contract: contractAddress,
173+
msg: toUint8Array(msg),
174+
funds: funds || []
175+
};
176+
177+
// Execute the transaction using InterchainJS
178+
const result = await executeContract(
179+
signingClient as any,
180+
sender,
181+
message,
182+
finalFee,
183+
memo || ''
184+
);
185+
186+
return result;
187+
},
188+
};
189+
}

__fixtures__/issues/98/out/bundle.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
import * as _0 from "./98.types";
88
import * as _1 from "./98.client";
99
import * as _2 from "./98.react-query";
10+
import * as _3 from "./baseClient";
1011
export namespace contracts {
1112
export const 98 = {
1213
..._0,
1314
..._1,
1415
..._2
1516
};
17+
export const baseClient = {
18+
..._3
19+
};
1620
}

0 commit comments

Comments
 (0)