Files
monero_c/impls/monero.ts/src/wallet.ts
2025-01-16 09:37:11 +01:00

337 lines
9.7 KiB
TypeScript

import { WalletManager } from "./wallet_manager.ts";
import { C_SEPARATOR, CString, readCString, SEPARATOR } from "./utils.ts";
import { PendingTransaction, PendingTransactionPtr } from "./pending_transaction.ts";
import { UnsignedTransaction, UnsignedTransactionPtr } from "./unsigned_transaction.ts";
import { Coins, CoinsPtr } from "./coins.ts";
import { fns } from "./bindings.ts";
export type WalletPtr = Deno.PointerObject<"walletManager">;
interface DaemonInfo {
address?: string;
username?: string;
password?: string;
lightWallet?: boolean;
proxyAddress?: string;
}
export class Wallet {
#walletManager: WalletManager;
#ptr: WalletPtr;
constructor(walletManager: WalletManager, ptr: WalletPtr) {
this.#walletManager = walletManager;
this.#ptr = ptr;
}
getPointer() {
return this.#ptr;
}
async init(daemonInfo: DaemonInfo, log = false): Promise<boolean> {
const success = await fns.Wallet_init(
this.#ptr,
CString(daemonInfo.address ?? ""),
0n,
CString(daemonInfo.username ?? ""),
CString(daemonInfo.password ?? ""),
false,
daemonInfo.lightWallet ?? false,
CString(daemonInfo.proxyAddress ?? ""),
);
if (log) {
await fns.Wallet_init3(
this.#ptr,
CString(""),
CString(""),
CString(""),
true,
);
}
await this.setTrustedDaemon(true);
await this.startRefresh();
await this.refreshAsync();
return success;
}
async setTrustedDaemon(value: boolean): Promise<void> {
return await fns.Wallet_setTrustedDaemon(this.#ptr, value);
}
async startRefresh(): Promise<void> {
return await fns.Wallet_startRefresh(this.#ptr);
}
async refreshAsync(): Promise<void> {
return await fns.Wallet_refreshAsync(this.#ptr);
}
async setupBackgroundSync(
backgroundSyncType: number,
walletPassword: string,
backgroundCachePassword: string,
): Promise<boolean> {
return await fns.Wallet_setupBackgroundSync(
this.#ptr,
backgroundSyncType,
CString(walletPassword),
CString(backgroundCachePassword),
);
}
async startBackgroundSync(): Promise<boolean> {
return await fns.Wallet_startBackgroundSync(this.#ptr);
}
async stopBackgroundSync(walletPassword: string): Promise<boolean> {
return await fns.Wallet_stopBackgroundSync(this.#ptr, CString(walletPassword));
}
async store(path = ""): Promise<boolean> {
return await fns.Wallet_store(this.#ptr, CString(path));
}
async close(store: boolean): Promise<boolean> {
return await fns.WalletManager_closeWallet(this.#walletManager.getPointer(), this.#ptr, store);
}
async seed(offset = ""): Promise<string | null> {
return await readCString(
await fns.Wallet_seed(this.#ptr, CString(offset)),
);
}
async address(accountIndex = 0n, addressIndex = 0n): Promise<string | null> {
return await readCString(
await fns.Wallet_address(this.#ptr, accountIndex, addressIndex),
);
}
async setRefreshFromBlockHeight(height = 0n): Promise<void> {
return await fns.Wallet_setRefreshFromBlockHeight(this.#ptr, height);
}
async balance(accountIndex = 0): Promise<bigint> {
return await fns.Wallet_balance(this.#ptr, accountIndex);
}
async unlockedBalance(accountIndex = 0): Promise<bigint> {
return await fns.Wallet_unlockedBalance(this.#ptr, accountIndex);
}
async synchronized(): Promise<boolean> {
return await fns.Wallet_synchronized(this.#ptr);
}
async blockChainHeight(): Promise<bigint> {
return await fns.Wallet_blockChainHeight(this.#ptr);
}
async daemonBlockChainHeight(): Promise<bigint> {
return await fns.Wallet_daemonBlockChainHeight(this.#ptr);
}
async addSubaddressAccount(label: string): Promise<void> {
return await fns.Wallet_addSubaddressAccount(this.#ptr, CString(label));
}
async numSubaddressAccounts(): Promise<bigint> {
return await fns.Wallet_numSubaddressAccounts(this.#ptr);
}
async addSubaddress(accountIndex: number, label: string): Promise<void> {
return await fns.Wallet_addSubaddress(
this.#ptr,
accountIndex,
CString(label),
);
}
async numSubaddresses(accountIndex: number): Promise<bigint> {
return await fns.Wallet_numSubaddresses(
this.#ptr,
accountIndex,
);
}
async getSubaddressLabel(accountIndex: number, addressIndex: number): Promise<string | null> {
return await readCString(
await fns.Wallet_getSubaddressLabel(this.#ptr, accountIndex, addressIndex),
);
}
async setSubaddressLabel(accountIndex: number, addressIndex: number, label: string): Promise<void> {
return await fns.Wallet_setSubaddressLabel(this.#ptr, accountIndex, addressIndex, CString(label));
}
async isOffline(): Promise<boolean> {
return await fns.Wallet_isOffline(this.#ptr);
}
async setOffline(offline: boolean): Promise<void> {
return await fns.Wallet_setOffline(this.#ptr, offline);
}
async publicViewKey(): Promise<string | null> {
return await readCString(await fns.Wallet_publicViewKey(this.#ptr));
}
async secretViewKey(): Promise<string | null> {
return await readCString(await fns.Wallet_secretViewKey(this.#ptr));
}
async publicSpendKey(): Promise<string | null> {
return await readCString(await fns.Wallet_publicSpendKey(this.#ptr));
}
async secretSpendKey(): Promise<string | null> {
return await readCString(await fns.Wallet_secretSpendKey(this.#ptr));
}
async exportOutputs(fileName: string, all: boolean): Promise<boolean> {
return await fns.Wallet_exportOutputs(this.#ptr, CString(fileName), all);
}
async exportOutputsUR(maxFragmentLength: bigint, all: boolean): Promise<string | null> {
const exportOutputsUR = fns.Wallet_exportOutputsUR;
if (!exportOutputsUR) return null;
return await readCString(
await exportOutputsUR(this.#ptr, maxFragmentLength, all),
);
}
async importOutputs(fileName: string): Promise<boolean> {
return await fns.Wallet_importOutputs(this.#ptr, CString(fileName));
}
async importOutputsUR(input: string): Promise<boolean | null> {
const importOutputsUR = fns.Wallet_importOutputsUR;
if (!importOutputsUR) return null;
return await importOutputsUR(this.#ptr, CString(input));
}
async exportKeyImages(fileName: string, all: boolean): Promise<boolean> {
return await fns.Wallet_exportKeyImages(this.#ptr, CString(fileName), all);
}
async exportKeyImagesUR(maxFragmentLength: bigint, all: boolean): Promise<string | null> {
const exportKeyImagesUR = fns.Wallet_exportKeyImagesUR;
if (!exportKeyImagesUR) return null;
return await readCString(
await exportKeyImagesUR(this.#ptr, maxFragmentLength, all),
);
}
async importKeyImages(fileName: string): Promise<boolean> {
return await fns.Wallet_importKeyImages(this.#ptr, CString(fileName));
}
async importKeyImagesUR(input: string): Promise<boolean | null> {
const importKeyImagesUR = fns.Wallet_importKeyImagesUR;
if (!importKeyImagesUR) return null;
return await importKeyImagesUR(this.#ptr, CString(input));
}
async loadUnsignedTx(fileName: string): Promise<UnsignedTransaction> {
const pendingTxPtr = await fns.Wallet_loadUnsignedTx(this.#ptr, CString(fileName));
return UnsignedTransaction.new(pendingTxPtr as UnsignedTransactionPtr);
}
async loadUnsignedTxUR(input: string): Promise<UnsignedTransaction | null> {
const loadUnsignedTxUR = fns.Wallet_loadUnsignedTxUR;
if (!loadUnsignedTxUR) return null;
const pendingTxPtr = await loadUnsignedTxUR(this.#ptr, CString(input));
if (await this.status()) {
throw this.errorString();
}
return UnsignedTransaction.new(pendingTxPtr as UnsignedTransactionPtr);
}
async createTransaction(
destinationAddress: string,
amount: bigint,
pendingTransactionPriority: 0 | 1 | 2 | 3,
subaddressAccount: number,
prefferedInputs = "",
mixinCount = 0,
paymentId = "",
): Promise<PendingTransaction | null> {
const pendingTxPtr = await fns.Wallet_createTransaction(
this.#ptr,
CString(destinationAddress),
CString(paymentId),
amount,
mixinCount,
pendingTransactionPriority,
subaddressAccount,
CString(prefferedInputs),
C_SEPARATOR,
);
if (!pendingTxPtr) return null;
return PendingTransaction.new(pendingTxPtr as PendingTransactionPtr);
}
async createTransactionMultDest(
destinationAddresses: string[],
amounts: bigint[],
amountSweepAll: boolean,
pendingTransactionPriority: 0 | 1 | 2 | 3,
subaddressAccount: number,
preferredInputs: string[] = [],
mixinCount = 0,
paymentId = "",
): Promise<PendingTransaction | null> {
const pendingTxPtr = await fns.Wallet_createTransactionMultDest?.(
this.#ptr,
CString(destinationAddresses.join(SEPARATOR)),
C_SEPARATOR,
CString(paymentId),
amountSweepAll,
CString(amounts.join(SEPARATOR)),
C_SEPARATOR,
mixinCount,
pendingTransactionPriority,
subaddressAccount,
CString(preferredInputs.join(SEPARATOR)),
C_SEPARATOR,
);
if (!pendingTxPtr) return null;
return PendingTransaction.new(pendingTxPtr as PendingTransactionPtr);
}
async coins(): Promise<Coins | null> {
const coinsPtr = await fns.Wallet_coins(this.#ptr);
if (!coinsPtr) return null;
return new Coins(coinsPtr as CoinsPtr);
}
async status(): Promise<number> {
return await fns.Wallet_status(this.#ptr);
}
async errorString(): Promise<string | null> {
if (!await this.status()) return null;
const error = await fns.Wallet_errorString(this.#ptr);
return await readCString(error);
}
async throwIfError(): Promise<void> {
const maybeError = await this.errorString();
if (maybeError) {
throw new Error(maybeError);
}
}
}