@blindmarket/sdk 0.1.4
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/README.md +72 -0
- package/biome.json +19 -0
- package/dist/BlindEscrowClient-CyPuKMge.d.cts +54 -0
- package/dist/BlindEscrowClient-R7iGpE-n.d.ts +54 -0
- package/dist/KeyStore-Be_SSpCt.d.cts +21 -0
- package/dist/KeyStore-k1JgYPJY.d.ts +21 -0
- package/dist/Signer-BnqH_qew.d.cts +38 -0
- package/dist/Signer-LColE0Uo.d.ts +38 -0
- package/dist/Storage-4QOrh7rm.d.ts +17 -0
- package/dist/Storage-Cf4IJRMk.d.cts +17 -0
- package/dist/TaskRegistryClient-Ch6lYqM_.d.ts +24 -0
- package/dist/TaskRegistryClient-CrQjddDc.d.cts +24 -0
- package/dist/aes-J-7HrHze.d.cts +17 -0
- package/dist/aes-J-7HrHze.d.ts +17 -0
- package/dist/agent/Agent.d.ts +59 -0
- package/dist/agent/Agent.js +73 -0
- package/dist/agent/index.cjs +425 -0
- package/dist/agent/index.cjs.map +1 -0
- package/dist/agent/index.d.cts +63 -0
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +1 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/api/index.cjs +4 -0
- package/dist/api/index.cjs.map +1 -0
- package/dist/api/index.d.cts +2 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -0
- package/dist/chain/BlindEscrowClient.d.ts +51 -0
- package/dist/chain/BlindEscrowClient.js +142 -0
- package/dist/chain/BlindReputationClient.d.ts +16 -0
- package/dist/chain/BlindReputationClient.js +45 -0
- package/dist/chain/ChainClient.d.ts +26 -0
- package/dist/chain/ChainClient.js +46 -0
- package/dist/chain/TaskRegistryClient.d.ts +21 -0
- package/dist/chain/TaskRegistryClient.js +70 -0
- package/dist/chain/abi/BlindEscrow.json +1113 -0
- package/dist/chain/abi/BlindReputation.json +447 -0
- package/dist/chain/abi/TaskRegistry.json +586 -0
- package/dist/chain/abi/index.d.ts +4 -0
- package/dist/chain/abi/index.js +4 -0
- package/dist/chain/errors.d.ts +8 -0
- package/dist/chain/errors.js +32 -0
- package/dist/chain/index.cjs +2484 -0
- package/dist/chain/index.cjs.map +1 -0
- package/dist/chain/index.d.cts +2305 -0
- package/dist/chain/index.d.ts +6 -0
- package/dist/chain/index.js +6 -0
- package/dist/chain/index.js.map +1 -0
- package/dist/compute/index.cjs +4 -0
- package/dist/compute/index.cjs.map +1 -0
- package/dist/compute/index.d.cts +2 -0
- package/dist/compute/index.d.ts +1 -0
- package/dist/compute/index.js +1 -0
- package/dist/compute/index.js.map +1 -0
- package/dist/crypto/aes.d.ts +15 -0
- package/dist/crypto/aes.js +81 -0
- package/dist/crypto/constants.d.ts +7 -0
- package/dist/crypto/constants.js +7 -0
- package/dist/crypto/ecies.d.ts +8 -0
- package/dist/crypto/ecies.js +51 -0
- package/dist/crypto/envelope.d.ts +35 -0
- package/dist/crypto/envelope.js +103 -0
- package/dist/crypto/hkdf.d.ts +5 -0
- package/dist/crypto/hkdf.js +34 -0
- package/dist/crypto/index.cjs +424 -0
- package/dist/crypto/index.cjs.map +1 -0
- package/dist/crypto/index.d.cts +74 -0
- package/dist/crypto/index.d.ts +6 -0
- package/dist/crypto/index.js +6 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/keys.d.ts +12 -0
- package/dist/crypto/keys.js +42 -0
- package/dist/errors/BlindBountyError.d.ts +14 -0
- package/dist/errors/BlindBountyError.js +30 -0
- package/dist/errors/codes.d.ts +19 -0
- package/dist/errors/codes.js +48 -0
- package/dist/errors/index.cjs +136 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +60 -0
- package/dist/errors/index.d.ts +3 -0
- package/dist/errors/index.js +3 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/subclasses.d.ts +26 -0
- package/dist/errors/subclasses.js +41 -0
- package/dist/events/EventBus.d.ts +13 -0
- package/dist/events/EventBus.js +41 -0
- package/dist/events/index.cjs +41 -0
- package/dist/events/index.cjs.map +1 -0
- package/dist/events/index.d.cts +61 -0
- package/dist/events/index.d.ts +2 -0
- package/dist/events/index.js +2 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +45 -0
- package/dist/events/types.js +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +129 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/keystore/InMemoryKeyStore.d.ts +21 -0
- package/dist/keystore/InMemoryKeyStore.js +111 -0
- package/dist/keystore/KeyStore.d.ts +18 -0
- package/dist/keystore/KeyStore.js +1 -0
- package/dist/keystore/index.cjs +335 -0
- package/dist/keystore/index.cjs.map +1 -0
- package/dist/keystore/index.d.cts +23 -0
- package/dist/keystore/index.d.ts +2 -0
- package/dist/keystore/index.js +2 -0
- package/dist/keystore/index.js.map +1 -0
- package/dist/network/index.cjs +74 -0
- package/dist/network/index.cjs.map +1 -0
- package/dist/network/index.d.cts +36 -0
- package/dist/network/index.d.ts +3 -0
- package/dist/network/index.js +3 -0
- package/dist/network/index.js.map +1 -0
- package/dist/network/presets.d.ts +24 -0
- package/dist/network/presets.js +23 -0
- package/dist/network/resolve.d.ts +7 -0
- package/dist/network/resolve.js +17 -0
- package/dist/network/types.d.ts +16 -0
- package/dist/network/types.js +1 -0
- package/dist/signer/EthersSigner.d.ts +24 -0
- package/dist/signer/EthersSigner.js +68 -0
- package/dist/signer/PrivateKeySigner.d.ts +14 -0
- package/dist/signer/PrivateKeySigner.js +18 -0
- package/dist/signer/Signer.d.ts +35 -0
- package/dist/signer/Signer.js +1 -0
- package/dist/signer/index.cjs +121 -0
- package/dist/signer/index.cjs.map +1 -0
- package/dist/signer/index.d.cts +40 -0
- package/dist/signer/index.d.ts +3 -0
- package/dist/signer/index.js +3 -0
- package/dist/signer/index.js.map +1 -0
- package/dist/storage/MemoryStorage.d.ts +18 -0
- package/dist/storage/MemoryStorage.js +40 -0
- package/dist/storage/Storage.d.ts +14 -0
- package/dist/storage/Storage.js +1 -0
- package/dist/storage/ZgStorage.d.ts +24 -0
- package/dist/storage/ZgStorage.js +102 -0
- package/dist/storage/index.cjs +221 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +44 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/testing/index.cjs +4 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +2 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-BOG5Ub1z.d.cts +31 -0
- package/dist/types-BOG5Ub1z.d.ts +31 -0
- package/dist/types-V7_ZmUb-.d.cts +19 -0
- package/dist/types-hAsITUQ7.d.ts +19 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +1 -0
- package/dist/verifier/index.cjs +4 -0
- package/dist/verifier/index.cjs.map +1 -0
- package/dist/verifier/index.d.cts +2 -0
- package/dist/verifier/index.d.ts +1 -0
- package/dist/verifier/index.js +1 -0
- package/dist/verifier/index.js.map +1 -0
- package/dist/worker/Worker.d.ts +53 -0
- package/dist/worker/Worker.js +53 -0
- package/dist/worker/index.cjs +382 -0
- package/dist/worker/index.cjs.map +1 -0
- package/dist/worker/index.d.cts +58 -0
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/index.js +1 -0
- package/dist/worker/index.js.map +1 -0
- package/examples/agent-demo.ts +121 -0
- package/package.json +46 -0
- package/scripts/gen-crypto-fixtures.mjs +72 -0
- package/src/agent/Agent.ts +122 -0
- package/src/agent/index.ts +1 -0
- package/src/api/index.ts +1 -0
- package/src/chain/BlindEscrowClient.ts +182 -0
- package/src/chain/BlindReputationClient.ts +55 -0
- package/src/chain/ChainClient.ts +59 -0
- package/src/chain/TaskRegistryClient.ts +82 -0
- package/src/chain/abi/BlindEscrow.json +1113 -0
- package/src/chain/abi/BlindReputation.json +447 -0
- package/src/chain/abi/TaskRegistry.json +586 -0
- package/src/chain/abi/index.ts +5 -0
- package/src/chain/errors.ts +43 -0
- package/src/chain/index.ts +6 -0
- package/src/compute/index.ts +1 -0
- package/src/crypto/aes.ts +104 -0
- package/src/crypto/constants.ts +7 -0
- package/src/crypto/ecies.ts +60 -0
- package/src/crypto/envelope.ts +131 -0
- package/src/crypto/hkdf.ts +45 -0
- package/src/crypto/index.ts +6 -0
- package/src/crypto/keys.ts +56 -0
- package/src/errors/BlindMarketError.ts +38 -0
- package/src/errors/codes.ts +67 -0
- package/src/errors/index.ts +3 -0
- package/src/errors/subclasses.ts +59 -0
- package/src/events/EventBus.ts +45 -0
- package/src/events/index.ts +2 -0
- package/src/events/types.ts +13 -0
- package/src/index.ts +222 -0
- package/src/keystore/InMemoryKeyStore.ts +146 -0
- package/src/keystore/KeyStore.ts +19 -0
- package/src/keystore/index.ts +2 -0
- package/src/network/index.ts +3 -0
- package/src/network/presets.ts +27 -0
- package/src/network/resolve.ts +19 -0
- package/src/network/types.ts +18 -0
- package/src/signer/EthersSigner.ts +82 -0
- package/src/signer/PrivateKeySigner.ts +19 -0
- package/src/signer/Signer.ts +40 -0
- package/src/signer/index.ts +3 -0
- package/src/storage/MemoryStorage.ts +49 -0
- package/src/storage/Storage.ts +15 -0
- package/src/storage/ZgStorage.ts +124 -0
- package/src/storage/index.ts +3 -0
- package/src/testing/index.ts +1 -0
- package/src/types.ts +76 -0
- package/src/verifier/index.ts +1 -0
- package/src/worker/Worker.ts +98 -0
- package/src/worker/index.ts +1 -0
- package/test/agent.test.ts +193 -0
- package/test/chain.test.ts +145 -0
- package/test/crypto.aes.test.ts +81 -0
- package/test/crypto.compat.test.ts +33 -0
- package/test/crypto.ecies.test.ts +64 -0
- package/test/envelope.test.ts +82 -0
- package/test/errors.test.ts +64 -0
- package/test/events.test.ts +59 -0
- package/test/fixtures/crypto.json +16 -0
- package/test/keystore.test.ts +103 -0
- package/test/network.test.ts +53 -0
- package/test/signer.test.ts +66 -0
- package/test/smoke.test.ts +7 -0
- package/test/storage.test.ts +55 -0
- package/test/worker.test.ts +181 -0
- package/tsconfig.build.json +1 -0
- package/tsconfig.json +13 -0
- package/tsup.config.ts +32 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { StorageError } from '../src/errors/index.js';
|
|
3
|
+
import { MemoryStorage } from '../src/storage/index.js';
|
|
4
|
+
|
|
5
|
+
describe('MemoryStorage', () => {
|
|
6
|
+
it('upload returns deterministic root hash for the same bytes', async () => {
|
|
7
|
+
const s = new MemoryStorage();
|
|
8
|
+
const bytes = new TextEncoder().encode('hello');
|
|
9
|
+
const a = await s.upload(bytes);
|
|
10
|
+
const b = await s.upload(bytes);
|
|
11
|
+
expect(a.rootHash).toBe(b.rootHash);
|
|
12
|
+
expect(a.size).toBe(5);
|
|
13
|
+
expect(s.size()).toBe(1);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('download returns the uploaded bytes', async () => {
|
|
17
|
+
const s = new MemoryStorage();
|
|
18
|
+
const bytes = new TextEncoder().encode('payload');
|
|
19
|
+
const { rootHash } = await s.upload(bytes);
|
|
20
|
+
const got = await s.download(rootHash);
|
|
21
|
+
expect(new TextDecoder().decode(got)).toBe('payload');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('download of unknown hash throws STORAGE/NOT_FOUND', async () => {
|
|
25
|
+
const s = new MemoryStorage();
|
|
26
|
+
await expect(s.download('0x' + '00'.repeat(32) as `0x${string}`)).rejects.toBeInstanceOf(StorageError);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('hash is content-addressed and matches SHA-256', async () => {
|
|
30
|
+
const s = new MemoryStorage();
|
|
31
|
+
const h = await s.hash(new TextEncoder().encode('abc'));
|
|
32
|
+
// Known vector for SHA-256('abc')
|
|
33
|
+
expect(h).toBe('0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('returned bytes are a copy (mutation does not affect stored blob)', async () => {
|
|
37
|
+
const s = new MemoryStorage();
|
|
38
|
+
const bytes = new TextEncoder().encode('one');
|
|
39
|
+
const { rootHash } = await s.upload(bytes);
|
|
40
|
+
const a = await s.download(rootHash);
|
|
41
|
+
// biome-ignore lint/style/noNonNullAssertion: non-empty
|
|
42
|
+
a[0] = (a[0]! ^ 0xff) & 0xff;
|
|
43
|
+
const b = await s.download(rootHash);
|
|
44
|
+
expect(b[0]).not.toBe(a[0]);
|
|
45
|
+
expect(new TextDecoder().decode(b)).toBe('one');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('clear wipes all blobs', async () => {
|
|
49
|
+
const s = new MemoryStorage();
|
|
50
|
+
await s.upload(new Uint8Array([1]));
|
|
51
|
+
expect(s.size()).toBe(1);
|
|
52
|
+
s.clear();
|
|
53
|
+
expect(s.size()).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import type {
|
|
3
|
+
BlindEscrowClient,
|
|
4
|
+
CreateTaskArgs,
|
|
5
|
+
OnChainTask,
|
|
6
|
+
TaskRegistryClient,
|
|
7
|
+
} from '../src/chain/index.js';
|
|
8
|
+
import {
|
|
9
|
+
aesEncrypt,
|
|
10
|
+
eciesEncrypt,
|
|
11
|
+
generateAesKey,
|
|
12
|
+
generateKeyPair,
|
|
13
|
+
openEvidenceAsAgent,
|
|
14
|
+
} from '../src/crypto/index.js';
|
|
15
|
+
import { EventBus, type SdkEvents } from '../src/events/index.js';
|
|
16
|
+
import { PrivateKeySigner } from '../src/signer/index.js';
|
|
17
|
+
import { MemoryStorage } from '../src/storage/index.js';
|
|
18
|
+
import type { Address, Hex, RootHash, TaskId, TxReceiptLike } from '../src/types.js';
|
|
19
|
+
import { Worker } from '../src/worker/index.js';
|
|
20
|
+
|
|
21
|
+
const WORKER_PK = '0x1000000000000000000000000000000000000000000000000000000000000001';
|
|
22
|
+
const FAKE_USDC = '0x317227efcA18D004E12CA8046AEf7E1597458F25' as Address;
|
|
23
|
+
const FAKE_TASK_HASH = `0x${'ab'.repeat(32)}` as Hex;
|
|
24
|
+
|
|
25
|
+
class MockEscrow {
|
|
26
|
+
readonly calls: Array<{ method: string; args: unknown }> = [];
|
|
27
|
+
async submitEvidence(taskId: TaskId, evidenceHash: Hex): Promise<TxReceiptLike> {
|
|
28
|
+
this.calls.push({ method: 'submitEvidence', args: { taskId, evidenceHash } });
|
|
29
|
+
return { hash: `0x${'11'.repeat(32)}` as Hex, blockNumber: 10, gasUsed: 21000n };
|
|
30
|
+
}
|
|
31
|
+
async claimTimeout(taskId: TaskId): Promise<TxReceiptLike> {
|
|
32
|
+
this.calls.push({ method: 'claimTimeout', args: { taskId } });
|
|
33
|
+
return { hash: `0x${'22'.repeat(32)}` as Hex, blockNumber: 20, gasUsed: 21000n };
|
|
34
|
+
}
|
|
35
|
+
async getTask(_taskId: TaskId): Promise<OnChainTask> {
|
|
36
|
+
const t: OnChainTask = {
|
|
37
|
+
taskId: 1n,
|
|
38
|
+
agent: '0x0000000000000000000000000000000000000001' as Address,
|
|
39
|
+
worker: '0x0000000000000000000000000000000000000002' as Address,
|
|
40
|
+
token: FAKE_USDC,
|
|
41
|
+
amount: 5_000000n,
|
|
42
|
+
taskHash: FAKE_TASK_HASH,
|
|
43
|
+
evidenceHash: `0x${'00'.repeat(32)}` as Hex,
|
|
44
|
+
status: 'assigned',
|
|
45
|
+
createdAt: new Date(),
|
|
46
|
+
deadline: new Date(Date.now() + 3600_000),
|
|
47
|
+
};
|
|
48
|
+
return t;
|
|
49
|
+
}
|
|
50
|
+
// unused but required for shape
|
|
51
|
+
async createTask(_args: CreateTaskArgs) {
|
|
52
|
+
return { taskId: 1n, receipt: { hash: '0x' as Hex, blockNumber: 0, gasUsed: 0n } };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class MockRegistry {
|
|
57
|
+
async getOpenTasks(_offset: bigint, _limit: bigint): Promise<TaskId[]> {
|
|
58
|
+
return [1n, 2n, 3n];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function mkDeps() {
|
|
63
|
+
const storage = new MemoryStorage();
|
|
64
|
+
const signer = new PrivateKeySigner(WORKER_PK);
|
|
65
|
+
const events = new EventBus<SdkEvents>();
|
|
66
|
+
const escrow = new MockEscrow();
|
|
67
|
+
const registry = new MockRegistry();
|
|
68
|
+
return {
|
|
69
|
+
storage,
|
|
70
|
+
signer,
|
|
71
|
+
events,
|
|
72
|
+
escrow,
|
|
73
|
+
registry,
|
|
74
|
+
worker: new Worker({
|
|
75
|
+
// biome-ignore lint/suspicious/noExplicitAny: mocks match the subset used
|
|
76
|
+
escrow: escrow as any as BlindEscrowClient,
|
|
77
|
+
// biome-ignore lint/suspicious/noExplicitAny: mocks match the subset used
|
|
78
|
+
registry: registry as any as TaskRegistryClient,
|
|
79
|
+
storage,
|
|
80
|
+
signer,
|
|
81
|
+
events,
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
describe('Worker.browse + getTaskDetail', () => {
|
|
87
|
+
it('delegates to registry.getOpenTasks', async () => {
|
|
88
|
+
const { worker } = mkDeps();
|
|
89
|
+
const ids = await worker.browse(0n, 10n);
|
|
90
|
+
expect(ids).toEqual([1n, 2n, 3n]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('returns task detail from escrow.getTask', async () => {
|
|
94
|
+
const { worker } = mkDeps();
|
|
95
|
+
const detail = await worker.getTaskDetail(1n);
|
|
96
|
+
expect(detail.status).toBe('assigned');
|
|
97
|
+
expect(detail.token).toBe(FAKE_USDC);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('Worker.decryptInstructions', () => {
|
|
102
|
+
it('recovers plaintext instructions end-to-end', async () => {
|
|
103
|
+
const { worker, storage, signer } = mkDeps();
|
|
104
|
+
|
|
105
|
+
// Simulate agent side: generate AES key, encrypt instructions, upload, and
|
|
106
|
+
// wrap AES key to worker pubkey.
|
|
107
|
+
const aesKey = await generateAesKey();
|
|
108
|
+
const instructions = new TextEncoder().encode('photograph the storefront at 123 Main St');
|
|
109
|
+
const ciphertext = await aesEncrypt(instructions, aesKey);
|
|
110
|
+
const { rootHash } = await storage.upload(ciphertext);
|
|
111
|
+
const workerPub = await signer.getPublicKey();
|
|
112
|
+
const wrappedKey = await eciesEncrypt(aesKey, workerPub);
|
|
113
|
+
|
|
114
|
+
const decrypted = await worker.decryptInstructions({
|
|
115
|
+
wrappedKey,
|
|
116
|
+
workerPrivKey: WORKER_PK,
|
|
117
|
+
taskHash: rootHash,
|
|
118
|
+
});
|
|
119
|
+
expect(new TextDecoder().decode(decrypted)).toBe('photograph the storefront at 123 Main St');
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('Worker.submitEvidence', () => {
|
|
124
|
+
it('seals envelope + uploads + calls chain + emits event; agent can decrypt', async () => {
|
|
125
|
+
const { worker, storage, escrow, events } = mkDeps();
|
|
126
|
+
|
|
127
|
+
const agent = generateKeyPair();
|
|
128
|
+
const enclave = generateKeyPair();
|
|
129
|
+
|
|
130
|
+
const submitted: SdkEvents['evidence.submitted'][] = [];
|
|
131
|
+
events.on('evidence.submitted', (p) => submitted.push(p));
|
|
132
|
+
|
|
133
|
+
const res = await worker.submitEvidence({
|
|
134
|
+
taskId: 42n,
|
|
135
|
+
evidence: 'done: photos uploaded',
|
|
136
|
+
agentPubKey: agent.publicKey,
|
|
137
|
+
enclavePubKey: enclave.publicKey,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(res.rootHash).toMatch(/^0x[0-9a-f]{64}$/);
|
|
141
|
+
expect(escrow.calls.some((c) => c.method === 'submitEvidence')).toBe(true);
|
|
142
|
+
|
|
143
|
+
// Agent can download + decrypt the envelope
|
|
144
|
+
const blob = await storage.download(res.rootHash as RootHash);
|
|
145
|
+
const recovered = await openEvidenceAsAgent(blob, agent.privateKey);
|
|
146
|
+
expect(new TextDecoder().decode(recovered)).toBe('done: photos uploaded');
|
|
147
|
+
|
|
148
|
+
expect(submitted).toHaveLength(1);
|
|
149
|
+
expect(submitted[0]?.taskId).toBe(42n);
|
|
150
|
+
expect(submitted[0]?.rootHash).toBe(res.rootHash);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('accepts Uint8Array evidence as well as strings', async () => {
|
|
154
|
+
const { worker, storage } = mkDeps();
|
|
155
|
+
const agent = generateKeyPair();
|
|
156
|
+
const enclave = generateKeyPair();
|
|
157
|
+
const res = await worker.submitEvidence({
|
|
158
|
+
taskId: 1n,
|
|
159
|
+
evidence: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),
|
|
160
|
+
agentPubKey: agent.publicKey,
|
|
161
|
+
enclavePubKey: enclave.publicKey,
|
|
162
|
+
});
|
|
163
|
+
const blob = await storage.download(res.rootHash);
|
|
164
|
+
const recovered = await openEvidenceAsAgent(blob, agent.privateKey);
|
|
165
|
+
expect(Array.from(recovered)).toEqual([0xde, 0xad, 0xbe, 0xef]);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('Worker.claimTimeout', () => {
|
|
170
|
+
it('calls chain and emits payment.claimed', async () => {
|
|
171
|
+
const { worker, escrow, events } = mkDeps();
|
|
172
|
+
const claimed: SdkEvents['payment.claimed'][] = [];
|
|
173
|
+
events.on('payment.claimed', (p) => claimed.push(p));
|
|
174
|
+
|
|
175
|
+
const rec = await worker.claimTimeout(7n);
|
|
176
|
+
expect(rec.hash).toMatch(/^0x[0-9a-f]{64}$/);
|
|
177
|
+
expect(escrow.calls.some((c) => c.method === 'claimTimeout')).toBe(true);
|
|
178
|
+
expect(claimed).toHaveLength(1);
|
|
179
|
+
expect(claimed[0]?.taskId).toBe(7n);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "extends": "./tsconfig.json", "compilerOptions": { "noEmit": false }, "exclude": ["test/**/*", "node_modules", "dist"] }
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
|
+
|
|
3
|
+
const entries = [
|
|
4
|
+
'src/index.ts',
|
|
5
|
+
'src/agent/index.ts',
|
|
6
|
+
'src/worker/index.ts',
|
|
7
|
+
'src/verifier/index.ts',
|
|
8
|
+
'src/chain/index.ts',
|
|
9
|
+
'src/storage/index.ts',
|
|
10
|
+
'src/compute/index.ts',
|
|
11
|
+
'src/crypto/index.ts',
|
|
12
|
+
'src/api/index.ts',
|
|
13
|
+
'src/signer/index.ts',
|
|
14
|
+
'src/keystore/index.ts',
|
|
15
|
+
'src/events/index.ts',
|
|
16
|
+
'src/errors/index.ts',
|
|
17
|
+
'src/network/index.ts',
|
|
18
|
+
'src/testing/index.ts',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
entry: entries,
|
|
23
|
+
format: ['esm', 'cjs'],
|
|
24
|
+
dts: true,
|
|
25
|
+
sourcemap: true,
|
|
26
|
+
clean: true,
|
|
27
|
+
treeshake: true,
|
|
28
|
+
splitting: false,
|
|
29
|
+
target: 'es2022',
|
|
30
|
+
tsconfig: './tsconfig.build.json',
|
|
31
|
+
outDir: 'dist',
|
|
32
|
+
});
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
environment: 'node',
|
|
6
|
+
globals: false,
|
|
7
|
+
include: ['test/**/*.test.ts'],
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
reporter: ['text', 'html', 'lcov'],
|
|
11
|
+
include: ['src/**/*.ts'],
|
|
12
|
+
exclude: ['src/**/index.ts', 'src/**/*.d.ts'],
|
|
13
|
+
thresholds: { lines: 90, functions: 90, branches: 85, statements: 90 },
|
|
14
|
+
},
|
|
15
|
+
testTimeout: 20_000,
|
|
16
|
+
},
|
|
17
|
+
});
|