@labacacia/nps-sdk 1.0.0-alpha.6 → 1.0.0-alpha.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 (369) hide show
  1. package/CHANGELOG.cn.md +126 -0
  2. package/CHANGELOG.md +135 -0
  3. package/README.cn.md +9 -2
  4. package/README.md +9 -2
  5. package/dist/core/anchor-cache.d.ts +42 -0
  6. package/dist/core/anchor-cache.d.ts.map +1 -0
  7. package/dist/core/anchor-cache.js +104 -0
  8. package/dist/core/anchor-cache.js.map +1 -0
  9. package/dist/core/cache.d.ts +14 -0
  10. package/dist/core/cache.d.ts.map +1 -0
  11. package/dist/core/cache.js +80 -0
  12. package/dist/core/cache.js.map +1 -0
  13. package/dist/core/canonical-json.d.ts +12 -0
  14. package/dist/core/canonical-json.d.ts.map +1 -0
  15. package/dist/core/canonical-json.js +44 -0
  16. package/dist/core/canonical-json.js.map +1 -0
  17. package/dist/core/codec.d.ts +32 -0
  18. package/dist/core/codec.d.ts.map +1 -0
  19. package/dist/core/codec.js +119 -0
  20. package/dist/core/codec.js.map +1 -0
  21. package/dist/core/codecs/index.d.ts +4 -0
  22. package/dist/core/codecs/index.d.ts.map +1 -0
  23. package/{src/core/codecs/index.ts → dist/core/codecs/index.js} +1 -0
  24. package/dist/core/codecs/index.js.map +1 -0
  25. package/dist/core/codecs/ncp-codec.d.ts +39 -0
  26. package/dist/core/codecs/ncp-codec.d.ts.map +1 -0
  27. package/dist/core/codecs/ncp-codec.js +93 -0
  28. package/dist/core/codecs/ncp-codec.js.map +1 -0
  29. package/dist/core/codecs/tier1-json-codec.d.ts +10 -0
  30. package/dist/core/codecs/tier1-json-codec.d.ts.map +1 -0
  31. package/{src/core/codecs/tier1-json-codec.ts → dist/core/codecs/tier1-json-codec.js} +11 -16
  32. package/dist/core/codecs/tier1-json-codec.js.map +1 -0
  33. package/dist/core/codecs/tier2-msgpack-codec.d.ts +10 -0
  34. package/dist/core/codecs/tier2-msgpack-codec.d.ts.map +1 -0
  35. package/{src/core/codecs/tier2-msgpack-codec.ts → dist/core/codecs/tier2-msgpack-codec.js} +10 -14
  36. package/dist/core/codecs/tier2-msgpack-codec.js.map +1 -0
  37. package/dist/core/crypto-provider.d.ts +31 -0
  38. package/dist/core/crypto-provider.d.ts.map +1 -0
  39. package/dist/core/crypto-provider.js +10 -0
  40. package/dist/core/crypto-provider.js.map +1 -0
  41. package/dist/core/exceptions.d.ts +27 -0
  42. package/dist/core/exceptions.d.ts.map +1 -0
  43. package/dist/core/exceptions.js +52 -0
  44. package/dist/core/exceptions.js.map +1 -0
  45. package/dist/core/frame-header.d.ts +87 -0
  46. package/dist/core/frame-header.d.ts.map +1 -0
  47. package/dist/core/frame-header.js +185 -0
  48. package/dist/core/frame-header.js.map +1 -0
  49. package/dist/core/frame-registry.d.ts +35 -0
  50. package/dist/core/frame-registry.d.ts.map +1 -0
  51. package/dist/core/frame-registry.js +63 -0
  52. package/dist/core/frame-registry.js.map +1 -0
  53. package/dist/core/frames.d.ts +82 -0
  54. package/dist/core/frames.d.ts.map +1 -0
  55. package/dist/core/frames.js +155 -0
  56. package/dist/core/frames.js.map +1 -0
  57. package/dist/core/index.d.ts +11 -0
  58. package/dist/core/index.d.ts.map +1 -0
  59. package/{src/core/index.ts → dist/core/index.js} +3 -23
  60. package/dist/core/index.js.map +1 -0
  61. package/dist/core/registry.d.ts +11 -0
  62. package/dist/core/registry.d.ts.map +1 -0
  63. package/dist/core/registry.js +17 -0
  64. package/dist/core/registry.js.map +1 -0
  65. package/dist/core/status-codes.d.ts +29 -0
  66. package/dist/core/status-codes.d.ts.map +1 -0
  67. package/dist/core/status-codes.js +39 -0
  68. package/dist/core/status-codes.js.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/{src/index.ts → dist/index.js} +1 -1
  72. package/dist/index.js.map +1 -0
  73. package/dist/ncp/frames/anchor-frame.d.ts +29 -0
  74. package/dist/ncp/frames/anchor-frame.d.ts.map +1 -0
  75. package/dist/ncp/frames/anchor-frame.js +54 -0
  76. package/dist/ncp/frames/anchor-frame.js.map +1 -0
  77. package/dist/ncp/frames/caps-frame.d.ts +29 -0
  78. package/dist/ncp/frames/caps-frame.d.ts.map +1 -0
  79. package/dist/ncp/frames/caps-frame.js +29 -0
  80. package/dist/ncp/frames/caps-frame.js.map +1 -0
  81. package/dist/ncp/frames/diff-frame.d.ts +32 -0
  82. package/dist/ncp/frames/diff-frame.d.ts.map +1 -0
  83. package/dist/ncp/frames/diff-frame.js +37 -0
  84. package/dist/ncp/frames/diff-frame.js.map +1 -0
  85. package/dist/ncp/frames/error-frame.d.ts +16 -0
  86. package/dist/ncp/frames/error-frame.d.ts.map +1 -0
  87. package/dist/ncp/frames/error-frame.js +13 -0
  88. package/dist/ncp/frames/error-frame.js.map +1 -0
  89. package/dist/ncp/frames/hello-frame.d.ts +21 -0
  90. package/dist/ncp/frames/hello-frame.d.ts.map +1 -0
  91. package/dist/ncp/frames/hello-frame.js +25 -0
  92. package/dist/ncp/frames/hello-frame.js.map +1 -0
  93. package/dist/ncp/frames/stream-frame.d.ts +16 -0
  94. package/dist/ncp/frames/stream-frame.d.ts.map +1 -0
  95. package/dist/ncp/frames/stream-frame.js +18 -0
  96. package/dist/ncp/frames/stream-frame.js.map +1 -0
  97. package/dist/ncp/frames.d.ts +94 -0
  98. package/dist/ncp/frames.d.ts.map +1 -0
  99. package/dist/ncp/frames.js +192 -0
  100. package/dist/ncp/frames.js.map +1 -0
  101. package/dist/ncp/handshake.d.ts +30 -0
  102. package/dist/ncp/handshake.d.ts.map +1 -0
  103. package/dist/ncp/handshake.js +80 -0
  104. package/dist/ncp/handshake.js.map +1 -0
  105. package/dist/ncp/index.d.ts +12 -0
  106. package/dist/ncp/index.d.ts.map +1 -0
  107. package/{src/ncp/index.ts → dist/ncp/index.js} +1 -0
  108. package/dist/ncp/index.js.map +1 -0
  109. package/dist/ncp/ncp-error-codes.d.ts +23 -0
  110. package/dist/ncp/ncp-error-codes.d.ts.map +1 -0
  111. package/dist/ncp/ncp-error-codes.js +34 -0
  112. package/dist/ncp/ncp-error-codes.js.map +1 -0
  113. package/dist/ncp/ncp-patch-format.d.ts +7 -0
  114. package/dist/ncp/ncp-patch-format.d.ts.map +1 -0
  115. package/dist/ncp/ncp-patch-format.js +13 -0
  116. package/dist/ncp/ncp-patch-format.js.map +1 -0
  117. package/dist/ncp/preamble.d.ts +47 -0
  118. package/dist/ncp/preamble.d.ts.map +1 -0
  119. package/dist/ncp/preamble.js +74 -0
  120. package/dist/ncp/preamble.js.map +1 -0
  121. package/dist/ncp/registry.d.ts +3 -0
  122. package/dist/ncp/registry.d.ts.map +1 -0
  123. package/dist/ncp/registry.js +13 -0
  124. package/dist/ncp/registry.js.map +1 -0
  125. package/dist/ncp/stream-manager.d.ts +57 -0
  126. package/dist/ncp/stream-manager.d.ts.map +1 -0
  127. package/dist/ncp/stream-manager.js +163 -0
  128. package/dist/ncp/stream-manager.js.map +1 -0
  129. package/dist/ndp/dns-txt.d.ts +35 -0
  130. package/dist/ndp/dns-txt.d.ts.map +1 -0
  131. package/dist/ndp/dns-txt.js +67 -0
  132. package/dist/ndp/dns-txt.js.map +1 -0
  133. package/dist/ndp/frames.d.ts +56 -0
  134. package/dist/ndp/frames.d.ts.map +1 -0
  135. package/dist/ndp/frames.js +87 -0
  136. package/dist/ndp/frames.js.map +1 -0
  137. package/dist/ndp/index.d.ts +6 -0
  138. package/dist/ndp/index.d.ts.map +1 -0
  139. package/{src/ndp/index.ts → dist/ndp/index.js} +1 -1
  140. package/dist/ndp/index.js.map +1 -0
  141. package/dist/ndp/ndp-registry.d.ts +13 -0
  142. package/dist/ndp/ndp-registry.d.ts.map +1 -0
  143. package/dist/ndp/ndp-registry.js +104 -0
  144. package/dist/ndp/ndp-registry.js.map +1 -0
  145. package/dist/ndp/registry.d.ts +3 -0
  146. package/dist/ndp/registry.d.ts.map +1 -0
  147. package/dist/ndp/registry.js +10 -0
  148. package/dist/ndp/registry.js.map +1 -0
  149. package/dist/ndp/validator.d.ts +18 -0
  150. package/dist/ndp/validator.d.ts.map +1 -0
  151. package/dist/ndp/validator.js +48 -0
  152. package/dist/ndp/validator.js.map +1 -0
  153. package/dist/nip/acme/client.d.ts +31 -0
  154. package/dist/nip/acme/client.d.ts.map +1 -0
  155. package/dist/nip/acme/client.js +136 -0
  156. package/dist/nip/acme/client.js.map +1 -0
  157. package/dist/nip/acme/index.d.ts +6 -0
  158. package/dist/nip/acme/index.d.ts.map +1 -0
  159. package/{src/nip/acme/index.ts → dist/nip/acme/index.js} +1 -1
  160. package/dist/nip/acme/index.js.map +1 -0
  161. package/dist/nip/acme/jws.d.ts +31 -0
  162. package/dist/nip/acme/jws.d.ts.map +1 -0
  163. package/dist/nip/acme/jws.js +76 -0
  164. package/dist/nip/acme/jws.js.map +1 -0
  165. package/dist/nip/acme/messages.d.ts +71 -0
  166. package/dist/nip/acme/messages.d.ts.map +1 -0
  167. package/dist/nip/acme/messages.js +4 -0
  168. package/dist/nip/acme/messages.js.map +1 -0
  169. package/dist/nip/acme/server.d.ts +41 -0
  170. package/dist/nip/acme/server.d.ts.map +1 -0
  171. package/dist/nip/acme/server.js +458 -0
  172. package/dist/nip/acme/server.js.map +1 -0
  173. package/dist/nip/acme/wire.d.ts +19 -0
  174. package/dist/nip/acme/wire.d.ts.map +1 -0
  175. package/dist/nip/acme/wire.js +21 -0
  176. package/dist/nip/acme/wire.js.map +1 -0
  177. package/dist/nip/assurance-level.d.ts +19 -0
  178. package/dist/nip/assurance-level.d.ts.map +1 -0
  179. package/dist/nip/assurance-level.js +38 -0
  180. package/dist/nip/assurance-level.js.map +1 -0
  181. package/dist/nip/cert-format.d.ts +5 -0
  182. package/dist/nip/cert-format.d.ts.map +1 -0
  183. package/dist/nip/cert-format.js +6 -0
  184. package/dist/nip/cert-format.js.map +1 -0
  185. package/dist/nip/error-codes.d.ts +25 -0
  186. package/dist/nip/error-codes.d.ts.map +1 -0
  187. package/{src/nip/error-codes.ts → dist/nip/error-codes.js} +19 -25
  188. package/dist/nip/error-codes.js.map +1 -0
  189. package/dist/nip/frames.d.ts +53 -0
  190. package/dist/nip/frames.d.ts.map +1 -0
  191. package/dist/nip/frames.js +106 -0
  192. package/dist/nip/frames.js.map +1 -0
  193. package/dist/nip/identity.d.ts +18 -0
  194. package/dist/nip/identity.d.ts.map +1 -0
  195. package/dist/nip/identity.js +94 -0
  196. package/dist/nip/identity.js.map +1 -0
  197. package/dist/nip/index.d.ts +11 -0
  198. package/dist/nip/index.d.ts.map +1 -0
  199. package/{src/nip/index.ts → dist/nip/index.js} +3 -2
  200. package/dist/nip/index.js.map +1 -0
  201. package/dist/nip/registry.d.ts +3 -0
  202. package/dist/nip/registry.d.ts.map +1 -0
  203. package/dist/nip/registry.js +10 -0
  204. package/dist/nip/registry.js.map +1 -0
  205. package/dist/nip/reputation-client.d.ts +116 -0
  206. package/dist/nip/reputation-client.d.ts.map +1 -0
  207. package/dist/nip/reputation-client.js +261 -0
  208. package/dist/nip/reputation-client.js.map +1 -0
  209. package/dist/nip/verifier.d.ts +23 -0
  210. package/dist/nip/verifier.d.ts.map +1 -0
  211. package/dist/nip/verifier.js +90 -0
  212. package/dist/nip/verifier.js.map +1 -0
  213. package/dist/nip/x509/builder.d.ts +35 -0
  214. package/dist/nip/x509/builder.d.ts.map +1 -0
  215. package/dist/nip/x509/builder.js +59 -0
  216. package/dist/nip/x509/builder.js.map +1 -0
  217. package/dist/nip/x509/index.d.ts +4 -0
  218. package/dist/nip/x509/index.d.ts.map +1 -0
  219. package/{src/nip/x509/index.ts → dist/nip/x509/index.js} +1 -1
  220. package/dist/nip/x509/index.js.map +1 -0
  221. package/dist/nip/x509/oids.d.ts +16 -0
  222. package/dist/nip/x509/oids.d.ts.map +1 -0
  223. package/{src/nip/x509/oids.ts → dist/nip/x509/oids.js} +5 -10
  224. package/dist/nip/x509/oids.js.map +1 -0
  225. package/dist/nip/x509/verifier.d.ts +26 -0
  226. package/dist/nip/x509/verifier.d.ts.map +1 -0
  227. package/dist/nip/x509/verifier.js +171 -0
  228. package/dist/nip/x509/verifier.js.map +1 -0
  229. package/dist/nop/client.d.ts +34 -0
  230. package/dist/nop/client.d.ts.map +1 -0
  231. package/dist/nop/client.js +90 -0
  232. package/dist/nop/client.js.map +1 -0
  233. package/dist/nop/frames.d.ts +65 -0
  234. package/dist/nop/frames.d.ts.map +1 -0
  235. package/dist/nop/frames.js +148 -0
  236. package/dist/nop/frames.js.map +1 -0
  237. package/dist/nop/index.d.ts +5 -0
  238. package/dist/nop/index.d.ts.map +1 -0
  239. package/{src/nop/index.ts → dist/nop/index.js} +1 -1
  240. package/dist/nop/index.js.map +1 -0
  241. package/dist/nop/models.d.ts +58 -0
  242. package/dist/nop/models.d.ts.map +1 -0
  243. package/dist/nop/models.js +50 -0
  244. package/dist/nop/models.js.map +1 -0
  245. package/dist/nop/nop-types.d.ts +136 -0
  246. package/dist/nop/nop-types.d.ts.map +1 -0
  247. package/dist/nop/nop-types.js +44 -0
  248. package/dist/nop/nop-types.js.map +1 -0
  249. package/dist/nop/registry.d.ts +3 -0
  250. package/dist/nop/registry.d.ts.map +1 -0
  251. package/dist/nop/registry.js +11 -0
  252. package/dist/nop/registry.js.map +1 -0
  253. package/dist/nwp/anchor-client.d.ts +109 -0
  254. package/dist/nwp/anchor-client.d.ts.map +1 -0
  255. package/dist/nwp/anchor-client.js +279 -0
  256. package/dist/nwp/anchor-client.js.map +1 -0
  257. package/dist/nwp/client.d.ts +28 -0
  258. package/dist/nwp/client.d.ts.map +1 -0
  259. package/dist/nwp/client.js +142 -0
  260. package/dist/nwp/client.js.map +1 -0
  261. package/dist/nwp/frames.d.ts +107 -0
  262. package/dist/nwp/frames.d.ts.map +1 -0
  263. package/dist/nwp/frames.js +198 -0
  264. package/dist/nwp/frames.js.map +1 -0
  265. package/dist/nwp/index.d.ts +6 -0
  266. package/dist/nwp/index.d.ts.map +1 -0
  267. package/{src/nwp/index.ts → dist/nwp/index.js} +3 -1
  268. package/dist/nwp/index.js.map +1 -0
  269. package/dist/nwp/manifest.d.ts +69 -0
  270. package/dist/nwp/manifest.d.ts.map +1 -0
  271. package/dist/nwp/manifest.js +4 -0
  272. package/dist/nwp/manifest.js.map +1 -0
  273. package/dist/nwp/registry.d.ts +3 -0
  274. package/dist/nwp/registry.d.ts.map +1 -0
  275. package/dist/nwp/registry.js +10 -0
  276. package/dist/nwp/registry.js.map +1 -0
  277. package/dist/setup.d.ts +10 -0
  278. package/dist/setup.d.ts.map +1 -0
  279. package/{src/setup.ts → dist/setup.js} +13 -16
  280. package/dist/setup.js.map +1 -0
  281. package/package.json +12 -1
  282. package/CONTRIBUTING.cn.md +0 -35
  283. package/CONTRIBUTING.md +0 -35
  284. package/nip-ca-server/Dockerfile +0 -27
  285. package/nip-ca-server/README.md +0 -45
  286. package/nip-ca-server/db/001_init.sql +0 -25
  287. package/nip-ca-server/docker-compose.yml +0 -29
  288. package/nip-ca-server/package.json +0 -23
  289. package/nip-ca-server/src/ca.ts +0 -155
  290. package/nip-ca-server/src/db.ts +0 -104
  291. package/nip-ca-server/src/index.ts +0 -157
  292. package/nip-ca-server/tsconfig.json +0 -13
  293. package/src/core/anchor-cache.ts +0 -129
  294. package/src/core/cache.ts +0 -93
  295. package/src/core/canonical-json.ts +0 -50
  296. package/src/core/codec.ts +0 -158
  297. package/src/core/codecs/ncp-codec.ts +0 -170
  298. package/src/core/crypto-provider.ts +0 -47
  299. package/src/core/exceptions.ts +0 -57
  300. package/src/core/frame-header.ts +0 -282
  301. package/src/core/frame-registry.ts +0 -91
  302. package/src/core/frames.ts +0 -184
  303. package/src/core/registry.ts +0 -28
  304. package/src/core/status-codes.ts +0 -47
  305. package/src/ncp/frames/anchor-frame.ts +0 -87
  306. package/src/ncp/frames/caps-frame.ts +0 -59
  307. package/src/ncp/frames/diff-frame.ts +0 -69
  308. package/src/ncp/frames/error-frame.ts +0 -26
  309. package/src/ncp/frames/hello-frame.ts +0 -50
  310. package/src/ncp/frames/stream-frame.ts +0 -35
  311. package/src/ncp/frames.ts +0 -251
  312. package/src/ncp/handshake.ts +0 -95
  313. package/src/ncp/ncp-error-codes.ts +0 -36
  314. package/src/ncp/ncp-patch-format.ts +0 -16
  315. package/src/ncp/preamble.ts +0 -79
  316. package/src/ncp/registry.ts +0 -15
  317. package/src/ncp/stream-manager.ts +0 -212
  318. package/src/ndp/dns-txt.ts +0 -86
  319. package/src/ndp/frames.ts +0 -124
  320. package/src/ndp/ndp-registry.ts +0 -116
  321. package/src/ndp/registry.ts +0 -12
  322. package/src/ndp/validator.ts +0 -64
  323. package/src/nip/acme/client.ts +0 -185
  324. package/src/nip/acme/jws.ts +0 -109
  325. package/src/nip/acme/messages.ts +0 -85
  326. package/src/nip/acme/server.ts +0 -480
  327. package/src/nip/acme/wire.ts +0 -24
  328. package/src/nip/assurance-level.ts +0 -40
  329. package/src/nip/cert-format.ts +0 -9
  330. package/src/nip/frames.ts +0 -138
  331. package/src/nip/identity.ts +0 -113
  332. package/src/nip/registry.ts +0 -12
  333. package/src/nip/verifier.ts +0 -122
  334. package/src/nip/x509/builder.ts +0 -91
  335. package/src/nip/x509/verifier.ts +0 -214
  336. package/src/nop/client.ts +0 -103
  337. package/src/nop/frames.ts +0 -181
  338. package/src/nop/models.ts +0 -79
  339. package/src/nop/nop-types.ts +0 -208
  340. package/src/nop/registry.ts +0 -13
  341. package/src/nwp/client.ts +0 -114
  342. package/src/nwp/frames.ts +0 -116
  343. package/src/nwp/registry.ts +0 -11
  344. package/tests/_rfc0002-keys.ts +0 -57
  345. package/tests/core/anchor-cache.test.ts +0 -242
  346. package/tests/core/codec.test.ts +0 -205
  347. package/tests/core/frame-registry.test.ts +0 -46
  348. package/tests/core.test.ts +0 -327
  349. package/tests/ncp/diff-binary-bitset.test.ts +0 -107
  350. package/tests/ncp/e2e-enc-reject.test.ts +0 -93
  351. package/tests/ncp/err-error-frame.test.ts +0 -152
  352. package/tests/ncp/frames.test.ts +0 -359
  353. package/tests/ncp/framing.test.ts +0 -233
  354. package/tests/ncp/hello-frame.test.ts +0 -122
  355. package/tests/ncp/inline-anchor.test.ts +0 -88
  356. package/tests/ncp/preamble.test.ts +0 -93
  357. package/tests/ncp/security.test.ts +0 -184
  358. package/tests/ncp/stream-window.test.ts +0 -167
  359. package/tests/ncp/stream.test.ts +0 -242
  360. package/tests/ncp/version-negotiation.test.ts +0 -123
  361. package/tests/ndp.test.ts +0 -377
  362. package/tests/nip-acme-agent01.test.ts +0 -192
  363. package/tests/nip-x509.test.ts +0 -280
  364. package/tests/nip.test.ts +0 -184
  365. package/tests/nop.test.ts +0 -344
  366. package/tests/nwp.test.ts +0 -237
  367. package/tsconfig.json +0 -20
  368. package/tsup.config.ts +0 -20
  369. package/vitest.config.ts +0 -10
@@ -1,185 +0,0 @@
1
- // Copyright 2026 INNO LOTUS PTY LTD
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * ACME client implementing the `agent-01` challenge type per NPS-RFC-0002 §4.4.
6
- *
7
- * Flow: newNonce → newAccount → newOrder → fetch authz → sign challenge token →
8
- * finalize with CSR → fetch leaf cert.
9
- */
10
-
11
- import * as ed25519 from "@noble/ed25519";
12
- import { sha512 } from "@noble/hashes/sha512";
13
- import * as x509 from "@peculiar/x509";
14
-
15
- import * as Jws from "./jws.js";
16
- import type {
17
- Authorization, Challenge, Directory, FinalizePayload,
18
- Identifier, NewAccountPayload, NewOrderPayload, Order,
19
- } from "./messages.js";
20
- import * as wire from "./wire.js";
21
-
22
- ed25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));
23
- x509.cryptoProvider.set(globalThis.crypto);
24
-
25
- export interface AcmeClientOptions {
26
- /** ACME directory URL. */
27
- directoryUrl: string;
28
- /** Account/agent Ed25519 private key (32-byte raw). */
29
- privateKey: Uint8Array;
30
- /** Account/agent Ed25519 public key (32-byte raw). */
31
- publicKey: Uint8Array;
32
- /** Web Crypto Ed25519 keypair for CSR signing (must match privateKey). */
33
- webCryptoKeys: CryptoKeyPair;
34
- }
35
-
36
- export class AcmeClient {
37
- private directory: Directory | null = null;
38
- private accountUrl: string | null = null;
39
- private lastNonce: string | null = null;
40
-
41
- constructor(public readonly options: AcmeClientOptions) {}
42
-
43
- /** Drive the full agent-01 flow for `nid`. Returns issued PEM cert chain. */
44
- async issueAgentCert(nid: string): Promise<string> {
45
- await this.ensureDirectory();
46
- if (this.accountUrl === null) await this.newAccount();
47
- const order = await this.newOrder(nid);
48
- const authz = await this.fetchAuthz(order.authorizations[0]);
49
- await this.respondAgent01(authz);
50
- const finalized = await this.finalizeOrder(order, nid);
51
- return this.downloadPem(finalized.certificate!);
52
- }
53
-
54
- // ── Stages ───────────────────────────────────────────────────────────────
55
-
56
- private async ensureDirectory(): Promise<void> {
57
- if (this.directory !== null) return;
58
- const resp = await fetch(this.options.directoryUrl);
59
- ensureSuccess(resp);
60
- this.directory = await resp.json() as Directory;
61
- await this.refreshNonce();
62
- }
63
-
64
- private async refreshNonce(): Promise<void> {
65
- const resp = await fetch(this.directory!.newNonce, { method: "HEAD" });
66
- ensureSuccess(resp);
67
- this.lastNonce = resp.headers.get("Replay-Nonce");
68
- if (this.lastNonce === null) {
69
- throw new Error("server omitted Replay-Nonce");
70
- }
71
- }
72
-
73
- private async newAccount(): Promise<void> {
74
- const jwk = Jws.jwkFromPublicKey(this.options.publicKey);
75
- const env = Jws.sign(
76
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url: this.directory!.newAccount, jwk },
77
- { termsOfServiceAgreed: true } as NewAccountPayload,
78
- this.options.privateKey);
79
-
80
- const resp = await this.post(this.directory!.newAccount, env);
81
- ensureSuccess(resp);
82
- this.accountUrl = resp.headers.get("Location");
83
- if (this.accountUrl === null) throw new Error("server omitted account Location");
84
- this.captureNonce(resp);
85
- }
86
-
87
- private async newOrder(nid: string): Promise<Order> {
88
- const env = Jws.sign(
89
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url: this.directory!.newOrder, kid: this.accountUrl! },
90
- {
91
- identifiers: [{ type: wire.IDENTIFIER_TYPE_NID, value: nid } as Identifier],
92
- } as NewOrderPayload,
93
- this.options.privateKey);
94
-
95
- const resp = await this.post(this.directory!.newOrder, env);
96
- ensureSuccess(resp);
97
- this.captureNonce(resp);
98
- return await resp.json() as Order;
99
- }
100
-
101
- private async fetchAuthz(url: string): Promise<Authorization> {
102
- // POST-as-GET (RFC 8555 §6.3).
103
- const env = Jws.sign(
104
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url, kid: this.accountUrl! },
105
- null,
106
- this.options.privateKey);
107
- const resp = await this.post(url, env);
108
- ensureSuccess(resp);
109
- this.captureNonce(resp);
110
- return await resp.json() as Authorization;
111
- }
112
-
113
- private async respondAgent01(authz: Authorization): Promise<void> {
114
- const challenge = authz.challenges.find((c) => c.type === wire.CHALLENGE_AGENT_01);
115
- if (!challenge) throw new Error("authz has no agent-01 challenge");
116
-
117
- // Sign the challenge token with the account/NID private key.
118
- const tokenBytes = new TextEncoder().encode(challenge.token);
119
- const sig = ed25519.sign(tokenBytes, this.options.privateKey);
120
-
121
- const env = Jws.sign(
122
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url: challenge.url, kid: this.accountUrl! },
123
- { agent_signature: Jws.b64uEncode(sig) },
124
- this.options.privateKey);
125
- const resp = await this.post(challenge.url, env);
126
- ensureSuccess(resp);
127
- this.captureNonce(resp);
128
- }
129
-
130
- private async finalizeOrder(order: Order, nid: string): Promise<Order> {
131
- const csrDer = await this.buildCsr(nid);
132
- const env = Jws.sign(
133
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url: order.finalize, kid: this.accountUrl! },
134
- { csr: Jws.b64uEncode(csrDer) } as FinalizePayload,
135
- this.options.privateKey);
136
- const resp = await this.post(order.finalize, env);
137
- ensureSuccess(resp);
138
- this.captureNonce(resp);
139
- return await resp.json() as Order;
140
- }
141
-
142
- private async downloadPem(certUrl: string): Promise<string> {
143
- const env = Jws.sign(
144
- { alg: Jws.ALG_EDDSA, nonce: this.lastNonce!, url: certUrl, kid: this.accountUrl! },
145
- null,
146
- this.options.privateKey);
147
- const resp = await this.post(certUrl, env);
148
- ensureSuccess(resp);
149
- this.captureNonce(resp);
150
- return await resp.text();
151
- }
152
-
153
- // ── helpers ──────────────────────────────────────────────────────────────
154
-
155
- private async post(url: string, env: Jws.Envelope): Promise<Response> {
156
- return await fetch(url, {
157
- method: "POST",
158
- headers: { "Content-Type": wire.CONTENT_TYPE_JOSE_JSON },
159
- body: JSON.stringify(env),
160
- });
161
- }
162
-
163
- private captureNonce(resp: Response): void {
164
- const nonce = resp.headers.get("Replay-Nonce");
165
- if (nonce !== null) this.lastNonce = nonce;
166
- }
167
-
168
- private async buildCsr(nid: string): Promise<Uint8Array> {
169
- const csr = await x509.Pkcs10CertificateRequestGenerator.create({
170
- name: `CN=${nid.replace(/([",+;<>\\])/g, "\\$1")}`,
171
- keys: this.options.webCryptoKeys,
172
- signingAlgorithm: { name: "Ed25519" },
173
- extensions: [
174
- new x509.SubjectAlternativeNameExtension([{ type: "url", value: nid }], false),
175
- ],
176
- });
177
- return new Uint8Array(csr.rawData);
178
- }
179
- }
180
-
181
- function ensureSuccess(resp: Response): void {
182
- if (!resp.ok) {
183
- throw new Error(`ACME ${resp.url} HTTP ${resp.status}`);
184
- }
185
- }
@@ -1,109 +0,0 @@
1
- // Copyright 2026 INNO LOTUS PTY LTD
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * JWS signing helpers for ACME with Ed25519 (`alg: "EdDSA"` per RFC 8037).
6
- *
7
- * Wire shape (RFC 8555 §6.2 + RFC 7515 flattened JWS JSON serialization):
8
- * {
9
- * "protected": base64url(JSON({alg, nonce, url, [jwk|kid]})),
10
- * "payload": base64url(JSON(payload)),
11
- * "signature": base64url(Ed25519(protected || "." || payload))
12
- * }
13
- */
14
-
15
- import * as ed25519 from "@noble/ed25519";
16
- import { sha512 } from "@noble/hashes/sha512";
17
- import { sha256 } from "@noble/hashes/sha2";
18
-
19
- ed25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));
20
-
21
- export const ALG_EDDSA = "EdDSA"; // RFC 8037 §3.1
22
- export const KTY_OKP = "OKP"; // RFC 8037 §2
23
- export const CRV_ED25519 = "Ed25519"; // RFC 8037 §2
24
-
25
- export interface Jwk {
26
- kty: string;
27
- crv: string;
28
- x: string;
29
- }
30
-
31
- export interface ProtectedHeader {
32
- alg: string;
33
- nonce: string;
34
- url: string;
35
- jwk?: Jwk;
36
- kid?: string;
37
- }
38
-
39
- export interface Envelope {
40
- protected: string;
41
- payload: string;
42
- signature: string;
43
- }
44
-
45
- export function jwkFromPublicKey(rawPubKey: Uint8Array): Jwk {
46
- if (rawPubKey.length !== 32) {
47
- throw new Error(`Ed25519 public key must be 32 bytes, got ${rawPubKey.length}`);
48
- }
49
- return { kty: KTY_OKP, crv: CRV_ED25519, x: b64uEncode(rawPubKey) };
50
- }
51
-
52
- export function publicKeyFromJwk(jwk: Jwk): Uint8Array {
53
- if (jwk.kty !== KTY_OKP || jwk.crv !== CRV_ED25519) {
54
- throw new Error(`JWK is not OKP/Ed25519: kty=${jwk.kty} crv=${jwk.crv}`);
55
- }
56
- return b64uDecode(jwk.x);
57
- }
58
-
59
- /** RFC 7638 §3 thumbprint of an Ed25519 JWK (lex-sorted compact JSON, SHA-256, base64url). */
60
- export function thumbprint(jwk: Jwk): string {
61
- const canonical = `{"crv":"${jwk.crv}","kty":"${jwk.kty}","x":"${jwk.x}"}`;
62
- return b64uEncode(sha256(new TextEncoder().encode(canonical)));
63
- }
64
-
65
- export function sign(
66
- header: ProtectedHeader,
67
- payload: unknown | null,
68
- privKey: Uint8Array,
69
- ): Envelope {
70
- const headerBytes = new TextEncoder().encode(JSON.stringify(header));
71
- const headerB64u = b64uEncode(headerBytes);
72
- const payloadB64u = payload === null
73
- ? ""
74
- : b64uEncode(new TextEncoder().encode(JSON.stringify(payload)));
75
- const signingInput = new TextEncoder().encode(`${headerB64u}.${payloadB64u}`);
76
- const sig = ed25519.sign(signingInput, privKey);
77
- return { protected: headerB64u, payload: payloadB64u, signature: b64uEncode(sig) };
78
- }
79
-
80
- /** Verify a JWS envelope. Returns the parsed protected header on success, else null. */
81
- export function verify(envelope: Envelope, pubKey: Uint8Array): ProtectedHeader | null {
82
- try {
83
- const signingInput = new TextEncoder().encode(`${envelope.protected}.${envelope.payload}`);
84
- const sigBytes = b64uDecode(envelope.signature);
85
- if (!ed25519.verify(sigBytes, signingInput, pubKey)) return null;
86
- const headerJson = new TextDecoder().decode(b64uDecode(envelope.protected));
87
- return JSON.parse(headerJson) as ProtectedHeader;
88
- } catch {
89
- return null;
90
- }
91
- }
92
-
93
- export function decodePayload<T = unknown>(envelope: Envelope): T | null {
94
- if (!envelope.payload) return null;
95
- return JSON.parse(new TextDecoder().decode(b64uDecode(envelope.payload))) as T;
96
- }
97
-
98
- // ── helpers ──────────────────────────────────────────────────────────────────
99
-
100
- export function b64uEncode(bytes: Uint8Array): string {
101
- return Buffer.from(bytes).toString("base64").replace(/=+$/, "")
102
- .replace(/\+/g, "-").replace(/\//g, "_");
103
- }
104
-
105
- export function b64uDecode(s: string): Uint8Array {
106
- const padded = s + "=".repeat((4 - (s.length % 4)) % 4);
107
- const std = padded.replace(/-/g, "+").replace(/_/g, "/");
108
- return new Uint8Array(Buffer.from(std, "base64"));
109
- }
@@ -1,85 +0,0 @@
1
- // Copyright 2026 INNO LOTUS PTY LTD
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /** ACME wire-level DTOs (RFC 8555 + NPS-RFC-0002 §4.4) — plain interfaces. */
5
-
6
- export interface DirectoryMeta {
7
- termsOfService?: string;
8
- website?: string;
9
- caaIdentities?: readonly string[];
10
- externalAccountRequired?: boolean;
11
- }
12
-
13
- export interface Directory {
14
- newNonce: string;
15
- newAccount: string;
16
- newOrder: string;
17
- revokeCert?: string;
18
- keyChange?: string;
19
- meta?: DirectoryMeta;
20
- }
21
-
22
- export interface NewAccountPayload {
23
- termsOfServiceAgreed?: boolean;
24
- contact?: readonly string[];
25
- onlyReturnExisting?: boolean;
26
- }
27
-
28
- export interface Account {
29
- status: string;
30
- contact?: readonly string[];
31
- orders?: string;
32
- }
33
-
34
- export interface Identifier {
35
- type: string; // "nid" per NPS-RFC-0002 §4.4
36
- value: string;
37
- }
38
-
39
- export interface NewOrderPayload {
40
- identifiers: readonly Identifier[];
41
- notBefore?: string;
42
- notAfter?: string;
43
- }
44
-
45
- export interface ProblemDetail {
46
- type: string;
47
- detail?: string;
48
- status?: number;
49
- }
50
-
51
- export interface Order {
52
- status: string;
53
- expires?: string;
54
- identifiers: readonly Identifier[];
55
- authorizations: readonly string[];
56
- finalize: string;
57
- certificate?: string;
58
- error?: ProblemDetail;
59
- }
60
-
61
- export interface Challenge {
62
- type: string; // "agent-01" per NPS-RFC-0002 §4.4
63
- url: string;
64
- status: string;
65
- token: string;
66
- validated?: string;
67
- error?: ProblemDetail;
68
- }
69
-
70
- export interface Authorization {
71
- status: string;
72
- expires?: string;
73
- identifier: Identifier;
74
- challenges: readonly Challenge[];
75
- }
76
-
77
- export interface ChallengeRespondPayload {
78
- /** base64url(Ed25519(token)) per NPS-RFC-0002 §4.4. */
79
- agent_signature: string;
80
- }
81
-
82
- export interface FinalizePayload {
83
- /** base64url(CSR DER). */
84
- csr: string;
85
- }