-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathmultiple-wallets.ts
More file actions
133 lines (113 loc) · 4.45 KB
/
multiple-wallets.ts
File metadata and controls
133 lines (113 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* This example shows how to create two wallets using the SDK.
* Alice's wallet will be persisted in SQLite, while Bob's wallet will be in-memory.
*
* By inspecting the `alice-wallet.sqlite` file created upon running the code,
* you can see the persisted data for Alice's wallet.
*
* To run it:
* ```
* $ npx tsx examples/node/multiple-wallets.ts
* ```
*
* Requires `better-sqlite3` (included as a devDependency).
*/
import {
InMemoryContractRepository,
InMemoryWalletRepository,
SingleKey,
Wallet,
Ramps,
} from "../../src";
import { WalletState } from "../../src/repositories";
import {
SQLiteWalletRepository,
SQLiteContractRepository,
SQLExecutor,
} from "../../src/repositories/sqlite";
import Database from "better-sqlite3";
import { execSync } from "child_process";
// EventSource is used internally by the SDK for settlement events (SSE).
// It is not available in Node.js by default, so we need to polyfill it.
import { EventSource } from "eventsource";
(globalThis as any).EventSource = EventSource;
function createSQLExecutor(dbPath: string): SQLExecutor {
const db = new Database(dbPath);
db.pragma("journal_mode = WAL");
return {
run: async (sql, params) => {
db.prepare(sql).run(...(params ?? []));
},
get: async <T>(sql: string, params?: unknown[]) =>
db.prepare(sql).get(...(params ?? [])) as T | undefined,
all: async <T>(sql: string, params?: unknown[]) =>
db.prepare(sql).all(...(params ?? [])) as T[],
};
}
async function main() {
console.log("Starting Ark SDK NodeJS Example...");
const bob = SingleKey.fromRandomBytes();
const alice = SingleKey.fromRandomBytes();
// In-memory wallet
const bobWallet = await Wallet.create({
identity: bob,
arkServerUrl: "http://localhost:7070",
esploraUrl: "http://localhost:3000",
storage: {
walletRepository: new InMemoryWalletRepository(),
contractRepository: new InMemoryContractRepository(),
},
});
console.log("[Bob]\tWallet created successfully!");
console.log("[Bob]\tArk Address:", bobWallet.arkAddress.encode());
// SQLite-persisted wallet
const executor = createSQLExecutor("alice-wallet.sqlite");
const aliceWallet = await Wallet.create({
identity: alice,
arkServerUrl: "http://localhost:7070",
esploraUrl: "http://localhost:3000",
storage: {
walletRepository: new SQLiteWalletRepository(executor),
contractRepository: new SQLiteContractRepository(executor),
},
});
console.log("[Alice]\tWallet created successfully!");
console.log("[Alice]\tArk Address:", aliceWallet.arkAddress.encode());
const state: WalletState = {
settings: { theme: "dark" },
};
await aliceWallet.walletRepository.saveWalletState(state);
await bobWallet.walletRepository.saveWalletState(state);
// Fund Alice's boarding address
const boardingAddress = await aliceWallet.getBoardingAddress();
console.log("[Alice]\tBoarding Address:", boardingAddress);
console.log("[Alice]\tFunding boarding address via nigiri faucet...");
execSync(`nigiri faucet ${boardingAddress} 0.001`);
// Wait for the boarding inputs to be available (timeout after 60s)
console.log("[Alice]\tWaiting for boarding UTXOs...");
const deadline = Date.now() + 60_000;
let utxos = await aliceWallet.getBoardingUtxos();
while (utxos.length === 0) {
if (Date.now() > deadline) {
throw new Error("Timed out waiting for boarding UTXOs");
}
await new Promise((resolve) => setTimeout(resolve, 2000));
utxos = await aliceWallet.getBoardingUtxos();
}
console.log("[Alice]\tBoarding UTXOs found:", utxos.length);
// Settle (onboard) into the Ark protocol
console.log("[Alice]\tOnboarding into Ark...");
const info = await aliceWallet.arkProvider.getInfo();
const ramps = new Ramps(aliceWallet);
const txid = await ramps.onboard(info.fees);
console.log("[Alice]\tSettlement txid:", txid);
const bobOffChainAddress = await bobWallet.getAddress();
await aliceWallet.sendBitcoin({
address: bobOffChainAddress,
amount: 50000,
});
console.log("[Alice]\tBalance:", await aliceWallet.getBalance());
console.log("[Bob]\tBalance:", await bobWallet.getBalance());
console.log("Only Alice's data is persisted on disk");
}
main().catch(console.error);