Add ERC20 supprt to parseMsg

This commit is contained in:
Simon Warta 2020-02-17 14:27:38 +01:00
parent 3f534908f8
commit c94a49a1fb
3 changed files with 85 additions and 5 deletions

View File

@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/camelcase */
import { types } from "@cosmwasm/sdk";
import { Address, Algorithm, SendTransaction, TokenTicker } from "@iov/bcp";
import { Address, Algorithm, isSendTransaction, SendTransaction, TokenTicker } from "@iov/bcp";
import { Encoding } from "@iov/encoding";
import { assert } from "@iov/utils";
import {
decodeAmount,
@ -17,7 +18,7 @@ import {
} from "./decode";
import * as testdata from "./testdata.spec";
import cosmoshub from "./testdata/cosmoshub.json";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
const { fromBase64, fromHex } = Encoding;
@ -63,6 +64,23 @@ describe("decode", () => {
denom: "uatom",
},
];
const defaultErc20Tokens: Erc20Token[] = [
{
contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5",
fractionalDigits: 5,
ticker: "ASH",
},
{
contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd",
fractionalDigits: 0,
ticker: "BASH",
},
{
contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c",
fractionalDigits: 18,
ticker: "CASH",
},
];
describe("decodePubkey", () => {
it("works for secp256k1", () => {
@ -126,7 +144,7 @@ describe("decode", () => {
});
describe("parseMsg", () => {
it("works", () => {
it("works for bank send transaction", () => {
const msg: types.Msg = {
type: "cosmos-sdk/MsgSend",
value: {
@ -142,6 +160,37 @@ describe("decode", () => {
};
expect(parseMsg(msg, defaultMemo, testdata.chainId, defaultTokens)).toEqual(defaultSendTransaction);
});
it("works for ERC20 send transaction", () => {
const msg: types.MsgExecuteContract = {
type: "wasm/execute",
value: {
sender: "cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r",
contract: defaultErc20Tokens[0].contractAddress,
msg: {
transfer: {
amount: "887878484",
recipient: "cosmos1z7g5w84ynmjyg0kqpahdjqpj7yq34v3suckp0e",
},
},
sent_funds: [],
},
};
const transaction = parseMsg(msg, defaultMemo, testdata.chainId, defaultTokens, defaultErc20Tokens);
assert(isSendTransaction(transaction));
expect(transaction).toEqual({
kind: "bcp/send",
chainId: testdata.chainId,
sender: "cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r" as Address,
recipient: "cosmos1z7g5w84ynmjyg0kqpahdjqpj7yq34v3suckp0e" as Address,
amount: {
quantity: "887878484",
tokenTicker: "ASH" as TokenTicker,
fractionalDigits: 5,
},
memo: defaultMemo,
});
});
});
describe("parseFee", () => {

View File

@ -19,8 +19,9 @@ import {
UnsignedTransaction,
} from "@iov/bcp";
import { Decimal, Encoding } from "@iov/encoding";
import BN from "bn.js";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
const { fromBase64 } = Encoding;
@ -76,6 +77,7 @@ export function parseMsg(
memo: string | undefined,
chainId: ChainId,
tokens: BankTokens,
erc20Tokens: readonly Erc20Token[] = [],
): UnsignedTransaction {
if (types.isMsgSend(msg)) {
if (msg.value.amount.length !== 1) {
@ -90,6 +92,34 @@ export function parseMsg(
memo: memo,
};
return send;
} else if (types.isMsgExecuteContract(msg)) {
const matchingTokenContract = erc20Tokens.find(t => t.contractAddress === msg.value.contract);
if (!matchingTokenContract) {
return {
chainId: chainId,
kind: "bcp/unknown",
};
}
const recipient: string | undefined = (msg.value.msg as any).transfer?.recipient;
if (!recipient) throw new Error("Could not read recipient");
const amount: string | undefined = (msg.value.msg as any).transfer?.amount;
if (!amount) throw new Error("Could not read recipient");
const send: SendTransaction = {
kind: "bcp/send",
chainId: chainId,
sender: msg.value.sender as Address,
recipient: recipient as Address,
amount: {
quantity: new BN(amount).toString(),
fractionalDigits: matchingTokenContract.fractionalDigits,
tokenTicker: matchingTokenContract.ticker as TokenTicker,
},
memo: memo,
};
return send;
} else {
// Unknown transaction type
const unknown = {

View File

@ -13,7 +13,7 @@ import {
UnsignedTransaction,
} from "@iov/bcp";
import { Decimal } from "@iov/encoding";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
export declare function decodePubkey(pubkey: types.PubKey): PubkeyBundle;
export declare function decodeSignature(signature: string): SignatureBytes;
export declare function decodeFullSignature(signature: types.StdSignature, nonce: number): FullSignature;
@ -24,6 +24,7 @@ export declare function parseMsg(
memo: string | undefined,
chainId: ChainId,
tokens: BankTokens,
erc20Tokens?: readonly Erc20Token[],
): UnsignedTransaction;
export declare function parseFee(fee: types.StdFee, tokens: BankTokens): Fee;
export declare function parseUnsignedTx(