@xyo-network/wallet 4.3.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,10 @@ import type { PrivateKeyInstance } from '@xyo-network/key-model';
5
5
  import { WalletInstance } from '@xyo-network/wallet-model';
6
6
  import { HDNodeWallet, Mnemonic } from 'ethers';
7
7
  export declare class HDWallet extends Account implements WalletInstance {
8
- protected readonly node: HDNodeWallet;
9
8
  static readonly uniqueName: string;
10
9
  protected static _addressMap: Record<Address, WeakRef<WalletInstance>>;
11
- constructor(key: unknown, node: HDNodeWallet, privateKey: PrivateKeyInstance);
10
+ protected readonly node: HDNodeWallet;
11
+ constructor(key: symbol, node: HDNodeWallet, privateKey: PrivateKeyInstance);
12
12
  get address(): Address;
13
13
  get addressBytes(): ArrayBufferLike;
14
14
  get chainCode(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAM3D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY;IALvC,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;gBAGlF,GAAG,EAAE,OAAO,EACO,IAAI,EAAE,YAAY,EACrC,UAAU,EAAE,kBAAkB;IAKhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
1
+ {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAC7D,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;IAEpF,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;gBAGnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,kBAAkB;IAMhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
@@ -34,8 +34,9 @@ import {
34
34
  Mnemonic
35
35
  } from "ethers";
36
36
  var HDWallet = class extends Account {
37
+ node;
37
38
  constructor(key, node, privateKey) {
38
- super(Account._protectedConstructorKey, privateKey);
39
+ super(key, privateKey);
39
40
  this.node = node;
40
41
  }
41
42
  get address() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n constructor(\n key: unknown,\n protected readonly node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(Account._protectedConstructorKey, privateKey)\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,wBAAwB;AACjC,SAAS,YAAY,uBAAuB;AAC5C,SAAS,oBAAoB;AAC7B,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B;AAAA,EACW;AAAA,EAAgB;AAAA,OACpB;AACP,SAAS,wBAAwB;AACjC,SAAS,SAAS,kBAAkB;AACpC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EAAa;AAAA,EAAc;AAAA,OACtB;AAGA,IAAM,WAAN,cAAuB,QAAkC;AAAA,EAI9D,YACE,KACmB,MACnB,YACA;AACA,UAAM,QAAQ,0BAA0B,UAAU;AAH/B;AAAA,EAIrB;AAAA,EAEA,IAAa,UAAmB;AAC9B,WAAO,UAAU,iBAAiB,KAAK,KAAK,SAAS,EAAE,QAAQ,MAAM,CAAC,GAAG,IAAI;AAAA,EAC/E;AAAA,EAEA,IAAa,eAAgC;AAC3C,WAAO,aAAa,KAAK,SAAS,QAAW,EAAE,EAAE;AAAA,EACnD;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,WAA4B;AAC9B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,OAAsB;AACxB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,aAAkB;AACpB,WAAO,KAAK,KAAK,WAAW,YAAY;AAAA,EAC1C;AAAA,EAEA,IAAI,YAAiB;AACnB,WAAO,KAAK,KAAK,UAAU,YAAY;AAAA,EACzC;AAAA,EAEA,aAAsB,OAAO,MAA+C;AAC1E,QAAI,6BAA6B,IAAI,GAAG;AACtC,aAAO,MAAM,KAAK,WAAW,KAAK,MAAM;AAAA,IAC1C;AACA,QAAI,+BAA+B,IAAI,GAAG;AACxC,aAAO,MAAM,KAAK,WAAW,KAAK,UAAU,KAAK,IAAI;AAAA,IACvD;AACA,QAAI,iCAAiC,IAAI,GAAG;AAC1C,YAAM,IAAI,MAAM,oGAAoG;AAAA,IACtH;AACA,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAAA,EAEA,aAAa,eAAe,MAAoB,cAAgD;AAC9F,WAAO,MAAM,KAAK,uBAAuB,MAAM,YAAY;AAAA,EAC7D;AAAA,EAEA,aAAa,gBAAgB,KAAsC;AACjE,UAAM,OAAO,aAAa,gBAAgB,GAAG;AAE7C,WAAO,MAAM,SAAS,eAAe,IAAoB;AAAA,EAC3D;AAAA,EAEA,aAAa,aAAa,UAAoB,OAAe,aAAsC;AACjG,UAAM,OAAO,aAAa,aAAa,UAAU,IAAI;AACrD,UAAM,gBAAgB,MAAM,KAAK,uBAAuB,IAAI;AAC5D,WAAO,KAAK,gCAAgC,aAAa;AAAA,EAC3D;AAAA,EAEA,aAAa,WAAW,QAAgB,OAAe,aAAsC;AAC3F,WAAO,MAAM,KAAK,aAAa,SAAS,WAAW,MAAM,GAAG,IAAI;AAAA,EAClE;AAAA,EAEA,aAAa,SAAS,MAAyD;AAC7E,UAAM,OAAO,aAAa,SAAS,aAAa,IAAI,CAAC;AACrD,UAAM,gBAAgB,MAAM,KAAK,uBAAuB,IAAI;AAC5D,WAAO,KAAK,gCAAgC,aAAa;AAAA,EAC3D;AAAA,EAEA,OAAO,iBAAiB,WAAqB,iBAAiB,WAAmB,KAAa;AAC5F,WAAO,iBAAiB,UAAU,QAAQ;AAAA,EAC5C;AAAA,EAEA,aAAsB,SAAkC;AACtD,WAAO,MAAM,KAAK,aAAa,SAAS,WAAW,SAAS,iBAAiB,CAAC,CAAC;AAAA,EACjF;AAAA,EAEA,aAAuB,uBAAuB,MAAoB,cAAgD;AAChH,UAAM,aAAa,aAAa,KAAK,WAAW,QAAQ,MAAM,EAAE,CAAC;AACjE,aAAS,WAAW,WAAW,IAAI,MAAM,iCAAiC,YAAY,MAAM,GAAG;AAC/F,UAAM,YAAY,MAAM,IAAI,SAAS,QAAQ,0BAA0B,MAAM,MAAM,WAAW,OAAO,WAAW,MAAM,CAAC,EAAE,iBAAiB,YAAY;AACtJ,WAAO,SAAS,YAAY,UAAU,OAAO,GAAG,MAAM,KAAK;AAAA,EAC7D;AAAA,EAEA,OAAiB,gCAAgC,eAA+C;AAC9F,UAAM,iBAAiB,KAAK,YAAY,cAAc,OAAO,GAAG,MAAM;AACtE,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AACA,UAAM,MAAM,IAAI,QAAQ,aAAa;AACrC,SAAK,YAAY,cAAc,OAAO,IAAI;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,MAAuC;AAEtD,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,YAAM,aAAa,KAAK;AACxB,UAAI,eAAe,QAAQ,KAAK,WAAW,UAAU,GAAG;AACtD,cAAM,YAAY,KAAK,MAAM,WAAW,SAAS,CAAC;AAClD,eAAO,MAAM,SAAS,eAAe,KAAK,KAAK,WAAW,SAAS,CAAC;AAAA,MACtE;AACA,YAAM,IAAI,MAAM,yBAAyB,IAAI,yBAAyB,UAAU,EAAE;AAAA,IACpF;AACA,WAAO,MAAM,SAAS,eAAe,KAAK,KAAK,WAAW,IAAI,CAAC;AAAA,EACjE;AAAA,EAEA,SAAyB,MAAM;AAC7B,SAAK,KAAK,OAAO;AACjB,WAAO;AAAA,EACT;AACF;AA5IE,cADW,UACc,cAAa,eAAe,YAAY,UAAU,KAAK;AAChF,cAFW,UAEe,eAAwD,CAAC;AAFxE,WAAN;AAAA,EADN,iBAA+B;AAAA,GACnB;","names":[]}
1
+ {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n protected readonly node: HDNodeWallet\n\n constructor(\n key: symbol,\n node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(key, privateKey)\n this.node = node\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":"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","names":[]}
@@ -5,10 +5,10 @@ import type { PrivateKeyInstance } from '@xyo-network/key-model';
5
5
  import { WalletInstance } from '@xyo-network/wallet-model';
6
6
  import { HDNodeWallet, Mnemonic } from 'ethers';
7
7
  export declare class HDWallet extends Account implements WalletInstance {
8
- protected readonly node: HDNodeWallet;
9
8
  static readonly uniqueName: string;
10
9
  protected static _addressMap: Record<Address, WeakRef<WalletInstance>>;
11
- constructor(key: unknown, node: HDNodeWallet, privateKey: PrivateKeyInstance);
10
+ protected readonly node: HDNodeWallet;
11
+ constructor(key: symbol, node: HDNodeWallet, privateKey: PrivateKeyInstance);
12
12
  get address(): Address;
13
13
  get addressBytes(): ArrayBufferLike;
14
14
  get chainCode(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAM3D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY;IALvC,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;gBAGlF,GAAG,EAAE,OAAO,EACO,IAAI,EAAE,YAAY,EACrC,UAAU,EAAE,kBAAkB;IAKhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
1
+ {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAC7D,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;IAEpF,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;gBAGnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,kBAAkB;IAMhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
@@ -34,8 +34,9 @@ import {
34
34
  Mnemonic
35
35
  } from "ethers";
36
36
  var HDWallet = class extends Account {
37
+ node;
37
38
  constructor(key, node, privateKey) {
38
- super(Account._protectedConstructorKey, privateKey);
39
+ super(key, privateKey);
39
40
  this.node = node;
40
41
  }
41
42
  get address() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n constructor(\n key: unknown,\n protected readonly node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(Account._protectedConstructorKey, privateKey)\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n protected readonly node: HDNodeWallet\n\n constructor(\n key: symbol,\n node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(key, privateKey)\n this.node = node\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":"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","names":[]}
@@ -5,10 +5,10 @@ import type { PrivateKeyInstance } from '@xyo-network/key-model';
5
5
  import { WalletInstance } from '@xyo-network/wallet-model';
6
6
  import { HDNodeWallet, Mnemonic } from 'ethers';
7
7
  export declare class HDWallet extends Account implements WalletInstance {
8
- protected readonly node: HDNodeWallet;
9
8
  static readonly uniqueName: string;
10
9
  protected static _addressMap: Record<Address, WeakRef<WalletInstance>>;
11
- constructor(key: unknown, node: HDNodeWallet, privateKey: PrivateKeyInstance);
10
+ protected readonly node: HDNodeWallet;
11
+ constructor(key: symbol, node: HDNodeWallet, privateKey: PrivateKeyInstance);
12
12
  get address(): Address;
13
13
  get addressBytes(): ArrayBufferLike;
14
14
  get chainCode(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAM3D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY;IALvC,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;gBAGlF,GAAG,EAAE,OAAO,EACO,IAAI,EAAE,YAAY,EACrC,UAAU,EAAE,kBAAkB;IAKhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
1
+ {"version":3,"file":"HDWallet.d.ts","sourceRoot":"","sources":["../../src/HDWallet.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EAAa,GAAG,EACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,OAAO,EAAc,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,aAAa,EAId,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAgB,MAAM,2BAA2B,CAAA;AACxE,OAAO,EACQ,YAAY,EAAE,QAAQ,EACpC,MAAM,QAAQ,CAAA;AAEf,qBACa,QAAS,SAAQ,OAAQ,YAAW,cAAc;IAC7D,gBAAyB,UAAU,SAA8C;IACjF,iBAA0B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAK;IAEpF,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;gBAGnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,kBAAkB;IAMhC,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED,IAAa,YAAY,IAAI,eAAe,CAE3C;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,IAAI,CAExB;IAED,IAAI,UAAU,IAAI,GAAG,CAEpB;IAED,IAAI,SAAS,IAAI,GAAG,CAEnB;WAEqB,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WAa9D,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAIlF,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrD,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAMrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;WAI/E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAM9E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,GAAE,MAAM,EAAoB,EAAE,QAAQ,GAAE,MAAY,GAAG,MAAM;WAIvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;qBAIhC,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOjH,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC,aAAa,EAAE,cAAc,GAAG,cAAc;IAUzF,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAavD,MAAM,EAAE,MAAM,QAAQ,CAGrB;CACF"}
@@ -34,8 +34,9 @@ import {
34
34
  Mnemonic
35
35
  } from "ethers";
36
36
  var HDWallet = class extends Account {
37
+ node;
37
38
  constructor(key, node, privateKey) {
38
- super(Account._protectedConstructorKey, privateKey);
39
+ super(key, privateKey);
39
40
  this.node = node;
40
41
  }
41
42
  get address() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n constructor(\n key: unknown,\n protected readonly node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(Account._protectedConstructorKey, privateKey)\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/HDWallet.ts"],"sourcesContent":["import { generateMnemonic } from '@scure/bip39'\nimport { wordlist as englishWordlist } from '@scure/bip39/wordlists/english'\nimport { toUint8Array } from '@xylabs/arraybuffer'\nimport { assertEx } from '@xylabs/assert'\nimport { globallyUnique } from '@xylabs/base'\nimport {\n Address, asAddress, Hex, hexFromHexString,\n} from '@xylabs/hex'\nimport { staticImplements } from '@xylabs/static-implements'\nimport { Account, PrivateKey } from '@xyo-network/account'\nimport {\n AccountConfig,\n isMnemonicInitializationConfig,\n isPhraseInitializationConfig,\n isPrivateKeyInitializationConfig,\n} from '@xyo-network/account-model'\nimport type { PrivateKeyInstance } from '@xyo-network/key-model'\nimport { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'\nimport {\n defaultPath, HDNodeWallet, Mnemonic,\n} from 'ethers'\n\n@staticImplements<WalletStatic>()\nexport class HDWallet extends Account implements WalletInstance {\n static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')\n protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}\n\n protected readonly node: HDNodeWallet\n\n constructor(\n key: symbol,\n node: HDNodeWallet,\n privateKey: PrivateKeyInstance,\n ) {\n super(key, privateKey)\n this.node = node\n }\n\n override get address(): Address {\n return asAddress(hexFromHexString(this.node.address, { prefix: false }), true)\n }\n\n override get addressBytes(): ArrayBufferLike {\n return toUint8Array(this.address, undefined, 16).buffer\n }\n\n get chainCode(): string {\n return this.node.chainCode\n }\n\n get depth(): number {\n return this.node.depth\n }\n\n get extendedKey(): string {\n return this.node.extendedKey\n }\n\n get fingerprint(): string {\n return this.node.fingerprint\n }\n\n get index(): number {\n return this.node.index\n }\n\n get mnemonic(): Mnemonic | null {\n return this.node.mnemonic\n }\n\n get parentFingerprint(): string {\n return this.node.parentFingerprint\n }\n\n get path(): string | null {\n return this.node.path\n }\n\n get privateKey(): Hex {\n return this.node.privateKey.toLowerCase() as Hex\n }\n\n get publicKey(): Hex {\n return this.node.publicKey.toLowerCase() as Hex\n }\n\n static override async create(opts?: AccountConfig): Promise<WalletInstance> {\n if (isPhraseInitializationConfig(opts)) {\n return await this.fromPhrase(opts.phrase)\n }\n if (isMnemonicInitializationConfig(opts)) {\n return await this.fromPhrase(opts.mnemonic, opts.path)\n }\n if (isPrivateKeyInitializationConfig(opts)) {\n throw new Error('Invalid initialization config. from privateKey not supported. Use Account.fromPrivateKey instead.')\n }\n throw new Error('Invalid initialization config')\n }\n\n static async createFromNode(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n return await this.createFromNodeInternal(node, previousHash)\n }\n\n static async fromExtendedKey(key: string): Promise<WalletInstance> {\n const node = HDNodeWallet.fromExtendedKey(key)\n /* TODO: Handle HDNodeVoidWallet */\n return await HDWallet.createFromNode(node as HDNodeWallet)\n }\n\n static async fromMnemonic(mnemonic: Mnemonic, path: string = defaultPath): Promise<WalletInstance> {\n const node = HDNodeWallet.fromMnemonic(mnemonic, path)\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static async fromPhrase(phrase: string, path: string = defaultPath): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(phrase), path)\n }\n\n static async fromSeed(seed: string | ArrayBufferLike): Promise<WalletInstance> {\n const node = HDNodeWallet.fromSeed(toUint8Array(seed))\n const createdWallet = await this.createFromNodeInternal(node)\n return this.getCachedWalletOrCacheNewWallet(createdWallet)\n }\n\n static generateMnemonic(wordlist: string[] = englishWordlist, strength: number = 256): string {\n return generateMnemonic(wordlist, strength)\n }\n\n static override async random(): Promise<WalletInstance> {\n return await this.fromMnemonic(Mnemonic.fromPhrase(HDWallet.generateMnemonic()))\n }\n\n protected static async createFromNodeInternal(node: HDNodeWallet, previousHash?: string): Promise<WalletInstance> {\n const privateKey = toUint8Array(node.privateKey.replace('0x', ''))\n assertEx(privateKey.length === 32, () => `Private key must be 32 bytes [${privateKey?.length}]`)\n const newWallet = await new HDWallet(Account._protectedConstructorKey, node, await PrivateKey.create(privateKey.buffer)).loadPreviousHash(previousHash)\n return HDWallet._addressMap[newWallet.address]?.deref() ?? newWallet\n }\n\n protected static getCachedWalletOrCacheNewWallet(createdWallet: WalletInstance): WalletInstance {\n const existingWallet = this._addressMap[createdWallet.address]?.deref()\n if (existingWallet) {\n return existingWallet\n }\n const ref = new WeakRef(createdWallet)\n this._addressMap[createdWallet.address] = ref\n return createdWallet\n }\n\n async derivePath(path: string): Promise<WalletInstance> {\n // if an absolute path, check if it matches the parent root and work with it\n if (path.startsWith('m/')) {\n const parentPath = this.path\n if (parentPath !== null && path.startsWith(parentPath)) {\n const childPath = path.slice(parentPath.length + 1)\n return await HDWallet.createFromNode(this.node.derivePath(childPath))\n }\n throw new Error(`Invalid absolute path ${path} for wallet with path ${parentPath}`)\n }\n return await HDWallet.createFromNode(this.node.derivePath(path))\n }\n\n neuter: () => HDWallet = () => {\n this.node.neuter()\n return this\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/wallet",
3
- "version": "4.3.0",
3
+ "version": "5.0.1",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -28,25 +28,29 @@
28
28
  },
29
29
  "module": "dist/neutral/index.mjs",
30
30
  "types": "dist/neutral/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "src"
34
+ ],
31
35
  "dependencies": {
32
- "@scure/bip39": "^1.6.0",
33
- "@xylabs/arraybuffer": "^4.15.0",
34
- "@xylabs/assert": "^4.15.0",
35
- "@xylabs/base": "^4.15.0",
36
- "@xylabs/hex": "^4.15.0",
37
- "@xylabs/static-implements": "^4.15.0",
38
- "@xyo-network/account": "^4.3.0",
39
- "@xyo-network/account-model": "^4.3.0",
40
- "@xyo-network/key-model": "^4.3.0",
41
- "@xyo-network/wallet-model": "^4.3.0",
42
- "ethers": "^6.15.0"
36
+ "@scure/bip39": "~1.6.0",
37
+ "@xylabs/arraybuffer": "~5.0.3",
38
+ "@xylabs/assert": "~5.0.3",
39
+ "@xylabs/base": "~5.0.3",
40
+ "@xylabs/hex": "~5.0.3",
41
+ "@xylabs/static-implements": "~5.0.3",
42
+ "@xyo-network/account": "~5.0.1",
43
+ "@xyo-network/account-model": "~5.0.1",
44
+ "@xyo-network/key-model": "~5.0.1",
45
+ "@xyo-network/wallet-model": "~5.0.1",
46
+ "ethers": "~6.15.0"
43
47
  },
44
48
  "devDependencies": {
45
- "@xylabs/ts-scripts-yarn3": "^7.0.1",
46
- "@xylabs/tsconfig": "^7.0.1",
47
- "@xylabs/vitest-matchers": "^4.15.0",
48
- "typescript": "^5.8.3",
49
- "vitest": "^3.2.4"
49
+ "@xylabs/ts-scripts-yarn3": "~7.1.0",
50
+ "@xylabs/tsconfig": "~7.1.0",
51
+ "@xylabs/vitest-matchers": "~5.0.3",
52
+ "typescript": "~5.9.2",
53
+ "vitest": "~3.2.4"
50
54
  },
51
55
  "publishConfig": {
52
56
  "access": "public"
package/src/HDWallet.ts CHANGED
@@ -25,12 +25,15 @@ export class HDWallet extends Account implements WalletInstance {
25
25
  static override readonly uniqueName = globallyUnique('HDWallet', HDWallet, 'xyo')
26
26
  protected static override _addressMap: Record<Address, WeakRef<WalletInstance>> = {}
27
27
 
28
+ protected readonly node: HDNodeWallet
29
+
28
30
  constructor(
29
- key: unknown,
30
- protected readonly node: HDNodeWallet,
31
+ key: symbol,
32
+ node: HDNodeWallet,
31
33
  privateKey: PrivateKeyInstance,
32
34
  ) {
33
- super(Account._protectedConstructorKey, privateKey)
35
+ super(key, privateKey)
36
+ this.node = node
34
37
  }
35
38
 
36
39
  override get address(): Address {
@@ -0,0 +1,17 @@
1
+ import { Account } from '@xyo-network/account'
2
+ import {
3
+ describe, expect, it,
4
+ } from 'vitest'
5
+
6
+ import { HDWallet } from '../HDWallet.ts'
7
+
8
+ describe('Address', () => {
9
+ it('should round trip from BigInt', async () => {
10
+ for (let index = 0; index < 100; index++) {
11
+ const foo = await HDWallet.random()
12
+ const privateKey = BigInt(foo.privateKey)
13
+ const sharedAccount = await Account.fromPrivateKey(privateKey)
14
+ expect(sharedAccount).toBeDefined()
15
+ }
16
+ })
17
+ })
@@ -0,0 +1,20 @@
1
+ import {
2
+ describe, expect, it,
3
+ } from 'vitest'
4
+
5
+ // import { HDWallet } from '../../HDWallet'
6
+ // import { generateHDWalletTests } from './HDWallet.spec'
7
+
8
+ /**
9
+ * @group jsdom
10
+ */
11
+ /* describe.skip('Node Wallet Test', () => {
12
+ generateHDWalletTests('HDWallet: Browser', HDWallet)
13
+ })
14
+ */
15
+
16
+ describe('Node Wallet Test - Commented Out', () => {
17
+ it('Stub', () => {
18
+ expect(true).toBe(true)
19
+ })
20
+ })
@@ -0,0 +1,11 @@
1
+ import { describe } from 'vitest'
2
+
3
+ import { HDWallet } from '../../HDWallet.ts'
4
+ import { generateHDWalletTests } from './HDWallet.spec.ts'
5
+
6
+ /**
7
+ * @group nodejs
8
+ */
9
+ describe('Node Wallet Test', () => {
10
+ generateHDWalletTests('HDWallet: Node', HDWallet)
11
+ })
@@ -0,0 +1,228 @@
1
+ import type { Address, Hex } from '@xylabs/hex'
2
+ import { isAddress } from '@xylabs/hex'
3
+ import { matchers } from '@xylabs/vitest-matchers'
4
+ import type { WalletInstance, WalletStatic } from '@xyo-network/wallet-model'
5
+ import {
6
+ defaultPath, Mnemonic, SigningKey,
7
+ } from 'ethers'
8
+ import {
9
+ describe, expect, it,
10
+ test,
11
+ } from 'vitest'
12
+
13
+ expect.extend(matchers)
14
+
15
+ import { HDWallet } from '../../HDWallet.ts'
16
+
17
+ /**
18
+ * The wallet types that can be tested
19
+ */
20
+ type Wallet = HDWallet | WalletInstance
21
+
22
+ /**
23
+ * The serializable information of a wallet
24
+ */
25
+ interface WalletSnapshot {
26
+ address: Address
27
+ path: string | null
28
+ privateKey: Hex
29
+ publicKey: Hex
30
+ }
31
+
32
+ /**
33
+ * Converts a compressed public key to an uncompressed public key
34
+ * @param compressed The compressed public key
35
+ * @returns The uncompressed public key
36
+ */
37
+ const toUncompressedPublicKey = (compressed: string): string => SigningKey.computePublicKey(compressed, false).toLowerCase().replace('0x04', '')
38
+
39
+ /**
40
+ * Standardizes the representation of a hex string
41
+ * @param unformatted The unformatted hex string
42
+ * @returns The formatted hex string
43
+ */
44
+ const formatHexString = (unformatted: string): string => unformatted.toLowerCase().replace('0x', '')
45
+
46
+ /**
47
+ * Serializes a wallet to its snapshot representation
48
+ * @param wallet The wallet to snapshot
49
+ * @returns The snapshot representation of the wallet
50
+ */
51
+ const toWalletSnapshot = (wallet: Wallet): WalletSnapshot => {
52
+ const {
53
+ address, path, privateKey, publicKey,
54
+ } = wallet as WalletInstance
55
+ return {
56
+ address, path, privateKey, publicKey,
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Snapshots the instances of two wallets to ensure repeatability
62
+ * of creation from the same source and prevent unintentional changes
63
+ * to the wallet protocol
64
+ * @param walletA The first wallet to snapshot
65
+ * @param walletB The second wallet to snapshot
66
+ */
67
+ const snapshotWalletInstances = (walletA: Wallet, walletB: Wallet) => {
68
+ expect(toWalletSnapshot(walletA)).toMatchSnapshot()
69
+ expect([toWalletSnapshot(walletA), toWalletSnapshot(walletB)]).toMatchSnapshot()
70
+ }
71
+
72
+ /**
73
+ * Compares two wallets to ensure their public/private keys are equal
74
+ * @param sutA The first wallet to compare
75
+ * @param sutB The second wallet to compare
76
+ */
77
+ const expectWalletsEqual = (sutA: WalletInstance, sutB: Wallet) => {
78
+ expect(sutA.address).toEqual(formatHexString(sutB.address))
79
+ expect(sutA.privateKey).toEqual(sutB.privateKey)
80
+ expect(sutA.private?.hex).toEqual(formatHexString(sutB.privateKey))
81
+ expect(sutA.publicKey).toEqual(sutB.publicKey)
82
+ expect(sutA.public?.hex).toEqual(toUncompressedPublicKey(sutB.publicKey))
83
+ }
84
+
85
+ /**
86
+ * Compares two wallets to ensure their public/private keys and paths are equal
87
+ * @param sutA The first wallet to compare
88
+ * @param sutB The second wallet to compare
89
+ */
90
+ const expectWalletsAndPathsEqual = (sutA: WalletInstance, sutB: Wallet) => {
91
+ expectWalletsEqual(sutA, sutB)
92
+ expect(sutA.path).toEqual(sutB.path)
93
+ }
94
+
95
+ /**
96
+ * Generates tests for a wallet type
97
+ * @param title The title of the test suite
98
+ * @param HDWallet The wallet type to test
99
+ */
100
+ export const generateHDWalletTests = (title: string, HDWallet: WalletStatic) => {
101
+ describe(title, () => {
102
+ const phrase = 'later puppy sound rebuild rebuild noise ozone amazing hope broccoli crystal grief'
103
+ const paths = ['0/4', "44'/0'/0'", "44'/60'/0'/0/0", "44'/60'/0'/0/1", "49'/0'/0'", "84'/0'/0'", "84'/0'/0'/0"]
104
+
105
+ describe('constructor', () => {
106
+ it('can be created from mnemonic', async () => {
107
+ const sut = await HDWallet.fromPhrase(phrase)
108
+ console.log('address', sut.address)
109
+ console.log('privateKeyX', sut.privateKey)
110
+ const mnemonic = Mnemonic.fromPhrase(phrase)
111
+ console.log('mnemonic.entropy', mnemonic.entropy)
112
+ expect(isAddress(sut.address)).toBe(true)
113
+ expect(sut).toBeDefined()
114
+ })
115
+ it.each(paths)('works repeatably & interoperably with Ethers', async (path: string) => {
116
+ const sutA = await HDWallet.fromPhrase(phrase)
117
+ const sutB = await HDWallet.fromMnemonic(Mnemonic.fromPhrase(phrase))
118
+ expectWalletsAndPathsEqual(sutA, sutB)
119
+ snapshotWalletInstances(sutA, sutB)
120
+ const accountA = await sutA.derivePath(path)
121
+ const accountB = await sutB.derivePath(path)
122
+ expectWalletsAndPathsEqual(accountA, accountB)
123
+ snapshotWalletInstances(accountA, accountB)
124
+ })
125
+ })
126
+ describe('derivePath', () => {
127
+ it.each(paths)('works repeatably & interoperably from phrase & extended key', async (path: string) => {
128
+ const sutA = await HDWallet.fromPhrase(phrase)
129
+ const sutB = await HDWallet.fromExtendedKey(sutA.extendedKey)
130
+ expectWalletsEqual(sutA, sutB)
131
+ expect(sutA.path).not.toBeNull()
132
+ expect(sutB.path).not.toBeNull()
133
+ snapshotWalletInstances(sutA, sutB)
134
+ const accountA = await sutA.derivePath?.(path)
135
+ const accountB = await sutB.derivePath?.(path)
136
+ expectWalletsEqual(accountA, accountB)
137
+ expect(accountA.path).not.toBeNull()
138
+ expect(accountB.path).not.toBeNull()
139
+ snapshotWalletInstances(accountA, accountB)
140
+ })
141
+
142
+ it('works when paths provided incrementally', async () => {
143
+ const parentRelativePath = "44'/60'/0'"
144
+ const childRelativePath = '0/1'
145
+ const sutA = await HDWallet.fromPhrase(phrase)
146
+ const sutB = await HDWallet.fromPhrase(phrase)
147
+ expectWalletsAndPathsEqual(sutA, sutB)
148
+ snapshotWalletInstances(sutA, sutB)
149
+ const accountA = await (await sutA.derivePath(parentRelativePath)).derivePath?.(childRelativePath)
150
+ const accountB = await sutB.derivePath?.([parentRelativePath, childRelativePath].join('/'))
151
+ expectWalletsAndPathsEqual(accountA, accountB)
152
+ snapshotWalletInstances(accountA, accountB)
153
+ })
154
+ it('works when paths provided absolutely', async () => {
155
+ const parentAbsolutePath = "m/44'/60'/0'"
156
+ const childRelativePath = '0/1'
157
+ const absolutePath = [parentAbsolutePath, childRelativePath].join('/')
158
+ const sutA = await HDWallet.fromPhrase(phrase, absolutePath)
159
+ const sutB = await HDWallet.fromPhrase(phrase, parentAbsolutePath)
160
+ expect(sutA.path).toEqual(absolutePath)
161
+ expect(sutB.path).toEqual(parentAbsolutePath)
162
+ // Skip intermediate snapshot since wallets currently have different paths
163
+ // snapshotWalletInstances(sutA, sutB)
164
+ const accountA = sutA
165
+ const accountB = await sutB.derivePath(childRelativePath)
166
+ expectWalletsAndPathsEqual(accountA, accountB)
167
+ // accountA and accountB should be the same instance
168
+ // expect(accountA).toBe(accountB)
169
+ snapshotWalletInstances(accountA, accountB)
170
+ })
171
+ it('returns cached instances on subsequent requests', async () => {
172
+ const parent = "44'/60'/0'"
173
+ const child = '0/1'
174
+ const sutA = await HDWallet.fromPhrase(phrase)
175
+ const sutB = await HDWallet.fromPhrase(phrase)
176
+ expectWalletsAndPathsEqual(sutA, sutB)
177
+ // sutA and sutB should be the same instance
178
+ expect(sutA).toBe(sutB)
179
+ const accountA = await (await sutA.derivePath(parent)).derivePath?.(child)
180
+ const accountB = await sutB.derivePath?.([parent, child].join('/'))
181
+ expectWalletsAndPathsEqual(accountA, accountB)
182
+ // accountA and accountB should be the same instance
183
+ // expect(accountA).toBe(accountB)
184
+ snapshotWalletInstances(accountA, accountB)
185
+ })
186
+ })
187
+ })
188
+ }
189
+
190
+ test('HDWallet tests generator is defined', () => {
191
+ expect(typeof generateHDWalletTests).toBe('function')
192
+ })
193
+
194
+ test('Same address, two paths', async () => {
195
+ const sut = await HDWallet.fromMnemonic(Mnemonic.fromPhrase('later puppy sound rebuild rebuild noise ozone amazing hope broccoli crystal grief'))
196
+ const accountNode = await sut.derivePath('0')
197
+ expect(accountNode.path).toBe(`${defaultPath}/0`)
198
+ const accountA = await sut.derivePath('0/2')
199
+ const accountB = await accountNode.derivePath('2')
200
+ const accountAPrime = await accountNode.derivePath("0'/2")
201
+ const accountAPrime2 = await accountNode.derivePath("0/2'")
202
+ expect(accountA.address).toEqual(accountB.address)
203
+ expect(accountNode.address === accountB.address).toBe(false)
204
+ expect(accountA.address === accountAPrime.address).toBe(false)
205
+ expect(accountA.address === accountAPrime2.address).toBe(false)
206
+
207
+ expect(accountNode.address).toMatchSnapshot()
208
+ expect(accountA.address).toMatchSnapshot()
209
+ expect(accountB.address).toMatchSnapshot()
210
+ expect(accountAPrime.address).toMatchSnapshot()
211
+ })
212
+
213
+ test('Random Wallet', async () => {
214
+ const sut = await HDWallet.random()
215
+ expect(sut).toBeDefined()
216
+ expect(sut.address).toBeDefined()
217
+ expect(sut.privateKey).toBeDefined()
218
+ expect(sut.publicKey).toBeDefined()
219
+ expect(sut.extendedKey).toBeDefined()
220
+ expect(sut.path).toBeDefined()
221
+ expect(sut.path).toBe(defaultPath)
222
+ })
223
+
224
+ test('HDWallet can be created from mnemonic', async () => {
225
+ const sut = await HDWallet.fromPhrase('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', "m/44'/0'/0'/0/0")
226
+ expect(sut).toBeDefined()
227
+ console.log('privateKey', sut.privateKey)
228
+ })