@spirobel/monero-wallet-api 0.1.1 → 0.2.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 +12 -0
- package/dist/api.d.ts +45 -2
- package/dist/api.js +83 -9
- package/dist/node-interaction/binaryEndpoints.d.ts +12 -0
- package/dist/node-interaction/binaryEndpoints.js +22 -4
- package/dist/testscrap.d.ts +1 -0
- package/dist/testscrap.js +36 -0
- package/dist/wasm-processing/wasmFile.js +8 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,6 +21,18 @@ cd rust || cd ../rust
|
|
|
21
21
|
cargo wasi build --target wasm32-wasip1 --release --lib
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
prerequisite: install rust
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
rustup install 1.83.0
|
|
32
|
+
rustup default 1.83.0
|
|
33
|
+
rustup target add wasm32-wasip1
|
|
34
|
+
```
|
|
35
|
+
|
|
24
36
|
## reproducible build with pinned cargo + rust + cargo wasi
|
|
25
37
|
|
|
26
38
|
make the image
|
package/dist/api.d.ts
CHANGED
|
@@ -13,13 +13,32 @@ export type ScanResultCallback = (result: ScanResult | ErrorResponse) => void;
|
|
|
13
13
|
export declare class ViewPair extends WasmProcessor {
|
|
14
14
|
static create(primary_address: string, secret_view_key: string, node_url?: string): Promise<ViewPair>;
|
|
15
15
|
/**
|
|
16
|
-
* This
|
|
16
|
+
* 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.
|
|
17
|
+
* (if outputs are found in the blocks that are returned)
|
|
17
18
|
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
18
|
-
* @param params params that will be turned into epee (
|
|
19
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
19
20
|
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
20
21
|
* @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.
|
|
21
22
|
*/
|
|
22
23
|
getBlocksBin(params: GetBlocksBinRequest, metaCallBack?: GetBlocksBinMetaCallback): Promise<ScanResult | ErrorResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* This function helps with making requests to the get_blocks.bin endpoint of the Monerod nodes.
|
|
26
|
+
* The difference compared to the getBlocksBin method is that it returns a Uint8Array that still has to be scanned for outputs.
|
|
27
|
+
* 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.
|
|
28
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
29
|
+
* @returns This method will return a Uint8Array that can subsequently be scanned for outputs with the getBlocksBinScanResponse method.
|
|
30
|
+
*/
|
|
31
|
+
getBlocksBinExecuteRequest(params: GetBlocksBinRequest): Promise<Uint8Array>;
|
|
32
|
+
/**
|
|
33
|
+
* This function helps with scanning the response of the getBlocksBinExecuteRequest method.
|
|
34
|
+
* It will parse the Uint8Array and return the outputs that belong to the ViewPair.
|
|
35
|
+
* (if outputs are found in the blocks that are contained in the Uint8Array that was returned by the getBlocksBinExecuteRequest method)
|
|
36
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
37
|
+
* @param getBlocksBinResponseBuffer the Uint8Array that was returned by the getBlocksBinExecuteRequest method.(which contains the blocks in binary format, returned from the Monerod node)
|
|
38
|
+
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
39
|
+
* @returns It returns {@link ScanResult} (outputs that belong to viewpair)
|
|
40
|
+
*/
|
|
41
|
+
getBlocksBinScanResponse(getBlocksBinResponseBuffer: Uint8Array, metaCallBack?: GetBlocksBinMetaCallback): Promise<ScanResult | ErrorResponse>;
|
|
23
42
|
/**
|
|
24
43
|
* This method will use getBlocks.bin from start height to daemon height.
|
|
25
44
|
* This is CPU bound work, so it should be executed in a seperate thread (worker).
|
|
@@ -53,3 +72,27 @@ export declare class NodeUrl extends WasmProcessor {
|
|
|
53
72
|
*/
|
|
54
73
|
getBlocksBin(params: GetBlocksBinRequest): Promise<import("./api").GetBlocksBinResponse | ErrorResponse>;
|
|
55
74
|
}
|
|
75
|
+
export type AddressAndViewKey = {
|
|
76
|
+
primary_address: string;
|
|
77
|
+
secret_view_key: string;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* The ViewPairs class contains a set of ViewPair objects that can be used to scan multiple addresses at once.
|
|
81
|
+
* (while only retrieving the blocks from the node once)
|
|
82
|
+
*/
|
|
83
|
+
export declare class ViewPairs {
|
|
84
|
+
private viewPairs;
|
|
85
|
+
protected constructor();
|
|
86
|
+
static create(pairs: AddressAndViewKey[], node_url?: string): Promise<ViewPairs>;
|
|
87
|
+
addViewPair(primary_address: string, secret_view_key: string, node_url?: string): Promise<ViewPair>;
|
|
88
|
+
getViewPair(primary_address: string): ViewPair | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* This method will use getBlocks.bin from start height to daemon height.
|
|
91
|
+
* This is CPU bound work, so it should be executed in a seperate thread (worker).
|
|
92
|
+
* The scanner.ts worker in the standard-checkout dir shows how to keep scanning after the tip is reached.
|
|
93
|
+
* It also shows how the outputs are saved (note the unqiue requirement for the stealth_adress).
|
|
94
|
+
* @param start_height the height to start syncing from.
|
|
95
|
+
* @param callback this function will get the new outputs as they are found as a parameter
|
|
96
|
+
*/
|
|
97
|
+
scan(start_height: number, callback: ScanResultCallback): Promise<void>;
|
|
98
|
+
}
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getBlocksBinJson, getBlocksBinScan, } from "./node-interaction/binaryEndpoints";
|
|
1
|
+
import { getBlocksBinJson, getBlocksBinScan, getBlocksBinExecuteRequest, getBlocksBinScanResponse, } from "./node-interaction/binaryEndpoints";
|
|
2
2
|
import { TinyWASI } from "./wasm-processing/wasi";
|
|
3
3
|
import { WasmProcessor } from "./wasm-processing/wasmProcessor";
|
|
4
4
|
export * from "./node-interaction/binaryEndpoints";
|
|
@@ -25,15 +25,38 @@ export class ViewPair extends WasmProcessor {
|
|
|
25
25
|
return viewPair;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* This
|
|
28
|
+
* 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.
|
|
29
|
+
* (if outputs are found in the blocks that are returned)
|
|
29
30
|
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
30
|
-
* @param params params that will be turned into epee (
|
|
31
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
31
32
|
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
32
33
|
* @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.
|
|
33
34
|
*/
|
|
34
35
|
getBlocksBin(params, metaCallBack) {
|
|
35
36
|
return getBlocksBinScan(this, params, metaCallBack);
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* This function helps with making requests to the get_blocks.bin endpoint of the Monerod nodes.
|
|
40
|
+
* The difference compared to the getBlocksBin method is that it returns a Uint8Array that still has to be scanned for outputs.
|
|
41
|
+
* 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.
|
|
42
|
+
* @param params params that will be turned into epee (monero lib that does binary serialization)
|
|
43
|
+
* @returns This method will return a Uint8Array that can subsequently be scanned for outputs with the getBlocksBinScanResponse method.
|
|
44
|
+
*/
|
|
45
|
+
async getBlocksBinExecuteRequest(params) {
|
|
46
|
+
return await getBlocksBinExecuteRequest(this, params);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* This function helps with scanning the response of the getBlocksBinExecuteRequest method.
|
|
50
|
+
* It will parse the Uint8Array and return the outputs that belong to the ViewPair.
|
|
51
|
+
* (if outputs are found in the blocks that are contained in the Uint8Array that was returned by the getBlocksBinExecuteRequest method)
|
|
52
|
+
* @link https://docs.getmonero.org/rpc-library/monerod-rpc/#get_blocksbin
|
|
53
|
+
* @param getBlocksBinResponseBuffer the Uint8Array that was returned by the getBlocksBinExecuteRequest method.(which contains the blocks in binary format, returned from the Monerod node)
|
|
54
|
+
* @param metaCallBack contains meta information about the getBlocksbin call (new sync height = start_height param + number of blocks)
|
|
55
|
+
* @returns It returns {@link ScanResult} (outputs that belong to viewpair)
|
|
56
|
+
*/
|
|
57
|
+
getBlocksBinScanResponse(getBlocksBinResponseBuffer, metaCallBack) {
|
|
58
|
+
return getBlocksBinScanResponse(this, getBlocksBinResponseBuffer, metaCallBack);
|
|
59
|
+
}
|
|
37
60
|
/**
|
|
38
61
|
* This method will use getBlocks.bin from start height to daemon height.
|
|
39
62
|
* This is CPU bound work, so it should be executed in a seperate thread (worker).
|
|
@@ -47,6 +70,7 @@ export class ViewPair extends WasmProcessor {
|
|
|
47
70
|
new_height: start_height,
|
|
48
71
|
daemon_height: start_height + 1,
|
|
49
72
|
status: "",
|
|
73
|
+
primary_address: "",
|
|
50
74
|
};
|
|
51
75
|
while (latest_meta.new_height < latest_meta.daemon_height) {
|
|
52
76
|
const res = await this.getBlocksBin({
|
|
@@ -95,9 +119,59 @@ export class NodeUrl extends WasmProcessor {
|
|
|
95
119
|
return getBlocksBinJson(this, params);
|
|
96
120
|
}
|
|
97
121
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
/**
|
|
123
|
+
* The ViewPairs class contains a set of ViewPair objects that can be used to scan multiple addresses at once.
|
|
124
|
+
* (while only retrieving the blocks from the node once)
|
|
125
|
+
*/
|
|
126
|
+
export class ViewPairs {
|
|
127
|
+
viewPairs;
|
|
128
|
+
constructor() {
|
|
129
|
+
this.viewPairs = new Map();
|
|
130
|
+
}
|
|
131
|
+
static async create(pairs, node_url) {
|
|
132
|
+
const viewPairs = new ViewPairs();
|
|
133
|
+
for (const element of pairs) {
|
|
134
|
+
const viewPair = await ViewPair.create(element.primary_address, element.secret_view_key, node_url);
|
|
135
|
+
viewPairs.viewPairs.set(element.primary_address, viewPair);
|
|
136
|
+
}
|
|
137
|
+
return viewPairs;
|
|
138
|
+
}
|
|
139
|
+
async addViewPair(primary_address, secret_view_key, node_url) {
|
|
140
|
+
const viewPair = await ViewPair.create(primary_address, secret_view_key, node_url);
|
|
141
|
+
this.viewPairs.set(primary_address, viewPair);
|
|
142
|
+
return viewPair;
|
|
143
|
+
}
|
|
144
|
+
getViewPair(primary_address) {
|
|
145
|
+
return this.viewPairs.get(primary_address);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* This method will use getBlocks.bin from start height to daemon height.
|
|
149
|
+
* This is CPU bound work, so it should be executed in a seperate thread (worker).
|
|
150
|
+
* The scanner.ts worker in the standard-checkout dir shows how to keep scanning after the tip is reached.
|
|
151
|
+
* It also shows how the outputs are saved (note the unqiue requirement for the stealth_adress).
|
|
152
|
+
* @param start_height the height to start syncing from.
|
|
153
|
+
* @param callback this function will get the new outputs as they are found as a parameter
|
|
154
|
+
*/
|
|
155
|
+
async scan(start_height, callback) {
|
|
156
|
+
let latest_meta = {
|
|
157
|
+
new_height: start_height,
|
|
158
|
+
daemon_height: start_height + 1,
|
|
159
|
+
status: "",
|
|
160
|
+
primary_address: "",
|
|
161
|
+
};
|
|
162
|
+
while (latest_meta.new_height < latest_meta.daemon_height) {
|
|
163
|
+
let firstResponse;
|
|
164
|
+
for (const [key, value] of this.viewPairs) {
|
|
165
|
+
if (!firstResponse) {
|
|
166
|
+
firstResponse = await value.getBlocksBinExecuteRequest({
|
|
167
|
+
start_height: latest_meta.new_height - 1,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
const res = await value.getBlocksBinScanResponse(firstResponse, (meta) => {
|
|
171
|
+
latest_meta = meta;
|
|
172
|
+
});
|
|
173
|
+
callback(res);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -37,6 +37,7 @@ export type GetBlocksResultMeta = {
|
|
|
37
37
|
new_height: number;
|
|
38
38
|
daemon_height: number;
|
|
39
39
|
status: Status;
|
|
40
|
+
primary_address: "parsing-monerod-response-without-wallet" | "error-address-not-set" | string;
|
|
40
41
|
};
|
|
41
42
|
export type Output = {
|
|
42
43
|
amount: number;
|
|
@@ -46,15 +47,26 @@ export type Output = {
|
|
|
46
47
|
payment_id: number;
|
|
47
48
|
stealth_address: string;
|
|
48
49
|
tx_hash: string;
|
|
50
|
+
primary_address: string;
|
|
49
51
|
};
|
|
50
52
|
export type ScanResult = {
|
|
51
53
|
outputs: Output[];
|
|
52
54
|
new_height: number;
|
|
55
|
+
primary_address: string;
|
|
53
56
|
};
|
|
54
57
|
export type ErrorResponse = {
|
|
55
58
|
error: string;
|
|
56
59
|
};
|
|
57
60
|
export type GetBlocksBinMetaCallback = (meta: GetBlocksResultMeta) => void;
|
|
61
|
+
/**
|
|
62
|
+
* This function creates a binary request to the get_blocks.bin endpoint of the Monerod node.
|
|
63
|
+
* @param processor it uses the wasm module to build the request and parse the response.
|
|
64
|
+
* @param params params that will be turned into epee (moner lib that does binary serialization)
|
|
65
|
+
* @returns a Uint8Array that can be used to make a fetch request to the get_blocks.bin endpoint.
|
|
66
|
+
*/
|
|
67
|
+
export declare function getBlocksBinMakeRequest<T extends WasmProcessor>(processor: T, params: GetBlocksBinRequest): Uint8Array;
|
|
68
|
+
export declare function getBlocksBinExecuteRequest<T extends WasmProcessor>(processor: T, params: GetBlocksBinRequest): Promise<Uint8Array>;
|
|
69
|
+
export declare function getBlocksBinScanResponse<T extends WasmProcessor>(processor: T, getBlocksBinResponseBuffer: Uint8Array, metaCallBack?: GetBlocksBinMetaCallback): Promise<ScanResult | ErrorResponse>;
|
|
58
70
|
export declare function getBlocksBinScan<T extends WasmProcessor>(processor: T, params: GetBlocksBinRequest, metaCallBack?: GetBlocksBinMetaCallback): Promise<ScanResult | ErrorResponse>;
|
|
59
71
|
export declare function getBlocksBinJson<T extends WasmProcessor>(processor: T, params: GetBlocksBinRequest): Promise<GetBlocksBinResponse | ErrorResponse>;
|
|
60
72
|
export declare function binaryFetchRequest(url: string, body: Uint8Array): Promise<Uint8Array>;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* This function creates a binary request to the get_blocks.bin endpoint of the Monerod node.
|
|
3
|
+
* @param processor it uses the wasm module to build the request and parse the response.
|
|
4
|
+
* @param params params that will be turned into epee (moner lib that does binary serialization)
|
|
5
|
+
* @returns a Uint8Array that can be used to make a fetch request to the get_blocks.bin endpoint.
|
|
6
|
+
*/
|
|
7
|
+
export function getBlocksBinMakeRequest(processor, params) {
|
|
2
8
|
// https://github.com/monero-project/monero/blob/941ecefab21db382e88065c16659864cb8e763ae/src/rpc/core_rpc_server_commands_defs.h#L178
|
|
3
9
|
// enum REQUESTED_INFO
|
|
4
10
|
// {
|
|
@@ -21,14 +27,21 @@ export async function getBlocksBinScan(processor, params, metaCallBack) {
|
|
|
21
27
|
if (params.no_miner_tx) {
|
|
22
28
|
no_miner_tx_num = 1;
|
|
23
29
|
}
|
|
24
|
-
let
|
|
30
|
+
let getBlocksRequestArray;
|
|
25
31
|
processor.readFromWasmMemory = (ptr, len) => {
|
|
26
|
-
|
|
32
|
+
getBlocksRequestArray = processor.readArray(ptr, len);
|
|
27
33
|
};
|
|
28
34
|
//@ts-ignore
|
|
29
35
|
processor.tinywasi.instance.exports.build_getblocksbin_request(requested_info, BigInt(params.start_height), prune_num, no_miner_tx_num, BigInt(params.pool_info_since || 0));
|
|
30
|
-
|
|
36
|
+
return getBlocksRequestArray; // written in build_getblocksbin_request call to readFromWasmMemory
|
|
37
|
+
}
|
|
38
|
+
export async function getBlocksBinExecuteRequest(processor, params) {
|
|
39
|
+
const getBlocksRequestArray = getBlocksBinMakeRequest(processor, params);
|
|
40
|
+
const getBlocksBinResponseBuffer = await binaryFetchRequest(processor.node_url + "/getblocks.bin", getBlocksRequestArray // written in build_getblocksbin_request call to readFromWasmMemory
|
|
31
41
|
);
|
|
42
|
+
return getBlocksBinResponseBuffer;
|
|
43
|
+
}
|
|
44
|
+
export async function getBlocksBinScanResponse(processor, getBlocksBinResponseBuffer, metaCallBack) {
|
|
32
45
|
processor.writeToWasmMemory = (ptr, len) => {
|
|
33
46
|
processor.writeArray(ptr, len, getBlocksBinResponseBuffer);
|
|
34
47
|
};
|
|
@@ -42,6 +55,7 @@ export async function getBlocksBinScan(processor, params, metaCallBack) {
|
|
|
42
55
|
result = JSON.parse(processor.readString(ptr, len));
|
|
43
56
|
if (!("error" in result)) {
|
|
44
57
|
result.new_height = resultMeta.new_height;
|
|
58
|
+
result.primary_address = resultMeta.primary_address;
|
|
45
59
|
}
|
|
46
60
|
};
|
|
47
61
|
};
|
|
@@ -49,6 +63,10 @@ export async function getBlocksBinScan(processor, params, metaCallBack) {
|
|
|
49
63
|
processor.tinywasi.instance.exports.scan_blocks_with_get_blocks_bin(getBlocksBinResponseBuffer.length);
|
|
50
64
|
return result; //result written in scan_blocks_with_get_blocks_bin
|
|
51
65
|
}
|
|
66
|
+
export async function getBlocksBinScan(processor, params, metaCallBack) {
|
|
67
|
+
const getBlocksBinResponseBuffer = await getBlocksBinExecuteRequest(processor, params);
|
|
68
|
+
return getBlocksBinScanResponse(processor, getBlocksBinResponseBuffer, metaCallBack);
|
|
69
|
+
}
|
|
52
70
|
export async function getBlocksBinJson(processor, params) {
|
|
53
71
|
// https://github.com/monero-project/monero/blob/941ecefab21db382e88065c16659864cb8e763ae/src/rpc/core_rpc_server_commands_defs.h#L178
|
|
54
72
|
// enum REQUESTED_INFO
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//57wmxQgZugZRrsaZ2mhcVtZqrUxAB6nXdEj4pnQ975Te2J2djFbBEubUFxTwxurF4cYE1oF8m26BkA9QcZZXLkf3FM7qX9U
|
|
2
|
+
//8e4fe64233b5a0213e06ef4662582f72d47f7304502654485050c8ac06ee0309
|
|
3
|
+
// const viewpairs = await ViewPairs.create([
|
|
4
|
+
// {
|
|
5
|
+
// primary_address:
|
|
6
|
+
// "5B5ieVKGSyfAyh68X6AFB48Gnx9diT8jPbWN6UcZHJUZVQSLRhaaHuHQz3dGuxxZDXPYgCXzrkerK3m6Q1tHoougR7VYyd9",
|
|
7
|
+
// secret_view_key:
|
|
8
|
+
// "10b9885324933ee6055b001a3ee4b70f6832b866db389ad023b51fe7e2e7ca01",
|
|
9
|
+
// },
|
|
10
|
+
// {
|
|
11
|
+
// primary_address:
|
|
12
|
+
// "57wmxQgZugZRrsaZ2mhcVtZqrUxAB6nXdEj4pnQ975Te2J2djFbBEubUFxTwxurF4cYE1oF8m26BkA9QcZZXLkf3FM7qX9U",
|
|
13
|
+
// secret_view_key:
|
|
14
|
+
// "8e4fe64233b5a0213e06ef4662582f72d47f7304502654485050c8ac06ee0309",
|
|
15
|
+
// },
|
|
16
|
+
// ]);
|
|
17
|
+
// viewpairs.scan(1731707, (result) => {
|
|
18
|
+
// if ("error" in result) {
|
|
19
|
+
// console.error("Error during scan:", result.error);
|
|
20
|
+
// } else {
|
|
21
|
+
// console.log("Scan result:", result);
|
|
22
|
+
// // Here you can handle the scan result, e.g., save outputs to a database
|
|
23
|
+
// }
|
|
24
|
+
// });
|
|
25
|
+
// console.log(viewpairs);
|
|
26
|
+
import { ViewPair } from "./api";
|
|
27
|
+
const viewpair = await ViewPair.create("5B5ieVKGSyfAyh68X6AFB48Gnx9diT8jPbWN6UcZHJUZVQSLRhaaHuHQz3dGuxxZDXPYgCXzrkerK3m6Q1tHoougR7VYyd9", "10b9885324933ee6055b001a3ee4b70f6832b866db389ad023b51fe7e2e7ca01");
|
|
28
|
+
console.log(viewpair.makeIntegratedAddress(0));
|
|
29
|
+
// viewpair.scan(1731707, (result) => {
|
|
30
|
+
// if ("error" in result) {
|
|
31
|
+
// console.error("Error during scan:", result.error);
|
|
32
|
+
// } else {
|
|
33
|
+
// console.log("Scan result:", result);
|
|
34
|
+
// // Here you can handle the scan result, e.g., save outputs to a database
|
|
35
|
+
// }
|
|
36
|
+
// });
|