@antseed/cli 0.1.157 → 0.1.159

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 (285) hide show
  1. package/README.md +158 -6
  2. package/dist/cli/commands/ants/addresses.d.ts +3 -0
  3. package/dist/cli/commands/ants/addresses.d.ts.map +1 -0
  4. package/dist/cli/commands/ants/addresses.js +20 -0
  5. package/dist/cli/commands/ants/addresses.js.map +1 -0
  6. package/dist/cli/commands/ants/addresses.test.d.ts +2 -0
  7. package/dist/cli/commands/ants/addresses.test.d.ts.map +1 -0
  8. package/dist/cli/commands/ants/addresses.test.js +12 -0
  9. package/dist/cli/commands/ants/addresses.test.js.map +1 -0
  10. package/dist/cli/commands/ants/arguments.test.d.ts +2 -0
  11. package/dist/cli/commands/ants/arguments.test.d.ts.map +1 -0
  12. package/dist/cli/commands/ants/arguments.test.js +51 -0
  13. package/dist/cli/commands/ants/arguments.test.js.map +1 -0
  14. package/dist/cli/commands/ants/dashboard.d.ts +4 -0
  15. package/dist/cli/commands/ants/dashboard.d.ts.map +1 -0
  16. package/dist/cli/commands/ants/dashboard.js +45 -0
  17. package/dist/cli/commands/ants/dashboard.js.map +1 -0
  18. package/dist/cli/commands/ants/dashboard.test.d.ts +2 -0
  19. package/dist/cli/commands/ants/dashboard.test.d.ts.map +1 -0
  20. package/dist/cli/commands/ants/dashboard.test.js +14 -0
  21. package/dist/cli/commands/ants/dashboard.test.js.map +1 -0
  22. package/dist/cli/commands/ants/emissions.d.ts +5 -0
  23. package/dist/cli/commands/ants/emissions.d.ts.map +1 -0
  24. package/dist/cli/commands/ants/emissions.js +44 -0
  25. package/dist/cli/commands/ants/emissions.js.map +1 -0
  26. package/dist/cli/commands/ants/emissions.test.d.ts +2 -0
  27. package/dist/cli/commands/ants/emissions.test.d.ts.map +1 -0
  28. package/dist/cli/commands/ants/emissions.test.js +17 -0
  29. package/dist/cli/commands/ants/emissions.test.js.map +1 -0
  30. package/dist/cli/commands/ants/extend.d.ts +3 -0
  31. package/dist/cli/commands/ants/extend.d.ts.map +1 -0
  32. package/dist/cli/commands/ants/extend.js +14 -0
  33. package/dist/cli/commands/ants/extend.js.map +1 -0
  34. package/dist/cli/commands/ants/extend.test.d.ts +2 -0
  35. package/dist/cli/commands/ants/extend.test.d.ts.map +1 -0
  36. package/dist/cli/commands/ants/extend.test.js +13 -0
  37. package/dist/cli/commands/ants/extend.test.js.map +1 -0
  38. package/dist/cli/commands/ants/index.d.ts +7 -0
  39. package/dist/cli/commands/ants/index.d.ts.map +1 -0
  40. package/dist/cli/commands/ants/index.js +46 -0
  41. package/dist/cli/commands/ants/index.js.map +1 -0
  42. package/dist/cli/commands/ants/index.test.d.ts +2 -0
  43. package/dist/cli/commands/ants/index.test.d.ts.map +1 -0
  44. package/dist/cli/commands/ants/index.test.js +24 -0
  45. package/dist/cli/commands/ants/index.test.js.map +1 -0
  46. package/dist/cli/commands/ants/max-lock.d.ts +3 -0
  47. package/dist/cli/commands/ants/max-lock.d.ts.map +1 -0
  48. package/dist/cli/commands/ants/max-lock.js +13 -0
  49. package/dist/cli/commands/ants/max-lock.js.map +1 -0
  50. package/dist/cli/commands/ants/max-lock.test.d.ts +2 -0
  51. package/dist/cli/commands/ants/max-lock.test.d.ts.map +1 -0
  52. package/dist/cli/commands/ants/max-lock.test.js +15 -0
  53. package/dist/cli/commands/ants/max-lock.test.js.map +1 -0
  54. package/dist/cli/commands/ants/merge.d.ts +3 -0
  55. package/dist/cli/commands/ants/merge.d.ts.map +1 -0
  56. package/dist/cli/commands/ants/merge.js +12 -0
  57. package/dist/cli/commands/ants/merge.js.map +1 -0
  58. package/dist/cli/commands/ants/merge.test.d.ts +2 -0
  59. package/dist/cli/commands/ants/merge.test.d.ts.map +1 -0
  60. package/dist/cli/commands/ants/merge.test.js +16 -0
  61. package/dist/cli/commands/ants/merge.test.js.map +1 -0
  62. package/dist/cli/commands/ants/move.d.ts +3 -0
  63. package/dist/cli/commands/ants/move.d.ts.map +1 -0
  64. package/dist/cli/commands/ants/move.js +14 -0
  65. package/dist/cli/commands/ants/move.js.map +1 -0
  66. package/dist/cli/commands/ants/move.test.d.ts +2 -0
  67. package/dist/cli/commands/ants/move.test.d.ts.map +1 -0
  68. package/dist/cli/commands/ants/move.test.js +16 -0
  69. package/dist/cli/commands/ants/move.test.js.map +1 -0
  70. package/dist/cli/commands/ants/pool.d.ts +3 -0
  71. package/dist/cli/commands/ants/pool.d.ts.map +1 -0
  72. package/dist/cli/commands/ants/pool.js +21 -0
  73. package/dist/cli/commands/ants/pool.js.map +1 -0
  74. package/dist/cli/commands/ants/pool.test.d.ts +2 -0
  75. package/dist/cli/commands/ants/pool.test.d.ts.map +1 -0
  76. package/dist/cli/commands/ants/pool.test.js +13 -0
  77. package/dist/cli/commands/ants/pool.test.js.map +1 -0
  78. package/dist/cli/commands/ants/pools.d.ts +6 -0
  79. package/dist/cli/commands/ants/pools.d.ts.map +1 -0
  80. package/dist/cli/commands/ants/pools.js +50 -0
  81. package/dist/cli/commands/ants/pools.js.map +1 -0
  82. package/dist/cli/commands/ants/pools.test.d.ts +2 -0
  83. package/dist/cli/commands/ants/pools.test.d.ts.map +1 -0
  84. package/dist/cli/commands/ants/pools.test.js +18 -0
  85. package/dist/cli/commands/ants/pools.test.js.map +1 -0
  86. package/dist/cli/commands/ants/positions.d.ts +6 -0
  87. package/dist/cli/commands/ants/positions.d.ts.map +1 -0
  88. package/dist/cli/commands/ants/positions.js +46 -0
  89. package/dist/cli/commands/ants/positions.js.map +1 -0
  90. package/dist/cli/commands/ants/positions.test.d.ts +2 -0
  91. package/dist/cli/commands/ants/positions.test.d.ts.map +1 -0
  92. package/dist/cli/commands/ants/positions.test.js +19 -0
  93. package/dist/cli/commands/ants/positions.test.js.map +1 -0
  94. package/dist/cli/commands/ants/rewards.d.ts +9 -0
  95. package/dist/cli/commands/ants/rewards.d.ts.map +1 -0
  96. package/dist/cli/commands/ants/rewards.js +93 -0
  97. package/dist/cli/commands/ants/rewards.js.map +1 -0
  98. package/dist/cli/commands/ants/rewards.test.d.ts +2 -0
  99. package/dist/cli/commands/ants/rewards.test.d.ts.map +1 -0
  100. package/dist/cli/commands/ants/rewards.test.js +46 -0
  101. package/dist/cli/commands/ants/rewards.test.js.map +1 -0
  102. package/dist/cli/commands/ants/seller.d.ts +3 -0
  103. package/dist/cli/commands/ants/seller.d.ts.map +1 -0
  104. package/dist/cli/commands/ants/seller.js +32 -0
  105. package/dist/cli/commands/ants/seller.js.map +1 -0
  106. package/dist/cli/commands/ants/seller.test.d.ts +2 -0
  107. package/dist/cli/commands/ants/seller.test.d.ts.map +1 -0
  108. package/dist/cli/commands/ants/seller.test.js +16 -0
  109. package/dist/cli/commands/ants/seller.test.js.map +1 -0
  110. package/dist/cli/commands/ants/shared.d.ts +26 -0
  111. package/dist/cli/commands/ants/shared.d.ts.map +1 -0
  112. package/dist/cli/commands/ants/shared.js +94 -0
  113. package/dist/cli/commands/ants/shared.js.map +1 -0
  114. package/dist/cli/commands/ants/shared.test.d.ts +2 -0
  115. package/dist/cli/commands/ants/shared.test.d.ts.map +1 -0
  116. package/dist/cli/commands/ants/shared.test.js +25 -0
  117. package/dist/cli/commands/ants/shared.test.js.map +1 -0
  118. package/dist/cli/commands/ants/split.d.ts +3 -0
  119. package/dist/cli/commands/ants/split.d.ts.map +1 -0
  120. package/dist/cli/commands/ants/split.js +12 -0
  121. package/dist/cli/commands/ants/split.js.map +1 -0
  122. package/dist/cli/commands/ants/split.test.d.ts +2 -0
  123. package/dist/cli/commands/ants/split.test.d.ts.map +1 -0
  124. package/dist/cli/commands/ants/split.test.js +13 -0
  125. package/dist/cli/commands/ants/split.test.js.map +1 -0
  126. package/dist/cli/commands/ants/stake.d.ts +3 -0
  127. package/dist/cli/commands/ants/stake.d.ts.map +1 -0
  128. package/dist/cli/commands/ants/stake.js +15 -0
  129. package/dist/cli/commands/ants/stake.js.map +1 -0
  130. package/dist/cli/commands/ants/stake.test.d.ts +2 -0
  131. package/dist/cli/commands/ants/stake.test.d.ts.map +1 -0
  132. package/dist/cli/commands/ants/stake.test.js +17 -0
  133. package/dist/cli/commands/ants/stake.test.js.map +1 -0
  134. package/dist/cli/commands/ants/status.d.ts +9 -0
  135. package/dist/cli/commands/ants/status.d.ts.map +1 -0
  136. package/dist/cli/commands/ants/status.js +43 -0
  137. package/dist/cli/commands/ants/status.js.map +1 -0
  138. package/dist/cli/commands/ants/status.test.d.ts +2 -0
  139. package/dist/cli/commands/ants/status.test.d.ts.map +1 -0
  140. package/dist/cli/commands/ants/status.test.js +23 -0
  141. package/dist/cli/commands/ants/status.test.js.map +1 -0
  142. package/dist/cli/commands/ants/usage.d.ts +4 -0
  143. package/dist/cli/commands/ants/usage.d.ts.map +1 -0
  144. package/dist/cli/commands/ants/usage.js +31 -0
  145. package/dist/cli/commands/ants/usage.js.map +1 -0
  146. package/dist/cli/commands/ants/usage.test.d.ts +2 -0
  147. package/dist/cli/commands/ants/usage.test.d.ts.map +1 -0
  148. package/dist/cli/commands/ants/usage.test.js +15 -0
  149. package/dist/cli/commands/ants/usage.test.js.map +1 -0
  150. package/dist/cli/commands/ants/verify.d.ts +3 -0
  151. package/dist/cli/commands/ants/verify.d.ts.map +1 -0
  152. package/dist/cli/commands/ants/verify.js +51 -0
  153. package/dist/cli/commands/ants/verify.js.map +1 -0
  154. package/dist/cli/commands/ants/verify.test.d.ts +2 -0
  155. package/dist/cli/commands/ants/verify.test.d.ts.map +1 -0
  156. package/dist/cli/commands/ants/verify.test.js +51 -0
  157. package/dist/cli/commands/ants/verify.test.js.map +1 -0
  158. package/dist/cli/commands/ants/withdraw.d.ts +16 -0
  159. package/dist/cli/commands/ants/withdraw.d.ts.map +1 -0
  160. package/dist/cli/commands/ants/withdraw.js +48 -0
  161. package/dist/cli/commands/ants/withdraw.js.map +1 -0
  162. package/dist/cli/commands/ants/withdraw.test.d.ts +2 -0
  163. package/dist/cli/commands/ants/withdraw.test.d.ts.map +1 -0
  164. package/dist/cli/commands/ants/withdraw.test.js +30 -0
  165. package/dist/cli/commands/ants/withdraw.test.js.map +1 -0
  166. package/dist/cli/commands/buyer/start.d.ts.map +1 -1
  167. package/dist/cli/commands/buyer/start.js +7 -1
  168. package/dist/cli/commands/buyer/start.js.map +1 -1
  169. package/dist/cli/commands/emissions.d.ts +7 -0
  170. package/dist/cli/commands/emissions.d.ts.map +1 -1
  171. package/dist/cli/commands/emissions.js +105 -27
  172. package/dist/cli/commands/emissions.js.map +1 -1
  173. package/dist/cli/commands/emissions.test.js +7 -1
  174. package/dist/cli/commands/emissions.test.js.map +1 -1
  175. package/dist/cli/commands/network/browse.d.ts.map +1 -1
  176. package/dist/cli/commands/network/browse.js +12 -3
  177. package/dist/cli/commands/network/browse.js.map +1 -1
  178. package/dist/cli/commands/network/chain-config-helper.d.ts +21 -1
  179. package/dist/cli/commands/network/chain-config-helper.d.ts.map +1 -1
  180. package/dist/cli/commands/network/chain-config-helper.js +6 -1
  181. package/dist/cli/commands/network/chain-config-helper.js.map +1 -1
  182. package/dist/cli/commands/network/peer.d.ts.map +1 -1
  183. package/dist/cli/commands/network/peer.js +21 -1
  184. package/dist/cli/commands/network/peer.js.map +1 -1
  185. package/dist/cli/commands/parse-positive-integer.d.ts +2 -0
  186. package/dist/cli/commands/parse-positive-integer.d.ts.map +1 -0
  187. package/dist/cli/commands/parse-positive-integer.js +9 -0
  188. package/dist/cli/commands/parse-positive-integer.js.map +1 -0
  189. package/dist/cli/commands/reward-actions.d.ts +11 -0
  190. package/dist/cli/commands/reward-actions.d.ts.map +1 -0
  191. package/dist/cli/commands/reward-actions.js +22 -0
  192. package/dist/cli/commands/reward-actions.js.map +1 -0
  193. package/dist/cli/commands/seller/contract-clients.test.d.ts +2 -0
  194. package/dist/cli/commands/seller/contract-clients.test.d.ts.map +1 -0
  195. package/dist/cli/commands/seller/contract-clients.test.js +46 -0
  196. package/dist/cli/commands/seller/contract-clients.test.js.map +1 -0
  197. package/dist/cli/commands/seller/index.d.ts.map +1 -1
  198. package/dist/cli/commands/seller/index.js +4 -2
  199. package/dist/cli/commands/seller/index.js.map +1 -1
  200. package/dist/cli/commands/seller/pool.d.ts +15 -0
  201. package/dist/cli/commands/seller/pool.d.ts.map +1 -0
  202. package/dist/cli/commands/seller/pool.js +201 -0
  203. package/dist/cli/commands/seller/pool.js.map +1 -0
  204. package/dist/cli/commands/seller/pool.test.d.ts +2 -0
  205. package/dist/cli/commands/seller/pool.test.d.ts.map +1 -0
  206. package/dist/cli/commands/seller/pool.test.js +16 -0
  207. package/dist/cli/commands/seller/pool.test.js.map +1 -0
  208. package/dist/cli/commands/seller/register.d.ts.map +1 -1
  209. package/dist/cli/commands/seller/register.js +38 -8
  210. package/dist/cli/commands/seller/register.js.map +1 -1
  211. package/dist/cli/commands/seller/rewards.d.ts +13 -0
  212. package/dist/cli/commands/seller/rewards.d.ts.map +1 -0
  213. package/dist/cli/commands/seller/rewards.js +115 -0
  214. package/dist/cli/commands/seller/rewards.js.map +1 -0
  215. package/dist/cli/commands/seller/rewards.test.d.ts +2 -0
  216. package/dist/cli/commands/seller/rewards.test.d.ts.map +1 -0
  217. package/dist/cli/commands/seller/rewards.test.js +21 -0
  218. package/dist/cli/commands/seller/rewards.test.js.map +1 -0
  219. package/dist/cli/commands/seller/setup.d.ts.map +1 -1
  220. package/dist/cli/commands/seller/setup.js +2 -1
  221. package/dist/cli/commands/seller/setup.js.map +1 -1
  222. package/dist/cli/commands/seller/stake.d.ts.map +1 -1
  223. package/dist/cli/commands/seller/stake.js +104 -65
  224. package/dist/cli/commands/seller/stake.js.map +1 -1
  225. package/dist/cli/commands/seller/stake.test.d.ts +2 -0
  226. package/dist/cli/commands/seller/stake.test.d.ts.map +1 -0
  227. package/dist/cli/commands/seller/stake.test.js +99 -0
  228. package/dist/cli/commands/seller/stake.test.js.map +1 -0
  229. package/dist/cli/commands/seller/start.d.ts.map +1 -1
  230. package/dist/cli/commands/seller/start.js +6 -0
  231. package/dist/cli/commands/seller/start.js.map +1 -1
  232. package/dist/cli/commands/seller/status.d.ts.map +1 -1
  233. package/dist/cli/commands/seller/status.js +44 -2
  234. package/dist/cli/commands/seller/status.js.map +1 -1
  235. package/dist/cli/index.js +2 -0
  236. package/dist/cli/index.js.map +1 -1
  237. package/dist/cli/payment-utils.d.ts +33 -2
  238. package/dist/cli/payment-utils.d.ts.map +1 -1
  239. package/dist/cli/payment-utils.js +101 -2
  240. package/dist/cli/payment-utils.js.map +1 -1
  241. package/dist/config/types.d.ts +20 -0
  242. package/dist/config/types.d.ts.map +1 -1
  243. package/dist/plugins/verifier-evidence.test.d.ts +2 -0
  244. package/dist/plugins/verifier-evidence.test.d.ts.map +1 -0
  245. package/dist/plugins/verifier-evidence.test.js +41 -0
  246. package/dist/plugins/verifier-evidence.test.js.map +1 -0
  247. package/dist/plugins/verifier.d.ts +8 -10
  248. package/dist/plugins/verifier.d.ts.map +1 -1
  249. package/dist/plugins/verifier.js +23 -51
  250. package/dist/plugins/verifier.js.map +1 -1
  251. package/dist/plugins/verifier.test.js +1 -37
  252. package/dist/plugins/verifier.test.js.map +1 -1
  253. package/dist/proxy/buyer-proxy.d.ts +2 -1
  254. package/dist/proxy/buyer-proxy.d.ts.map +1 -1
  255. package/dist/proxy/buyer-proxy.js +104 -28
  256. package/dist/proxy/buyer-proxy.js.map +1 -1
  257. package/dist/proxy/buyer-proxy.test.js +177 -19
  258. package/dist/proxy/buyer-proxy.test.js.map +1 -1
  259. package/dist/proxy/network-models.d.ts +1 -2
  260. package/dist/proxy/network-models.d.ts.map +1 -1
  261. package/dist/proxy/network-models.js +10 -23
  262. package/dist/proxy/network-models.js.map +1 -1
  263. package/dist/proxy/network-models.test.js +56 -27
  264. package/dist/proxy/network-models.test.js.map +1 -1
  265. package/dist/proxy/tee-control.d.ts +14 -0
  266. package/dist/proxy/tee-control.d.ts.map +1 -0
  267. package/dist/proxy/tee-control.js +100 -0
  268. package/dist/proxy/tee-control.js.map +1 -0
  269. package/dist/proxy/tee-control.test.d.ts +2 -0
  270. package/dist/proxy/tee-control.test.d.ts.map +1 -0
  271. package/dist/proxy/tee-control.test.js +56 -0
  272. package/dist/proxy/tee-control.test.js.map +1 -0
  273. package/dist/proxy/tee-verification.d.ts +24 -0
  274. package/dist/proxy/tee-verification.d.ts.map +1 -0
  275. package/dist/proxy/tee-verification.js +128 -0
  276. package/dist/proxy/tee-verification.js.map +1 -0
  277. package/dist/proxy/tee-verification.test.d.ts +2 -0
  278. package/dist/proxy/tee-verification.test.d.ts.map +1 -0
  279. package/dist/proxy/tee-verification.test.js +241 -0
  280. package/dist/proxy/tee-verification.test.js.map +1 -0
  281. package/package.json +8 -6
  282. package/dist/cli/commands/seller/emissions.d.ts +0 -3
  283. package/dist/cli/commands/seller/emissions.d.ts.map +0 -1
  284. package/dist/cli/commands/seller/emissions.js +0 -5
  285. package/dist/cli/commands/seller/emissions.js.map +0 -1
@@ -0,0 +1,100 @@
1
+ import { randomBytes, timingSafeEqual } from 'node:crypto';
2
+ import { chmod, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { teeControlFileName } from '@antseed/node/tee-status';
5
+ export class TeeControl {
6
+ sessionId;
7
+ token = randomBytes(32).toString('hex');
8
+ file;
9
+ ready = false;
10
+ lastCheck = 0;
11
+ constructor(sessionId) {
12
+ this.sessionId = sessionId;
13
+ }
14
+ async publish(directory, port) {
15
+ await mkdir(directory, { recursive: true });
16
+ this.file = join(directory, teeControlFileName(port));
17
+ const temporary = `${this.file}.${this.sessionId}.tmp`;
18
+ try {
19
+ await writeFile(temporary, JSON.stringify({ token: this.token, sessionId: this.sessionId, port }), { mode: 0o600, flag: 'wx' });
20
+ await chmod(temporary, 0o600);
21
+ await rename(temporary, this.file);
22
+ this.ready = true;
23
+ }
24
+ finally {
25
+ await unlink(temporary).catch(() => { });
26
+ }
27
+ }
28
+ async close() {
29
+ this.ready = false;
30
+ if (!this.file)
31
+ return;
32
+ try {
33
+ const current = JSON.parse(await readFile(this.file, 'utf8'));
34
+ if (current.sessionId === this.sessionId)
35
+ await unlink(this.file);
36
+ }
37
+ catch { }
38
+ }
39
+ async handle(req, res, method, path, snapshot, check) {
40
+ const reply = (status, body) => {
41
+ res.writeHead(status, { 'content-type': 'application/json', 'cache-control': 'no-store' });
42
+ res.end(JSON.stringify(body));
43
+ };
44
+ const supplied = req.headers.authorization ?? '';
45
+ const expected = `Bearer ${this.token}`;
46
+ const remote = req.socket.remoteAddress;
47
+ if (!this.ready || req.headers.origin !== undefined
48
+ || !['127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(remote ?? '')
49
+ || Buffer.byteLength(supplied) !== Buffer.byteLength(expected)
50
+ || !timingSafeEqual(Buffer.from(supplied), Buffer.from(expected))) {
51
+ reply(403, { error: 'Local verification authorization required' });
52
+ return;
53
+ }
54
+ if (method === 'GET' && path === '/_antseed/verification') {
55
+ reply(200, snapshot());
56
+ return;
57
+ }
58
+ if (method !== 'POST' || path !== '/_antseed/verification/check') {
59
+ reply(404, { error: 'Unknown verification endpoint' });
60
+ return;
61
+ }
62
+ if (Date.now() - this.lastCheck < 1000) {
63
+ reply(429, { error: 'Wait before checking another seller' });
64
+ return;
65
+ }
66
+ this.lastCheck = Date.now();
67
+ try {
68
+ const chunks = [];
69
+ let size = 0;
70
+ const timer = setTimeout(() => req.destroy(), 5000);
71
+ try {
72
+ for await (const chunk of req) {
73
+ const bytes = Buffer.from(chunk);
74
+ size += bytes.length;
75
+ if (size > 1024) {
76
+ reply(413, { error: 'Request too large' });
77
+ return;
78
+ }
79
+ chunks.push(bytes);
80
+ }
81
+ }
82
+ finally {
83
+ clearTimeout(timer);
84
+ }
85
+ const body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
86
+ if (!body || typeof body !== 'object' || Array.isArray(body)
87
+ || Object.keys(body).length !== 1 || !('peerId' in body)
88
+ || typeof body.peerId !== 'string' || !/^(?:0x)?[a-f0-9]{40}$/i.test(body.peerId)) {
89
+ reply(400, { error: 'A known seller peerId is required' });
90
+ return;
91
+ }
92
+ await check(body.peerId);
93
+ reply(200, snapshot());
94
+ }
95
+ catch (error) {
96
+ reply(400, { error: error instanceof Error ? error.message : 'Verification unavailable' });
97
+ }
98
+ }
99
+ }
100
+ //# sourceMappingURL=tee-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-control.js","sourceRoot":"","sources":["../../src/proxy/tee-control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tee-control.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-control.test.d.ts","sourceRoot":"","sources":["../../src/proxy/tee-control.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { createServer } from 'node:http';
4
+ import { mkdtemp, readFile, rm, stat } from 'node:fs/promises';
5
+ import { tmpdir } from 'node:os';
6
+ import { join } from 'node:path';
7
+ import { teeControlFileName } from '@antseed/node/tee-status';
8
+ import { TeeControl } from './tee-control.js';
9
+ test('verification control authenticates, rejects origins/targets, bounds requests and cleans credentials', async (context) => {
10
+ const directory = await mkdtemp(join(tmpdir(), 'tee-control-'));
11
+ const control = new TeeControl('session');
12
+ const checks = [];
13
+ const seller = 'a'.repeat(40);
14
+ const snapshot = { sessionId: 'session', verificationEnabled: true, evidence: [] };
15
+ const server = createServer((req, res) => {
16
+ void control.handle(req, res, req.method, req.url, () => snapshot, async (peerId) => {
17
+ if (peerId !== seller)
18
+ throw new Error('Unknown seller');
19
+ checks.push(peerId);
20
+ });
21
+ });
22
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
23
+ const port = server.address().port;
24
+ context.after(async () => {
25
+ await control.close();
26
+ await new Promise((resolve) => server.close(() => resolve()));
27
+ await rm(directory, { recursive: true, force: true });
28
+ });
29
+ await control.publish(directory, port);
30
+ const file = join(directory, teeControlFileName(port));
31
+ assert.equal((await stat(file)).mode & 0o777, 0o600);
32
+ const credential = JSON.parse(await readFile(file, 'utf8'));
33
+ const url = `http://127.0.0.1:${port}/_antseed/verification`;
34
+ const headers = { authorization: `Bearer ${credential.token}` };
35
+ assert.equal((await fetch(url)).status, 403);
36
+ assert.equal((await fetch(url, { headers: { authorization: 'Bearer invalid' } })).status, 403);
37
+ assert.equal((await fetch(url, { headers: { ...headers, origin: 'http://127.0.0.1.evil.test' } })).status, 403);
38
+ assert.equal((await fetch(url, { headers: { ...headers, origin: 'http://localhost:3000' } })).status, 403);
39
+ const status = await (await fetch(url, { headers })).json();
40
+ assert.deepEqual(status, snapshot);
41
+ assert.equal((await fetch(`${url}/resume`, { method: 'POST', headers })).status, 404);
42
+ assert.ok(!JSON.stringify(status).includes(credential.token));
43
+ assert.equal((await fetch(`${url}/check`, { method: 'POST', headers, body: JSON.stringify({ peerId: seller, url: 'https://evil.test' }) })).status, 400);
44
+ await new Promise((resolve) => setTimeout(resolve, 1010));
45
+ assert.equal((await fetch(`${url}/check`, { method: 'POST', headers, body: JSON.stringify({ peerId: 'b'.repeat(40) }) })).status, 400);
46
+ await new Promise((resolve) => setTimeout(resolve, 1010));
47
+ assert.equal((await fetch(`${url}/check`, { method: 'POST', headers, body: JSON.stringify({ peerId: seller }) })).status, 200);
48
+ assert.deepEqual(checks, [seller]);
49
+ assert.equal((await fetch(`${url}/check`, { method: 'POST', headers, body: JSON.stringify({ peerId: seller }) })).status, 429);
50
+ await new Promise((resolve) => setTimeout(resolve, 1010));
51
+ assert.equal((await fetch(`${url}/check`, { method: 'POST', headers, body: 'x'.repeat(2048) })).status, 413);
52
+ await control.close();
53
+ await assert.rejects(readFile(file));
54
+ assert.equal((await fetch(url, { headers })).status, 403);
55
+ });
56
+ //# sourceMappingURL=tee-control.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-control.test.js","sourceRoot":"","sources":["../../src/proxy/tee-control.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type TeeSnapshot } from '@antseed/node/tee-status';
2
+ import { type VerifierPolicy, type VerifyOutcome } from '../plugins/verifier.js';
3
+ type Peer = {
4
+ peerId: string;
5
+ capabilities?: string[];
6
+ };
7
+ export declare class TeeVerification {
8
+ readonly policy: VerifierPolicy | undefined;
9
+ private readonly now;
10
+ readonly sessionId: `${string}-${string}-${string}-${string}-${string}`;
11
+ private readonly queries;
12
+ private closed;
13
+ private activeChecks;
14
+ constructor(policy: VerifierPolicy | undefined, now?: () => number);
15
+ verify(peer: Peer, policy: VerifierPolicy, run: () => Promise<VerifyOutcome>, force?: boolean): Promise<VerifyOutcome>;
16
+ verifyForDisplay(peer: Peer, run: () => Promise<VerifyOutcome>): Promise<VerifyOutcome>;
17
+ private cacheExpiry;
18
+ private verifyCached;
19
+ observePeers(peers: readonly Peer[]): void;
20
+ snapshot(peers: readonly Peer[]): TeeSnapshot;
21
+ close(): void;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=tee-verification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-verification.d.ts","sourceRoot":"","sources":["../../src/proxy/tee-verification.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2E,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEpI,OAAO,EAA8C,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE5H,KAAK,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAGvD,qBAAa,eAAe;IAQd,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS;IAAE,OAAO,CAAC,QAAQ,CAAC,GAAG;IAP7E,QAAQ,CAAC,SAAS,sDAAe;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IACF,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,YAAY,CAAI;gBAEH,MAAM,EAAE,cAAc,GAAG,SAAS,EAAmB,GAAG,eAAW;IAElF,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpH,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAK7F,OAAO,CAAC,WAAW;YAKL,YAAY;IAmD1B,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI;IAO1C,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,WAAW;IA2B7C,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,128 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { QueryClient } from '@tanstack/query-core';
3
+ import { TEE_BADGE_MAX_AGE_MS, TEE_MAX_AGE_MS, TEE_VERIFIER_ID } from '@antseed/node/tee-status';
4
+ import { parseVerifierCapabilities } from '@antseed/node/verifier-capabilities';
5
+ import { selectVerifier, verifierSupportFingerprint } from '../plugins/verifier.js';
6
+ export class TeeVerification {
7
+ policy;
8
+ now;
9
+ sessionId = randomUUID();
10
+ queries = new QueryClient({
11
+ defaultOptions: { queries: { retry: false, networkMode: 'always', gcTime: Infinity, structuralSharing: false } },
12
+ });
13
+ closed = false;
14
+ activeChecks = 0;
15
+ constructor(policy, now = Date.now) {
16
+ this.policy = policy;
17
+ this.now = now;
18
+ }
19
+ async verify(peer, policy, run, force = false) {
20
+ return this.verifyCached(peer, policy, run, TEE_MAX_AGE_MS, force);
21
+ }
22
+ async verifyForDisplay(peer, run) {
23
+ return this.verifyCached(peer, { require: true, prefer: [TEE_VERIFIER_ID] }, run, TEE_BADGE_MAX_AGE_MS, false, true);
24
+ }
25
+ cacheExpiry(entry, maxAgeMs) {
26
+ return entry.outcome?.sellerNodeVerified && !entry.outcome.transient
27
+ ? entry.checkedAt + maxAgeMs : entry.checkedAt + TEE_MAX_AGE_MS;
28
+ }
29
+ async verifyCached(peer, policy, run, maxAgeMs, force = false, requireSellerNode = false) {
30
+ if (this.closed)
31
+ return { ok: false, verified: false, reason: 'Buyer stopped', transient: true };
32
+ const chosen = selectVerifier(policy, parseVerifierCapabilities(peer.capabilities));
33
+ const fingerprint = verifierSupportFingerprint(peer.capabilities);
34
+ const queryKey = [peer.peerId, chosen ?? '', fingerprint];
35
+ const cache = this.queries.getQueryCache();
36
+ for (const query of cache.findAll({ queryKey: [peer.peerId] })) {
37
+ if (query.queryKey[2] !== fingerprint)
38
+ cache.remove(query);
39
+ }
40
+ const previous = cache.find({ queryKey, exact: true });
41
+ const pending = previous?.state.fetchStatus === 'fetching';
42
+ const allow = (outcome) => ({
43
+ ...outcome, ok: !policy.require || (requireSellerNode ? outcome.sellerNodeVerified === true : outcome.verified),
44
+ });
45
+ const entry = previous?.state.data;
46
+ if (!pending && !force && entry?.outcome && !entry.outcome.transient && this.cacheExpiry(entry, maxAgeMs) > this.now())
47
+ return allow(entry.outcome);
48
+ if (!pending && this.activeChecks >= 8) {
49
+ return { ok: !policy.require, verified: false, transient: true, code: 'busy', reason: 'Verification busy; retry shortly' };
50
+ }
51
+ if (!previous && cache.getAll().length >= 512) {
52
+ const oldest = cache.getAll().find((query) => query.state.fetchStatus === 'idle');
53
+ if (oldest)
54
+ cache.remove(oldest);
55
+ }
56
+ const checkedAt = pending ? Number(previous.meta?.checkedAt) : this.now();
57
+ const options = {
58
+ queryKey, staleTime: 0, meta: { checkedAt },
59
+ queryFn: async () => {
60
+ this.activeChecks += 1;
61
+ try {
62
+ const { ok: _allowed, ...outcome } = await Promise.resolve().then(run);
63
+ return { checkedAt, outcome };
64
+ }
65
+ catch (error) {
66
+ return { checkedAt, outcome: {
67
+ verified: false, transient: true, reason: error instanceof Error ? error.message : 'Verification unavailable',
68
+ } };
69
+ }
70
+ finally {
71
+ this.activeChecks -= 1;
72
+ }
73
+ },
74
+ };
75
+ const resultPromise = this.queries.fetchQuery(options);
76
+ const query = cache.find({ queryKey, exact: true });
77
+ try {
78
+ const result = await resultPromise;
79
+ if (!this.closed && cache.find({ queryKey, exact: true }) === query && result.outcome)
80
+ return allow(result.outcome);
81
+ }
82
+ catch {
83
+ return { ok: !policy.require && !this.closed, verified: false, transient: true, reason: 'Verification session or seller capabilities changed' };
84
+ }
85
+ return { ok: !policy.require && !this.closed, verified: false, transient: true, reason: 'Verification session or seller capabilities changed' };
86
+ }
87
+ observePeers(peers) {
88
+ const fingerprints = new Map(peers.map((peer) => [peer.peerId, verifierSupportFingerprint(peer.capabilities)]));
89
+ for (const query of this.queries.getQueryCache().getAll()) {
90
+ if (fingerprints.get(String(query.queryKey[0])) !== query.queryKey[2])
91
+ this.queries.getQueryCache().remove(query);
92
+ }
93
+ }
94
+ snapshot(peers) {
95
+ const evidence = [];
96
+ this.observePeers(peers);
97
+ for (const peer of peers) {
98
+ if (!parseVerifierCapabilities(peer.capabilities).supported.includes(TEE_VERIFIER_ID))
99
+ continue;
100
+ const fingerprint = verifierSupportFingerprint(peer.capabilities);
101
+ const query = this.queries.getQueryCache().find({ queryKey: [peer.peerId, TEE_VERIFIER_ID, fingerprint], exact: true });
102
+ if (!query)
103
+ continue;
104
+ const checking = query.state.fetchStatus === 'fetching';
105
+ const entry = checking ? { checkedAt: Number(query.meta?.checkedAt) } : query.state.data;
106
+ if (!entry)
107
+ continue;
108
+ evidence.push({
109
+ peerId: peer.peerId, verifierId: TEE_VERIFIER_ID, verifierVersion: entry.outcome?.version,
110
+ fingerprint, checkedAt: entry.checkedAt, expiresAt: checking ? 0 : this.cacheExpiry(entry, TEE_BADGE_MAX_AGE_MS),
111
+ sellerNodeVerified: entry.outcome?.sellerNodeVerified === true,
112
+ claims: entry.outcome?.claims ?? [], reason: entry.outcome?.reason,
113
+ checking,
114
+ unavailable: entry.outcome?.transient === true,
115
+ });
116
+ }
117
+ return {
118
+ sessionId: this.sessionId,
119
+ verificationEnabled: Boolean(this.policy),
120
+ evidence,
121
+ };
122
+ }
123
+ close() {
124
+ this.closed = true;
125
+ this.queries.clear();
126
+ }
127
+ }
128
+ //# sourceMappingURL=tee-verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-verification.js","sourceRoot":"","sources":["../../src/proxy/tee-verification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tee-verification.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee-verification.test.d.ts","sourceRoot":"","sources":["../../src/proxy/tee-verification.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,241 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { onlineManager } from '@tanstack/query-core';
4
+ import { TEE_BADGE_MAX_AGE_MS, TEE_MAX_AGE_MS } from '@antseed/node/tee-status';
5
+ import { TeeVerification } from './tee-verification.js';
6
+ const peer = { peerId: 'a'.repeat(40), capabilities: ['verifier.antseed-verifier'] };
7
+ const strict = { require: true, prefer: ['antseed-verifier'] };
8
+ const pass = { ok: true, verified: true, sellerNodeVerified: true, sdk: 'antseed-verifier' };
9
+ test('display checks reuse successful evidence for 24 hours without extending it on reads', async () => {
10
+ let now = 100;
11
+ let runs = 0;
12
+ const service = new TeeVerification(strict, () => now);
13
+ const run = async () => { runs += 1; return pass; };
14
+ await service.verifyForDisplay(peer, run);
15
+ const evidence = service.snapshot([peer]).evidence[0];
16
+ assert.equal(evidence.checkedAt, 100);
17
+ assert.equal(evidence.expiresAt, 100 + TEE_BADGE_MAX_AGE_MS);
18
+ now += TEE_MAX_AGE_MS;
19
+ await service.verifyForDisplay(peer, run);
20
+ now = evidence.expiresAt - 1;
21
+ await service.verifyForDisplay(peer, run);
22
+ assert.equal(runs, 1);
23
+ assert.deepEqual(service.snapshot([peer]).evidence[0], evidence);
24
+ now = evidence.expiresAt;
25
+ await service.verifyForDisplay(peer, run);
26
+ assert.equal(runs, 2);
27
+ });
28
+ test('a day-long badge never authorizes routing after the five-minute routing expiry', async () => {
29
+ let now = 100;
30
+ const service = new TeeVerification(strict, () => now);
31
+ let runs = 0;
32
+ await service.verifyForDisplay(peer, async () => pass);
33
+ now += TEE_MAX_AGE_MS;
34
+ assert.ok(service.snapshot([peer]).evidence[0].expiresAt > now);
35
+ const outcome = await service.verify(peer, strict, async () => {
36
+ runs += 1;
37
+ return { ok: false, verified: false, sellerNodeVerified: false };
38
+ });
39
+ assert.equal(runs, 1);
40
+ assert.equal(outcome.ok, false);
41
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
42
+ assert.equal(service.snapshot([peer]).evidence[0]?.expiresAt, now + TEE_MAX_AGE_MS);
43
+ });
44
+ test('routing and display share in-flight checks and revoke badges on unavailable results', async () => {
45
+ let now = 100;
46
+ const service = new TeeVerification(strict, () => now);
47
+ let finish;
48
+ const display = service.verifyForDisplay(peer, () => new Promise((resolve) => { finish = resolve; }));
49
+ const routed = service.verify(peer, strict, async () => { assert.fail('duplicate attestation'); });
50
+ await Promise.resolve();
51
+ finish(pass);
52
+ assert.ok((await display).sellerNodeVerified);
53
+ assert.ok((await routed).ok);
54
+ now += TEE_MAX_AGE_MS;
55
+ await service.verify(peer, strict, async () => ({ ok: false, verified: false, transient: true }));
56
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
57
+ assert.equal(service.snapshot([peer]).evidence[0]?.unavailable, true);
58
+ assert.ok((await service.verifyForDisplay(peer, async () => pass)).sellerNodeVerified);
59
+ });
60
+ test('display failures keep the short TTL and capability changes discard day-long successes', async () => {
61
+ let now = 100;
62
+ let runs = 0;
63
+ const service = new TeeVerification(strict, () => now);
64
+ await service.verifyForDisplay(peer, async () => ({ ok: false, verified: false }));
65
+ assert.equal(service.snapshot([peer]).evidence[0]?.expiresAt, now + TEE_MAX_AGE_MS);
66
+ now += TEE_MAX_AGE_MS;
67
+ const run = async () => { runs += 1; return pass; };
68
+ await service.verifyForDisplay(peer, run);
69
+ const changed = { ...peer, capabilities: [...peer.capabilities, 'verifier.other'] };
70
+ service.observePeers([changed]);
71
+ assert.deepEqual(service.snapshot([changed]).evidence, []);
72
+ await service.verifyForDisplay(changed, run);
73
+ assert.equal(runs, 2);
74
+ service.close();
75
+ assert.deepEqual(service.snapshot([changed]).evidence, []);
76
+ assert.equal((await service.verifyForDisplay(changed, run)).ok, false);
77
+ });
78
+ test('evidence cache never reuses an optional routing allowance as required verification', async () => {
79
+ const service = new TeeVerification(strict);
80
+ const fail = { ok: true, verified: false, reason: 'Failed' };
81
+ assert.equal((await service.verify(peer, { require: false }, async () => fail)).ok, true);
82
+ assert.equal((await service.verify(peer, strict, async () => pass)).ok, false);
83
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
84
+ assert.equal(service.snapshot([peer]).evidence[0]?.unavailable, false);
85
+ });
86
+ test('badge claim requirements do not become a new CLI routing policy', async () => {
87
+ const service = new TeeVerification(strict);
88
+ const genericPass = { ok: true, verified: true, sellerNodeVerified: false };
89
+ const display = await service.verifyForDisplay(peer, async () => genericPass);
90
+ assert.equal(display.ok, false);
91
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
92
+ const routed = await service.verify(peer, strict, async () => { assert.fail('should reuse generic verifier evidence'); });
93
+ assert.equal(routed.ok, true);
94
+ assert.deepEqual(service.snapshot([peer]), {
95
+ sessionId: service.sessionId, verificationEnabled: true, evidence: service.snapshot([peer]).evidence,
96
+ });
97
+ service.close();
98
+ });
99
+ test('expiry, forced failed recheck, transient retries and daemon restart revoke success', async () => {
100
+ let now = 100;
101
+ let runs = 0;
102
+ const service = new TeeVerification(strict, () => now);
103
+ const run = async () => { runs += 1; return pass; };
104
+ await service.verify(peer, strict, run);
105
+ await service.verify(peer, strict, run);
106
+ assert.equal(runs, 1);
107
+ now += TEE_MAX_AGE_MS;
108
+ await service.verify(peer, strict, run);
109
+ assert.equal(runs, 2);
110
+ await service.verify(peer, strict, async () => ({ ok: false, verified: false, transient: true }), true);
111
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
112
+ assert.equal(service.snapshot([peer]).evidence[0]?.unavailable, true);
113
+ await service.verify(peer, strict, run);
114
+ assert.equal(runs, 3);
115
+ const restarted = new TeeVerification(strict);
116
+ assert.notEqual(service.sessionId, restarted.sessionId);
117
+ assert.deepEqual(restarted.snapshot([peer]).evidence, []);
118
+ });
119
+ test('concurrent checks deduplicate; superseded advertisements cannot restore old evidence', async () => {
120
+ const service = new TeeVerification(strict);
121
+ let finish;
122
+ let runs = 0;
123
+ const run = () => { runs += 1; return new Promise((resolve) => { finish = resolve; }); };
124
+ const first = service.verify(peer, strict, run);
125
+ const second = service.verify(peer, strict, run, true);
126
+ await Promise.resolve();
127
+ assert.equal(runs, 1);
128
+ assert.equal(service.snapshot([peer]).evidence[0]?.checking, true);
129
+ const changed = { ...peer, capabilities: [...peer.capabilities, 'verifier.other'] };
130
+ await service.verify(changed, strict, async () => ({ ok: false, verified: false }));
131
+ finish(pass);
132
+ assert.equal((await first).ok, false);
133
+ assert.equal((await second).ok, false);
134
+ assert.equal(service.snapshot([changed]).evidence[0]?.sellerNodeVerified, false);
135
+ assert.deepEqual(service.snapshot([{ ...peer, capabilities: [] }]).evidence, []);
136
+ assert.deepEqual(service.snapshot([peer]).evidence, []);
137
+ });
138
+ test('discovery updates revoke evidence even without a status reader', async () => {
139
+ const service = new TeeVerification(strict);
140
+ await service.verify(peer, strict, async () => pass);
141
+ service.observePeers([{ ...peer, capabilities: [] }]);
142
+ service.observePeers([peer]);
143
+ assert.deepEqual(service.snapshot([peer]).evidence, []);
144
+ });
145
+ test('stopped sessions and exhausted concurrency fail closed', async () => {
146
+ const service = new TeeVerification(strict);
147
+ const finishers = [];
148
+ const pending = Array.from({ length: 8 }, (_, index) => service.verify({ ...peer, peerId: String(index) }, strict, () => new Promise((resolve) => finishers.push(resolve))));
149
+ assert.equal((await service.verify(peer, strict, async () => pass)).ok, false);
150
+ await Promise.resolve();
151
+ service.close();
152
+ finishers.forEach((finish) => finish(pass));
153
+ assert.ok((await Promise.all(pending)).every((outcome) => !outcome.ok));
154
+ assert.equal((await service.verify(peer, strict, async () => pass)).ok, false);
155
+ });
156
+ test('verifier exceptions revoke success without automatic retries', async () => {
157
+ const service = new TeeVerification(strict);
158
+ await service.verifyForDisplay(peer, async () => pass);
159
+ let runs = 0;
160
+ const run = async () => { runs += 1; throw new Error('Verifier unavailable'); };
161
+ const result = await service.verify(peer, strict, run, true);
162
+ assert.equal(result.ok, false);
163
+ assert.equal(result.transient, true);
164
+ assert.equal(result.reason, 'Verifier unavailable');
165
+ assert.equal(runs, 1);
166
+ assert.equal(service.snapshot([peer]).evidence[0]?.sellerNodeVerified, false);
167
+ await service.verifyForDisplay(peer, run);
168
+ assert.equal(runs, 2);
169
+ service.close();
170
+ });
171
+ test('refresh hides stale success and shares evidence, not caller routing policy', async () => {
172
+ const service = new TeeVerification(strict);
173
+ await service.verifyForDisplay(peer, async () => pass);
174
+ let finish;
175
+ const optional = service.verify(peer, { require: false }, () => new Promise((resolve) => { finish = resolve; }), true);
176
+ const required = service.verifyForDisplay(peer, async () => { assert.fail('duplicate attestation'); });
177
+ const evidence = service.snapshot([peer]).evidence[0];
178
+ assert.equal(evidence.checking, true);
179
+ assert.equal(evidence.sellerNodeVerified, false);
180
+ await Promise.resolve();
181
+ finish({ ok: true, verified: false, sellerNodeVerified: false });
182
+ assert.equal((await optional).ok, true);
183
+ assert.equal((await required).ok, false);
184
+ service.close();
185
+ });
186
+ test('invalidating pending queries releases waiters but retains the underlying concurrency limit', async () => {
187
+ const service = new TeeVerification(strict);
188
+ const finishers = [];
189
+ const pending = Array.from({ length: 8 }, (_, index) => service.verify({ ...peer, peerId: String(index) }, strict, () => new Promise((resolve) => finishers.push(resolve))));
190
+ await Promise.resolve();
191
+ service.observePeers([]);
192
+ assert.ok((await Promise.all(pending)).every((outcome) => !outcome.ok && outcome.transient));
193
+ const busy = await service.verifyForDisplay(peer, async () => { assert.fail('exceeded concurrency limit'); });
194
+ assert.equal(busy.code, 'busy');
195
+ finishers.forEach((finish) => finish(pass));
196
+ await new Promise((resolve) => setImmediate(resolve));
197
+ assert.deepEqual(service.snapshot([peer]).evidence, []);
198
+ assert.equal((await service.verifyForDisplay(peer, async () => pass)).ok, true);
199
+ service.close();
200
+ });
201
+ test('bounded query cache evicts settled entries, not pending checks', async () => {
202
+ const service = new TeeVerification(strict);
203
+ let finish;
204
+ const pending = service.verifyForDisplay(peer, () => new Promise((resolve) => { finish = resolve; }));
205
+ const peers = Array.from({ length: 512 }, (_, index) => ({ ...peer, peerId: String(index) }));
206
+ for (const seller of peers)
207
+ await service.verifyForDisplay(seller, async () => pass);
208
+ const snapshot = service.snapshot([peer, ...peers]);
209
+ assert.equal(snapshot.evidence.length, 512);
210
+ assert.equal(snapshot.evidence.find((entry) => entry.peerId === peer.peerId)?.checking, true);
211
+ assert.equal(snapshot.evidence.some((entry) => entry.peerId === peers[0].peerId), false);
212
+ const duplicate = service.verifyForDisplay(peer, async () => { assert.fail('evicted pending attestation'); });
213
+ finish(pass);
214
+ assert.equal((await pending).ok, true);
215
+ assert.equal((await duplicate).ok, true);
216
+ service.close();
217
+ });
218
+ test('expiry is measured from check start, not query completion time', async () => {
219
+ let now = 100;
220
+ const service = new TeeVerification(strict, () => now);
221
+ await service.verifyForDisplay(peer, async () => { now += TEE_MAX_AGE_MS; return pass; });
222
+ assert.equal(service.snapshot([peer]).evidence[0]?.checkedAt, 100);
223
+ assert.equal(service.snapshot([peer]).evidence[0]?.expiresAt, 100 + TEE_BADGE_MAX_AGE_MS);
224
+ let runs = 0;
225
+ await service.verify(peer, strict, async () => { runs += 1; return pass; });
226
+ assert.equal(runs, 1);
227
+ service.close();
228
+ });
229
+ test('headless buyer checks do not pause for browser connectivity state', async () => {
230
+ const service = new TeeVerification(strict);
231
+ const wasOnline = onlineManager.isOnline();
232
+ onlineManager.setOnline(false);
233
+ try {
234
+ assert.equal((await service.verifyForDisplay(peer, async () => pass)).ok, true);
235
+ }
236
+ finally {
237
+ service.close();
238
+ onlineManager.setOnline(wasOnline);
239
+ }
240
+ });
241
+ //# sourceMappingURL=tee-verification.test.js.map