@prosopo/account 2.8.63 → 2.8.64
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/.turbo/turbo-build$colon$cjs.log +16 -34
- package/.turbo/turbo-build$colon$tsc.log +18 -35
- package/.turbo/turbo-build.log +17 -33
- package/CHANGELOG.md +15 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/extension/Extension.cjs +6 -4
- package/dist/cjs/extension/ExtensionWeb2.cjs +79 -92
- package/dist/cjs/extension/ExtensionWeb3.cjs +26 -31
- package/dist/cjs/index.cjs +6 -7
- package/dist/cjs/workers/CryptoWorkerManager.cjs +119 -122
- package/dist/cjs/workers/cryptoWorker.cjs +17 -25
- package/dist/extension/Extension.js +7 -5
- package/dist/extension/ExtensionWeb2.js +68 -65
- package/dist/extension/ExtensionWeb3.js +23 -29
- package/dist/index.js +2 -5
- package/dist/workers/CryptoWorkerManager.js +119 -123
- package/dist/workers/cryptoWorker.js +17 -26
- package/package.json +10 -10
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,73 +1,76 @@
|
|
|
1
|
+
import { Extension } from "./Extension.js";
|
|
2
|
+
import { getCryptoWorkerManager } from "../workers/CryptoWorkerManager.js";
|
|
1
3
|
import Signer from "@polkadot/extension-base/page/Signer";
|
|
2
4
|
import { stringToU8a } from "@polkadot/util";
|
|
3
|
-
import {
|
|
5
|
+
import { getFingerprint, prefetchFingerprint } from "@prosopo/fingerprint";
|
|
4
6
|
import { Keyring } from "@prosopo/keyring";
|
|
5
7
|
import { u8aToHex, version } from "@prosopo/util";
|
|
6
8
|
import { hexHash } from "@prosopo/util-crypto";
|
|
7
|
-
|
|
8
|
-
import { Extension } from "./Extension.js";
|
|
9
|
+
//#region src/extension/ExtensionWeb2.ts
|
|
9
10
|
prefetchFingerprint();
|
|
10
11
|
getCryptoWorkerManager().prewarm();
|
|
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
|
-
|
|
12
|
+
var EntropyToMnemonicLoader = async () => (await import("@prosopo/util-crypto")).entropyToMnemonic;
|
|
13
|
+
/**
|
|
14
|
+
* Class for interfacing with web3 accounts.
|
|
15
|
+
*/
|
|
16
|
+
var ExtensionWeb2 = class extends Extension {
|
|
17
|
+
async getAccount(config) {
|
|
18
|
+
const account = await this.createAccount(config);
|
|
19
|
+
return {
|
|
20
|
+
account,
|
|
21
|
+
extension: this.createExtension(account)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
createExtension(account) {
|
|
25
|
+
const signer = new Signer(async () => {});
|
|
26
|
+
signer.signRaw = async (payload) => {
|
|
27
|
+
return {
|
|
28
|
+
id: 1,
|
|
29
|
+
signature: u8aToHex(account.keypair.sign(payload.data))
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
accounts: {
|
|
34
|
+
get: async () => {
|
|
35
|
+
return [account];
|
|
36
|
+
},
|
|
37
|
+
subscribe: () => {
|
|
38
|
+
return () => {};
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
name: "procaptcha-web2",
|
|
42
|
+
version,
|
|
43
|
+
signer
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async createAccount(config) {
|
|
47
|
+
const u8Entropy = stringToU8a(hexHash(await getFingerprint(), 128).slice(2));
|
|
48
|
+
const type = "sr25519";
|
|
49
|
+
const keyring = new Keyring({ type });
|
|
50
|
+
const workerManager = getCryptoWorkerManager();
|
|
51
|
+
try {
|
|
52
|
+
const { publicKey, secretKey } = await workerManager.entropyToKeypair(u8Entropy);
|
|
53
|
+
const keypair = keyring.addFromPair({
|
|
54
|
+
publicKey,
|
|
55
|
+
secretKey
|
|
56
|
+
}, {}, type);
|
|
57
|
+
const address = keypair.address;
|
|
58
|
+
return {
|
|
59
|
+
address,
|
|
60
|
+
name: address,
|
|
61
|
+
keypair
|
|
62
|
+
};
|
|
63
|
+
} catch (workerError) {
|
|
64
|
+
const mnemonic = (await EntropyToMnemonicLoader())(u8Entropy);
|
|
65
|
+
const keypair = keyring.addFromMnemonic(mnemonic);
|
|
66
|
+
const address = keypair.address;
|
|
67
|
+
return {
|
|
68
|
+
address,
|
|
69
|
+
name: address,
|
|
70
|
+
keypair
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
73
74
|
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { ExtensionWeb2, ExtensionWeb2 as default };
|
|
@@ -1,33 +1,27 @@
|
|
|
1
|
+
import { Extension } from "./Extension.js";
|
|
1
2
|
import { web3Enable } from "@polkadot/extension-dapp";
|
|
2
3
|
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
3
4
|
import { ProsopoError } from "@prosopo/common";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
throw new ProsopoError("WIDGET.ACCOUNT_NOT_FOUND", {
|
|
26
|
-
context: { error: `No account found matching ${address}` }
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export {
|
|
31
|
-
ExtensionWeb3,
|
|
32
|
-
ExtensionWeb3 as default
|
|
5
|
+
//#region src/extension/ExtensionWeb3.ts
|
|
6
|
+
/**
|
|
7
|
+
* Class for interfacing with web3 accounts.
|
|
8
|
+
*/
|
|
9
|
+
var ExtensionWeb3 = class extends Extension {
|
|
10
|
+
async getAccount(config) {
|
|
11
|
+
const { dappName, userAccountAddress: address } = config;
|
|
12
|
+
if (!address) throw new ProsopoError("WIDGET.NO_ACCOUNTS_FOUND", { context: { error: "No account address provided" } });
|
|
13
|
+
await cryptoWaitReady();
|
|
14
|
+
const extensions = await web3Enable(dappName);
|
|
15
|
+
if (extensions.length === 0) throw new ProsopoError("WIDGET.NO_EXTENSION_FOUND");
|
|
16
|
+
for (const extension of extensions) {
|
|
17
|
+
const account = (await extension.accounts.get()).find((account) => account.address === address);
|
|
18
|
+
if (account) return {
|
|
19
|
+
account,
|
|
20
|
+
extension
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
throw new ProsopoError("WIDGET.ACCOUNT_NOT_FOUND", { context: { error: `No account found matching ${address}` } });
|
|
24
|
+
}
|
|
33
25
|
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { ExtensionWeb3, ExtensionWeb3 as default };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
import "./_virtual/_rolldown/runtime.js";
|
|
1
2
|
import { Extension } from "./extension/Extension.js";
|
|
2
3
|
import { ExtensionWeb2 } from "./extension/ExtensionWeb2.js";
|
|
3
4
|
import { ExtensionWeb3 } from "./extension/ExtensionWeb3.js";
|
|
4
|
-
export {
|
|
5
|
-
Extension,
|
|
6
|
-
ExtensionWeb2,
|
|
7
|
-
ExtensionWeb3
|
|
8
|
-
};
|
|
5
|
+
export { Extension, ExtensionWeb2, ExtensionWeb3 };
|
|
@@ -1,126 +1,122 @@
|
|
|
1
1
|
import WorkerWrapper from "./cryptoWorker.js";
|
|
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
|
-
|
|
2
|
+
//#region src/workers/CryptoWorkerManager.ts
|
|
3
|
+
/**
|
|
4
|
+
* Manages Web Worker for cryptographic operations to prevent blocking the main thread
|
|
5
|
+
*/
|
|
6
|
+
var CryptoWorkerManager = class {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.worker = null;
|
|
9
|
+
this.isInitializing = false;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Initialize the worker. No test round-trip — construction failure throws
|
|
13
|
+
* synchronously (caught below); post-construction failures surface via
|
|
14
|
+
* `worker.onerror` (cleans up so the next call retries); anything that
|
|
15
|
+
* gets past both surfaces via `runTask`'s timeout + reject path, which
|
|
16
|
+
* already falls back to main-thread crypto. The prior `testWorker()` ping
|
|
17
|
+
* was a Blob-URL-era defensive check that no longer earns its ~30–80ms
|
|
18
|
+
* critical-path cost under Vite's `?worker&inline` constructor.
|
|
19
|
+
*/
|
|
20
|
+
initWorker() {
|
|
21
|
+
if (this.worker || this.isInitializing) return;
|
|
22
|
+
this.isInitializing = true;
|
|
23
|
+
try {
|
|
24
|
+
this.worker = new WorkerWrapper({ type: "module" });
|
|
25
|
+
this.worker.onerror = () => {
|
|
26
|
+
this.cleanup();
|
|
27
|
+
};
|
|
28
|
+
} catch {
|
|
29
|
+
this.cleanup();
|
|
30
|
+
} finally {
|
|
31
|
+
this.isInitializing = false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Eagerly spawn the worker so the first runTask() doesn't pay the
|
|
36
|
+
* worker-spawn + module-parse cost. Synchronous now — construction is
|
|
37
|
+
* fire-and-forget with cleanup via `worker.onerror`.
|
|
38
|
+
*/
|
|
39
|
+
prewarm() {
|
|
40
|
+
this.initWorker();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run a task in the Web Worker
|
|
44
|
+
*/
|
|
45
|
+
async runTask(task, data) {
|
|
46
|
+
this.initWorker();
|
|
47
|
+
if (!this.worker) throw new Error("Failed to initialize worker");
|
|
48
|
+
const worker = this.worker;
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const taskId = Math.random().toString(36).substr(2, 9);
|
|
51
|
+
const timeoutId = setTimeout(() => {
|
|
52
|
+
worker.removeEventListener("message", handleMessage);
|
|
53
|
+
worker.removeEventListener("error", handleError);
|
|
54
|
+
reject(/* @__PURE__ */ new Error(`Worker task ${task} timeout (Task ID: ${taskId})`));
|
|
55
|
+
}, 1e4);
|
|
56
|
+
const handleMessage = (event) => {
|
|
57
|
+
if (event.data.taskId === taskId) {
|
|
58
|
+
clearTimeout(timeoutId);
|
|
59
|
+
worker.removeEventListener("message", handleMessage);
|
|
60
|
+
worker.removeEventListener("error", handleError);
|
|
61
|
+
if (event.data.error) reject(/* @__PURE__ */ new Error(`Worker task failed: ${event.data.error}`));
|
|
62
|
+
else resolve(event.data.result);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const handleError = (error) => {
|
|
66
|
+
clearTimeout(timeoutId);
|
|
67
|
+
worker.removeEventListener("message", handleMessage);
|
|
68
|
+
worker.removeEventListener("error", handleError);
|
|
69
|
+
reject(/* @__PURE__ */ new Error(`Worker error during task: ${error.message}`));
|
|
70
|
+
};
|
|
71
|
+
worker.addEventListener("message", handleMessage);
|
|
72
|
+
worker.addEventListener("error", handleError);
|
|
73
|
+
const message = {
|
|
74
|
+
taskId,
|
|
75
|
+
task,
|
|
76
|
+
data
|
|
77
|
+
};
|
|
78
|
+
worker.postMessage(message);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Convert entropy to mnemonic using Web Worker
|
|
83
|
+
*/
|
|
84
|
+
async entropyToMnemonic(entropy) {
|
|
85
|
+
return this.runTask("entropyToMnemonic", { entropy });
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Fused: entropy → mnemonic → sr25519 keypair in a single worker
|
|
89
|
+
* round-trip. Callers that don't need the mnemonic separately should
|
|
90
|
+
* prefer this over two `entropyToMnemonic + keypairFromMnemonic` hops —
|
|
91
|
+
* saves one postMessage transit (~30–80ms on constrained hardware / under
|
|
92
|
+
* throttle) on the frictionless critical path. sr25519 derivation is a
|
|
93
|
+
* ~500ms main-thread cost otherwise.
|
|
94
|
+
*/
|
|
95
|
+
async entropyToKeypair(entropy) {
|
|
96
|
+
return this.runTask("entropyToKeypair", { entropy });
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Clean up worker resources
|
|
100
|
+
*/
|
|
101
|
+
cleanup() {
|
|
102
|
+
if (this.worker) this.worker.terminate();
|
|
103
|
+
this.worker = null;
|
|
104
|
+
this.isInitializing = false;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Public dispose method
|
|
108
|
+
*/
|
|
109
|
+
dispose() {
|
|
110
|
+
this.cleanup();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var workerManagerInstance = null;
|
|
114
|
+
/**
|
|
115
|
+
* Get the singleton CryptoWorkerManager instance
|
|
116
|
+
*/
|
|
117
117
|
function getCryptoWorkerManager() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
return workerManagerInstance;
|
|
118
|
+
if (!workerManagerInstance) workerManagerInstance = new CryptoWorkerManager();
|
|
119
|
+
return workerManagerInstance;
|
|
122
120
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
getCryptoWorkerManager
|
|
126
|
-
};
|
|
121
|
+
//#endregion
|
|
122
|
+
export { CryptoWorkerManager, getCryptoWorkerManager };
|