From 34c8027167e826f7ade86589f6d78a1106481edb Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 20 Mar 2020 16:36:30 +0100 Subject: [PATCH] Update mask demo to everything except staking --- packages/cli/MASK.md | 77 ++++++++++++++++++++++++++++++++++- packages/cli/examples/mask.ts | 46 +++++++++++++++------ 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/packages/cli/MASK.md b/packages/cli/MASK.md index 9e6e13b1..5b873c0e 100644 --- a/packages/cli/MASK.md +++ b/packages/cli/MASK.md @@ -56,6 +56,81 @@ const codeId = codes.filter(x => x.checksum === hash).map(x => x.id)[0] // instantiate one contract const maskResp = await client.instantiate(codeId, {}, "My Mask"); const mask = maskResp.contractAddress; + +// You can also find the contractAddress later (in a future session), like: +const contracts = await client.getContracts(codeId); +const mask = contracts.filter(x => x.label == "My Mask").map(x => x.address)[0]; ``` -TODO: using it with proper types +Now, let's use the mask. To do so, we need to load it up with some tokens +(both native and ERC20 - from the contract you deployed last time). + +```ts +client.sendTokens(mask, [{amount: "500000", "denom": "ucosm"}]) +client.getAccount(mask) + +// get the foo contract again... +const ercId = 1; // from earlier example, change this if different on your network +const ercs = await client.getContracts(ercId); +const foo = ercs.filter(x => x.label == "FOO").map(x => x.address)[0]; + +// send some erc tokens to the mask as before +smartQuery(client, foo, { balance: { address: mask } }) +const ercMsg = { transfer: {recipient: mask, amount: "800000"}} +client.execute(foo, ercMsg); +smartQuery(client, foo, { balance: { address: mask } }) +``` + +Now, let's send some tokens from it: + +```ts +const rand = await randomAddress("cosmos"); +client.getAccount(rand) +client.getAccount(mask) + +const callSend: HandleMsg = { reflectmsg: { msgs: [sendMsg(mask, rand, [{amount: "80000", denom: "ucosm"}])]}}; +client.execute(mask, callSend) +client.getAccount(rand) +client.getAccount(mask) +``` + +And call the ERC20 contract from it: + +```ts +smartQuery(client, foo, { balance: { address: rand } }) +smartQuery(client, foo, { balance: { address: mask } }) + +const callContract: HandleMsg = { reflectmsg: { msgs: [contractMsg(foo, {transfer: {"amount": "80000", "recipient": rand}})]}}; +client.execute(mask, callContract) +smartQuery(client, foo, { balance: { address: rand } }) +smartQuery(client, foo, { balance: { address: mask } }) +``` + +And now... let's use OpaqueMsg to call into native blockchain messages. +Here we will trigger a staking command. This is an "opaque" command, so neither cosmwams-js +nor the cosmwasm contract understands it. It is passed verbatim from the client to +the wasmd blockchain (reflected by mask, so using the mask address). + +To view this properly, we will have to use the cli tooling: + +```sh +TODO +``` + +To create such a message, we need to produce the amino json encoding of a staking message. +That does involve a bit of investigation, but looks like: + +```json +TODO +``` + +```ts +const staking = {} +const callOpaque: HandleMsg = { reflectmsg: { msgs: [opaqueMsg(staking)]}}; +client.execute(mask, callOpaque) +``` + +Now validate this with the CLI tooling: +```sh +TODO +``` diff --git a/packages/cli/examples/mask.ts b/packages/cli/examples/mask.ts index 7c3a567b..cecbd2b7 100644 --- a/packages/cli/examples/mask.ts +++ b/packages/cli/examples/mask.ts @@ -12,10 +12,7 @@ export type HandleMsg = msgs: ( | { send: { - amount: { - amount: string; - denom: string; - }[]; + amount: types.Coin[]; from_address: string; to_address: string; }; @@ -23,19 +20,14 @@ export type HandleMsg = | { contract: { contract_addr: string; - // this must be changed - is Base64 encoded string + // this had to be changed - is Base64 encoded string msg: string; - send: - | { - amount: string; - denom: string; - }[] - | null; + send: types.Coin[] | null; }; } | { opaque: { - // this must be changed - is Base64 encoded string + // this had to be changed - is Base64 encoded string data: string; }; } @@ -65,3 +57,33 @@ export interface State { } /*** END auto-gen ****/ + +const base64Msg = (msg: object): string => toBase64(toUtf8(JSON.stringify(msg))); + +const sendMsg = (from_address: string, to_address: string, amount: types.Coin[]) => { + return { + send: { + from_address, + to_address, + amount, + } + }; +} + +const contractMsg = (contract_addr: string, msg: object, amount?: types.Coin[]) => { + return { + contract: { + contract_addr, + msg: base64Msg(msg), + send: amount || null, + } + }; +} + +const opaqueMsg = (data: object) => { + return { + opaque: { + data: base64Msg(data), + } + }; +}