space-data-module-sdk 0.1.0

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 (102) hide show
  1. package/README.md +139 -0
  2. package/bin/space-data-module.js +230 -0
  3. package/package.json +40 -0
  4. package/schemas/PluginManifest.fbs +144 -0
  5. package/schemas/TypedArenaBuffer.fbs +78 -0
  6. package/src/auth/canonicalize.js +72 -0
  7. package/src/auth/index.js +10 -0
  8. package/src/auth/permissions.js +190 -0
  9. package/src/compiler/compileModule.js +237 -0
  10. package/src/compiler/index.js +7 -0
  11. package/src/compliance/index.js +56 -0
  12. package/src/compliance/pluginCompliance.js +574 -0
  13. package/src/embeddedManifest.js +124 -0
  14. package/src/generated/orbpro/manifest/accepted-type-set.d.ts +45 -0
  15. package/src/generated/orbpro/manifest/accepted-type-set.d.ts.map +1 -0
  16. package/src/generated/orbpro/manifest/accepted-type-set.js +100 -0
  17. package/src/generated/orbpro/manifest/accepted-type-set.js.map +1 -0
  18. package/src/generated/orbpro/manifest/accepted-type-set.ts +200 -0
  19. package/src/generated/orbpro/manifest/build-artifact.d.ts +41 -0
  20. package/src/generated/orbpro/manifest/build-artifact.d.ts.map +1 -0
  21. package/src/generated/orbpro/manifest/build-artifact.js +105 -0
  22. package/src/generated/orbpro/manifest/build-artifact.js.map +1 -0
  23. package/src/generated/orbpro/manifest/build-artifact.ts +193 -0
  24. package/src/generated/orbpro/manifest/capability-kind.d.ts +17 -0
  25. package/src/generated/orbpro/manifest/capability-kind.d.ts.map +1 -0
  26. package/src/generated/orbpro/manifest/capability-kind.js +20 -0
  27. package/src/generated/orbpro/manifest/capability-kind.js.map +1 -0
  28. package/src/generated/orbpro/manifest/capability-kind.ts +20 -0
  29. package/src/generated/orbpro/manifest/drain-policy.d.ts +9 -0
  30. package/src/generated/orbpro/manifest/drain-policy.d.ts.map +1 -0
  31. package/src/generated/orbpro/manifest/drain-policy.js +12 -0
  32. package/src/generated/orbpro/manifest/drain-policy.js.map +1 -0
  33. package/src/generated/orbpro/manifest/drain-policy.ts +12 -0
  34. package/src/generated/orbpro/manifest/host-capability.d.ts +36 -0
  35. package/src/generated/orbpro/manifest/host-capability.d.ts.map +1 -0
  36. package/src/generated/orbpro/manifest/host-capability.js +91 -0
  37. package/src/generated/orbpro/manifest/host-capability.js.map +1 -0
  38. package/src/generated/orbpro/manifest/host-capability.ts +161 -0
  39. package/src/generated/orbpro/manifest/method-manifest.d.ts +53 -0
  40. package/src/generated/orbpro/manifest/method-manifest.d.ts.map +1 -0
  41. package/src/generated/orbpro/manifest/method-manifest.js +154 -0
  42. package/src/generated/orbpro/manifest/method-manifest.js.map +1 -0
  43. package/src/generated/orbpro/manifest/method-manifest.ts +306 -0
  44. package/src/generated/orbpro/manifest/plugin-family.d.ts +17 -0
  45. package/src/generated/orbpro/manifest/plugin-family.d.ts.map +1 -0
  46. package/src/generated/orbpro/manifest/plugin-family.js +20 -0
  47. package/src/generated/orbpro/manifest/plugin-family.js.map +1 -0
  48. package/src/generated/orbpro/manifest/plugin-family.ts +20 -0
  49. package/src/generated/orbpro/manifest/plugin-manifest.d.ts +85 -0
  50. package/src/generated/orbpro/manifest/plugin-manifest.d.ts.map +1 -0
  51. package/src/generated/orbpro/manifest/plugin-manifest.js +268 -0
  52. package/src/generated/orbpro/manifest/plugin-manifest.js.map +1 -0
  53. package/src/generated/orbpro/manifest/plugin-manifest.ts +562 -0
  54. package/src/generated/orbpro/manifest/port-manifest.d.ts +70 -0
  55. package/src/generated/orbpro/manifest/port-manifest.d.ts.map +1 -0
  56. package/src/generated/orbpro/manifest/port-manifest.js +150 -0
  57. package/src/generated/orbpro/manifest/port-manifest.js.map +1 -0
  58. package/src/generated/orbpro/manifest/port-manifest.ts +284 -0
  59. package/src/generated/orbpro/manifest/protocol-spec.d.ts +41 -0
  60. package/src/generated/orbpro/manifest/protocol-spec.d.ts.map +1 -0
  61. package/src/generated/orbpro/manifest/protocol-spec.js +105 -0
  62. package/src/generated/orbpro/manifest/protocol-spec.js.map +1 -0
  63. package/src/generated/orbpro/manifest/protocol-spec.ts +205 -0
  64. package/src/generated/orbpro/manifest/timer-spec.d.ts +40 -0
  65. package/src/generated/orbpro/manifest/timer-spec.d.ts.map +1 -0
  66. package/src/generated/orbpro/manifest/timer-spec.js +104 -0
  67. package/src/generated/orbpro/manifest/timer-spec.js.map +1 -0
  68. package/src/generated/orbpro/manifest/timer-spec.ts +195 -0
  69. package/src/generated/orbpro/manifest.js +14 -0
  70. package/src/generated/orbpro/stream/buffer-mutability.d.ts +9 -0
  71. package/src/generated/orbpro/stream/buffer-mutability.d.ts.map +1 -0
  72. package/src/generated/orbpro/stream/buffer-mutability.js +12 -0
  73. package/src/generated/orbpro/stream/buffer-mutability.js.map +1 -0
  74. package/src/generated/orbpro/stream/buffer-mutability.ts +12 -0
  75. package/src/generated/orbpro/stream/buffer-ownership.d.ts +10 -0
  76. package/src/generated/orbpro/stream/buffer-ownership.d.ts.map +1 -0
  77. package/src/generated/orbpro/stream/buffer-ownership.js +13 -0
  78. package/src/generated/orbpro/stream/buffer-ownership.js.map +1 -0
  79. package/src/generated/orbpro/stream/buffer-ownership.ts +13 -0
  80. package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts +51 -0
  81. package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts.map +1 -0
  82. package/src/generated/orbpro/stream/flat-buffer-type-ref.js +115 -0
  83. package/src/generated/orbpro/stream/flat-buffer-type-ref.js.map +1 -0
  84. package/src/generated/orbpro/stream/flat-buffer-type-ref.ts +222 -0
  85. package/src/generated/orbpro/stream/typed-arena-buffer.d.ts +100 -0
  86. package/src/generated/orbpro/stream/typed-arena-buffer.d.ts.map +1 -0
  87. package/src/generated/orbpro/stream/typed-arena-buffer.js +215 -0
  88. package/src/generated/orbpro/stream/typed-arena-buffer.js.map +1 -0
  89. package/src/generated/orbpro/stream/typed-arena-buffer.ts +344 -0
  90. package/src/index.js +8 -0
  91. package/src/manifest/codec.js +40 -0
  92. package/src/manifest/index.js +9 -0
  93. package/src/manifest/normalize.js +275 -0
  94. package/src/runtime/bufferLike.js +28 -0
  95. package/src/runtime/constants.js +34 -0
  96. package/src/standards/index.js +153 -0
  97. package/src/standards/sharedCatalog.js +196 -0
  98. package/src/transport/index.js +8 -0
  99. package/src/transport/pki.js +140 -0
  100. package/src/utils/crypto.js +8 -0
  101. package/src/utils/encoding.js +54 -0
  102. package/src/utils/wasmCrypto.js +70 -0
@@ -0,0 +1,140 @@
1
+ import { canonicalBytes } from "../auth/canonicalize.js";
2
+ import {
3
+ base64ToBytes,
4
+ bytesToBase64,
5
+ hexToBytes,
6
+ toUint8Array,
7
+ } from "../utils/encoding.js";
8
+ import {
9
+ aesGcmDecrypt,
10
+ aesGcmEncrypt,
11
+ hkdfBytes,
12
+ randomBytes,
13
+ x25519PublicKey,
14
+ x25519SharedSecret,
15
+ } from "../utils/wasmCrypto.js";
16
+
17
+ const HKDF_SALT_LABEL = new TextEncoder().encode("space-data-module-sdk");
18
+
19
+ function normalizePublicKey(value) {
20
+ if (typeof value === "string") {
21
+ return hexToBytes(value);
22
+ }
23
+ return toUint8Array(value);
24
+ }
25
+
26
+ function normalizePrivateKey(value) {
27
+ if (typeof value === "string") {
28
+ return hexToBytes(value);
29
+ }
30
+ return toUint8Array(value);
31
+ }
32
+
33
+ async function deriveSharedSecret(privateKey, publicKey) {
34
+ return x25519SharedSecret(
35
+ normalizePrivateKey(privateKey),
36
+ normalizePublicKey(publicKey),
37
+ );
38
+ }
39
+
40
+ async function deriveAesKey(sharedSecret, salt, context) {
41
+ return hkdfBytes(
42
+ sharedSecret,
43
+ salt,
44
+ new TextEncoder().encode(context),
45
+ 32,
46
+ );
47
+ }
48
+
49
+ export async function generateX25519Keypair() {
50
+ const privateKey = await randomBytes(32);
51
+ const publicKey = await x25519PublicKey(privateKey);
52
+ return {
53
+ publicKey,
54
+ privateKey,
55
+ };
56
+ }
57
+
58
+ export async function encryptBytesForRecipient({
59
+ plaintext,
60
+ recipientPublicKey,
61
+ context = "space-data-module-sdk/package",
62
+ senderKeyPair = null,
63
+ } = {}) {
64
+ if (!recipientPublicKey) {
65
+ throw new Error("encryptBytesForRecipient requires recipientPublicKey.");
66
+ }
67
+ const sender = senderKeyPair ?? (await generateX25519Keypair());
68
+ const salt = await randomBytes(32);
69
+ salt.set(
70
+ HKDF_SALT_LABEL.slice(0, Math.min(HKDF_SALT_LABEL.length, salt.length)),
71
+ );
72
+ const iv = await randomBytes(12);
73
+ const sharedSecret = await deriveSharedSecret(
74
+ sender.privateKey,
75
+ recipientPublicKey,
76
+ );
77
+ const aesKey = await deriveAesKey(sharedSecret, salt, context);
78
+ const { ciphertext, tag } = await aesGcmEncrypt(
79
+ aesKey,
80
+ toUint8Array(plaintext),
81
+ iv,
82
+ );
83
+ const packedCiphertext = new Uint8Array(ciphertext.length + tag.length);
84
+ packedCiphertext.set(ciphertext, 0);
85
+ packedCiphertext.set(tag, ciphertext.length);
86
+ return {
87
+ version: 1,
88
+ scheme: "x25519-hkdf-aes-256-gcm",
89
+ context,
90
+ senderPublicKeyBase64: bytesToBase64(sender.publicKey),
91
+ saltBase64: bytesToBase64(salt),
92
+ ivBase64: bytesToBase64(iv),
93
+ ciphertextBase64: bytesToBase64(packedCiphertext),
94
+ };
95
+ }
96
+
97
+ export async function decryptBytesFromEnvelope({
98
+ envelope,
99
+ recipientPrivateKey,
100
+ } = {}) {
101
+ if (!envelope || !recipientPrivateKey) {
102
+ throw new Error(
103
+ "decryptBytesFromEnvelope requires envelope and recipientPrivateKey.",
104
+ );
105
+ }
106
+ const sharedSecret = await deriveSharedSecret(
107
+ recipientPrivateKey,
108
+ base64ToBytes(envelope.senderPublicKeyBase64),
109
+ );
110
+ const aesKey = await deriveAesKey(
111
+ sharedSecret,
112
+ base64ToBytes(envelope.saltBase64),
113
+ envelope.context,
114
+ );
115
+ const packedCiphertext = base64ToBytes(envelope.ciphertextBase64);
116
+ if (packedCiphertext.length < 16) {
117
+ throw new Error("Encrypted envelope payload is truncated.");
118
+ }
119
+ const ciphertext = packedCiphertext.slice(0, packedCiphertext.length - 16);
120
+ const tag = packedCiphertext.slice(packedCiphertext.length - 16);
121
+ return aesGcmDecrypt(
122
+ aesKey,
123
+ ciphertext,
124
+ tag,
125
+ base64ToBytes(envelope.ivBase64),
126
+ );
127
+ }
128
+
129
+ export async function encryptJsonForRecipient(options = {}) {
130
+ return encryptBytesForRecipient({
131
+ ...options,
132
+ plaintext: canonicalBytes(options.payload ?? {}),
133
+ });
134
+ }
135
+
136
+ export async function decryptJsonFromEnvelope(options = {}) {
137
+ const bytes = await decryptBytesFromEnvelope(options);
138
+ return JSON.parse(new TextDecoder().decode(bytes));
139
+ }
140
+
@@ -0,0 +1,8 @@
1
+ export function getCrypto() {
2
+ throw new Error(
3
+ "Direct WebCrypto access is forbidden. Use the WASM crypto helpers instead.",
4
+ );
5
+ }
6
+
7
+ export { randomBytes, sha256Bytes } from "./wasmCrypto.js";
8
+
@@ -0,0 +1,54 @@
1
+ function assertByteValue(value) {
2
+ if (!Number.isInteger(value) || value < 0 || value > 255) {
3
+ throw new TypeError("Expected byte values in range 0..255.");
4
+ }
5
+ }
6
+
7
+ export function toUint8Array(value) {
8
+ if (value instanceof Uint8Array) {
9
+ return value;
10
+ }
11
+ if (ArrayBuffer.isView(value)) {
12
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
13
+ }
14
+ if (value instanceof ArrayBuffer) {
15
+ return new Uint8Array(value);
16
+ }
17
+ if (Array.isArray(value)) {
18
+ value.forEach(assertByteValue);
19
+ return Uint8Array.from(value);
20
+ }
21
+ throw new TypeError(
22
+ "Expected Uint8Array, ArrayBuffer, ArrayBufferView, or byte array.",
23
+ );
24
+ }
25
+
26
+ export function bytesToHex(bytes) {
27
+ return Array.from(toUint8Array(bytes), (byte) =>
28
+ byte.toString(16).padStart(2, "0"),
29
+ ).join("");
30
+ }
31
+
32
+ export function hexToBytes(hex) {
33
+ const normalized = String(hex ?? "")
34
+ .trim()
35
+ .replace(/^0x/i, "")
36
+ .toLowerCase();
37
+ if (normalized.length === 0 || normalized.length % 2 !== 0) {
38
+ throw new TypeError("Expected even-length hex string.");
39
+ }
40
+ const bytes = new Uint8Array(normalized.length / 2);
41
+ for (let index = 0; index < normalized.length; index += 2) {
42
+ bytes[index / 2] = parseInt(normalized.slice(index, index + 2), 16);
43
+ }
44
+ return bytes;
45
+ }
46
+
47
+ export function bytesToBase64(bytes) {
48
+ return Buffer.from(toUint8Array(bytes)).toString("base64");
49
+ }
50
+
51
+ export function base64ToBytes(base64) {
52
+ return new Uint8Array(Buffer.from(String(base64 ?? "").trim(), "base64"));
53
+ }
54
+
@@ -0,0 +1,70 @@
1
+ import { toUint8Array } from "./encoding.js";
2
+
3
+ let walletPromise = null;
4
+
5
+ export async function getWasmWallet() {
6
+ if (!walletPromise) {
7
+ walletPromise = (async () => {
8
+ const module = await import("hd-wallet-wasm");
9
+ const init = module.default ?? module.createHDWallet;
10
+ return init();
11
+ })();
12
+ }
13
+
14
+ return walletPromise;
15
+ }
16
+
17
+ export async function randomBytes(length) {
18
+ const wallet = await getWasmWallet();
19
+ return wallet.utils.getRandomBytes(length);
20
+ }
21
+
22
+ export async function sha256Bytes(value) {
23
+ const wallet = await getWasmWallet();
24
+ return wallet.utils.sha256(toUint8Array(value));
25
+ }
26
+
27
+ export async function hkdfBytes(ikm, salt, info, length) {
28
+ const wallet = await getWasmWallet();
29
+ return wallet.utils.hkdf(
30
+ toUint8Array(ikm),
31
+ toUint8Array(salt),
32
+ toUint8Array(info),
33
+ length,
34
+ );
35
+ }
36
+
37
+ export async function x25519PublicKey(privateKey) {
38
+ const wallet = await getWasmWallet();
39
+ return wallet.curves.x25519.publicKey(toUint8Array(privateKey));
40
+ }
41
+
42
+ export async function x25519SharedSecret(privateKey, publicKey) {
43
+ const wallet = await getWasmWallet();
44
+ return wallet.curves.x25519.ecdh(
45
+ toUint8Array(privateKey),
46
+ toUint8Array(publicKey),
47
+ );
48
+ }
49
+
50
+ export async function aesGcmEncrypt(key, plaintext, iv, aad = null) {
51
+ const wallet = await getWasmWallet();
52
+ return wallet.utils.aesGcm.encrypt(
53
+ toUint8Array(key),
54
+ toUint8Array(plaintext),
55
+ toUint8Array(iv),
56
+ aad ? toUint8Array(aad) : undefined,
57
+ );
58
+ }
59
+
60
+ export async function aesGcmDecrypt(key, ciphertext, tag, iv, aad = null) {
61
+ const wallet = await getWasmWallet();
62
+ return wallet.utils.aesGcm.decrypt(
63
+ toUint8Array(key),
64
+ toUint8Array(ciphertext),
65
+ toUint8Array(tag),
66
+ toUint8Array(iv),
67
+ aad ? toUint8Array(aad) : undefined,
68
+ );
69
+ }
70
+