@spirobel/monero-wallet-api 0.6.12 → 0.6.16
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/frost_dkg.wasm +0 -0
- package/dist/monero_wallet_api.wasm +0 -0
- package/dist/scanning-syncing/worker-entrypoints/worker.js +1 -1
- package/dist/tools/calls/001.js +8 -1
- package/dist/tools/content.d.ts +2 -16
- package/dist/tools/content.js +3 -6
- package/dist/tools/globals.d.ts +16 -0
- package/dist/tools/monero-tools.d.ts +2 -0
- package/dist/tools/monero-tools.js +31 -0
- package/dist/wasm-processing/wasmFile.js +2 -2
- package/dist/worker_unpacked.js +4 -1
- package/package.json +6 -1
package/dist/tools/calls/001.js
CHANGED
|
@@ -26,17 +26,24 @@ function make(payload) {
|
|
|
26
26
|
const base = `${TOOL_MAGIC_STRING}001_amount_${payload.amount}_address_${payload.address}`;
|
|
27
27
|
return payload.no_check ? `${base}_no_check` : base;
|
|
28
28
|
}
|
|
29
|
+
// base58, 95 chars for a standard address and 106 for an integrated one.
|
|
30
|
+
const MONERO_ADDRESS_SHAPE = /^[1-9A-HJ-NP-Za-km-z]{95}$|^[1-9A-HJ-NP-Za-km-z]{106}$/;
|
|
29
31
|
async function validate_check(invo) {
|
|
30
32
|
const tool = invo.tool;
|
|
31
33
|
if (tool.tool_id !== "001")
|
|
32
34
|
return "unverified";
|
|
33
35
|
if (tool.payload.no_check)
|
|
34
36
|
return "unverified";
|
|
37
|
+
// the address goes into the path. a real address is base58 and 95 or 106 chars.
|
|
38
|
+
// anything else could rewrite the request path, so it never reaches the fetch.
|
|
39
|
+
if (!MONERO_ADDRESS_SHAPE.test(tool.payload.address))
|
|
40
|
+
return "invalid";
|
|
35
41
|
const link = invo[invo.found_in];
|
|
36
42
|
const invo_link = new URL(link);
|
|
37
43
|
const checkUrl = `${invo_link.origin}/monerochan001/${tool.payload.address}`;
|
|
38
44
|
try {
|
|
39
|
-
|
|
45
|
+
// no redirects: a shop must not bounce the request to another host.
|
|
46
|
+
const result = (await (await fetch(checkUrl, { redirect: "error" })).json());
|
|
40
47
|
if (result &&
|
|
41
48
|
typeof result === "object" &&
|
|
42
49
|
"valid_address" in result &&
|
package/dist/tools/content.d.ts
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
|
-
type
|
|
2
|
-
sendMessage: (msg: unknown) => Promise<unknown>;
|
|
3
|
-
connect: (info: {
|
|
4
|
-
name: string;
|
|
5
|
-
}) => {
|
|
6
|
-
onMessage: {
|
|
7
|
-
addListener: (cb: (msg: unknown) => void) => void;
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
type ExtensionBrowser = {
|
|
12
|
-
runtime: ExtensionRuntime;
|
|
13
|
-
};
|
|
1
|
+
import type { ExtensionBrowser } from "./globals";
|
|
14
2
|
declare global {
|
|
15
3
|
var browser: ExtensionBrowser;
|
|
16
4
|
var chrome: ExtensionBrowser;
|
|
17
5
|
}
|
|
18
6
|
export declare function interceptToolLinkCallback(e: Event): void;
|
|
19
7
|
export declare function deliverToolUrl(url: string): boolean;
|
|
20
|
-
export declare function
|
|
21
|
-
export declare function installToolLinkEventInterception(confirmationcallback?: (loc_href: string) => boolean): void;
|
|
22
|
-
export {};
|
|
8
|
+
export declare function installToolLinkEventInterception(): void;
|
package/dist/tools/content.js
CHANGED
|
@@ -71,11 +71,8 @@ export function deliverToolUrl(url) {
|
|
|
71
71
|
deliver(invo);
|
|
72
72
|
return true;
|
|
73
73
|
}
|
|
74
|
-
export function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
export function installToolLinkEventInterception(confirmationcallback = DefaultConfirmationCallback) {
|
|
74
|
+
export function installToolLinkEventInterception() {
|
|
75
|
+
// click only. keyboard activation (enter) dispatches a click, a touch tap does too.
|
|
76
|
+
// a keydown on a focused link is not an activation, so it must not deliver.
|
|
78
77
|
document.addEventListener("click", interceptToolLinkCallback, true);
|
|
79
|
-
document.addEventListener("touchend", interceptToolLinkCallback, true);
|
|
80
|
-
document.addEventListener("keydown", interceptToolLinkCallback, true);
|
|
81
78
|
}
|
package/dist/tools/globals.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ export type ExtensionRuntime = {
|
|
|
120
120
|
connect: (info: {
|
|
121
121
|
name: string;
|
|
122
122
|
}) => ExtensionPort;
|
|
123
|
+
getURL: (path: string) => string;
|
|
123
124
|
onMessage: {
|
|
124
125
|
addListener: (cb: (msg: unknown, sender: unknown) => void) => void;
|
|
125
126
|
};
|
|
@@ -127,6 +128,21 @@ export type ExtensionRuntime = {
|
|
|
127
128
|
addListener: (cb: (port: ExtensionPort) => void) => void;
|
|
128
129
|
};
|
|
129
130
|
};
|
|
131
|
+
export type ExtensionBrowser = {
|
|
132
|
+
runtime: ExtensionRuntime;
|
|
133
|
+
tabs: {
|
|
134
|
+
query: (query: {
|
|
135
|
+
url?: string;
|
|
136
|
+
}) => Promise<{
|
|
137
|
+
id?: number;
|
|
138
|
+
}[]>;
|
|
139
|
+
remove: (ids: number[]) => Promise<void>;
|
|
140
|
+
update: (id: number, update: {
|
|
141
|
+
url?: string;
|
|
142
|
+
active?: boolean;
|
|
143
|
+
}) => Promise<unknown>;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
130
146
|
export declare function getExtensionRuntime(): ExtensionRuntime | null;
|
|
131
147
|
export declare function sendToBackground<K extends ExtensionMessageKind>(kind: K, payload: ExtensionMessageByKind[K]): Promise<unknown>;
|
|
132
148
|
export type PortMessageByKind = {
|
|
@@ -2,6 +2,7 @@ import { TOOL_MAGIC_STRING, type ToolArm, type ToolInvocationValidity, type Tool
|
|
|
2
2
|
export { TOOL_MAGIC_STRING, type ToolInvocationValidity };
|
|
3
3
|
export type { ToolArm, ToolContentZone, ToolCounterpartyZone, ToolInvocationForValidate, ToolWorkerZone, } from "./globals";
|
|
4
4
|
export type { ToolUiCopy, ToolNotice, ToolPermission, } from "./globals";
|
|
5
|
+
export type { ExtensionRuntime, ExtensionBrowser } from "./globals";
|
|
5
6
|
export declare const tools: {
|
|
6
7
|
readonly "001": ToolArm<import("./calls/001").SendTransactionToolPayload, {
|
|
7
8
|
validate_route: (deps: {
|
|
@@ -14,6 +15,7 @@ export declare const tools: {
|
|
|
14
15
|
};
|
|
15
16
|
export type ToolId = keyof typeof tools;
|
|
16
17
|
export declare const TOOL_IDS: ToolId[];
|
|
18
|
+
export declare const TOOL_IDS_WITHOUT_DIRECT_OPEN: ToolId[];
|
|
17
19
|
export declare function getToolUiByPermissions(permissions: ToolPermission[]): ToolUiCopy | null;
|
|
18
20
|
type PayloadOf<A> = A extends ToolArm<infer P, infer _E> ? P : never;
|
|
19
21
|
export type MoneroTool = {
|
|
@@ -10,6 +10,9 @@ export const tools = {
|
|
|
10
10
|
"002": tool002,
|
|
11
11
|
};
|
|
12
12
|
export const TOOL_IDS = Object.keys(tools);
|
|
13
|
+
// tool calls that cannot be started from a tool link. the content script port
|
|
14
|
+
// carries the rest of the exchange, so the page that made the call has to stay.
|
|
15
|
+
export const TOOL_IDS_WITHOUT_DIRECT_OPEN = ["002"];
|
|
13
16
|
export function getToolUiByPermissions(permissions) {
|
|
14
17
|
const want = new Set(permissions);
|
|
15
18
|
for (const id of Object.keys(tools)) {
|
|
@@ -25,6 +28,34 @@ function isToolId(id) {
|
|
|
25
28
|
return id in tools;
|
|
26
29
|
}
|
|
27
30
|
export function parseToolLink(link) {
|
|
31
|
+
// the browser can wrap a pasted monero: uri in the search url it built, escaped or plain
|
|
32
|
+
const lower = link.toLowerCase();
|
|
33
|
+
const plain_at = lower.indexOf("monero:");
|
|
34
|
+
const escaped_at = lower.indexOf("monero%3a");
|
|
35
|
+
const legacy_at = plain_at !== -1 ? plain_at : escaped_at;
|
|
36
|
+
if (legacy_at !== -1) {
|
|
37
|
+
try {
|
|
38
|
+
// an escaped uri sits inside one parameter, so the next raw & ends it
|
|
39
|
+
//...?q=monero%3AADDR&source=desktop
|
|
40
|
+
// the pasted uri, ends at &
|
|
41
|
+
const tail = link.slice(legacy_at);
|
|
42
|
+
const uri = new URL(decodeURIComponent(plain_at !== -1 ? tail : tail.split("&")[0] ?? ""));
|
|
43
|
+
const address = uri.pathname;
|
|
44
|
+
const amount = uri.searchParams.get("tx_amount") ?? "";
|
|
45
|
+
if (!/^([1-9A-HJ-NP-Za-km-z]{95}|[1-9A-HJ-NP-Za-km-z]{106})$/.test(address))
|
|
46
|
+
return null;
|
|
47
|
+
if (amount && !/^\d+(?:\.\d{1,12})?$/.test(amount))
|
|
48
|
+
return null;
|
|
49
|
+
// separate payment ids are not supported. do not drop one or choose between amounts.
|
|
50
|
+
if (uri.searchParams.has("tx_payment_id") || uri.searchParams.getAll("tx_amount").length > 1)
|
|
51
|
+
return null;
|
|
52
|
+
return { tool_id: "001", payload: { address, amount, no_check: true } };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// a broken monero uri is not a tool call. do not fall through to the marker scan.
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
28
59
|
const magic_str_index = link.lastIndexOf(TOOL_MAGIC_STRING);
|
|
29
60
|
if (magic_str_index === -1)
|
|
30
61
|
return null;
|