@spirobel/monero-wallet-api 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/api.d.ts +25 -96
- package/dist/api.js +23 -175
- package/dist/io/BunFileInterface.d.ts +32 -0
- package/dist/io/atomicWrite.d.ts +2 -0
- package/dist/io/atomicWrite.js +10 -0
- package/dist/io/extension.d.ts +18 -0
- package/dist/io/extension.js +11 -0
- package/dist/io/indexedDB.d.ts +45 -0
- package/dist/io/indexedDB.js +221 -0
- package/dist/io/readDir.d.ts +1 -0
- package/dist/io/readDir.js +7 -0
- package/dist/io/sleep.d.ts +1 -0
- package/dist/io/sleep.js +1 -0
- package/dist/keypairs-seeds/keypairs.d.ts +29 -0
- package/dist/keypairs-seeds/keypairs.js +207 -0
- package/dist/keypairs-seeds/writeKeypairs.d.ts +11 -0
- package/dist/keypairs-seeds/writeKeypairs.js +75 -0
- package/dist/node-interaction/binaryEndpoints.d.ts +59 -14
- package/dist/node-interaction/binaryEndpoints.js +110 -54
- package/dist/node-interaction/jsonEndpoints.d.ts +249 -187
- package/dist/node-interaction/jsonEndpoints.js +287 -0
- package/dist/node-interaction/nodeUrl.d.ts +129 -0
- package/dist/node-interaction/nodeUrl.js +113 -0
- package/dist/scanning-syncing/backgroundWorker.d.ts +6 -0
- package/dist/scanning-syncing/backgroundWorker.js +56 -0
- package/dist/scanning-syncing/connectionStatus.d.ts +15 -0
- package/dist/scanning-syncing/connectionStatus.js +35 -0
- package/dist/scanning-syncing/openWallet.d.ts +28 -0
- package/dist/scanning-syncing/openWallet.js +57 -0
- package/dist/scanning-syncing/scanSettings.d.ts +96 -0
- package/dist/scanning-syncing/scanSettings.js +243 -0
- package/dist/scanning-syncing/scanresult/computeKeyImage.d.ts +3 -0
- package/dist/scanning-syncing/scanresult/computeKeyImage.js +21 -0
- package/dist/scanning-syncing/scanresult/getBlocksbinBuffer.d.ts +28 -0
- package/dist/scanning-syncing/scanresult/getBlocksbinBuffer.js +52 -0
- package/dist/scanning-syncing/scanresult/reorg.d.ts +14 -0
- package/dist/scanning-syncing/scanresult/reorg.js +78 -0
- package/dist/scanning-syncing/scanresult/scanCache.d.ts +84 -0
- package/dist/scanning-syncing/scanresult/scanCache.js +134 -0
- package/dist/scanning-syncing/scanresult/scanCacheOpened.d.ts +149 -0
- package/dist/scanning-syncing/scanresult/scanCacheOpened.js +648 -0
- package/dist/scanning-syncing/scanresult/scanResult.d.ts +64 -0
- package/dist/scanning-syncing/scanresult/scanResult.js +213 -0
- package/dist/scanning-syncing/scanresult/scanStats.d.ts +60 -0
- package/dist/scanning-syncing/scanresult/scanStats.js +273 -0
- package/dist/scanning-syncing/worker-entrypoints/worker.d.ts +1 -0
- package/dist/scanning-syncing/worker-entrypoints/worker.js +8 -0
- package/dist/scanning-syncing/worker-mains/worker.d.ts +1 -0
- package/dist/scanning-syncing/worker-mains/worker.js +7 -0
- package/dist/send-functionality/conversion.d.ts +4 -0
- package/dist/send-functionality/conversion.js +75 -0
- package/dist/send-functionality/inputSelection.d.ts +13 -0
- package/dist/send-functionality/inputSelection.js +8 -0
- package/dist/send-functionality/transactionBuilding.d.ts +51 -0
- package/dist/send-functionality/transactionBuilding.js +111 -0
- package/dist/tools/monero-tools.d.ts +46 -0
- package/dist/tools/monero-tools.js +165 -0
- package/dist/viewpair/ViewPair.d.ts +157 -0
- package/dist/viewpair/ViewPair.js +346 -0
- package/dist/wasm-processing/wasi.js +1 -2
- package/dist/wasm-processing/wasmFile.d.ts +1 -1
- package/dist/wasm-processing/wasmFile.js +2 -2
- package/dist/wasm-processing/wasmProcessor.d.ts +16 -4
- package/dist/wasm-processing/wasmProcessor.js +23 -7
- package/package.json +29 -6
- package/dist/testscrap.js +0 -36
- /package/dist/{testscrap.d.ts → io/BunFileInterface.js} +0 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { processScanResult, } from "../scanning-syncing/scanresult/scanResult";
|
|
2
|
+
export {};
|
|
3
|
+
export { NodeUrl } from "../node-interaction/nodeUrl";
|
|
4
|
+
import { getBlocksBinScan, getBlocksBinExecuteRequest, getBlocksBinScanResponse, MAINNET_GENESIS_BLOCK_HASH, STAGENET_GENESIS_BLOCK_HASH, } from "../node-interaction/binaryEndpoints";
|
|
5
|
+
import { handleScanError, lastRange, writeCacheFileDefaultLocationThrows, } from "../scanning-syncing/scanresult/scanCache";
|
|
6
|
+
import { makeTransaction, } from "../send-functionality/transactionBuilding";
|
|
7
|
+
import { WasmProcessor } from "../wasm-processing/wasmProcessor";
|
|
8
|
+
import { LOCAL_NODE_DEFAULT_URL } from "../node-interaction/nodeUrl";
|
|
9
|
+
import { atomicWrite, get_block_headers_range, get_info, } from "../api";
|
|
10
|
+
import { readGetblocksBinBuffer, trimGetBlocksBinBuffer, writeGetblocksBinBuffer, } from "../scanning-syncing/scanresult/getBlocksbinBuffer";
|
|
11
|
+
import { initScanCache, readCacheFileDefaultLocation, } from "../scanning-syncing/scanresult/scanCache";
|
|
12
|
+
import { cullTooLargeScanHeight, openNonHaltedWallets, readWalletFromScanSettings, walletSettingsPlusKeys, } from "../scanning-syncing/scanSettings";
|
|
13
|
+
import { sleep } from "../io/sleep";
|
|
14
|
+
import { readWriteConnectionStatusFile, writeConnectionStatusFile, } from "../scanning-syncing/connectionStatus";
|
|
15
|
+
/**
|
|
16
|
+
* This class is useful to interact with Moneros DaemonRpc binary requests in a convenient way.
|
|
17
|
+
* (similar to how you would interact with a REST api that gives you json back.)
|
|
18
|
+
* The wasm part will handle the creation of the binary requests and parse the responses and then parse them
|
|
19
|
+
* and return outputs that belong to the ViewPair.
|
|
20
|
+
* {@link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin}
|
|
21
|
+
*/
|
|
22
|
+
export class ViewPair extends WasmProcessor {
|
|
23
|
+
node_url;
|
|
24
|
+
primary_address;
|
|
25
|
+
_network;
|
|
26
|
+
get network() {
|
|
27
|
+
return this._network; // we set this in ViewPair.create()
|
|
28
|
+
}
|
|
29
|
+
_genesis_hash;
|
|
30
|
+
get genesis_hash() {
|
|
31
|
+
if (!this._genesis_hash) {
|
|
32
|
+
throw new Error("Genesis hash not set. Node not connected?");
|
|
33
|
+
}
|
|
34
|
+
return this._genesis_hash; // set in first call to ViewPair.getBlocksBin, if params.block_ids is supplied
|
|
35
|
+
}
|
|
36
|
+
constructor(node_url, primary_address) {
|
|
37
|
+
super();
|
|
38
|
+
this.node_url = node_url;
|
|
39
|
+
this.primary_address = primary_address;
|
|
40
|
+
}
|
|
41
|
+
static async create(primary_address, secret_view_key, subaddress_index = 0, node_url) {
|
|
42
|
+
const viewPair = new ViewPair(node_url || LOCAL_NODE_DEFAULT_URL, primary_address);
|
|
43
|
+
const tinywasi = await viewPair.initWasmModule();
|
|
44
|
+
viewPair.writeToWasmMemory = (ptr, len) => {
|
|
45
|
+
viewPair.writeString(ptr, len, primary_address);
|
|
46
|
+
viewPair.writeToWasmMemory = (ptr, len) => {
|
|
47
|
+
viewPair.writeString(ptr, len, secret_view_key);
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
let init_viewpair_result = undefined;
|
|
51
|
+
viewPair.readFromWasmMemory = (ptr, len) => {
|
|
52
|
+
init_viewpair_result = JSON.parse(viewPair.readString(ptr, len));
|
|
53
|
+
};
|
|
54
|
+
//@ts-ignore
|
|
55
|
+
tinywasi.instance.exports.init_viewpair(primary_address.length, secret_view_key.length, subaddress_index);
|
|
56
|
+
if (!init_viewpair_result) {
|
|
57
|
+
throw new Error("Failed to init viewpair");
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
//@ts-ignore
|
|
61
|
+
viewPair._network = init_viewpair_result.network;
|
|
62
|
+
}
|
|
63
|
+
return viewPair;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* This function helps with making requests to the get_blocks.bin endpoint of the Monerod nodes. It does the Request and returns the outputs that belong to the ViewPair.
|
|
67
|
+
* (if outputs are found in the blocks that are returned)
|
|
68
|
+
*
|
|
69
|
+
* if params.block_ids is supplied, it will add the genesis hash to the end of the block_ids array.
|
|
70
|
+
* (so you can just supply the block_id you want to start fetching from)
|
|
71
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
72
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
73
|
+
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
74
|
+
* @param stopSync optional AbortSignal to stop the syncing process
|
|
75
|
+
* @returns The difference to the same method on NodeUrl is: It returns {@link ScanResult} (outputs that belong to viewpair) and not just the blocks as json.
|
|
76
|
+
*/
|
|
77
|
+
async getBlocksBin(params, metaCallBack, stopSync) {
|
|
78
|
+
return await getBlocksBinScan(this, await this.addGenesisHashToBlockIds(params), metaCallBack, stopSync);
|
|
79
|
+
}
|
|
80
|
+
async addGenesisHashToBlockIds(params) {
|
|
81
|
+
if (params.block_ids) {
|
|
82
|
+
if (!this._genesis_hash && this.network === "mainnet") {
|
|
83
|
+
this._genesis_hash = MAINNET_GENESIS_BLOCK_HASH;
|
|
84
|
+
}
|
|
85
|
+
if (!this._genesis_hash && this.network === "stagenet") {
|
|
86
|
+
this._genesis_hash = STAGENET_GENESIS_BLOCK_HASH;
|
|
87
|
+
}
|
|
88
|
+
if (!this._genesis_hash) {
|
|
89
|
+
// TESTNET
|
|
90
|
+
const range = await this.getBlockHeadersRange({
|
|
91
|
+
start_height: 0,
|
|
92
|
+
end_height: 0,
|
|
93
|
+
});
|
|
94
|
+
this._genesis_hash = range.headers[0].hash;
|
|
95
|
+
}
|
|
96
|
+
params.block_ids.push(this.genesis_hash);
|
|
97
|
+
}
|
|
98
|
+
return params;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* This function helps with making requests to the get_blocks.bin endpoint of the Monerod nodes.
|
|
102
|
+
* if params.block_ids is supplied, it will add the genesis hash to the end of the block_ids array.
|
|
103
|
+
* (so you can just supply the block_id you want to start fetching from)
|
|
104
|
+
*
|
|
105
|
+
* The difference compared to the getBlocksBin method is that it returns a Uint8Array that still has to be scanned for outputs.
|
|
106
|
+
* This is useful if you want to scan multiple viewpairs at once. You can take the Uint8Array and pass it to another ViewPair to scan for outputs.
|
|
107
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
108
|
+
* @param stopSync optional AbortSignal to stop the syncing process
|
|
109
|
+
* @returns This method will return a Uint8Array that can subsequently be scanned for outputs with the getBlocksBinScanResponse method.
|
|
110
|
+
*/
|
|
111
|
+
async getBlocksBinExecuteRequest(params, stopSync) {
|
|
112
|
+
return await getBlocksBinExecuteRequest(this, await this.addGenesisHashToBlockIds(params), stopSync);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* This function helps with scanning the response of the getBlocksBinExecuteRequest method.
|
|
116
|
+
* It will parse the Uint8Array and return the outputs that belong to the ViewPair.
|
|
117
|
+
* (if outputs are found in the blocks that are contained in the Uint8Array that was returned by the getBlocksBinExecuteRequest method)
|
|
118
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
119
|
+
* @param getBlocksBinResponseBuffer the Uint8Array that was returned by the getBlocksBinExecuteRequest method.(which contains the blocks in binary format, returned from the Monerod node)
|
|
120
|
+
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
121
|
+
* @returns It returns {@link ScanResult} (outputs that belong to viewpair)
|
|
122
|
+
*/
|
|
123
|
+
getBlocksBinScanResponse(getBlocksBinResponseBuffer, metaCallBack) {
|
|
124
|
+
return getBlocksBinScanResponse(this, getBlocksBinResponseBuffer, metaCallBack);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* scan
|
|
128
|
+
*/
|
|
129
|
+
async scan(cacheChanged = (params) => console.log(params), stopSync, scan_settings_path, pathPrefix) {
|
|
130
|
+
const processor = this;
|
|
131
|
+
const nonHaltedWallets = await openNonHaltedWallets(scan_settings_path);
|
|
132
|
+
const masterWalletSettings = nonHaltedWallets[0];
|
|
133
|
+
if (masterWalletSettings.primary_address !== this.primary_address)
|
|
134
|
+
throw new Error("master wallet should be the first of the non halted wallets");
|
|
135
|
+
let masterStartHeight = await cullTooLargeScanHeight(processor.node_url, scan_settings_path);
|
|
136
|
+
let current_range = await initScanCache(processor, masterStartHeight, scan_settings_path, pathPrefix);
|
|
137
|
+
const blockGenerator = (async function* () {
|
|
138
|
+
while (true) {
|
|
139
|
+
if (stopSync?.aborted)
|
|
140
|
+
return;
|
|
141
|
+
const firstResponse = await processor.getBlocksBinExecuteRequest({ block_ids: current_range.block_hashes.map((b) => b.block_hash) }, stopSync);
|
|
142
|
+
await readWriteConnectionStatusFile((cs) => {
|
|
143
|
+
if (cs?.last_packet.status === "catastrophic_reorg")
|
|
144
|
+
return;
|
|
145
|
+
const connectionStatus = {
|
|
146
|
+
last_packet: {
|
|
147
|
+
status: "OK",
|
|
148
|
+
bytes_read: firstResponse.length,
|
|
149
|
+
node_url: processor.node_url,
|
|
150
|
+
timestamp: new Date().toISOString(),
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
return connectionStatus;
|
|
154
|
+
});
|
|
155
|
+
yield firstResponse;
|
|
156
|
+
}
|
|
157
|
+
})();
|
|
158
|
+
const masterWithKeys = await walletSettingsPlusKeys(masterWalletSettings);
|
|
159
|
+
const slaveViewPairs = [];
|
|
160
|
+
if (nonHaltedWallets.length > 1) {
|
|
161
|
+
for (const slaveWallet of nonHaltedWallets.slice(1)) {
|
|
162
|
+
const slaveWithKeys = await walletSettingsPlusKeys(slaveWallet);
|
|
163
|
+
const viewpair = await ViewPair.create(slaveWallet.primary_address, slaveWithKeys.secret_view_key, slaveWallet.subaddress_index, masterWalletSettings.node_url);
|
|
164
|
+
slaveViewPairs.push({
|
|
165
|
+
viewpair,
|
|
166
|
+
current_range: await initScanCache(viewpair, masterStartHeight, scan_settings_path, pathPrefix),
|
|
167
|
+
secret_spend_key: slaveWithKeys.secret_spend_key,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const catastrophic_reorg_cb = async () => {
|
|
172
|
+
writeConnectionStatusFile("catastrophic_reorg", processor.node_url, undefined, scan_settings_path);
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
for await (const firstResponse of blockGenerator) {
|
|
176
|
+
if (!firstResponse)
|
|
177
|
+
continue;
|
|
178
|
+
await this.writeSubaddressesToScanCache(scan_settings_path, pathPrefix);
|
|
179
|
+
const result = await processor.getBlocksBinScanResponse(firstResponse);
|
|
180
|
+
const oldMasterCurrentRange = structuredClone(current_range);
|
|
181
|
+
current_range = await processScanResult({
|
|
182
|
+
current_range,
|
|
183
|
+
result,
|
|
184
|
+
cacheChanged,
|
|
185
|
+
secret_spend_key: masterWithKeys.secret_spend_key,
|
|
186
|
+
pathPrefix,
|
|
187
|
+
catastrophic_reorg_cb,
|
|
188
|
+
});
|
|
189
|
+
if (slaveViewPairs.length > 0) {
|
|
190
|
+
if (result && "block_infos" in result)
|
|
191
|
+
await writeGetblocksBinBuffer(firstResponse, result.block_infos, pathPrefix); // feed the slaves
|
|
192
|
+
for (const slave of slaveViewPairs) {
|
|
193
|
+
let blocksBinItems = await readGetblocksBinBuffer(slave.current_range.end, pathPrefix);
|
|
194
|
+
let use_master_current_range = false;
|
|
195
|
+
if (!blocksBinItems.length) {
|
|
196
|
+
blocksBinItems = await readGetblocksBinBuffer(current_range.end, // we use the new current range end to find the blocks
|
|
197
|
+
pathPrefix);
|
|
198
|
+
slave.current_range = structuredClone(oldMasterCurrentRange); // but we use the old master current range to scan with slaves
|
|
199
|
+
use_master_current_range = true;
|
|
200
|
+
}
|
|
201
|
+
for (const blocksBinItem of blocksBinItems) {
|
|
202
|
+
const blocksbin = new Uint8Array(await Bun.file(`${pathPrefix ?? ""}getblocksbinbuffer/${blocksBinItem.filename}`).arrayBuffer());
|
|
203
|
+
await slave.viewpair.writeSubaddressesToScanCache(scan_settings_path, pathPrefix);
|
|
204
|
+
const slaveResult = await slave.viewpair.getBlocksBinScanResponse(blocksbin);
|
|
205
|
+
slave.current_range = await processScanResult({
|
|
206
|
+
current_range: slave.current_range,
|
|
207
|
+
result: slaveResult,
|
|
208
|
+
cacheChanged,
|
|
209
|
+
secret_spend_key: slave.secret_spend_key,
|
|
210
|
+
pathPrefix,
|
|
211
|
+
use_master_current_range,
|
|
212
|
+
catastrophic_reorg_cb,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
} // scan the slaves
|
|
216
|
+
await trimGetBlocksBinBuffer(nonHaltedWallets, pathPrefix);
|
|
217
|
+
}
|
|
218
|
+
if (!result ||
|
|
219
|
+
(result && "block_infos" in result && result.block_infos.length === 0)) {
|
|
220
|
+
// we are at the tip, and there are no new blocks
|
|
221
|
+
// sleep for 1 second before sending another
|
|
222
|
+
// getBlocks.bin request
|
|
223
|
+
//
|
|
224
|
+
await sleep(1000);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
handleScanError(error);
|
|
230
|
+
const cache = await readCacheFileDefaultLocation(processor.primary_address, pathPrefix);
|
|
231
|
+
if (!cache)
|
|
232
|
+
throw new Error(`${error} in scan() + cache not found for primary address: ${processor.primary_address} and path prefix: ${pathPrefix}`);
|
|
233
|
+
await cacheChanged({
|
|
234
|
+
newCache: cache,
|
|
235
|
+
changed_outputs: [],
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* This method makes an integrated Address for the Address of the Viewpair it was opened with.
|
|
241
|
+
* The network (mainnet, stagenet, testnet) is the same as the one of the Viewpairaddress.
|
|
242
|
+
* @param paymentId (u64 under the hood) you can use a random number or a primary key of an sqlite db to associate payments with customer sessions.
|
|
243
|
+
* @returns Adressstring
|
|
244
|
+
*/
|
|
245
|
+
makeIntegratedAddress(paymentId) {
|
|
246
|
+
let address = "";
|
|
247
|
+
this.readFromWasmMemory = (ptr, len) => {
|
|
248
|
+
address = this.readString(ptr, len);
|
|
249
|
+
};
|
|
250
|
+
//@ts-ignore
|
|
251
|
+
this.tinywasi.instance.exports.make_integrated_address(BigInt(paymentId));
|
|
252
|
+
return address;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* This method makes a Subaddress for the Address of the Viewpair it was opened with.
|
|
256
|
+
* The network (mainnet, stagenet, testnet) is the same as the one of the Viewpairaddress.
|
|
257
|
+
* if there is an active scan going on, call this on ScanCacheOpened, so the new subaddress will be scanned
|
|
258
|
+
*
|
|
259
|
+
* @param minor address index, we always set major (also called account index) to 0
|
|
260
|
+
* @returns Adressstring
|
|
261
|
+
*/
|
|
262
|
+
makeSubaddress(minor) {
|
|
263
|
+
return this.makeSubaddressRaw(0, minor);
|
|
264
|
+
}
|
|
265
|
+
async writeSubaddressesToScanCache(scan_settings_path, pathPrefix) {
|
|
266
|
+
await writeCacheFileDefaultLocationThrows({
|
|
267
|
+
primary_address: this.primary_address,
|
|
268
|
+
pathPrefix: pathPrefix,
|
|
269
|
+
writeCallback: async (cache) => {
|
|
270
|
+
await this.addSubaddressesToScanCache(cache, scan_settings_path);
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async addSubaddressesToScanCache(cache, scan_settings_path) {
|
|
275
|
+
const walletSettings = await readWalletFromScanSettings(this.primary_address, scan_settings_path);
|
|
276
|
+
if (!walletSettings)
|
|
277
|
+
throw new Error(`wallet not found in settings. did you call openwallet with the right params?
|
|
278
|
+
Either wrong file name supplied to params.scan_settings_path: ${scan_settings_path}
|
|
279
|
+
Or wrong primary_address supplied params.primary_address: ${this.primary_address}`);
|
|
280
|
+
const last_subaddress_index = walletSettings.subaddress_index || 1;
|
|
281
|
+
if (!cache.subaddresses)
|
|
282
|
+
cache.subaddresses = [];
|
|
283
|
+
const highestMinor = Math.max(...cache.subaddresses.map((sub) => sub.minor), 0);
|
|
284
|
+
let minor = highestMinor + 1;
|
|
285
|
+
while (minor <= last_subaddress_index) {
|
|
286
|
+
const subaddress = this.makeSubaddress(minor);
|
|
287
|
+
const created_at_height = lastRange(cache.scanned_ranges)?.end || 0;
|
|
288
|
+
const created_at_timestamp = new Date().getTime();
|
|
289
|
+
cache.subaddresses.push({
|
|
290
|
+
minor,
|
|
291
|
+
address: subaddress,
|
|
292
|
+
created_at_height,
|
|
293
|
+
created_at_timestamp,
|
|
294
|
+
});
|
|
295
|
+
minor++;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* This method makes a Subaddress for the Address of the Viewpair it was opened with.
|
|
300
|
+
* The network (mainnet, stagenet, testnet) is the same as the one of the Viewpairaddress.
|
|
301
|
+
*
|
|
302
|
+
* @param major account index should be set to 0 in most cases
|
|
303
|
+
* @param minor address index starting at 1
|
|
304
|
+
* @returns Adressstring
|
|
305
|
+
*/
|
|
306
|
+
makeSubaddressRaw(major, minor) {
|
|
307
|
+
if (typeof major !== "number" ||
|
|
308
|
+
typeof minor !== "number" ||
|
|
309
|
+
major < 0 ||
|
|
310
|
+
minor < 1)
|
|
311
|
+
throw new Error(`subaddress major and minor must be positive numbers, minor index must be above 1.
|
|
312
|
+
makeSubaddressRaw arguments: major: ${major}, minor: ${minor}`);
|
|
313
|
+
let address = "";
|
|
314
|
+
this.readFromWasmMemory = (ptr, len) => {
|
|
315
|
+
address = this.readString(ptr, len);
|
|
316
|
+
};
|
|
317
|
+
//@ts-ignore
|
|
318
|
+
this.tinywasi.instance.exports.make_subaddress(major, minor);
|
|
319
|
+
return address;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Creates a signable transaction using the provided parameters.
|
|
323
|
+
* @param params - The transaction parameters.
|
|
324
|
+
* @returns The serialized transaction as an array of numbers.
|
|
325
|
+
*/
|
|
326
|
+
makeTransaction(params) {
|
|
327
|
+
return makeTransaction(this, params);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Retrieve block headers for a specified range of heights.
|
|
331
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_block_headers_range
|
|
332
|
+
* @param params The parameters including start_height, end_height, and optional fill_pow_hash.
|
|
333
|
+
* @returns The result object with headers, status, etc. Throws if the range is invalid:(end_height > daemonheight)
|
|
334
|
+
*/
|
|
335
|
+
async getBlockHeadersRange(params) {
|
|
336
|
+
return await get_block_headers_range(this.node_url, params);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Fetch general information about the Monero daemon.
|
|
340
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_info
|
|
341
|
+
* @returns The result object with daemon info like height, status, etc.
|
|
342
|
+
*/
|
|
343
|
+
async getInfo() {
|
|
344
|
+
return get_info(this.node_url);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as crypto from "crypto";
|
|
2
1
|
//vendored from https://github.com/qrdate/tinywasi/blob/main/src/TinyWASI.ts
|
|
3
2
|
export class TinyWASI {
|
|
4
3
|
instance = undefined;
|
|
@@ -162,7 +161,7 @@ export class TinyWASI {
|
|
|
162
161
|
random_get(pointer, size) {
|
|
163
162
|
const memory = this.getMemory();
|
|
164
163
|
const buffer = new Uint8Array(memory.buffer, pointer, size);
|
|
165
|
-
crypto.
|
|
164
|
+
crypto.getRandomValues(buffer);
|
|
166
165
|
return this.WASI_ERRNO_SUCCESS;
|
|
167
166
|
}
|
|
168
167
|
environ_sizes_get(environCount, environBufSize) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const monero_wallet_api_wasm: Uint8Array
|
|
1
|
+
export declare const monero_wallet_api_wasm: Uint8Array<ArrayBuffer>;
|