From: Chris Duncan Date: Thu, 17 Jul 2025 15:46:08 +0000 (-0700) Subject: Start migrating to bespoke type definition file. X-Git-Tag: v0.10.5~56^2~15 X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=b604edde9903287ca7b13bbebf8aceabf32055d4;p=libnemo.git Start migrating to bespoke type definition file. --- diff --git a/esbuild-common.mjs b/esbuild-common.mjs index 8f9592d..7cb5919 100644 --- a/esbuild-common.mjs +++ b/esbuild-common.mjs @@ -7,8 +7,12 @@ export const options = { bundle: true, entryPoints: [ - { in: './src/main.ts', out: 'main.min' } + { in: './src/main.ts', out: 'main.min' }, + { in: './src/types.d.ts', out: 'types.d' } ], + loader: { + '.d.ts': 'copy' + }, inject: ['./buffer.mjs'], format: 'esm', legalComments: 'inline', diff --git a/package.json b/package.json index 64b2445..a972b4c 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "type": "module", "exports": { ".": { - "types": "./dist/types/main.d.ts", + "types": "./dist/types.d.ts", "default": "./dist/main.min.js" } }, diff --git a/src/lib/account.ts b/src/lib/account.ts index 9d571cc..3f7c4a8 100644 --- a/src/lib/account.ts +++ b/src/lib/account.ts @@ -77,7 +77,6 @@ export class Account { this.#weight = undefined } - /** * Instantiates an Account object from its Nano address. * diff --git a/src/lib/rolodex.ts b/src/lib/rolodex.ts index 28a800a..2d1a886 100644 --- a/src/lib/rolodex.ts +++ b/src/lib/rolodex.ts @@ -2,12 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import { Account } from './account' - - -export type RolodexEntry = { - name: string - account: Account -} +import { RolodexEntry } from '#types' /** * Represents a basic address book of Nano accounts. Multiple addresses can be diff --git a/src/types.d.ts b/src/types.d.ts index 81217c2..81fe2f0 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,6 +1,296 @@ // SPDX-FileCopyrightText: 2025 Chris Duncan // SPDX-License-Identifier: GPL-3.0-or-later +/** +* Represents a single Nano address and the associated public key. To include the +* matching private key, it must be known at the time of object instantiation. +* The frontier, balance, and representative for the account can also be set or +* be fetched from the network. +*/ +export declare class Account { + get address (): string + get publicKey (): string + get balance (): bigint | undefined + get frontier (): string | undefined + get receivable (): bigint | undefined + get representative (): Account | undefined + get weight (): bigint | undefined + set balance (v: bigint | undefined) + set frontier (v: string | undefined) + set receivable (v: bigint | undefined) + set representative (v: Account | undefined) + set weight (v: bigint | undefined) + private constructor () + /** + * Removes encrypted secrets in storage and releases variable references to + * allow garbage collection. + */ + destroy (): Promise + /** + * Instantiates an Account object from its Nano address. + * + * @param {string} addresses - Address of the account + * @returns {Account} The instantiated Account object + */ + static import (address: string): Account + /** + * Instantiates Account objects from their Nano addresses. + * + * @param {string[]} addresses - Addresses of the accounts + * @returns {Account[]} The instantiated Account objects + */ + static import (addresses: string[]): Account[] + /** + * Instantiates an Account object from its public key. It is unable to sign + * blocks or messages since it has no private key. + * + * @param {string} publicKey - Public key of the account + * @returns {Account} The instantiated Account object + */ + static import (publicKey: string): Account + /** + * Instantiates an Account object from its public key. It is unable to sign + * blocks or messages since it has no private key. + * + * @param {Uint8Array} publicKey - Public key of the account + * @returns {Account} The instantiated Account object + */ + static import (publicKey: Uint8Array): Account + /** + * Instantiates Account objects from their public keys. They are unable to sign + * blocks or messages since they have no private key. + * + * @param {string[]} publicKeys - Public keys of the accounts + * @returns {Account[]} The instantiated Account objects + */ + static import (publicKeys: string[]): Account[] + /** + * Instantiates Account objects from their public keys. They are unable to sign + * blocks or messages since they have no private key. + * + * @param {Uint8Array[]} publicKeys - Public keys of the accounts + * @returns {Account[]} The instantiated Account objects + */ + static import (publicKeys: Uint8Array[]): Account[] + /** + * Instantiates an Account object from its private key which is then encrypted + * and stored in IndexedDB. The corresponding public key will automatically be + * derived and saved. + * + * @param {string} privateKey - Private key of the account + * @param {(string|Uint8Array)} password - Used to encrypt the private key + * @returns {Account} A new Account object + */ + static import (privateKey: string, password: string | Uint8Array): Promise + /** + * Instantiates an Account object from its private key which is then encrypted + * and stored in IndexedDB. The corresponding public key will automatically be + * derived and saved. + * + * @param {Uint8Array} privateKey - Private key of the account + * @param {(string|Uint8Array)} password - Used to encrypt the private key + * @returns {Account} A new Account object + */ + static import (privateKey: Uint8Array, password: string | Uint8Array): Promise + /** + * Instantiates Account objects from their private keys which are then + * encrypted and stored in IndexedDB. The corresponding public keys will + * automatically be derived and saved. + * + * @param {string[]} privateKeys - Private keys of the account + * @param {(string|Uint8Array)} password - Used to encrypt the private keys + * @returns {Account[]} The instantiated Account objects + */ + static import (privateKeys: string[], password: string | Uint8Array): Promise + /** + * Instantiates Account objects from their private keys which are then + * encrypted and stored in IndexedDB. The corresponding public keys will + * automatically be derived and saved. + * + * @param {Uint8Array[]} privateKeys - Private keys of the account + * @param {(string|Uint8Array)} password - Used to encrypt the private keys + * @returns {Account[]} The instantiated Account objects + */ + static import (privateKeys: Uint8Array[], password: string | Uint8Array): Promise + /** + * Refreshes the account from its current state on the network. + * + * A successful response sets the balance, frontier, and representative + * properties. + * + * @param {Rpc|string|URL} rpc - RPC node information required to call `account_info` + */ + refresh (rpc: Rpc | string | URL): Promise + /** + * Signs a block using the private key of the account. The signature is + * appended to the signature field of the block before being returned. + * + * @param {(string|Uint8Array)} password - Required to decrypt the private key for signing + * @param {(ChangeBlock|ReceiveBlock|SendBlock)} block - The block data to be hashed and signed + * @returns {Promise} Hexadecimal-formatted 64-byte signature + */ + sign (block: ChangeBlock | ReceiveBlock | SendBlock, password: string | Uint8Array): Promise + /** + * Retrieves and decryptes the private key of the Account. The same password + * used to lock it must be used to unlock it. + * + * @param {(string|Uint8Array)} password Used previously to lock the Account + * @returns Private key bytes as a Uint8Array + */ + exportPrivateKey (password: string | Uint8Array): Promise> + /** + * Retrieves and decryptes the private key of the Account. The same password + * used to lock it must be used to unlock it. + * + * @param {(string|Uint8Array)} password Used previously to lock the Account + * @returns Private key bytes as a hexadecimal string + */ + exportPrivateKey (password: string | Uint8Array, format: 'hex'): Promise + /** + * Validates a Nano address with 'nano' and 'xrb' prefixes + * Derived from https://github.com/alecrios/nano-address-validator + * + * @param {string} address - Nano address to validate + * @throws Error if address is undefined, not a string, or an invalid format + */ + static validate (address: unknown): asserts address is string +} + +/** +* Represents a block as defined by the Nano cryptocurrency protocol. The Block +* class is abstract and cannot be directly instantiated. Every block must be one +* of three derived classes: SendBlock, ReceiveBlock, ChangeBlock. +*/ +declare abstract class Block { + account: Account + type: 'state' + abstract subtype: 'send' | 'receive' | 'change' + abstract previous: string + abstract representative: Account + abstract balance: bigint + abstract link: string + abstract signature?: string + abstract work?: string + constructor (account: Account | string) + /** + * Calculates the block hash using Blake2b. + * + * @returns {Promise} Block data hashed to a byte array + */ + get hash (): string + /** + * Converts the block to JSON format as expected by the `process` RPC. + * + * @returns {string} JSON representation of the block + */ + toJSON (): { + [key: string]: string + } + /** + * Calculates proof-of-work using a pool of Web Workers. + * + * A successful response sets the `work` property. + */ + pow (): Promise + /** + * Signs the block using a private key. If a key is not provided, the private + * key of the block's account will be used if it exists. If that fails, an + * error is thrown. + * + * If successful, the result is stored in the object's `signature` + * property. + * + * @param {string} [key] - Hexadecimal-formatted private key to use for signing + */ + sign (key?: string): Promise + /** + * Signs the block using a Ledger hardware wallet. If that fails, an error is + * thrown with the status code from the device. + * + * If successful, the result is stored in the object's `signature` + * property. + * + * @param {number} index - Account index between 0x0 and 0x7fffffff + * @param {object} [block] - JSON of previous block for offline signing + */ + sign (index?: number, block?: { + [key: string]: string + }): Promise + /** + * Sends the block to a node for processing on the network. + * + * The block must already be signed (see `sign()` for more information). + * The block must also have a `work` value. + * + * @param {Rpc|string|URL} rpc - RPC node information required to call `process` + * @returns {Promise} Hash of the processed block + */ + process (rpc: Rpc): Promise + /** + * Verifies the signature of the block. If a key is not provided, the public + * key of the block's account will be used if it exists. + * + * @param {string} [key] - Hexadecimal-formatted public key to use for verification + * @returns {boolean} True if block was signed by the matching private key + */ + verify (key?: string): Promise +} + +/** +* Represents a block that sends funds from one address to another as defined by +* the Nano cryptocurrency protocol. +*/ +export declare class SendBlock extends Block { + type: 'state' + subtype: 'send' + previous: string + representative: Account + balance: bigint + link: string + signature?: string + work?: string + constructor (sender: Account | string, balance: string, recipient: string, amount: string, representative: Account | string, frontier: string, work?: string) +} + +/** +* Represents a block that receives funds sent to one address from another as +* defined by the Nano cryptocurrency protocol. +*/ +export declare class ReceiveBlock extends Block { + type: 'state' + subtype: 'receive' + previous: string + representative: Account + balance: bigint + link: string + signature?: string + work?: string + constructor (recipient: Account | string, balance: string, origin: string, amount: string, representative: Account | string, frontier?: string, work?: string) +} + +/** +* Represents a block that changes the representative account to which the user +* account delegates their vote weight using the the Open Representative Voting +* specification as defined by the Nano cryptocurrency protocol. +*/ +export declare class ChangeBlock extends Block { + type: 'state' + subtype: 'change' + previous: string + representative: Account + balance: bigint + link: string + signature?: string + work?: string + constructor (account: Account | string, balance: string, representative: Account | string, frontier: string, work?: string) +} + +export declare class AccountList extends Object { + [index: number]: Account + get length (): number; + [Symbol.iterator] (): Iterator +} + export type Data = { [key: string]: ArrayBuffer } @@ -15,6 +305,31 @@ export type KeyPair = { index?: number } +export type RolodexEntry = { + name: string + account: Account +} + +/** +* Represents a Nano network node. It primarily consists of a URL which will +* accept RPC calls, and an optional API key header construction can be passed if +* required by the node. Once instantiated, the Rpc object can be used to call +* any action supported by the Nano protocol. The URL protocol must be HTTPS; any +* other value will be changed automatically. +*/ +export declare class Rpc { + constructor (url: string | URL, apiKeyName?: string) + /** + * + * @param {string} action - Nano protocol RPC call to execute + * @param {object} [data] - JSON to send to the node as defined by the action + * @returns {Promise} JSON-formatted RPC results from the node + */ + call (action: string, data?: { + [key: string]: any + }): Promise +} + export type SafeRecord = { iv: string salt: string