mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
Merge pull request #96 from confio/expose-send
Expose sendToken() on CosmWasmClient
This commit is contained in:
commit
fda2df453f
@ -222,50 +222,22 @@ describe("CosmWasmClient", () => {
|
||||
beforeAll(async () => {
|
||||
if (cosmosEnabled()) {
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = CosmWasmClient.makeReadOnly(httpUrl);
|
||||
const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes));
|
||||
|
||||
const memo = "My first contract on chain";
|
||||
const sendMsg: MsgSend = {
|
||||
type: "cosmos-sdk/MsgSend",
|
||||
value: {
|
||||
from_address: faucet.address,
|
||||
to_address: makeRandomAddress(),
|
||||
amount: [
|
||||
{
|
||||
denom: "ucosm",
|
||||
amount: "1234567",
|
||||
},
|
||||
],
|
||||
const recipient = makeRandomAddress();
|
||||
const transferAmount = [
|
||||
{
|
||||
denom: "ucosm",
|
||||
amount: "1234567",
|
||||
},
|
||||
};
|
||||
];
|
||||
const result = await client.sendTokens(recipient, transferAmount);
|
||||
|
||||
const fee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "890000",
|
||||
};
|
||||
|
||||
const chainId = await client.chainId();
|
||||
const { accountNumber, sequence } = await client.getNonce(faucet.address);
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await pen.sign(signBytes);
|
||||
const signedTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
memo: memo,
|
||||
signatures: [signature],
|
||||
};
|
||||
|
||||
const result = await client.postTx(marshalTx(signedTx));
|
||||
await sleep(50); // wait until tx is indexed
|
||||
const txDetails = await new RestClient(httpUrl).txsById(result.transactionHash);
|
||||
posted = {
|
||||
sender: sendMsg.value.from_address,
|
||||
recipient: sendMsg.value.to_address,
|
||||
sender: faucet.address,
|
||||
recipient: recipient,
|
||||
hash: result.transactionHash,
|
||||
height: Number.parseInt(txDetails.height, 10),
|
||||
tx: txDetails.tx,
|
||||
@ -446,6 +418,37 @@ describe("CosmWasmClient", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("sendTokens", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic);
|
||||
const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes));
|
||||
|
||||
// instantiate
|
||||
const transferAmount: readonly Coin[] = [
|
||||
{
|
||||
amount: "7890",
|
||||
denom: "ucosm",
|
||||
},
|
||||
];
|
||||
const beneficiaryAddress = makeRandomAddress();
|
||||
|
||||
// no tokens here
|
||||
const before = await client.getAccount(beneficiaryAddress);
|
||||
expect(before).toBeUndefined();
|
||||
|
||||
// send
|
||||
const result = await client.sendTokens(beneficiaryAddress, transferAmount, "for dinner");
|
||||
const [firstLog] = result.logs;
|
||||
expect(firstLog).toBeTruthy();
|
||||
|
||||
// got tokens
|
||||
const after = await client.getAccount(beneficiaryAddress);
|
||||
assert(after);
|
||||
expect(after.coins).toEqual(transferAmount);
|
||||
});
|
||||
});
|
||||
|
||||
describe("queryContractRaw", () => {
|
||||
const configKey = toAscii("config");
|
||||
const otherKey = toAscii("this_does_not_exist");
|
||||
|
@ -10,39 +10,40 @@ import {
|
||||
CosmosSdkTx,
|
||||
MsgExecuteContract,
|
||||
MsgInstantiateContract,
|
||||
MsgSend,
|
||||
MsgStoreCode,
|
||||
StdFee,
|
||||
StdSignature,
|
||||
} from "./types";
|
||||
|
||||
const defaultUploadFee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "1000000", // one million
|
||||
};
|
||||
export interface FeeTable {
|
||||
readonly upload: StdFee;
|
||||
readonly init: StdFee;
|
||||
readonly exec: StdFee;
|
||||
readonly send: StdFee;
|
||||
}
|
||||
|
||||
const defaultInitFee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "500000", // 500k
|
||||
};
|
||||
function singleAmount(amount: number, denom: string): readonly Coin[] {
|
||||
return [{ amount: amount.toString(), denom: denom }];
|
||||
}
|
||||
|
||||
const defaultExecFee: StdFee = {
|
||||
amount: [
|
||||
{
|
||||
amount: "5000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
],
|
||||
gas: "200000", // 200k
|
||||
const defaultFees: FeeTable = {
|
||||
upload: {
|
||||
amount: singleAmount(25000, "ucosm"),
|
||||
gas: "1000000", // one million
|
||||
},
|
||||
init: {
|
||||
amount: singleAmount(12500, "ucosm"),
|
||||
gas: "500000", // 500k
|
||||
},
|
||||
exec: {
|
||||
amount: singleAmount(5000, "ucosm"),
|
||||
gas: "200000", // 200k
|
||||
},
|
||||
send: {
|
||||
amount: singleAmount(2000, "ucosm"),
|
||||
gas: "80000", // 80k
|
||||
},
|
||||
};
|
||||
|
||||
export interface SigningCallback {
|
||||
@ -98,22 +99,28 @@ export interface ExecuteResult {
|
||||
|
||||
export class CosmWasmClient {
|
||||
public static makeReadOnly(url: string): CosmWasmClient {
|
||||
return new CosmWasmClient(url);
|
||||
return new CosmWasmClient(url, undefined, {});
|
||||
}
|
||||
|
||||
public static makeWritable(
|
||||
url: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
feeTable?: Partial<FeeTable>,
|
||||
): CosmWasmClient {
|
||||
return new CosmWasmClient(url, {
|
||||
senderAddress: senderAddress,
|
||||
signCallback: signCallback,
|
||||
});
|
||||
return new CosmWasmClient(
|
||||
url,
|
||||
{
|
||||
senderAddress: senderAddress,
|
||||
signCallback: signCallback,
|
||||
},
|
||||
feeTable || {},
|
||||
);
|
||||
}
|
||||
|
||||
private readonly restClient: RestClient;
|
||||
private readonly signingData: SigningData | undefined;
|
||||
private readonly fees: FeeTable;
|
||||
|
||||
private get senderAddress(): string {
|
||||
if (!this.signingData) throw new Error("Signing data not set in this client");
|
||||
@ -125,9 +132,10 @@ export class CosmWasmClient {
|
||||
return this.signingData.signCallback;
|
||||
}
|
||||
|
||||
private constructor(url: string, signingData?: SigningData) {
|
||||
private constructor(url: string, signingData: SigningData | undefined, customFees: Partial<FeeTable>) {
|
||||
this.restClient = new RestClient(url);
|
||||
this.signingData = signingData;
|
||||
this.fees = { ...defaultFees, ...customFees };
|
||||
}
|
||||
|
||||
public async chainId(): Promise<string> {
|
||||
@ -234,7 +242,7 @@ export class CosmWasmClient {
|
||||
builder: "",
|
||||
},
|
||||
};
|
||||
const fee = defaultUploadFee;
|
||||
const fee = this.fees.upload;
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.chainId();
|
||||
const signBytes = makeSignBytes([storeCodeMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
@ -270,7 +278,7 @@ export class CosmWasmClient {
|
||||
init_funds: transferAmount || [],
|
||||
},
|
||||
};
|
||||
const fee = defaultInitFee;
|
||||
const fee = this.fees.init;
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.chainId();
|
||||
const signBytes = makeSignBytes([instantiateMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
@ -304,7 +312,7 @@ export class CosmWasmClient {
|
||||
sent_funds: transferAmount || [],
|
||||
},
|
||||
};
|
||||
const fee = defaultExecFee;
|
||||
const fee = this.fees.exec;
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.chainId();
|
||||
const signBytes = makeSignBytes([executeMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
@ -322,6 +330,36 @@ export class CosmWasmClient {
|
||||
};
|
||||
}
|
||||
|
||||
public async sendTokens(
|
||||
recipientAddress: string,
|
||||
transferAmount: readonly Coin[],
|
||||
memo = "",
|
||||
): Promise<PostTxResult> {
|
||||
const sendMsg: MsgSend = {
|
||||
type: "cosmos-sdk/MsgSend",
|
||||
value: {
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
from_address: this.senderAddress,
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
to_address: recipientAddress,
|
||||
amount: transferAmount,
|
||||
},
|
||||
};
|
||||
const fee = this.fees.send;
|
||||
const { accountNumber, sequence } = await this.getNonce();
|
||||
const chainId = await this.chainId();
|
||||
const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence);
|
||||
const signature = await this.signCallback(signBytes);
|
||||
const signedTx = {
|
||||
msg: [sendMsg],
|
||||
fee: fee,
|
||||
memo: memo,
|
||||
signatures: [signature],
|
||||
};
|
||||
|
||||
return this.postTx(marshalTx(signedTx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data at the key if present (raw contract dependent storage data)
|
||||
* or null if no data at this key.
|
||||
|
17
packages/sdk/types/cosmwasmclient.d.ts
vendored
17
packages/sdk/types/cosmwasmclient.d.ts
vendored
@ -1,6 +1,12 @@
|
||||
import { Log } from "./logs";
|
||||
import { BlockResponse, TxsResponse } from "./restclient";
|
||||
import { Coin, CosmosSdkAccount, CosmosSdkTx, StdSignature } from "./types";
|
||||
import { Coin, CosmosSdkAccount, CosmosSdkTx, StdFee, StdSignature } from "./types";
|
||||
export interface FeeTable {
|
||||
readonly upload: StdFee;
|
||||
readonly init: StdFee;
|
||||
readonly exec: StdFee;
|
||||
readonly send: StdFee;
|
||||
}
|
||||
export interface SigningCallback {
|
||||
(signBytes: Uint8Array): Promise<StdSignature>;
|
||||
}
|
||||
@ -29,9 +35,15 @@ export interface ExecuteResult {
|
||||
}
|
||||
export declare class CosmWasmClient {
|
||||
static makeReadOnly(url: string): CosmWasmClient;
|
||||
static makeWritable(url: string, senderAddress: string, signCallback: SigningCallback): CosmWasmClient;
|
||||
static makeWritable(
|
||||
url: string,
|
||||
senderAddress: string,
|
||||
signCallback: SigningCallback,
|
||||
feeTable?: Partial<FeeTable>,
|
||||
): CosmWasmClient;
|
||||
private readonly restClient;
|
||||
private readonly signingData;
|
||||
private readonly fees;
|
||||
private get senderAddress();
|
||||
private get signCallback();
|
||||
private constructor();
|
||||
@ -71,6 +83,7 @@ export declare class CosmWasmClient {
|
||||
memo?: string,
|
||||
transferAmount?: readonly Coin[],
|
||||
): Promise<ExecuteResult>;
|
||||
sendTokens(recipientAddress: string, transferAmount: readonly Coin[], memo?: string): Promise<PostTxResult>;
|
||||
/**
|
||||
* Returns the data at the key if present (raw contract dependent storage data)
|
||||
* or null if no data at this key.
|
||||
|
Loading…
x
Reference in New Issue
Block a user