Pull out wasm contract actions as test helper functions
This commit is contained in:
parent
477511f1b3
commit
da9eff547e
@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { ChainId, PrehashType, SignableBytes } from "@iov/bcp";
|
||||
import { ChainId, Identity, PrehashType, SignableBytes } from "@iov/bcp";
|
||||
import { Random } from "@iov/crypto";
|
||||
import { Bech32, Encoding } from "@iov/encoding";
|
||||
import { HdPaths, Secp256k1HdWallet } from "@iov/keycontrol";
|
||||
@ -7,7 +7,7 @@ import { HdPaths, Secp256k1HdWallet } from "@iov/keycontrol";
|
||||
import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
|
||||
import { leb128Encode } from "./leb128.spec";
|
||||
import { Attribute, Log, parseLogs } from "./logs";
|
||||
import { RestClient } from "./restclient";
|
||||
import { PostTxsResponse, RestClient } from "./restclient";
|
||||
import contract from "./testdata/contract.json";
|
||||
import cosmoshub from "./testdata/cosmoshub.json";
|
||||
import {
|
||||
@ -174,6 +174,112 @@ describe("RestClient", () => {
|
||||
expect(result.code).toBeFalsy();
|
||||
});
|
||||
|
||||
async function uploadContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
): Promise<PostTxsResponse> {
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgStoreCode = {
|
||||
type: "wasm/store-code",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
wasm_byte_code: toBase64(getRandomizedContract()),
|
||||
source: "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm",
|
||||
builder: "cosmwasm-opt:0.6.2",
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
async function instantiateContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
codeId: number,
|
||||
beneficiaryAddress: string,
|
||||
transferAmount: readonly Coin[],
|
||||
): Promise<PostTxsResponse> {
|
||||
const memo = "Create an escrow instance";
|
||||
const theMsg: MsgInstantiateContract = {
|
||||
type: "wasm/instantiate",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
code_id: codeId.toString(),
|
||||
init_msg: {
|
||||
verifier: faucetAddress,
|
||||
beneficiary: beneficiaryAddress,
|
||||
},
|
||||
init_funds: transferAmount,
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
async function executeContract(
|
||||
client: RestClient,
|
||||
wallet: Secp256k1HdWallet,
|
||||
signer: Identity,
|
||||
contractAddress: string,
|
||||
): Promise<PostTxsResponse> {
|
||||
const memo = "Time for action";
|
||||
const theMsg: MsgExecuteContract = {
|
||||
type: "wasm/execute",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
contract: contractAddress,
|
||||
msg: {},
|
||||
sent_funds: [],
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
return client.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
it("can upload, instantiate and execute wasm", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const wallet = Secp256k1HdWallet.fromMnemonic(faucetMnemonic);
|
||||
@ -196,33 +302,8 @@ describe("RestClient", () => {
|
||||
|
||||
// upload
|
||||
{
|
||||
const memo = "My first contract on chain";
|
||||
const theMsg: MsgStoreCode = {
|
||||
type: "wasm/store-code",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
wasm_byte_code: toBase64(getRandomizedContract()),
|
||||
source: "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm",
|
||||
builder: "cosmwasm-opt:0.6.2",
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
const result = await client.postTx(marshalTx(signedTx));
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const result = await uploadContract(client, wallet, signer);
|
||||
expect(result.code).toBeFalsy();
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
const codeIdAttr = findAttribute(logs, "message", "code_id");
|
||||
@ -235,35 +316,14 @@ describe("RestClient", () => {
|
||||
|
||||
// instantiate
|
||||
{
|
||||
const memo = "Create an escrow instance";
|
||||
const theMsg: MsgInstantiateContract = {
|
||||
type: "wasm/instantiate",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
code_id: codeId.toString(),
|
||||
init_msg: {
|
||||
verifier: faucetAddress,
|
||||
beneficiary: beneficiaryAddress,
|
||||
},
|
||||
init_funds: transferAmount,
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
const result = await client.postTx(marshalTx(signedTx));
|
||||
const result = await instantiateContract(
|
||||
client,
|
||||
wallet,
|
||||
signer,
|
||||
codeId,
|
||||
beneficiaryAddress,
|
||||
transferAmount,
|
||||
);
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const logs = parseSuccess(result.raw_log);
|
||||
@ -278,32 +338,7 @@ describe("RestClient", () => {
|
||||
|
||||
// execute
|
||||
{
|
||||
const memo = "Time for action";
|
||||
const theMsg: MsgExecuteContract = {
|
||||
type: "wasm/execute",
|
||||
value: {
|
||||
sender: faucetAddress,
|
||||
contract: contractAddress,
|
||||
msg: {},
|
||||
sent_funds: [],
|
||||
},
|
||||
};
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "89000000",
|
||||
};
|
||||
|
||||
const account = (await client.authAccounts(faucetAddress)).result.value;
|
||||
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account) as SignableBytes;
|
||||
const rawSignature = await wallet.createTransactionSignature(signer, signBytes, PrehashType.Sha256);
|
||||
const signature = encodeSecp256k1Signature(signer.pubkey.data, rawSignature);
|
||||
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
|
||||
const result = await client.postTx(marshalTx(signedTx));
|
||||
const result = await executeContract(client, wallet, signer, contractAddress);
|
||||
expect(result.code).toBeFalsy();
|
||||
// console.log("Raw log:", result.raw_log);
|
||||
const [firstLog] = parseSuccess(result.raw_log);
|
||||
|
||||
@ -73,7 +73,7 @@ interface SearchTxsResponse {
|
||||
|
||||
interface PostTxsParams {}
|
||||
|
||||
interface PostTxsResponse {
|
||||
export interface PostTxsResponse {
|
||||
readonly height: string;
|
||||
readonly txhash: string;
|
||||
readonly code?: number;
|
||||
@ -236,6 +236,7 @@ export class RestClient {
|
||||
// this will download the original wasm bytecode by code id
|
||||
// throws error if no code with this id
|
||||
public async getCode(id: number): Promise<Uint8Array> {
|
||||
// TODO: broken currently
|
||||
const path = `/wasm/code/${id}`;
|
||||
const responseData = await this.get(path);
|
||||
const { code } = parseWasmResponse(responseData as WasmResponse);
|
||||
|
||||
18
packages/sdk/types/restclient.d.ts
vendored
18
packages/sdk/types/restclient.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { AminoTx, BaseAccount, CodeInfo, CodeInfoWithId, ContractInfo, StdTx } from "./types";
|
||||
import { AminoTx, BaseAccount, CodeInfo, ContractInfo, StdTx, WasmData } from "./types";
|
||||
interface NodeInfo {
|
||||
readonly network: string;
|
||||
}
|
||||
@ -29,9 +29,14 @@ interface AuthAccountsResponse {
|
||||
readonly value: BaseAccount;
|
||||
};
|
||||
}
|
||||
interface WasmResponse {
|
||||
declare type WasmResponse = WasmSuccess | WasmError;
|
||||
interface WasmSuccess {
|
||||
readonly height: string;
|
||||
readonly result: string;
|
||||
}
|
||||
interface WasmError {
|
||||
readonly error: string;
|
||||
}
|
||||
export interface TxsResponse {
|
||||
readonly height: string;
|
||||
readonly txhash: string;
|
||||
@ -47,7 +52,7 @@ interface SearchTxsResponse {
|
||||
readonly txs: readonly TxsResponse[];
|
||||
}
|
||||
interface PostTxsParams {}
|
||||
interface PostTxsResponse {
|
||||
export interface PostTxsResponse {
|
||||
readonly height: string;
|
||||
readonly txhash: string;
|
||||
readonly code?: number;
|
||||
@ -87,9 +92,12 @@ export declare class RestClient {
|
||||
txs(query: string): Promise<SearchTxsResponse>;
|
||||
txsById(id: string): Promise<TxsResponse>;
|
||||
postTx(tx: Uint8Array): Promise<PostTxsResponse>;
|
||||
listCodeInfo(): Promise<readonly CodeInfoWithId[]>;
|
||||
getCodeInfo(id: number): Promise<CodeInfo>;
|
||||
listCodeInfo(): Promise<readonly CodeInfo[]>;
|
||||
getCode(id: number): Promise<Uint8Array>;
|
||||
listContractAddresses(): Promise<readonly string[]>;
|
||||
getContractInfo(address: string): Promise<ContractInfo>;
|
||||
getAllContractState(address: string): Promise<readonly WasmData[]>;
|
||||
getContractKey(address: string, key: Uint8Array): Promise<unknown | null>;
|
||||
queryContract(address: string, query: object): Promise<unknown>;
|
||||
}
|
||||
export {};
|
||||
|
||||
9
packages/sdk/types/types.d.ts
vendored
9
packages/sdk/types/types.d.ts
vendored
@ -121,6 +121,7 @@ export interface BaseAccount {
|
||||
/** The data we need from BaseAccount to create a nonce */
|
||||
export declare type NonceInfo = Pick<BaseAccount, "account_number" | "sequence">;
|
||||
export interface CodeInfo {
|
||||
readonly id: number;
|
||||
/** Bech32 account address */
|
||||
readonly creator: string;
|
||||
/** Hex-encoded sha256 hash of the code stored here */
|
||||
@ -128,8 +129,8 @@ export interface CodeInfo {
|
||||
readonly source?: string;
|
||||
readonly builder?: string;
|
||||
}
|
||||
export interface CodeInfoWithId extends CodeInfo {
|
||||
readonly id: number;
|
||||
export interface CodeDetails {
|
||||
readonly code: string;
|
||||
}
|
||||
export interface ContractInfo {
|
||||
readonly code_id: number;
|
||||
@ -138,4 +139,8 @@ export interface ContractInfo {
|
||||
/** Argument passed on initialization of the contract */
|
||||
readonly init_msg: object;
|
||||
}
|
||||
export interface WasmData {
|
||||
readonly key: string;
|
||||
readonly val: unknown;
|
||||
}
|
||||
export {};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user