@blindmarket/sdk 0.1.7 → 0.1.8

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.
Files changed (133) hide show
  1. package/dist/chain/BlindEscrowClient.d.ts +2 -0
  2. package/dist/chain/BlindEscrowClient.js +14 -6
  3. package/dist/chain/BlindReputationClient.d.ts +3 -0
  4. package/dist/chain/BlindReputationClient.js +3 -1
  5. package/dist/chain/ChainClient.d.ts +5 -2
  6. package/dist/chain/ChainClient.js +5 -0
  7. package/dist/chain/IBlindMarketChain.d.ts +74 -0
  8. package/dist/chain/IBlindMarketChain.js +1 -0
  9. package/dist/chain/TaskRegistryClient.d.ts +2 -1
  10. package/dist/chain/TaskRegistryClient.js +15 -7
  11. package/dist/chain/createChainAdapter.d.ts +25 -0
  12. package/dist/chain/createChainAdapter.js +24 -0
  13. package/dist/chain/domain-types.d.ts +77 -0
  14. package/dist/chain/domain-types.js +1 -0
  15. package/dist/chain/evm/EVMChainAdapter.d.ts +56 -0
  16. package/dist/chain/evm/EVMChainAdapter.js +161 -0
  17. package/dist/chain/evm/index.d.ts +1 -0
  18. package/dist/chain/evm/index.js +1 -0
  19. package/dist/chain/index.d.ts +4 -0
  20. package/dist/chain/index.js +5 -0
  21. package/dist/executor/WorkerRuntime.d.ts +113 -0
  22. package/dist/executor/WorkerRuntime.js +248 -0
  23. package/dist/executor/index.d.ts +1 -0
  24. package/dist/executor/index.js +1 -0
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.js +8 -3
  27. package/dist/network/presets.d.ts +33 -5
  28. package/dist/network/presets.js +35 -8
  29. package/dist/network/resolve.d.ts +12 -3
  30. package/dist/network/resolve.js +15 -7
  31. package/dist/network/types.d.ts +3 -16
  32. package/dist/types.d.ts +1 -1
  33. package/package.json +1 -1
  34. package/src/chain/BlindEscrowClient.ts +15 -6
  35. package/src/chain/BlindReputationClient.ts +6 -1
  36. package/src/chain/ChainClient.ts +9 -3
  37. package/src/chain/IBlindMarketChain.ts +109 -0
  38. package/src/chain/TaskRegistryClient.ts +17 -8
  39. package/src/chain/createChainAdapter.ts +40 -0
  40. package/src/chain/domain-types.ts +92 -0
  41. package/src/chain/evm/EVMChainAdapter.ts +212 -0
  42. package/src/chain/evm/index.ts +1 -0
  43. package/src/chain/index.ts +6 -0
  44. package/src/executor/WorkerRuntime.ts +338 -0
  45. package/src/executor/index.ts +8 -0
  46. package/src/index.ts +23 -4
  47. package/src/network/presets.ts +47 -8
  48. package/src/network/resolve.ts +20 -8
  49. package/src/network/types.ts +18 -16
  50. package/src/signer/index.ts +1 -1
  51. package/src/types.ts +2 -1
  52. package/dist/BlindEscrowClient-CyPuKMge.d.cts +0 -54
  53. package/dist/BlindEscrowClient-R7iGpE-n.d.ts +0 -54
  54. package/dist/KeyStore-Be_SSpCt.d.cts +0 -21
  55. package/dist/KeyStore-k1JgYPJY.d.ts +0 -21
  56. package/dist/Signer-BnqH_qew.d.cts +0 -38
  57. package/dist/Signer-LColE0Uo.d.ts +0 -38
  58. package/dist/Storage-4QOrh7rm.d.ts +0 -17
  59. package/dist/Storage-Cf4IJRMk.d.cts +0 -17
  60. package/dist/TaskRegistryClient-Ch6lYqM_.d.ts +0 -24
  61. package/dist/TaskRegistryClient-CrQjddDc.d.cts +0 -24
  62. package/dist/aes-J-7HrHze.d.cts +0 -17
  63. package/dist/aes-J-7HrHze.d.ts +0 -17
  64. package/dist/agent/index.cjs +0 -425
  65. package/dist/agent/index.cjs.map +0 -1
  66. package/dist/agent/index.d.cts +0 -63
  67. package/dist/agent/index.js.map +0 -1
  68. package/dist/api/index.cjs +0 -4
  69. package/dist/api/index.cjs.map +0 -1
  70. package/dist/api/index.d.cts +0 -2
  71. package/dist/api/index.js.map +0 -1
  72. package/dist/chain/index.cjs +0 -2484
  73. package/dist/chain/index.cjs.map +0 -1
  74. package/dist/chain/index.d.cts +0 -2305
  75. package/dist/chain/index.js.map +0 -1
  76. package/dist/compute/index.cjs +0 -4
  77. package/dist/compute/index.cjs.map +0 -1
  78. package/dist/compute/index.d.cts +0 -2
  79. package/dist/compute/index.js.map +0 -1
  80. package/dist/crypto/index.cjs +0 -424
  81. package/dist/crypto/index.cjs.map +0 -1
  82. package/dist/crypto/index.d.cts +0 -74
  83. package/dist/crypto/index.js.map +0 -1
  84. package/dist/errors/BlindBountyError.d.ts +0 -14
  85. package/dist/errors/BlindBountyError.js +0 -30
  86. package/dist/errors/index.cjs +0 -136
  87. package/dist/errors/index.cjs.map +0 -1
  88. package/dist/errors/index.d.cts +0 -60
  89. package/dist/errors/index.js.map +0 -1
  90. package/dist/events/index.cjs +0 -41
  91. package/dist/events/index.cjs.map +0 -1
  92. package/dist/events/index.d.cts +0 -61
  93. package/dist/events/index.js.map +0 -1
  94. package/dist/index.cjs +0 -4
  95. package/dist/index.cjs.map +0 -1
  96. package/dist/index.d.cts +0 -2
  97. package/dist/index.js.map +0 -1
  98. package/dist/keystore/index.cjs +0 -335
  99. package/dist/keystore/index.cjs.map +0 -1
  100. package/dist/keystore/index.d.cts +0 -23
  101. package/dist/keystore/index.js.map +0 -1
  102. package/dist/mcp.d.ts +0 -23
  103. package/dist/mcp.js +0 -101
  104. package/dist/network/index.cjs +0 -74
  105. package/dist/network/index.cjs.map +0 -1
  106. package/dist/network/index.d.cts +0 -36
  107. package/dist/network/index.js.map +0 -1
  108. package/dist/signer/index.cjs +0 -121
  109. package/dist/signer/index.cjs.map +0 -1
  110. package/dist/signer/index.d.cts +0 -40
  111. package/dist/signer/index.js.map +0 -1
  112. package/dist/storage/ZgStorage.d.ts +0 -24
  113. package/dist/storage/ZgStorage.js +0 -102
  114. package/dist/storage/index.cjs +0 -221
  115. package/dist/storage/index.cjs.map +0 -1
  116. package/dist/storage/index.d.cts +0 -44
  117. package/dist/storage/index.js.map +0 -1
  118. package/dist/testing/index.cjs +0 -4
  119. package/dist/testing/index.cjs.map +0 -1
  120. package/dist/testing/index.d.cts +0 -2
  121. package/dist/testing/index.js.map +0 -1
  122. package/dist/types-BOG5Ub1z.d.cts +0 -31
  123. package/dist/types-BOG5Ub1z.d.ts +0 -31
  124. package/dist/types-V7_ZmUb-.d.cts +0 -19
  125. package/dist/types-hAsITUQ7.d.ts +0 -19
  126. package/dist/verifier/index.cjs +0 -4
  127. package/dist/verifier/index.cjs.map +0 -1
  128. package/dist/verifier/index.d.cts +0 -2
  129. package/dist/verifier/index.js.map +0 -1
  130. package/dist/worker/index.cjs +0 -382
  131. package/dist/worker/index.cjs.map +0 -1
  132. package/dist/worker/index.d.cts +0 -58
  133. package/dist/worker/index.js.map +0 -1
@@ -1,21 +0,0 @@
1
- import { T as TaskId, a as TaskKey, A as Address, H as Hex, c as TaskKeyRef } from './types-BOG5Ub1z.cjs';
2
-
3
- /**
4
- * Per-session storage for task AES keys and cached peer public keys. The SDK
5
- * never logs or serializes anything from here — this is the one place at-rest
6
- * secrets live. Implementations MUST treat passphrase-protected exports as the
7
- * only portable format.
8
- */
9
- interface KeyStore {
10
- putTaskKey(taskId: TaskId, key: TaskKey): Promise<void>;
11
- getTaskKey(taskId: TaskId): Promise<TaskKey | null>;
12
- putPeerPubKey(addr: Address, pubkey: Hex): Promise<void>;
13
- getPeerPubKey(addr: Address): Promise<Hex | null>;
14
- list(): Promise<TaskKeyRef[]>;
15
- delete(taskId: TaskId): Promise<void>;
16
- /** Portable, encrypted-at-rest JSON export for backup/migration. */
17
- export(passphrase: string): Promise<string>;
18
- import(data: string, passphrase: string): Promise<void>;
19
- }
20
-
21
- export type { KeyStore as K };
@@ -1,21 +0,0 @@
1
- import { T as TaskId, a as TaskKey, A as Address, H as Hex, c as TaskKeyRef } from './types-BOG5Ub1z.js';
2
-
3
- /**
4
- * Per-session storage for task AES keys and cached peer public keys. The SDK
5
- * never logs or serializes anything from here — this is the one place at-rest
6
- * secrets live. Implementations MUST treat passphrase-protected exports as the
7
- * only portable format.
8
- */
9
- interface KeyStore {
10
- putTaskKey(taskId: TaskId, key: TaskKey): Promise<void>;
11
- getTaskKey(taskId: TaskId): Promise<TaskKey | null>;
12
- putPeerPubKey(addr: Address, pubkey: Hex): Promise<void>;
13
- getPeerPubKey(addr: Address): Promise<Hex | null>;
14
- list(): Promise<TaskKeyRef[]>;
15
- delete(taskId: TaskId): Promise<void>;
16
- /** Portable, encrypted-at-rest JSON export for backup/migration. */
17
- export(passphrase: string): Promise<string>;
18
- import(data: string, passphrase: string): Promise<void>;
19
- }
20
-
21
- export type { KeyStore as K };
@@ -1,38 +0,0 @@
1
- import { A as Address, H as Hex } from './types-BOG5Ub1z.cjs';
2
-
3
- interface TxRequest {
4
- to: Address;
5
- from?: Address;
6
- data?: Hex;
7
- value?: bigint;
8
- gasLimit?: bigint;
9
- nonce?: number;
10
- chainId?: bigint;
11
- }
12
- interface TypedDataDomain {
13
- name?: string;
14
- version?: string;
15
- chainId?: bigint | number;
16
- verifyingContract?: Address;
17
- salt?: Hex;
18
- }
19
- type TypedDataField = {
20
- name: string;
21
- type: string;
22
- };
23
- /**
24
- * Uniform signing interface used across the SDK. Adapters wrap ethers Signer,
25
- * raw private keys, EIP-1193 providers, or KMS. Implementations MUST return
26
- * hex-encoded signatures (0x-prefixed) and addresses (0x-prefixed, 20 bytes).
27
- */
28
- interface Signer {
29
- getAddress(): Promise<Address>;
30
- chainId(): Promise<bigint>;
31
- signMessage(msg: string | Uint8Array): Promise<Hex>;
32
- signTypedData(domain: TypedDataDomain, types: Record<string, TypedDataField[]>, value: Record<string, unknown>): Promise<Hex>;
33
- signTransaction(tx: TxRequest): Promise<Hex>;
34
- /** Uncompressed secp256k1 public key, 0x04-prefixed (hex). */
35
- getPublicKey(): Promise<Hex>;
36
- }
37
-
38
- export type { Signer as S, TypedDataDomain as T, TypedDataField as a, TxRequest as b };
@@ -1,38 +0,0 @@
1
- import { A as Address, H as Hex } from './types-BOG5Ub1z.js';
2
-
3
- interface TxRequest {
4
- to: Address;
5
- from?: Address;
6
- data?: Hex;
7
- value?: bigint;
8
- gasLimit?: bigint;
9
- nonce?: number;
10
- chainId?: bigint;
11
- }
12
- interface TypedDataDomain {
13
- name?: string;
14
- version?: string;
15
- chainId?: bigint | number;
16
- verifyingContract?: Address;
17
- salt?: Hex;
18
- }
19
- type TypedDataField = {
20
- name: string;
21
- type: string;
22
- };
23
- /**
24
- * Uniform signing interface used across the SDK. Adapters wrap ethers Signer,
25
- * raw private keys, EIP-1193 providers, or KMS. Implementations MUST return
26
- * hex-encoded signatures (0x-prefixed) and addresses (0x-prefixed, 20 bytes).
27
- */
28
- interface Signer {
29
- getAddress(): Promise<Address>;
30
- chainId(): Promise<bigint>;
31
- signMessage(msg: string | Uint8Array): Promise<Hex>;
32
- signTypedData(domain: TypedDataDomain, types: Record<string, TypedDataField[]>, value: Record<string, unknown>): Promise<Hex>;
33
- signTransaction(tx: TxRequest): Promise<Hex>;
34
- /** Uncompressed secp256k1 public key, 0x04-prefixed (hex). */
35
- getPublicKey(): Promise<Hex>;
36
- }
37
-
38
- export type { Signer as S, TypedDataDomain as T, TypedDataField as a, TxRequest as b };
@@ -1,17 +0,0 @@
1
- import { U as UploadResult, d as RootHash } from './types-BOG5Ub1z.js';
2
-
3
- /**
4
- * Abstraction over blob storage. Default implementation (ZgStorage) uses
5
- * 0G Storage; MemoryStorage is for tests and local fallback. Consumers can
6
- * provide their own adapter for IPFS, S3, etc.
7
- */
8
- interface Storage {
9
- /** Upload bytes, return root hash + optional tx hash + size. */
10
- upload(bytes: Uint8Array): Promise<UploadResult>;
11
- /** Download bytes by root hash. Throws StorageError('STORAGE/NOT_FOUND') if absent. */
12
- download(rootHash: RootHash): Promise<Uint8Array>;
13
- /** Compute the canonical root hash without uploading. */
14
- hash(bytes: Uint8Array): Promise<RootHash>;
15
- }
16
-
17
- export type { Storage as S };
@@ -1,17 +0,0 @@
1
- import { U as UploadResult, d as RootHash } from './types-BOG5Ub1z.cjs';
2
-
3
- /**
4
- * Abstraction over blob storage. Default implementation (ZgStorage) uses
5
- * 0G Storage; MemoryStorage is for tests and local fallback. Consumers can
6
- * provide their own adapter for IPFS, S3, etc.
7
- */
8
- interface Storage {
9
- /** Upload bytes, return root hash + optional tx hash + size. */
10
- upload(bytes: Uint8Array): Promise<UploadResult>;
11
- /** Download bytes by root hash. Throws StorageError('STORAGE/NOT_FOUND') if absent. */
12
- download(rootHash: RootHash): Promise<Uint8Array>;
13
- /** Compute the canonical root hash without uploading. */
14
- hash(bytes: Uint8Array): Promise<RootHash>;
15
- }
16
-
17
- export type { Storage as S };
@@ -1,24 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { A as Address, T as TaskId, b as TxReceiptLike } from './types-BOG5Ub1z.js';
3
-
4
- interface OpenTaskMeta {
5
- taskId: TaskId;
6
- token: Address;
7
- category: string;
8
- locationZone: string;
9
- reward: bigint;
10
- createdAt: Date;
11
- }
12
- declare class TaskRegistryClient {
13
- readonly contract: ethers.Contract;
14
- readonly address: Address;
15
- constructor(address: Address, runner: ethers.ContractRunner);
16
- getTaskMeta(taskId: TaskId): Promise<OpenTaskMeta>;
17
- getOpenTasks(offset: bigint, limit: bigint): Promise<TaskId[]>;
18
- totalTasks(): Promise<bigint>;
19
- openTaskCount(): Promise<bigint>;
20
- taskExists(taskId: TaskId): Promise<boolean>;
21
- closeTask(taskId: TaskId): Promise<TxReceiptLike>;
22
- }
23
-
24
- export { type OpenTaskMeta as O, TaskRegistryClient as T };
@@ -1,24 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { A as Address, T as TaskId, b as TxReceiptLike } from './types-BOG5Ub1z.cjs';
3
-
4
- interface OpenTaskMeta {
5
- taskId: TaskId;
6
- token: Address;
7
- category: string;
8
- locationZone: string;
9
- reward: bigint;
10
- createdAt: Date;
11
- }
12
- declare class TaskRegistryClient {
13
- readonly contract: ethers.Contract;
14
- readonly address: Address;
15
- constructor(address: Address, runner: ethers.ContractRunner);
16
- getTaskMeta(taskId: TaskId): Promise<OpenTaskMeta>;
17
- getOpenTasks(offset: bigint, limit: bigint): Promise<TaskId[]>;
18
- totalTasks(): Promise<bigint>;
19
- openTaskCount(): Promise<bigint>;
20
- taskExists(taskId: TaskId): Promise<boolean>;
21
- closeTask(taskId: TaskId): Promise<TxReceiptLike>;
22
- }
23
-
24
- export { type OpenTaskMeta as O, TaskRegistryClient as T };
@@ -1,17 +0,0 @@
1
- /** Generate a fresh 32-byte AES-256 key. */
2
- declare function generateAesKey(): Promise<Uint8Array>;
3
- /**
4
- * AES-256-GCM encrypt. Output format: [12 IV][16 tag][ciphertext].
5
- * This ordering matches backend/src/services/crypto.ts and frontend/src/lib/crypto.ts
6
- * byte-for-byte, so SDK blobs decrypt anywhere in the stack.
7
- */
8
- declare function aesEncrypt(plaintext: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
9
- /**
10
- * AES-256-GCM decrypt. Input format: [12 IV][16 tag][ciphertext].
11
- * Throws CRYPTO/INTEGRITY_CHECK on truncation or tag mismatch.
12
- */
13
- declare function aesDecrypt(blob: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
14
- /** SHA-256 of arbitrary bytes. Returns 32-byte digest. */
15
- declare function sha256(data: Uint8Array): Promise<Uint8Array>;
16
-
17
- export { aesDecrypt as a, aesEncrypt as b, generateAesKey as g, sha256 as s };
@@ -1,17 +0,0 @@
1
- /** Generate a fresh 32-byte AES-256 key. */
2
- declare function generateAesKey(): Promise<Uint8Array>;
3
- /**
4
- * AES-256-GCM encrypt. Output format: [12 IV][16 tag][ciphertext].
5
- * This ordering matches backend/src/services/crypto.ts and frontend/src/lib/crypto.ts
6
- * byte-for-byte, so SDK blobs decrypt anywhere in the stack.
7
- */
8
- declare function aesEncrypt(plaintext: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
9
- /**
10
- * AES-256-GCM decrypt. Input format: [12 IV][16 tag][ciphertext].
11
- * Throws CRYPTO/INTEGRITY_CHECK on truncation or tag mismatch.
12
- */
13
- declare function aesDecrypt(blob: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
14
- /** SHA-256 of arbitrary bytes. Returns 32-byte digest. */
15
- declare function sha256(data: Uint8Array): Promise<Uint8Array>;
16
-
17
- export { aesDecrypt as a, aesEncrypt as b, generateAesKey as g, sha256 as s };
@@ -1,425 +0,0 @@
1
- 'use strict';
2
-
3
- var ethers = require('ethers');
4
-
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __esm = (fn, res) => function __init() {
8
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
- };
10
- var __export = (target, all) => {
11
- for (var name in all)
12
- __defProp(target, name, { get: all[name], enumerable: true });
13
- };
14
-
15
- // src/crypto/constants.ts
16
- var IV_LENGTH, TAG_LENGTH, KEY_LENGTH, ECIES_PUBKEY_LENGTH, ECIES_HKDF_INFO, AES_MIN_BLOB, ECIES_MIN_BLOB;
17
- var init_constants = __esm({
18
- "src/crypto/constants.ts"() {
19
- IV_LENGTH = 12;
20
- TAG_LENGTH = 16;
21
- KEY_LENGTH = 32;
22
- ECIES_PUBKEY_LENGTH = 65;
23
- ECIES_HKDF_INFO = new TextEncoder().encode("BlindBounty-ECIES-v1");
24
- AES_MIN_BLOB = IV_LENGTH + TAG_LENGTH;
25
- ECIES_MIN_BLOB = ECIES_PUBKEY_LENGTH + AES_MIN_BLOB;
26
- }
27
- });
28
-
29
- // src/errors/codes.ts
30
- var init_codes = __esm({
31
- "src/errors/codes.ts"() {
32
- }
33
- });
34
-
35
- // src/errors/BlindBountyError.ts
36
- var BlindBountyError;
37
- var init_BlindBountyError = __esm({
38
- "src/errors/BlindBountyError.ts"() {
39
- BlindBountyError = class extends Error {
40
- code;
41
- retriable;
42
- context;
43
- cause;
44
- constructor(code, message, opts = {}) {
45
- super(message);
46
- this.code = code;
47
- this.retriable = opts.retriable ?? false;
48
- if (opts.context !== void 0) this.context = opts.context;
49
- if (opts.cause !== void 0) this.cause = opts.cause;
50
- Object.defineProperty(this, "name", {
51
- value: this.constructor.name,
52
- enumerable: false,
53
- configurable: true,
54
- writable: true
55
- });
56
- }
57
- toJSON() {
58
- return {
59
- name: this.name,
60
- code: this.code,
61
- message: this.message,
62
- retriable: this.retriable,
63
- ...this.context ? { context: this.context } : {}
64
- };
65
- }
66
- };
67
- }
68
- });
69
-
70
- // src/errors/subclasses.ts
71
- var CryptoError, LifecycleError;
72
- var init_subclasses = __esm({
73
- "src/errors/subclasses.ts"() {
74
- init_BlindBountyError();
75
- CryptoError = class extends BlindBountyError {
76
- constructor(code, msg, opts) {
77
- super(code, msg, opts);
78
- }
79
- };
80
- LifecycleError = class extends BlindBountyError {
81
- constructor(code, msg, opts) {
82
- super(code, msg, opts);
83
- }
84
- };
85
- }
86
- });
87
-
88
- // src/errors/index.ts
89
- var init_errors = __esm({
90
- "src/errors/index.ts"() {
91
- init_codes();
92
- init_BlindBountyError();
93
- init_subclasses();
94
- }
95
- });
96
-
97
- // src/crypto/aes.ts
98
- function getCrypto() {
99
- const c = globalThis.crypto;
100
- if (!c?.subtle) {
101
- throw new CryptoError("CRYPTO/UNSUPPORTED_CIPHER", "Web Crypto (crypto.subtle) is not available");
102
- }
103
- return c;
104
- }
105
- function toArrayBuffer(u) {
106
- const ab = new ArrayBuffer(u.byteLength);
107
- new Uint8Array(ab).set(u);
108
- return ab;
109
- }
110
- async function generateAesKey() {
111
- const key = new Uint8Array(KEY_LENGTH);
112
- getCrypto().getRandomValues(key);
113
- return key;
114
- }
115
- async function aesEncrypt(plaintext, key) {
116
- if (key.byteLength !== KEY_LENGTH) {
117
- throw new CryptoError(
118
- "CRYPTO/INVALID_KEY",
119
- `AES key must be ${KEY_LENGTH} bytes, got ${key.byteLength}`
120
- );
121
- }
122
- const c = getCrypto();
123
- const iv = new Uint8Array(IV_LENGTH);
124
- c.getRandomValues(iv);
125
- try {
126
- const ck = await c.subtle.importKey("raw", toArrayBuffer(key), "AES-GCM", false, ["encrypt"]);
127
- const wcOut = new Uint8Array(
128
- await c.subtle.encrypt(
129
- { name: "AES-GCM", iv: toArrayBuffer(iv), tagLength: TAG_LENGTH * 8 },
130
- ck,
131
- toArrayBuffer(plaintext)
132
- )
133
- );
134
- const ctLen = wcOut.length - TAG_LENGTH;
135
- const ct = wcOut.subarray(0, ctLen);
136
- const tag = wcOut.subarray(ctLen);
137
- const blob = new Uint8Array(IV_LENGTH + TAG_LENGTH + ctLen);
138
- blob.set(iv, 0);
139
- blob.set(tag, IV_LENGTH);
140
- blob.set(ct, IV_LENGTH + TAG_LENGTH);
141
- return blob;
142
- } catch (cause) {
143
- throw new CryptoError("CRYPTO/DECRYPT_FAILED", "AES-GCM encryption failed", { cause });
144
- }
145
- }
146
- async function aesDecrypt(blob, key) {
147
- if (key.byteLength !== KEY_LENGTH) {
148
- throw new CryptoError(
149
- "CRYPTO/INVALID_KEY",
150
- `AES key must be ${KEY_LENGTH} bytes, got ${key.byteLength}`
151
- );
152
- }
153
- if (blob.byteLength < AES_MIN_BLOB) {
154
- throw new CryptoError(
155
- "CRYPTO/INTEGRITY_CHECK",
156
- `AES blob too short: need \u2265${AES_MIN_BLOB} bytes, got ${blob.byteLength}`
157
- );
158
- }
159
- const iv = blob.subarray(0, IV_LENGTH);
160
- const tag = blob.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH);
161
- const ct = blob.subarray(IV_LENGTH + TAG_LENGTH);
162
- const combined = new Uint8Array(ct.length + TAG_LENGTH);
163
- combined.set(ct, 0);
164
- combined.set(tag, ct.length);
165
- try {
166
- const c = getCrypto();
167
- const ck = await c.subtle.importKey("raw", toArrayBuffer(key), "AES-GCM", false, ["decrypt"]);
168
- const pt = await c.subtle.decrypt(
169
- { name: "AES-GCM", iv: toArrayBuffer(iv), tagLength: TAG_LENGTH * 8 },
170
- ck,
171
- toArrayBuffer(combined)
172
- );
173
- return new Uint8Array(pt);
174
- } catch (cause) {
175
- throw new CryptoError("CRYPTO/DECRYPT_FAILED", "AES-GCM decryption failed (wrong key or tampered data)", { cause });
176
- }
177
- }
178
- var init_aes = __esm({
179
- "src/crypto/aes.ts"() {
180
- init_errors();
181
- init_constants();
182
- }
183
- });
184
-
185
- // src/crypto/hkdf.ts
186
- function getSubtle() {
187
- const c = globalThis.crypto;
188
- if (!c?.subtle) {
189
- throw new CryptoError("CRYPTO/UNSUPPORTED_CIPHER", "Web Crypto (crypto.subtle) is not available");
190
- }
191
- return c.subtle;
192
- }
193
- function toArrayBuffer2(u) {
194
- const ab = new ArrayBuffer(u.byteLength);
195
- new Uint8Array(ab).set(u);
196
- return ab;
197
- }
198
- async function hkdfSha256(ikm, length = 32, info = ECIES_HKDF_INFO, salt = new Uint8Array(0)) {
199
- try {
200
- const subtle = getSubtle();
201
- const baseKey = await subtle.importKey("raw", toArrayBuffer2(ikm), "HKDF", false, ["deriveBits"]);
202
- const derived = await subtle.deriveBits(
203
- {
204
- name: "HKDF",
205
- hash: "SHA-256",
206
- info: toArrayBuffer2(info),
207
- salt: toArrayBuffer2(salt)
208
- },
209
- baseKey,
210
- length * 8
211
- );
212
- return new Uint8Array(derived);
213
- } catch (cause) {
214
- throw new CryptoError("CRYPTO/INVALID_KEY", "HKDF derivation failed", { cause });
215
- }
216
- }
217
- var init_hkdf = __esm({
218
- "src/crypto/hkdf.ts"() {
219
- init_errors();
220
- init_constants();
221
- }
222
- });
223
- function strip(hex) {
224
- return hex.startsWith("0x") || hex.startsWith("0X") ? hex.slice(2) : hex;
225
- }
226
- function assertUncompressedPubKey(pub) {
227
- const s = strip(pub);
228
- if (s.length !== 130 || !/^04/i.test(s)) {
229
- throw new CryptoError(
230
- "CRYPTO/INVALID_KEY",
231
- "expected uncompressed secp256k1 pubkey (65 bytes hex, starts with 04)"
232
- );
233
- }
234
- }
235
- function hexToBytes(hex) {
236
- const s = strip(hex);
237
- if (s.length % 2 !== 0) {
238
- throw new CryptoError("CRYPTO/INVALID_KEY", "hex string has odd length");
239
- }
240
- const out = new Uint8Array(s.length / 2);
241
- for (let i = 0; i < out.length; i++) {
242
- const byte = Number.parseInt(s.substring(i * 2, i * 2 + 2), 16);
243
- if (Number.isNaN(byte)) {
244
- throw new CryptoError("CRYPTO/INVALID_KEY", `invalid hex byte at position ${i * 2}`);
245
- }
246
- out[i] = byte;
247
- }
248
- return out;
249
- }
250
- function bytesToHex(u) {
251
- return Array.from(u, (b) => b.toString(16).padStart(2, "0")).join("");
252
- }
253
- var init_keys = __esm({
254
- "src/crypto/keys.ts"() {
255
- init_errors();
256
- }
257
- });
258
-
259
- // src/crypto/ecies.ts
260
- var ecies_exports = {};
261
- __export(ecies_exports, {
262
- eciesDecrypt: () => eciesDecrypt,
263
- eciesEncrypt: () => eciesEncrypt
264
- });
265
- async function eciesEncrypt(plaintext, recipientPubKey) {
266
- assertUncompressedPubKey(recipientPubKey);
267
- const ephemeral = ethers.ethers.Wallet.createRandom();
268
- const shared = deriveSharedSecretX(ephemeral.privateKey, `0x${strip(recipientPubKey)}`);
269
- const aesKey = await hkdfSha256(shared, KEY_LENGTH);
270
- const aesBlob = await aesEncrypt(plaintext, aesKey);
271
- const ephPub = hexToBytes(strip(ephemeral.signingKey.publicKey));
272
- if (ephPub.byteLength !== ECIES_PUBKEY_LENGTH) {
273
- throw new CryptoError("CRYPTO/INVALID_KEY", `ephemeral pubkey length ${ephPub.byteLength}`);
274
- }
275
- const blob = new Uint8Array(ECIES_PUBKEY_LENGTH + aesBlob.byteLength);
276
- blob.set(ephPub, 0);
277
- blob.set(aesBlob, ECIES_PUBKEY_LENGTH);
278
- return blob;
279
- }
280
- async function eciesDecrypt(blob, recipientPrivKey) {
281
- if (blob.byteLength < ECIES_MIN_BLOB) {
282
- throw new CryptoError(
283
- "CRYPTO/INTEGRITY_CHECK",
284
- `ECIES blob too short: need \u2265${ECIES_MIN_BLOB} bytes, got ${blob.byteLength}`
285
- );
286
- }
287
- const ephPub = blob.subarray(0, ECIES_PUBKEY_LENGTH);
288
- const aesBlob = blob.subarray(ECIES_PUBKEY_LENGTH);
289
- const shared = deriveSharedSecretX(`0x${strip(recipientPrivKey)}`, `0x${bytesToHex(ephPub)}`);
290
- const aesKey = await hkdfSha256(shared, KEY_LENGTH);
291
- return aesDecrypt(aesBlob, aesKey);
292
- }
293
- function deriveSharedSecretX(privHex, pubHex) {
294
- const sk = new ethers.ethers.SigningKey(privHex);
295
- const shared = sk.computeSharedSecret(pubHex);
296
- const bytes = hexToBytes(strip(shared));
297
- if (bytes.byteLength !== 65 || bytes[0] !== 4) {
298
- throw new CryptoError(
299
- "CRYPTO/INVALID_KEY",
300
- `unexpected shared secret shape (len=${bytes.byteLength}, prefix=${bytes[0]?.toString(16) ?? "none"})`
301
- );
302
- }
303
- return bytes.subarray(1, 33);
304
- }
305
- var init_ecies = __esm({
306
- "src/crypto/ecies.ts"() {
307
- init_errors();
308
- init_aes();
309
- init_constants();
310
- init_hkdf();
311
- init_keys();
312
- }
313
- });
314
-
315
- // src/crypto/envelope.ts
316
- init_errors();
317
- init_aes();
318
- var MAGIC_0 = 66;
319
- var MAGIC_1 = 66;
320
- var VERSION = 1;
321
- var HEADER_LEN = 3;
322
- async function openEvidenceAsAgent(envelope, agentPrivKey) {
323
- const parsed = parse(envelope);
324
- const { eciesDecrypt: eciesDecrypt2 } = await Promise.resolve().then(() => (init_ecies(), ecies_exports));
325
- const aesKey = await eciesDecrypt2(parsed.wrappedForAgent, agentPrivKey);
326
- return aesDecrypt(parsed.aesCiphertext, aesKey);
327
- }
328
- function parse(blob) {
329
- if (blob.byteLength < HEADER_LEN + 4 + 4) {
330
- throw new CryptoError("CRYPTO/INTEGRITY_CHECK", `envelope too short: ${blob.byteLength}`);
331
- }
332
- if (blob[0] !== MAGIC_0 || blob[1] !== MAGIC_1) {
333
- throw new CryptoError("CRYPTO/INTEGRITY_CHECK", "bad envelope magic");
334
- }
335
- if (blob[2] !== VERSION) {
336
- throw new CryptoError("CRYPTO/UNSUPPORTED_CIPHER", `unknown envelope version ${blob[2]}`);
337
- }
338
- const view = new DataView(blob.buffer, blob.byteOffset, blob.byteLength);
339
- let off = HEADER_LEN;
340
- const agentLen = view.getUint32(off, false);
341
- off += 4;
342
- if (off + agentLen + 4 > blob.byteLength) {
343
- throw new CryptoError("CRYPTO/INTEGRITY_CHECK", "envelope truncated (agent)");
344
- }
345
- const wrappedForAgent = blob.slice(off, off + agentLen);
346
- off += agentLen;
347
- const enclaveLen = view.getUint32(off, false);
348
- off += 4;
349
- if (off + enclaveLen > blob.byteLength) {
350
- throw new CryptoError("CRYPTO/INTEGRITY_CHECK", "envelope truncated (enclave)");
351
- }
352
- const wrappedForEnclave = blob.slice(off, off + enclaveLen);
353
- off += enclaveLen;
354
- const aesCiphertext = blob.slice(off);
355
- return { wrappedForAgent, wrappedForEnclave, aesCiphertext };
356
- }
357
-
358
- // src/agent/Agent.ts
359
- init_errors();
360
- var Agent = class {
361
- constructor(deps) {
362
- this.deps = deps;
363
- }
364
- deps;
365
- async createTask(input) {
366
- const { storage, escrow, keystore, events } = this.deps;
367
- const aesKey = await generateAesKey();
368
- const plaintext = toBytes(input.instructions);
369
- const ciphertext = await aesEncrypt(plaintext, aesKey);
370
- const uploaded = await storage.upload(ciphertext);
371
- const rootHash = uploaded.rootHash;
372
- const deadline = typeof input.deadline === "bigint" ? input.deadline : BigInt(Math.floor(input.deadline.getTime() / 1e3));
373
- const { taskId, receipt } = await escrow.createTask({
374
- taskHash: rootHash,
375
- token: input.reward.token,
376
- amount: input.reward.amount,
377
- category: input.category,
378
- locationZone: input.locationZone,
379
- deadline
380
- });
381
- const taskKey = { aesKey, createdAt: /* @__PURE__ */ new Date() };
382
- await keystore.putTaskKey(taskId, taskKey);
383
- events?.emit("task.created", { taskId, txHash: receipt.hash, rootHash });
384
- return { taskId, taskKey, rootHash, txHash: receipt.hash, receipt };
385
- }
386
- /**
387
- * Wrap the stored AES key for the chosen worker and record the assignment
388
- * on-chain. The caller must deliver `wrappedKey` to the worker separately
389
- * (backend API, DM, etc.). Returns the wrapped bytes and the tx receipt.
390
- */
391
- async assignWorker(taskId, worker, workerPubKey) {
392
- const { keystore, escrow, events } = this.deps;
393
- const stored = await keystore.getTaskKey(taskId);
394
- if (!stored) {
395
- throw new LifecycleError("LIFECYCLE/TASK_NOT_FOUND", `no task key in keystore for task ${taskId}`);
396
- }
397
- const wrappedKey = await eciesEncrypt(stored.aesKey, workerPubKey);
398
- const receipt = await escrow.assignWorker(taskId, worker);
399
- events?.emit("task.assigned", { taskId, worker, txHash: receipt.hash });
400
- return { wrappedKey, receipt };
401
- }
402
- async cancelTask(taskId) {
403
- const { escrow, keystore, events } = this.deps;
404
- const receipt = await this.deps.escrow.cancelTask(taskId);
405
- await keystore.delete(taskId);
406
- events?.emit("task.cancelled", { taskId, txHash: receipt.hash });
407
- return receipt;
408
- }
409
- /**
410
- * Fetch evidence by root hash, unwrap the AES key with the agent's private
411
- * key (signer's key material is not accessible, so a raw private key is
412
- * required), and return the decrypted evidence plaintext.
413
- */
414
- async fetchAndDecryptEvidence(evidenceHash, agentPrivKey) {
415
- const envelope = await this.deps.storage.download(evidenceHash);
416
- return openEvidenceAsAgent(envelope, agentPrivKey);
417
- }
418
- };
419
- function toBytes(x) {
420
- return typeof x === "string" ? new TextEncoder().encode(x) : x;
421
- }
422
-
423
- exports.Agent = Agent;
424
- //# sourceMappingURL=index.cjs.map
425
- //# sourceMappingURL=index.cjs.map