From 6edfb17134884dfa56275dc880997ada03ed4192 Mon Sep 17 00:00:00 2001 From: tate Date: Thu, 15 Feb 2024 12:42:44 +1100 Subject: [PATCH] typed support + api --- src/index.test.ts | 10 ++++++++++ src/index.ts | 9 ++++++--- src/types.ts | 23 ++++++++++++++++------- src/utils/evm.ts | 14 +++++++++++++- src/utils/index.ts | 1 + 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index 297c7038..af086f3a 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -44,6 +44,16 @@ test("evm coin type", () => { expect(coder.decode).toBeFunction(); }); +test("unknown evm coin type", () => { + const coder = getCoderByCoinType(2147483659); + expect(coder.coinType).toBe(2147483659); + expect(coder.name).toBe("Unknown Chain (11)"); + expect(coder.evmChainId).toBe(11); + expect(coder.isUnknownChain).toBeTrue(); + expect(coder.encode).toBeFunction(); + expect(coder.decode).toBeFunction(); +}); + const nonEvmCoinNames = Object.keys(nonEvmCoinNameToTypeMap); const evmCoinNames = Object.keys(evmCoinNameToTypeMap); diff --git a/src/index.ts b/src/index.ts index 821f8e24..225f86ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,21 +66,24 @@ export const getCoderByCoinName = < }; export const getCoderByCoinType = < - TCoinType extends CoinType | number = CoinType | number + const TCoinType extends CoinType | number = CoinType | number >( coinType: TCoinType ): GetCoderByCoinType => { - const names = coinTypeToNameMap[String(coinType) as keyof typeof coinTypeToNameMap]; + const names = + coinTypeToNameMap[String(coinType) as keyof typeof coinTypeToNameMap]; // https://docs.ens.domains/ens-improvement-proposals/ensip-11-evmchain-address-resolution if (coinType >= SLIP44_MSB) { // EVM coin const evmChainId = coinTypeToEvmChainId(coinType); - const name = names ? names[0] : `Chain(${evmChainId})`; // name is derivable + const isUnknownChain = !names; + const name = isUnknownChain ? `Unknown Chain (${evmChainId})` : names[0]; // name is derivable const ethFormat = formats["eth"]; return { name, coinType: coinType as EvmCoinType, evmChainId, + isUnknownChain, encode: ethFormat.encode, decode: ethFormat.decode, } as GetCoderByCoinType; diff --git a/src/types.ts b/src/types.ts index f6f71a58..3f68f198 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type { Subtract } from "ts-arithmetic"; +import type { GtOrEq, Subtract } from "ts-arithmetic"; import type * as formats from "./coins.js"; import type { coinNameToTypeMap, @@ -20,7 +20,7 @@ type NonEvmCoinTypeToFormat = { }; export type CoinTypeToFormatMap = { [key in CoinType]: key extends EvmCoinType - ? Prettify> + ? Prettify> : key extends keyof NonEvmCoinTypeToFormat ? NonEvmCoinTypeToFormat[key] : never; @@ -35,12 +35,16 @@ export type EvmCoinType = EvmCoinMap[EvmCoinName]; export type EvmChainId = Subtract; export type GetEvmCoin< - TEvmName extends EvmCoinName, - TCoinType extends CoinNameToTypeMap[TEvmName] = CoinNameToTypeMap[TEvmName] + TCoinType extends number, + TChainId extends number = Subtract, + TCoinName extends string = TCoinType extends EvmCoinType + ? CoinTypeToNameMap[`${TCoinType}`][0] + : `Unknown Chain (${TChainId})` > = { - name: TEvmName; + name: TCoinName; coinType: TCoinType; - evmChainId: Subtract; + evmChainId: TChainId; + isUnknownChain: TCoinType extends EvmCoinType ? false : true; encode: EncoderFunction; decode: DecoderFunction; }; @@ -52,6 +56,7 @@ export type CoinParameters = { name: string; coinType: number; evmChainId?: number; + isUnknownChain?: boolean; }; export type CoinCoder = { @@ -72,7 +77,11 @@ export type GetCoderByCoinName = TCoinName extends CoinName ? CoinNameToFormatMap[TCoinName] : Coin; export type GetCoderByCoinType = - TCoinType extends CoinType ? CoinTypeToFormatMap[TCoinType] : Coin; + TCoinType extends CoinType + ? CoinTypeToFormatMap[TCoinType] + : GtOrEq extends 1 + ? Prettify> + : Coin; export type ParseInt = T extends `${infer N extends number}` ? N : never; diff --git a/src/utils/evm.ts b/src/utils/evm.ts index d4b8416e..441e048e 100644 --- a/src/utils/evm.ts +++ b/src/utils/evm.ts @@ -1,8 +1,20 @@ -import type { Add, Lt, Subtract } from "ts-arithmetic"; +import type { Add, GtOrEq, Lt, Subtract } from "ts-arithmetic"; import type { EvmChainId, EvmCoinType } from "../types.js"; export const SLIP44_MSB = 0x80000000; +export const isEvmCoinType = < + TCoinType extends EvmCoinType | number = EvmCoinType | number +>( + coinType: TCoinType +) => + ((coinType & SLIP44_MSB) !== 0) as GtOrEq< + TCoinType, + typeof SLIP44_MSB + > extends 1 + ? true + : false; + type EvmChainIdToCoinType< TChainId extends EvmChainId | number = EvmChainId | number > = Lt extends 1 diff --git a/src/utils/index.ts b/src/utils/index.ts index a3aceaf2..7122e3dd 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -41,6 +41,7 @@ export { SLIP44_MSB, coinTypeToEvmChainId, evmChainIdToCoinType, + isEvmCoinType, } from "./evm.js"; export { validateFlowAddress } from "./flow.js"; export { decodeLeb128, encodeLeb128 } from "./leb128.js";