@spirobel/monero-wallet-api 0.5.4 → 0.6.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/dist/actionlog/actionLogOpened.d.ts +96 -1
- package/dist/actionlog/actionLogOpened.js +386 -1
- package/dist/actionlog/actionLogTypes.d.ts +114 -0
- package/dist/actionlog/actionLogTypes.js +198 -0
- package/dist/actionlog/backend/idbBackend.d.ts +13 -0
- package/dist/actionlog/backend/idbBackend.js +109 -0
- package/dist/actionlog/backend/jsonlBackend.d.ts +19 -0
- package/dist/actionlog/backend/jsonlBackend.js +110 -0
- package/dist/actionlog/backend/memoryBackend.d.ts +11 -0
- package/dist/actionlog/backend/memoryBackend.js +31 -0
- package/dist/actionlog/backend/sqliteBackend.d.ts +14 -0
- package/dist/actionlog/backend/sqliteBackend.js +96 -0
- package/dist/actionlog/backend.d.ts +12 -0
- package/dist/actionlog/backend.js +1 -0
- package/dist/actionlog/idbBackend.d.ts +19 -0
- package/dist/actionlog/idbBackend.js +98 -0
- package/dist/actionlog/jsonlBackend.d.ts +19 -0
- package/dist/actionlog/jsonlBackend.js +75 -0
- package/dist/actionlog/memoryBackend.d.ts +14 -0
- package/dist/actionlog/memoryBackend.js +38 -0
- package/dist/actionlog/openMaps.d.ts +11 -0
- package/dist/actionlog/openMaps.js +32 -0
- package/dist/actionlog/sqliteBackend.d.ts +18 -0
- package/dist/actionlog/sqliteBackend.js +105 -0
- package/dist/actionlog/toolContext.d.ts +36 -0
- package/dist/actionlog/toolContext.js +1 -0
- package/dist/actionlog/types.d.ts +62 -0
- package/dist/actionlog/types.js +62 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.js +3 -0
- package/dist/io/sleep.d.ts +1 -1
- package/dist/io/sleep.js +16 -1
- package/dist/scanning-syncing/backgroundWorker.d.ts +2 -0
- package/dist/scanning-syncing/backgroundWorker.js +92 -10
- package/dist/scanning-syncing/blocksbuffer/blocksBufferFetchLoop.js +33 -2
- package/dist/scanning-syncing/blocksbuffer/blocksbufferCoordination.js +2 -2
- package/dist/scanning-syncing/connectionStatus.d.ts +8 -0
- package/dist/scanning-syncing/connectionStatus.js +50 -0
- package/dist/scanning-syncing/connectionStatusOpened.d.ts +3 -1
- package/dist/scanning-syncing/connectionStatusOpened.js +22 -14
- package/dist/scanning-syncing/openWallet.d.ts +4 -1
- package/dist/scanning-syncing/openWallet.js +3 -0
- package/dist/scanning-syncing/scanresult/scanCache.d.ts +5 -1
- package/dist/scanning-syncing/scanresult/scanCache.js +11 -2
- package/dist/scanning-syncing/scanresult/scanCacheOpened.d.ts +56 -5
- package/dist/scanning-syncing/scanresult/scanCacheOpened.js +422 -83
- package/dist/scanning-syncing/scanresult/scanCoordination.d.ts +7 -3
- package/dist/scanning-syncing/scanresult/scanCoordination.js +126 -28
- package/dist/scanning-syncing/scanresult/scanLoop.d.ts +1 -2
- package/dist/scanning-syncing/scanresult/scanLoop.js +0 -13
- package/dist/scanning-syncing/scanresult/scanResult.js +17 -12
- package/dist/scanning-syncing/scanresult/scanStats.js +8 -5
- package/dist/scanning-syncing/worker-entrypoints/worker.js +1 -1
- package/dist/scanning-syncing/worker-mains/coordinator-main.d.ts +1 -0
- package/dist/scanning-syncing/worker-mains/coordinator-main.js +16 -1
- package/dist/scanning-syncing/worker-mains/cpubound-main.js +3 -2
- package/dist/scanning-syncing/worker-mains/worker.js +45 -2
- package/dist/tools/calls/001.d.ts +20 -0
- package/dist/tools/calls/001.js +236 -0
- package/dist/tools/calls/002-content.d.ts +46 -0
- package/dist/tools/calls/002-content.js +135 -0
- package/dist/tools/calls/002-fail-cleanup.d.ts +27 -0
- package/dist/tools/calls/002-fail-cleanup.js +60 -0
- package/dist/tools/calls/002.d.ts +64 -0
- package/dist/tools/calls/002.js +353 -0
- package/dist/tools/content.d.ts +22 -0
- package/dist/tools/content.js +41 -0
- package/dist/tools/counterparty.d.ts +3 -0
- package/dist/tools/counterparty.js +1 -0
- package/dist/tools/download-public-suffix.d.ts +1 -0
- package/dist/tools/download-public-suffix.js +20 -0
- package/dist/tools/globals.d.ts +196 -0
- package/dist/tools/globals.js +14 -0
- package/dist/tools/monero-tools-content.d.ts +29 -0
- package/dist/tools/monero-tools-content.js +80 -0
- package/dist/tools/monero-tools.d.ts +27 -52
- package/dist/tools/monero-tools.js +127 -222
- package/dist/tools/public-suffix-list.d.ts +1 -0
- package/dist/tools/public-suffix-list.js +10336 -0
- package/dist/tools/runtimeMessages.d.ts +4 -0
- package/dist/tools/runtimeMessages.js +18 -0
- package/dist/tools/toolActionLogContext.d.ts +33 -0
- package/dist/tools/toolActionLogContext.js +1 -0
- package/dist/tools/toolArm.d.ts +47 -0
- package/dist/tools/toolArm.js +1 -0
- package/dist/tools/ui.d.ts +2 -0
- package/dist/tools/ui.js +1 -0
- package/dist/tools/worker.d.ts +1 -0
- package/dist/tools/worker.js +1 -0
- package/dist/wasm-processing/wasmFile.js +2 -2
- package/package.json +8 -1
|
@@ -1,30 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { TOOL_MAGIC_STRING, } from "./globals";
|
|
2
|
+
import tool001 from "./calls/001";
|
|
3
|
+
import tool002 from "./calls/002";
|
|
4
|
+
import { publicSuffixRules } from "./public-suffix-list";
|
|
5
|
+
const publicSuffixSet = new Set(publicSuffixRules);
|
|
6
|
+
export { TOOL_MAGIC_STRING };
|
|
7
|
+
// add a tool: import + one key here
|
|
8
|
+
export const tools = {
|
|
9
|
+
"001": tool001,
|
|
10
|
+
"002": tool002,
|
|
11
|
+
};
|
|
12
|
+
export const TOOL_IDS = Object.keys(tools);
|
|
13
|
+
export function getToolUiByPermissions(permissions) {
|
|
14
|
+
const want = new Set(permissions);
|
|
15
|
+
for (const id of Object.keys(tools)) {
|
|
16
|
+
const arm = tools[id];
|
|
17
|
+
if (!arm.permissions.some((p) => want.has(p)))
|
|
18
|
+
continue;
|
|
19
|
+
if (arm.ui)
|
|
20
|
+
return arm.ui;
|
|
16
21
|
}
|
|
17
22
|
return null;
|
|
18
23
|
}
|
|
24
|
+
function isToolId(id) {
|
|
25
|
+
return id in tools;
|
|
26
|
+
}
|
|
27
|
+
export function parseToolLink(link) {
|
|
28
|
+
const magic_str_index = link.lastIndexOf(TOOL_MAGIC_STRING);
|
|
29
|
+
if (magic_str_index === -1)
|
|
30
|
+
return null;
|
|
31
|
+
const link_start_index = magic_str_index + TOOL_MAGIC_STRING.length;
|
|
32
|
+
const tool_id = link.substring(link_start_index, link_start_index + 3);
|
|
33
|
+
if (!isToolId(tool_id))
|
|
34
|
+
return null;
|
|
35
|
+
const args = link
|
|
36
|
+
.substring(link_start_index + 3)
|
|
37
|
+
.split("_")
|
|
38
|
+
.slice(1);
|
|
39
|
+
const parsed = tools[tool_id].content.recognize_parse(args);
|
|
40
|
+
return parsed ?? null;
|
|
41
|
+
}
|
|
42
|
+
export function createToolLink(tool) {
|
|
43
|
+
const id = tool.tool_id;
|
|
44
|
+
if (!isToolId(id))
|
|
45
|
+
throw new Error("unknown tool");
|
|
46
|
+
return tools[id].counterparty.make(tool.payload);
|
|
47
|
+
}
|
|
19
48
|
export function parseToolInvocation(link, linkText, context_location) {
|
|
20
49
|
const context_domain = getDomainWithTLD(context_location.hostname);
|
|
21
50
|
const context_href = context_location.href;
|
|
22
51
|
const link_parse = parseToolLink(link);
|
|
23
52
|
if (link_parse) {
|
|
24
|
-
const destination_domain = parseDestination(link);
|
|
25
53
|
return {
|
|
26
54
|
tool: link_parse,
|
|
27
|
-
destination_domain,
|
|
55
|
+
destination_domain: parseDestination(link),
|
|
28
56
|
context_domain,
|
|
29
57
|
found_in: "link",
|
|
30
58
|
link,
|
|
@@ -35,221 +63,98 @@ export function parseToolInvocation(link, linkText, context_location) {
|
|
|
35
63
|
valid: "unverified",
|
|
36
64
|
};
|
|
37
65
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (linkText_parse) {
|
|
41
|
-
const destination_domain = parseDestination(linkText);
|
|
42
|
-
return {
|
|
43
|
-
tool: linkText_parse,
|
|
44
|
-
destination_domain,
|
|
45
|
-
context_domain,
|
|
46
|
-
found_in: "linkText",
|
|
47
|
-
link,
|
|
48
|
-
linkText,
|
|
49
|
-
timestamp: Date.now(),
|
|
50
|
-
invocation_id: crypto.randomUUID(),
|
|
51
|
-
context_href,
|
|
52
|
-
valid: "unverified",
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
export function parseSendTransactionToolArgs(args) {
|
|
59
|
-
const amount = args[1];
|
|
60
|
-
const address = args[3];
|
|
61
|
-
try {
|
|
62
|
-
convertAmountBigIntThrows(amount);
|
|
63
|
-
}
|
|
64
|
-
catch (e) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
if (address && amount) {
|
|
68
|
-
return {
|
|
69
|
-
tool_id: "001",
|
|
70
|
-
payload: {
|
|
71
|
-
address,
|
|
72
|
-
amount,
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
export function createSendTransactionToolLink(address, amount) {
|
|
79
|
-
convertAmountBigIntThrows(amount);
|
|
80
|
-
return `${TOOL_MAGIC_STRING}001_amount_${amount}_address_${address}`;
|
|
81
|
-
}
|
|
82
|
-
export function make001ToolLink(address, amount) {
|
|
83
|
-
return createSendTransactionToolLink(address, amount);
|
|
84
|
-
}
|
|
85
|
-
export function parseCreateAndShareViewOnlyWalletToolArgs(args) {
|
|
86
|
-
const wallet_slot = args[5];
|
|
87
|
-
if (wallet_slot && !isNaN(parseInt(wallet_slot))) {
|
|
66
|
+
const linkText_parse = parseToolLink(linkText);
|
|
67
|
+
if (linkText_parse) {
|
|
88
68
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
69
|
+
tool: linkText_parse,
|
|
70
|
+
destination_domain: parseDestination(linkText),
|
|
71
|
+
context_domain,
|
|
72
|
+
found_in: "linkText",
|
|
73
|
+
link,
|
|
74
|
+
linkText,
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
invocation_id: crypto.randomUUID(),
|
|
77
|
+
context_href,
|
|
78
|
+
valid: "unverified",
|
|
93
79
|
};
|
|
94
80
|
}
|
|
95
81
|
return null;
|
|
96
82
|
}
|
|
97
|
-
export function
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (tool.tool_id === "001") {
|
|
106
|
-
return createSendTransactionToolLink(tool.payload.address, tool.payload.amount);
|
|
107
|
-
}
|
|
108
|
-
if (tool.tool_id === "002") {
|
|
109
|
-
return createCreateAndShareViewOnlyWalletToolLink(tool.payload.wallet_slot);
|
|
110
|
-
}
|
|
111
|
-
throw new Error("unknown tool");
|
|
83
|
+
export async function checkToolInvocationValidity(invo) {
|
|
84
|
+
const id = invo.tool.tool_id;
|
|
85
|
+
if (!isToolId(id))
|
|
86
|
+
return "unverified";
|
|
87
|
+
const check = tools[id].content.validate_check;
|
|
88
|
+
if (!check)
|
|
89
|
+
return "unverified";
|
|
90
|
+
return check(invo);
|
|
112
91
|
}
|
|
113
92
|
export function getDomainWithTLD(hostname) {
|
|
114
|
-
|
|
115
|
-
|
|
93
|
+
// strip one pair of brackets from bracketed ipv6 literals first
|
|
94
|
+
const bare = hostname.startsWith("[") && hostname.endsWith("]")
|
|
95
|
+
? hostname.slice(1, -1)
|
|
96
|
+
: hostname;
|
|
97
|
+
// the loopback spellings name the host users call localhost.
|
|
98
|
+
// one bucket for all three, or one dev server derives three wallets.
|
|
99
|
+
if (bare === "127.0.0.1" || bare === "::1")
|
|
100
|
+
return "localhost";
|
|
101
|
+
// lower case, then split on "." and drop empty pieces from a stray dot
|
|
102
|
+
const parts = bare.toLowerCase().split(".").filter(Boolean);
|
|
103
|
+
// for localhost or single-part hostnames, return as-is
|
|
116
104
|
if (parts.length <= 1)
|
|
117
|
-
return
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
else {
|
|
147
|
-
return "invalid";
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
return "invalid";
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// create view only wallet 002 make sure context + destination domain is the same
|
|
155
|
-
if (invo.tool.tool_id == "002") {
|
|
156
|
-
if (invo.context_domain == invo.destination_domain) {
|
|
157
|
-
return "valid";
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
return "invalid";
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return "unverified";
|
|
164
|
-
}
|
|
165
|
-
export const ADDRESS_VALID_RESPONSE = {
|
|
166
|
-
valid_address: true,
|
|
167
|
-
};
|
|
168
|
-
export const ADDRESS_INVALID_RESPONSE = {
|
|
169
|
-
valid_address: false,
|
|
170
|
-
};
|
|
171
|
-
export async function shareViewKey002(payload) {
|
|
172
|
-
const invo = payload.tool_invo;
|
|
173
|
-
if (invo.tool.tool_id !== "002")
|
|
174
|
-
return {
|
|
175
|
-
ok: false,
|
|
176
|
-
successUrl: null,
|
|
177
|
-
};
|
|
178
|
-
if (invo.valid !== "valid")
|
|
179
|
-
return {
|
|
180
|
-
ok: false,
|
|
181
|
-
successUrl: null,
|
|
182
|
-
};
|
|
183
|
-
const link = invo[invo.found_in];
|
|
184
|
-
const invo_link = new URL(link);
|
|
185
|
-
const shareVKUrl = `${invo_link.origin}/monerochan002/`;
|
|
186
|
-
const result = await fetch(shareVKUrl, {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: { "Content-Type": "application/json" },
|
|
189
|
-
body: JSON.stringify({
|
|
190
|
-
viewkey: payload.viewkey,
|
|
191
|
-
primary_address: payload.primary_address,
|
|
192
|
-
wallet_slot: invo.tool.payload.wallet_slot,
|
|
193
|
-
}),
|
|
194
|
-
});
|
|
195
|
-
if (result.ok) {
|
|
196
|
-
const data = (await result.json());
|
|
197
|
-
if (data && typeof data === "object" && "ok" in data && data.ok === true) {
|
|
198
|
-
return {
|
|
199
|
-
ok: true,
|
|
200
|
-
successUrl: data.successUrl ?? null,
|
|
201
|
-
};
|
|
105
|
+
return bare;
|
|
106
|
+
// ip literals are not domain names. the psl would chop them into
|
|
107
|
+
// meaningless tails (127.0.0.1 becomes 0.1, and two different lan hosts
|
|
108
|
+
// can land in one bucket). return them unchanged.
|
|
109
|
+
// ipv4 has only numeric labels. numeric tlds do not exist.
|
|
110
|
+
if (parts.every((p) => /^\d+$/.test(p)))
|
|
111
|
+
return bare;
|
|
112
|
+
// ipv6 has colons, dns names never do
|
|
113
|
+
if (bare.includes(":"))
|
|
114
|
+
return bare;
|
|
115
|
+
// if nothing in the list matches, the psl says pretend the rule was "*". the suffix is the last label only.
|
|
116
|
+
let suffixLen = 1;
|
|
117
|
+
// exception rules are the lines that start with "!". null until one of those lines matches.
|
|
118
|
+
let exceptionLen = null;
|
|
119
|
+
// i walks left to right, but we never test the left side by itself.
|
|
120
|
+
// first pass is the whole name. each next pass chops one word off the left, so the ending gets shorter.
|
|
121
|
+
for (let i = 0; i < parts.length; i++) {
|
|
122
|
+
// shop.example.co.uk is checked as itself, then example.co.uk, then co.uk, then uk.
|
|
123
|
+
// co.uk.evil.com never produces the tail "co.uk", because those words are not the ending.
|
|
124
|
+
const tail = parts.slice(i).join(".");
|
|
125
|
+
// the labels to the right of the first label of this ending. "foo.ck" gives "ck".
|
|
126
|
+
const parent = parts.slice(i + 1).join(".");
|
|
127
|
+
// how many labels this ending has. starts big, shrinks by one each pass.
|
|
128
|
+
const len = parts.length - i;
|
|
129
|
+
// exception rule, file line "!www.ck". the "!" is only the first character of that line.
|
|
130
|
+
// the name after it is not a public suffix. the suffix is the rest, so save one less label.
|
|
131
|
+
// the first hit is the longest. a later, shorter exception must not replace it.
|
|
132
|
+
if (exceptionLen === null && publicSuffixSet.has("!" + tail)) {
|
|
133
|
+
exceptionLen = len - 1;
|
|
202
134
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
135
|
+
// exact rule, file line "co.uk". the whole ending is the public suffix.
|
|
136
|
+
// keep it only when it has more labels than the suffix already saved. "uk" must not replace "co.uk".
|
|
137
|
+
if (publicSuffixSet.has(tail) && len > suffixLen)
|
|
138
|
+
suffixLen = len;
|
|
139
|
+
// wildcard rule, file line "*.ck". the "*" is one label, and only the leftmost label of the rule.
|
|
140
|
+
// "foo.ck" lines up with "*.ck", so the lookup string is "*." plus parent "ck".
|
|
141
|
+
// keep it only when that lined-up suffix is longer than the one already saved.
|
|
142
|
+
if (parent && publicSuffixSet.has("*." + parent) && len > suffixLen) {
|
|
143
|
+
suffixLen = len;
|
|
208
144
|
}
|
|
209
145
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (shareVKresult.ok && shareVKresult.successUrl) {
|
|
221
|
-
window.location.href = shareVKresult.successUrl;
|
|
222
|
-
window.location.reload();
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
return shareVKresult;
|
|
226
|
-
}
|
|
146
|
+
// the psl prevailing rule: an exception wins even when an exact or wildcard match is longer.
|
|
147
|
+
// "*.ck" would make the suffix "www.ck". "!www.ck" makes the suffix "ck" instead.
|
|
148
|
+
if (exceptionLen !== null)
|
|
149
|
+
suffixLen = exceptionLen;
|
|
150
|
+
// the whole name is already the public suffix, like "co.uk". no label sits to the left of it.
|
|
151
|
+
if (suffixLen >= parts.length)
|
|
152
|
+
return parts.join(".");
|
|
153
|
+
// take the last 2 parts (domain + tld).
|
|
154
|
+
// keep the suffix plus the one word on its left. a 2-word suffix co.uk keeps example.co.uk
|
|
155
|
+
return parts.slice(-(suffixLen + 1)).join(".");
|
|
227
156
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const json_body = await req.json();
|
|
232
|
-
const { viewkey, primary_address, wallet_slot } = json_body;
|
|
233
|
-
if (typeof viewkey !== "string" ||
|
|
234
|
-
viewkey.trim().length === 0 ||
|
|
235
|
-
typeof primary_address !== "string" ||
|
|
236
|
-
primary_address.trim().length === 0 ||
|
|
237
|
-
typeof wallet_slot !== "number") {
|
|
238
|
-
return { ok: false, successUrl: null };
|
|
239
|
-
}
|
|
240
|
-
const foundSlot = wallets.find((wallet) => wallet.wallet_slot === wallet_slot);
|
|
241
|
-
if (foundSlot) {
|
|
242
|
-
if (foundSlot.primary_address !== primary_address) {
|
|
243
|
-
return { ok: false, successUrl: null };
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
await parsed_cb({ viewkey, primary_address, wallet_slot });
|
|
247
|
-
return {
|
|
248
|
-
ok: true,
|
|
249
|
-
successUrl: successUrl ?? null,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
catch {
|
|
253
|
-
return { ok: false, successUrl: null };
|
|
254
|
-
}
|
|
157
|
+
export function parseDestination(destination) {
|
|
158
|
+
const url = new URL(destination);
|
|
159
|
+
return getDomainWithTLD(url.hostname);
|
|
255
160
|
}
|