2121 /* dotenv not installed */
2222}
2323
24+ /** @typedef {import('@dashevo/evo-sdk').Identity } Identity */
25+ /** @typedef {import('@dashevo/evo-sdk').IdentityPublicKey } IdentityPublicKey */
26+ /** @typedef {import('@dashevo/evo-sdk').PlatformAddress } PlatformAddress */
27+ /** @typedef {import('@dashevo/evo-sdk').PlatformAddressInfo } PlatformAddressInfo */
28+ /** @typedef {import('@dashevo/evo-sdk').NetworkLike } NetworkLike */
29+
30+ /**
31+ * @typedef {Object } DerivedKeyEntry
32+ * @property {number } keyId
33+ * @property {string } privateKeyWif
34+ * @property {string } [publicKey] - Only present via createForNewIdentity()
35+ */
36+
37+ /**
38+ * @typedef {Object } AddressEntry
39+ * @property {PlatformAddress } address
40+ * @property {string } bech32m
41+ * @property {string } privateKeyWif
42+ * @property {string } path
43+ */
44+
2445// ⚠️ Tutorial helper — holds WIFs in memory for convenience.
2546// Do not use this pattern as-is for production key management.
2647
@@ -44,6 +65,10 @@ const clientConfig = {
4465 * Build a DIP-13 identity key derivation path.
4566 * Returns the full 7-level hardened path:
4667 * m/9'/{coin}'/5'/0'/0'/{identityIndex}'/{keyIndex}'
68+ * @param {string } network
69+ * @param {number } identityIndex
70+ * @param {number } keyIndex
71+ * @returns {Promise<string> }
4772 */
4873export async function dip13KeyPath ( network , identityIndex , keyIndex ) {
4974 const base =
@@ -57,12 +82,18 @@ export async function dip13KeyPath(network, identityIndex, keyIndex) {
5782// SDK client helpers
5883// ---------------------------------------------------------------------------
5984
85+ /**
86+ * Create and connect an EvoSDK client for the selected network.
87+ *
88+ * @param {string } [network='testnet']
89+ * @returns {Promise<EvoSDK> }
90+ */
6091export async function createClient ( network = 'testnet' ) {
61- const factories = {
92+ const factories = /** @type { Record<string, () => EvoSDK> } */ ( {
6293 testnet : ( ) => EvoSDK . testnetTrusted ( ) ,
6394 mainnet : ( ) => EvoSDK . mainnetTrusted ( ) ,
6495 local : ( ) => EvoSDK . localTrusted ( ) ,
65- } ;
96+ } ) ;
6697
6798 const factory = factories [ network ] ;
6899 if ( ! factory ) {
@@ -71,7 +102,7 @@ export async function createClient(network = 'testnet') {
71102 ) ;
72103 }
73104
74- const sdk = factory ( ) ;
105+ const sdk = /** @type { EvoSDK } */ ( factory ( ) ) ;
75106 await sdk . connect ( ) ;
76107 return sdk ;
77108}
@@ -125,6 +156,12 @@ const KEY_SPECS = [
125156 * Key 4 = ENCRYPTION MEDIUM (encrypted messaging/data)
126157 */
127158class IdentityKeyManager {
159+ /**
160+ * @param {EvoSDK } sdk
161+ * @param {string|null|undefined } identityId
162+ * @param {Record<string, DerivedKeyEntry> } keys
163+ * @param {number } identityIndex
164+ */
128165 constructor ( sdk , identityId , keys , identityIndex ) {
129166 this . sdk = sdk ;
130167 this . id = identityId ;
@@ -141,12 +178,13 @@ class IdentityKeyManager {
141178 * Derives all standard identity keys using DIP-9 paths.
142179 *
143180 * @param {object } opts
144- * @param {object } opts.sdk - Connected EvoSDK instance
181+ * @param {EvoSDK } opts.sdk - Connected EvoSDK instance
145182 * @param {string } [opts.identityId] - Identity ID. If omitted, auto-resolved
146183 * from the mnemonic by looking up the master key's public key hash on-chain.
147184 * @param {string } opts.mnemonic - BIP39 mnemonic
148185 * @param {string } [opts.network='testnet'] - 'testnet' or 'mainnet'
149186 * @param {number } [opts.identityIndex=0] - Which identity derived from this mnemonic
187+ * @returns {Promise<IdentityKeyManager> }
150188 */
151189 static async create ( {
152190 sdk,
@@ -155,7 +193,7 @@ class IdentityKeyManager {
155193 network = 'testnet' ,
156194 identityIndex = 0 ,
157195 } ) {
158- const derive = async ( keyIndex ) =>
196+ const derive = async ( /** @type { number } */ keyIndex ) =>
159197 wallet . deriveKeyFromSeedWithPath ( {
160198 mnemonic,
161199 path : await dip13KeyPath ( network , identityIndex , keyIndex ) ,
@@ -211,7 +249,7 @@ class IdentityKeyManager {
211249 * Find the first unused DIP-9 identity index for a mnemonic.
212250 * Scans indices starting at 0 until no on-chain identity is found.
213251 *
214- * @param {object } sdk - Connected EvoSDK instance
252+ * @param {EvoSDK } sdk - Connected EvoSDK instance
215253 * @param {string } mnemonic - BIP39 mnemonic
216254 * @param {string } [network='testnet'] - 'testnet' or 'mainnet'
217255 * @returns {Promise<number> } The first unused identity index
@@ -240,7 +278,7 @@ class IdentityKeyManager {
240278 * If identityIndex is omitted, auto-selects the next unused index.
241279 *
242280 * @param {object } opts
243- * @param {object } opts.sdk - Connected EvoSDK instance
281+ * @param {EvoSDK } opts.sdk - Connected EvoSDK instance
244282 * @param {string } opts.mnemonic - BIP39 mnemonic
245283 * @param {string } [opts.network='testnet'] - 'testnet' or 'mainnet'
246284 * @param {number } [opts.identityIndex] - Identity index (auto-scanned if omitted)
@@ -255,7 +293,7 @@ class IdentityKeyManager {
255293 const idx =
256294 identityIndex ??
257295 ( await IdentityKeyManager . findNextIndex ( sdk , mnemonic , network ) ) ;
258- const derive = async ( keyIndex ) =>
296+ const derive = async ( /** @type { number } */ keyIndex ) =>
259297 wallet . deriveKeyFromSeedWithPath ( {
260298 mnemonic,
261299 path : await dip13KeyPath ( network , idx , keyIndex ) ,
@@ -339,7 +377,7 @@ class IdentityKeyManager {
339377 /**
340378 * Fetch identity and build { identity, identityKey, signer } for a given key.
341379 * @param {string } keyName - One of: master, auth, authHigh, transfer, encryption
342- * @returns {{ identity, identityKey, signer } }
380+ * @returns {Promise< { identity: Identity , identityKey: IdentityPublicKey | undefined , signer: IdentitySigner }> }
343381 */
344382 async getSigner ( keyName ) {
345383 if ( ! this . id ) {
@@ -348,42 +386,60 @@ class IdentityKeyManager {
348386 'or create/register the identity first and then set the ID.' ,
349387 ) ;
350388 }
351- const key = this . keys [ keyName ] ;
389+ const key = /** @type {Record<string, DerivedKeyEntry> } */ ( this . keys ) [
390+ keyName
391+ ] ;
352392 if ( ! key ) {
353393 throw new Error (
354394 `Unknown key "${ keyName } ". Use: ${ Object . keys ( this . keys ) . join ( ', ' ) } ` ,
355395 ) ;
356396 }
357397 const identity = await this . sdk . identities . fetch ( this . id ) ;
398+ if ( ! identity ) {
399+ throw new Error ( `Identity "${ this . id } " not found on-chain.` ) ;
400+ }
358401 const identityKey = identity . getPublicKeyById ( key . keyId ) ;
359402 const signer = new IdentitySigner ( ) ;
360403 signer . addKeyFromWif ( key . privateKeyWif ) ;
361404 return { identity, identityKey, signer } ;
362405 }
363406
364- /** CRITICAL auth (key 2) — contracts, documents, names. */
407+ /**
408+ * CRITICAL auth (key 2) — contracts, documents, names.
409+ * @returns {Promise<{ identity: Identity, identityKey: IdentityPublicKey | undefined, signer: IdentitySigner }> }
410+ */
365411 async getAuth ( ) {
366412 return this . getSigner ( 'auth' ) ;
367413 }
368414
369- /** HIGH auth (key 1) — documents, names. */
415+ /**
416+ * HIGH auth (key 1) — documents, names.
417+ * @returns {Promise<{ identity: Identity, identityKey: IdentityPublicKey | undefined, signer: IdentitySigner }> }
418+ */
370419 async getAuthHigh ( ) {
371420 return this . getSigner ( 'authHigh' ) ;
372421 }
373422
374- /** TRANSFER — credit transfers, withdrawals. */
423+ /**
424+ * TRANSFER — credit transfers, withdrawals.
425+ * @returns {Promise<{ identity: Identity, identityKey: IdentityPublicKey | undefined, signer: IdentitySigner }> }
426+ */
375427 async getTransfer ( ) {
376428 return this . getSigner ( 'transfer' ) ;
377429 }
378430
379- /** ENCRYPTION MEDIUM — encrypted messaging/data. */
431+ /**
432+ * ENCRYPTION MEDIUM — encrypted messaging/data.
433+ * @returns {Promise<{ identity: Identity, identityKey: IdentityPublicKey | undefined, signer: IdentitySigner }> }
434+ */
380435 async getEncryption ( ) {
381436 return this . getSigner ( 'encryption' ) ;
382437 }
383438
384439 /**
385440 * MASTER — identity updates (add/disable keys).
386441 * @param {string[] } [additionalKeyWifs] - WIFs for new keys being added
442+ * @returns {Promise<{ identity: Identity, identityKey: IdentityPublicKey | undefined, signer: IdentitySigner }> }
387443 */
388444 async getMaster ( additionalKeyWifs ) {
389445 const result = await this . getSigner ( 'master' ) ;
@@ -409,6 +465,11 @@ class IdentityKeyManager {
409465 * that hold credits directly, independent of identities.
410466 */
411467class AddressKeyManager {
468+ /**
469+ * @param {EvoSDK } sdk
470+ * @param {AddressEntry[] } addresses
471+ * @param {string } network
472+ */
412473 constructor ( sdk , addresses , network ) {
413474 this . sdk = sdk ;
414475 this . addresses = addresses ; // [{ address, bech32m, privateKeyWif, path }]
@@ -425,10 +486,11 @@ class AddressKeyManager {
425486 * Derives platform address keys using BIP44 paths.
426487 *
427488 * @param {object } opts
428- * @param {object } opts.sdk - Connected EvoSDK instance
489+ * @param {EvoSDK } opts.sdk - Connected EvoSDK instance
429490 * @param {string } opts.mnemonic - BIP39 mnemonic
430491 * @param {string } [opts.network='testnet'] - 'testnet' or 'mainnet'
431492 * @param {number } [opts.count=1] - Number of addresses to derive
493+ * @returns {Promise<AddressKeyManager> }
432494 */
433495 static async create ( { sdk, mnemonic, network = 'testnet' , count = 1 } ) {
434496 const addresses = [ ] ;
@@ -452,7 +514,9 @@ class AddressKeyManager {
452514
453515 addresses . push ( {
454516 address : platformAddress ,
455- bech32m : platformAddress . toBech32m ( network ) ,
517+ bech32m : platformAddress . toBech32m (
518+ /** @type {NetworkLike } */ ( network ) ,
519+ ) ,
456520 privateKeyWif : obj . privateKeyWif ,
457521 path,
458522 } ) ;
@@ -488,7 +552,7 @@ class AddressKeyManager {
488552
489553 /**
490554 * Fetch current balance and nonce for the primary address.
491- * @returns {Promise<PlatformAddressInfo| undefined> }
555+ * @returns {Promise<PlatformAddressInfo | undefined> }
492556 */
493557 async getInfo ( ) {
494558 return this . sdk . addresses . get ( this . primaryAddress . bech32m ) ;
@@ -497,7 +561,7 @@ class AddressKeyManager {
497561 /**
498562 * Fetch current balance and nonce for an address by index.
499563 * @param {number } index - Address index
500- * @returns {Promise<PlatformAddressInfo| undefined> }
564+ * @returns {Promise<PlatformAddressInfo | undefined> }
501565 */
502566 async getInfoAt ( index ) {
503567 const entry = this . addresses [ index ] ;
@@ -514,9 +578,13 @@ class AddressKeyManager {
514578// setupDashClient — convenience wrapper
515579// ---------------------------------------------------------------------------
516580
581+ /**
582+ * @param {{requireIdentity?: boolean, identityIndex?: number} } opts
583+ * @returns {Promise<{ sdk: EvoSDK, keyManager: IdentityKeyManager | undefined, addressKeyManager: AddressKeyManager | undefined }> }
584+ */
517585export async function setupDashClient ( {
518586 requireIdentity = true ,
519- identityIndex,
587+ identityIndex = undefined ,
520588} = { } ) {
521589 const { network, mnemonic } = clientConfig ;
522590
0 commit comments