Replace RestClient with LcdClient
This commit is contained in:
parent
a317dac01e
commit
dc661dfe5c
@ -1,10 +1,18 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { Coin, coins, CosmosSdkTx, isMsgSend, makeSignBytes, MsgSend, Secp256k1Pen } from "@cosmjs/sdk38";
|
||||
import {
|
||||
Coin,
|
||||
coins,
|
||||
CosmosSdkTx,
|
||||
isMsgSend,
|
||||
LcdClient,
|
||||
makeSignBytes,
|
||||
MsgSend,
|
||||
Secp256k1Pen,
|
||||
} from "@cosmjs/sdk38";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
|
||||
import { CosmWasmClient, isPostTxFailure } from "./cosmwasmclient";
|
||||
import { isMsgExecuteContract, isMsgInstantiateContract } from "./msgs";
|
||||
import { RestClient } from "./restclient";
|
||||
import { SigningCosmWasmClient } from "./signingcosmwasmclient";
|
||||
import {
|
||||
alice,
|
||||
@ -50,7 +58,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
const transferAmount = coins(1234567, "ucosm");
|
||||
const result = await client.sendTokens(recipient, transferAmount);
|
||||
await sleep(75); // wait until tx is indexed
|
||||
const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
const txDetails = await new LcdClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
sendSuccessful = {
|
||||
sender: alice.address0,
|
||||
recipient: recipient,
|
||||
@ -68,7 +76,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
};
|
||||
const result = await client.sendTokens(recipient, [transferAmount]);
|
||||
await sleep(75); // wait until tx is indexed
|
||||
const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
const txDetails = await new LcdClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
sendSelfSuccessful = {
|
||||
sender: alice.address0,
|
||||
recipient: recipient,
|
||||
@ -132,7 +140,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
};
|
||||
const result = await client.execute(hashInstance, msg);
|
||||
await sleep(75); // wait until tx is indexed
|
||||
const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
const txDetails = await new LcdClient(wasmd.endpoint).txById(result.transactionHash);
|
||||
execute = {
|
||||
sender: alice.address0,
|
||||
contract: hashInstance,
|
||||
|
||||
@ -54,7 +54,7 @@ describe("CosmWasmClient", () => {
|
||||
pendingWithoutWasmd();
|
||||
const client = new CosmWasmClient(wasmd.endpoint);
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const getCodeSpy = spyOn(openedClient.restClient, "nodeInfo").and.callThrough();
|
||||
const getCodeSpy = spyOn(openedClient.lcdClient, "nodeInfo").and.callThrough();
|
||||
|
||||
expect(await client.getChainId()).toEqual(wasmd.chainId); // from network
|
||||
expect(await client.getChainId()).toEqual(wasmd.chainId); // from cache
|
||||
@ -68,7 +68,7 @@ describe("CosmWasmClient", () => {
|
||||
pendingWithoutWasmd();
|
||||
const client = new CosmWasmClient(wasmd.endpoint);
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough();
|
||||
const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough();
|
||||
|
||||
const height1 = await client.getHeight();
|
||||
expect(height1).toBeGreaterThan(0);
|
||||
@ -85,8 +85,8 @@ describe("CosmWasmClient", () => {
|
||||
const client = new CosmWasmClient(wasmd.endpoint);
|
||||
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough();
|
||||
const authAccountsSpy = spyOn(openedClient.restClient, "authAccounts").and.callThrough();
|
||||
const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough();
|
||||
const authAccountsSpy = spyOn(openedClient.lcdClient.auth, "account").and.callThrough();
|
||||
|
||||
const height1 = await client.getHeight();
|
||||
expect(height1).toBeGreaterThan(0);
|
||||
@ -292,7 +292,7 @@ describe("CosmWasmClient", () => {
|
||||
pendingWithoutWasmd();
|
||||
const client = new CosmWasmClient(wasmd.endpoint);
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const getCodeSpy = spyOn(openedClient.restClient, "getCode").and.callThrough();
|
||||
const getCodeSpy = spyOn(openedClient.lcdClient.wasm, "getCode").and.callThrough();
|
||||
|
||||
const result1 = await client.getCodeDetails(deployedErc20.codeId); // from network
|
||||
const result2 = await client.getCodeDetails(deployedErc20.codeId); // from cache
|
||||
|
||||
@ -2,17 +2,20 @@ import { Sha256 } from "@cosmjs/crypto";
|
||||
import { fromBase64, fromHex, toHex } from "@cosmjs/encoding";
|
||||
import { Uint53 } from "@cosmjs/math";
|
||||
import {
|
||||
AuthExtension,
|
||||
BroadcastMode,
|
||||
Coin,
|
||||
CosmosSdkTx,
|
||||
decodeBech32Pubkey,
|
||||
IndexedTx,
|
||||
LcdClient,
|
||||
PubKey,
|
||||
setupAuthExtension,
|
||||
StdTx,
|
||||
} from "@cosmjs/sdk38";
|
||||
|
||||
import { setupWasmExtension, WasmExtension } from "./lcdapi/wasm";
|
||||
import { Log, parseLogs } from "./logs";
|
||||
import { RestClient } from "./restclient";
|
||||
import { JsonObject } from "./types";
|
||||
|
||||
export interface GetNonceResult {
|
||||
@ -160,11 +163,11 @@ export interface Block {
|
||||
|
||||
/** Use for testing only */
|
||||
export interface PrivateCosmWasmClient {
|
||||
readonly restClient: RestClient;
|
||||
readonly lcdClient: LcdClient & AuthExtension & WasmExtension;
|
||||
}
|
||||
|
||||
export class CosmWasmClient {
|
||||
protected readonly restClient: RestClient;
|
||||
protected readonly lcdClient: LcdClient & AuthExtension & WasmExtension;
|
||||
/** Any address the chain considers valid (valid bech32 with proper prefix) */
|
||||
protected anyValidAddress: string | undefined;
|
||||
|
||||
@ -181,12 +184,16 @@ export class CosmWasmClient {
|
||||
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
|
||||
*/
|
||||
public constructor(apiUrl: string, broadcastMode = BroadcastMode.Block) {
|
||||
this.restClient = new RestClient(apiUrl, broadcastMode);
|
||||
this.lcdClient = LcdClient.withExtensions(
|
||||
{ apiUrl: apiUrl, broadcastMode: broadcastMode },
|
||||
setupAuthExtension,
|
||||
setupWasmExtension,
|
||||
);
|
||||
}
|
||||
|
||||
public async getChainId(): Promise<string> {
|
||||
if (!this.chainId) {
|
||||
const response = await this.restClient.nodeInfo();
|
||||
const response = await this.lcdClient.nodeInfo();
|
||||
const chainId = response.node_info.network;
|
||||
if (!chainId) throw new Error("Chain ID must not be empty");
|
||||
this.chainId = chainId;
|
||||
@ -197,12 +204,12 @@ export class CosmWasmClient {
|
||||
|
||||
public async getHeight(): Promise<number> {
|
||||
if (this.anyValidAddress) {
|
||||
const { height } = await this.restClient.authAccounts(this.anyValidAddress);
|
||||
const { height } = await this.lcdClient.auth.account(this.anyValidAddress);
|
||||
return parseInt(height, 10);
|
||||
} else {
|
||||
// Note: this gets inefficient when blocks contain a lot of transactions since it
|
||||
// requires downloading and deserializing all transactions in the block.
|
||||
const latest = await this.restClient.blocksLatest();
|
||||
const latest = await this.lcdClient.blocksLatest();
|
||||
return parseInt(latest.block.header.height, 10);
|
||||
}
|
||||
}
|
||||
@ -212,7 +219,7 @@ export class CosmWasmClient {
|
||||
*/
|
||||
public async getIdentifier(tx: CosmosSdkTx): Promise<string> {
|
||||
// We consult the REST API because we don't have a local amino encoder
|
||||
const response = await this.restClient.encodeTx(tx);
|
||||
const response = await this.lcdClient.encodeTx(tx);
|
||||
const hash = new Sha256(fromBase64(response.tx)).digest();
|
||||
return toHex(hash).toUpperCase();
|
||||
}
|
||||
@ -238,7 +245,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
|
||||
public async getAccount(address: string): Promise<Account | undefined> {
|
||||
const account = await this.restClient.authAccounts(address);
|
||||
const account = await this.lcdClient.auth.account(address);
|
||||
const value = account.result.value;
|
||||
if (value.address === "") {
|
||||
return undefined;
|
||||
@ -261,7 +268,7 @@ export class CosmWasmClient {
|
||||
*/
|
||||
public async getBlock(height?: number): Promise<Block> {
|
||||
const response =
|
||||
height !== undefined ? await this.restClient.blocks(height) : await this.restClient.blocksLatest();
|
||||
height !== undefined ? await this.lcdClient.blocks(height) : await this.lcdClient.blocksLatest();
|
||||
|
||||
return {
|
||||
id: response.block_id.hash,
|
||||
@ -333,7 +340,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
|
||||
public async postTx(tx: StdTx): Promise<PostTxResult> {
|
||||
const result = await this.restClient.postTx(tx);
|
||||
const result = await this.lcdClient.postTx(tx);
|
||||
if (!result.txhash.match(/^([0-9A-F][0-9A-F])+$/)) {
|
||||
throw new Error("Received ill-formatted txhash. Must be non-empty upper-case hex");
|
||||
}
|
||||
@ -354,7 +361,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
|
||||
public async getCodes(): Promise<readonly Code[]> {
|
||||
const result = await this.restClient.listCodeInfo();
|
||||
const result = await this.lcdClient.wasm.listCodeInfo();
|
||||
return result.map(
|
||||
(entry): Code => {
|
||||
this.anyValidAddress = entry.creator;
|
||||
@ -373,7 +380,7 @@ export class CosmWasmClient {
|
||||
const cached = this.codesCache.get(codeId);
|
||||
if (cached) return cached;
|
||||
|
||||
const getCodeResult = await this.restClient.getCode(codeId);
|
||||
const getCodeResult = await this.lcdClient.wasm.getCode(codeId);
|
||||
const codeDetails: CodeDetails = {
|
||||
id: getCodeResult.id,
|
||||
creator: getCodeResult.creator,
|
||||
@ -387,7 +394,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
|
||||
public async getContracts(codeId: number): Promise<readonly Contract[]> {
|
||||
const result = await this.restClient.listContractsByCodeId(codeId);
|
||||
const result = await this.lcdClient.wasm.listContractsByCodeId(codeId);
|
||||
return result.map(
|
||||
(entry): Contract => ({
|
||||
address: entry.address,
|
||||
@ -403,7 +410,7 @@ export class CosmWasmClient {
|
||||
* Throws an error if no contract was found at the address
|
||||
*/
|
||||
public async getContract(address: string): Promise<ContractDetails> {
|
||||
const result = await this.restClient.getContractInfo(address);
|
||||
const result = await this.lcdClient.wasm.getContractInfo(address);
|
||||
if (!result) throw new Error(`No contract found at address "${address}"`);
|
||||
return {
|
||||
address: result.address,
|
||||
@ -425,7 +432,7 @@ export class CosmWasmClient {
|
||||
// just test contract existence
|
||||
const _info = await this.getContract(address);
|
||||
|
||||
return this.restClient.queryContractRaw(address, key);
|
||||
return this.lcdClient.wasm.queryContractRaw(address, key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -437,7 +444,7 @@ export class CosmWasmClient {
|
||||
*/
|
||||
public async queryContractSmart(address: string, queryMsg: object): Promise<JsonObject> {
|
||||
try {
|
||||
return await this.restClient.queryContractSmart(address, queryMsg);
|
||||
return await this.lcdClient.wasm.queryContractSmart(address, queryMsg);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.message.startsWith("not found: contract")) {
|
||||
@ -454,7 +461,7 @@ export class CosmWasmClient {
|
||||
private async txsQuery(query: string): Promise<readonly IndexedTx[]> {
|
||||
// TODO: we need proper pagination support
|
||||
const limit = 100;
|
||||
const result = await this.restClient.txsQuery(`${query}&limit=${limit}`);
|
||||
const result = await this.lcdClient.txsQuery(`${query}&limit=${limit}`);
|
||||
const pages = parseInt(result.page_total, 10);
|
||||
if (pages > 1) {
|
||||
throw new Error(
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
import { Sha256 } from "@cosmjs/crypto";
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
import { coin, coins, Secp256k1Pen } from "@cosmjs/sdk38";
|
||||
import { AuthExtension, coin, coins, LcdClient, Secp256k1Pen, setupAuthExtension } from "@cosmjs/sdk38";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { isPostTxFailure, PrivateCosmWasmClient } from "./cosmwasmclient";
|
||||
import { RestClient } from "./restclient";
|
||||
import { setupWasmExtension, WasmExtension } from "./lcdapi/wasm";
|
||||
import { SigningCosmWasmClient, UploadMeta } from "./signingcosmwasmclient";
|
||||
import { alice, getHackatom, makeRandomAddress, pendingWithoutWasmd, unused } from "./testutils.spec";
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
|
||||
function makeWasmClient(apiUrl: string): LcdClient & AuthExtension & WasmExtension {
|
||||
return LcdClient.withExtensions({ apiUrl }, setupAuthExtension, setupWasmExtension);
|
||||
}
|
||||
|
||||
describe("SigningCosmWasmClient", () => {
|
||||
describe("makeReadOnly", () => {
|
||||
it("can be constructed", async () => {
|
||||
@ -26,8 +30,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
const client = new SigningCosmWasmClient(httpUrl, alice.address0, (signBytes) => pen.sign(signBytes));
|
||||
|
||||
const openedClient = (client as unknown) as PrivateCosmWasmClient;
|
||||
const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough();
|
||||
const authAccountsSpy = spyOn(openedClient.restClient, "authAccounts").and.callThrough();
|
||||
const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough();
|
||||
const authAccountsSpy = spyOn(openedClient.lcdClient.auth, "account").and.callThrough();
|
||||
|
||||
const height = await client.getHeight();
|
||||
expect(height).toBeGreaterThan(0);
|
||||
@ -97,8 +101,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const rest = new RestClient(httpUrl);
|
||||
const balance = (await rest.authAccounts(contractAddress)).result.value.coins;
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const balance = (await lcdClient.auth.account(contractAddress)).result.value.coins;
|
||||
expect(balance).toEqual(transferAmount);
|
||||
});
|
||||
|
||||
@ -119,8 +123,8 @@ describe("SigningCosmWasmClient", () => {
|
||||
{ admin: unused.address },
|
||||
);
|
||||
|
||||
const rest = new RestClient(httpUrl);
|
||||
const contract = await rest.getContractInfo(contractAddress);
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const contract = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(contract);
|
||||
expect(contract.admin).toEqual(unused.address);
|
||||
});
|
||||
@ -171,14 +175,14 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const rest = new RestClient(httpUrl);
|
||||
const state1 = await rest.getContractInfo(contractAddress);
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const state1 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state1);
|
||||
expect(state1.admin).toEqual(alice.address0);
|
||||
|
||||
await client.updateAdmin(contractAddress, unused.address);
|
||||
|
||||
const state2 = await rest.getContractInfo(contractAddress);
|
||||
const state2 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state2);
|
||||
expect(state2.admin).toEqual(unused.address);
|
||||
});
|
||||
@ -204,14 +208,14 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const rest = new RestClient(httpUrl);
|
||||
const state1 = await rest.getContractInfo(contractAddress);
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const state1 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state1);
|
||||
expect(state1.admin).toEqual(alice.address0);
|
||||
|
||||
await client.clearAdmin(contractAddress);
|
||||
|
||||
const state2 = await rest.getContractInfo(contractAddress);
|
||||
const state2 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state2);
|
||||
expect(state2.admin).toBeUndefined();
|
||||
});
|
||||
@ -238,15 +242,15 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const rest = new RestClient(httpUrl);
|
||||
const state1 = await rest.getContractInfo(contractAddress);
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const state1 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state1);
|
||||
expect(state1.admin).toEqual(alice.address0);
|
||||
|
||||
const newVerifier = makeRandomAddress();
|
||||
await client.migrate(contractAddress, codeId2, { verifier: newVerifier });
|
||||
|
||||
const state2 = await rest.getContractInfo(contractAddress);
|
||||
const state2 = await lcdClient.wasm.getContractInfo(contractAddress);
|
||||
assert(state2);
|
||||
expect(state2).toEqual({
|
||||
...state1,
|
||||
@ -289,10 +293,10 @@ describe("SigningCosmWasmClient", () => {
|
||||
});
|
||||
|
||||
// Verify token transfer from contract to beneficiary
|
||||
const rest = new RestClient(httpUrl);
|
||||
const beneficiaryBalance = (await rest.authAccounts(beneficiaryAddress)).result.value.coins;
|
||||
const lcdClient = makeWasmClient(httpUrl);
|
||||
const beneficiaryBalance = (await lcdClient.auth.account(beneficiaryAddress)).result.value.coins;
|
||||
expect(beneficiaryBalance).toEqual(transferAmount);
|
||||
const contractBalance = (await rest.authAccounts(contractAddress)).result.value.coins;
|
||||
const contractBalance = (await lcdClient.auth.account(contractAddress)).result.value.coins;
|
||||
expect(contractBalance).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
17
packages/cosmwasm/types/cosmwasmclient.d.ts
vendored
17
packages/cosmwasm/types/cosmwasmclient.d.ts
vendored
@ -1,6 +1,15 @@
|
||||
import { BroadcastMode, Coin, CosmosSdkTx, IndexedTx, PubKey, StdTx } from "@cosmjs/sdk38";
|
||||
import {
|
||||
AuthExtension,
|
||||
BroadcastMode,
|
||||
Coin,
|
||||
CosmosSdkTx,
|
||||
IndexedTx,
|
||||
LcdClient,
|
||||
PubKey,
|
||||
StdTx,
|
||||
} from "@cosmjs/sdk38";
|
||||
import { WasmExtension } from "./lcdapi/wasm";
|
||||
import { Log } from "./logs";
|
||||
import { RestClient } from "./restclient";
|
||||
import { JsonObject } from "./types";
|
||||
export interface GetNonceResult {
|
||||
readonly accountNumber: number;
|
||||
@ -114,10 +123,10 @@ export interface Block {
|
||||
}
|
||||
/** Use for testing only */
|
||||
export interface PrivateCosmWasmClient {
|
||||
readonly restClient: RestClient;
|
||||
readonly lcdClient: LcdClient & AuthExtension & WasmExtension;
|
||||
}
|
||||
export declare class CosmWasmClient {
|
||||
protected readonly restClient: RestClient;
|
||||
protected readonly lcdClient: LcdClient & AuthExtension & WasmExtension;
|
||||
/** Any address the chain considers valid (valid bech32 with proper prefix) */
|
||||
protected anyValidAddress: string | undefined;
|
||||
private readonly codesCache;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user