Merge pull request #73 from confio/update-rest-queries
Update return types for queries
This commit is contained in:
commit
708f7744e7
@ -41,7 +41,7 @@ import { Caip5 } from "./caip5";
|
||||
import { decodeAmount, parseTxsResponse } from "./decode";
|
||||
import { accountToNonce, BankToken, Erc20Token } from "./types";
|
||||
|
||||
const { toHex } = Encoding;
|
||||
const { fromAscii, toHex } = Encoding;
|
||||
|
||||
interface ChainData {
|
||||
readonly chainId: ChainId;
|
||||
@ -168,9 +168,8 @@ export class CosmWasmConnection implements BlockchainConnection {
|
||||
this.erc20Tokens.map(
|
||||
async (erc20): Promise<Amount> => {
|
||||
const queryMsg = { balance: { address: address } };
|
||||
const response = JSON.parse(
|
||||
await this.restClient.queryContractSmart(erc20.contractAddress, queryMsg),
|
||||
);
|
||||
const smart = await this.restClient.queryContractSmart(erc20.contractAddress, queryMsg);
|
||||
const response = JSON.parse(fromAscii(smart));
|
||||
const normalizedBalance = new BN(response.balance).toString();
|
||||
return {
|
||||
fractionalDigits: erc20.fractionalDigits,
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
StdTx,
|
||||
} from "./types";
|
||||
|
||||
const { fromBase64, fromHex, toAscii, toBase64, toHex } = Encoding;
|
||||
const { fromAscii, fromBase64, fromHex, toAscii, toBase64, toHex } = Encoding;
|
||||
|
||||
const httpUrl = "http://localhost:1317";
|
||||
const defaultNetworkId = "testing";
|
||||
@ -496,9 +496,10 @@ describe("RestClient", () => {
|
||||
const state = await client.getAllContractState(contractAddress!);
|
||||
expect(state.length).toEqual(1);
|
||||
const data = state[0];
|
||||
expect(data.key.toLowerCase()).toEqual(toHex(expectedKey));
|
||||
expect((data.val as any).verifier).toBeDefined();
|
||||
expect((data.val as any).beneficiary).toBeDefined();
|
||||
expect(data.key).toEqual(expectedKey);
|
||||
const value = JSON.parse(fromAscii(data.val));
|
||||
expect(value.verifier).toBeDefined();
|
||||
expect(value.beneficiary).toBeDefined();
|
||||
|
||||
// bad address is empty array
|
||||
const noContractState = await client.getAllContractState(noContract);
|
||||
@ -509,10 +510,11 @@ describe("RestClient", () => {
|
||||
pendingWithoutCosmos();
|
||||
|
||||
// query by one key
|
||||
const model = await client.queryContractRaw(contractAddress!, expectedKey);
|
||||
expect(model).not.toBeNull();
|
||||
expect((model as any).verifier).toBeDefined();
|
||||
expect((model as any).beneficiary).toBeDefined();
|
||||
const raw = await client.queryContractRaw(contractAddress!, expectedKey);
|
||||
assert(raw, "must get result");
|
||||
const model = JSON.parse(fromAscii(raw));
|
||||
expect(model.verifier).toBeDefined();
|
||||
expect(model.beneficiary).toBeDefined();
|
||||
|
||||
// missing key is null
|
||||
const missing = await client.queryContractRaw(contractAddress!, fromHex("cafe0dad"));
|
||||
@ -528,7 +530,7 @@ describe("RestClient", () => {
|
||||
|
||||
// we can query the verifier properly
|
||||
const verifier = await client.queryContractSmart(contractAddress!, { verifier: {} });
|
||||
expect(verifier).toEqual(faucet.address);
|
||||
expect(fromAscii(verifier)).toEqual(faucet.address);
|
||||
|
||||
// invalid query syntax throws an error
|
||||
await client.queryContractSmart(contractAddress!, { nosuchkey: {} }).then(
|
||||
|
||||
@ -1,7 +1,17 @@
|
||||
import { Encoding } from "@iov/encoding";
|
||||
import axios, { AxiosError, AxiosInstance } from "axios";
|
||||
|
||||
import { AminoTx, CodeInfo, ContractInfo, CosmosSdkAccount, isAminoStdTx, StdTx, WasmData } from "./types";
|
||||
import {
|
||||
AminoTx,
|
||||
CodeInfo,
|
||||
ContractInfo,
|
||||
CosmosSdkAccount,
|
||||
isAminoStdTx,
|
||||
Model,
|
||||
parseWasmData,
|
||||
StdTx,
|
||||
WasmData,
|
||||
} from "./types";
|
||||
|
||||
const { fromBase64, fromUtf8, toHex, toUtf8 } = Encoding;
|
||||
|
||||
@ -97,6 +107,11 @@ interface GetCodeResult {
|
||||
readonly code: string;
|
||||
}
|
||||
|
||||
interface SmartQueryResponse {
|
||||
// base64 encoded response
|
||||
readonly smart: string;
|
||||
}
|
||||
|
||||
type RestClientResponse =
|
||||
| NodeInfoResponse
|
||||
| BlocksResponse
|
||||
@ -306,32 +321,31 @@ export class RestClient {
|
||||
|
||||
// Returns all contract state.
|
||||
// This is an empty array if no such contract, or contract has no data.
|
||||
public async getAllContractState(address: string): Promise<readonly WasmData[]> {
|
||||
public async getAllContractState(address: string): Promise<readonly Model[]> {
|
||||
const path = `/wasm/contract/${address}/state`;
|
||||
const responseData = await this.get(path);
|
||||
return parseWasmResponse(responseData as WasmResponse);
|
||||
const responseData = (await this.get(path)) as WasmResponse<WasmData[]>;
|
||||
const r = unwrapWasmResponse(responseData);
|
||||
return r ? r.map(parseWasmData) : [];
|
||||
}
|
||||
|
||||
// Returns the data at the key if present (unknown decoded json),
|
||||
// or null if no data at this (contract address, key) pair
|
||||
public async queryContractRaw(address: string, key: Uint8Array): Promise<unknown | null> {
|
||||
public async queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null> {
|
||||
const hexKey = toHex(key);
|
||||
const path = `/wasm/contract/${address}/raw/${hexKey}?encoding=hex`;
|
||||
const responseData = await this.get(path);
|
||||
const data: readonly WasmData[] = parseWasmResponse(responseData as WasmResponse);
|
||||
return data.length === 0 ? null : data[0].val;
|
||||
const responseData = (await this.get(path)) as WasmResponse<WasmData[]>;
|
||||
const data = unwrapWasmResponse(responseData);
|
||||
return data.length === 0 ? null : fromBase64(data[0].val);
|
||||
}
|
||||
|
||||
// Makes a "smart query" on the contract, returns response verbatim (json.RawMessage)
|
||||
// Throws error if no such contract or invalid query format
|
||||
public async queryContractSmart(address: string, query: object): Promise<string> {
|
||||
public async queryContractSmart(address: string, query: object): Promise<Uint8Array> {
|
||||
const encoded = toHex(toUtf8(JSON.stringify(query)));
|
||||
const path = `/wasm/contract/${address}/smart/${encoded}?encoding=hex`;
|
||||
const responseData = (await this.get(path)) as WasmResponse;
|
||||
if (isWasmError(responseData)) {
|
||||
throw new Error(responseData.error);
|
||||
}
|
||||
const responseData = (await this.get(path)) as WasmResponse<SmartQueryResponse>;
|
||||
const result = unwrapWasmResponse(responseData);
|
||||
// no extra parse here for now, see https://github.com/confio/cosmwasm/issues/144
|
||||
return responseData.result;
|
||||
return fromBase64(result.smart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
import { Encoding } from "@iov/encoding";
|
||||
|
||||
const { fromBase64, fromHex } = Encoding;
|
||||
|
||||
// We will move all needed *interfaces* from amino-js here
|
||||
// This means bcp can just import them from here (if needed at all)
|
||||
export interface Tx {
|
||||
@ -190,6 +194,19 @@ export interface ContractInfo {
|
||||
export interface WasmData {
|
||||
// key is hex-encoded
|
||||
readonly key: string;
|
||||
// value can be any decoded json, often an object but can be anything
|
||||
readonly val: unknown;
|
||||
// value is base64 encoded
|
||||
readonly val: string;
|
||||
}
|
||||
|
||||
// Model is a parsed WasmData object
|
||||
export interface Model {
|
||||
readonly key: Uint8Array;
|
||||
readonly val: Uint8Array;
|
||||
}
|
||||
|
||||
export function parseWasmData({ key, val }: WasmData): Model {
|
||||
return {
|
||||
key: fromHex(key),
|
||||
val: fromBase64(val),
|
||||
};
|
||||
}
|
||||
|
||||
8
packages/sdk/types/restclient.d.ts
vendored
8
packages/sdk/types/restclient.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { AminoTx, CodeInfo, ContractInfo, CosmosSdkAccount, StdTx, WasmData } from "./types";
|
||||
import { AminoTx, CodeInfo, ContractInfo, CosmosSdkAccount, Model, StdTx } from "./types";
|
||||
interface NodeInfo {
|
||||
readonly network: string;
|
||||
}
|
||||
@ -102,8 +102,8 @@ export declare class RestClient {
|
||||
listContractAddresses(): Promise<readonly string[]>;
|
||||
listContractsByCodeId(id: number): Promise<readonly ContractInfo[]>;
|
||||
getContractInfo(address: string): Promise<ContractInfo>;
|
||||
getAllContractState(address: string): Promise<readonly WasmData[]>;
|
||||
queryContractRaw(address: string, key: Uint8Array): Promise<unknown | null>;
|
||||
queryContractSmart(address: string, query: object): Promise<string>;
|
||||
getAllContractState(address: string): Promise<readonly Model[]>;
|
||||
queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null>;
|
||||
queryContractSmart(address: string, query: object): Promise<Uint8Array>;
|
||||
}
|
||||
export {};
|
||||
|
||||
7
packages/sdk/types/types.d.ts
vendored
7
packages/sdk/types/types.d.ts
vendored
@ -141,6 +141,11 @@ export interface ContractInfo {
|
||||
}
|
||||
export interface WasmData {
|
||||
readonly key: string;
|
||||
readonly val: unknown;
|
||||
readonly val: string;
|
||||
}
|
||||
export interface Model {
|
||||
readonly key: Uint8Array;
|
||||
readonly val: Uint8Array;
|
||||
}
|
||||
export declare function parseWasmData({ key, val }: WasmData): Model;
|
||||
export {};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Choose from https://hub.docker.com/r/cosmwasm/wasmd-demo/tags
|
||||
REPOSITORY="cosmwasm/wasmd-demo"
|
||||
VERSION="v0.0.5"
|
||||
VERSION="v0.6.0"
|
||||
|
||||
CONTAINER_NAME="wasmd"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user