-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into cyjan-cleanup-patches
Showing
22 changed files
with
3,820 additions
and
808 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
release/ | ||
build/ | ||
tests/monero-cli | ||
tests/wownero-cli | ||
tests/libs | ||
tests/wallets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
export * from "./src/bindings.ts"; | ||
export * from "./src/coins.ts"; | ||
export * from "./src/coins_info.ts"; | ||
export * from "./src/pending_transaction.ts"; | ||
export * from "./src/symbols.ts"; | ||
export * from "./src/transaction_history.ts"; | ||
export * from "./src/transaction_info.ts"; | ||
export * from "./src/unsigned_transaction.ts"; | ||
export * from "./src/utils.ts"; | ||
export * from "./src/wallet.ts"; | ||
export * from "./src/wallet_manager.ts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { CoinsInfo, type CoinsInfoPtr } from "./coins_info.ts"; | ||
import { fns } from "./bindings.ts"; | ||
|
||
export type CoinsPtr = Deno.PointerObject<"coins">; | ||
|
||
export class Coins { | ||
#ptr: CoinsPtr; | ||
|
||
#coins: CoinsInfo[] = []; | ||
|
||
constructor(ptr: CoinsPtr) { | ||
this.#ptr = ptr; | ||
} | ||
|
||
async count(): Promise<number> { | ||
return await fns.Coins_count(this.#ptr); | ||
} | ||
|
||
async coin(index: number): Promise<CoinsInfo | null> { | ||
if (this.#coins[index]) { | ||
return this.#coins[index]; | ||
} | ||
|
||
const coinPtr = await fns.Coins_coin(this.#ptr, index); | ||
if (!coinPtr) return null; | ||
|
||
return CoinsInfo.new(coinPtr as CoinsInfoPtr); | ||
} | ||
|
||
async setFrozen(index: number) { | ||
return await fns.Coins_setFrozen(this.#ptr, index); | ||
} | ||
|
||
async thaw(index: number) { | ||
return await fns.Coins_thaw(this.#ptr, index); | ||
} | ||
|
||
async getAllSize(): Promise<number> { | ||
return await fns.Coins_getAll_size(this.#ptr); | ||
} | ||
|
||
async getAllByIndex(index: number): Promise<unknown> { | ||
return await fns.Coins_getAll_byIndex(this.#ptr, index); | ||
} | ||
|
||
async refresh(): Promise<void> { | ||
await fns.Coins_refresh(this.#ptr); | ||
|
||
for (const coin of this.#coins) { | ||
coin.refresh(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { fns } from "./bindings.ts"; | ||
import { readCString } from "./utils.ts"; | ||
|
||
export type CoinsInfoPtr = Deno.PointerObject<"coinsInfo">; | ||
|
||
export class CoinsInfo { | ||
#ptr: CoinsInfoPtr; | ||
|
||
#hash!: string | null; | ||
#keyImage!: string | null; | ||
#blockHeight!: bigint; | ||
#amount!: bigint; | ||
#spent!: boolean; | ||
#spentHeight!: bigint; | ||
#frozen!: boolean; | ||
#unlocked!: boolean; | ||
|
||
constructor(ptr: CoinsInfoPtr) { | ||
this.#ptr = ptr; | ||
} | ||
|
||
getPointer(): CoinsInfoPtr { | ||
return this.#ptr; | ||
} | ||
|
||
static async new(ptr: CoinsInfoPtr): Promise<CoinsInfo> { | ||
const instance = new CoinsInfo(ptr); | ||
await instance.refresh(); | ||
return instance; | ||
} | ||
|
||
async refresh() { | ||
const [hash, keyImage, blockHeight, amount, spent, spentHeight, frozen, unlocked] = await Promise.all([ | ||
fns.CoinsInfo_hash(this.#ptr).then(readCString), | ||
fns.CoinsInfo_keyImage(this.#ptr).then(readCString), | ||
fns.CoinsInfo_blockHeight(this.#ptr), | ||
fns.CoinsInfo_amount(this.#ptr), | ||
fns.CoinsInfo_spent(this.#ptr), | ||
fns.CoinsInfo_spentHeight(this.#ptr), | ||
fns.CoinsInfo_frozen(this.#ptr), | ||
fns.CoinsInfo_unlocked(this.#ptr), | ||
]); | ||
|
||
this.#hash = hash; | ||
this.#keyImage = keyImage; | ||
this.#blockHeight = blockHeight; | ||
this.#amount = amount; | ||
this.#spent = spent; | ||
this.#spentHeight = spentHeight; | ||
this.#frozen = frozen; | ||
this.#unlocked = unlocked; | ||
} | ||
|
||
get hash(): string | null { | ||
return this.#hash; | ||
} | ||
|
||
get keyImage(): string | null { | ||
return this.#keyImage; | ||
} | ||
|
||
get blockHeight(): bigint { | ||
return this.#blockHeight; | ||
} | ||
|
||
get amount(): bigint { | ||
return this.#amount; | ||
} | ||
|
||
get spent(): boolean { | ||
return this.#spent; | ||
} | ||
|
||
get spentHeight(): bigint { | ||
return this.#spentHeight; | ||
} | ||
|
||
get frozen(): boolean { | ||
return this.#frozen; | ||
} | ||
|
||
get unlocked(): boolean { | ||
return this.#unlocked; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,84 @@ | ||
import { CString, getSymbol, readCString, type Sanitizer } from "./utils.ts"; | ||
import { fns } from "./bindings.ts"; | ||
import { C_SEPARATOR, CString, maybeMultipleStrings, readCString } from "./utils.ts"; | ||
|
||
export type PendingTransactionPtr = Deno.PointerObject<"transactionInfo">; | ||
export type PendingTransactionPtr = Deno.PointerObject<"pendingTransaction">; | ||
|
||
export class PendingTransaction { | ||
#pendingTxPtr: PendingTransactionPtr; | ||
sanitizer?: Sanitizer; | ||
export class PendingTransaction<MultDest extends boolean = false> { | ||
#ptr: PendingTransactionPtr; | ||
|
||
constructor(pendingTxPtr: PendingTransactionPtr, sanitizer?: Sanitizer) { | ||
this.sanitizer = sanitizer; | ||
this.#pendingTxPtr = pendingTxPtr; | ||
} | ||
#amount!: bigint; | ||
#dust!: bigint; | ||
#fee!: bigint; | ||
#txid!: string | string[] | null; | ||
#txCount!: bigint; | ||
|
||
async status(): Promise<number> { | ||
return await getSymbol("PendingTransaction_status")(this.#pendingTxPtr); | ||
constructor(ptr: PendingTransactionPtr) { | ||
this.#ptr = ptr; | ||
} | ||
|
||
async errorString(): Promise<string | null> { | ||
if (!await this.status()) return null; | ||
static async new(ptr: PendingTransactionPtr): Promise<PendingTransaction> { | ||
const instance = new PendingTransaction(ptr); | ||
|
||
const error = await getSymbol("PendingTransaction_errorString")(this.#pendingTxPtr); | ||
if (!error) return null; | ||
const [amount, dust, fee, txCount, txid] = await Promise.all([ | ||
fns.PendingTransaction_amount(ptr), | ||
fns.PendingTransaction_dust(ptr), | ||
fns.PendingTransaction_fee(ptr), | ||
fns.PendingTransaction_txCount(ptr), | ||
fns.PendingTransaction_txid(ptr, C_SEPARATOR), | ||
]); | ||
|
||
return await readCString(error) || null; | ||
} | ||
instance.#amount = amount; | ||
instance.#dust = dust; | ||
instance.#fee = fee; | ||
instance.#txCount = txCount; | ||
instance.#txid = maybeMultipleStrings(await readCString(txid)); | ||
|
||
async throwIfError(sanitize = true): Promise<void> { | ||
const maybeError = await this.errorString(); | ||
if (maybeError) { | ||
if (sanitize) this.sanitizer?.(); | ||
throw new Error(maybeError); | ||
} | ||
return instance; | ||
} | ||
|
||
async commit(fileName: string, overwrite: boolean, sanitize = true): Promise<boolean> { | ||
const bool = await getSymbol("PendingTransaction_commit")( | ||
this.#pendingTxPtr, | ||
CString(fileName), | ||
overwrite, | ||
); | ||
await this.throwIfError(sanitize); | ||
return bool; | ||
get amount(): bigint { | ||
return this.#amount; | ||
} | ||
|
||
async commitUR(maxFragmentLength: number): Promise<string | null> { | ||
const commitUR = getSymbol("PendingTransaction_commitUR"); | ||
|
||
if (!commitUR) { | ||
return null; | ||
} | ||
get dust(): bigint { | ||
return this.#dust; | ||
} | ||
|
||
const result = await commitUR( | ||
this.#pendingTxPtr, | ||
maxFragmentLength, | ||
); | ||
get fee(): bigint { | ||
return this.#fee; | ||
} | ||
|
||
if (!result) return null; | ||
await this.throwIfError(); | ||
return await readCString(result) || null; | ||
get txCount(): bigint { | ||
return this.#txCount; | ||
} | ||
|
||
async amount(): Promise<bigint> { | ||
return await getSymbol("PendingTransaction_amount")(this.#pendingTxPtr); | ||
async commit(fileName: string, overwrite: boolean): Promise<boolean> { | ||
return await fns.PendingTransaction_commit(this.#ptr, CString(fileName), overwrite); | ||
} | ||
|
||
async dust(): Promise<bigint> { | ||
return await getSymbol("PendingTransaction_dust")(this.#pendingTxPtr); | ||
async commitUR(maxFragmentLength: number): Promise<string | null> { | ||
const commitUR = fns.PendingTransaction_commitUR; | ||
if (!commitUR) return null; | ||
|
||
return await readCString( | ||
await commitUR(this.#ptr, maxFragmentLength), | ||
); | ||
} | ||
|
||
async fee(): Promise<bigint> { | ||
return await getSymbol("PendingTransaction_fee")(this.#pendingTxPtr); | ||
async status(): Promise<number> { | ||
return await fns.PendingTransaction_status(this.#ptr); | ||
} | ||
|
||
async txid(separator: string, sanitize = true): Promise<string | null> { | ||
const result = await getSymbol("PendingTransaction_txid")( | ||
this.#pendingTxPtr, | ||
CString(separator), | ||
); | ||
if (!result) return null; | ||
await this.throwIfError(sanitize); | ||
return await readCString(result) || null; | ||
async errorString(): Promise<string | null> { | ||
if (!await this.status()) return null; | ||
const error = await fns.PendingTransaction_errorString(this.#ptr); | ||
return await readCString(error); | ||
} | ||
|
||
async txCount(): Promise<bigint> { | ||
return await getSymbol("PendingTransaction_txCount")(this.#pendingTxPtr); | ||
async throwIfError(): Promise<void> { | ||
const maybeError = await this.errorString(); | ||
if (maybeError) { | ||
throw new Error(maybeError); | ||
} | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,147 @@ | ||
import { dylib } from "./bindings.ts"; | ||
import { getSymbol, readCString, Sanitizer } from "./utils.ts"; | ||
import { fns } from "./bindings.ts"; | ||
import { C_SEPARATOR, CString, maybeMultipleStrings, readCString, SEPARATOR } from "./utils.ts"; | ||
|
||
export type TransactionInfoPtr = Deno.PointerObject<"transactionInfo">; | ||
export type TransactionInfoPtr = Deno.PointerObject<"pendingTransaction">; | ||
|
||
export class TransactionInfo { | ||
#txInfoPtr: TransactionInfoPtr; | ||
sanitizer?: Sanitizer; | ||
|
||
constructor(txInfoPtr: TransactionInfoPtr, sanitizer?: Sanitizer) { | ||
this.#txInfoPtr = txInfoPtr; | ||
this.sanitizer = sanitizer; | ||
} | ||
export interface TransferData { | ||
address: string | null; | ||
amount: bigint; | ||
} | ||
|
||
async direction(): Promise<"in" | "out"> { | ||
switch (await getSymbol("TransactionInfo_direction")(this.#txInfoPtr)) { | ||
case 0: | ||
return "in"; | ||
case 1: | ||
return "out"; | ||
default: | ||
await this.sanitizer?.(); | ||
throw new Error("Invalid TransactionInfo direction"); | ||
export class TransactionInfo<MultDest extends boolean = boolean> { | ||
#ptr: TransactionInfoPtr; | ||
|
||
#amount!: bigint; | ||
#fee!: bigint; | ||
#timestamp!: bigint; | ||
#transfersCount!: number; | ||
#paymentId!: string | null; | ||
#hash!: string | null; | ||
|
||
#subaddrAccount!: number; | ||
#subaddrIndex!: string | null; | ||
|
||
#transfers!: readonly TransferData[]; | ||
|
||
constructor(ptr: TransactionInfoPtr) { | ||
this.#ptr = ptr; | ||
} | ||
|
||
static async new(ptr: TransactionInfoPtr): Promise<TransactionInfo> { | ||
const instance = new TransactionInfo(ptr); | ||
|
||
const [amount, paymentId, fee, hash, subaddrIndex, subaddrAccount, timestamp, transfersCount] = await Promise.all([ | ||
fns.TransactionInfo_amount(ptr), | ||
fns.TransactionInfo_paymentId(ptr).then(readCString), | ||
fns.TransactionInfo_fee(ptr), | ||
fns.TransactionInfo_hash(ptr).then(readCString), | ||
fns.TransactionInfo_subaddrIndex(ptr, C_SEPARATOR).then(readCString), | ||
fns.TransactionInfo_subaddrAccount(ptr), | ||
fns.TransactionInfo_timestamp(ptr), | ||
fns.TransactionInfo_transfers_count(ptr), | ||
]); | ||
|
||
instance.#amount = amount; | ||
instance.#fee = fee; | ||
instance.#timestamp = timestamp; | ||
instance.#transfersCount = transfersCount; | ||
instance.#paymentId = paymentId; | ||
instance.#hash = hash; | ||
|
||
instance.#subaddrAccount = subaddrAccount; | ||
instance.#subaddrIndex = subaddrIndex; | ||
|
||
const transfers = []; | ||
for (let i = 0; i < transfersCount; ++i) { | ||
const [amount, address] = await Promise.all([ | ||
fns.TransactionInfo_transfers_amount(ptr, i), | ||
fns.TransactionInfo_transfers_address(ptr, i).then(readCString), | ||
]); | ||
|
||
transfers.push({ amount, address }); | ||
} | ||
} | ||
Object.freeze(transfers); | ||
instance.#transfers = transfers; | ||
|
||
async isPending(): Promise<boolean> { | ||
return await getSymbol("TransactionInfo_isPending")(this.#txInfoPtr); | ||
return instance; | ||
} | ||
|
||
async isFailed(): Promise<boolean> { | ||
return await getSymbol("TransactionInfo_isFailed")(this.#txInfoPtr); | ||
get amount(): bigint { | ||
return this.#amount; | ||
} | ||
|
||
async isCoinbase(): Promise<boolean> { | ||
return await getSymbol("TransactionInfo_isCoinbase")(this.#txInfoPtr); | ||
get fee(): bigint { | ||
return this.#fee; | ||
} | ||
|
||
async amount(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_amount")(this.#txInfoPtr); | ||
get timestamp(): bigint { | ||
return this.#timestamp; | ||
} | ||
|
||
async fee(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_fee")(this.#txInfoPtr); | ||
get transfersCount(): number { | ||
return this.#transfersCount; | ||
} | ||
|
||
async blockHeight(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_blockHeight")(this.#txInfoPtr); | ||
get paymentId(): string | null { | ||
return this.#paymentId; | ||
} | ||
|
||
async description(): Promise<string> { | ||
const description = await getSymbol("TransactionInfo_description")(this.#txInfoPtr); | ||
return await readCString(description) || ""; | ||
get hash(): string | null { | ||
return this.#hash; | ||
} | ||
|
||
async subaddrIndex(): Promise<string> { | ||
const subaddrIndex = await getSymbol("TransactionInfo_subaddrIndex")(this.#txInfoPtr); | ||
return await readCString(subaddrIndex) || ""; | ||
get subaddrAccount(): number { | ||
return this.#subaddrAccount; | ||
} | ||
|
||
async subaddrAccount(): Promise<number> { | ||
return await getSymbol("TransactionInfo_subaddrAccount")(this.#txInfoPtr); | ||
get subaddrIndex(): string | null { | ||
return this.#subaddrIndex; | ||
} | ||
|
||
async label(): Promise<string> { | ||
const label = await getSymbol("TransactionInfo_label")(this.#txInfoPtr); | ||
return await readCString(label) || ""; | ||
get transfers(): readonly TransferData[] { | ||
return this.#transfers; | ||
} | ||
|
||
async confirmations(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_confirmations")(this.#txInfoPtr); | ||
async direction(): Promise<"in" | "out"> { | ||
switch (await fns.TransactionInfo_direction(this.#ptr)) { | ||
case 0: | ||
return "in"; | ||
case 1: | ||
return "out"; | ||
default: | ||
throw new Error("Invalid TransactionInfo direction"); | ||
} | ||
} | ||
|
||
async unlockTime(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_unlockTime")(this.#txInfoPtr); | ||
async description(): Promise<string | null> { | ||
return await readCString( | ||
await fns.TransactionInfo_description(this.#ptr), | ||
); | ||
} | ||
|
||
async hash(): Promise<string> { | ||
const hash = await getSymbol("TransactionInfo_hash")(this.#txInfoPtr); | ||
return await readCString(hash) || ""; | ||
async label(): Promise<string | null> { | ||
return await readCString( | ||
await fns.TransactionInfo_label(this.#ptr), | ||
); | ||
} | ||
|
||
async timestamp(): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_timestamp")(this.#txInfoPtr); | ||
async confirmations(): Promise<bigint> { | ||
return await fns.TransactionInfo_confirmations(this.#ptr); | ||
} | ||
|
||
async paymentId(): Promise<string> { | ||
const paymentId = await getSymbol("TransactionInfo_paymentId")(this.#txInfoPtr); | ||
return await readCString(paymentId) || ""; | ||
async unlockTime(): Promise<bigint> { | ||
return await fns.TransactionInfo_unlockTime(this.#ptr); | ||
} | ||
|
||
async transfersCount(): Promise<number> { | ||
return await getSymbol("TransactionInfo_transfers_count")(this.#txInfoPtr); | ||
async isPending(): Promise<boolean> { | ||
return await fns.TransactionInfo_isPending(this.#ptr); | ||
} | ||
|
||
async transfersAmount(index: number): Promise<bigint> { | ||
return await getSymbol("TransactionInfo_transfers_amount")(this.#txInfoPtr, index); | ||
async isFailed(): Promise<boolean> { | ||
return await fns.TransactionInfo_isFailed(this.#ptr); | ||
} | ||
|
||
async transfersAddress(index: number): Promise<string> { | ||
const transfersAddress = await getSymbol("TransactionInfo_transfers_address")(this.#txInfoPtr, index); | ||
return await readCString(transfersAddress) || ""; | ||
async isCoinbase(): Promise<boolean> { | ||
return await fns.TransactionInfo_isCoinbase(this.#ptr); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { fns } from "./bindings.ts"; | ||
import { C_SEPARATOR, CString, maybeMultipleStrings, readCString } from "./utils.ts"; | ||
|
||
export type UnsignedTransactionPtr = Deno.PointerObject<"pendingTransaction">; | ||
|
||
export class UnsignedTransaction<MultDest extends boolean = false> { | ||
#ptr: UnsignedTransactionPtr; | ||
|
||
#amount!: string | string[] | null; | ||
#fee!: string | string[] | null; | ||
#txCount!: bigint; | ||
#paymentId!: string | null; | ||
#recipientAddress!: string | string[] | null; | ||
|
||
constructor(ptr: UnsignedTransactionPtr) { | ||
this.#ptr = ptr; | ||
} | ||
|
||
async status(): Promise<number> { | ||
return await fns.UnsignedTransaction_status(this.#ptr); | ||
} | ||
|
||
async errorString(): Promise<string | null> { | ||
return await readCString(await fns.UnsignedTransaction_errorString(this.#ptr)); | ||
} | ||
|
||
static async new(ptr: UnsignedTransactionPtr): Promise<UnsignedTransaction> { | ||
const instance = new UnsignedTransaction(ptr); | ||
|
||
const [amount, paymentId, fee, txCount, recipientAddress] = await Promise.all([ | ||
fns.UnsignedTransaction_amount(ptr, C_SEPARATOR).then(readCString), | ||
fns.UnsignedTransaction_paymentId(ptr, C_SEPARATOR).then(readCString), | ||
fns.UnsignedTransaction_fee(ptr, C_SEPARATOR).then(readCString), | ||
fns.UnsignedTransaction_txCount(ptr), | ||
fns.UnsignedTransaction_recipientAddress(ptr, C_SEPARATOR).then(readCString), | ||
]); | ||
|
||
instance.#amount = maybeMultipleStrings(amount); | ||
instance.#fee = maybeMultipleStrings(fee); | ||
instance.#recipientAddress = maybeMultipleStrings(recipientAddress); | ||
instance.#txCount = txCount; | ||
instance.#paymentId = paymentId; | ||
|
||
return instance; | ||
} | ||
|
||
get amount(): string | string[] | null { | ||
return this.#amount; | ||
} | ||
|
||
get fee(): string | string[] | null { | ||
return this.#fee; | ||
} | ||
|
||
get txCount(): bigint { | ||
return this.#txCount; | ||
} | ||
|
||
get paymentId(): string | null { | ||
return this.#paymentId; | ||
} | ||
|
||
get recipientAddress(): string | string[] | null { | ||
return this.#recipientAddress; | ||
} | ||
|
||
async sign(signedFileName: string): Promise<boolean> { | ||
return await fns.UnsignedTransaction_sign(this.#ptr, CString(signedFileName)); | ||
} | ||
|
||
async signUR(maxFragmentLength: number): Promise<string | null> { | ||
const signUR = fns.UnsignedTransaction_signUR; | ||
if (!signUR) return null; | ||
|
||
return await readCString( | ||
await signUR(this.#ptr, maxFragmentLength), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,148 @@ | ||
import { getSymbol, Sanitizer } from "./utils.ts"; | ||
import { fns } from "./bindings.ts"; | ||
import { CString } from "./utils.ts"; | ||
import { Wallet, WalletPtr } from "./wallet.ts"; | ||
|
||
export type WalletManagerPtr = Deno.PointerObject<"walletManager">; | ||
|
||
export class WalletManager { | ||
#ptr: WalletManagerPtr; | ||
sanitizer?: Sanitizer; | ||
|
||
constructor(walletManagerPtr: WalletManagerPtr, sanitizer?: Sanitizer) { | ||
constructor(walletManagerPtr: WalletManagerPtr) { | ||
this.#ptr = walletManagerPtr; | ||
this.sanitizer = sanitizer; | ||
} | ||
|
||
getPointer(): WalletManagerPtr { | ||
return this.#ptr; | ||
} | ||
|
||
static async new(sanitizer?: Sanitizer) { | ||
const ptr = await getSymbol("WalletManagerFactory_getWalletManager")(); | ||
static async new() { | ||
const ptr = await fns.WalletManagerFactory_getWalletManager(); | ||
if (!ptr) { | ||
sanitizer?.(); | ||
throw new Error("Failed retrieving wallet manager"); | ||
} | ||
return new WalletManager(ptr as WalletManagerPtr, sanitizer); | ||
|
||
return new WalletManager(ptr as WalletManagerPtr); | ||
} | ||
|
||
async setDaemonAddress(address: string): Promise<void> { | ||
return await fns.WalletManager_setDaemonAddress(this.#ptr, CString(address)); | ||
} | ||
|
||
async createWallet(path: string, password: string): Promise<Wallet> { | ||
const walletPtr = await fns.WalletManager_createWallet( | ||
this.#ptr, | ||
CString(path), | ||
CString(password), | ||
CString("English"), | ||
0, | ||
); | ||
|
||
const wallet = new Wallet(this, walletPtr as WalletPtr); | ||
await wallet.throwIfError(); | ||
return wallet; | ||
} | ||
|
||
async openWallet(path: string, password: string): Promise<Wallet> { | ||
const walletPtr = await fns.WalletManager_openWallet( | ||
this.#ptr, | ||
CString(path), | ||
CString(password), | ||
0, | ||
); | ||
|
||
const wallet = new Wallet(this, walletPtr as WalletPtr); | ||
await wallet.throwIfError(); | ||
return wallet; | ||
} | ||
|
||
async recoverWallet( | ||
path: string, | ||
password: string, | ||
mnemonic: string, | ||
restoreHeight: bigint, | ||
seedOffset: string = "", | ||
): Promise<Wallet> { | ||
const walletPtr = await fns.WalletManager_recoveryWallet( | ||
this.#ptr, | ||
CString(path), | ||
CString(password), | ||
CString(mnemonic), | ||
0, | ||
restoreHeight, | ||
1n, | ||
CString(seedOffset), | ||
); | ||
|
||
const wallet = new Wallet(this, walletPtr as WalletPtr); | ||
await wallet.throwIfError(); | ||
return wallet; | ||
} | ||
|
||
async recoverFromPolyseed( | ||
path: string, | ||
password: string, | ||
mnemonic: string, | ||
restoreHeight: bigint, | ||
passphrase = "", | ||
): Promise<Wallet> { | ||
return await this.createFromPolyseed( | ||
path, | ||
password, | ||
mnemonic, | ||
restoreHeight, | ||
passphrase, | ||
false, | ||
); | ||
} | ||
|
||
async createFromPolyseed( | ||
path: string, | ||
password: string, | ||
mnemonic: string, | ||
restoreHeight: bigint, | ||
passphrase = "", | ||
newWallet = true, | ||
): Promise<Wallet> { | ||
const walletPtr = await fns.WalletManager_createWalletFromPolyseed( | ||
this.#ptr, | ||
CString(path), | ||
CString(password), | ||
0, | ||
CString(mnemonic), | ||
CString(passphrase), | ||
newWallet, | ||
restoreHeight, | ||
1n, | ||
); | ||
|
||
const wallet = new Wallet(this, walletPtr as WalletPtr); | ||
await wallet.throwIfError(); | ||
return wallet; | ||
} | ||
|
||
async recoverFromKeys( | ||
path: string, | ||
password: string, | ||
restoreHeight: bigint, | ||
address: string, | ||
viewKey: string, | ||
spendKey: string, | ||
): Promise<Wallet> { | ||
const walletPtr = await fns.WalletManager_createWalletFromKeys( | ||
this.#ptr, | ||
CString(path), | ||
CString(password), | ||
CString("English"), | ||
0, | ||
restoreHeight, | ||
CString(address), | ||
CString(viewKey), | ||
CString(spendKey), | ||
0n, | ||
); | ||
|
||
const wallet = new Wallet(this, walletPtr as WalletPtr); | ||
await wallet.throwIfError(); | ||
return wallet; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,80 +1,34 @@ | ||
import { moneroSymbols as symbols, type MoneroTsDylib, type WowneroTsDylib } from "../impls/monero.ts/src/symbols.ts"; | ||
import { loadMoneroDylib, loadWowneroDylib } from "../impls/monero.ts/src/bindings.ts"; | ||
import { Wallet, WalletManager } from "../impls/monero.ts/mod.ts"; | ||
import { readCString } from "../impls/monero.ts/src/utils.ts"; | ||
import { assertEquals } from "jsr:@std/assert"; | ||
|
||
import { | ||
loadMoneroDylib, | ||
loadWowneroDylib, | ||
moneroSymbols, | ||
WalletManager, | ||
wowneroSymbols, | ||
} from "../impls/monero.ts/mod.ts"; | ||
|
||
const coin = Deno.args[0] as "monero" | "wownero"; | ||
const version = Deno.args[1]; | ||
const walletInfo = JSON.parse(Deno.args[2]); | ||
|
||
const moneroSymbols = { | ||
...symbols, | ||
|
||
"MONERO_Wallet_secretViewKey": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// const char* | ||
result: "pointer", | ||
}, | ||
"MONERO_Wallet_publicViewKey": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// const char* | ||
result: "pointer", | ||
}, | ||
|
||
"MONERO_Wallet_secretSpendKey": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// const char* | ||
result: "pointer", | ||
}, | ||
"MONERO_Wallet_publicSpendKey": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// const char* | ||
result: "pointer", | ||
}, | ||
} as const; | ||
|
||
type ReplaceMonero<T extends string> = T extends `MONERO${infer Y}` ? `WOWNERO${Y}` : never; | ||
type WowneroSymbols = { [Key in keyof typeof moneroSymbols as ReplaceMonero<Key>]: (typeof moneroSymbols)[Key] }; | ||
const wowneroSymbols = Object.fromEntries( | ||
Object.entries(moneroSymbols).map(([key, value]) => [key.replace("MONERO", "WOWNERO"), value]), | ||
) as WowneroSymbols; | ||
|
||
let getKey: (wallet: Wallet, type: `${"secret" | "public"}${"Spend" | "View"}Key`) => Promise<string | null>; | ||
|
||
if (coin === "monero") { | ||
const dylib = Deno.dlopen(`tests/libs/${version}/monero_libwallet2_api_c.so`, moneroSymbols); | ||
loadMoneroDylib(dylib as MoneroTsDylib); | ||
|
||
getKey = async (wallet, type) => | ||
await readCString(await dylib.symbols[`MONERO_Wallet_${type}` as const](wallet.getPointer())); | ||
loadMoneroDylib(dylib); | ||
} else { | ||
const dylib = Deno.dlopen(`tests/libs/${version}/wownero_libwallet2_api_c.so`, wowneroSymbols); | ||
loadWowneroDylib(dylib as WowneroTsDylib); | ||
|
||
getKey = async (wallet, type) => | ||
await readCString( | ||
await dylib.symbols[`WOWNERO_Wallet_${type}` as const](wallet.getPointer()), | ||
); | ||
loadWowneroDylib(dylib); | ||
} | ||
|
||
const walletManager = await WalletManager.new(); | ||
const wallet = await Wallet.open(walletManager, walletInfo.path, walletInfo.password); | ||
const wallet = await walletManager.openWallet(walletInfo.path, walletInfo.password); | ||
|
||
assertEquals(await wallet.address(), walletInfo.address); | ||
|
||
assertEquals(await getKey(wallet, "publicSpendKey"), walletInfo.publicSpendKey); | ||
assertEquals(await getKey(wallet, "secretSpendKey"), walletInfo.secretSpendKey); | ||
assertEquals(await wallet.publicSpendKey(), walletInfo.publicSpendKey); | ||
assertEquals(await wallet.secretSpendKey(), walletInfo.secretSpendKey); | ||
|
||
assertEquals(await getKey(wallet, "publicViewKey"), walletInfo.publicViewKey); | ||
assertEquals(await getKey(wallet, "secretViewKey"), walletInfo.secretViewKey); | ||
assertEquals(await wallet.publicViewKey(), walletInfo.publicViewKey); | ||
assertEquals(await wallet.secretViewKey(), walletInfo.secretViewKey); | ||
|
||
await wallet.store(walletInfo.path); |
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters