-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
347 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"deno.enable": true | ||
} |
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 @@ | ||
*_libwallet2_api_c.* |
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 @@ | ||
# monero.ts wip library |
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,3 @@ | ||
export const MONERO_wallet2_api_c_h_sha256 = "e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad"; | ||
export const MONERO_wallet2_api_c_cpp_sha256 = "d1842cded0040c16b8886878681c8938005f69ec1378fa9be68a430311cc3666"; | ||
export const MONERO_wallet2_api_c_exp_sha256 = "c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c"; |
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,3 @@ | ||
export const WOWNERO_wallet2_api_c_h_sha256 = "8a8d386dd5d996c89a0586c55b295ef95ca584bf1ffa26255152b291910a0a77"; | ||
export const WOWNERO_wallet2_api_c_cpp_sha256 = "ed400bd9c4709383ffd42a9fbe68be37a2a47a42f92eacaf3a2dbd248c422739"; | ||
export const WOWNERO_wallet2_api_c_exp_sha256 = "3673e40e1a7115552276d1d541f6e4d5a0fef47c40fff7b988f49923af84c8a4"; |
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,186 @@ | ||
import { Wallet } from "./wallet.ts"; | ||
import { WalletManager } from "./wallet_manager.ts"; | ||
import { platform } from 'node:process'; | ||
|
||
const libPath = () => { | ||
if (platform == 'win32') return 'monero_libwallet2_api_c.dll' | ||
// ios missing, if you ever happen to run this on iOS | ||
// 1) seek help | ||
// 2) return | ||
// 2.1) if compliant with app store - MoneroWallet.framework/MoneroWallet | ||
// 2.2) if hacked around 'monero_libwallet2_api_c.dylib' | ||
if (platform == 'darwin') return './monero_libwallet2_api_c.dylib' | ||
if (platform == 'android') return 'libmonero_libwallet2_api_c.so' | ||
return 'monero_libwallet2_api_c.so' | ||
}; | ||
|
||
export const dylib = Deno.dlopen(libPath(), { | ||
"MONERO_WalletManagerFactory_getWalletManager": { | ||
nonblocking: true, | ||
parameters: [], | ||
// void* | ||
result: "pointer", | ||
}, | ||
|
||
//#region WalletManager | ||
"MONERO_WalletManager_createWallet": { | ||
nonblocking: true, | ||
// void* wm_ptr, const char* path, const char* password, const char* language, int networkType | ||
parameters: ["pointer", "pointer", "pointer", "pointer", "i32"], | ||
// void* | ||
result: "pointer", | ||
}, | ||
"MONERO_WalletManager_openWallet": { | ||
nonblocking: true, | ||
// void* wm_ptr, const char* path, const char* password, int networkType | ||
"parameters": ["pointer", "pointer", "pointer", "i32"], | ||
// void* | ||
result: "pointer", | ||
}, | ||
"MONERO_WalletManager_recoveryWallet": { | ||
nonblocking: true, | ||
// void* wm_ptr, const char* path, const char* password, const char* mnemonic, int networkType, uint64_t restoreHeight, uint64_t kdfRounds, const char* seedOffset | ||
parameters: ["pointer", "pointer", "pointer", "pointer", "i32", "u64", "u64", "pointer"], | ||
// void* | ||
result: "pointer", | ||
}, | ||
//#endregion | ||
|
||
//#region Wallet | ||
"MONERO_Wallet_address": { | ||
nonblocking: true, | ||
// void* wallet_ptr, uint64_t accountIndex, uint64_t addressIndex | ||
parameters: ["pointer", "u64", "u64"], | ||
// char* | ||
result: "pointer", | ||
}, | ||
"MONERO_Wallet_balance": { | ||
nonblocking: true, | ||
// void* wallet_ptr, uint32_t accountIndex | ||
parameters: ["pointer", "u32"], | ||
// uint64_t | ||
result: "u64", | ||
}, | ||
"MONERO_Wallet_status": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// int | ||
result: "i32", | ||
}, | ||
"MONERO_Wallet_errorString": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// char* | ||
result: "pointer", | ||
}, | ||
"MONERO_Wallet_blockChainHeight": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// uint64_t | ||
result: "u64", | ||
}, | ||
"MONERO_Wallet_daemonBlockChainHeight": { | ||
nonblocking: true, | ||
// void* wallet_ptr | ||
parameters: ["pointer"], | ||
// uint64_t | ||
result: "u64", | ||
}, | ||
//#endregion | ||
}); | ||
|
||
if (import.meta.main) { | ||
let option: string | null = null; | ||
while (option !== "o" && option !== "c") { | ||
const message = option | ||
? "Your option has to be either (c)reate or (o)pen" | ||
: "Do you want to (c)reate or (o)pen a wallet?"; | ||
option = prompt(message); | ||
} | ||
|
||
const path = prompt("Wallet path:"); | ||
if (!path) throw "You have to set path"; | ||
const absolutePath = import.meta.resolve(path).replace("file://", ""); | ||
|
||
const password = prompt("Password:"); | ||
if (!password) throw "You have to choose password"; | ||
|
||
const walletManager = await WalletManager.new(); | ||
const wallet = option === "c" | ||
? await Wallet.create(walletManager, absolutePath, password) | ||
: await Wallet.open(walletManager, absolutePath, password); | ||
|
||
const error = await wallet.error(); | ||
if (error) throw error; | ||
|
||
const address = await wallet.address(); | ||
|
||
if (address !== null) { | ||
console.log("Your address is:", address); | ||
} | ||
} | ||
|
||
if (import.meta.main) { | ||
let option: string | null = null; | ||
while (option !== "o" && option !== "c") { | ||
const message = option | ||
? "Your option has to be either (c)reate or (o)pen" | ||
: "Do you want to (c)reate or (o)pen a wallet?"; | ||
option = prompt(message); | ||
} | ||
|
||
const path = prompt("Wallet path:"); | ||
if (!path) throw "You have to set path"; | ||
const absolutePath = import.meta.resolve(path).replace("file://", ""); | ||
|
||
const password = prompt("Password:"); | ||
if (!password) throw "You have to choose password"; | ||
|
||
const walletManager = await WalletManager.new(); | ||
const wallet = option === "c" | ||
? await Wallet.create(walletManager, absolutePath, password) | ||
: await Wallet.open(walletManager, absolutePath, password); | ||
|
||
const error = await wallet.error(); | ||
if (error) throw error; | ||
|
||
const address = await wallet.address(); | ||
|
||
if (address !== null) { | ||
console.log("Your address is:", address); | ||
} | ||
} | ||
|
||
if (import.meta.main) { | ||
let option: string | null = null; | ||
while (option !== "o" && option !== "c") { | ||
const message = option | ||
? "Your option has to be either (c)reate or (o)pen" | ||
: "Do you want to (c)reate or (o)pen a wallet?"; | ||
option = prompt(message); | ||
} | ||
|
||
const path = prompt("Wallet path:"); | ||
if (!path) throw "You have to set path"; | ||
const absolutePath = import.meta.resolve(path).replace("file://", ""); | ||
|
||
const password = prompt("Password:"); | ||
if (!password) throw "You have to choose password"; | ||
|
||
const walletManager = await WalletManager.new(); | ||
const wallet = option === "c" | ||
? await Wallet.create(walletManager, absolutePath, password) | ||
: await Wallet.open(walletManager, absolutePath, password); | ||
|
||
const error = await wallet.error(); | ||
if (error) throw error; | ||
|
||
const address = await wallet.address(); | ||
|
||
if (address !== null) { | ||
console.log("Your address is:", address); | ||
} | ||
} |
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,4 @@ | ||
const textEncoder = new TextEncoder(); | ||
export function CString(string: string): Deno.PointerValue<string> { | ||
return Deno.UnsafePointer.of(textEncoder.encode(`${string}\x00`)); | ||
} |
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,111 @@ | ||
import { dylib } from "./monero_bindings.ts"; | ||
import { CString } from "./utils.ts"; | ||
import { WalletManager, type WalletManagerPtr } from "./wallet_manager.ts"; | ||
|
||
export type WalletPtr = Deno.PointerObject<"walletManager">; | ||
|
||
export class Wallet { | ||
#walletManagerPtr: WalletManagerPtr; | ||
#walletPtr: WalletPtr; | ||
|
||
constructor(walletManagerPtr: WalletManager, walletPtr: WalletPtr) { | ||
this.#walletPtr = walletPtr; | ||
this.#walletManagerPtr = walletManagerPtr.getPointer(this); | ||
} | ||
|
||
async address(accountIndex = 0n, addressIndex = 0n): Promise<string> { | ||
const address = await dylib.symbols.MONERO_Wallet_address(this.#walletPtr, accountIndex, addressIndex); | ||
if (!address) { | ||
const error = await this.error(); | ||
throw new Error(`Failed getting address from a wallet: ${error ?? "<Error unknown>"}`); | ||
} | ||
return new Deno.UnsafePointerView(address).getCString(); | ||
} | ||
|
||
async balance(accountIndex = 0): Promise<bigint> { | ||
return await dylib.symbols.MONERO_Wallet_balance(this.#walletPtr, accountIndex); | ||
} | ||
|
||
static async create(walletManager: WalletManager, path: string, password: string): Promise<Wallet> { | ||
// We assign holder of the pointer in Wallet constructor | ||
const walletManagerPtr = walletManager.getPointer(); | ||
|
||
const walletPtr = await dylib.symbols.MONERO_WalletManager_createWallet( | ||
walletManagerPtr, | ||
CString(path), | ||
CString(password), | ||
CString("English"), | ||
0, | ||
); | ||
|
||
const wallet = new Wallet(walletManager, walletPtr as WalletPtr); | ||
|
||
const maybeError = await wallet.error(); | ||
if (maybeError) throw new Error(maybeError); | ||
|
||
return wallet; | ||
} | ||
|
||
static async open(walletManager: WalletManager, path: string, password: string): Promise<Wallet> { | ||
// We assign holder of the pointer in Wallet constructor | ||
const walletManagerPtr = walletManager.getPointer(); | ||
|
||
const walletPtr = await dylib.symbols.MONERO_WalletManager_openWallet( | ||
walletManagerPtr, | ||
CString(path), | ||
CString(password), | ||
0, | ||
); | ||
|
||
const wallet = new Wallet(walletManager, walletPtr as WalletPtr); | ||
|
||
const maybeError = await wallet.error(); | ||
if (maybeError) throw new Error(maybeError); | ||
|
||
return wallet; | ||
} | ||
|
||
static async recover( | ||
walletManager: WalletManager, | ||
path: string, | ||
password: string, | ||
mnemonic: string, | ||
restoreHeight: bigint = 0n, | ||
seedOffset: string = "", | ||
): Promise<Wallet> { | ||
// We assign holder of the pointer in Wallet constructor | ||
const walletManagerPtr = walletManager.getPointer(); | ||
|
||
const walletPtr = await dylib.symbols.MONERO_WalletManager_recoveryWallet( | ||
walletManagerPtr, | ||
CString(path), | ||
CString(password), | ||
CString(mnemonic), | ||
0, | ||
restoreHeight, | ||
1n, | ||
CString(seedOffset), | ||
); | ||
|
||
const wallet = new Wallet(walletManager, walletPtr as WalletPtr); | ||
|
||
const maybeError = await wallet.error(); | ||
if (maybeError) throw new Error(maybeError); | ||
|
||
return wallet; | ||
} | ||
|
||
status(): Promise<number> { | ||
return dylib.symbols.MONERO_Wallet_status(this.#walletPtr); | ||
} | ||
|
||
async error(): Promise<string | null> { | ||
if (!await this.status()) return null; | ||
|
||
const error = await dylib.symbols.MONERO_Wallet_errorString(this.#walletPtr); | ||
if (!error) return null; | ||
|
||
const errorString = new Deno.UnsafePointerView(error).getCString(); | ||
return errorString || null; | ||
} | ||
} |
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,25 @@ | ||
import { dylib } from "./monero_bindings.ts"; | ||
|
||
export type WalletManagerPtr = Deno.PointerObject<"walletManager">; | ||
|
||
export class WalletManager { | ||
#ptr: WalletManagerPtr; | ||
// Stores data about who uses the pointer | ||
#pointerUsers: WeakSet<object>; | ||
|
||
constructor(walletManagerPtr: WalletManagerPtr) { | ||
this.#ptr = walletManagerPtr; | ||
this.#pointerUsers = new WeakSet(); | ||
} | ||
|
||
getPointer(holder?: object) { | ||
if (holder) this.#pointerUsers.add(holder); | ||
return this.#ptr; | ||
} | ||
|
||
static async new() { | ||
const ptr = await dylib.symbols.MONERO_WalletManagerFactory_getWalletManager(); | ||
if (!ptr) throw new Error("Failed retrieving wallet manager"); | ||
return new WalletManager(ptr as WalletManagerPtr); | ||
} | ||
} |