space-data-module-sdk 0.8.4 → 0.8.5

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 (354) hide show
  1. package/README.md +117 -20
  2. package/bin/space-data-module.js +263 -0
  3. package/docs/.nojekyll +1 -0
  4. package/docs/AGENTS.md +34 -0
  5. package/docs/architecture.svg +141 -0
  6. package/docs/browser-wasmedge-isomorphic.md +179 -0
  7. package/docs/flatsql-streaming-standard.md +341 -0
  8. package/docs/gpu-module-abi.md +193 -0
  9. package/docs/index.html +125 -0
  10. package/docs/isomorphic-pthreads.md +188 -0
  11. package/docs/isomorphic-sdn-runtime-plan.md +167 -0
  12. package/docs/language-runtime-matrix.md +82 -0
  13. package/docs/manifest-structure.svg +114 -0
  14. package/docs/module-bundle-runtime-plan.md +19 -0
  15. package/docs/module-lifecycle.svg +70 -0
  16. package/docs/module-publication-standard.md +540 -0
  17. package/docs/node-red-default-node-parity.md +88 -0
  18. package/docs/protocol-installation.md +196 -0
  19. package/docs/secrets-capability.md +152 -0
  20. package/docs/styles.css +288 -0
  21. package/docs/testing-harness.md +408 -0
  22. package/docs/tri-runtime-parity.md +132 -0
  23. package/docs/wallet-callback.html +2 -0
  24. package/package.json +25 -6
  25. package/schemas/HttpRequestAbi.fbs +41 -0
  26. package/schemas/HttpResponseAbi.fbs +36 -0
  27. package/schemas/PluginManifest.fbs +2 -1
  28. package/src/AGENTS.md +1 -1
  29. package/src/app/codec.js +548 -0
  30. package/src/app/index.js +6 -0
  31. package/src/browser.js +5 -0
  32. package/src/bundle/constants.js +1 -0
  33. package/src/bundle/index.js +15 -0
  34. package/src/bundle/sigdomain.js +179 -0
  35. package/src/bundle/signing.js +767 -0
  36. package/src/bundle/wasm.js +3 -2
  37. package/src/capabilities.js +3 -0
  38. package/src/compat/index.js +7 -0
  39. package/src/compat/sdnLegacy.js +449 -0
  40. package/src/compiler/compileModule.js +556 -55
  41. package/src/compiler/flatcSupport.js +41 -27
  42. package/src/compiler/index.d.ts +2 -0
  43. package/src/compiler/index.js +18 -0
  44. package/src/compiler/invokeGlue.js +1212 -183
  45. package/src/compiler/pthreadArtifactGuard.js +910 -0
  46. package/src/compiler/sdnShimGenerator.js +323 -0
  47. package/src/compiler/wasiThreadsToolchain.js +150 -0
  48. package/src/compliance/index.js +11 -1
  49. package/src/compliance/legacyWildcardPorts.js +228 -0
  50. package/src/compliance/pluginCompliance.js +1000 -96
  51. package/src/field-stream/index.d.ts +31 -0
  52. package/src/field-stream/index.js +119 -0
  53. package/src/flow/dependencyStreamBridge.js +234 -0
  54. package/src/flow/flatsqlLinkShim.js +304 -0
  55. package/src/flow/flowCodec.js +107 -0
  56. package/src/flow/flowCompiler.js +2900 -0
  57. package/src/flow/flowRuntimeHost.js +877 -0
  58. package/src/flow/index.d.ts +117 -0
  59. package/src/flow/index.js +31 -0
  60. package/src/flow/isomorphicFlowHost.js +384 -0
  61. package/src/flow/jsFlowRuntime.js +275 -0
  62. package/src/flow/normalize.js +294 -0
  63. package/src/flow/runtime-src/flow_runtime.cpp +1699 -0
  64. package/src/flow/vendor/sdn-flow/MethodRegistry.js +400 -0
  65. package/src/flow/vendor/sdn-flow/constants.js +39 -0
  66. package/src/flow/vendor/sdn-flow/index.js +29 -0
  67. package/src/flow/vendor/sdn-flow/normalize.js +506 -0
  68. package/src/flow/vendor/sdn-flow/wasmCompatibility.js +189 -0
  69. package/src/generated/http/cpp/HttpRequestAbi_generated.h +285 -0
  70. package/src/generated/http/cpp/HttpResponseAbi_generated.h +192 -0
  71. package/src/generated/http/sdn/http/http-header.js +53 -0
  72. package/src/generated/http/sdn/http/http-header.ts +67 -0
  73. package/src/generated/http/sdn/http/http-request.js +132 -0
  74. package/src/generated/http/sdn/http/http-request.ts +179 -0
  75. package/src/generated/http/sdn/http/http-response.js +144 -0
  76. package/src/generated/http/sdn/http/http-response.ts +168 -0
  77. package/src/generated/http/sdn/http.js +11 -0
  78. package/src/generated/http/sdn/http.ts +4 -0
  79. package/src/generated/orbpro/flow/backpressure-policy.d.ts +12 -0
  80. package/src/generated/orbpro/flow/backpressure-policy.d.ts.map +1 -0
  81. package/src/generated/orbpro/flow/backpressure-policy.js +17 -0
  82. package/src/generated/orbpro/flow/backpressure-policy.js.map +1 -0
  83. package/src/generated/orbpro/flow/backpressure-policy.ts +15 -0
  84. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts +142 -0
  85. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts.map +1 -0
  86. package/src/generated/orbpro/flow/flow-bundle-manifest.js +304 -0
  87. package/src/generated/orbpro/flow/flow-bundle-manifest.js.map +1 -0
  88. package/src/generated/orbpro/flow/flow-bundle-manifest.ts +399 -0
  89. package/src/generated/orbpro/flow/flow-edge.d.ts +113 -0
  90. package/src/generated/orbpro/flow/flow-edge.d.ts.map +1 -0
  91. package/src/generated/orbpro/flow/flow-edge.js +221 -0
  92. package/src/generated/orbpro/flow/flow-edge.js.map +1 -0
  93. package/src/generated/orbpro/flow/flow-edge.ts +292 -0
  94. package/src/generated/orbpro/flow/flow-node.d.ts +80 -0
  95. package/src/generated/orbpro/flow/flow-node.d.ts.map +1 -0
  96. package/src/generated/orbpro/flow/flow-node.js +158 -0
  97. package/src/generated/orbpro/flow/flow-node.js.map +1 -0
  98. package/src/generated/orbpro/flow/flow-node.ts +202 -0
  99. package/src/generated/orbpro/flow/flow-program.d.ts +164 -0
  100. package/src/generated/orbpro/flow/flow-program.d.ts.map +1 -0
  101. package/src/generated/orbpro/flow/flow-program.js +350 -0
  102. package/src/generated/orbpro/flow/flow-program.js.map +1 -0
  103. package/src/generated/orbpro/flow/flow-program.ts +477 -0
  104. package/src/generated/orbpro/flow/flow-trigger.d.ts +108 -0
  105. package/src/generated/orbpro/flow/flow-trigger.d.ts.map +1 -0
  106. package/src/generated/orbpro/flow/flow-trigger.js +207 -0
  107. package/src/generated/orbpro/flow/flow-trigger.js.map +1 -0
  108. package/src/generated/orbpro/flow/flow-trigger.ts +276 -0
  109. package/src/generated/orbpro/flow/node-kind.d.ts +13 -0
  110. package/src/generated/orbpro/flow/node-kind.d.ts.map +1 -0
  111. package/src/generated/orbpro/flow/node-kind.js +16 -0
  112. package/src/generated/orbpro/flow/node-kind.js.map +1 -0
  113. package/src/generated/orbpro/{invoke.ts → flow/node-kind.ts} +12 -2
  114. package/src/generated/orbpro/flow/plugin-version-binding.d.ts +52 -0
  115. package/src/generated/orbpro/flow/plugin-version-binding.d.ts.map +1 -0
  116. package/src/generated/orbpro/flow/plugin-version-binding.js +85 -0
  117. package/src/generated/orbpro/flow/plugin-version-binding.js.map +1 -0
  118. package/src/generated/orbpro/flow/plugin-version-binding.ts +121 -0
  119. package/src/generated/orbpro/flow/schema-hash-binding.d.ts +70 -0
  120. package/src/generated/orbpro/flow/schema-hash-binding.d.ts.map +1 -0
  121. package/src/generated/orbpro/flow/schema-hash-binding.js +143 -0
  122. package/src/generated/orbpro/flow/schema-hash-binding.js.map +1 -0
  123. package/src/generated/orbpro/flow/schema-hash-binding.ts +189 -0
  124. package/src/generated/orbpro/flow/trigger-binding.d.ts +71 -0
  125. package/src/generated/orbpro/flow/trigger-binding.d.ts.map +1 -0
  126. package/src/generated/orbpro/flow/trigger-binding.js +142 -0
  127. package/src/generated/orbpro/flow/trigger-binding.js.map +1 -0
  128. package/src/generated/orbpro/flow/trigger-binding.ts +181 -0
  129. package/src/generated/orbpro/flow/trigger-kind.d.ts +14 -0
  130. package/src/generated/orbpro/flow/trigger-kind.d.ts.map +1 -0
  131. package/src/generated/orbpro/flow/trigger-kind.js +17 -0
  132. package/src/generated/orbpro/flow/trigger-kind.js.map +1 -0
  133. package/src/generated/orbpro/flow/trigger-kind.ts +17 -0
  134. package/src/generated/orbpro/flow.d.ts +21 -0
  135. package/src/generated/orbpro/flow.d.ts.map +1 -0
  136. package/src/generated/orbpro/flow.js +23 -0
  137. package/src/generated/orbpro/flow.js.map +1 -0
  138. package/src/generated/orbpro/flow.ts +24 -0
  139. package/src/generated/orbpro/manifest/capability-kind.d.ts +2 -1
  140. package/src/generated/orbpro/manifest/capability-kind.js +1 -0
  141. package/src/generated/orbpro/manifest/capability-kind.ts +1 -0
  142. package/src/generated/orbpro/plugin/stream-invoke-request.d.ts +93 -0
  143. package/src/generated/orbpro/plugin/stream-invoke-request.js +160 -0
  144. package/src/generated/orbpro/plugin/stream-invoke-request.ts +211 -0
  145. package/src/generated/orbpro/plugin/stream-invoke-response.d.ts +99 -0
  146. package/src/generated/orbpro/plugin/stream-invoke-response.js +175 -0
  147. package/src/generated/orbpro/plugin/stream-invoke-response.ts +226 -0
  148. package/src/generated/orbpro/plugin.js +8 -0
  149. package/src/generated/orbpro/stream.d.ts +12 -0
  150. package/src/generated/orbpro/stream.js +14 -0
  151. package/src/generated/orbpro/stream.ts +15 -0
  152. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts +52 -0
  153. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts.map +1 -0
  154. package/src/generated/spacedatastandards/plg/EntryFunction.js +106 -0
  155. package/src/generated/spacedatastandards/plg/EntryFunction.ts +162 -0
  156. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts +90 -0
  157. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts.map +1 -0
  158. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.js +189 -0
  159. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.ts +270 -0
  160. package/src/generated/spacedatastandards/plg/PLG.d.ts +492 -0
  161. package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -0
  162. package/src/generated/spacedatastandards/plg/PLG.js +1139 -0
  163. package/src/generated/spacedatastandards/plg/PLG.ts +1600 -0
  164. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts +63 -0
  165. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts.map +1 -0
  166. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.js +138 -0
  167. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.ts +189 -0
  168. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts +41 -0
  169. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts.map +1 -0
  170. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.js +104 -0
  171. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.ts +151 -0
  172. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts +68 -0
  173. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts.map +1 -0
  174. package/src/generated/spacedatastandards/plg/PLGFlowEdge.js +124 -0
  175. package/src/generated/spacedatastandards/plg/PLGFlowEdge.ts +184 -0
  176. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts +58 -0
  177. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts.map +1 -0
  178. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.js +126 -0
  179. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.ts +161 -0
  180. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts +82 -0
  181. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts.map +1 -0
  182. package/src/generated/spacedatastandards/plg/PLGFlowNode.js +164 -0
  183. package/src/generated/spacedatastandards/plg/PLGFlowNode.ts +244 -0
  184. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts +55 -0
  185. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts.map +1 -0
  186. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.js +105 -0
  187. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.ts +162 -0
  188. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts +42 -0
  189. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts.map +1 -0
  190. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.js +83 -0
  191. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.ts +127 -0
  192. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts +36 -0
  193. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts.map +1 -0
  194. package/src/generated/spacedatastandards/plg/PLGHostCapability.js +90 -0
  195. package/src/generated/spacedatastandards/plg/PLGHostCapability.ts +127 -0
  196. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts +53 -0
  197. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts.map +1 -0
  198. package/src/generated/spacedatastandards/plg/PLGMethodManifest.js +153 -0
  199. package/src/generated/spacedatastandards/plg/PLGMethodManifest.ts +210 -0
  200. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts +70 -0
  201. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts.map +1 -0
  202. package/src/generated/spacedatastandards/plg/PLGPortManifest.js +149 -0
  203. package/src/generated/spacedatastandards/plg/PLGPortManifest.ts +212 -0
  204. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts +73 -0
  205. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts.map +1 -0
  206. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.js +199 -0
  207. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.ts +292 -0
  208. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts +40 -0
  209. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts.map +1 -0
  210. package/src/generated/spacedatastandards/plg/PLGTimerSpec.js +103 -0
  211. package/src/generated/spacedatastandards/plg/PLGTimerSpec.ts +148 -0
  212. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts +41 -0
  213. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts.map +1 -0
  214. package/src/generated/spacedatastandards/plg/PluginCapability.js +82 -0
  215. package/src/generated/spacedatastandards/plg/{plugin-capability.ts → PluginCapability.ts} +55 -18
  216. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts +42 -0
  217. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts.map +1 -0
  218. package/src/generated/spacedatastandards/plg/PluginDependency.js +80 -0
  219. package/src/generated/spacedatastandards/plg/PluginDependency.ts +124 -0
  220. package/src/generated/spacedatastandards/plg/TAB.d.ts +85 -0
  221. package/src/generated/spacedatastandards/plg/TAB.d.ts.map +1 -0
  222. package/src/generated/spacedatastandards/plg/TAB.js +173 -0
  223. package/src/generated/spacedatastandards/plg/TAB.ts +228 -0
  224. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts +18 -0
  225. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts.map +1 -0
  226. package/src/generated/spacedatastandards/plg/bufferMutability.js +20 -0
  227. package/src/generated/spacedatastandards/plg/bufferMutability.ts +23 -0
  228. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts +18 -0
  229. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts.map +1 -0
  230. package/src/generated/spacedatastandards/plg/bufferOwnership.js +20 -0
  231. package/src/generated/spacedatastandards/plg/bufferOwnership.ts +23 -0
  232. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts +20 -0
  233. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts.map +1 -0
  234. package/src/generated/spacedatastandards/plg/drainBehavior.js +22 -0
  235. package/src/generated/spacedatastandards/plg/drainBehavior.ts +25 -0
  236. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts +10 -0
  237. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts.map +1 -0
  238. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.js +12 -0
  239. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.ts +13 -0
  240. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts +51 -0
  241. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts.map +1 -0
  242. package/src/generated/spacedatastandards/plg/hostCapabilityKind.js +53 -0
  243. package/src/generated/spacedatastandards/plg/hostCapabilityKind.ts +55 -0
  244. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts +15 -0
  245. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts.map +1 -0
  246. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.js +17 -0
  247. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.ts +19 -0
  248. package/src/generated/spacedatastandards/plg/main.d.ts +29 -0
  249. package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -0
  250. package/src/generated/spacedatastandards/plg/main.js +30 -0
  251. package/src/generated/spacedatastandards/plg/main.ts +32 -0
  252. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts +17 -0
  253. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts.map +1 -0
  254. package/src/generated/spacedatastandards/plg/payloadWireFormat.js +19 -0
  255. package/src/generated/spacedatastandards/plg/payloadWireFormat.ts +21 -0
  256. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +82 -0
  257. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -0
  258. package/src/generated/spacedatastandards/plg/pluginCategory.js +84 -0
  259. package/src/generated/spacedatastandards/plg/pluginCategory.ts +103 -0
  260. package/src/generated/spacedatastandards/plg/publicationState.d.ts +18 -0
  261. package/src/generated/spacedatastandards/plg/publicationState.d.ts.map +1 -0
  262. package/src/generated/spacedatastandards/plg/publicationState.js +20 -0
  263. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts +18 -0
  264. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts.map +1 -0
  265. package/src/generated/spacedatastandards/plg/purchaseTier.js +20 -0
  266. package/src/host/AGENTS.md +2 -2
  267. package/src/host/abi.js +53 -66
  268. package/src/host/browserHost.js +355 -8
  269. package/src/host/cpp/keyslotClient.hpp +231 -0
  270. package/src/host/cpp/secretsClient.hpp +583 -0
  271. package/src/host/hostcallWire.js +183 -0
  272. package/src/host/index.js +2 -0
  273. package/src/host/isomorphicLoader.js +44 -7
  274. package/src/host/nodeHost.js +227 -8
  275. package/src/host/sabHostcallChannel.js +206 -0
  276. package/src/host/timerDriver.js +203 -0
  277. package/src/host/wasiShim.js +41 -1
  278. package/src/host/wasiThreadBrowserWorker.mjs +48 -0
  279. package/src/host/wasiThreadHost.js +393 -0
  280. package/src/host/wasiThreadWorker.mjs +32 -0
  281. package/src/host/wasiThreadWorkerRuntime.js +93 -0
  282. package/src/http/index.js +339 -0
  283. package/src/index.d.ts +716 -10
  284. package/src/index.js +4 -0
  285. package/src/invoke/codec.js +1202 -128
  286. package/src/invoke/index.js +5 -1
  287. package/src/licensing/index.d.ts +2 -0
  288. package/src/licensing/index.js +2 -0
  289. package/src/licensing/records.js +287 -8
  290. package/src/manifest/codec.js +62 -14
  291. package/src/manifest/index.js +2 -0
  292. package/src/manifest/legacyToPlg.js +164 -25
  293. package/src/manifest/normalize.js +1 -0
  294. package/src/manifest/plgCodec.js +1303 -62
  295. package/src/manifest/typeRefs.js +162 -24
  296. package/src/runtime/compiledRuntimeAbi.js +47 -0
  297. package/src/runtime/compiledRuntimeAbi.json +33 -0
  298. package/src/runtime/index.d.ts +32 -0
  299. package/src/runtime/index.js +1 -0
  300. package/src/runtime-host/index.js +3 -0
  301. package/src/runtime-host/methodRegistry.js +55 -0
  302. package/src/standards/index.js +200 -56
  303. package/src/standards/sharedCatalog.js +16 -0
  304. package/src/testing/browserModuleHarness.js +604 -31
  305. package/src/testing/docker/wasmedge-parity.Dockerfile +39 -0
  306. package/src/testing/index.d.ts +151 -0
  307. package/src/testing/index.js +21 -0
  308. package/src/testing/native/wasmedge_emscripten_pthread_runner.c +25 -1
  309. package/src/testing/parityBrowserRunner.js +138 -0
  310. package/src/testing/parityHarness.js +616 -0
  311. package/src/testing/parityLanes.js +537 -0
  312. package/src/testing/processInvoke.js +29 -21
  313. package/src/testing/streamInvokeCodec.js +10 -175
  314. package/src/testing/wasmedgePin.json +6 -0
  315. package/src/testing/workerModuleHarness.js +242 -0
  316. package/src/testing/workerModuleHarnessWorker.js +176 -0
  317. package/src/transport/index.js +3 -0
  318. package/src/transport/pki.js +299 -11
  319. package/src/transport/records.js +16 -7
  320. package/src/utils/ecdsaDer.js +106 -0
  321. package/src/utils/wasmCrypto.js +0 -43
  322. package/templates/gpu-module/README.md +48 -0
  323. package/templates/gpu-module/include/space_data_gpu_abi.h +122 -0
  324. package/templates/gpu-module/manifest.json +84 -0
  325. package/schemas/PluginInvokeRequest.fbs +0 -18
  326. package/schemas/PluginInvokeResponse.fbs +0 -30
  327. package/schemas/spacedatastandards/PLG.fbs +0 -191
  328. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +0 -51
  329. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +0 -1
  330. package/src/generated/orbpro/invoke/plugin-invoke-request.js +0 -131
  331. package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +0 -1
  332. package/src/generated/orbpro/invoke/plugin-invoke-request.ts +0 -173
  333. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +0 -76
  334. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +0 -1
  335. package/src/generated/orbpro/invoke/plugin-invoke-response.js +0 -184
  336. package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +0 -1
  337. package/src/generated/orbpro/invoke/plugin-invoke-response.ts +0 -243
  338. package/src/generated/orbpro/invoke.d.ts +0 -3
  339. package/src/generated/orbpro/invoke.js +0 -5
  340. package/src/generated/spacedatastandards/plg/entry-function.js +0 -86
  341. package/src/generated/spacedatastandards/plg/entry-function.ts +0 -119
  342. package/src/generated/spacedatastandards/plg/index.js +0 -16
  343. package/src/generated/spacedatastandards/plg/index.ts +0 -11
  344. package/src/generated/spacedatastandards/plg/plg.js +0 -657
  345. package/src/generated/spacedatastandards/plg/plg.ts +0 -924
  346. package/src/generated/spacedatastandards/plg/plugin-capability.js +0 -66
  347. package/src/generated/spacedatastandards/plg/plugin-category.js +0 -15
  348. package/src/generated/spacedatastandards/plg/plugin-category.ts +0 -53
  349. package/src/generated/spacedatastandards/plg/plugin-dependency.js +0 -63
  350. package/src/generated/spacedatastandards/plg/plugin-dependency.ts +0 -86
  351. package/src/generated/spacedatastandards/plg/publication-state.js +0 -9
  352. package/src/generated/spacedatastandards/plg/purchase-tier.js +0 -9
  353. /package/src/generated/spacedatastandards/plg/{publication-state.ts → publicationState.ts} +0 -0
  354. /package/src/generated/spacedatastandards/plg/{purchase-tier.ts → purchaseTier.ts} +0 -0
@@ -1,13 +1,14 @@
1
1
  import { canonicalBytes } from "../auth/canonicalize.js";
2
+ import * as flatbuffers from "flatbuffers";
3
+ import { KMF, keyMaterialAlgorithm, keyMaterialEncoding, keyMaterialRole } from "spacedatastandards.org/lib/js/KMF/main.js";
2
4
  import {
3
5
  base64ToBytes,
4
6
  bytesToBase64,
7
+ bytesToHex,
5
8
  hexToBytes,
6
9
  toUint8Array,
7
10
  } from "../utils/encoding.js";
8
11
  import {
9
- aesCtrDecrypt,
10
- aesCtrEncrypt,
11
12
  aesGcmDecrypt,
12
13
  aesGcmEncrypt,
13
14
  hkdfBytes,
@@ -19,10 +20,36 @@ import {
19
20
  appendPublicationRecordCollection,
20
21
  createEncryptedEnvelopePayload,
21
22
  decodeEncRecord,
23
+ encodeEncRecord,
22
24
  encodePublicationRecordCollection,
23
25
  extractPublicationRecordCollection,
24
26
  } from "./records.js";
25
27
 
28
+ const GCM_TAG_LENGTH = 16;
29
+
30
+ // The authenticated payload layout is ciphertext || 16-byte GCM tag. The ENC
31
+ // FlatBuffer schema has no dedicated tag field, so the tag travels appended to
32
+ // the ciphertext, mirroring the packed layout already used by the legacy
33
+ // salt-based envelope format.
34
+ function splitGcmPayload(payloadBytes) {
35
+ const payload = toUint8Array(payloadBytes);
36
+ if (payload.length < GCM_TAG_LENGTH) {
37
+ throw new Error("AES-256-GCM protected payload is truncated.");
38
+ }
39
+ return {
40
+ ciphertext: payload.subarray(0, payload.length - GCM_TAG_LENGTH),
41
+ tag: payload.subarray(payload.length - GCM_TAG_LENGTH),
42
+ };
43
+ }
44
+
45
+ function assertGcmEncRecord(enc) {
46
+ if (enc?.symmetric !== "AES_256_GCM") {
47
+ throw new Error(
48
+ `Unsupported ENC symmetric algorithm "${enc?.symmetric}"; only AES_256_GCM is supported.`,
49
+ );
50
+ }
51
+ }
52
+
26
53
  function normalizePublicKey(value) {
27
54
  if (typeof value === "string") {
28
55
  return hexToBytes(value);
@@ -53,6 +80,130 @@ async function deriveAesKey(sharedSecret, salt, context) {
53
80
  );
54
81
  }
55
82
 
83
+ function normalizeOptionalBytes(value) {
84
+ if (value === null || value === undefined) {
85
+ return new Uint8Array(0);
86
+ }
87
+ if (typeof value === "string") {
88
+ return hexToBytes(value);
89
+ }
90
+ return toUint8Array(value);
91
+ }
92
+
93
+ function normalizeRequiredString(value, name) {
94
+ const normalized = String(value ?? "").trim();
95
+ if (!normalized) {
96
+ throw new Error(`${name} is required.`);
97
+ }
98
+ return normalized;
99
+ }
100
+
101
+ function normalizeArtifactBinding(artifact = {}) {
102
+ const listingId = normalizeRequiredString(artifact.listingId, "artifact.listingId");
103
+ const moduleId = normalizeRequiredString(artifact.moduleId, "artifact.moduleId");
104
+ const version = normalizeRequiredString(artifact.version, "artifact.version");
105
+ const encryptedCid = normalizeRequiredString(
106
+ artifact.encryptedCid,
107
+ "artifact.encryptedCid",
108
+ );
109
+ const providerId = normalizeRequiredString(artifact.providerId, "artifact.providerId");
110
+ const policyId = normalizeRequiredString(artifact.policyId, "artifact.policyId");
111
+ const keyEpoch = normalizeRequiredString(artifact.keyEpoch, "artifact.keyEpoch");
112
+ const contentKeyId =
113
+ String(artifact.contentKeyId ?? "").trim() ||
114
+ `${listingId}:${moduleId}:${version}:${keyEpoch}`;
115
+ const encryptedHash = normalizeOptionalBytes(artifact.encryptedHash);
116
+ if (encryptedHash.length !== 32) {
117
+ throw new Error("artifact.encryptedHash must be 32 bytes.");
118
+ }
119
+ const manifestHash = normalizeOptionalBytes(artifact.manifestHash);
120
+ if (manifestHash.length !== 32) {
121
+ throw new Error("artifact.manifestHash must be 32 bytes.");
122
+ }
123
+ return {
124
+ listingId,
125
+ moduleId,
126
+ version,
127
+ encryptedCid,
128
+ encryptedHash: bytesToHex(encryptedHash),
129
+ providerId,
130
+ policyId,
131
+ keyEpoch,
132
+ manifestHash: bytesToHex(manifestHash),
133
+ contentKeyId,
134
+ };
135
+ }
136
+
137
+ export function createMarketplaceContentAad(artifact = {}) {
138
+ const binding = normalizeArtifactBinding(artifact);
139
+ return canonicalBytes({
140
+ encryptedCid: binding.encryptedCid,
141
+ encryptedHash: binding.encryptedHash,
142
+ keyEpoch: binding.keyEpoch,
143
+ listingId: binding.listingId,
144
+ manifestHash: binding.manifestHash,
145
+ moduleId: binding.moduleId,
146
+ policyId: binding.policyId,
147
+ providerId: binding.providerId,
148
+ version: binding.version,
149
+ });
150
+ }
151
+
152
+ function createWrapAad({ artifact, recipient, algorithm }) {
153
+ return canonicalBytes({
154
+ algorithm,
155
+ contentKeyId: artifact.contentKeyId,
156
+ encryptedCid: artifact.encryptedCid,
157
+ expiresAtMs: Number(recipient.expiresAtMs ?? 0),
158
+ grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
159
+ keyEpoch: artifact.keyEpoch,
160
+ providerId: artifact.providerId,
161
+ recipientKeyId: normalizeRequiredString(
162
+ recipient.recipientKeyId,
163
+ "recipient.recipientKeyId",
164
+ ),
165
+ scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
166
+ });
167
+ }
168
+
169
+ function encodeContentKeyMaterial({ keyId, keyBytes, expiresAtMs }) {
170
+ const builder = new flatbuffers.Builder(256);
171
+ const keyIdOffset = builder.createString(keyId);
172
+ const keyBytesOffset = KMF.createKeyBytesVector(builder, keyBytes);
173
+ const root = KMF.createKMF(
174
+ builder,
175
+ keyIdOffset,
176
+ keyMaterialRole.PublicationContent,
177
+ keyMaterialAlgorithm.Aes256Gcm,
178
+ keyMaterialEncoding.RawBytes,
179
+ keyBytesOffset,
180
+ 1,
181
+ BigInt(Number(expiresAtMs ?? 0)),
182
+ );
183
+ KMF.finishKMFBuffer(builder, root);
184
+ return builder.asUint8Array();
185
+ }
186
+
187
+ function decodeContentKeyMaterial(bytes) {
188
+ const payload = toUint8Array(bytes);
189
+ const bb = new flatbuffers.ByteBuffer(payload);
190
+ if (!KMF.bufferHasIdentifier(bb)) {
191
+ throw new Error("Wrapped marketplace content key payload is not a KMF record.");
192
+ }
193
+ const kmf = KMF.getRootAsKMF(bb);
194
+ if (kmf.ROLE() !== keyMaterialRole.PublicationContent) {
195
+ throw new Error("Wrapped marketplace key material is not a publication content key.");
196
+ }
197
+ if (kmf.ALGORITHM() !== keyMaterialAlgorithm.Aes256Gcm) {
198
+ throw new Error("Wrapped marketplace key material is not an AES-256-GCM key.");
199
+ }
200
+ const keyBytes = kmf.keyBytesArray();
201
+ if (!keyBytes || keyBytes.length !== 32) {
202
+ throw new Error("Wrapped marketplace content key must be 32 bytes.");
203
+ }
204
+ return new Uint8Array(keyBytes);
205
+ }
206
+
56
207
  export async function generateX25519Keypair() {
57
208
  const privateKey = await randomBytes(32);
58
209
  const publicKey = await x25519PublicKey(privateKey);
@@ -62,6 +213,121 @@ export async function generateX25519Keypair() {
62
213
  };
63
214
  }
64
215
 
216
+ export async function protectMarketplaceContent({
217
+ plaintext,
218
+ artifact,
219
+ recipients = [],
220
+ contentKey = null,
221
+ contentNonce = null,
222
+ providerWrapKeyPair = null,
223
+ wrapNonce = null,
224
+ } = {}) {
225
+ if (!Array.isArray(recipients) || recipients.length === 0) {
226
+ throw new Error("protectMarketplaceContent requires at least one recipient.");
227
+ }
228
+ const binding = normalizeArtifactBinding(artifact);
229
+ const keyBytes = contentKey ? toUint8Array(contentKey) : await randomBytes(32);
230
+ if (keyBytes.length !== 32) {
231
+ throw new Error("Marketplace content keys must be 32 bytes.");
232
+ }
233
+ const nonce = contentNonce ? toUint8Array(contentNonce) : await randomBytes(12);
234
+ if (nonce.length !== 12) {
235
+ throw new Error("AES-256-GCM content encryption requires a 12-byte nonce.");
236
+ }
237
+ const aad = createMarketplaceContentAad(binding);
238
+ const encrypted = await aesGcmEncrypt(
239
+ keyBytes,
240
+ toUint8Array(plaintext),
241
+ nonce,
242
+ aad,
243
+ );
244
+ const wrappedKeys = [];
245
+ for (const recipient of recipients) {
246
+ const sender = providerWrapKeyPair ?? (await generateX25519Keypair());
247
+ const recipientPublicKey = normalizePublicKey(recipient.publicKey);
248
+ const wrapIv = wrapNonce ? toUint8Array(wrapNonce) : await randomBytes(12);
249
+ if (wrapIv.length !== 12) {
250
+ throw new Error("AES-256-GCM key wrapping requires a 12-byte nonce.");
251
+ }
252
+ const wrapAad = createWrapAad({
253
+ artifact: binding,
254
+ recipient,
255
+ algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
256
+ });
257
+ const sharedSecret = await deriveSharedSecret(
258
+ sender.privateKey,
259
+ recipientPublicKey,
260
+ );
261
+ const wrapContext = `marketplace-content-key:${binding.providerId}:${binding.contentKeyId}:${recipient.recipientKeyId}`;
262
+ const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
263
+ const keyMaterial = encodeContentKeyMaterial({
264
+ keyId: binding.contentKeyId,
265
+ keyBytes,
266
+ expiresAtMs: recipient.expiresAtMs,
267
+ });
268
+ const wrapped = await aesGcmEncrypt(wrapKey, keyMaterial, wrapIv, wrapAad);
269
+ wrappedKeys.push({
270
+ algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
271
+ contentKeyId: binding.contentKeyId,
272
+ recipientPeerId: normalizeRequiredString(
273
+ recipient.recipientPeerId,
274
+ "recipient.recipientPeerId",
275
+ ),
276
+ recipientKeyId: normalizeRequiredString(
277
+ recipient.recipientKeyId,
278
+ "recipient.recipientKeyId",
279
+ ),
280
+ providerId: binding.providerId,
281
+ encryptedCid: binding.encryptedCid,
282
+ grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
283
+ scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
284
+ expiresAtMs: Number(recipient.expiresAtMs ?? 0),
285
+ providerEphemeralPublicKey: sender.publicKey,
286
+ nonce: wrapIv,
287
+ aad: wrapAad,
288
+ ciphertext: wrapped.ciphertext,
289
+ tag: wrapped.tag,
290
+ });
291
+ }
292
+ return {
293
+ algorithm: "AES-256-GCM",
294
+ contentKeyId: binding.contentKeyId,
295
+ artifact: binding,
296
+ aad,
297
+ encryptedPayload: {
298
+ algorithm: "AES-256-GCM",
299
+ nonce,
300
+ aad,
301
+ ciphertext: encrypted.ciphertext,
302
+ tag: encrypted.tag,
303
+ },
304
+ wrappedKeys,
305
+ };
306
+ }
307
+
308
+ export async function decryptMarketplaceContentKeyWrap({
309
+ wrap,
310
+ recipientPrivateKey,
311
+ } = {}) {
312
+ if (!wrap) {
313
+ throw new Error("decryptMarketplaceContentKeyWrap requires wrap.");
314
+ }
315
+ const sharedSecret = await deriveSharedSecret(
316
+ recipientPrivateKey,
317
+ wrap.providerEphemeralPublicKey,
318
+ );
319
+ const wrapContext = `marketplace-content-key:${wrap.providerId}:${wrap.contentKeyId}:${wrap.recipientKeyId}`;
320
+ const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
321
+ const keyMaterial = await aesGcmDecrypt(
322
+ wrapKey,
323
+ wrap.ciphertext,
324
+ wrap.tag,
325
+ wrap.nonce,
326
+ wrap.aad,
327
+ );
328
+ return decodeContentKeyMaterial(keyMaterial);
329
+ }
330
+
65
331
  async function encryptBytesLegacy({
66
332
  plaintext,
67
333
  recipientPublicKey,
@@ -103,6 +369,7 @@ export async function decryptProtectedBytes({
103
369
  if (!parsed?.enc) {
104
370
  return toUint8Array(protectedBytes);
105
371
  }
372
+ assertGcmEncRecord(parsed.enc);
106
373
  const sharedSecret = await deriveSharedSecret(
107
374
  recipientPrivateKey,
108
375
  parsed.enc.ephemeralPublicKey,
@@ -112,7 +379,14 @@ export async function decryptProtectedBytes({
112
379
  new Uint8Array(0),
113
380
  parsed.enc.context ?? "",
114
381
  );
115
- return aesCtrDecrypt(aesKey, parsed.payloadBytes, parsed.enc.nonceStart);
382
+ const { ciphertext, tag } = splitGcmPayload(parsed.payloadBytes);
383
+ return aesGcmDecrypt(
384
+ aesKey,
385
+ ciphertext,
386
+ tag,
387
+ parsed.enc.nonceStart,
388
+ encodeEncRecord(parsed.enc),
389
+ );
116
390
  }
117
391
 
118
392
  export async function encryptBytesForRecipient({
@@ -134,11 +408,10 @@ export async function encryptBytesForRecipient({
134
408
  recipientPublicKey,
135
409
  );
136
410
  const aesKey = await deriveAesKey(sharedSecret, new Uint8Array(0), context);
137
- const ciphertext = await aesCtrEncrypt(aesKey, toUint8Array(plaintext), nonceStart);
138
411
  const enc = {
139
412
  version: 1,
140
413
  keyExchange: "X25519",
141
- symmetric: "AES_256_CTR",
414
+ symmetric: "AES_256_GCM",
142
415
  keyDerivation: "HKDF_SHA256",
143
416
  ephemeralPublicKey: sender.publicKey,
144
417
  nonceStart,
@@ -148,15 +421,29 @@ export async function encryptBytesForRecipient({
148
421
  rootType,
149
422
  timestamp: Date.now(),
150
423
  };
424
+ // The encoded ENC record doubles as the GCM AAD so every delivery parameter
425
+ // (context, schema hash, root type, recipient key id, nonce, ephemeral key)
426
+ // is authenticated alongside the ciphertext. encodeEncRecord() is
427
+ // deterministic for a normalized record, so decrypt paths recompute the
428
+ // identical bytes from the parsed ENC record.
429
+ const { ciphertext, tag } = await aesGcmEncrypt(
430
+ aesKey,
431
+ toUint8Array(plaintext),
432
+ nonceStart,
433
+ encodeEncRecord(enc),
434
+ );
435
+ const payloadBytes = new Uint8Array(ciphertext.length + tag.length);
436
+ payloadBytes.set(ciphertext, 0);
437
+ payloadBytes.set(tag, ciphertext.length);
151
438
  const recordCollectionBytes = encodePublicationRecordCollection({ enc });
152
439
  const protectedBlobBytes = appendPublicationRecordCollection(
153
- ciphertext,
440
+ payloadBytes,
154
441
  recordCollectionBytes,
155
442
  );
156
443
  return createEncryptedEnvelopePayload({
157
444
  protectedBlobBytes,
158
445
  parsedProtectedBlob: {
159
- payloadBytes: ciphertext,
446
+ payloadBytes,
160
447
  recordCollectionBytes,
161
448
  enc,
162
449
  pnm: null,
@@ -182,7 +469,9 @@ export async function decryptBytesFromEnvelope({
182
469
  });
183
470
  }
184
471
  if (envelope.ciphertextBase64 && envelope.encRecordBase64) {
185
- const enc = decodeEncRecord(base64ToBytes(envelope.encRecordBase64));
472
+ const encRecordBytes = base64ToBytes(envelope.encRecordBase64);
473
+ const enc = decodeEncRecord(encRecordBytes);
474
+ assertGcmEncRecord(enc);
186
475
  const sharedSecret = await deriveSharedSecret(
187
476
  recipientPrivateKey,
188
477
  enc.ephemeralPublicKey,
@@ -192,11 +481,10 @@ export async function decryptBytesFromEnvelope({
192
481
  new Uint8Array(0),
193
482
  enc.context ?? envelope.context ?? "",
194
483
  );
195
- return aesCtrDecrypt(
196
- aesKey,
484
+ const { ciphertext, tag } = splitGcmPayload(
197
485
  base64ToBytes(envelope.ciphertextBase64),
198
- enc.nonceStart,
199
486
  );
487
+ return aesGcmDecrypt(aesKey, ciphertext, tag, enc.nonceStart, encRecordBytes);
200
488
  }
201
489
  const sharedSecret = await deriveSharedSecret(
202
490
  recipientPrivateKey,
@@ -40,8 +40,14 @@ const KEY_EXCHANGE_NAME_BY_VALUE = Object.freeze(
40
40
  Object.entries(KEY_EXCHANGE_BY_NAME).map(([name, value]) => [value, name]),
41
41
  ),
42
42
  );
43
+ // AES_256_GCM is not yet published in the spacedatastandards.org generated
44
+ // SymmetricAlgo enum (which only defines AES_256_CTR = 0). The SYMMETRIC field
45
+ // is a plain byte on the wire, so value 1 is encoded directly until the schema
46
+ // publishes the enum member.
47
+ const SYMMETRIC_ALGO_AES_256_GCM = 1;
43
48
  const SYMMETRIC_ALGO_BY_NAME = Object.freeze({
44
49
  AES_256_CTR: SymmetricAlgo.AES_256_CTR,
50
+ AES_256_GCM: SYMMETRIC_ALGO_AES_256_GCM,
45
51
  });
46
52
  const SYMMETRIC_ALGO_NAME_BY_VALUE = Object.freeze(
47
53
  Object.fromEntries(
@@ -429,12 +435,15 @@ function normalizeSymmetricAlgorithm(value) {
429
435
  if (typeof value === "number") {
430
436
  return value;
431
437
  }
432
- return SYMMETRIC_ALGO_BY_NAME[
433
- String(value ?? "AES_256_CTR")
434
- .trim()
435
- .replace(/[^A-Za-z0-9]+/g, "_")
436
- .toUpperCase()
437
- ] ?? SymmetricAlgo.AES_256_CTR;
438
+ const normalized = String(value ?? "AES_256_GCM")
439
+ .trim()
440
+ .replace(/[^A-Za-z0-9]+/g, "_")
441
+ .toUpperCase();
442
+ const resolved = SYMMETRIC_ALGO_BY_NAME[normalized];
443
+ if (resolved === undefined) {
444
+ throw new Error(`Unsupported ENC symmetric algorithm "${value}".`);
445
+ }
446
+ return resolved;
438
447
  }
439
448
 
440
449
  function normalizeKdf(value) {
@@ -834,7 +843,7 @@ export function createEncryptedEnvelopePayload(options = {}) {
834
843
  const envelope = {
835
844
  version: Number(options.version ?? 2),
836
845
  scheme:
837
- normalizeStringField(options.scheme) ?? "x25519-hkdf-aes-256-ctr-rec",
846
+ normalizeStringField(options.scheme) ?? "x25519-hkdf-aes-256-gcm-rec",
838
847
  context: normalizeStringField(options.context ?? enc?.context) ?? "",
839
848
  protectedBlobBase64: bytesToBase64(protectedBlob),
840
849
  recordCollectionBase64: parsed
@@ -0,0 +1,106 @@
1
+ /**
2
+ * DER <-> raw conversion for secp256k1 ECDSA signatures.
3
+ *
4
+ * The shared WASM crypto backend (hd-wallet-wasm) produces and consumes
5
+ * raw 64-byte (r || s) signatures. EPM SIGNATURE bytes, however, are
6
+ * ECDSA-DER encoded (SEQUENCE { INTEGER r, INTEGER s }). These helpers
7
+ * bridge the two encodings so the host-crypto ABI can honor the DER
8
+ * contract while calling the raw-signature WASM primitives.
9
+ */
10
+
11
+ import { toUint8Array } from "./encoding.js";
12
+
13
+ const RAW_SIGNATURE_LENGTH = 64;
14
+ const COMPONENT_LENGTH = 32;
15
+
16
+ function encodeDerInteger(component) {
17
+ // Strip superfluous leading zero bytes, keeping at least one byte.
18
+ let start = 0;
19
+ while (start < component.length - 1 && component[start] === 0) {
20
+ start += 1;
21
+ }
22
+ let value = component.subarray(start);
23
+ // DER integers are signed; prepend 0x00 when the high bit is set so the
24
+ // value is not interpreted as negative.
25
+ if ((value[0] & 0x80) !== 0) {
26
+ const padded = new Uint8Array(value.length + 1);
27
+ padded.set(value, 1);
28
+ value = padded;
29
+ }
30
+ const encoded = new Uint8Array(value.length + 2);
31
+ encoded[0] = 0x02; // INTEGER
32
+ encoded[1] = value.length;
33
+ encoded.set(value, 2);
34
+ return encoded;
35
+ }
36
+
37
+ /**
38
+ * Encode a raw 64-byte (r || s) secp256k1 ECDSA signature as DER.
39
+ */
40
+ export function rawSignatureToDer(rawSignature) {
41
+ const bytes = toUint8Array(rawSignature);
42
+ if (bytes.length !== RAW_SIGNATURE_LENGTH) {
43
+ throw new Error(
44
+ `secp256k1 raw signature must be ${RAW_SIGNATURE_LENGTH} bytes, received ${bytes.length}.`,
45
+ );
46
+ }
47
+ const r = encodeDerInteger(bytes.subarray(0, COMPONENT_LENGTH));
48
+ const s = encodeDerInteger(bytes.subarray(COMPONENT_LENGTH, RAW_SIGNATURE_LENGTH));
49
+ const body = new Uint8Array(r.length + s.length);
50
+ body.set(r, 0);
51
+ body.set(s, r.length);
52
+ // Signature bodies never exceed 127 bytes, so short-form length is safe.
53
+ const der = new Uint8Array(body.length + 2);
54
+ der[0] = 0x30; // SEQUENCE
55
+ der[1] = body.length;
56
+ der.set(body, 2);
57
+ return der;
58
+ }
59
+
60
+ function normalizeComponent(component) {
61
+ let start = 0;
62
+ while (start < component.length - 1 && component[start] === 0) {
63
+ start += 1;
64
+ }
65
+ const value = component.subarray(start);
66
+ if (value.length > COMPONENT_LENGTH) {
67
+ throw new Error("Invalid DER signature: integer component exceeds 32 bytes.");
68
+ }
69
+ const out = new Uint8Array(COMPONENT_LENGTH);
70
+ out.set(value, COMPONENT_LENGTH - value.length);
71
+ return out;
72
+ }
73
+
74
+ function readDerInteger(bytes, offset) {
75
+ if (bytes[offset] !== 0x02) {
76
+ throw new Error("Invalid DER signature: expected INTEGER.");
77
+ }
78
+ const length = bytes[offset + 1];
79
+ const start = offset + 2;
80
+ const end = start + length;
81
+ if (end > bytes.length) {
82
+ throw new Error("Invalid DER signature: INTEGER length exceeds bounds.");
83
+ }
84
+ return { value: bytes.subarray(start, end), next: end };
85
+ }
86
+
87
+ /**
88
+ * Decode a DER-encoded secp256k1 ECDSA signature into raw 64-byte (r || s).
89
+ */
90
+ export function derSignatureToRaw(derSignature) {
91
+ const bytes = toUint8Array(derSignature);
92
+ if (bytes.length < 8 || bytes[0] !== 0x30) {
93
+ throw new Error("Invalid DER signature: expected SEQUENCE.");
94
+ }
95
+ let offset = 2;
96
+ if ((bytes[1] & 0x80) !== 0) {
97
+ // Long-form length; skip the length-of-length bytes.
98
+ offset = 2 + (bytes[1] & 0x7f);
99
+ }
100
+ const rPart = readDerInteger(bytes, offset);
101
+ const sPart = readDerInteger(bytes, rPart.next);
102
+ const raw = new Uint8Array(RAW_SIGNATURE_LENGTH);
103
+ raw.set(normalizeComponent(rPart.value), 0);
104
+ raw.set(normalizeComponent(sPart.value), COMPONENT_LENGTH);
105
+ return raw;
106
+ }
@@ -116,46 +116,3 @@ export async function aesGcmDecrypt(key, ciphertext, tag, iv, aad = null) {
116
116
  aad ? toUint8Array(aad) : undefined,
117
117
  );
118
118
  }
119
-
120
- function normalizeCtrIv(nonceStart) {
121
- const nonce = toUint8Array(nonceStart);
122
- if (nonce.length !== 12) {
123
- throw new Error("AES-256-CTR expects a 12-byte NONCE_START value.");
124
- }
125
- const iv = new Uint8Array(16);
126
- iv.set(nonce, 0);
127
- return iv;
128
- }
129
-
130
- async function getAesCtrApi() {
131
- const wallet = await getWasmWallet();
132
- const aesCtr = wallet?.aesCtr;
133
- if (
134
- !aesCtr ||
135
- typeof aesCtr.encrypt !== "function" ||
136
- typeof aesCtr.decrypt !== "function"
137
- ) {
138
- throw new Error(
139
- "hd-wallet-wasm aesCtr API is unavailable; cannot process ENC payloads.",
140
- );
141
- }
142
- return aesCtr;
143
- }
144
-
145
- export async function aesCtrEncrypt(key, plaintext, nonceStart) {
146
- const aesCtr = await getAesCtrApi();
147
- return aesCtr.encrypt(
148
- toUint8Array(key),
149
- toUint8Array(plaintext),
150
- normalizeCtrIv(nonceStart),
151
- );
152
- }
153
-
154
- export async function aesCtrDecrypt(key, ciphertext, nonceStart) {
155
- const aesCtr = await getAesCtrApi();
156
- return aesCtr.decrypt(
157
- toUint8Array(key),
158
- toUint8Array(ciphertext),
159
- normalizeCtrIv(nonceStart),
160
- );
161
- }
@@ -0,0 +1,48 @@
1
+ # GPU Module Template
2
+
3
+ This template is the SDK starting point for modules that can use WebGPU in the
4
+ browser and Dawn in a native WasmEdge host while keeping a portable CPU
5
+ fallback.
6
+
7
+ ## Files
8
+
9
+ - `include/space_data_gpu_abi.h`: shared C/C++ layout ABI for GPU-capable
10
+ module code and host adapters.
11
+ - `manifest.json`: starter manifest showing the `gpu_compute` capability.
12
+
13
+ ## Runtime Shape
14
+
15
+ Keep the canonical module artifact at:
16
+
17
+ ```text
18
+ dist/isomorphic/module.wasm
19
+ ```
20
+
21
+ That artifact must run without GPU access. Put optional GPU adapters beside it:
22
+
23
+ ```text
24
+ dist/browser/module.js
25
+ dist/wasmedge/gpu-host.{so,dylib,dll}
26
+ ```
27
+
28
+ The browser adapter owns WebGPU. The WasmEdge host extension owns Dawn. The
29
+ module owns correctness, fallback, and final result validation.
30
+
31
+ ## C++ Integration
32
+
33
+ Include the ABI header from module or host code:
34
+
35
+ ```cpp
36
+ #include "space_data_gpu_abi.h"
37
+ ```
38
+
39
+ Use `SdnGpuSplitF64` for double-like values that must cross into WGSL as two
40
+ `f32` values:
41
+
42
+ ```cpp
43
+ SdnGpuVec3SplitF64 position = sdn_gpu_split_vec3_f64(x_km, y_km, z_km);
44
+ ```
45
+
46
+ Use the dispatch/result descriptor structs for host adapter boundaries. Do not
47
+ store raw pointers in manifests, publication metadata, or durable runtime
48
+ records.