Skip to content

Commit

Permalink
typed support + api
Browse files Browse the repository at this point in the history
  • Loading branch information
TateB committed Feb 15, 2024
1 parent 8a72eb8 commit 6edfb17
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 11 deletions.
10 changes: 10 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
9 changes: 6 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<TCoinType> => {
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<TCoinType>;
Expand Down
23 changes: 16 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -20,7 +20,7 @@ type NonEvmCoinTypeToFormat = {
};
export type CoinTypeToFormatMap = {
[key in CoinType]: key extends EvmCoinType
? Prettify<GetEvmCoin<CoinTypeToNameMap[`${key}`][0]>>
? Prettify<GetEvmCoin<key>>
: key extends keyof NonEvmCoinTypeToFormat
? NonEvmCoinTypeToFormat[key]
: never;
Expand All @@ -35,12 +35,16 @@ export type EvmCoinType = EvmCoinMap[EvmCoinName];
export type EvmChainId = Subtract<EvmCoinType, typeof SLIP44_MSB>;

export type GetEvmCoin<
TEvmName extends EvmCoinName,
TCoinType extends CoinNameToTypeMap[TEvmName] = CoinNameToTypeMap[TEvmName]
TCoinType extends number,
TChainId extends number = Subtract<TCoinType, typeof SLIP44_MSB>,
TCoinName extends string = TCoinType extends EvmCoinType
? CoinTypeToNameMap[`${TCoinType}`][0]
: `Unknown Chain (${TChainId})`
> = {
name: TEvmName;
name: TCoinName;
coinType: TCoinType;
evmChainId: Subtract<TCoinType, typeof SLIP44_MSB>;
evmChainId: TChainId;
isUnknownChain: TCoinType extends EvmCoinType ? false : true;
encode: EncoderFunction;
decode: DecoderFunction;
};
Expand All @@ -52,6 +56,7 @@ export type CoinParameters = {
name: string;
coinType: number;
evmChainId?: number;
isUnknownChain?: boolean;
};

export type CoinCoder = {
Expand All @@ -72,7 +77,11 @@ export type GetCoderByCoinName<TCoinName extends CoinName | string> =
TCoinName extends CoinName ? CoinNameToFormatMap[TCoinName] : Coin;

export type GetCoderByCoinType<TCoinType extends CoinType | number> =
TCoinType extends CoinType ? CoinTypeToFormatMap[TCoinType] : Coin;
TCoinType extends CoinType
? CoinTypeToFormatMap[TCoinType]
: GtOrEq<TCoinType, typeof SLIP44_MSB> extends 1
? Prettify<GetEvmCoin<TCoinType>>
: Coin;

export type ParseInt<T> = T extends `${infer N extends number}` ? N : never;

Expand Down
14 changes: 13 additions & 1 deletion src/utils/evm.ts
Original file line number Diff line number Diff line change
@@ -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<TChainId, typeof SLIP44_MSB> extends 1
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export {
SLIP44_MSB,
coinTypeToEvmChainId,
evmChainIdToCoinType,
isEvmCoinType,
} from "./evm.js";
export { validateFlowAddress } from "./flow.js";
export { decodeLeb128, encodeLeb128 } from "./leb128.js";
Expand Down

0 comments on commit 6edfb17

Please sign in to comment.