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