Remove CosmosAddressBech32Prefix/isValidAddress

This commit is contained in:
Simon Warta 2020-02-19 10:02:08 +01:00
parent c106975df9
commit ef999070e8
16 changed files with 66 additions and 126 deletions

View File

@ -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 = {

View File

@ -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);
});
});

View File

@ -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;
}
}
}

View File

@ -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<Account | undefined>();
(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);

View File

@ -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<CosmWasmConnection> {
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;

View File

@ -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<CosmWasmConnection> {

View File

@ -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;

View File

@ -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;

View File

@ -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<CosmWasmConnection>;
private static initialize;

View File

@ -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<CosmWasmConnection>;

View File

@ -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();

View File

@ -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";

View File

@ -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 {

View File

@ -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";

View File

@ -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;

View File

@ -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";