Skip to content

Commit

Permalink
Feat/add chain wallet sdks (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustin01 authored Dec 16, 2024
1 parent 6d54208 commit 72f5859
Show file tree
Hide file tree
Showing 82 changed files with 4,006 additions and 60 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
"build:sdk": "turbo run @delandlabs/hibit-id-wallet-sdk#build",
"test:coin-kaspa": "turbo run @delandlabs/coin-kaspa#test",
"build:coin-kaspa": "turbo run @delandlabs/coin-kaspa#build",
"build:coin-ethereum": "turbo run @delandlabs/coin-ethereum#build",
"build:coin-ton": "turbo run @delandlabs/coin-ton#build",
"build:coin-dfinity": "turbo run @delandlabs/coin-dfinity#build",
"build:coin-solana": "turbo run @delandlabs/coin-solana#build",
"build:coin-tron": "turbo run @delandlabs/coin-tron#build",
"prepare": "husky install"
},
"workspaces": [
Expand Down
24 changes: 24 additions & 0 deletions packages/coin-base/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
1 change: 1 addition & 0 deletions packages/coin-base/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tsconfig.json
47 changes: 47 additions & 0 deletions packages/coin-base/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@delandlabs/coin-base",
"private": false,
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"main": "./dist/coin-base.umd.cjs",
"module": "./dist/coin-base.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/coin-base.js"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/coin-base.umd.cjs"
}
}
},
"scripts": {
"dev": "vite",
"test": "vitest",
"build": "vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"format": "prettier --write ."
},
"dependencies": {
"class-transformer": "^0.5.1",
"reflect-metadata": "^0.2.2"
},
"devDependencies": {
"@eslint/js": "^9.16.0",
"@rollup/plugin-typescript": "^12.1.1",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",
"eslint": "^9.16.0",
"globals": "^15.12.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.16.0",
"vite": "^6.0.1",
"vitest": "^2.1.6"
}
}
20 changes: 20 additions & 0 deletions packages/coin-base/src/enums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export enum WalletSignatureSchema {
BtcEcdsa = '0x3e8',
EvmEcdsa = '0x3e9',
TronEcdsa = '0x3ea',
TonEddsaOpenMask = '0x7d0',
SolanaEddsa = '0x7da',
IcpEddsa = '0x7e4',
KaspaSchnorr = '0xbc2',
}

// TODO: Add support for other ecosystems
export enum Ecosystem {
EVM = 'EVM',
Bitcoin = 'Bitcoin',
Solana = 'Solana',
Tron = 'Tron',
Ton = 'Ton',
IC = 'Internet Computer',
Kaspa = 'Kaspa',
}
22 changes: 22 additions & 0 deletions packages/coin-base/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'reflect-metadata';
import BigNumber from "bignumber.js";
import { AssetInfo, ChainInfo, WalletAccount } from "./types";

export * from "./types"
export * from "./enums"

export abstract class BaseChainWallet {
public readonly chainInfo: ChainInfo
protected readonly phrase: string

constructor(chainInfo: ChainInfo, phrase: string) {
this.chainInfo = chainInfo
this.phrase = phrase
}

public abstract getAccount: () => Promise<WalletAccount>
public abstract signMessage: (message: string) => Promise<string>
public abstract balanceOf: (address: string, assetInfo: AssetInfo) => Promise<BigNumber>
public abstract transfer: (toAddress: string, amount: BigNumber, assetInfo: AssetInfo) => Promise<string>
public abstract getEstimatedFee: (toAddress: string, amount: BigNumber, assetInfo: AssetInfo) => Promise<BigNumber>
}
251 changes: 251 additions & 0 deletions packages/coin-base/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import BigNumber from "bignumber.js";
import { Transform, Type } from 'class-transformer';
import { WalletSignatureSchema, Ecosystem } from "./enums";

export class Chain {
value: BigNumber;

constructor(value: BigNumber) {
this.value = value;
}

static Bitcoin = new Chain(new BigNumber(0));
static Ethereum = new Chain(new BigNumber(60));
static Solana = new Chain(new BigNumber(501));
static Dfinity = new Chain(new BigNumber(223));
static Ton = new Chain(new BigNumber(607));
static Tron = new Chain(new BigNumber(195));
static Kaspa = new Chain(new BigNumber(111111));

static fromString(value: string): Chain | null {
if (!value) {
return null;
}
return new Chain(new BigNumber(value));
}

toString(): string {
return this.value.toString();
}

equals(other: Chain): boolean {
if (!other) {
return false;
}
return this.value.isEqualTo(other.value);
}
}

export class ChainNetwork {
value: BigNumber;

constructor(value: BigNumber) {
this.value = value;
}

static MainNet = new ChainNetwork(new BigNumber(1));
static TestNet = new ChainNetwork(new BigNumber(0));

static BtcMainNet = new ChainNetwork(new BigNumber(1));
static BtcTestNet = new ChainNetwork(new BigNumber(2));

static EvmMainNet = new ChainNetwork(new BigNumber(0x1));
static EvmSepoliaNet = new ChainNetwork(new BigNumber(0xaa36a7));
static EvmBscNet = new ChainNetwork(new BigNumber(0x38));
static EvmBscTestNet = new ChainNetwork(new BigNumber(97));
static EvmBaseNet = new ChainNetwork(new BigNumber(8453));
static EvmBaseSepoliaNet = new ChainNetwork(new BigNumber(84532));
static EvmAvalancheNet = new ChainNetwork(new BigNumber(43114));
static EvmAvalancheFujiNet = new ChainNetwork(new BigNumber(43113));
static EvmScrollNet = new ChainNetwork(new BigNumber(534352));
static EvmScrollSepoliaNet = new ChainNetwork(new BigNumber(534351));
static EvmBitlayerNet = new ChainNetwork(new BigNumber(200901));
static EvmBitlayerTestNet = new ChainNetwork(new BigNumber(200810));
static EvmSwanNet = new ChainNetwork(new BigNumber(254));
static EvmSwanTestNet = new ChainNetwork(new BigNumber(20241133));

static SolanaMainNet = new ChainNetwork(new BigNumber(0x3));
static SolanaTestNet = new ChainNetwork(new BigNumber(0x2));

static TonMainNet = new ChainNetwork(new BigNumber(1));
static TonTestNet = new ChainNetwork(new BigNumber(2));

static TronMainNet = new ChainNetwork(new BigNumber(0x2b6653dc));
static TronShastaTestNet = new ChainNetwork(new BigNumber(0x94a9059e));
static TronNileTestNet = new ChainNetwork(new BigNumber(0xcd8690dc));

static DfinityMainNet = new ChainNetwork(new BigNumber(1));

static KaspaMainNet = new ChainNetwork(new BigNumber(0));
static KaspaTestNet = new ChainNetwork(new BigNumber(1));

static fromString(value: string): ChainNetwork | null {
if (!value) {
return null;
}
return new ChainNetwork(new BigNumber(value));
}

toString(): string {
return this.value.toString();
}

equals(other: ChainNetwork): boolean {
if (!other) {
return false;
}
return this.value.isEqualTo(other.value);
}
}

export class ChainId {
type: Chain;
network: ChainNetwork;

constructor(type: Chain, network: ChainNetwork) {
this.type = type;
this.network = network;
}

static fromString(value: string): ChainId | null {
if (!value) {
return null;
}
const [type, network] = value.split('_');
return new ChainId(
Chain.fromString(type)!,
ChainNetwork.fromString(network)!
);
}

toString(): string {
return `${this.type.toString()}_${this.network.toString()}`;
}

equals(other: ChainId): boolean {
if (!other) {
return false;
}
return this.type.equals(other.type) && this.network.equals(other.network);
}
}

export class ChainAssetType {
value: BigNumber;

constructor(value: BigNumber) {
this.value = value;
}

static Native = new ChainAssetType(new BigNumber(0));
static NativeGas = new ChainAssetType(new BigNumber(1));
static ERC20 = new ChainAssetType(new BigNumber(3));
static ERC721 = new ChainAssetType(new BigNumber(4));
static ICP = new ChainAssetType(new BigNumber(5));
static ICRC3 = new ChainAssetType(new BigNumber(6));
static BRC20 = new ChainAssetType(new BigNumber(7));
static SPL = new ChainAssetType(new BigNumber(8));
static TRC20 = new ChainAssetType(new BigNumber(9));
static Jetton = new ChainAssetType(new BigNumber(10));
static KRC20 = new ChainAssetType(new BigNumber(11));

static fromString(value: string): ChainAssetType | null {
if (!value) {
return null;
}
return new ChainAssetType(new BigNumber(value));
}

toString(): string {
return this.value.toString();
}

equals(other: ChainAssetType): boolean {
if (!other) {
return false;
}
return this.value.isEqualTo(other.value);
}
}

export class DecimalPlaces {
value: number;

constructor(value: number) {
this.value = value;
}

static fromNumber(value: number): DecimalPlaces {
return new DecimalPlaces(value);
}

toString(): string {
return this.value.toString();
}

equals(other: DecimalPlaces): boolean {
if (!other) {
return false;
}
return this.value === other.value;
}
}

export class ChainInfo {
/**
* Chain id
* @type {ChainId} https://github.com/satoshilabs/slips/blob/master/slip-0044.md.
*/
@Type(() => ChainId)
@Transform(
({ value }) => ChainId.fromString(`${value.type.value}_${value.network.value}`),
{
toClassOnly: true
}
)
chainId!: ChainId;
name!: string;
fullName!: string;
icon!: string;
nativeAssetSymbol!: string;
nativeAssetDecimals!: number;
supportedSignaturesSchemas!: WalletSignatureSchema[];
explorer!: string;
rpcUrls!: string[];
isMainnet!: boolean
isNativeGas!: boolean;
ecosystem!: Ecosystem;
caseSensitiveAddress?: boolean;
getServerFormatAddress?: (address: string) => string | null
getTxLink?: (txId: string) => string
getAddressLink?: (address: string) => string
}

export class AssetInfo {
@Type(() => Chain)
@Transform(({ value }) => Chain.fromString(value) ?? undefined, {
toClassOnly: true
})
chain!: Chain;
@Type(() => ChainNetwork)
@Transform(({ value }) => ChainNetwork.fromString(value) ?? undefined, {
toClassOnly: true
})
chainNetwork!: ChainNetwork;
@Type(() => ChainAssetType)
@Transform(({ value }) => ChainAssetType.fromString(value) ?? undefined, {
toClassOnly: true
})
chainAssetType!: ChainAssetType;
contractAddress!: string;
@Type(() => DecimalPlaces)
@Transform(({ value }) => DecimalPlaces.fromNumber(value) ?? undefined, {
toClassOnly: true
})
decimalPlaces!: DecimalPlaces;
}

export interface WalletAccount {
address: string;
publicKey?: string;
}
1 change: 1 addition & 0 deletions packages/coin-base/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
12 changes: 12 additions & 0 deletions packages/coin-base/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"src/*": ["src/*"]
},
"experimentalDecorators": true,
},
"include": ["src"],
"exclude": ["**/node_modules"]
}
Loading

0 comments on commit 72f5859

Please sign in to comment.