From ef999070e8115f5a59bf2f5df9a0d1cd94eb2c21 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 19 Feb 2020 10:02:08 +0100 Subject: [PATCH] Remove CosmosAddressBech32Prefix/isValidAddress --- packages/bcp/src/address.ts | 4 +- packages/bcp/src/cosmwasmcodec.spec.ts | 7 ++- packages/bcp/src/cosmwasmcodec.ts | 27 +++++------ packages/bcp/src/cosmwasmconnection.spec.ts | 54 ++++++++++----------- packages/bcp/src/cosmwasmconnection.ts | 14 ++---- packages/bcp/src/cosmwasmconnector.ts | 3 +- packages/bcp/types/address.d.ts | 3 +- packages/bcp/types/cosmwasmcodec.d.ts | 7 +-- packages/bcp/types/cosmwasmconnection.d.ts | 3 +- packages/bcp/types/cosmwasmconnector.d.ts | 3 +- packages/faucet/src/faucet.spec.ts | 23 +++++---- packages/sdk/src/address.spec.ts | 19 +------- packages/sdk/src/address.ts | 19 -------- packages/sdk/src/index.ts | 2 +- packages/sdk/types/address.d.ts | 2 - packages/sdk/types/index.d.ts | 2 +- 16 files changed, 66 insertions(+), 126 deletions(-) diff --git a/packages/bcp/src/address.ts b/packages/bcp/src/address.ts index 82046fdf..10a718bf 100644 --- a/packages/bcp/src/address.ts +++ b/packages/bcp/src/address.ts @@ -1,4 +1,4 @@ -import { CosmosAddressBech32Prefix, decodeBech32Pubkey, encodeAddress, types } from "@cosmwasm/sdk"; +import { decodeBech32Pubkey, encodeAddress, types } from "@cosmwasm/sdk"; import { Address, Algorithm, PubkeyBundle, PubkeyBytes } from "@iov/bcp"; import { Secp256k1 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; @@ -18,7 +18,7 @@ export function decodeCosmosPubkey(encodedPubkey: string): PubkeyBundle { } // See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography -export function pubkeyToAddress(pubkey: PubkeyBundle, prefix: CosmosAddressBech32Prefix): Address { +export function pubkeyToAddress(pubkey: PubkeyBundle, prefix: string): Address { let sdkKey: types.PubKey; if (pubkey.algo === Algorithm.Secp256k1) { sdkKey = { diff --git a/packages/bcp/src/cosmwasmcodec.spec.ts b/packages/bcp/src/cosmwasmcodec.spec.ts index d44dffe6..c40b17c2 100644 --- a/packages/bcp/src/cosmwasmcodec.spec.ts +++ b/packages/bcp/src/cosmwasmcodec.spec.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { Address, PostableBytes, PrehashType, SendTransaction, TokenTicker } from "@iov/bcp"; import { Encoding } from "@iov/encoding"; @@ -8,7 +7,7 @@ import { BankToken, Erc20Token } from "./types"; const { toUtf8 } = Encoding; -const defaultPrefix = "cosmos" as CosmosAddressBech32Prefix; +const defaultPrefix = "cosmos"; const defaultBankTokens: readonly BankToken[] = [ { @@ -42,8 +41,6 @@ describe("CosmWasmCodec", () => { describe("isValidAddress", () => { it("accepts valid addresses", () => { expect(codec.isValidAddress("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6")).toEqual(true); - expect(codec.isValidAddress("cosmosvalcons10q82zkzzmaku5lazhsvxv7hsg4ntpuhdwadmss")).toEqual(true); - expect(codec.isValidAddress("cosmosvaloper17mggn4znyeyg25wd7498qxl7r2jhgue8u4qjcq")).toEqual(true); }); it("rejects invalid addresses", () => { @@ -53,6 +50,8 @@ describe("CosmWasmCodec", () => { expect(codec.isValidAddress("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs7")).toEqual(false); // Bad prefix expect(codec.isValidAddress("cosmot10q82zkzzmaku5lazhsvxv7hsg4ntpuhd8j5266")).toEqual(false); + expect(codec.isValidAddress("cosmosvalcons10q82zkzzmaku5lazhsvxv7hsg4ntpuhdwadmss")).toEqual(false); + expect(codec.isValidAddress("cosmosvaloper17mggn4znyeyg25wd7498qxl7r2jhgue8u4qjcq")).toEqual(false); }); }); diff --git a/packages/bcp/src/cosmwasmcodec.ts b/packages/bcp/src/cosmwasmcodec.ts index 584ea5e7..865dfe3e 100644 --- a/packages/bcp/src/cosmwasmcodec.ts +++ b/packages/bcp/src/cosmwasmcodec.ts @@ -1,11 +1,5 @@ /* eslint-disable @typescript-eslint/camelcase */ -import { - CosmosAddressBech32Prefix, - isValidAddress, - makeSignBytes, - marshalTx, - unmarshalTx, -} from "@cosmwasm/sdk"; +import { makeSignBytes, marshalTx, unmarshalTx } from "@cosmwasm/sdk"; import { Address, ChainId, @@ -20,6 +14,7 @@ import { TxCodec, UnsignedTransaction, } from "@iov/bcp"; +import { Bech32 } from "@iov/encoding"; import { pubkeyToAddress } from "./address"; import { Caip5 } from "./caip5"; @@ -28,15 +23,11 @@ import { buildSignedTx, buildUnsignedTx } from "./encode"; import { BankTokens, Erc20Token, nonceToAccountNumber, nonceToSequence } from "./types"; export class CosmWasmCodec implements TxCodec { - private readonly addressPrefix: CosmosAddressBech32Prefix; + private readonly addressPrefix: string; private readonly bankTokens: BankTokens; private readonly erc20Tokens: readonly Erc20Token[]; - public constructor( - addressPrefix: CosmosAddressBech32Prefix, - bankTokens: BankTokens, - erc20Tokens: readonly Erc20Token[] = [], - ) { + public constructor(addressPrefix: string, bankTokens: BankTokens, erc20Tokens: readonly Erc20Token[] = []) { this.addressPrefix = addressPrefix; this.bankTokens = bankTokens; this.erc20Tokens = erc20Tokens; @@ -89,6 +80,14 @@ export class CosmWasmCodec implements TxCodec { } public isValidAddress(address: string): boolean { - return isValidAddress(address); + try { + const { prefix, data } = Bech32.decode(address); + if (prefix !== this.addressPrefix) { + return false; + } + return data.length === 20; + } catch { + return false; + } } } diff --git a/packages/bcp/src/cosmwasmconnection.spec.ts b/packages/bcp/src/cosmwasmconnection.spec.ts index ff7e9d7f..70b8bdb0 100644 --- a/packages/bcp/src/cosmwasmconnection.spec.ts +++ b/packages/bcp/src/cosmwasmconnection.spec.ts @@ -1,8 +1,4 @@ -import { - CosmosAddressBech32Prefix, - decodeSignature, - makeSecp256k1SignatureFromFixedLength, -} from "@cosmwasm/sdk"; +import { decodeSignature, makeSecp256k1SignatureFromFixedLength } from "@cosmwasm/sdk"; import { Account, Address, @@ -39,10 +35,10 @@ function pendingWithoutWasmd(): void { } } -const defaultPrefix = "cosmos" as CosmosAddressBech32Prefix; +const defaultAddressPrefix = "cosmos"; function makeRandomAddress(): Address { - return Bech32.encode(defaultPrefix, Random.getBytes(20)) as Address; + return Bech32.encode(defaultAddressPrefix, Random.getBytes(20)) as Address; } const faucet = { @@ -129,7 +125,7 @@ describe("CosmWasmConnection", () => { describe("establish", () => { it("can connect to Cosmos via http", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); expect(connection).toBeTruthy(); connection.disconnect(); }); @@ -138,7 +134,7 @@ describe("CosmWasmConnection", () => { describe("chainId", () => { it("displays the chain ID", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); expect(connection.chainId).toEqual(defaultChainId); connection.disconnect(); }); @@ -147,7 +143,7 @@ describe("CosmWasmConnection", () => { describe("height", () => { it("displays the current height", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const height = await connection.height(); expect(height).toBeGreaterThan(0); connection.disconnect(); @@ -157,7 +153,7 @@ describe("CosmWasmConnection", () => { describe("getToken", () => { it("displays a given token", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const token = await connection.getToken("COSM" as TokenTicker); expect(token).toEqual({ fractionalDigits: 6, @@ -169,7 +165,7 @@ describe("CosmWasmConnection", () => { it("resolves to undefined if the token is not supported", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const token = await connection.getToken("whatever" as TokenTicker); expect(token).toBeUndefined(); connection.disconnect(); @@ -179,7 +175,7 @@ describe("CosmWasmConnection", () => { describe("getAllTokens", () => { it("resolves to a list of all supported tokens", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const tokens = await connection.getAllTokens(); expect(tokens).toEqual([ { @@ -215,7 +211,7 @@ describe("CosmWasmConnection", () => { describe("identifier", () => { it("calculates tx hash from PostableBytes", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, atomConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, atomConfig); const id = await connection.identifier(testdata.signedTxJson); expect(id).toMatch(/^[0-9A-F]{64}$/); expect(id).toEqual(testdata.txId); @@ -225,7 +221,7 @@ describe("CosmWasmConnection", () => { describe("getAccount", () => { it("gets an empty account by address", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const account = await connection.getAccount({ address: defaultEmptyAddress }); expect(account).toBeUndefined(); connection.disconnect(); @@ -233,7 +229,7 @@ describe("CosmWasmConnection", () => { it("gets an account by address", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const account = await connection.getAccount({ address: unusedAccount.address }); assert(account, "Account must be defined"); expect(account.address).toEqual(unusedAccount.address); @@ -265,7 +261,7 @@ describe("CosmWasmConnection", () => { it("gets an account by pubkey", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const byAddress = await connection.getAccount({ address: unusedAccount.address }); const byPubkey = await connection.getAccount({ pubkey: unusedAccount.pubkey }); expect(byPubkey).toEqual(byAddress); // above we verified that by address works as expected @@ -274,7 +270,7 @@ describe("CosmWasmConnection", () => { it("has a pubkey when getting account with transactions", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const account = await connection.getAccount({ address: faucet.address }); expect(account?.pubkey).toEqual(faucet.pubkey); connection.disconnect(); @@ -288,7 +284,7 @@ describe("CosmWasmConnection", () => { const events = new Array(); (async () => { - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const subscription = connection.watchAccount({ address: recipient }).subscribe({ next: event => { events.push(event); @@ -348,7 +344,7 @@ describe("CosmWasmConnection", () => { describe("getTx", () => { it("can get a recently posted bank send transaction", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); const senderIdentity = await profile.createIdentity(wallet.id, defaultChainId, faucet.path); @@ -399,7 +395,7 @@ describe("CosmWasmConnection", () => { it("can get a recently posted ERC20 send transaction", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); const senderIdentity = await profile.createIdentity(wallet.id, defaultChainId, faucet.path); @@ -449,7 +445,7 @@ describe("CosmWasmConnection", () => { it("can get an old transaction", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const results = await connection.searchTx({ sentFromOrTo: faucet.address }); const firstSearchResult = results.find(() => true); @@ -490,7 +486,7 @@ describe("CosmWasmConnection", () => { it("throws for non-existent transaction", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const nonExistentId = "0000000000000000000000000000000000000000000000000000000000000000" as TransactionId; await connection.getTx(nonExistentId).then( @@ -505,7 +501,7 @@ describe("CosmWasmConnection", () => { describe("searchTx", () => { it("can post and search for a transaction", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); const sender = await profile.createIdentity(wallet.id, defaultChainId, faucet.path); @@ -595,7 +591,7 @@ describe("CosmWasmConnection", () => { it("can search by minHeight and maxHeight", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); const sender = await profile.createIdentity(wallet.id, defaultChainId, faucet.path); @@ -806,7 +802,7 @@ describe("CosmWasmConnection", () => { pendingWithoutWasmd(); (async () => { - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); @@ -889,7 +885,7 @@ describe("CosmWasmConnection", () => { pendingWithoutWasmd(); (async () => { - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); @@ -939,7 +935,7 @@ describe("CosmWasmConnection", () => { pendingWithoutWasmd(); (async () => { - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); @@ -988,7 +984,7 @@ describe("CosmWasmConnection", () => { describe("integration tests", () => { it("can send ERC20 tokens", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const profile = new UserProfile(); const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic)); const sender = await profile.createIdentity(wallet.id, defaultChainId, faucet.path); diff --git a/packages/bcp/src/cosmwasmconnection.ts b/packages/bcp/src/cosmwasmconnection.ts index c0b57339..1a4ca439 100644 --- a/packages/bcp/src/cosmwasmconnection.ts +++ b/packages/bcp/src/cosmwasmconnection.ts @@ -1,11 +1,5 @@ /* eslint-disable @typescript-eslint/camelcase */ -import { - CosmosAddressBech32Prefix, - CosmWasmClient, - findSequenceForSignedTx, - TxsResponse, - types, -} from "@cosmwasm/sdk"; +import { CosmWasmClient, findSequenceForSignedTx, TxsResponse, types } from "@cosmwasm/sdk"; import { Account, AccountQuery, @@ -73,7 +67,7 @@ export class CosmWasmConnection implements BlockchainConnection { // we must know prefix and tokens a priori to understand the chain public static async establish( url: string, - addressPrefix: CosmosAddressBech32Prefix, + addressPrefix: string, tokens: TokenConfiguration, ): Promise { const cosmWasmClient = new CosmWasmClient(url); @@ -90,7 +84,7 @@ export class CosmWasmConnection implements BlockchainConnection { public readonly codec: TxCodec; private readonly cosmWasmClient: CosmWasmClient; - private readonly addressPrefix: CosmosAddressBech32Prefix; + private readonly addressPrefix: string; private readonly bankTokens: readonly BankToken[]; private readonly erc20Tokens: readonly Erc20Token[]; @@ -101,7 +95,7 @@ export class CosmWasmConnection implements BlockchainConnection { private constructor( cosmWasmClient: CosmWasmClient, chainId: ChainId, - addressPrefix: CosmosAddressBech32Prefix, + addressPrefix: string, tokens: TokenConfiguration, ) { this.cosmWasmClient = cosmWasmClient; diff --git a/packages/bcp/src/cosmwasmconnector.ts b/packages/bcp/src/cosmwasmconnector.ts index 648568e9..f5395012 100644 --- a/packages/bcp/src/cosmwasmconnector.ts +++ b/packages/bcp/src/cosmwasmconnector.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { ChainConnector, ChainId } from "@iov/bcp"; import { CosmWasmCodec } from "./cosmwasmcodec"; @@ -9,7 +8,7 @@ import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection"; */ export function createCosmWasmConnector( url: string, - addressPrefix: CosmosAddressBech32Prefix, + addressPrefix: string, tokenConfig: TokenConfiguration, expectedChainId?: ChainId, ): ChainConnector { diff --git a/packages/bcp/types/address.d.ts b/packages/bcp/types/address.d.ts index 10e6c57a..aa49f713 100644 --- a/packages/bcp/types/address.d.ts +++ b/packages/bcp/types/address.d.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { Address, PubkeyBundle } from "@iov/bcp"; export declare function decodeCosmosPubkey(encodedPubkey: string): PubkeyBundle; -export declare function pubkeyToAddress(pubkey: PubkeyBundle, prefix: CosmosAddressBech32Prefix): Address; +export declare function pubkeyToAddress(pubkey: PubkeyBundle, prefix: string): Address; diff --git a/packages/bcp/types/cosmwasmcodec.d.ts b/packages/bcp/types/cosmwasmcodec.d.ts index c7f01fb1..59bc6e23 100644 --- a/packages/bcp/types/cosmwasmcodec.d.ts +++ b/packages/bcp/types/cosmwasmcodec.d.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { Address, ChainId, @@ -16,11 +15,7 @@ export declare class CosmWasmCodec implements TxCodec { private readonly addressPrefix; private readonly bankTokens; private readonly erc20Tokens; - constructor( - addressPrefix: CosmosAddressBech32Prefix, - bankTokens: BankTokens, - erc20Tokens?: readonly Erc20Token[], - ); + constructor(addressPrefix: string, bankTokens: BankTokens, erc20Tokens?: readonly Erc20Token[]); 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 2cf15164..b1161cf6 100644 --- a/packages/bcp/types/cosmwasmconnection.d.ts +++ b/packages/bcp/types/cosmwasmconnection.d.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { Account, AccountQuery, @@ -41,7 +40,7 @@ export interface TokenConfiguration { export declare class CosmWasmConnection implements BlockchainConnection { static establish( url: string, - addressPrefix: CosmosAddressBech32Prefix, + addressPrefix: string, tokens: TokenConfiguration, ): Promise; private static initialize; diff --git a/packages/bcp/types/cosmwasmconnector.d.ts b/packages/bcp/types/cosmwasmconnector.d.ts index 61ed984f..28e91d5d 100644 --- a/packages/bcp/types/cosmwasmconnector.d.ts +++ b/packages/bcp/types/cosmwasmconnector.d.ts @@ -1,4 +1,3 @@ -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { ChainConnector, ChainId } from "@iov/bcp"; import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection"; /** @@ -6,7 +5,7 @@ import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection"; */ export declare function createCosmWasmConnector( url: string, - addressPrefix: CosmosAddressBech32Prefix, + addressPrefix: string, tokenConfig: TokenConfiguration, expectedChainId?: ChainId, ): ChainConnector; diff --git a/packages/faucet/src/faucet.spec.ts b/packages/faucet/src/faucet.spec.ts index df83a906..6dbab18c 100644 --- a/packages/faucet/src/faucet.spec.ts +++ b/packages/faucet/src/faucet.spec.ts @@ -1,5 +1,4 @@ import { CosmWasmCodec, CosmWasmConnection, TokenConfiguration } from "@cosmwasm/bcp"; -import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk"; import { Address, ChainId, Identity, TokenTicker } from "@iov/bcp"; import { Random } from "@iov/crypto"; import { Bech32 } from "@iov/encoding"; @@ -40,12 +39,12 @@ const defaultConfig: TokenConfiguration = { }, ], }; -const defaultPrefix = "cosmos" as CosmosAddressBech32Prefix; +const defaultAddressPrefix = "cosmos"; const defaultChainId = "cosmos:testing" as ChainId; -const codec = new CosmWasmCodec(defaultPrefix, defaultConfig.bankTokens, defaultConfig.erc20Tokens); +const codec = new CosmWasmCodec(defaultAddressPrefix, defaultConfig.bankTokens, defaultConfig.erc20Tokens); function makeRandomAddress(): Address { - return Bech32.encode(defaultPrefix, Random.getBytes(20)) as Address; + return Bech32.encode(defaultAddressPrefix, Random.getBytes(20)) as Address; } const faucetMnemonic = @@ -66,7 +65,7 @@ describe("Faucet", () => { describe("constructor", () => { it("can be constructed", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); expect(faucet).toBeTruthy(); @@ -77,7 +76,7 @@ describe("Faucet", () => { describe("send", () => { it("can send bank token", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile, holder } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); const recipient = makeRandomAddress(); @@ -104,7 +103,7 @@ describe("Faucet", () => { it("can send ERC20 token", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile, holder } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); const recipient = makeRandomAddress(); @@ -133,7 +132,7 @@ describe("Faucet", () => { describe("refill", () => { it("works", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile, distributors } = await makeProfile(1); const faucet = new Faucet(defaultConfig, connection, codec, profile); await faucet.refill(); @@ -163,7 +162,7 @@ describe("Faucet", () => { describe("credit", () => { it("works for fee token", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile } = await makeProfile(1); const faucet = new Faucet(defaultConfig, connection, codec, profile); const recipient = makeRandomAddress(); @@ -182,7 +181,7 @@ describe("Faucet", () => { it("works for stake token", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile } = await makeProfile(1); const faucet = new Faucet(defaultConfig, connection, codec, profile); const recipient = makeRandomAddress(); @@ -203,7 +202,7 @@ describe("Faucet", () => { describe("loadTokenTickers", () => { it("works", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); const tickers = await faucet.loadTokenTickers(); @@ -215,7 +214,7 @@ describe("Faucet", () => { describe("loadAccounts", () => { it("works", async () => { pendingWithoutWasmd(); - const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig); + const connection = await CosmWasmConnection.establish(httpUrl, defaultAddressPrefix, defaultConfig); const { profile, holder } = await makeProfile(); const faucet = new Faucet(defaultConfig, connection, codec, profile); const accounts = await faucet.loadAccounts(); diff --git a/packages/sdk/src/address.spec.ts b/packages/sdk/src/address.spec.ts index 80df0b7a..875ec9bd 100644 --- a/packages/sdk/src/address.spec.ts +++ b/packages/sdk/src/address.spec.ts @@ -1,27 +1,10 @@ import { Encoding } from "@iov/encoding"; -import { encodeAddress, isValidAddress } from "./address"; +import { encodeAddress } from "./address"; const { toBase64, fromHex } = Encoding; describe("address", () => { - describe("isValidAddress", () => { - it("accepts valid addresses", () => { - expect(isValidAddress("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6")).toEqual(true); - expect(isValidAddress("cosmosvalcons10q82zkzzmaku5lazhsvxv7hsg4ntpuhdwadmss")).toEqual(true); - expect(isValidAddress("cosmosvaloper17mggn4znyeyg25wd7498qxl7r2jhgue8u4qjcq")).toEqual(true); - }); - - it("rejects invalid addresses", () => { - // Bad size - expect(isValidAddress("cosmos10q82zkzzmaku5lazhsvxv7hsg4ntpuhh8289f")).toEqual(false); - // Bad checksum - expect(isValidAddress("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs7")).toEqual(false); - // Bad prefix - expect(isValidAddress("cosmot10q82zkzzmaku5lazhsvxv7hsg4ntpuhd8j5266")).toEqual(false); - }); - }); - describe("encodeAddress", () => { it("works for Secp256k1 compressed", () => { const prefix = "cosmos"; diff --git a/packages/sdk/src/address.ts b/packages/sdk/src/address.ts index c5d5fa1a..2aa2e0cf 100644 --- a/packages/sdk/src/address.ts +++ b/packages/sdk/src/address.ts @@ -5,25 +5,6 @@ import { PubKey, pubkeyType } from "./types"; const { fromBase64 } = Encoding; -// TODO: make this much more configurable -export type CosmosAddressBech32Prefix = "cosmos" | "cosmosvalcons" | "cosmosvaloper"; - -function isCosmosAddressBech32Prefix(prefix: string): prefix is CosmosAddressBech32Prefix { - return ["cosmos", "cosmosvalcons", "cosmosvaloper"].includes(prefix); -} - -export function isValidAddress(address: string): boolean { - try { - const { prefix, data } = Bech32.decode(address); - if (!isCosmosAddressBech32Prefix(prefix)) { - return false; - } - return data.length === 20; - } catch { - return false; - } -} - // See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography // This assumes we already have a cosmos-compressed pubkey export function encodeAddress(pubkey: PubKey, prefix: string): string { diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index ca7ceb27..22a96fa5 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -2,7 +2,7 @@ import * as logs from "./logs"; import * as types from "./types"; export { logs, types }; -export { CosmosAddressBech32Prefix, encodeAddress, isValidAddress } from "./address"; +export { encodeAddress } from "./address"; export { unmarshalTx } from "./decoding"; export { makeSignBytes, marshalTx } from "./encoding"; export { BroadcastMode, RestClient, TxsResponse } from "./restclient"; diff --git a/packages/sdk/types/address.d.ts b/packages/sdk/types/address.d.ts index 50e7e04e..ab4e3184 100644 --- a/packages/sdk/types/address.d.ts +++ b/packages/sdk/types/address.d.ts @@ -1,4 +1,2 @@ import { PubKey } from "./types"; -export declare type CosmosAddressBech32Prefix = "cosmos" | "cosmosvalcons" | "cosmosvaloper"; -export declare function isValidAddress(address: string): boolean; export declare function encodeAddress(pubkey: PubKey, prefix: string): string; diff --git a/packages/sdk/types/index.d.ts b/packages/sdk/types/index.d.ts index dd2ad348..a2907b3d 100644 --- a/packages/sdk/types/index.d.ts +++ b/packages/sdk/types/index.d.ts @@ -1,7 +1,7 @@ import * as logs from "./logs"; import * as types from "./types"; export { logs, types }; -export { CosmosAddressBech32Prefix, encodeAddress, isValidAddress } from "./address"; +export { encodeAddress } from "./address"; export { unmarshalTx } from "./decoding"; export { makeSignBytes, marshalTx } from "./encoding"; export { BroadcastMode, RestClient, TxsResponse } from "./restclient";