Merge pull request #131 from confio/cosmwasm-client-types
CosmWasmClient types
This commit is contained in:
commit
792e133b29
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.7.0-alpha.2",
|
||||
"version": "0.7.0-alpha.4",
|
||||
"useWorkspaces": true,
|
||||
"npmClient": "yarn"
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cosmwasm/bcp",
|
||||
"version": "0.7.0-alpha.2",
|
||||
"version": "0.7.0-alpha.4",
|
||||
"description": "Transaction codec and client to communicate with any wasmd blockchain",
|
||||
"author": "Ethan Frey <ethanfrey@users.noreply.github.com>",
|
||||
"license": "Apache-2.0",
|
||||
@ -38,7 +38,7 @@
|
||||
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cosmwasm/sdk": "^0.7.0-alpha.2",
|
||||
"@cosmwasm/sdk": "^0.7.0-alpha.4",
|
||||
"@iov/bcp": "^2.1.0",
|
||||
"@iov/crypto": "^2.1.0",
|
||||
"@iov/encoding": "^2.1.0",
|
||||
|
||||
@ -1,22 +1,11 @@
|
||||
import { Algorithm, PubkeyBytes } from "@iov/bcp";
|
||||
import { Encoding } from "@iov/encoding";
|
||||
|
||||
import { decodeCosmosPubkey, pubkeyToAddress } from "./address";
|
||||
import { pubkeyToAddress } from "./address";
|
||||
|
||||
const { fromBase64, fromHex } = Encoding;
|
||||
|
||||
describe("address", () => {
|
||||
describe("decodeCosmosPubkey", () => {
|
||||
it("works", () => {
|
||||
expect(
|
||||
decodeCosmosPubkey("cosmospub1addwnpepqd8sgxq7aw348ydctp3n5ajufgxp395hksxjzc6565yfp56scupfqhlgyg5"),
|
||||
).toEqual({
|
||||
data: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"),
|
||||
algo: Algorithm.Secp256k1,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("pubkeyToAddress", () => {
|
||||
it("works for Secp256k1 compressed", () => {
|
||||
const prefix = "cosmos";
|
||||
|
||||
@ -1,21 +1,9 @@
|
||||
import { decodeBech32Pubkey, pubkeyToAddress as sdkPubkeyToAddress, types } from "@cosmwasm/sdk";
|
||||
import { Address, Algorithm, PubkeyBundle, PubkeyBytes } from "@iov/bcp";
|
||||
import { pubkeyToAddress as sdkPubkeyToAddress, types } from "@cosmwasm/sdk";
|
||||
import { Address, Algorithm, PubkeyBundle } from "@iov/bcp";
|
||||
import { Secp256k1 } from "@iov/crypto";
|
||||
import { Encoding } from "@iov/encoding";
|
||||
|
||||
const { fromBase64, toBase64 } = Encoding;
|
||||
|
||||
export function decodeCosmosPubkey(encodedPubkey: string): PubkeyBundle {
|
||||
const sdkPubKey = decodeBech32Pubkey(encodedPubkey);
|
||||
switch (sdkPubKey.type) {
|
||||
case types.pubkeyType.secp256k1:
|
||||
return { algo: Algorithm.Secp256k1, data: fromBase64(sdkPubKey.value) as PubkeyBytes };
|
||||
case types.pubkeyType.ed25519:
|
||||
return { algo: Algorithm.Ed25519, data: fromBase64(sdkPubKey.value) as PubkeyBytes };
|
||||
default:
|
||||
throw new Error("Unsupported Pubkey type: " + sdkPubKey.type);
|
||||
}
|
||||
}
|
||||
const { toBase64 } = Encoding;
|
||||
|
||||
// See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography
|
||||
export function pubkeyToAddress(pubkey: PubkeyBundle, prefix: string): Address {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { CosmWasmClient, findSequenceForSignedTx, SearchTxFilter, TxsResponse, types } from "@cosmwasm/sdk";
|
||||
import { CosmWasmClient, findSequenceForSignedTx, IndexedTx, SearchTxFilter, types } from "@cosmwasm/sdk";
|
||||
import {
|
||||
Account,
|
||||
AccountQuery,
|
||||
@ -37,10 +36,10 @@ import equal from "fast-deep-equal";
|
||||
import { ReadonlyDate } from "readonly-date";
|
||||
import { Producer, Stream } from "xstream";
|
||||
|
||||
import { decodeCosmosPubkey, pubkeyToAddress } from "./address";
|
||||
import { pubkeyToAddress } from "./address";
|
||||
import { Caip5 } from "./caip5";
|
||||
import { CosmWasmCodec } from "./cosmwasmcodec";
|
||||
import { decodeAmount, parseTxsResponseSigned, parseTxsResponseUnsigned } from "./decode";
|
||||
import { decodeAmount, decodePubkey, parseTxsResponseSigned, parseTxsResponseUnsigned } from "./decode";
|
||||
import { buildSignedTx } from "./encode";
|
||||
import { accountToNonce, BankToken, Erc20Token } from "./types";
|
||||
|
||||
@ -71,11 +70,11 @@ function deduplicate<T>(input: ReadonlyArray<T>, comparator: (a: T, b: T) => num
|
||||
}
|
||||
|
||||
/** Compares transaxtion by height. If the height is equal, compare by hash to ensure deterministic order */
|
||||
function compareByHeightAndHash(a: TxsResponse, b: TxsResponse): number {
|
||||
function compareByHeightAndHash(a: IndexedTx, b: IndexedTx): number {
|
||||
if (a.height === b.height) {
|
||||
return a.txhash.localeCompare(b.txhash);
|
||||
return a.hash.localeCompare(b.hash);
|
||||
} else {
|
||||
return parseInt(a.height, 10) - parseInt(b.height, 10);
|
||||
return a.height - b.height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,8 +138,8 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
}
|
||||
|
||||
public async height(): Promise<number> {
|
||||
const { block } = await this.cosmWasmClient.getBlock();
|
||||
return parseInt(block.header.height, 10);
|
||||
const { header } = await this.cosmWasmClient.getBlock();
|
||||
return header.height;
|
||||
}
|
||||
|
||||
public async getToken(searchTicker: TokenTicker): Promise<Token | undefined> {
|
||||
@ -165,7 +164,7 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
const address = isPubkeyQuery(query) ? pubkeyToAddress(query.pubkey, this.addressPrefix) : query.address;
|
||||
const bankAccount = await this.cosmWasmClient.getAccount(address);
|
||||
|
||||
const supportedBankCoins = (bankAccount?.coins || []).filter(({ denom }) =>
|
||||
const supportedBankCoins = (bankAccount?.balance || []).filter(({ denom }) =>
|
||||
this.bankTokens.find(token => token.denom === denom),
|
||||
);
|
||||
const erc20Amounts = await Promise.all(
|
||||
@ -192,7 +191,7 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
...supportedBankCoins.map(coin => decodeAmount(this.bankTokens, coin)),
|
||||
...nonZeroErc20Amounts,
|
||||
].sort((a, b) => a.tokenTicker.localeCompare(b.tokenTicker));
|
||||
const pubkey = bankAccount?.public_key ? decodeCosmosPubkey(bankAccount.public_key) : undefined;
|
||||
const pubkey = bankAccount?.pubkey ? decodePubkey(bankAccount.pubkey) : undefined;
|
||||
return {
|
||||
address: address,
|
||||
balance: balance,
|
||||
@ -248,12 +247,12 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
}
|
||||
|
||||
public async getBlockHeader(height: number): Promise<BlockHeader> {
|
||||
const { block_id, block } = await this.cosmWasmClient.getBlock(height);
|
||||
const { id, header, txs } = await this.cosmWasmClient.getBlock(height);
|
||||
return {
|
||||
id: block_id.hash as BlockId,
|
||||
height: parseInt(block.header.height, 10),
|
||||
time: new ReadonlyDate(block.header.time),
|
||||
transactionCount: block.data.txs?.length || 0,
|
||||
id: id as BlockId,
|
||||
height: header.height,
|
||||
time: new ReadonlyDate(header.time),
|
||||
transactionCount: txs.length,
|
||||
};
|
||||
}
|
||||
|
||||
@ -337,13 +336,13 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
|
||||
const filter: SearchTxFilter = { minHeight: minHeight, maxHeight: maxHeight };
|
||||
|
||||
let txs: readonly TxsResponse[];
|
||||
let txs: readonly IndexedTx[];
|
||||
if (id) {
|
||||
txs = await this.cosmWasmClient.searchTx({ id: id }, filter);
|
||||
} else if (height) {
|
||||
txs = await this.cosmWasmClient.searchTx({ height: height }, filter);
|
||||
} else if (sentFromOrTo) {
|
||||
const pendingRequests = new Array<Promise<readonly TxsResponse[]>>();
|
||||
const pendingRequests = new Array<Promise<readonly IndexedTx[]>>();
|
||||
pendingRequests.push(this.cosmWasmClient.searchTx({ sentFromOrTo: sentFromOrTo }, filter));
|
||||
for (const contract of this.erc20Tokens.map(token => token.contractAddress)) {
|
||||
const searchBySender = [
|
||||
@ -371,7 +370,7 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
}
|
||||
const responses = await Promise.all(pendingRequests);
|
||||
const allResults = responses.reduce((accumulator, results) => accumulator.concat(results), []);
|
||||
txs = deduplicate(allResults, (a, b) => a.txhash.localeCompare(b.txhash)).sort(compareByHeightAndHash);
|
||||
txs = deduplicate(allResults, (a, b) => a.hash.localeCompare(b.hash)).sort(compareByHeightAndHash);
|
||||
} else {
|
||||
throw new Error("Unsupported query");
|
||||
}
|
||||
@ -460,11 +459,11 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
}
|
||||
|
||||
private parseAndPopulateTxResponseUnsigned(
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
): ConfirmedTransaction<UnsignedTransaction> | FailedTransaction {
|
||||
return parseTxsResponseUnsigned(
|
||||
this.chainId,
|
||||
parseInt(response.height, 10),
|
||||
response.height,
|
||||
response,
|
||||
this.bankTokens,
|
||||
this.erc20Tokens,
|
||||
@ -472,7 +471,7 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
}
|
||||
|
||||
private async parseAndPopulateTxResponseSigned(
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
): Promise<ConfirmedAndSignedTransaction<UnsignedTransaction> | FailedTransaction> {
|
||||
const firstMsg = response.tx.value.msg.find(() => true);
|
||||
if (!firstMsg) throw new Error("Got transaction without a first message. What is going on here?");
|
||||
@ -503,7 +502,7 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
|
||||
return parseTxsResponseSigned(
|
||||
this.chainId,
|
||||
parseInt(response.height, 10),
|
||||
response.height,
|
||||
nonce,
|
||||
response,
|
||||
this.bankTokens,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { types } from "@cosmwasm/sdk";
|
||||
import { IndexedTx, types } from "@cosmwasm/sdk";
|
||||
import { Address, Algorithm, isSendTransaction, SendTransaction, TokenTicker } from "@iov/bcp";
|
||||
import { Encoding } from "@iov/encoding";
|
||||
import { assert } from "@iov/utils";
|
||||
@ -281,10 +281,11 @@ describe("decode", () => {
|
||||
describe("parseTxsResponseUnsigned", () => {
|
||||
it("works", () => {
|
||||
const currentHeight = 2923;
|
||||
const txsResponse = {
|
||||
height: "2823",
|
||||
txhash: testdata.txId,
|
||||
raw_log: '[{"msg_index":0,"success":true,"log":""}]',
|
||||
const txsResponse: IndexedTx = {
|
||||
height: 2823,
|
||||
hash: testdata.txId,
|
||||
rawLog: '[{"msg_index":0,"success":true,"log":""}]',
|
||||
logs: [],
|
||||
tx: cosmoshub.tx,
|
||||
timestamp: "2020-02-14T11:35:41Z",
|
||||
};
|
||||
@ -310,10 +311,11 @@ describe("decode", () => {
|
||||
describe("parseTxsResponseSigned", () => {
|
||||
it("works", () => {
|
||||
const currentHeight = 2923;
|
||||
const txsResponse = {
|
||||
height: "2823",
|
||||
txhash: testdata.txId,
|
||||
raw_log: '[{"msg_index":0,"success":true,"log":""}]',
|
||||
const txsResponse: IndexedTx = {
|
||||
height: 2823,
|
||||
hash: testdata.txId,
|
||||
rawLog: '[{"msg_index":0,"success":true,"log":""}]',
|
||||
logs: [],
|
||||
tx: cosmoshub.tx,
|
||||
timestamp: "2020-02-14T11:35:41Z",
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { TxsResponse, types } from "@cosmwasm/sdk";
|
||||
import { IndexedTx, types } from "@cosmwasm/sdk";
|
||||
import {
|
||||
Address,
|
||||
Algorithm,
|
||||
@ -180,17 +180,16 @@ export function parseSignedTx(
|
||||
export function parseTxsResponseUnsigned(
|
||||
chainId: ChainId,
|
||||
currentHeight: number,
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
tokens: BankTokens,
|
||||
erc20Tokens: readonly Erc20Token[],
|
||||
): ConfirmedTransaction<UnsignedTransaction> {
|
||||
const height = parseInt(response.height, 10);
|
||||
return {
|
||||
transaction: parseUnsignedTx(response.tx.value, chainId, tokens, erc20Tokens),
|
||||
height: height,
|
||||
confirmations: currentHeight - height + 1,
|
||||
transactionId: response.txhash as TransactionId,
|
||||
log: response.raw_log,
|
||||
height: response.height,
|
||||
confirmations: currentHeight - response.height + 1,
|
||||
transactionId: response.hash as TransactionId,
|
||||
log: response.rawLog,
|
||||
};
|
||||
}
|
||||
|
||||
@ -198,16 +197,15 @@ export function parseTxsResponseSigned(
|
||||
chainId: ChainId,
|
||||
currentHeight: number,
|
||||
nonce: Nonce,
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
tokens: BankTokens,
|
||||
erc20Tokens: readonly Erc20Token[],
|
||||
): ConfirmedAndSignedTransaction<UnsignedTransaction> {
|
||||
const height = parseInt(response.height, 10);
|
||||
return {
|
||||
...parseSignedTx(response.tx.value, chainId, nonce, tokens, erc20Tokens),
|
||||
height: height,
|
||||
confirmations: currentHeight - height + 1,
|
||||
transactionId: response.txhash as TransactionId,
|
||||
log: response.raw_log,
|
||||
height: response.height,
|
||||
confirmations: currentHeight - response.height + 1,
|
||||
transactionId: response.hash as TransactionId,
|
||||
log: response.rawLog,
|
||||
};
|
||||
}
|
||||
|
||||
1
packages/bcp/types/address.d.ts
vendored
1
packages/bcp/types/address.d.ts
vendored
@ -1,3 +1,2 @@
|
||||
import { Address, PubkeyBundle } from "@iov/bcp";
|
||||
export declare function decodeCosmosPubkey(encodedPubkey: string): PubkeyBundle;
|
||||
export declare function pubkeyToAddress(pubkey: PubkeyBundle, prefix: string): Address;
|
||||
|
||||
6
packages/bcp/types/decode.d.ts
vendored
6
packages/bcp/types/decode.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { TxsResponse, types } from "@cosmwasm/sdk";
|
||||
import { IndexedTx, types } from "@cosmwasm/sdk";
|
||||
import {
|
||||
Amount,
|
||||
ChainId,
|
||||
@ -43,7 +43,7 @@ export declare function parseSignedTx(
|
||||
export declare function parseTxsResponseUnsigned(
|
||||
chainId: ChainId,
|
||||
currentHeight: number,
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
tokens: BankTokens,
|
||||
erc20Tokens: readonly Erc20Token[],
|
||||
): ConfirmedTransaction<UnsignedTransaction>;
|
||||
@ -51,7 +51,7 @@ export declare function parseTxsResponseSigned(
|
||||
chainId: ChainId,
|
||||
currentHeight: number,
|
||||
nonce: Nonce,
|
||||
response: TxsResponse,
|
||||
response: IndexedTx,
|
||||
tokens: BankTokens,
|
||||
erc20Tokens: readonly Erc20Token[],
|
||||
): ConfirmedAndSignedTransaction<UnsignedTransaction>;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cosmwasm/cli",
|
||||
"version": "0.7.0-alpha.2",
|
||||
"version": "0.7.0-alpha.4",
|
||||
"description": "Command line interface",
|
||||
"contributors": [
|
||||
"IOV SAS <admin@iov.one>",
|
||||
@ -36,7 +36,7 @@
|
||||
"!**/testdata/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@cosmwasm/sdk": "^0.7.0-alpha.2",
|
||||
"@cosmwasm/sdk": "^0.7.0-alpha.4",
|
||||
"@iov/crypto": "^2.1.0",
|
||||
"@iov/encoding": "^2.1.0",
|
||||
"@iov/utils": "^2.0.2",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cosmwasm/faucet",
|
||||
"version": "0.7.0-alpha.2",
|
||||
"version": "0.7.0-alpha.4",
|
||||
"description": "The faucet",
|
||||
"author": "Ethan Frey <ethanfrey@users.noreply.github.com>",
|
||||
"license": "Apache-2.0",
|
||||
@ -35,7 +35,7 @@
|
||||
"test": "yarn build-or-skip && yarn test-node"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cosmwasm/bcp": "^0.7.0-alpha.2",
|
||||
"@cosmwasm/bcp": "^0.7.0-alpha.4",
|
||||
"@iov/bcp": "^2.1.0",
|
||||
"@iov/crypto": "^2.1.0",
|
||||
"@iov/encoding": "^2.1.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cosmwasm/sdk",
|
||||
"version": "0.7.0-alpha.2",
|
||||
"version": "0.7.0-alpha.4",
|
||||
"description": "CosmWasm SDK",
|
||||
"author": "Ethan Frey <ethanfrey@users.noreply.github.com>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@ -92,8 +92,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
expect(result.length).toEqual(1);
|
||||
expect(result[0]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedSend.height.toString(),
|
||||
txhash: postedSend.hash,
|
||||
height: postedSend.height,
|
||||
hash: postedSend.hash,
|
||||
tx: postedSend.tx,
|
||||
}),
|
||||
);
|
||||
@ -144,8 +144,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
expect(result.length).toEqual(1);
|
||||
expect(result[0]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedSend.height.toString(),
|
||||
txhash: postedSend.hash,
|
||||
height: postedSend.height,
|
||||
hash: postedSend.hash,
|
||||
tx: postedSend.tx,
|
||||
}),
|
||||
);
|
||||
@ -163,7 +163,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check basic structure of all results
|
||||
for (const result of results) {
|
||||
const msg = fromOneElementArray(result.tx.value.msg);
|
||||
assert(isMsgSend(msg), `${result.txhash} (height ${result.height}) is not a bank send transaction`);
|
||||
assert(isMsgSend(msg), `${result.hash} (height ${result.height}) is not a bank send transaction`);
|
||||
expect(
|
||||
msg.value.to_address === postedSend.sender || msg.value.from_address == postedSend.sender,
|
||||
).toEqual(true);
|
||||
@ -172,8 +172,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check details of most recent result
|
||||
expect(results[results.length - 1]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedSend.height.toString(),
|
||||
txhash: postedSend.hash,
|
||||
height: postedSend.height,
|
||||
hash: postedSend.hash,
|
||||
tx: postedSend.tx,
|
||||
}),
|
||||
);
|
||||
@ -189,7 +189,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check basic structure of all results
|
||||
for (const result of results) {
|
||||
const msg = fromOneElementArray(result.tx.value.msg);
|
||||
assert(isMsgSend(msg), `${result.txhash} (height ${result.height}) is not a bank send transaction`);
|
||||
assert(isMsgSend(msg), `${result.hash} (height ${result.height}) is not a bank send transaction`);
|
||||
expect(
|
||||
msg.value.to_address === postedSend.recipient || msg.value.from_address == postedSend.recipient,
|
||||
).toEqual(true);
|
||||
@ -198,8 +198,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check details of most recent result
|
||||
expect(results[results.length - 1]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedSend.height.toString(),
|
||||
txhash: postedSend.hash,
|
||||
height: postedSend.height,
|
||||
hash: postedSend.hash,
|
||||
tx: postedSend.tx,
|
||||
}),
|
||||
);
|
||||
@ -273,15 +273,15 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check basic structure of all results
|
||||
for (const result of results) {
|
||||
const msg = fromOneElementArray(result.tx.value.msg);
|
||||
assert(isMsgSend(msg), `${result.txhash} (height ${result.height}) is not a bank send transaction`);
|
||||
assert(isMsgSend(msg), `${result.hash} (height ${result.height}) is not a bank send transaction`);
|
||||
expect(msg.value.to_address).toEqual(postedSend.recipient);
|
||||
}
|
||||
|
||||
// Check details of most recent result
|
||||
expect(results[results.length - 1]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedSend.height.toString(),
|
||||
txhash: postedSend.hash,
|
||||
height: postedSend.height,
|
||||
hash: postedSend.hash,
|
||||
tx: postedSend.tx,
|
||||
}),
|
||||
);
|
||||
@ -301,7 +301,7 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
const msg = fromOneElementArray(result.tx.value.msg);
|
||||
assert(
|
||||
isMsgExecuteContract(msg) || isMsgInstantiateContract(msg),
|
||||
`${result.txhash} (at ${result.height}) not an execute or instantiate msg`,
|
||||
`${result.hash} (at ${result.height}) not an execute or instantiate msg`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -322,8 +322,8 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check details of most recent result
|
||||
expect(results[results.length - 1]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedExecute.height.toString(),
|
||||
txhash: postedExecute.hash,
|
||||
height: postedExecute.height,
|
||||
hash: postedExecute.hash,
|
||||
tx: postedExecute.tx,
|
||||
}),
|
||||
);
|
||||
@ -344,15 +344,15 @@ describe("CosmWasmClient.searchTx", () => {
|
||||
// Check basic structure of all results
|
||||
for (const result of results) {
|
||||
const msg = fromOneElementArray(result.tx.value.msg);
|
||||
assert(isMsgExecuteContract(msg), `${result.txhash} (at ${result.height}) not an execute msg`);
|
||||
assert(isMsgExecuteContract(msg), `${result.hash} (at ${result.height}) not an execute msg`);
|
||||
expect(msg.value.contract).toEqual(postedExecute.contract);
|
||||
}
|
||||
|
||||
// Check details of most recent result
|
||||
expect(results[results.length - 1]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
height: postedExecute.height.toString(),
|
||||
txhash: postedExecute.hash,
|
||||
height: postedExecute.height,
|
||||
hash: postedExecute.hash,
|
||||
tx: postedExecute.tx,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -83,10 +83,10 @@ describe("CosmWasmClient", () => {
|
||||
const client = new CosmWasmClient(wasmdEndpoint);
|
||||
expect(await client.getAccount(unused.address)).toEqual({
|
||||
address: unused.address,
|
||||
account_number: 5,
|
||||
accountNumber: 5,
|
||||
sequence: 0,
|
||||
public_key: "",
|
||||
coins: [
|
||||
pubkey: undefined,
|
||||
balance: [
|
||||
{ denom: "ucosm", amount: "1000000000" },
|
||||
{ denom: "ustake", amount: "1000000000" },
|
||||
],
|
||||
@ -108,39 +108,39 @@ describe("CosmWasmClient", () => {
|
||||
const response = await client.getBlock();
|
||||
|
||||
// id
|
||||
expect(response.block_id.hash).toMatch(tendermintIdMatcher);
|
||||
expect(response.id).toMatch(tendermintIdMatcher);
|
||||
|
||||
// header
|
||||
expect(parseInt(response.block.header.height, 10)).toBeGreaterThanOrEqual(1);
|
||||
expect(response.block.header.chain_id).toEqual(await client.chainId());
|
||||
expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now());
|
||||
expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual(
|
||||
expect(response.header.height).toBeGreaterThanOrEqual(1);
|
||||
expect(response.header.chainId).toEqual(await client.chainId());
|
||||
expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now());
|
||||
expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual(
|
||||
ReadonlyDate.now() - 5_000,
|
||||
);
|
||||
|
||||
// data
|
||||
expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true);
|
||||
// txs
|
||||
expect(Array.isArray(response.txs)).toEqual(true);
|
||||
});
|
||||
|
||||
it("works for block by height", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const client = new CosmWasmClient(wasmdEndpoint);
|
||||
const height = parseInt((await client.getBlock()).block.header.height, 10);
|
||||
const height = (await client.getBlock()).header.height;
|
||||
const response = await client.getBlock(height - 1);
|
||||
|
||||
// id
|
||||
expect(response.block_id.hash).toMatch(tendermintIdMatcher);
|
||||
expect(response.id).toMatch(tendermintIdMatcher);
|
||||
|
||||
// header
|
||||
expect(response.block.header.height).toEqual(`${height - 1}`);
|
||||
expect(response.block.header.chain_id).toEqual(await client.chainId());
|
||||
expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now());
|
||||
expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual(
|
||||
expect(response.header.height).toEqual(height - 1);
|
||||
expect(response.header.chainId).toEqual(await client.chainId());
|
||||
expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now());
|
||||
expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual(
|
||||
ReadonlyDate.now() - 5_000,
|
||||
);
|
||||
|
||||
// data
|
||||
expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true);
|
||||
// txs
|
||||
expect(Array.isArray(response.txs)).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -313,7 +313,7 @@ describe("CosmWasmClient", () => {
|
||||
);
|
||||
const { codeId } = await client.upload(getRandomizedHackatom());
|
||||
const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() };
|
||||
const contractAddress = await client.instantiate(codeId, initMsg, "random hackatom");
|
||||
const { contractAddress } = await client.instantiate(codeId, initMsg, "random hackatom");
|
||||
contract = { initMsg: initMsg, address: contractAddress };
|
||||
}
|
||||
});
|
||||
@ -366,7 +366,7 @@ describe("CosmWasmClient", () => {
|
||||
);
|
||||
const { codeId } = await client.upload(getRandomizedHackatom());
|
||||
const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() };
|
||||
const contractAddress = await client.instantiate(codeId, initMsg, "a different hackatom");
|
||||
const { contractAddress } = await client.instantiate(codeId, initMsg, "a different hackatom");
|
||||
contract = { initMsg: initMsg, address: contractAddress };
|
||||
}
|
||||
});
|
||||
|
||||
@ -2,14 +2,24 @@ import { Sha256 } from "@iov/crypto";
|
||||
import { Encoding } from "@iov/encoding";
|
||||
|
||||
import { Log, parseLogs } from "./logs";
|
||||
import { BlockResponse, BroadcastMode, RestClient, TxsResponse } from "./restclient";
|
||||
import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types";
|
||||
import { decodeBech32Pubkey } from "./pubkey";
|
||||
import { BroadcastMode, RestClient } from "./restclient";
|
||||
import { Coin, CosmosSdkTx, PubKey, StdTx } from "./types";
|
||||
|
||||
export interface GetNonceResult {
|
||||
readonly accountNumber: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly balance: ReadonlyArray<Coin>;
|
||||
readonly pubkey: PubKey | undefined;
|
||||
readonly accountNumber: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
|
||||
export interface PostTxResult {
|
||||
readonly logs: readonly Log[];
|
||||
readonly rawLog: string;
|
||||
@ -92,6 +102,41 @@ export interface ContractDetails extends Contract {
|
||||
readonly initMsg: object;
|
||||
}
|
||||
|
||||
/** A transaction that is indexed as part of the transaction history */
|
||||
export interface IndexedTx {
|
||||
readonly height: number;
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly hash: string;
|
||||
readonly rawLog: string;
|
||||
readonly logs: readonly Log[];
|
||||
readonly tx: CosmosSdkTx;
|
||||
/** The gas limit as set by the user */
|
||||
readonly gasWanted?: number;
|
||||
/** The gas used by the execution */
|
||||
readonly gasUsed?: number;
|
||||
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
|
||||
readonly timestamp: string;
|
||||
}
|
||||
|
||||
export interface BlockHeader {
|
||||
readonly version: {
|
||||
readonly block: string;
|
||||
readonly app: string;
|
||||
};
|
||||
readonly height: number;
|
||||
readonly chainId: string;
|
||||
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
|
||||
readonly time: string;
|
||||
}
|
||||
|
||||
export interface Block {
|
||||
/** The ID is a hash of the block header (uppercase hex) */
|
||||
readonly id: string;
|
||||
readonly header: BlockHeader;
|
||||
/** Array of raw transactions */
|
||||
readonly txs: ReadonlyArray<Uint8Array>;
|
||||
}
|
||||
|
||||
export class CosmWasmClient {
|
||||
protected readonly restClient: RestClient;
|
||||
|
||||
@ -129,15 +174,23 @@ export class CosmWasmClient {
|
||||
);
|
||||
}
|
||||
return {
|
||||
accountNumber: account.account_number,
|
||||
accountNumber: account.accountNumber,
|
||||
sequence: account.sequence,
|
||||
};
|
||||
}
|
||||
|
||||
public async getAccount(address: string): Promise<CosmosSdkAccount | undefined> {
|
||||
public async getAccount(address: string): Promise<Account | undefined> {
|
||||
const account = await this.restClient.authAccounts(address);
|
||||
const value = account.result.value;
|
||||
return value.address === "" ? undefined : value;
|
||||
return value.address === ""
|
||||
? undefined
|
||||
: {
|
||||
address: value.address,
|
||||
balance: value.coins,
|
||||
pubkey: value.public_key ? decodeBech32Pubkey(value.public_key) : undefined,
|
||||
accountNumber: value.account_number,
|
||||
sequence: value.sequence,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,15 +198,23 @@ export class CosmWasmClient {
|
||||
*
|
||||
* @param height The height of the block. If undefined, the latest height is used.
|
||||
*/
|
||||
public async getBlock(height?: number): Promise<BlockResponse> {
|
||||
if (height !== undefined) {
|
||||
return this.restClient.blocks(height);
|
||||
} else {
|
||||
return this.restClient.blocksLatest();
|
||||
}
|
||||
public async getBlock(height?: number): Promise<Block> {
|
||||
const response =
|
||||
height !== undefined ? await this.restClient.blocks(height) : await this.restClient.blocksLatest();
|
||||
|
||||
return {
|
||||
id: response.block_id.hash,
|
||||
header: {
|
||||
version: response.block.header.version,
|
||||
time: response.block.header.time,
|
||||
height: parseInt(response.block.header.height, 10),
|
||||
chainId: response.block.header.chain_id,
|
||||
},
|
||||
txs: (response.block.data.txs || []).map(encoded => Encoding.fromBase64(encoded)),
|
||||
};
|
||||
}
|
||||
|
||||
public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise<readonly TxsResponse[]> {
|
||||
public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise<readonly IndexedTx[]> {
|
||||
const minHeight = filter.minHeight || 0;
|
||||
const maxHeight = filter.maxHeight || Number.MAX_SAFE_INTEGER;
|
||||
|
||||
@ -163,7 +224,7 @@ export class CosmWasmClient {
|
||||
return `${originalQuery}&tx.minheight=${minHeight}&tx.maxheight=${maxHeight}`;
|
||||
}
|
||||
|
||||
let txs: readonly TxsResponse[];
|
||||
let txs: readonly IndexedTx[];
|
||||
if (isSearchByIdQuery(query)) {
|
||||
txs = await this.txsQuery(`tx.hash=${query.id}`);
|
||||
} else if (isSearchByHeightQuery(query)) {
|
||||
@ -180,8 +241,8 @@ export class CosmWasmClient {
|
||||
const sent = await this.txsQuery(sentQuery);
|
||||
const received = await this.txsQuery(receivedQuery);
|
||||
|
||||
const sentHashes = sent.map(t => t.txhash);
|
||||
txs = [...sent, ...received.filter(t => !sentHashes.includes(t.txhash))];
|
||||
const sentHashes = sent.map(t => t.hash);
|
||||
txs = [...sent, ...received.filter(t => !sentHashes.includes(t.hash))];
|
||||
} else if (isSearchByTagsQuery(query)) {
|
||||
const rawQuery = withFilters(query.tags.map(t => `${t.key}=${t.value}`).join("&"));
|
||||
txs = await this.txsQuery(rawQuery);
|
||||
@ -190,10 +251,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
|
||||
// backend sometimes messes up with min/max height filtering
|
||||
const filtered = txs.filter(tx => {
|
||||
const txHeight = parseInt(tx.height, 10);
|
||||
return txHeight >= minHeight && txHeight <= maxHeight;
|
||||
});
|
||||
const filtered = txs.filter(tx => tx.height >= minHeight && tx.height <= maxHeight);
|
||||
|
||||
return filtered;
|
||||
}
|
||||
@ -303,7 +361,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
}
|
||||
|
||||
private async txsQuery(query: string): Promise<readonly TxsResponse[]> {
|
||||
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}`);
|
||||
@ -313,6 +371,15 @@ export class CosmWasmClient {
|
||||
`Found more results on the backend than we can process currently. Results: ${result.total_count}, supported: ${limit}`,
|
||||
);
|
||||
}
|
||||
return result.txs;
|
||||
return result.txs.map(
|
||||
(restItem): IndexedTx => ({
|
||||
height: parseInt(restItem.height, 10),
|
||||
hash: restItem.txhash,
|
||||
rawLog: restItem.raw_log,
|
||||
logs: parseLogs(restItem.logs || []),
|
||||
tx: restItem.tx,
|
||||
timestamp: restItem.timestamp,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,16 @@ export { unmarshalTx } from "./decoding";
|
||||
export { makeSignBytes, marshalTx } from "./encoding";
|
||||
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
|
||||
export {
|
||||
Account,
|
||||
Block,
|
||||
BlockHeader,
|
||||
Code,
|
||||
CodeDetails,
|
||||
Contract,
|
||||
ContractDetails,
|
||||
CosmWasmClient,
|
||||
GetNonceResult,
|
||||
IndexedTx,
|
||||
PostTxResult,
|
||||
SearchByHeightQuery,
|
||||
SearchByIdQuery,
|
||||
@ -29,9 +34,10 @@ export {
|
||||
export { findSequenceForSignedTx } from "./sequence";
|
||||
export { encodeSecp256k1Signature, decodeSignature } from "./signature";
|
||||
export {
|
||||
ExecuteResult,
|
||||
InstantiateResult,
|
||||
SigningCallback,
|
||||
SigningCosmWasmClient,
|
||||
ExecuteResult,
|
||||
UploadMeta,
|
||||
UploadReceipt,
|
||||
UploadResult,
|
||||
} from "./signingcosmwasmclient";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Bech32, Encoding } from "@iov/encoding";
|
||||
import equal from "fast-deep-equal";
|
||||
|
||||
import { Bech32PubKey, PubKey, pubkeyType } from "./types";
|
||||
import { PubKey, pubkeyType } from "./types";
|
||||
|
||||
export function encodeSecp256k1Pubkey(pubkey: Uint8Array): PubKey {
|
||||
if (pubkey.length !== 33 || (pubkey[0] !== 0x02 && pubkey[0] !== 0x03)) {
|
||||
@ -28,8 +28,8 @@ const pubkeyAminoPrefixEd25519 = Encoding.fromHex("1624de6420");
|
||||
const pubkeyAminoPrefixSr25519 = Encoding.fromHex("0dfb1005");
|
||||
const pubkeyAminoPrefixLength = pubkeyAminoPrefixSecp256k1.length;
|
||||
|
||||
export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey {
|
||||
const { prefix, data } = Bech32.decode(bech);
|
||||
export function decodeBech32Pubkey(bechEncoded: string): PubKey {
|
||||
const { prefix, data } = Bech32.decode(bechEncoded);
|
||||
if (!isCosmosPubkeyBech32Prefix(prefix)) {
|
||||
throw new Error(`Invalid bech32 prefix. Must be one of ${validPubkeyPrefixes.join(", ")}.`);
|
||||
}
|
||||
@ -65,7 +65,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey {
|
||||
}
|
||||
}
|
||||
|
||||
export function encodeBech32Pubkey(pubkey: PubKey, prefix: CosmosPubkeyBech32Prefix): Bech32PubKey {
|
||||
export function encodeBech32Pubkey(pubkey: PubKey, prefix: CosmosPubkeyBech32Prefix): string {
|
||||
let aminoPrefix: Uint8Array;
|
||||
switch (pubkey.type) {
|
||||
// Note: please don't add cases here without writing additional unit tests
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
import { Encoding } from "@iov/encoding";
|
||||
import axios, { AxiosError, AxiosInstance } from "axios";
|
||||
|
||||
import { CosmosSdkAccount, CosmosSdkTx, Model, parseWasmData, StdTx, WasmData } from "./types";
|
||||
import { Coin, CosmosSdkTx, Model, parseWasmData, StdTx, WasmData } from "./types";
|
||||
|
||||
const { fromBase64, toHex, toUtf8 } = Encoding;
|
||||
|
||||
export interface CosmosSdkAccount {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly coins: ReadonlyArray<Coin>;
|
||||
/** Bech32 encoded pubkey */
|
||||
readonly public_key: string;
|
||||
readonly account_number: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
|
||||
interface NodeInfo {
|
||||
readonly network: string;
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
];
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
const contractAddress = await client.instantiate(
|
||||
const { contractAddress } = await client.instantiate(
|
||||
codeId,
|
||||
{
|
||||
verifier: faucet.address,
|
||||
@ -148,7 +148,7 @@ describe("SigningCosmWasmClient", () => {
|
||||
},
|
||||
];
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
const contractAddress = await client.instantiate(
|
||||
const { contractAddress } = await client.instantiate(
|
||||
codeId,
|
||||
{
|
||||
verifier: faucet.address,
|
||||
@ -205,7 +205,7 @@ describe("SigningCosmWasmClient", () => {
|
||||
// got tokens
|
||||
const after = await client.getAccount(beneficiaryAddress);
|
||||
assert(after);
|
||||
expect(after.coins).toEqual(transferAmount);
|
||||
expect(after.balance).toEqual(transferAmount);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,13 +3,12 @@ import { Encoding } from "@iov/encoding";
|
||||
import pako from "pako";
|
||||
|
||||
import { isValidBuilder } from "./builder";
|
||||
import { CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
|
||||
import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
|
||||
import { makeSignBytes } from "./encoding";
|
||||
import { findAttribute, Log } from "./logs";
|
||||
import { BroadcastMode } from "./restclient";
|
||||
import {
|
||||
Coin,
|
||||
CosmosSdkAccount,
|
||||
MsgExecuteContract,
|
||||
MsgInstantiateContract,
|
||||
MsgSend,
|
||||
@ -68,7 +67,7 @@ export interface UploadMeta {
|
||||
readonly builder?: string;
|
||||
}
|
||||
|
||||
export interface UploadReceipt {
|
||||
export interface UploadResult {
|
||||
/** Size of the original wasm code in bytes */
|
||||
readonly originalSize: number;
|
||||
/** A hex encoded sha256 checksum of the original wasm code (that is stored on chain) */
|
||||
@ -79,6 +78,17 @@ export interface UploadReceipt {
|
||||
readonly compressedChecksum: string;
|
||||
/** The ID of the code asigned by the chain */
|
||||
readonly codeId: number;
|
||||
readonly logs: readonly Log[];
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly transactionHash: string;
|
||||
}
|
||||
|
||||
export interface InstantiateResult {
|
||||
/** The address of the newly instantiated contract */
|
||||
readonly contractAddress: string;
|
||||
readonly logs: readonly Log[];
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly transactionHash: string;
|
||||
}
|
||||
|
||||
export interface ExecuteResult {
|
||||
@ -110,12 +120,12 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
return super.getNonce(address || this.senderAddress);
|
||||
}
|
||||
|
||||
public async getAccount(address?: string): Promise<CosmosSdkAccount | undefined> {
|
||||
public async getAccount(address?: string): Promise<Account | undefined> {
|
||||
return super.getAccount(address || this.senderAddress);
|
||||
}
|
||||
|
||||
/** Uploads code and returns a receipt, including the code ID */
|
||||
public async upload(wasmCode: Uint8Array, meta: UploadMeta = {}, memo = ""): Promise<UploadReceipt> {
|
||||
public async upload(wasmCode: Uint8Array, meta: UploadMeta = {}, memo = ""): Promise<UploadResult> {
|
||||
const source = meta.source || "";
|
||||
const builder = prepareBuilder(meta.builder);
|
||||
|
||||
@ -150,6 +160,8 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
compressedSize: compressed.length,
|
||||
compressedChecksum: Encoding.toHex(new Sha256(compressed).digest()),
|
||||
codeId: Number.parseInt(codeIdAttr.value, 10),
|
||||
logs: result.logs,
|
||||
transactionHash: result.transactionHash,
|
||||
};
|
||||
}
|
||||
|
||||
@ -159,7 +171,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
label: string,
|
||||
memo = "",
|
||||
transferAmount?: readonly Coin[],
|
||||
): Promise<string> {
|
||||
): Promise<InstantiateResult> {
|
||||
const instantiateMsg: MsgInstantiateContract = {
|
||||
type: "wasm/instantiate",
|
||||
value: {
|
||||
@ -188,7 +200,11 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
|
||||
const result = await this.postTx(signedTx);
|
||||
const contractAddressAttr = findAttribute(result.logs, "message", "contract_address");
|
||||
return contractAddressAttr.value;
|
||||
return {
|
||||
contractAddress: contractAddressAttr.value,
|
||||
logs: result.logs,
|
||||
transactionHash: result.transactionHash,
|
||||
};
|
||||
}
|
||||
|
||||
public async execute(
|
||||
|
||||
@ -150,18 +150,6 @@ export const pubkeyType = {
|
||||
|
||||
export const pubkeyTypes: readonly string[] = [pubkeyType.secp256k1, pubkeyType.ed25519, pubkeyType.sr25519];
|
||||
|
||||
// bech32-encoded amino-binary encoded PubKey interface. oof.
|
||||
export type Bech32PubKey = string;
|
||||
|
||||
export interface CosmosSdkAccount {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly coins: ReadonlyArray<Coin>;
|
||||
readonly public_key: Bech32PubKey;
|
||||
readonly account_number: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
|
||||
export interface WasmData {
|
||||
// key is hex-encoded
|
||||
readonly key: string;
|
||||
|
||||
50
packages/sdk/types/cosmwasmclient.d.ts
vendored
50
packages/sdk/types/cosmwasmclient.d.ts
vendored
@ -1,10 +1,18 @@
|
||||
import { Log } from "./logs";
|
||||
import { BlockResponse, BroadcastMode, RestClient, TxsResponse } from "./restclient";
|
||||
import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types";
|
||||
import { BroadcastMode, RestClient } from "./restclient";
|
||||
import { Coin, CosmosSdkTx, PubKey, StdTx } from "./types";
|
||||
export interface GetNonceResult {
|
||||
readonly accountNumber: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
export interface Account {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly balance: ReadonlyArray<Coin>;
|
||||
readonly pubkey: PubKey | undefined;
|
||||
readonly accountNumber: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
export interface PostTxResult {
|
||||
readonly logs: readonly Log[];
|
||||
readonly rawLog: string;
|
||||
@ -63,6 +71,38 @@ export interface ContractDetails extends Contract {
|
||||
/** Argument passed on initialization of the contract */
|
||||
readonly initMsg: object;
|
||||
}
|
||||
/** A transaction that is indexed as part of the transaction history */
|
||||
export interface IndexedTx {
|
||||
readonly height: number;
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly hash: string;
|
||||
readonly rawLog: string;
|
||||
readonly logs: readonly Log[];
|
||||
readonly tx: CosmosSdkTx;
|
||||
/** The gas limit as set by the user */
|
||||
readonly gasWanted?: number;
|
||||
/** The gas used by the execution */
|
||||
readonly gasUsed?: number;
|
||||
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
|
||||
readonly timestamp: string;
|
||||
}
|
||||
export interface BlockHeader {
|
||||
readonly version: {
|
||||
readonly block: string;
|
||||
readonly app: string;
|
||||
};
|
||||
readonly height: number;
|
||||
readonly chainId: string;
|
||||
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
|
||||
readonly time: string;
|
||||
}
|
||||
export interface Block {
|
||||
/** The ID is a hash of the block header (uppercase hex) */
|
||||
readonly id: string;
|
||||
readonly header: BlockHeader;
|
||||
/** Array of raw transactions */
|
||||
readonly txs: ReadonlyArray<Uint8Array>;
|
||||
}
|
||||
export declare class CosmWasmClient {
|
||||
protected readonly restClient: RestClient;
|
||||
constructor(url: string, broadcastMode?: BroadcastMode);
|
||||
@ -79,14 +119,14 @@ export declare class CosmWasmClient {
|
||||
* @param address returns data for this address. When unset, the client's sender adddress is used.
|
||||
*/
|
||||
getNonce(address: string): Promise<GetNonceResult>;
|
||||
getAccount(address: string): Promise<CosmosSdkAccount | undefined>;
|
||||
getAccount(address: string): Promise<Account | undefined>;
|
||||
/**
|
||||
* Gets block header and meta
|
||||
*
|
||||
* @param height The height of the block. If undefined, the latest height is used.
|
||||
*/
|
||||
getBlock(height?: number): Promise<BlockResponse>;
|
||||
searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise<readonly TxsResponse[]>;
|
||||
getBlock(height?: number): Promise<Block>;
|
||||
searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise<readonly IndexedTx[]>;
|
||||
postTx(tx: StdTx): Promise<PostTxResult>;
|
||||
getCodes(): Promise<readonly Code[]>;
|
||||
getCodeDetails(codeId: number): Promise<CodeDetails>;
|
||||
|
||||
10
packages/sdk/types/index.d.ts
vendored
10
packages/sdk/types/index.d.ts
vendored
@ -6,11 +6,16 @@ export { unmarshalTx } from "./decoding";
|
||||
export { makeSignBytes, marshalTx } from "./encoding";
|
||||
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
|
||||
export {
|
||||
Account,
|
||||
Block,
|
||||
BlockHeader,
|
||||
Code,
|
||||
CodeDetails,
|
||||
Contract,
|
||||
ContractDetails,
|
||||
CosmWasmClient,
|
||||
GetNonceResult,
|
||||
IndexedTx,
|
||||
PostTxResult,
|
||||
SearchByHeightQuery,
|
||||
SearchByIdQuery,
|
||||
@ -28,9 +33,10 @@ export {
|
||||
export { findSequenceForSignedTx } from "./sequence";
|
||||
export { encodeSecp256k1Signature, decodeSignature } from "./signature";
|
||||
export {
|
||||
ExecuteResult,
|
||||
InstantiateResult,
|
||||
SigningCallback,
|
||||
SigningCosmWasmClient,
|
||||
ExecuteResult,
|
||||
UploadMeta,
|
||||
UploadReceipt,
|
||||
UploadResult,
|
||||
} from "./signingcosmwasmclient";
|
||||
|
||||
6
packages/sdk/types/pubkey.d.ts
vendored
6
packages/sdk/types/pubkey.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
import { Bech32PubKey, PubKey } from "./types";
|
||||
import { PubKey } from "./types";
|
||||
export declare function encodeSecp256k1Pubkey(pubkey: Uint8Array): PubKey;
|
||||
export declare type CosmosPubkeyBech32Prefix = "cosmospub" | "cosmosvalconspub" | "cosmosvaloperpub";
|
||||
export declare function decodeBech32Pubkey(bech: Bech32PubKey): PubKey;
|
||||
export declare function encodeBech32Pubkey(pubkey: PubKey, prefix: CosmosPubkeyBech32Prefix): Bech32PubKey;
|
||||
export declare function decodeBech32Pubkey(bechEncoded: string): PubKey;
|
||||
export declare function encodeBech32Pubkey(pubkey: PubKey, prefix: CosmosPubkeyBech32Prefix): string;
|
||||
|
||||
11
packages/sdk/types/restclient.d.ts
vendored
11
packages/sdk/types/restclient.d.ts
vendored
@ -1,4 +1,13 @@
|
||||
import { CosmosSdkAccount, CosmosSdkTx, Model, StdTx } from "./types";
|
||||
import { Coin, CosmosSdkTx, Model, StdTx } from "./types";
|
||||
export interface CosmosSdkAccount {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly coins: ReadonlyArray<Coin>;
|
||||
/** Bech32 encoded pubkey */
|
||||
readonly public_key: string;
|
||||
readonly account_number: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
interface NodeInfo {
|
||||
readonly network: string;
|
||||
}
|
||||
|
||||
22
packages/sdk/types/signingcosmwasmclient.d.ts
vendored
22
packages/sdk/types/signingcosmwasmclient.d.ts
vendored
@ -1,7 +1,7 @@
|
||||
import { CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
|
||||
import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
|
||||
import { Log } from "./logs";
|
||||
import { BroadcastMode } from "./restclient";
|
||||
import { Coin, CosmosSdkAccount, StdFee, StdSignature } from "./types";
|
||||
import { Coin, StdFee, StdSignature } from "./types";
|
||||
export interface SigningCallback {
|
||||
(signBytes: Uint8Array): Promise<StdSignature>;
|
||||
}
|
||||
@ -17,7 +17,7 @@ export interface UploadMeta {
|
||||
/** The builder tag */
|
||||
readonly builder?: string;
|
||||
}
|
||||
export interface UploadReceipt {
|
||||
export interface UploadResult {
|
||||
/** Size of the original wasm code in bytes */
|
||||
readonly originalSize: number;
|
||||
/** A hex encoded sha256 checksum of the original wasm code (that is stored on chain) */
|
||||
@ -28,6 +28,16 @@ export interface UploadReceipt {
|
||||
readonly compressedChecksum: string;
|
||||
/** The ID of the code asigned by the chain */
|
||||
readonly codeId: number;
|
||||
readonly logs: readonly Log[];
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly transactionHash: string;
|
||||
}
|
||||
export interface InstantiateResult {
|
||||
/** The address of the newly instantiated contract */
|
||||
readonly contractAddress: string;
|
||||
readonly logs: readonly Log[];
|
||||
/** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */
|
||||
readonly transactionHash: string;
|
||||
}
|
||||
export interface ExecuteResult {
|
||||
readonly logs: readonly Log[];
|
||||
@ -46,16 +56,16 @@ export declare class SigningCosmWasmClient extends CosmWasmClient {
|
||||
broadcastMode?: BroadcastMode,
|
||||
);
|
||||
getNonce(address?: string): Promise<GetNonceResult>;
|
||||
getAccount(address?: string): Promise<CosmosSdkAccount | undefined>;
|
||||
getAccount(address?: string): Promise<Account | undefined>;
|
||||
/** Uploads code and returns a receipt, including the code ID */
|
||||
upload(wasmCode: Uint8Array, meta?: UploadMeta, memo?: string): Promise<UploadReceipt>;
|
||||
upload(wasmCode: Uint8Array, meta?: UploadMeta, memo?: string): Promise<UploadResult>;
|
||||
instantiate(
|
||||
codeId: number,
|
||||
initMsg: object,
|
||||
label: string,
|
||||
memo?: string,
|
||||
transferAmount?: readonly Coin[],
|
||||
): Promise<string>;
|
||||
): Promise<InstantiateResult>;
|
||||
execute(
|
||||
contractAddress: string,
|
||||
handleMsg: object,
|
||||
|
||||
9
packages/sdk/types/types.d.ts
vendored
9
packages/sdk/types/types.d.ts
vendored
@ -109,15 +109,6 @@ export declare const pubkeyType: {
|
||||
sr25519: "tendermint/PubKeySr25519";
|
||||
};
|
||||
export declare const pubkeyTypes: readonly string[];
|
||||
export declare type Bech32PubKey = string;
|
||||
export interface CosmosSdkAccount {
|
||||
/** Bech32 account address */
|
||||
readonly address: string;
|
||||
readonly coins: ReadonlyArray<Coin>;
|
||||
readonly public_key: Bech32PubKey;
|
||||
readonly account_number: number;
|
||||
readonly sequence: number;
|
||||
}
|
||||
export interface WasmData {
|
||||
readonly key: string;
|
||||
readonly val: string;
|
||||
|
||||
@ -82,7 +82,7 @@ async function main() {
|
||||
|
||||
for (const initMsg of [initMsgHash, initMsgIsa, initMsgJade]) {
|
||||
const memo = `Create an ERC20 instance for ${initMsg.symbol}`;
|
||||
const contractAddress = await client.instantiate(uploadReceipt.codeId, initMsg, initMsg.symbol, memo);
|
||||
const { contractAddress } = await client.instantiate(uploadReceipt.codeId, initMsg, initMsg.symbol, memo);
|
||||
console.info(`Contract instantiated for ${initMsg.symbol} at ${contractAddress}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ async function main() {
|
||||
|
||||
for (const { label, initMsg } of [free, luxury]) {
|
||||
const memo = `Create an nameservice instance "${label}"`;
|
||||
const contractAddress = await client.instantiate(uploadReceipt.codeId, initMsg, label, memo);
|
||||
const { contractAddress } = await client.instantiate(uploadReceipt.codeId, initMsg, label, memo);
|
||||
console.info(`Contract "${label}" instantiated at ${contractAddress}`);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user