149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import {
|
|
type InputTemplateBCH,
|
|
type TransactionTemplate,
|
|
type WalletAddresses,
|
|
type WalletTransactions,
|
|
} from './types.js';
|
|
|
|
import { type BlockchainUTXOs } from '../blockchain';
|
|
import { type EventMap, EventEmitter } from '../utils';
|
|
|
|
import { type TokenBalances, type Address } from '@xocash/primitives';
|
|
|
|
/**
|
|
* Common interface for all wallet types.
|
|
*
|
|
* @remarks
|
|
*
|
|
* All function signatures are deliberately asynchronous to accommodate for cases where wallets might be remote.
|
|
* For example, we might eventually want to support a multisig service.
|
|
* Or we might have to support some other custodial "Apple Pay"-like OS-interface to get accepted onto their app store.
|
|
*/
|
|
export abstract class BaseWallet<
|
|
WalletEvents extends EventMap,
|
|
> extends EventEmitter<WalletEvents> {
|
|
/**
|
|
* Start monitoring this wallet for any transaction activity.
|
|
*/
|
|
abstract start(): Promise<void>;
|
|
|
|
/**
|
|
* Stop monitoring this wallet for any transaction activity.
|
|
*/
|
|
abstract stop(): Promise<void>;
|
|
|
|
/**
|
|
* Remove any event listeners from this wallet.
|
|
*/
|
|
abstract destroy(): Promise<void>;
|
|
|
|
/**
|
|
* Fetch all transactions from the blockchain involving this wallet.
|
|
*
|
|
* @remarks
|
|
*
|
|
* We will want to add a query argument so that workers can use this efficiently:
|
|
*
|
|
* ```ts
|
|
* {
|
|
* limit?: number;
|
|
* offset?: number;
|
|
* sort?: () => number;
|
|
* filter?: () => boolean;
|
|
* }
|
|
* ```
|
|
*
|
|
* This "query" argument should be turned into a generic type as we will want to re-use it for Activities.
|
|
*/
|
|
abstract getTransactions(): Promise<WalletTransactions>;
|
|
|
|
/**
|
|
* Fetch all unspents from the blockchain belonging to this wallet.
|
|
*/
|
|
abstract getUnspents(): Promise<BlockchainUTXOs>;
|
|
|
|
/**
|
|
* Fetch all unspents from the blockchain belonging to this wallet.
|
|
*
|
|
* @remarks
|
|
*
|
|
* I was considering removing this and just storing unspents as "UTXOSignable"s.
|
|
* But that might not be ideal if we want to have Watch-only wallets.
|
|
* A better approach might be to have Fetch Unspents return `Array<UTXO | UTXOSignable>`
|
|
* Still need to flesh that out.
|
|
*
|
|
* EDIT: We're going to want to store state for caching anyway...
|
|
* May as well just getUnspentDirectives() from the local state instead of fetch.
|
|
* Likewise for balances.
|
|
*/
|
|
abstract getUnspentDirectives(): Promise<Array<InputTemplateBCH>>;
|
|
|
|
/**
|
|
* Get the satoshi balance of this wallet.
|
|
*
|
|
* @remarks
|
|
*
|
|
* Consider confirmed/unconfirmed balances (or some other representation).
|
|
*
|
|
* This becomes important in some instances because services like BitPay require one confirmation.
|
|
* This'll also have bearing on how we define our UTXO Selection strategies.
|
|
*/
|
|
abstract getBalanceSats(): Promise<bigint>;
|
|
|
|
/**
|
|
* Get the token balance of this wallet.
|
|
*
|
|
* @remarks
|
|
*
|
|
* Consider confirmed/unconfirmed balances (or some other representation).
|
|
*
|
|
* This becomes important in some instances because services like BitPay require one confirmation.
|
|
* This'll also have bearing on how we define our UTXO Selection strategies.
|
|
*/
|
|
abstract getBalanceTokens(): Promise<TokenBalances>;
|
|
|
|
/**
|
|
* Get all addresses belonging to this wallet.
|
|
*/
|
|
abstract getAddresses(): Promise<WalletAddresses>;
|
|
|
|
/**
|
|
* Get the address that this wallet should receive to.
|
|
*/
|
|
abstract getReceivingAddress(): Promise<Address>;
|
|
|
|
/**
|
|
* Select UTXOs from this wallet to meet the amounts required.
|
|
*
|
|
* @remarks
|
|
*
|
|
* TODO: We are going to want to return the Transaction that was compiled.
|
|
*
|
|
* TODO: This should accept a second argument (probably function) that can filter/sory UTXOs.
|
|
* The intent here is to provide a "spending policy". E.g. Only use (or prioritise) UTXOs with 1-conf.
|
|
*/
|
|
abstract signTransaction(
|
|
template: Partial<TransactionTemplate>,
|
|
): Promise<Uint8Array>;
|
|
|
|
/**
|
|
* Select UTXOs from this wallet to meet the amounts required and broadcast it to the Blockchain.
|
|
*
|
|
* @remarks
|
|
*
|
|
* TODO: We are going to want to return the Transaction that was compiled.
|
|
*/
|
|
abstract sendTransaction(
|
|
template: Partial<TransactionTemplate>,
|
|
): Promise<void>;
|
|
|
|
// TODO: This should be a push-only list.
|
|
// Need to understand how Jason's pruning approach works.
|
|
// It might make more sense to "key" activities by type:
|
|
// This would allow us to filter more effectively each time a new activity is added.
|
|
// As it stands, we would have to collate the entire list if it's done by timestamp.
|
|
abstract addActivity<T>(activity: T): Promise<void>;
|
|
|
|
abstract export(): Promise<string>;
|
|
}
|