cosmwasm-stargate: Switch to ts-proto codec

This commit is contained in:
willclarktech 2021-01-28 13:51:35 +00:00
parent 8c78486a9a
commit f1e4649e59
No known key found for this signature in database
GPG Key ID: 551A86E2E398ADF7
10 changed files with 186 additions and 192 deletions

View File

@ -1,4 +1,17 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {
MsgClearAdmin as LaunchpadMsgClearAdmin,
MsgExecuteContract as LaunchpadMsgExecuteContract,
MsgInstantiateContract as LaunchpadMsgInstantiateContract,
MsgMigrateContract as LaunchpadMsgMigrateContract,
MsgStoreCode as LaunchpadMsgStoreCode,
MsgUpdateAdmin as LaunchpadMsgUpdateAdmin,
} from "@cosmjs/cosmwasm-launchpad";
import { fromBase64, fromUtf8, toBase64, toUtf8 } from "@cosmjs/encoding";
import { AminoConverter, coinFromProto } from "@cosmjs/stargate";
import { assertDefinedAndNotNull } from "@cosmjs/utils";
import Long from "long";
import {
MsgClearAdmin,
MsgExecuteContract,
@ -6,25 +19,12 @@ import {
MsgMigrateContract,
MsgStoreCode,
MsgUpdateAdmin,
} from "@cosmjs/cosmwasm-launchpad";
import { fromBase64, fromUtf8, toBase64, toUtf8 } from "@cosmjs/encoding";
import { AminoConverter, coinFromProto } from "@cosmjs/stargate";
import { assertDefinedAndNotNull } from "@cosmjs/utils";
import Long from "long";
import { cosmwasm } from "./codec";
type IMsgStoreCode = cosmwasm.wasm.v1beta1.IMsgStoreCode;
type IMsgInstantiateContract = cosmwasm.wasm.v1beta1.IMsgInstantiateContract;
type IMsgUpdateAdmin = cosmwasm.wasm.v1beta1.IMsgUpdateAdmin;
type IMsgClearAdmin = cosmwasm.wasm.v1beta1.IMsgClearAdmin;
type IMsgExecuteContract = cosmwasm.wasm.v1beta1.IMsgExecuteContract;
type IMsgMigrateContract = cosmwasm.wasm.v1beta1.IMsgMigrateContract;
} from "./codec/x/wasm/internal/types/tx";
export const cosmWasmTypes: Record<string, AminoConverter> = {
"/cosmwasm.wasm.v1beta1.MsgStoreCode": {
aminoType: "wasm/MsgStoreCode",
toAmino: ({ sender, wasmByteCode, source, builder }: IMsgStoreCode): MsgStoreCode["value"] => {
toAmino: ({ sender, wasmByteCode, source, builder }: MsgStoreCode): LaunchpadMsgStoreCode["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(wasmByteCode, "missing wasmByteCode");
assertDefinedAndNotNull(source, "missing source");
@ -36,7 +36,12 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
builder: builder,
};
},
fromAmino: ({ sender, wasm_byte_code, source, builder }: MsgStoreCode["value"]): IMsgStoreCode => ({
fromAmino: ({
sender,
wasm_byte_code,
source,
builder,
}: LaunchpadMsgStoreCode["value"]): MsgStoreCode => ({
sender: sender,
wasmByteCode: fromBase64(wasm_byte_code),
source: source,
@ -52,7 +57,7 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
initMsg,
initFunds,
admin,
}: IMsgInstantiateContract): MsgInstantiateContract["value"] => {
}: MsgInstantiateContract): LaunchpadMsgInstantiateContract["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(codeId, "missing codeId");
assertDefinedAndNotNull(label, "missing label");
@ -74,18 +79,18 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
init_msg,
init_funds,
admin,
}: MsgInstantiateContract["value"]): IMsgInstantiateContract => ({
}: LaunchpadMsgInstantiateContract["value"]): MsgInstantiateContract => ({
sender: sender,
codeId: Long.fromString(code_id),
label: label,
initMsg: toUtf8(JSON.stringify(init_msg)),
initFunds: [...init_funds],
admin: admin,
admin: admin ?? "",
}),
},
"/cosmwasm.wasm.v1beta1.MsgUpdateAdmin": {
aminoType: "wasm/MsgUpdateAdmin",
toAmino: ({ sender, newAdmin, contract }: IMsgUpdateAdmin): MsgUpdateAdmin["value"] => {
toAmino: ({ sender, newAdmin, contract }: MsgUpdateAdmin): LaunchpadMsgUpdateAdmin["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(newAdmin, "missing newAdmin");
assertDefinedAndNotNull(contract, "missing contract");
@ -95,7 +100,7 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
contract: contract,
};
},
fromAmino: ({ sender, new_admin, contract }: MsgUpdateAdmin["value"]): IMsgUpdateAdmin => ({
fromAmino: ({ sender, new_admin, contract }: LaunchpadMsgUpdateAdmin["value"]): MsgUpdateAdmin => ({
sender: sender,
newAdmin: new_admin,
contract: contract,
@ -103,7 +108,7 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
},
"/cosmwasm.wasm.v1beta1.MsgClearAdmin": {
aminoType: "wasm/MsgClearAdmin",
toAmino: ({ sender, contract }: IMsgClearAdmin): MsgClearAdmin["value"] => {
toAmino: ({ sender, contract }: MsgClearAdmin): LaunchpadMsgClearAdmin["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(contract, "missing contract");
return {
@ -111,14 +116,19 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
contract: contract,
};
},
fromAmino: ({ sender, contract }: MsgClearAdmin["value"]): IMsgClearAdmin => ({
fromAmino: ({ sender, contract }: LaunchpadMsgClearAdmin["value"]): MsgClearAdmin => ({
sender: sender,
contract: contract,
}),
},
"/cosmwasm.wasm.v1beta1.MsgExecuteContract": {
aminoType: "wasm/MsgExecuteContract",
toAmino: ({ sender, contract, msg, sentFunds }: IMsgExecuteContract): MsgExecuteContract["value"] => {
toAmino: ({
sender,
contract,
msg,
sentFunds,
}: MsgExecuteContract): LaunchpadMsgExecuteContract["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(contract, "missing contract");
assertDefinedAndNotNull(msg, "missing msg");
@ -130,7 +140,12 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
sent_funds: sentFunds.map(coinFromProto),
};
},
fromAmino: ({ sender, contract, msg, sent_funds }: MsgExecuteContract["value"]): IMsgExecuteContract => ({
fromAmino: ({
sender,
contract,
msg,
sent_funds,
}: LaunchpadMsgExecuteContract["value"]): MsgExecuteContract => ({
sender: sender,
contract: contract,
msg: toUtf8(JSON.stringify(msg)),
@ -139,7 +154,12 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
},
"/cosmwasm.wasm.v1beta1.MsgMigrateContract": {
aminoType: "wasm/MsgMigrateContract",
toAmino: ({ sender, contract, codeId, migrateMsg }: IMsgMigrateContract): MsgMigrateContract["value"] => {
toAmino: ({
sender,
contract,
codeId,
migrateMsg,
}: MsgMigrateContract): LaunchpadMsgMigrateContract["value"] => {
assertDefinedAndNotNull(sender, "missing sender");
assertDefinedAndNotNull(contract, "missing contract");
assertDefinedAndNotNull(codeId, "missing codeId");
@ -151,7 +171,12 @@ export const cosmWasmTypes: Record<string, AminoConverter> = {
msg: JSON.parse(fromUtf8(migrateMsg)),
};
},
fromAmino: ({ sender, contract, code_id, msg }: MsgMigrateContract["value"]): IMsgMigrateContract => ({
fromAmino: ({
sender,
contract,
code_id,
msg,
}: LaunchpadMsgMigrateContract["value"]): MsgMigrateContract => ({
sender: sender,
contract: contract,
codeId: Long.fromString(code_id),

View File

@ -8,7 +8,8 @@ import {
makeSignDoc,
Registry,
} from "@cosmjs/proto-signing";
import { BroadcastTxResponse, codec, isBroadcastTxFailure, isBroadcastTxSuccess } from "@cosmjs/stargate";
import { BroadcastTxResponse, isBroadcastTxFailure, isBroadcastTxSuccess } from "@cosmjs/stargate";
import { Tx, TxRaw } from "@cosmjs/stargate/src/codec/cosmos/tx/v1beta1/tx";
import { assert, sleep } from "@cosmjs/utils";
import { CosmWasmClient } from "./cosmwasmclient";
@ -21,8 +22,6 @@ import {
wasmdEnabled,
} from "./testutils.spec";
const { Tx, TxRaw } = codec.cosmos.tx.v1beta1;
interface TestTxSend {
readonly sender: string;
readonly recipient: string;
@ -77,7 +76,7 @@ async function sendTokens(
const chainId = await client.getChainId();
const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber);
const { signature } = await wallet.signDirect(walletAddress, signDoc);
const txRaw = TxRaw.create({
const txRaw = TxRaw.fromPartial({
bodyBytes: txBodyBytes,
authInfoBytes: authInfoBytes,
signatures: [fromBase64(signature.signature)],
@ -227,9 +226,9 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
// Check basic structure of all results
for (const result of results) {
const tx = Tx.decode(result.tx);
const filteredMsgs = tx.body!.messages!.filter(({ type_url: typeUrl, value }) => {
const filteredMsgs = tx.body!.messages.filter(({ typeUrl: typeUrl, value }) => {
if (typeUrl !== "/cosmos.bank.v1beta1.MsgSend") return false;
const decoded = registry.decode({ typeUrl: typeUrl, value: value! });
const decoded = registry.decode({ typeUrl: typeUrl, value: value });
return decoded.fromAddress === sendSuccessful?.sender;
});
expect(filteredMsgs.length).toBeGreaterThanOrEqual(1);
@ -255,9 +254,9 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
// Check basic structure of all results
for (const result of results) {
const tx = Tx.decode(result.tx);
const filteredMsgs = tx.body!.messages!.filter(({ type_url: typeUrl, value }) => {
const filteredMsgs = tx.body!.messages.filter(({ typeUrl: typeUrl, value }) => {
if (typeUrl !== "/cosmos.bank.v1beta1.MsgSend") return false;
const decoded = registry.decode({ typeUrl: typeUrl, value: value! });
const decoded = registry.decode({ typeUrl: typeUrl, value: value });
return decoded.toAddress === sendSuccessful?.recipient;
});
expect(filteredMsgs.length).toBeGreaterThanOrEqual(1);
@ -341,9 +340,9 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
// Check basic structure of all results
for (const result of results) {
const tx = Tx.decode(result.tx);
const { type_url: typeUrl, value } = fromOneElementArray(tx.body!.messages!);
const { typeUrl, value } = fromOneElementArray(tx.body!.messages);
expect(typeUrl).toEqual("/cosmos.bank.v1beta1.MsgSend");
const decoded = registry.decode({ typeUrl: typeUrl!, value: value! });
const decoded = registry.decode({ typeUrl: typeUrl, value: value });
expect(decoded.toAddress).toEqual(sendSuccessful.recipient);
}

View File

@ -11,7 +11,8 @@ import {
makeSignDoc,
Registry,
} from "@cosmjs/proto-signing";
import { assertIsBroadcastTxSuccess, codec, parseRawLog } from "@cosmjs/stargate";
import { assertIsBroadcastTxSuccess, parseRawLog } from "@cosmjs/stargate";
import { TxRaw } from "@cosmjs/stargate/src/codec/cosmos/tx/v1beta1/tx";
import { assert, sleep } from "@cosmjs/utils";
import { ReadonlyDate } from "readonly-date";
@ -29,8 +30,6 @@ import {
wasmdEnabled,
} from "./testutils.spec";
const { TxRaw } = codec.cosmos.tx.v1beta1;
interface HackatomInstance {
readonly initMsg: {
readonly verifier: string;
@ -203,7 +202,7 @@ describe("CosmWasmClient", () => {
const authInfoBytes = makeAuthInfoBytes([pubkeyAny], fee.amount, gasLimit, sequence);
const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber);
const { signed, signature } = await wallet.signDirect(alice.address0, signDoc);
const txRaw = TxRaw.create({
const txRaw = TxRaw.fromPartial({
bodyBytes: signed.bodyBytes,
authInfoBytes: signed.authInfoBytes,
signatures: [fromBase64(signature.signature)],

View File

@ -23,7 +23,6 @@ import {
AuthExtension,
BankExtension,
BroadcastTxResponse,
codec,
coinFromProto,
IndexedTx,
QueryClient,
@ -31,6 +30,7 @@ import {
setupAuthExtension,
setupBankExtension,
} from "@cosmjs/stargate";
import { TxMsgData } from "@cosmjs/stargate/src/codec/cosmos/base/abci/v1beta1/abci";
import {
adaptor34,
broadcastTxCommitSuccess,
@ -39,15 +39,10 @@ import {
} from "@cosmjs/tendermint-rpc";
import { assert } from "@cosmjs/utils";
import { cosmwasm } from "./codec";
import { CodeInfoResponse } from "./codec/x/wasm/internal/types/query";
import { ContractCodeHistoryOperationType } from "./codec/x/wasm/internal/types/types";
import { setupWasmExtension, WasmExtension } from "./queries";
type ICodeInfoResponse = cosmwasm.wasm.v1beta1.ICodeInfoResponse;
type ContractCodeHistoryOperationType = cosmwasm.wasm.v1beta1.ContractCodeHistoryOperationType;
const { TxMsgData } = codec.cosmos.base.abci.v1beta1;
const { ContractCodeHistoryOperationType } = cosmwasm.wasm.v1beta1;
/** Use for testing only */
export interface PrivateCosmWasmClient {
readonly tmClient: TendermintClient;
@ -207,7 +202,7 @@ export class CosmWasmClient {
public async getCodes(): Promise<readonly Code[]> {
const { codeInfos } = await this.queryClient.unverified.wasm.listCodeInfo();
return (codeInfos || []).map(
(entry: ICodeInfoResponse): Code => {
(entry: CodeInfoResponse): Code => {
assert(entry.creator && entry.codeId && entry.dataHash, "entry incomplete");
return {
id: entry.codeId.toNumber(),

View File

@ -1,4 +1,3 @@
export * as codec from "./codec";
export { cosmWasmTypes } from "./aminotypes";
export { CosmWasmClient } from "./cosmwasmclient";
export { SigningCosmWasmClient, SigningCosmWasmClientOptions } from "./signingcosmwasmclient";

View File

@ -12,7 +12,15 @@ import {
import { assert, assertDefined } from "@cosmjs/utils";
import Long from "long";
import { cosmwasm } from "../codec";
import {
MsgExecuteContract,
MsgExecuteContractResponse,
MsgInstantiateContract,
MsgInstantiateContractResponse,
MsgStoreCode,
MsgStoreCodeResponse,
} from "../codec/x/wasm/internal/types/tx";
import { ContractCodeHistoryOperationType } from "../codec/x/wasm/internal/types/types";
import { SigningCosmWasmClient } from "../signingcosmwasmclient";
import {
alice,
@ -28,15 +36,6 @@ import {
wasmdEnabled,
} from "../testutils.spec";
const {
MsgExecuteContract,
MsgExecuteContractResponse,
MsgInstantiateContract,
MsgInstantiateContractResponse,
MsgStoreCode,
MsgStoreCodeResponse,
} = cosmwasm.wasm.v1beta1;
const registry = new Registry([
["/cosmwasm.wasm.v1beta1.MsgExecuteContract", MsgExecuteContract],
["/cosmwasm.wasm.v1beta1.MsgStoreCode", MsgStoreCode],
@ -50,7 +49,7 @@ async function uploadContract(
const memo = "My first contract on chain";
const theMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgStoreCode",
value: MsgStoreCode.create({
value: MsgStoreCode.fromPartial({
sender: alice.address0,
wasmByteCode: contract.data,
source: contract.source || "",
@ -75,7 +74,7 @@ async function instantiateContract(
const memo = "Create an escrow instance";
const theMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgInstantiateContract",
value: MsgInstantiateContract.create({
value: MsgInstantiateContract.fromPartial({
sender: alice.address0,
codeId: Long.fromNumber(codeId),
label: "my escrow",
@ -106,7 +105,7 @@ async function executeContract(
const memo = "Time for action";
const theMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgExecuteContract",
value: MsgExecuteContract.create({
value: MsgExecuteContract.fromPartial({
sender: alice.address0,
contract: contractAddress,
msg: toAscii(JSON.stringify(msg)),
@ -157,11 +156,11 @@ describe("WasmExtension", () => {
const { codeInfos } = await client.unverified.wasm.listCodeInfo();
assert(codeInfos);
const lastCode = codeInfos[codeInfos.length - 1];
expect(lastCode.codeId!.toNumber()).toEqual(hackatomCodeId);
expect(lastCode.codeId.toNumber()).toEqual(hackatomCodeId);
expect(lastCode.creator).toEqual(alice.address0);
expect(lastCode.source).toEqual(hackatom.source);
expect(lastCode.builder).toEqual(hackatom.builder);
expect(toHex(lastCode.dataHash!)).toEqual(toHex(sha256(hackatom.data)));
expect(lastCode.source).toEqual(hackatom.source ?? "");
expect(lastCode.builder).toEqual(hackatom.builder ?? "");
expect(toHex(lastCode.dataHash)).toEqual(toHex(sha256(hackatom.data)));
});
});
@ -171,11 +170,11 @@ describe("WasmExtension", () => {
assert(hackatomCodeId);
const client = await makeWasmClient(wasmd.endpoint);
const { codeInfo, data } = await client.unverified.wasm.getCode(hackatomCodeId);
expect(codeInfo!.codeId!.toNumber()).toEqual(hackatomCodeId);
expect(codeInfo!.codeId.toNumber()).toEqual(hackatomCodeId);
expect(codeInfo!.creator).toEqual(alice.address0);
expect(codeInfo!.source).toEqual(hackatom.source);
expect(codeInfo!.builder).toEqual(hackatom.builder);
expect(toHex(codeInfo!.dataHash!)).toEqual(toHex(sha256(hackatom.data)));
expect(codeInfo!.source).toEqual(hackatom.source ?? "");
expect(codeInfo!.builder).toEqual(hackatom.builder ?? "");
expect(toHex(codeInfo!.dataHash)).toEqual(toHex(sha256(hackatom.data)));
expect(data).toEqual(hackatom.data);
});
});
@ -197,9 +196,9 @@ describe("WasmExtension", () => {
assert(existingContractInfos);
for (const { address, contractInfo } of existingContractInfos) {
expect(address).toMatch(bech32AddressMatcher);
expect(contractInfo!.codeId!.toNumber()).toEqual(hackatomCodeId);
expect(contractInfo!.creator).toMatch(bech32AddressMatcher);
expect(contractInfo!.label).toMatch(/^.+$/);
expect(contractInfo.codeId!.toNumber()).toEqual(hackatomCodeId);
expect(contractInfo.creator).toMatch(bech32AddressMatcher);
expect(contractInfo.label).toMatch(/^.+$/);
}
const result = await instantiateContract(wallet, hackatomCodeId, beneficiaryAddress, transferAmount);
@ -263,8 +262,7 @@ describe("WasmExtension", () => {
expect(history.entries).toContain(
jasmine.objectContaining({
codeId: Long.fromNumber(hackatomCodeId, true),
operation:
cosmwasm.wasm.v1beta1.ContractCodeHistoryOperationType.CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT,
operation: ContractCodeHistoryOperationType.CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT,
msg: toAscii(
JSON.stringify({
verifier: alice.address0,
@ -330,7 +328,7 @@ describe("WasmExtension", () => {
hackatomContractAddress,
fromHex("cafe0dad"),
);
expect({ ...response }).toEqual({});
expect({ ...response }).toEqual({ data: new Uint8Array() });
});
it("returns null for non-existent address", async () => {
@ -399,7 +397,7 @@ describe("WasmExtension", () => {
const msgData = fromOneElementArray(result.data);
expect(msgData.msgType).toEqual("store-code");
expect(MsgStoreCodeResponse.decode(msgData.data!)).toEqual(
MsgStoreCodeResponse.create({ codeId: Long.fromNumber(codeId, true) }),
MsgStoreCodeResponse.fromPartial({ codeId: Long.fromNumber(codeId, true) }),
);
}
@ -419,7 +417,7 @@ describe("WasmExtension", () => {
const msgData = fromOneElementArray(result.data);
expect(msgData.msgType).toEqual("instantiate");
expect(MsgInstantiateContractResponse.decode(msgData.data!)).toEqual(
MsgInstantiateContractResponse.create({ address: contractAddress }),
MsgInstantiateContractResponse.fromPartial({ address: contractAddress }),
);
const balanceUcosm = await client.bank.balance(contractAddress, "ucosm");
@ -445,7 +443,7 @@ describe("WasmExtension", () => {
const msgData = fromOneElementArray(result.data);
expect(msgData.msgType).toEqual("execute");
expect(MsgExecuteContractResponse.decode(msgData.data!)).toEqual(
MsgExecuteContractResponse.create({ data: fromHex("F00BAA") }),
MsgExecuteContractResponse.fromPartial({ data: fromHex("F00BAA") }),
);
// Verify token transfer from contract to beneficiary

View File

@ -4,43 +4,42 @@ import { fromUtf8, toAscii } from "@cosmjs/encoding";
import { QueryClient } from "@cosmjs/stargate";
import Long from "long";
import { cosmwasm } from "../codec";
type IQueryAllContractStateResponse = cosmwasm.wasm.v1beta1.IQueryAllContractStateResponse;
type IQueryCodesResponse = cosmwasm.wasm.v1beta1.IQueryCodesResponse;
type IQueryCodeResponse = cosmwasm.wasm.v1beta1.IQueryCodeResponse;
type IQueryContractHistoryResponse = cosmwasm.wasm.v1beta1.IQueryContractHistoryResponse;
type IQueryContractInfoResponse = cosmwasm.wasm.v1beta1.IQueryContractInfoResponse;
type IQueryContractsByCodeResponse = cosmwasm.wasm.v1beta1.IQueryContractsByCodeResponse;
type IQueryRawContractStateResponse = cosmwasm.wasm.v1beta1.IQueryRawContractStateResponse;
const { Query } = cosmwasm.wasm.v1beta1;
import {
QueryAllContractStateResponse,
QueryClientImpl,
QueryCodeResponse,
QueryCodesResponse,
QueryContractHistoryResponse,
QueryContractInfoResponse,
QueryContractsByCodeResponse,
QueryRawContractStateResponse,
} from "../codec/x/wasm/internal/types/query";
export interface WasmExtension {
readonly unverified: {
readonly wasm: {
readonly listCodeInfo: (paginationKey?: Uint8Array) => Promise<IQueryCodesResponse>;
readonly listCodeInfo: (paginationKey?: Uint8Array) => Promise<QueryCodesResponse>;
/**
* Downloads the original wasm bytecode by code ID.
*
* Throws an error if no code with this id
*/
readonly getCode: (id: number) => Promise<IQueryCodeResponse>;
readonly getCode: (id: number) => Promise<QueryCodeResponse>;
readonly listContractsByCodeId: (
id: number,
paginationKey?: Uint8Array,
) => Promise<IQueryContractsByCodeResponse>;
) => Promise<QueryContractsByCodeResponse>;
/**
* Returns null when contract was not found at this address.
*/
readonly getContractInfo: (address: string) => Promise<IQueryContractInfoResponse>;
readonly getContractInfo: (address: string) => Promise<QueryContractInfoResponse>;
/**
* Returns null when contract history was not found for this address.
*/
readonly getContractCodeHistory: (
address: string,
paginationKey?: Uint8Array,
) => Promise<IQueryContractHistoryResponse>;
) => Promise<QueryContractHistoryResponse>;
/**
* Returns all contract state.
* This is an empty array if no such contract, or contract has no data.
@ -48,15 +47,12 @@ export interface WasmExtension {
readonly getAllContractState: (
address: string,
paginationKey?: Uint8Array,
) => Promise<IQueryAllContractStateResponse>;
) => Promise<QueryAllContractStateResponse>;
/**
* Returns the data at the key if present (unknown decoded json),
* or null if no data at this (contract address, key) pair
*/
readonly queryContractRaw: (
address: string,
key: Uint8Array,
) => Promise<IQueryRawContractStateResponse>;
readonly queryContractRaw: (address: string, key: Uint8Array) => Promise<QueryRawContractStateResponse>;
/**
* Makes a smart query on the contract and parses the response as JSON.
* Throws error if no such contract exists, the query format is invalid or the response is invalid.
@ -67,54 +63,53 @@ export interface WasmExtension {
}
export function setupWasmExtension(base: QueryClient): WasmExtension {
const queryService = Query.create((method: any, requestData, callback) => {
const path = `/cosmwasm.wasm.v1beta1.Query/${method.name}`;
base
.queryUnverified(path, requestData)
.then((response) => callback(null, response))
.catch((error) => callback(error));
const queryService = new QueryClientImpl({
request: (service: string, method: string, data: Uint8Array): Promise<Uint8Array> => {
const path = `/cosmwasm.wasm.v1beta1.Query/${method}`;
return base.queryUnverified(path, data);
},
});
return {
unverified: {
wasm: {
listCodeInfo: async (paginationKey?: Uint8Array) => {
const request = paginationKey ? { pagination: { key: paginationKey } } : {};
return queryService.codes(request);
return queryService.Codes(request);
},
getCode: async (id: number) => {
const request = { codeId: Long.fromNumber(id) };
return queryService.code(request);
return queryService.Code(request);
},
listContractsByCodeId: async (id: number, paginationKey?: Uint8Array) => {
const pagination = paginationKey ? { pagination: { key: paginationKey } } : {};
const request = { ...pagination, codeId: Long.fromNumber(id) };
return queryService.contractsByCode(request);
return queryService.ContractsByCode(request);
},
getContractInfo: async (address: string) => {
const request = { address: address };
return queryService.contractInfo(request);
return queryService.ContractInfo(request);
},
getContractCodeHistory: async (address: string, paginationKey?: Uint8Array) => {
const pagination = paginationKey ? { pagination: { key: paginationKey } } : {};
const request = { ...pagination, address: address };
return queryService.contractHistory(request);
return queryService.ContractHistory(request);
},
getAllContractState: async (address: string, paginationKey?: Uint8Array) => {
const pagination = paginationKey ? { pagination: { key: paginationKey } } : {};
const request = { ...pagination, address: address };
return queryService.allContractState(request);
return queryService.AllContractState(request);
},
queryContractRaw: async (address: string, key: Uint8Array) => {
const request = { address: address, queryData: key };
return queryService.rawContractState(request);
return queryService.RawContractState(request);
},
queryContractSmart: async (address: string, query: Record<string, unknown>) => {
const request = { address: address, queryData: toAscii(JSON.stringify(query)) };
const { data } = await queryService.smartContractState(request);
const { data } = await queryService.SmartContractState(request);
// By convention, smart queries must return a valid JSON document (see https://github.com/CosmWasm/cosmwasm/issues/144)
try {
return JSON.parse(fromUtf8(data));

View File

@ -9,14 +9,18 @@ import {
MsgDelegate as LaunchpadMsgDelegate,
Secp256k1HdWallet,
} from "@cosmjs/launchpad";
import { Coin, cosmosField, DirectSecp256k1HdWallet, registered, Registry } from "@cosmjs/proto-signing";
import { AminoTypes, assertIsBroadcastTxSuccess, codec } from "@cosmjs/stargate";
import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
import { AminoTypes, assertIsBroadcastTxSuccess } from "@cosmjs/stargate";
import { MsgSend } from "@cosmjs/stargate/src/codec/cosmos/bank/v1beta1/tx";
import { Coin } from "@cosmjs/stargate/src/codec/cosmos/base/v1beta1/coin";
import { MsgDelegate } from "@cosmjs/stargate/src/codec/cosmos/staking/v1beta1/tx";
import { Tx } from "@cosmjs/stargate/src/codec/cosmos/tx/v1beta1/tx";
import { assert, sleep } from "@cosmjs/utils";
import Long from "long";
import pako from "pako";
import { Message } from "protobufjs";
import { cosmwasm } from "./codec";
import { MsgStoreCode } from "./codec/x/wasm/internal/types/tx";
import { PrivateSigningCosmWasmClient, SigningCosmWasmClient } from "./signingcosmwasmclient";
import {
alice,
@ -31,14 +35,6 @@ import {
wasmd,
} from "./testutils.spec";
type IMsgSend = codec.cosmos.bank.v1beta1.IMsgSend;
type IMsgDelegate = codec.cosmos.staking.v1beta1.IMsgDelegate;
type IMsgStoreCode = cosmwasm.wasm.v1beta1.IMsgStoreCode;
const { MsgSend } = codec.cosmos.bank.v1beta1;
const { MsgDelegate } = codec.cosmos.staking.v1beta1;
const { Tx } = codec.cosmos.tx.v1beta1;
describe("SigningCosmWasmClient", () => {
describe("connectWithSigner", () => {
it("can be constructed", async () => {
@ -515,7 +511,7 @@ describe("SigningCosmWasmClient", () => {
const options = { prefix: wasmd.prefix, registry: registry };
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const msg = MsgDelegate.create({
const msg = MsgDelegate.fromPartial({
delegatorAddress: alice.address0,
validatorAddress: validator.validatorAddress,
amount: coin(1234, "ustake"),
@ -546,7 +542,7 @@ describe("SigningCosmWasmClient", () => {
const options = { prefix: wasmd.prefix, registry: registry };
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const msg = MsgDelegate.create({
const msg = MsgDelegate.fromPartial({
delegatorAddress: alice.address0,
validatorAddress: validator.validatorAddress,
amount: coin(1234, "ustake"),
@ -570,8 +566,8 @@ describe("SigningCosmWasmClient", () => {
const tx = Tx.decode(searchResult.tx);
// From ModifyingDirectSecp256k1HdWallet
expect(tx.body!.memo).toEqual("This was modified");
expect({ ...tx.authInfo!.fee!.amount![0] }).toEqual(coin(3000, "ucosm"));
expect(tx.authInfo!.fee!.gasLimit!.toNumber()).toEqual(333333);
expect({ ...tx.authInfo!.fee!.amount[0] }).toEqual(coin(3000, "ucosm"));
expect(tx.authInfo!.fee!.gasLimit.toNumber()).toEqual(333333);
});
});
@ -582,15 +578,10 @@ describe("SigningCosmWasmClient", () => {
const customRegistry = new Registry();
const msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate";
@registered(customRegistry, msgDelegateTypeUrl)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class CustomMsgDelegate extends Message {
@cosmosField.string(1)
public readonly custom_delegator_address?: string;
@cosmosField.string(2)
public readonly custom_validator_address?: string;
@cosmosField.message(3, Coin)
public readonly custom_amount?: Coin;
interface CustomMsgDelegate {
readonly customDelegatorAddress?: string;
readonly customValidatorAddress?: string;
readonly customAmount?: Coin;
}
it("works with bank MsgSend", async () => {
@ -599,7 +590,7 @@ describe("SigningCosmWasmClient", () => {
const options = { prefix: wasmd.prefix };
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const msgSend: IMsgSend = {
const msgSend: MsgSend = {
fromAddress: alice.address0,
toAddress: makeRandomAddress(),
amount: coins(1234, "ucosm"),
@ -623,7 +614,7 @@ describe("SigningCosmWasmClient", () => {
const options = { prefix: wasmd.prefix };
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const msgDelegate: IMsgDelegate = {
const msgDelegate: MsgDelegate = {
delegatorAddress: alice.address0,
validatorAddress: validator.validatorAddress,
amount: coin(1234, "ustake"),
@ -648,11 +639,11 @@ describe("SigningCosmWasmClient", () => {
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const { data, builder, source } = getHackatom();
const msgStoreCode: IMsgStoreCode = {
const msgStoreCode: MsgStoreCode = {
sender: alice.address0,
wasmByteCode: pako.gzip(data),
source: source,
builder: builder,
source: source ?? "",
builder: builder ?? "",
};
const msgAny = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgStoreCode",
@ -676,21 +667,21 @@ describe("SigningCosmWasmClient", () => {
"/cosmos.staking.v1beta1.MsgDelegate": {
aminoType: "cosmos-sdk/MsgDelegate",
toAmino: ({
custom_delegator_address,
custom_validator_address,
custom_amount,
customDelegatorAddress,
customValidatorAddress,
customAmount,
}: CustomMsgDelegate): LaunchpadMsgDelegate["value"] => {
assert(custom_delegator_address, "missing custom_delegator_address");
assert(custom_validator_address, "missing validator_address");
assert(custom_amount, "missing amount");
assert(custom_amount.amount, "missing amount.amount");
assert(custom_amount.denom, "missing amount.denom");
assert(customDelegatorAddress, "missing customDelegatorAddress");
assert(customValidatorAddress, "missing validator_address");
assert(customAmount, "missing amount");
assert(customAmount.amount, "missing amount.amount");
assert(customAmount.denom, "missing amount.denom");
return {
delegator_address: custom_delegator_address,
validator_address: custom_validator_address,
delegator_address: customDelegatorAddress,
validator_address: customValidatorAddress,
amount: {
amount: custom_amount.amount,
denom: custom_amount.denom,
amount: customAmount.amount,
denom: customAmount.denom,
},
};
},
@ -698,12 +689,11 @@ describe("SigningCosmWasmClient", () => {
delegator_address,
validator_address,
amount,
}: LaunchpadMsgDelegate["value"]): CustomMsgDelegate =>
CustomMsgDelegate.create({
custom_delegator_address: delegator_address,
custom_validator_address: validator_address,
custom_amount: Coin.create(amount),
}),
}: LaunchpadMsgDelegate["value"]): CustomMsgDelegate => ({
customDelegatorAddress: delegator_address,
customValidatorAddress: validator_address,
customAmount: Coin.fromPartial(amount),
}),
},
},
});
@ -711,9 +701,9 @@ describe("SigningCosmWasmClient", () => {
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, options);
const msg = {
custom_delegator_address: alice.address0,
custom_validator_address: validator.validatorAddress,
custom_amount: coin(1234, "ustake"),
customDelegatorAddress: alice.address0,
customValidatorAddress: validator.validatorAddress,
customAmount: coin(1234, "ustake"),
};
const msgAny = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",

View File

@ -38,29 +38,26 @@ import {
AminoTypes,
BroadcastTxFailure,
BroadcastTxResponse,
codec,
defaultRegistryTypes,
isBroadcastTxFailure,
parseRawLog,
} from "@cosmjs/stargate";
import { SignMode } from "@cosmjs/stargate/src/codec/cosmos/tx/signing/v1beta1/signing";
import { TxRaw } from "@cosmjs/stargate/src/codec/cosmos/tx/v1beta1/tx";
import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc";
import Long from "long";
import pako from "pako";
import { cosmWasmTypes } from "./aminotypes";
import { cosmwasm } from "./codec";
import { CosmWasmClient } from "./cosmwasmclient";
const { SignMode } = codec.cosmos.tx.signing.v1beta1;
const { TxRaw } = codec.cosmos.tx.v1beta1;
const {
import {
MsgClearAdmin,
MsgExecuteContract,
MsgInstantiateContract,
MsgMigrateContract,
MsgStoreCode,
MsgUpdateAdmin,
} = cosmwasm.wasm.v1beta1;
} from "./codec/x/wasm/internal/types/tx";
import { CosmWasmClient } from "./cosmwasmclient";
function prepareBuilder(builder: string | undefined): string {
if (builder === undefined) {
@ -156,7 +153,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
const compressed = pako.gzip(wasmCode, { level: 9 });
const storeCodeMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgStoreCode",
value: MsgStoreCode.create({
value: MsgStoreCode.fromPartial({
sender: senderAddress,
wasmByteCode: compressed,
source: source,
@ -190,7 +187,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
): Promise<InstantiateResult> {
const instantiateMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgInstantiateContract",
value: MsgInstantiateContract.create({
value: MsgInstantiateContract.fromPartial({
sender: senderAddress,
codeId: Long.fromString(new Uint53(codeId).toString()),
label: label,
@ -220,7 +217,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
): Promise<ChangeAdminResult> {
const updateAdminMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgUpdateAdmin",
value: MsgUpdateAdmin.create({
value: MsgUpdateAdmin.fromPartial({
sender: senderAddress,
contract: contractAddress,
newAdmin: newAdmin,
@ -243,7 +240,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
): Promise<ChangeAdminResult> {
const clearAdminMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgClearAdmin",
value: MsgClearAdmin.create({
value: MsgClearAdmin.fromPartial({
sender: senderAddress,
contract: contractAddress,
}),
@ -267,7 +264,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
): Promise<MigrateResult> {
const msg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgMigrateContract",
value: MsgMigrateContract.create({
value: MsgMigrateContract.fromPartial({
sender: senderAddress,
contract: contractAddress,
codeId: Long.fromString(new Uint53(codeId).toString()),
@ -293,7 +290,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
): Promise<ExecuteResult> {
const executeMsg = {
typeUrl: "/cosmwasm.wasm.v1beta1.MsgExecuteContract",
value: MsgExecuteContract.create({
value: MsgExecuteContract.fromPartial({
sender: senderAddress,
contract: contractAddress,
msg: toAscii(JSON.stringify(handleMsg)),
@ -372,7 +369,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
const authInfoBytes = makeAuthInfoBytes([pubkeyAny], fee.amount, gasLimit, sequence);
const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber);
const { signature, signed } = await this.signer.signDirect(signerAddress, signDoc);
const txRaw = TxRaw.create({
const txRaw = TxRaw.fromPartial({
bodyBytes: signed.bodyBytes,
authInfoBytes: signed.authInfoBytes,
signatures: [fromBase64(signature.signature)],
@ -403,7 +400,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
signedSequence,
signMode,
);
const txRaw = TxRaw.create({
const txRaw = TxRaw.fromPartial({
bodyBytes: signedTxBodyBytes,
authInfoBytes: signedAuthInfoBytes,
signatures: [fromBase64(signature.signature)],

View File

@ -12,20 +12,17 @@ import { DirectSecp256k1HdWallet, DirectSignResponse, makeAuthInfoBytes } from "
import {
AuthExtension,
BankExtension,
codec,
QueryClient,
setupAuthExtension,
setupBankExtension,
} from "@cosmjs/stargate";
import { SignMode } from "@cosmjs/stargate/src/codec/cosmos/tx/signing/v1beta1/signing";
import { AuthInfo, SignDoc, TxBody } from "@cosmjs/stargate/src/codec/cosmos/tx/v1beta1/tx";
import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc";
import { setupWasmExtension, WasmExtension } from "./queries";
import hackatom from "./testdata/contract.json";
type ISignDoc = codec.cosmos.tx.v1beta1.ISignDoc;
const { AuthInfo, TxBody } = codec.cosmos.tx.v1beta1;
const { SignMode } = codec.cosmos.tx.signing.v1beta1;
/** An internal testing type. SigningCosmWasmClient has a similar but different interface */
export interface ContractUploadInstructions {
/** The wasm bytecode */
@ -268,15 +265,15 @@ export class ModifyingDirectSecp256k1HdWallet extends DirectSecp256k1HdWallet {
);
}
public async signDirect(address: string, signDoc: ISignDoc): Promise<DirectSignResponse> {
const txBody = TxBody.decode(signDoc.bodyBytes!);
const modifiedTxBody = TxBody.create({
public async signDirect(address: string, signDoc: SignDoc): Promise<DirectSignResponse> {
const txBody = TxBody.decode(signDoc.bodyBytes);
const modifiedTxBody = TxBody.fromPartial({
...txBody,
memo: "This was modified",
});
const authInfo = AuthInfo.decode(signDoc.authInfoBytes!);
const authInfo = AuthInfo.decode(signDoc.authInfoBytes);
const pubkeys = authInfo.signerInfos.map((signerInfo) => signerInfo.publicKey!);
const sequence = authInfo.signerInfos[0].sequence!.toNumber();
const sequence = authInfo.signerInfos[0].sequence.toNumber();
const modifiedFeeAmount = coins(3000, "ucosm");
const modifiedGasLimit = 333333;
const modifiedSignDoc = {