Make TokenInfo free from BCP types

This commit is contained in:
Simon Warta 2020-02-01 16:17:36 +01:00
parent fb9160f258
commit eb72f0e175
13 changed files with 68 additions and 48 deletions

View File

@ -9,7 +9,6 @@ import {
SignableBytes, SignableBytes,
SignedTransaction, SignedTransaction,
SigningJob, SigningJob,
TokenTicker,
TransactionId, TransactionId,
TxCodec, TxCodec,
UnsignedTransaction, UnsignedTransaction,
@ -107,8 +106,7 @@ const defaultPrefix = "cosmos" as CosmosBech32Prefix;
const defaultTokens: TokenInfos = [ const defaultTokens: TokenInfos = [
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Atom (Cosmos Hub)", ticker: "ATOM",
tokenTicker: "ATOM" as TokenTicker,
denom: "uatom", denom: "uatom",
}, },
]; ];

View File

@ -16,8 +16,8 @@ import { HdPaths, Secp256k1HdWallet, UserProfile } from "@iov/keycontrol";
import { CosmosBech32Prefix } from "./address"; import { CosmosBech32Prefix } from "./address";
import { CosmWasmCodec, cosmWasmCodec } from "./cosmwasmcodec"; import { CosmWasmCodec, cosmWasmCodec } from "./cosmwasmcodec";
import { CosmWasmConnection } from "./cosmwasmconnection"; import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection";
import { nonceToSequence, TokenInfos } from "./types"; import { nonceToSequence } from "./types";
const { fromBase64, toHex } = Encoding; const { fromBase64, toHex } = Encoding;
@ -45,17 +45,17 @@ describe("CosmWasmConnection", () => {
const defaultPrefix = "cosmos" as CosmosBech32Prefix; const defaultPrefix = "cosmos" as CosmosBech32Prefix;
// this is for wasmd blockchain // this is for wasmd blockchain
const defaultTokens: TokenInfos = [ const defaultTokens: TokenConfiguration = [
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Fee Token", name: "Fee Token",
tokenTicker: "COSM" as TokenTicker, ticker: "COSM",
denom: "ucosm", denom: "ucosm",
}, },
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Staking Token", name: "Staking Token",
tokenTicker: "STAKE" as TokenTicker, ticker: "STAKE",
denom: "ustake", denom: "ustake",
}, },
]; ];

View File

@ -38,7 +38,7 @@ import { Stream } from "xstream";
import { CosmosBech32Prefix, decodeCosmosPubkey, pubkeyToAddress } from "./address"; import { CosmosBech32Prefix, decodeCosmosPubkey, pubkeyToAddress } from "./address";
import { Caip5 } from "./caip5"; import { Caip5 } from "./caip5";
import { decodeAmount, parseTxsResponse } from "./decode"; import { decodeAmount, parseTxsResponse } from "./decode";
import { accountToNonce, TokenInfos } from "./types"; import { accountToNonce, TokenInfo, TokenInfos } from "./types";
interface ChainData { interface ChainData {
readonly chainId: ChainId; readonly chainId: ChainId;
@ -68,16 +68,18 @@ function buildQueryString({
return components.filter(Boolean).join("&"); return components.filter(Boolean).join("&");
} }
export type TokenConfiguration = readonly (TokenInfo & { readonly name: string })[];
export class CosmWasmConnection implements BlockchainConnection { export class CosmWasmConnection implements BlockchainConnection {
// we must know prefix and tokens a priori to understand the chain // we must know prefix and tokens a priori to understand the chain
public static async establish( public static async establish(
url: string, url: string,
prefix: CosmosBech32Prefix, prefix: CosmosBech32Prefix,
tokenInfo: TokenInfos, tokens: TokenConfiguration,
): Promise<CosmWasmConnection> { ): Promise<CosmWasmConnection> {
const restClient = new RestClient(url); const restClient = new RestClient(url);
const chainData = await this.initialize(restClient); const chainData = await this.initialize(restClient);
return new CosmWasmConnection(restClient, chainData, prefix, tokenInfo); return new CosmWasmConnection(restClient, chainData, prefix, tokens);
} }
private static async initialize(restClient: RestClient): Promise<ChainData> { private static async initialize(restClient: RestClient): Promise<ChainData> {
@ -102,16 +104,16 @@ export class CosmWasmConnection implements BlockchainConnection {
restClient: RestClient, restClient: RestClient,
chainData: ChainData, chainData: ChainData,
prefix: CosmosBech32Prefix, prefix: CosmosBech32Prefix,
tokenInfo: TokenInfos, tokens: TokenConfiguration,
) { ) {
this.restClient = restClient; this.restClient = restClient;
this.chainData = chainData; this.chainData = chainData;
this._prefix = prefix; this._prefix = prefix;
this.tokenInfo = tokenInfo; this.tokenInfo = tokens;
this.supportedTokens = this.tokenInfo.map(info => ({ this.supportedTokens = tokens.map(info => ({
tokenTicker: info.tokenTicker, tokenTicker: info.ticker as TokenTicker,
tokenName: info.tokenName, tokenName: info.name,
fractionalDigits: info.fractionalDigits, fractionalDigits: info.fractionalDigits,
})); }));
this.primaryToken = this.supportedTokens[0]; this.primaryToken = this.supportedTokens[0];

View File

@ -2,8 +2,7 @@ import { ChainConnector, ChainId } from "@iov/bcp";
import { CosmosBech32Prefix } from "./address"; import { CosmosBech32Prefix } from "./address";
import { CosmWasmCodec } from "./cosmwasmcodec"; import { CosmWasmCodec } from "./cosmwasmcodec";
import { CosmWasmConnection } from "./cosmwasmconnection"; import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection";
import { TokenInfo } from "./types";
/** /**
* A helper to connect to a cosmos-based chain at a given url * A helper to connect to a cosmos-based chain at a given url
@ -11,12 +10,12 @@ import { TokenInfo } from "./types";
export function createCosmWasmConnector( export function createCosmWasmConnector(
url: string, url: string,
prefix: CosmosBech32Prefix, prefix: CosmosBech32Prefix,
tokenInfo: readonly TokenInfo[], tokens: TokenConfiguration,
expectedChainId?: ChainId, expectedChainId?: ChainId,
): ChainConnector<CosmWasmConnection> { ): ChainConnector<CosmWasmConnection> {
const codec = new CosmWasmCodec(prefix, tokenInfo); const codec = new CosmWasmCodec(prefix, tokens);
return { return {
establishConnection: async () => CosmWasmConnection.establish(url, prefix, tokenInfo), establishConnection: async () => CosmWasmConnection.establish(url, prefix, tokens),
codec: codec, codec: codec,
expectedChainId: expectedChainId, expectedChainId: expectedChainId,
}; };

View File

@ -55,8 +55,7 @@ describe("decode", () => {
const defaultTokens: TokenInfos = [ const defaultTokens: TokenInfos = [
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Atom (Cosmos Hub)", ticker: "ATOM",
tokenTicker: "ATOM" as TokenTicker,
denom: "uatom", denom: "uatom",
}, },
]; ];

View File

@ -44,8 +44,7 @@ describe("encode", () => {
const defaultTokens: TokenInfos = [ const defaultTokens: TokenInfos = [
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Atom (Cosmos Hub)", ticker: "ATOM",
tokenTicker: "ATOM" as TokenTicker,
denom: "uatom", denom: "uatom",
}, },
]; ];

View File

@ -1,4 +1,4 @@
export { CosmWasmCodec } from "./cosmwasmcodec"; export { CosmWasmCodec } from "./cosmwasmcodec";
export { CosmWasmConnection } from "./cosmwasmconnection"; export { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection";
export { createCosmWasmConnector } from "./cosmwasmconnector"; export { createCosmWasmConnector } from "./cosmwasmconnector";
export { TokenInfo } from "./types"; export { TokenInfo } from "./types";

View File

@ -1,15 +1,26 @@
import { Amount, Nonce, Token } from "@iov/bcp"; import { Amount, Nonce, TokenTicker } from "@iov/bcp";
import amino from "@tendermint/amino-js"; import amino from "@tendermint/amino-js";
export interface TokenInfo extends Token { export interface TokenInfo {
readonly denom: string; readonly denom: 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 type TokenInfos = ReadonlyArray<TokenInfo>; export type TokenInfos = ReadonlyArray<TokenInfo>;
// TODO: return null vs throw exception for undefined??? // TODO: return null vs throw exception for undefined???
export function amountToCoin(lookup: ReadonlyArray<TokenInfo>, amount: Amount): amino.Coin { export function amountToCoin(lookup: ReadonlyArray<TokenInfo>, amount: Amount): amino.Coin {
const match = lookup.find(({ tokenTicker }) => tokenTicker === amount.tokenTicker); const match = lookup.find(({ ticker }) => ticker === amount.tokenTicker);
if (!match) { if (!match) {
throw Error(`unknown ticker: ${amount.tokenTicker}`); throw Error(`unknown ticker: ${amount.tokenTicker}`);
} }
@ -26,7 +37,7 @@ export function coinToAmount(tokens: TokenInfos, coin: amino.Coin): Amount {
throw Error(`unknown denom: ${coin.denom}`); throw Error(`unknown denom: ${coin.denom}`);
} }
return { return {
tokenTicker: match.tokenTicker, tokenTicker: match.ticker as TokenTicker,
fractionalDigits: match.fractionalDigits, fractionalDigits: match.fractionalDigits,
quantity: coin.amount, quantity: coin.amount,
}; };

View File

@ -21,12 +21,15 @@ import {
} from "@iov/bcp"; } from "@iov/bcp";
import { Stream } from "xstream"; import { Stream } from "xstream";
import { CosmosBech32Prefix } from "./address"; import { CosmosBech32Prefix } from "./address";
import { TokenInfos } from "./types"; import { TokenInfo } from "./types";
export declare type TokenConfiguration = readonly (TokenInfo & {
readonly name: string;
})[];
export declare class CosmWasmConnection implements BlockchainConnection { export declare class CosmWasmConnection implements BlockchainConnection {
static establish( static establish(
url: string, url: string,
prefix: CosmosBech32Prefix, prefix: CosmosBech32Prefix,
tokenInfo: TokenInfos, tokens: TokenConfiguration,
): Promise<CosmWasmConnection>; ): Promise<CosmWasmConnection>;
private static initialize; private static initialize;
private readonly restClient; private readonly restClient;

View File

@ -1,13 +1,12 @@
import { ChainConnector, ChainId } from "@iov/bcp"; import { ChainConnector, ChainId } from "@iov/bcp";
import { CosmosBech32Prefix } from "./address"; import { CosmosBech32Prefix } from "./address";
import { CosmWasmConnection } from "./cosmwasmconnection"; import { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection";
import { TokenInfo } from "./types";
/** /**
* A helper to connect to a cosmos-based chain at a given url * A helper to connect to a cosmos-based chain at a given url
*/ */
export declare function createCosmWasmConnector( export declare function createCosmWasmConnector(
url: string, url: string,
prefix: CosmosBech32Prefix, prefix: CosmosBech32Prefix,
tokenInfo: readonly TokenInfo[], tokens: TokenConfiguration,
expectedChainId?: ChainId, expectedChainId?: ChainId,
): ChainConnector<CosmWasmConnection>; ): ChainConnector<CosmWasmConnection>;

View File

@ -1,4 +1,4 @@
export { CosmWasmCodec } from "./cosmwasmcodec"; export { CosmWasmCodec } from "./cosmwasmcodec";
export { CosmWasmConnection } from "./cosmwasmconnection"; export { CosmWasmConnection, TokenConfiguration } from "./cosmwasmconnection";
export { createCosmWasmConnector } from "./cosmwasmconnector"; export { createCosmWasmConnector } from "./cosmwasmconnector";
export { TokenInfo } from "./types"; export { TokenInfo } from "./types";

View File

@ -1,8 +1,18 @@
import { Amount, Nonce, Token } from "@iov/bcp"; import { Amount, Nonce } from "@iov/bcp";
import amino from "@tendermint/amino-js"; import amino from "@tendermint/amino-js";
export declare function isAminoStdTx(txValue: amino.TxValue): txValue is amino.StdTx; export interface TokenInfo {
export interface TokenInfo extends Token {
readonly denom: string; readonly denom: 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 type TokenInfos = ReadonlyArray<TokenInfo>; export declare type TokenInfos = ReadonlyArray<TokenInfo>;
export declare function amountToCoin(lookup: ReadonlyArray<TokenInfo>, amount: Amount): amino.Coin; export declare function amountToCoin(lookup: ReadonlyArray<TokenInfo>, amount: Amount): amino.Coin;

View File

@ -1,18 +1,18 @@
import { CosmWasmCodec, CosmWasmConnection, TokenInfo } from "@cosmwasm/bcp"; import { CosmWasmCodec, CosmWasmConnection, TokenConfiguration } from "@cosmwasm/bcp";
import { TokenTicker, TxCodec } from "@iov/bcp"; import { TxCodec } from "@iov/bcp";
const prefix = "cosmos"; const prefix = "cosmos";
const tokens: readonly TokenInfo[] = [ const tokens: TokenConfiguration = [
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Fee Token", name: "Fee Token",
tokenTicker: "COSM" as TokenTicker, ticker: "COSM",
denom: "cosm", denom: "cosm",
}, },
{ {
fractionalDigits: 6, fractionalDigits: 6,
tokenName: "Staking Token", name: "Staking Token",
tokenTicker: "STAKE" as TokenTicker, ticker: "STAKE",
denom: "stake", denom: "stake",
}, },
]; ];