From 1e8ed6fc108fd0f38f273df31a67abdc063bfdc8 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 2 Jun 2020 16:50:47 +0200 Subject: [PATCH] Remove BCP's dependency on @cosmwasm/cosmwasm --- packages/bcp/package.json | 1 - packages/bcp/src/cosmwasmcodec.spec.ts | 56 +---- packages/bcp/src/cosmwasmcodec.ts | 16 +- packages/bcp/src/cosmwasmconnection.spec.ts | 214 -------------------- packages/bcp/src/cosmwasmconnection.ts | 131 +++--------- packages/bcp/src/cosmwasmconnector.ts | 2 +- packages/bcp/src/decode.spec.ts | 145 ++----------- packages/bcp/src/decode.ts | 45 +--- packages/bcp/src/encode.spec.ts | 101 +-------- packages/bcp/src/encode.ts | 50 +---- packages/bcp/src/index.ts | 2 +- packages/bcp/src/types.ts | 15 -- packages/bcp/types/cosmwasmcodec.d.ts | 5 +- packages/bcp/types/cosmwasmconnection.d.ts | 11 +- packages/bcp/types/decode.d.ts | 7 +- packages/bcp/types/encode.d.ts | 10 +- packages/bcp/types/index.d.ts | 2 +- packages/bcp/types/types.d.ts | 14 -- packages/faucet/src/constants.ts | 8 - packages/faucet/src/faucet.spec.ts | 46 +---- packages/faucet/src/tokenmanager.ts | 4 +- 21 files changed, 79 insertions(+), 806 deletions(-) diff --git a/packages/bcp/package.json b/packages/bcp/package.json index 5fc202bf..1a21cd31 100644 --- a/packages/bcp/package.json +++ b/packages/bcp/package.json @@ -36,7 +36,6 @@ "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, "dependencies": { - "@cosmwasm/cosmwasm": "^0.8.0", "@cosmwasm/sdk38": "^0.8.0", "@iov/bcp": "^2.1.0", "@iov/crypto": "^2.1.0", diff --git a/packages/bcp/src/cosmwasmcodec.spec.ts b/packages/bcp/src/cosmwasmcodec.spec.ts index c40b17c2..081e7e0a 100644 --- a/packages/bcp/src/cosmwasmcodec.spec.ts +++ b/packages/bcp/src/cosmwasmcodec.spec.ts @@ -1,9 +1,9 @@ -import { Address, PostableBytes, PrehashType, SendTransaction, TokenTicker } from "@iov/bcp"; +import { PostableBytes, PrehashType } from "@iov/bcp"; import { Encoding } from "@iov/encoding"; import { CosmWasmCodec } from "./cosmwasmcodec"; import { chainId, nonce, sendTxJson, signedTxBin, signedTxEncodedJson, signedTxJson } from "./testdata.spec"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; const { toUtf8 } = Encoding; @@ -17,26 +17,8 @@ const defaultBankTokens: readonly BankToken[] = [ }, ]; -const defaultErc20Tokens: readonly Erc20Token[] = [ - { - contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - fractionalDigits: 5, - ticker: "HASH", - }, - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - }, - { - contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", - fractionalDigits: 18, - ticker: "JADE", - }, -]; - describe("CosmWasmCodec", () => { - const codec = new CosmWasmCodec(defaultPrefix, defaultBankTokens, defaultErc20Tokens); + const codec = new CosmWasmCodec(defaultPrefix, defaultBankTokens); describe("isValidAddress", () => { it("accepts valid addresses", () => { @@ -65,38 +47,6 @@ describe("CosmWasmCodec", () => { }; expect(codec.bytesToSign(sendTxJson, nonce)).toEqual(expected); }); - - it("works for ERC20 send", () => { - const bashSendTx: SendTransaction = { - kind: "bcp/send", - chainId: chainId, - sender: "cosmos1txqfn5jmcts0x0q7krdxj8tgf98tj0965vqlmq" as Address, - recipient: "cosmos1dddd" as Address, - memo: "My first ISA payment", - amount: { - fractionalDigits: 0, - quantity: "345", - tokenTicker: "ISA" as TokenTicker, - }, - fee: { - tokens: { - fractionalDigits: 6, - quantity: "2500", - tokenTicker: "ATOM" as TokenTicker, - }, - gasLimit: "100000", - }, - }; - - const expected = { - bytes: toUtf8( - '{"account_number":"0","chain_id":"cosmoshub-3","fee":{"amount":[{"amount":"2500","denom":"uatom"}],"gas":"100000"},"memo":"My first ISA payment","msgs":[{"type":"wasm/execute","value":{"contract":"cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd","msg":{"transfer":{"amount":"345","recipient":"cosmos1dddd"}},"sender":"cosmos1txqfn5jmcts0x0q7krdxj8tgf98tj0965vqlmq","sent_funds":[]}}],"sequence":"99"}', - ), - prehashType: PrehashType.Sha256, - }; - - expect(codec.bytesToSign(bashSendTx, nonce)).toEqual(expected); - }); }); describe("bytesToPost", () => { diff --git a/packages/bcp/src/cosmwasmcodec.ts b/packages/bcp/src/cosmwasmcodec.ts index ddaa88d9..3109b6b1 100644 --- a/packages/bcp/src/cosmwasmcodec.ts +++ b/packages/bcp/src/cosmwasmcodec.ts @@ -20,25 +20,19 @@ import { pubkeyToAddress } from "./address"; import { Caip5 } from "./caip5"; import { parseSignedTx } from "./decode"; import { buildSignedTx, buildUnsignedTx } from "./encode"; -import { BankToken, Erc20Token, nonceToAccountNumber, nonceToSequence } from "./types"; +import { BankToken, nonceToAccountNumber, nonceToSequence } from "./types"; export class CosmWasmCodec implements TxCodec { private readonly addressPrefix: string; private readonly bankTokens: readonly BankToken[]; - private readonly erc20Tokens: readonly Erc20Token[]; - public constructor( - addressPrefix: string, - bankTokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[] = [], - ) { + public constructor(addressPrefix: string, bankTokens: readonly BankToken[]) { this.addressPrefix = addressPrefix; this.bankTokens = bankTokens; - this.erc20Tokens = erc20Tokens; } public bytesToSign(unsigned: UnsignedTransaction, nonce: Nonce): SigningJob { - const built = buildUnsignedTx(unsigned, this.bankTokens, this.erc20Tokens); + const built = buildUnsignedTx(unsigned, this.bankTokens); const signBytes = makeSignBytes( built.value.msg, @@ -58,7 +52,7 @@ export class CosmWasmCodec implements TxCodec { // PostableBytes are JSON-encoded StdTx public bytesToPost(signed: SignedTransaction): PostableBytes { // TODO: change this as well (return StdTx, not AminoTx)? - const built = buildSignedTx(signed, this.bankTokens, this.erc20Tokens); + const built = buildSignedTx(signed, this.bankTokens); return marshalTx(built.value) as PostableBytes; } @@ -76,7 +70,7 @@ export class CosmWasmCodec implements TxCodec { throw new Error("Nonce is required"); } const parsed = unmarshalTx(bytes); - return parseSignedTx(parsed, chainId, nonce, this.bankTokens, this.erc20Tokens); + return parseSignedTx(parsed, chainId, nonce, this.bankTokens); } public identityToAddress(identity: Identity): Address { diff --git a/packages/bcp/src/cosmwasmconnection.spec.ts b/packages/bcp/src/cosmwasmconnection.spec.ts index a661a87c..b1ffab57 100644 --- a/packages/bcp/src/cosmwasmconnection.spec.ts +++ b/packages/bcp/src/cosmwasmconnection.spec.ts @@ -69,7 +69,6 @@ const bob = { describe("CosmWasmConnection", () => { const cosm = "COSM" as TokenTicker; - const isa = "ISA" as TokenTicker; const httpUrl = "http://localhost:1317"; const defaultChainId = "cosmos:testing" as ChainId; const defaultEmptyAddress = "cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r" as Address; @@ -104,26 +103,6 @@ describe("CosmWasmConnection", () => { denom: "ustake", }, ], - erc20Tokens: [ - { - contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - fractionalDigits: 5, - ticker: "HASH", - name: "Hash Token", - }, - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - name: "Isa Token", - }, - { - contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", - fractionalDigits: 18, - ticker: "JADE", - name: "Jade Token", - }, - ], }; const atomConfig: TokenConfiguration = { @@ -198,21 +177,6 @@ describe("CosmWasmConnection", () => { tokenName: "Fee Token", tokenTicker: "COSM" as TokenTicker, }, - { - fractionalDigits: 5, - tokenName: "Hash Token", - tokenTicker: "HASH" as TokenTicker, - }, - { - fractionalDigits: 0, - tokenName: "Isa Token", - tokenTicker: "ISA" as TokenTicker, - }, - { - fractionalDigits: 18, - tokenName: "Jade Token", - tokenTicker: "JADE" as TokenTicker, - }, { fractionalDigits: 6, tokenName: "Staking Token", @@ -255,16 +219,6 @@ describe("CosmWasmConnection", () => { quantity: "1000000000", fractionalDigits: 6, }, - { - tokenTicker: "HASH" as TokenTicker, - quantity: "12812345", - fractionalDigits: 5, - }, - { - tokenTicker: "ISA" as TokenTicker, - quantity: "42", - fractionalDigits: 0, - }, { tokenTicker: "STAKE" as TokenTicker, quantity: "1000000000", @@ -408,56 +362,6 @@ describe("CosmWasmConnection", () => { connection.disconnect(); }); - it("can get a recently posted ERC20 send transaction", async () => { - pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); - const profile = new UserProfile(); - const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(bob.mnemonic)); - const senderIdentity = await profile.createIdentity(wallet.id, defaultChainId, bob.path); - const senderAddress = connection.codec.identityToAddress(senderIdentity); - - const unsigned = await connection.withDefaultFee({ - kind: "bcp/send", - chainId: defaultChainId, - sender: senderAddress, - recipient: defaultRecipient, - memo: "An ERC20 payment", - amount: { - quantity: "345", - fractionalDigits: 0, - tokenTicker: isa, - }, - }); - const nonce = await connection.getNonce({ address: senderAddress }); - const signed = await profile.signTransaction(senderIdentity, unsigned, connection.codec, nonce); - const postableBytes = connection.codec.bytesToPost(signed); - const response = await connection.postTx(postableBytes); - const { transactionId } = response; - await response.blockInfo.waitFor((info) => isBlockInfoSucceeded(info)); - - const getResponse = await connection.getTx(transactionId); - expect(getResponse.transactionId).toEqual(transactionId); - assert(isConfirmedTransaction(getResponse), "Expected transaction to succeed"); - assert(getResponse.log, "Log must be available"); - const [firstLog] = JSON.parse(getResponse.log); - expect(firstLog.events.length).toEqual(2); - - const { transaction, signatures } = getResponse; - assert(isSendTransaction(transaction), "Expected send transaction"); - expect(transaction).toEqual(unsigned); - expect(signatures.length).toEqual(1); - expect(signatures[0]).toEqual({ - nonce: signed.signatures[0].nonce, - pubkey: { - algo: signed.signatures[0].pubkey.algo, - data: Secp256k1.compressPubkey(signed.signatures[0].pubkey.data), - }, - signature: Secp256k1.trimRecoveryByte(signed.signatures[0].signature), - }); - - connection.disconnect(); - }); - it("can get an old transaction", async () => { pendingWithoutWasmd(); const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); @@ -604,124 +508,6 @@ describe("CosmWasmConnection", () => { connection.disconnect(); }); - it("can post an ERC20 transfer and search for the transaction", async () => { - pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); - const profile = new UserProfile(); - const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(bob.mnemonic)); - const sender = await profile.createIdentity(wallet.id, defaultChainId, bob.path); - const senderAddress = connection.codec.identityToAddress(sender); - - const recipient = makeRandomAddress(); - const unsigned = await connection.withDefaultFee({ - kind: "bcp/send", - chainId: defaultChainId, - sender: senderAddress, - recipient: recipient, - memo: "My first payment", - amount: { - quantity: "75", - fractionalDigits: 0, - tokenTicker: "ISA" as TokenTicker, - }, - }); - const nonce = await connection.getNonce({ address: senderAddress }); - const signed = await profile.signTransaction(sender, unsigned, connection.codec, nonce); - const postableBytes = connection.codec.bytesToPost(signed); - const response = await connection.postTx(postableBytes); - const { transactionId } = response; - const blockInfo = await response.blockInfo.waitFor((info) => !isBlockInfoPending(info)); - expect(blockInfo.state).toEqual(TransactionState.Succeeded); - - // search by id - const byIdResults = await connection.searchTx({ id: transactionId }); - expect(byIdResults.length).toEqual(1); - const byIdResult = byIdResults[0]; - expect(byIdResult.transactionId).toEqual(transactionId); - assert(isConfirmedTransaction(byIdResult), "Expected transaction to succeed"); - assert(byIdResult.log, "Log must be available"); - const [firstByIdlog] = JSON.parse(byIdResult.log); - expect(firstByIdlog.events.length).toEqual(2); - expect(firstByIdlog.events[0].type).toEqual("message"); - expect(firstByIdlog.events[1].type).toEqual("wasm"); - // wasm event attributes added by contract - expect(firstByIdlog.events[1].attributes).toContain({ key: "action", value: "transfer" }); - expect(firstByIdlog.events[1].attributes).toContain({ key: "sender", value: senderAddress }); - expect(firstByIdlog.events[1].attributes).toContain({ key: "recipient", value: recipient }); - // wasm event attributes added wasmd - expect(firstByIdlog.events[1].attributes).toContain({ - key: "contract_address", - value: defaultConfig.erc20Tokens![1].contractAddress, - }); - const byIdTransaction = byIdResult.transaction; - assert(isSendTransaction(byIdTransaction), "Expected send transaction"); - expect(byIdTransaction).toEqual(unsigned); - - // search by sender address - const bySenderResults = await connection.searchTx({ sentFromOrTo: senderAddress }); - expect(bySenderResults).toBeTruthy(); - expect(bySenderResults.length).toBeGreaterThanOrEqual(1); - const bySenderResult = bySenderResults[bySenderResults.length - 1]; - expect(bySenderResult.transactionId).toEqual(transactionId); - assert(isConfirmedTransaction(bySenderResult), "Expected transaction to succeed"); - assert(bySenderResult.log, "Log must be available"); - const [firstBySenderLog] = JSON.parse(bySenderResult.log); - expect(firstBySenderLog.events.length).toEqual(2); - expect(firstBySenderLog.events[0].type).toEqual("message"); - expect(firstBySenderLog.events[1].type).toEqual("wasm"); - // wasm event attributes added by contract - expect(firstBySenderLog.events[1].attributes).toContain({ key: "action", value: "transfer" }); - expect(firstBySenderLog.events[1].attributes).toContain({ key: "sender", value: senderAddress }); - expect(firstBySenderLog.events[1].attributes).toContain({ key: "recipient", value: recipient }); - // wasm event attributes added wasmd - expect(firstBySenderLog.events[1].attributes).toContain({ - key: "contract_address", - value: defaultConfig.erc20Tokens![1].contractAddress, - }); - const bySenderTransaction = bySenderResult.transaction; - assert(isSendTransaction(bySenderTransaction), "Expected send transaction"); - expect(bySenderTransaction).toEqual(unsigned); - - // search by recipient address - const byRecipientResults = await connection.searchTx({ sentFromOrTo: recipient }); - expect(byRecipientResults.length).toBeGreaterThanOrEqual(1); - const byRecipientResult = byRecipientResults[byRecipientResults.length - 1]; - expect(byRecipientResult.transactionId).toEqual(transactionId); - assert(isConfirmedTransaction(byRecipientResult), "Expected transaction to succeed"); - assert(byRecipientResult.log, "Log must be available"); - const [firstByRecipientLog] = JSON.parse(bySenderResult.log); - expect(firstByRecipientLog.events.length).toEqual(2); - expect(firstByRecipientLog.events[0].type).toEqual("message"); - expect(firstByRecipientLog.events[1].type).toEqual("wasm"); - // wasm event attributes added by contract - expect(firstByRecipientLog.events[1].attributes).toContain({ key: "action", value: "transfer" }); - expect(firstByRecipientLog.events[1].attributes).toContain({ key: "sender", value: senderAddress }); - expect(firstByRecipientLog.events[1].attributes).toContain({ key: "recipient", value: recipient }); - // wasm event attributes added wasmd - expect(firstByRecipientLog.events[1].attributes).toContain({ - key: "contract_address", - value: defaultConfig.erc20Tokens![1].contractAddress, - }); - const byRecipeintTransaction = byRecipientResult.transaction; - assert(isSendTransaction(byRecipeintTransaction), "Expected send transaction"); - expect(byRecipeintTransaction).toEqual(unsigned); - - // search by height - const heightResults = await connection.searchTx({ height: byIdResult.height }); - expect(heightResults.length).toEqual(1); - const heightResult = heightResults[0]; - expect(heightResult.transactionId).toEqual(transactionId); - assert(isConfirmedTransaction(heightResult), "Expected transaction to succeed"); - assert(heightResult.log, "Log must be available"); - const [firstHeightLog] = JSON.parse(heightResult.log); - expect(firstHeightLog.events.length).toEqual(2); - const heightTransaction = heightResult.transaction; - assert(isSendTransaction(heightTransaction), "Expected send transaction"); - expect(heightTransaction).toEqual(unsigned); - - connection.disconnect(); - }); - it("can search by minHeight and maxHeight", async () => { pendingWithoutWasmd(); const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); diff --git a/packages/bcp/src/cosmwasmconnection.ts b/packages/bcp/src/cosmwasmconnection.ts index b28c2c0f..f84ce8fe 100644 --- a/packages/bcp/src/cosmwasmconnection.ts +++ b/packages/bcp/src/cosmwasmconnection.ts @@ -1,15 +1,15 @@ import { - CosmWasmClient, - isMsgExecuteContract, - isMsgInstantiateContract, - isMsgStoreCode, -} from "@cosmwasm/cosmwasm"; -import { findSequenceForSignedTx, IndexedTx, isMsgSend, isStdTx, SearchTxFilter } from "@cosmwasm/sdk38"; + CosmosClient, + findSequenceForSignedTx, + IndexedTx, + isMsgSend, + isStdTx, + SearchTxFilter, +} from "@cosmwasm/sdk38"; import { Account, AccountQuery, AddressQuery, - Amount, BlockchainConnection, BlockHeader, BlockId, @@ -37,7 +37,6 @@ import { } from "@iov/bcp"; import { Encoding, Uint53 } from "@iov/encoding"; import { concat, DefaultValueProducer, ValueAndUpdates } from "@iov/stream"; -import BN from "bn.js"; import equal from "fast-deep-equal"; import { ReadonlyDate } from "readonly-date"; import { Producer, Stream } from "xstream"; @@ -47,7 +46,7 @@ import { Caip5 } from "./caip5"; import { CosmWasmCodec } from "./cosmwasmcodec"; import { decodeAmount, decodePubkey, parseTxsResponseSigned, parseTxsResponseUnsigned } from "./decode"; import { buildSignedTx } from "./encode"; -import { accountToNonce, BankToken, Erc20Token } from "./types"; +import { accountToNonce, BankToken } from "./types"; // poll every 0.5 seconds (block time 1s) const defaultPollInterval = 500; @@ -55,8 +54,6 @@ const defaultPollInterval = 500; export interface TokenConfiguration { /** Supported tokens of the Cosmos SDK bank module */ readonly bankTokens: ReadonlyArray; - /** Smart contract based tokens (ERC20 compatible). Unset means empty array. */ - readonly erc20Tokens?: ReadonlyArray; } function isDefined(value: X | undefined): value is X { @@ -92,43 +89,40 @@ export class CosmWasmConnection implements BlockchainConnection { addressPrefix: string, tokens: TokenConfiguration, ): Promise { - const cosmWasmClient = new CosmWasmClient(url); - const chainData = await this.initialize(cosmWasmClient); - return new CosmWasmConnection(cosmWasmClient, chainData, addressPrefix, tokens); + const cosmosClient = new CosmosClient(url); + const chainData = await this.initialize(cosmosClient); + return new CosmWasmConnection(cosmosClient, chainData, addressPrefix, tokens); } - private static async initialize(cosmWasmClient: CosmWasmClient): Promise { - const rawChainId = await cosmWasmClient.getChainId(); + private static async initialize(cosmosClient: CosmosClient): Promise { + const rawChainId = await cosmosClient.getChainId(); return Caip5.encode(rawChainId); } public readonly chainId: ChainId; public readonly codec: TxCodec; - private readonly cosmWasmClient: CosmWasmClient; + private readonly cosmosClient: CosmosClient; private readonly addressPrefix: string; private readonly bankTokens: readonly BankToken[]; - private readonly erc20Tokens: readonly Erc20Token[]; // these are derived from arguments (cached for use in multiple functions) private readonly feeToken: BankToken | undefined; private readonly supportedTokens: readonly Token[]; private constructor( - cosmWasmClient: CosmWasmClient, + cosmosClient: CosmosClient, chainId: ChainId, addressPrefix: string, tokens: TokenConfiguration, ) { - this.cosmWasmClient = cosmWasmClient; + this.cosmosClient = cosmosClient; this.chainId = chainId; - this.codec = new CosmWasmCodec(addressPrefix, tokens.bankTokens, tokens.erc20Tokens); + this.codec = new CosmWasmCodec(addressPrefix, tokens.bankTokens); this.addressPrefix = addressPrefix; this.bankTokens = tokens.bankTokens; this.feeToken = this.bankTokens.find(() => true); - const erc20Tokens = tokens.erc20Tokens || []; - this.erc20Tokens = erc20Tokens; - this.supportedTokens = [...tokens.bankTokens, ...erc20Tokens] + this.supportedTokens = tokens.bankTokens .map((info) => ({ tokenTicker: info.ticker as TokenTicker, tokenName: info.name, @@ -142,7 +136,7 @@ export class CosmWasmConnection implements BlockchainConnection { } public async height(): Promise { - return this.cosmWasmClient.getHeight(); + return this.cosmosClient.getHeight(); } public async getToken(searchTicker: TokenTicker): Promise { @@ -158,40 +152,24 @@ export class CosmWasmConnection implements BlockchainConnection { * context and network available, which we might use to implement the API in an async way. */ public async identifier(signed: SignedTransaction): Promise { - const tx = buildSignedTx(signed, this.bankTokens, this.erc20Tokens); - const id = await this.cosmWasmClient.getIdentifier(tx); + const tx = buildSignedTx(signed, this.bankTokens); + const id = await this.cosmosClient.getIdentifier(tx); return id as TransactionId; } public async getAccount(query: AccountQuery): Promise { const address = isPubkeyQuery(query) ? pubkeyToAddress(query.pubkey, this.addressPrefix) : query.address; - const bankAccount = await this.cosmWasmClient.getAccount(address); + const bankAccount = await this.cosmosClient.getAccount(address); const supportedBankCoins = (bankAccount?.balance || []).filter(({ denom }) => this.bankTokens.find((token) => token.denom === denom), ); - const erc20Amounts = await Promise.all( - this.erc20Tokens.map( - async (erc20): Promise => { - const queryMsg = { balance: { address: address } }; - const response = await this.cosmWasmClient.queryContractSmart(erc20.contractAddress, queryMsg); - const normalizedBalance = new BN(response.balance).toString(); - return { - fractionalDigits: erc20.fractionalDigits, - quantity: normalizedBalance, - tokenTicker: erc20.ticker as TokenTicker, - }; - }, - ), - ); - const nonZeroErc20Amounts = erc20Amounts.filter((amount) => amount.quantity !== "0"); - if (!bankAccount && nonZeroErc20Amounts.length === 0) { + if (!bankAccount) { return undefined; } else { const balance = [ ...supportedBankCoins.map((coin) => decodeAmount(this.bankTokens, coin)), - ...nonZeroErc20Amounts, ].sort((a, b) => a.tokenTicker.localeCompare(b.tokenTicker)); const pubkey = bankAccount?.pubkey ? decodePubkey(bankAccount.pubkey) : undefined; return { @@ -234,7 +212,7 @@ export class CosmWasmConnection implements BlockchainConnection { public async getNonce(query: AddressQuery | PubkeyQuery): Promise { const address = isPubkeyQuery(query) ? pubkeyToAddress(query.pubkey, this.addressPrefix) : query.address; - const { accountNumber, sequence } = await this.cosmWasmClient.getNonce(address); + const { accountNumber, sequence } = await this.cosmosClient.getNonce(address); return accountToNonce(accountNumber, sequence); } @@ -249,7 +227,7 @@ export class CosmWasmConnection implements BlockchainConnection { } public async getBlockHeader(height: number): Promise { - const { id, header, txs } = await this.cosmWasmClient.getBlock(height); + const { id, header, txs } = await this.cosmosClient.getBlock(height); return { id: id as BlockId, height: header.height, @@ -265,7 +243,7 @@ export class CosmWasmConnection implements BlockchainConnection { public async getTx( id: TransactionId, ): Promise | FailedTransaction> { - const results = await this.cosmWasmClient.searchTx({ id: id }); + const results = await this.cosmosClient.searchTx({ id: id }); switch (results.length) { case 0: throw new Error("Transaction does not exist"); @@ -279,7 +257,7 @@ export class CosmWasmConnection implements BlockchainConnection { public async postTx(tx: PostableBytes): Promise { const txAsJson = JSON.parse(Encoding.fromUtf8(tx)); if (!isStdTx(txAsJson)) throw new Error("Postable bytes must contain a JSON encoded StdTx"); - const { transactionHash, rawLog } = await this.cosmWasmClient.postTx(txAsJson); + const { transactionHash, rawLog } = await this.cosmosClient.postTx(txAsJson); const transactionId = transactionHash as TransactionId; const firstEvent: BlockInfo = { state: TransactionState.Pending }; let blockInfoInterval: NodeJS.Timeout; @@ -340,36 +318,12 @@ export class CosmWasmConnection implements BlockchainConnection { let txs: readonly IndexedTx[]; if (id) { - txs = await this.cosmWasmClient.searchTx({ id: id }, filter); + txs = await this.cosmosClient.searchTx({ id: id }, filter); } else if (height) { - txs = await this.cosmWasmClient.searchTx({ height: height }, filter); + txs = await this.cosmosClient.searchTx({ height: height }, filter); } else if (sentFromOrTo) { const pendingRequests = new Array>(); - pendingRequests.push(this.cosmWasmClient.searchTx({ sentFromOrTo: sentFromOrTo }, filter)); - for (const contract of this.erc20Tokens.map((token) => token.contractAddress)) { - const searchBySender = [ - { - key: "wasm.contract_address", - value: contract, - }, - { - key: "wasm.sender", - value: sentFromOrTo, - }, - ]; - const searchByRecipient = [ - { - key: "wasm.contract_address", - value: contract, - }, - { - key: "wasm.recipient", - value: sentFromOrTo, - }, - ]; - pendingRequests.push(this.cosmWasmClient.searchTx({ tags: searchBySender }, filter)); - pendingRequests.push(this.cosmWasmClient.searchTx({ tags: searchByRecipient }, filter)); - } + pendingRequests.push(this.cosmosClient.searchTx({ sentFromOrTo: sentFromOrTo }, filter)); const responses = await Promise.all(pendingRequests); const allResults = responses.reduce((accumulator, results) => accumulator.concat(results), []); txs = deduplicate(allResults, (a, b) => a.hash.localeCompare(b.hash)).sort(compareByHeightAndHash); @@ -463,13 +417,7 @@ export class CosmWasmConnection implements BlockchainConnection { private parseAndPopulateTxResponseUnsigned( response: IndexedTx, ): ConfirmedTransaction | FailedTransaction { - return parseTxsResponseUnsigned( - this.chainId, - response.height, - response, - this.bankTokens, - this.erc20Tokens, - ); + return parseTxsResponseUnsigned(this.chainId, response.height, response, this.bankTokens); } private async parseAndPopulateTxResponseSigned( @@ -481,17 +429,11 @@ export class CosmWasmConnection implements BlockchainConnection { let senderAddress: string; if (isMsgSend(firstMsg)) { senderAddress = firstMsg.value.from_address; - } else if ( - isMsgStoreCode(firstMsg) || - isMsgInstantiateContract(firstMsg) || - isMsgExecuteContract(firstMsg) - ) { - senderAddress = firstMsg.value.sender; } else { throw new Error(`Got unsupported type of message: ${firstMsg.type}`); } - const { accountNumber, sequence: currentSequence } = await this.cosmWasmClient.getNonce(senderAddress); + const { accountNumber, sequence: currentSequence } = await this.cosmosClient.getNonce(senderAddress); const sequenceForTx = await findSequenceForSignedTx( response.tx, Caip5.decode(this.chainId), @@ -502,14 +444,7 @@ export class CosmWasmConnection implements BlockchainConnection { const nonce = accountToNonce(accountNumber, sequenceForTx); - return parseTxsResponseSigned( - this.chainId, - response.height, - nonce, - response, - this.bankTokens, - this.erc20Tokens, - ); + return parseTxsResponseSigned(this.chainId, response.height, nonce, response, this.bankTokens); } private waitForTransaction( diff --git a/packages/bcp/src/cosmwasmconnector.ts b/packages/bcp/src/cosmwasmconnector.ts index f5395012..a2574a59 100644 --- a/packages/bcp/src/cosmwasmconnector.ts +++ b/packages/bcp/src/cosmwasmconnector.ts @@ -12,7 +12,7 @@ export function createCosmWasmConnector( tokenConfig: TokenConfiguration, expectedChainId?: ChainId, ): ChainConnector { - const codec = new CosmWasmCodec(addressPrefix, tokenConfig.bankTokens, tokenConfig.erc20Tokens); + const codec = new CosmWasmCodec(addressPrefix, tokenConfig.bankTokens); return { establishConnection: async () => CosmWasmConnection.establish(url, addressPrefix, tokenConfig), codec: codec, diff --git a/packages/bcp/src/decode.spec.ts b/packages/bcp/src/decode.spec.ts index c97e20ed..100282e5 100644 --- a/packages/bcp/src/decode.spec.ts +++ b/packages/bcp/src/decode.spec.ts @@ -1,9 +1,7 @@ /* eslint-disable @typescript-eslint/camelcase */ -import { MsgExecuteContract } from "@cosmwasm/cosmwasm"; -import { Coin, IndexedTx, Msg, PubKey, StdSignature, StdTx } from "@cosmwasm/sdk38"; -import { Address, Algorithm, isSendTransaction, SendTransaction, TokenTicker } from "@iov/bcp"; +import { Coin, IndexedTx, Msg, PubKey, StdSignature } from "@cosmwasm/sdk38"; +import { Address, Algorithm, SendTransaction, TokenTicker } from "@iov/bcp"; import { Encoding } from "@iov/encoding"; -import { assert } from "@iov/utils"; import { decodeAmount, @@ -19,7 +17,7 @@ import { } from "./decode"; import * as testdata from "./testdata.spec"; import cosmoshub from "./testdata/cosmoshub.json"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; const { fromBase64, fromHex } = Encoding; @@ -65,23 +63,6 @@ describe("decode", () => { denom: "uatom", }, ]; - const defaultErc20Tokens: Erc20Token[] = [ - { - contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - fractionalDigits: 5, - ticker: "HASH", - }, - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - }, - { - contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", - fractionalDigits: 18, - ticker: "JADE", - }, - ]; describe("decodePubkey", () => { it("works for secp256k1", () => { @@ -159,40 +140,7 @@ describe("decode", () => { ], }, }; - expect(parseMsg(msg, defaultMemo, testdata.chainId, defaultTokens, defaultErc20Tokens)).toEqual( - defaultSendTransaction, - ); - }); - - it("works for ERC20 send transaction", () => { - const msg: 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: "HASH" as TokenTicker, - fractionalDigits: 5, - }, - memo: defaultMemo, - }); + expect(parseMsg(msg, defaultMemo, testdata.chainId, defaultTokens)).toEqual(defaultSendTransaction); }); }); @@ -213,69 +161,17 @@ describe("decode", () => { describe("parseUnsignedTx", () => { it("works for bank send transaction", () => { - expect( - parseUnsignedTx(cosmoshub.tx.value, testdata.chainId, defaultTokens, defaultErc20Tokens), - ).toEqual(testdata.sendTxJson); - }); - - it("works for ERC20 send transaction", () => { - const msg: MsgExecuteContract = { - type: "wasm/execute", - value: { - sender: "cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r", - contract: defaultErc20Tokens[0].contractAddress, - msg: { - transfer: { - amount: "887878484", - recipient: "cosmos1z7g5w84ynmjyg0kqpahdjqpj7yq34v3suckp0e", - }, - }, - sent_funds: [], - }, - }; - const tx: StdTx = { - msg: [msg], - memo: defaultMemo, - fee: { - amount: [ - { - denom: "uatom", - amount: "5000", - }, - ], - gas: "200000", - }, - signatures: [], - }; - const unsigned = parseUnsignedTx(tx, testdata.chainId, defaultTokens, defaultErc20Tokens); - assert(isSendTransaction(unsigned)); - expect(unsigned).toEqual({ - kind: "bcp/send", - chainId: testdata.chainId, - sender: "cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r" as Address, - recipient: "cosmos1z7g5w84ynmjyg0kqpahdjqpj7yq34v3suckp0e" as Address, - amount: { - quantity: "887878484", - tokenTicker: "HASH" as TokenTicker, - fractionalDigits: 5, - }, - memo: defaultMemo, - fee: defaultFee, - }); + expect(parseUnsignedTx(cosmoshub.tx.value, testdata.chainId, defaultTokens)).toEqual( + testdata.sendTxJson, + ); }); }); describe("parseSignedTx", () => { it("works", () => { - expect( - parseSignedTx( - cosmoshub.tx.value, - testdata.chainId, - testdata.nonce, - defaultTokens, - defaultErc20Tokens, - ), - ).toEqual(testdata.signedTxJson); + expect(parseSignedTx(cosmoshub.tx.value, testdata.chainId, testdata.nonce, defaultTokens)).toEqual( + testdata.signedTxJson, + ); }); }); @@ -298,15 +194,9 @@ describe("decode", () => { transactionId: testdata.txId, log: '[{"msg_index":0,"success":true,"log":""}]', }; - expect( - parseTxsResponseUnsigned( - testdata.chainId, - currentHeight, - txsResponse, - defaultTokens, - defaultErc20Tokens, - ), - ).toEqual(expected); + expect(parseTxsResponseUnsigned(testdata.chainId, currentHeight, txsResponse, defaultTokens)).toEqual( + expected, + ); }); }); @@ -330,14 +220,7 @@ describe("decode", () => { log: '[{"msg_index":0,"success":true,"log":""}]', }; expect( - parseTxsResponseSigned( - testdata.chainId, - currentHeight, - testdata.nonce, - txsResponse, - defaultTokens, - defaultErc20Tokens, - ), + parseTxsResponseSigned(testdata.chainId, currentHeight, testdata.nonce, txsResponse, defaultTokens), ).toEqual(expected); }); }); diff --git a/packages/bcp/src/decode.ts b/packages/bcp/src/decode.ts index cab2543b..ca669a83 100644 --- a/packages/bcp/src/decode.ts +++ b/packages/bcp/src/decode.ts @@ -1,4 +1,3 @@ -import { isMsgExecuteContract } from "@cosmwasm/cosmwasm"; import { Coin, IndexedTx, @@ -31,9 +30,8 @@ import { UnsignedTransaction, } from "@iov/bcp"; import { Decimal, Encoding } from "@iov/encoding"; -import BN from "bn.js"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; const { fromBase64 } = Encoding; @@ -89,7 +87,6 @@ export function parseMsg( memo: string | undefined, chainId: ChainId, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): UnsignedTransaction { if (isMsgSend(msg)) { if (msg.value.amount.length !== 1) { @@ -104,34 +101,6 @@ export function parseMsg( memo: memo, }; return send; - } else if (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.transfer?.recipient; - if (!recipient) throw new Error("Could not read recipient"); - - const amount: string | undefined = msg.value.msg.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 = { @@ -156,7 +125,6 @@ export function parseUnsignedTx( txValue: StdTx, chainId: ChainId, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): UnsignedTransaction { if (!isStdTx(txValue)) { throw new Error("Only StdTx is supported"); @@ -165,7 +133,7 @@ export function parseUnsignedTx( throw new Error("Only single-message transactions currently supported"); } - const msg = parseMsg(txValue.msg[0], txValue.memo, chainId, tokens, erc20Tokens); + const msg = parseMsg(txValue.msg[0], txValue.memo, chainId, tokens); const fee = parseFee(txValue.fee, tokens); return { @@ -180,11 +148,10 @@ export function parseSignedTx( chainId: ChainId, nonce: Nonce, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): SignedTransaction { const [primarySignature] = txValue.signatures.map((signature) => decodeFullSignature(signature, nonce)); return { - transaction: parseUnsignedTx(txValue, chainId, tokens, erc20Tokens), + transaction: parseUnsignedTx(txValue, chainId, tokens), signatures: [primarySignature], }; } @@ -194,10 +161,9 @@ export function parseTxsResponseUnsigned( currentHeight: number, response: IndexedTx, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): ConfirmedTransaction { return { - transaction: parseUnsignedTx(response.tx.value, chainId, tokens, erc20Tokens), + transaction: parseUnsignedTx(response.tx.value, chainId, tokens), height: response.height, confirmations: currentHeight - response.height + 1, transactionId: response.hash as TransactionId, @@ -211,10 +177,9 @@ export function parseTxsResponseSigned( nonce: Nonce, response: IndexedTx, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): ConfirmedAndSignedTransaction { return { - ...parseSignedTx(response.tx.value, chainId, nonce, tokens, erc20Tokens), + ...parseSignedTx(response.tx.value, chainId, nonce, tokens), height: response.height, confirmations: currentHeight - response.height + 1, transactionId: response.hash as TransactionId, diff --git a/packages/bcp/src/encode.spec.ts b/packages/bcp/src/encode.spec.ts index 5655d59e..44862783 100644 --- a/packages/bcp/src/encode.spec.ts +++ b/packages/bcp/src/encode.spec.ts @@ -20,9 +20,8 @@ import { encodeFullSignature, encodePubkey, toBankCoin, - toErc20Amount, } from "./encode"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; const { fromBase64 } = Encoding; @@ -49,23 +48,6 @@ describe("encode", () => { denom: "uatom", }, ]; - const defaultErc20Tokens: Erc20Token[] = [ - { - contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - fractionalDigits: 5, - ticker: "HASH", - }, - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - }, - { - contractAddress: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", - fractionalDigits: 18, - ticker: "JADE", - }, - ]; describe("encodePubkey", () => { it("works for compressed public key", () => { @@ -76,37 +58,6 @@ describe("encode", () => { }); }); - describe("toErc20Amount", () => { - const [ash, bash] = defaultErc20Tokens; - - it("encodes an amount", () => { - const amount: Amount = { - quantity: "789", - fractionalDigits: 0, - tokenTicker: "ISA" as TokenTicker, - }; - expect(toErc20Amount(amount, bash)).toEqual("789"); - }); - - it("throws on ticker mismatch", () => { - const amount: Amount = { - quantity: "789", - fractionalDigits: 0, - tokenTicker: "ISA" as TokenTicker, - }; - expect(() => toErc20Amount(amount, ash)).toThrowError(/ticker mismatch/i); - }); - - it("throws on ticker mismatch", () => { - const amount: Amount = { - quantity: "789", - fractionalDigits: 2, - tokenTicker: "ISA" as TokenTicker, - }; - expect(() => toErc20Amount(amount, bash)).toThrowError(/fractional digits mismatch/i); - }); - }); - describe("toBankCoin", () => { it("encodes an amount", () => { expect(toBankCoin(defaultAmount, defaultTokens)).toEqual({ @@ -287,56 +238,6 @@ 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: 0, - quantity: "345", - tokenTicker: "ISA" 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", () => { diff --git a/packages/bcp/src/encode.ts b/packages/bcp/src/encode.ts index f8820a2a..97abb40b 100644 --- a/packages/bcp/src/encode.ts +++ b/packages/bcp/src/encode.ts @@ -22,7 +22,7 @@ import { import { Secp256k1 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; const { toBase64 } = Encoding; @@ -41,14 +41,6 @@ export function encodePubkey(pubkey: PubkeyBundle): PubKey { } } -export function toErc20Amount(amount: Amount, erc20Token: Erc20Token): string { - if (amount.tokenTicker !== erc20Token.ticker) throw new Error("Ticker mismatch between amount and token"); - if (amount.fractionalDigits !== erc20Token.fractionalDigits) { - throw new Error("Fractional digits mismatch between amount and token"); - } - return amount.quantity; -} - export function toBankCoin(amount: Amount, tokens: readonly BankToken[]): Coin { const match = tokens.find((token) => token.ticker === amount.tokenTicker); if (!match) throw Error(`unknown ticker: ${amount.tokenTicker}`); @@ -88,17 +80,12 @@ export function encodeFullSignature(fullSignature: FullSignature): StdSignature } } -export function buildUnsignedTx( - tx: UnsignedTransaction, - bankTokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[] = [], -): CosmosSdkTx { +export function buildUnsignedTx(tx: UnsignedTransaction, bankTokens: readonly BankToken[]): CosmosSdkTx { if (!isSendTransaction(tx)) { throw new Error("Received transaction of unsupported kind"); } const matchingBankToken = bankTokens.find((t) => t.ticker === tx.amount.tokenTicker); - const matchingErc20Token = erc20Tokens.find((t) => t.ticker === tx.amount.tokenTicker); if (!tx.fee) throw new Error("Transaction fee must be set"); @@ -121,42 +108,13 @@ export function buildUnsignedTx( fee: encodeFee(tx.fee, bankTokens), }, }; - } else if (matchingErc20Token) { - return { - type: "cosmos-sdk/StdTx", - value: { - msg: [ - { - type: "wasm/execute", - value: { - sender: tx.sender, - contract: matchingErc20Token.contractAddress, - msg: { - transfer: { - amount: toErc20Amount(tx.amount, matchingErc20Token), - recipient: tx.recipient, - }, - }, - sent_funds: [], - }, - }, - ], - memo: tx.memo || "", - signatures: [], - fee: encodeFee(tx.fee, bankTokens), - }, - }; } else { throw new Error("Cannot encode this type of transaction"); } } -export function buildSignedTx( - tx: SignedTransaction, - bankTokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[] = [], -): CosmosSdkTx { - const built = buildUnsignedTx(tx.transaction, bankTokens, erc20Tokens); +export function buildSignedTx(tx: SignedTransaction, bankTokens: readonly BankToken[]): CosmosSdkTx { + const built = buildUnsignedTx(tx.transaction, bankTokens); return { ...built, value: { diff --git a/packages/bcp/src/index.ts b/packages/bcp/src/index.ts index a43dbe22..3f5c70cf 100644 --- a/packages/bcp/src/index.ts +++ b/packages/bcp/src/index.ts @@ -1,4 +1,4 @@ export { CosmWasmCodec } from "./cosmwasmcodec"; export { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection"; export { createCosmWasmConnector } from "./cosmwasmconnector"; -export { BankToken, Erc20Token } from "./types"; +export { BankToken } from "./types"; diff --git a/packages/bcp/src/types.ts b/packages/bcp/src/types.ts index 6a7c9c26..9ceb2f1c 100644 --- a/packages/bcp/src/types.ts +++ b/packages/bcp/src/types.ts @@ -15,21 +15,6 @@ export interface BankToken { readonly fractionalDigits: number; } -export interface Erc20Token { - readonly contractAddress: string; - readonly ticker: string; - /** - * The number of fractional digits the token supports. - * - * A quantity is expressed as atomic units. 10^fractionalDigits of those - * atomic units make up 1 token. - * - * E.g. in Ethereum 10^18 wei are 1 ETH and from the quantity 123000000000000000000 - * the last 18 digits are the fractional part and the rest the wole part. - */ - readonly fractionalDigits: number; -} - // eslint-disable-next-line no-bitwise const maxAcct = 1 << 23; // eslint-disable-next-line no-bitwise diff --git a/packages/bcp/types/cosmwasmcodec.d.ts b/packages/bcp/types/cosmwasmcodec.d.ts index e523ddbe..9f913c41 100644 --- a/packages/bcp/types/cosmwasmcodec.d.ts +++ b/packages/bcp/types/cosmwasmcodec.d.ts @@ -10,12 +10,11 @@ import { TxCodec, UnsignedTransaction, } from "@iov/bcp"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; export declare class CosmWasmCodec implements TxCodec { private readonly addressPrefix; private readonly bankTokens; - private readonly erc20Tokens; - constructor(addressPrefix: string, bankTokens: readonly BankToken[], erc20Tokens?: readonly Erc20Token[]); + constructor(addressPrefix: string, bankTokens: readonly BankToken[]); bytesToSign(unsigned: UnsignedTransaction, nonce: Nonce): SigningJob; bytesToPost(signed: SignedTransaction): PostableBytes; identifier(_signed: SignedTransaction): TransactionId; diff --git a/packages/bcp/types/cosmwasmconnection.d.ts b/packages/bcp/types/cosmwasmconnection.d.ts index b4059376..c5aa97f0 100644 --- a/packages/bcp/types/cosmwasmconnection.d.ts +++ b/packages/bcp/types/cosmwasmconnection.d.ts @@ -22,7 +22,7 @@ import { UnsignedTransaction, } from "@iov/bcp"; import { Stream } from "xstream"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; export interface TokenConfiguration { /** Supported tokens of the Cosmos SDK bank module */ readonly bankTokens: ReadonlyArray< @@ -30,12 +30,6 @@ export interface TokenConfiguration { readonly name: string; } >; - /** Smart contract based tokens (ERC20 compatible). Unset means empty array. */ - readonly erc20Tokens?: ReadonlyArray< - Erc20Token & { - readonly name: string; - } - >; } export declare class CosmWasmConnection implements BlockchainConnection { static establish( @@ -46,10 +40,9 @@ export declare class CosmWasmConnection implements BlockchainConnection { private static initialize; readonly chainId: ChainId; readonly codec: TxCodec; - private readonly cosmWasmClient; + private readonly cosmosClient; private readonly addressPrefix; private readonly bankTokens; - private readonly erc20Tokens; private readonly feeToken; private readonly supportedTokens; private constructor(); diff --git a/packages/bcp/types/decode.d.ts b/packages/bcp/types/decode.d.ts index 495a92f9..d1df6609 100644 --- a/packages/bcp/types/decode.d.ts +++ b/packages/bcp/types/decode.d.ts @@ -13,7 +13,7 @@ import { UnsignedTransaction, } from "@iov/bcp"; import { Decimal } from "@iov/encoding"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; export declare function decodePubkey(pubkey: PubKey): PubkeyBundle; export declare function decodeSignature(signature: string): SignatureBytes; export declare function decodeFullSignature(signature: StdSignature, nonce: number): FullSignature; @@ -24,28 +24,24 @@ export declare function parseMsg( memo: string | undefined, chainId: ChainId, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): UnsignedTransaction; export declare function parseFee(fee: StdFee, tokens: readonly BankToken[]): Fee; export declare function parseUnsignedTx( txValue: StdTx, chainId: ChainId, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): UnsignedTransaction; export declare function parseSignedTx( txValue: StdTx, chainId: ChainId, nonce: Nonce, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): SignedTransaction; export declare function parseTxsResponseUnsigned( chainId: ChainId, currentHeight: number, response: IndexedTx, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): ConfirmedTransaction; export declare function parseTxsResponseSigned( chainId: ChainId, @@ -53,5 +49,4 @@ export declare function parseTxsResponseSigned( nonce: Nonce, response: IndexedTx, tokens: readonly BankToken[], - erc20Tokens: readonly Erc20Token[], ): ConfirmedAndSignedTransaction; diff --git a/packages/bcp/types/encode.d.ts b/packages/bcp/types/encode.d.ts index af4033d4..50fa8da4 100644 --- a/packages/bcp/types/encode.d.ts +++ b/packages/bcp/types/encode.d.ts @@ -1,18 +1,12 @@ import { Coin, CosmosSdkTx, PubKey, StdFee, StdSignature } from "@cosmwasm/sdk38"; import { Amount, Fee, FullSignature, PubkeyBundle, SignedTransaction, UnsignedTransaction } from "@iov/bcp"; -import { BankToken, Erc20Token } from "./types"; +import { BankToken } from "./types"; export declare function encodePubkey(pubkey: PubkeyBundle): PubKey; -export declare function toErc20Amount(amount: Amount, erc20Token: Erc20Token): string; export declare function toBankCoin(amount: Amount, tokens: readonly BankToken[]): Coin; export declare function encodeFee(fee: Fee, tokens: readonly BankToken[]): StdFee; export declare function encodeFullSignature(fullSignature: FullSignature): StdSignature; export declare function buildUnsignedTx( tx: UnsignedTransaction, bankTokens: readonly BankToken[], - erc20Tokens?: readonly Erc20Token[], -): CosmosSdkTx; -export declare function buildSignedTx( - tx: SignedTransaction, - bankTokens: readonly BankToken[], - erc20Tokens?: readonly Erc20Token[], ): CosmosSdkTx; +export declare function buildSignedTx(tx: SignedTransaction, bankTokens: readonly BankToken[]): CosmosSdkTx; diff --git a/packages/bcp/types/index.d.ts b/packages/bcp/types/index.d.ts index a43dbe22..3f5c70cf 100644 --- a/packages/bcp/types/index.d.ts +++ b/packages/bcp/types/index.d.ts @@ -1,4 +1,4 @@ export { CosmWasmCodec } from "./cosmwasmcodec"; export { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection"; export { createCosmWasmConnector } from "./cosmwasmconnector"; -export { BankToken, Erc20Token } from "./types"; +export { BankToken } from "./types"; diff --git a/packages/bcp/types/types.d.ts b/packages/bcp/types/types.d.ts index cf441e8d..15d96e7d 100644 --- a/packages/bcp/types/types.d.ts +++ b/packages/bcp/types/types.d.ts @@ -13,20 +13,6 @@ export interface BankToken { */ readonly fractionalDigits: number; } -export interface Erc20Token { - readonly contractAddress: string; - readonly ticker: string; - /** - * The number of fractional digits the token supports. - * - * A quantity is expressed as atomic units. 10^fractionalDigits of those - * atomic units make up 1 token. - * - * E.g. in Ethereum 10^18 wei are 1 ETH and from the quantity 123000000000000000000 - * the last 18 digits are the fractional part and the rest the wole part. - */ - readonly fractionalDigits: number; -} export declare function accountToNonce(accountNumber: number, sequence: number): Nonce; export declare function nonceToAccountNumber(nonce: Nonce): number; export declare function nonceToSequence(nonce: Nonce): number; diff --git a/packages/faucet/src/constants.ts b/packages/faucet/src/constants.ts index 510c5b98..2ebfaac5 100644 --- a/packages/faucet/src/constants.ts +++ b/packages/faucet/src/constants.ts @@ -23,12 +23,4 @@ export const developmentTokenConfig: TokenConfiguration = { denom: "ustake", }, ], - erc20Tokens: [ - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - name: "Isa Token", - }, - ], }; diff --git a/packages/faucet/src/faucet.spec.ts b/packages/faucet/src/faucet.spec.ts index 6dbab18c..6bf0d4c6 100644 --- a/packages/faucet/src/faucet.spec.ts +++ b/packages/faucet/src/faucet.spec.ts @@ -30,18 +30,10 @@ const defaultConfig: TokenConfiguration = { denom: "ustake", }, ], - erc20Tokens: [ - { - contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - fractionalDigits: 0, - ticker: "ISA", - name: "Isa Token", - }, - ], }; const defaultAddressPrefix = "cosmos"; const defaultChainId = "cosmos:testing" as ChainId; -const codec = new CosmWasmCodec(defaultAddressPrefix, defaultConfig.bankTokens, defaultConfig.erc20Tokens); +const codec = new CosmWasmCodec(defaultAddressPrefix, defaultConfig.bankTokens); function makeRandomAddress(): Address { return Bech32.encode(defaultAddressPrefix, Random.getBytes(20)) as Address; @@ -100,33 +92,6 @@ describe("Faucet", () => { ]); connection.disconnect(); }); - - it("can send ERC20 token", async () => { - pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); - const { profile, holder } = await makeProfile(); - const faucet = new Faucet(defaultConfig, connection, codec, profile); - const recipient = makeRandomAddress(); - await faucet.send({ - amount: { - quantity: "7", - fractionalDigits: 0, - tokenTicker: "ISA" as TokenTicker, - }, - sender: holder, - recipient: recipient, - }); - const account = await connection.getAccount({ address: recipient }); - assert(account); - expect(account.balance).toEqual([ - { - quantity: "7", - fractionalDigits: 0, - tokenTicker: "ISA" as TokenTicker, - }, - ]); - connection.disconnect(); - }); }); describe("refill", () => { @@ -143,18 +108,13 @@ describe("Faucet", () => { tokenTicker: "COSM", fractionalDigits: 6, }), - jasmine.objectContaining({ - tokenTicker: "ISA", - fractionalDigits: 0, - }), jasmine.objectContaining({ tokenTicker: "STAKE", fractionalDigits: 6, }), ]); expect(Number.parseInt(distributorBalance[0].quantity, 10)).toBeGreaterThanOrEqual(80_000000); - expect(Number.parseInt(distributorBalance[1].quantity, 10)).toBeGreaterThanOrEqual(80); - expect(Number.parseInt(distributorBalance[2].quantity, 10)).toBeGreaterThanOrEqual(80_000000); + expect(Number.parseInt(distributorBalance[1].quantity, 10)).toBeGreaterThanOrEqual(80_000000); connection.disconnect(); }); }); @@ -206,7 +166,7 @@ describe("Faucet", () => { const { profile } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); const tickers = await faucet.loadTokenTickers(); - expect(tickers).toEqual(["COSM", "ISA", "STAKE"]); + expect(tickers).toEqual(["COSM", "STAKE"]); connection.disconnect(); }); }); diff --git a/packages/faucet/src/tokenmanager.ts b/packages/faucet/src/tokenmanager.ts index d2be65da..c43d3502 100644 --- a/packages/faucet/src/tokenmanager.ts +++ b/packages/faucet/src/tokenmanager.ts @@ -58,9 +58,7 @@ export class TokenManager { } private getFractionalDigits(ticker: TokenTicker): number { - const match = [...this.config.bankTokens, ...(this.config.erc20Tokens || [])].find( - (token) => token.ticker === ticker, - ); + const match = this.config.bankTokens.find((token) => token.ticker === ticker); if (!match) throw new Error(`No token found for ticker symbol: ${ticker}`); return match.fractionalDigits; }