Add erc20 support to buildUnsignedTx

This commit is contained in:
Simon Warta 2020-02-10 17:06:25 +01:00
parent 6dc61379b9
commit 220a8ddd98
3 changed files with 150 additions and 29 deletions

View File

@ -21,7 +21,7 @@ import {
encodeFullSignature,
encodePubkey,
} from "./encode";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
const { fromBase64 } = Encoding;
@ -48,6 +48,23 @@ describe("encode", () => {
denom: "uatom",
},
];
const defaultErc20Tokens: Erc20Token[] = [
{
contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5",
fractionalDigits: 5,
ticker: "ASH",
},
{
contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd",
fractionalDigits: 0,
ticker: "BASH",
},
{
contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c",
fractionalDigits: 18,
ticker: "CASH",
},
];
describe("encodePubKey", () => {
it("encodes a Secp256k1 pubkey", () => {
@ -262,6 +279,56 @@ describe("encode", () => {
},
});
});
it("works for ERC20 send", () => {
const bashSendTx: SendTransaction = {
kind: "bcp/send",
chainId: defaultChainId,
sender: "cosmos1txqfn5jmcts0x0q7krdxj8tgf98tj0965vqlmq" as Address,
recipient: "cosmos1dddd" as Address,
memo: defaultMemo,
amount: {
fractionalDigits: 6,
quantity: "345",
tokenTicker: "BASH" as TokenTicker,
},
fee: {
tokens: {
fractionalDigits: 6,
quantity: "3333",
tokenTicker: "ATOM" as TokenTicker,
},
gasLimit: "234000",
},
};
expect(buildUnsignedTx(bashSendTx, defaultTokens, defaultErc20Tokens)).toEqual({
type: "cosmos-sdk/StdTx",
value: {
msg: [
{
type: "wasm/execute",
value: {
sender: "cosmos1txqfn5jmcts0x0q7krdxj8tgf98tj0965vqlmq",
contract: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd",
msg: {
transfer: {
recipient: "cosmos1dddd",
amount: "345",
},
},
sent_funds: [],
},
},
],
fee: {
amount: [{ denom: "uatom", amount: "3333" }],
gas: "234000",
},
signatures: [],
memo: defaultMemo,
},
});
});
});
describe("buildSignedTx", () => {

View File

@ -12,7 +12,7 @@ import {
} from "@iov/bcp";
import { Decimal, Encoding } from "@iov/encoding";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
const { toBase64 } = Encoding;
@ -79,37 +79,83 @@ export function encodeFullSignature(fullSignature: FullSignature): types.StdSign
}
}
export function buildUnsignedTx(tx: UnsignedTransaction, tokens: BankTokens): types.AminoTx {
export function buildUnsignedTx(
tx: UnsignedTransaction,
bankTokens: BankTokens,
erc20Tokens: readonly Erc20Token[] = [],
): types.AminoTx {
if (!isSendTransaction(tx)) {
throw new Error("Received transaction of unsupported kind");
}
return {
type: "cosmos-sdk/StdTx",
value: {
msg: [
{
type: "cosmos-sdk/MsgSend",
value: {
from_address: tx.sender,
to_address: tx.recipient,
amount: [encodeAmount(tx.amount, tokens)],
const matchingBankToken = bankTokens.find(t => t.ticker === tx.amount.tokenTicker);
const matchingErc20Token = erc20Tokens.find(t => t.ticker === tx.amount.tokenTicker);
if (matchingBankToken) {
return {
type: "cosmos-sdk/StdTx",
value: {
msg: [
{
type: "cosmos-sdk/MsgSend",
value: {
from_address: tx.sender,
to_address: tx.recipient,
amount: [encodeAmount(tx.amount, bankTokens)],
},
},
},
],
memo: tx.memo || "",
signatures: [],
fee: tx.fee
? encodeFee(tx.fee, tokens)
: {
amount: [],
gas: "",
],
memo: tx.memo || "",
signatures: [],
fee: tx.fee
? encodeFee(tx.fee, bankTokens)
: {
amount: [],
gas: "",
},
},
};
} else if (matchingErc20Token) {
return {
type: "cosmos-sdk/StdTx",
value: {
msg: [
{
type: "wasm/execute",
value: {
sender: tx.sender,
contract: matchingErc20Token.contractAddress,
msg: {
transfer: {
amount: tx.amount.quantity,
recipient: tx.recipient,
},
},
sent_funds: [],
},
},
},
};
],
memo: tx.memo || "",
signatures: [],
fee: tx.fee
? encodeFee(tx.fee, bankTokens)
: {
amount: [],
gas: "",
},
},
};
} else {
throw new Error("Cannot encode this type of transaction");
}
}
export function buildSignedTx(tx: SignedTransaction, tokens: BankTokens): types.AminoTx {
const built = buildUnsignedTx(tx.transaction, tokens);
export function buildSignedTx(
tx: SignedTransaction,
bankTokens: BankTokens,
erc20Tokens: readonly Erc20Token[] = [],
): types.AminoTx {
const built = buildUnsignedTx(tx.transaction, bankTokens, erc20Tokens);
return {
...built,
value: {

View File

@ -1,11 +1,19 @@
import { types } from "@cosmwasm/sdk";
import { Amount, Fee, FullSignature, PubkeyBundle, SignedTransaction, UnsignedTransaction } from "@iov/bcp";
import { Decimal } from "@iov/encoding";
import { BankTokens } from "./types";
import { BankTokens, Erc20Token } from "./types";
export declare function encodePubkey(pubkey: PubkeyBundle): types.PubKey;
export declare function decimalToCoin(lookup: BankTokens, value: Decimal, ticker: string): types.Coin;
export declare function encodeAmount(amount: Amount, tokens: BankTokens): types.Coin;
export declare function encodeFee(fee: Fee, tokens: BankTokens): types.StdFee;
export declare function encodeFullSignature(fullSignature: FullSignature): types.StdSignature;
export declare function buildUnsignedTx(tx: UnsignedTransaction, tokens: BankTokens): types.AminoTx;
export declare function buildSignedTx(tx: SignedTransaction, tokens: BankTokens): types.AminoTx;
export declare function buildUnsignedTx(
tx: UnsignedTransaction,
bankTokens: BankTokens,
erc20Tokens?: readonly Erc20Token[],
): types.AminoTx;
export declare function buildSignedTx(
tx: SignedTransaction,
bankTokens: BankTokens,
erc20Tokens?: readonly Erc20Token[],
): types.AminoTx;