@bandeira-tech/b3nd-web 0.5.1 → 0.5.2

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.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Blob and Link utilities for B3nd content-addressed storage
3
+ *
4
+ * @module blob
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { computeSha256, generateBlobUri, validateLinkValue } from "@bandeira-tech/b3nd-sdk/blob";
9
+ *
10
+ * // Compute hash and generate blob URI
11
+ * const data = { title: "Hello", content: "World" };
12
+ * const hash = await computeSha256(data);
13
+ * const blobUri = generateBlobUri(hash);
14
+ * // blobUri = "blob://open/sha256:2cf24dba..."
15
+ *
16
+ * // Validate a link value
17
+ * const result = validateLinkValue("blob://open/sha256:abc123...");
18
+ * // result = { valid: true }
19
+ * ```
20
+ */
21
+ /**
22
+ * Compute SHA256 hash of a value
23
+ * @param value - The value to hash (Uint8Array for binary, otherwise JSON-stringified)
24
+ * @returns Hex-encoded SHA256 hash (64 characters)
25
+ */
26
+ declare function computeSha256(value: Uint8Array | unknown): Promise<string>;
27
+ /**
28
+ * Generate a blob URI from a SHA256 hash
29
+ * @param hash - Hex-encoded SHA256 hash (64 characters)
30
+ * @returns Blob URI in format "blob://open/sha256:{hash}"
31
+ */
32
+ declare function generateBlobUri(hash: string): string;
33
+ /**
34
+ * Parse a blob URI to extract the hash
35
+ * @param uri - Blob URI in format "blob://open/sha256:{hash}"
36
+ * @returns Object with algorithm and hash, or null if invalid
37
+ */
38
+ declare function parseBlobUri(uri: string): {
39
+ algorithm: string;
40
+ hash: string;
41
+ } | null;
42
+ /**
43
+ * Validate that a value is a valid link (string URI)
44
+ * @param value - The value to validate
45
+ * @returns Validation result with valid boolean and optional error
46
+ */
47
+ declare function validateLinkValue(value: unknown): {
48
+ valid: boolean;
49
+ error?: string;
50
+ };
51
+ /**
52
+ * Generate a link URI for authenticated links
53
+ * @param pubkey - Public key (hex) of the account
54
+ * @param path - Path within the account namespace
55
+ * @returns Link URI in format "link://accounts/{pubkey}/{path}"
56
+ */
57
+ declare function generateLinkUri(pubkey: string, path: string): string;
58
+ /**
59
+ * Validate a SHA256 hash format
60
+ * @param hash - Hash string to validate
61
+ * @returns true if valid 64-character hex string
62
+ */
63
+ declare function isValidSha256Hash(hash: string): boolean;
64
+ /**
65
+ * Verify that content matches its blob URI hash
66
+ * @param uri - Blob URI containing the expected hash
67
+ * @param value - Content to verify
68
+ * @returns Object with valid boolean and computed hash
69
+ */
70
+ declare function verifyBlobContent(uri: string, value: Uint8Array | unknown): Promise<{
71
+ valid: boolean;
72
+ expectedHash?: string;
73
+ actualHash: string;
74
+ error?: string;
75
+ }>;
76
+
77
+ export { computeSha256, generateBlobUri, generateLinkUri, isValidSha256Hash, parseBlobUri, validateLinkValue, verifyBlobContent };
@@ -0,0 +1,74 @@
1
+ import "../chunk-MLKGABMK.js";
2
+
3
+ // blob/mod.ts
4
+ async function computeSha256(value) {
5
+ let data;
6
+ if (value instanceof Uint8Array) {
7
+ data = value;
8
+ } else {
9
+ const encoder = new TextEncoder();
10
+ data = encoder.encode(JSON.stringify(value));
11
+ }
12
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
13
+ const hashArray = new Uint8Array(hashBuffer);
14
+ return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
15
+ }
16
+ function generateBlobUri(hash) {
17
+ return `blob://open/sha256:${hash}`;
18
+ }
19
+ function parseBlobUri(uri) {
20
+ try {
21
+ const url = new URL(uri);
22
+ if (url.protocol !== "blob:") return null;
23
+ const match = url.pathname.match(/^\/([^:]+):([a-f0-9]+)$/i);
24
+ if (!match) return null;
25
+ return { algorithm: match[1], hash: match[2] };
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+ function validateLinkValue(value) {
31
+ if (typeof value !== "string") {
32
+ return { valid: false, error: "Link value must be a string URI" };
33
+ }
34
+ try {
35
+ new URL(value);
36
+ } catch {
37
+ return { valid: false, error: "Link value must be a valid URI" };
38
+ }
39
+ return { valid: true };
40
+ }
41
+ function generateLinkUri(pubkey, path) {
42
+ return `link://accounts/${pubkey}/${path}`;
43
+ }
44
+ function isValidSha256Hash(hash) {
45
+ return /^[a-f0-9]{64}$/i.test(hash);
46
+ }
47
+ async function verifyBlobContent(uri, value) {
48
+ const parsed = parseBlobUri(uri);
49
+ if (!parsed) {
50
+ const actualHash2 = await computeSha256(value);
51
+ return { valid: false, actualHash: actualHash2, error: "Invalid blob URI format" };
52
+ }
53
+ if (parsed.algorithm !== "sha256") {
54
+ const actualHash2 = await computeSha256(value);
55
+ return { valid: false, actualHash: actualHash2, error: `Unsupported algorithm: ${parsed.algorithm}` };
56
+ }
57
+ const actualHash = await computeSha256(value);
58
+ const valid = actualHash.toLowerCase() === parsed.hash.toLowerCase();
59
+ return {
60
+ valid,
61
+ expectedHash: parsed.hash,
62
+ actualHash,
63
+ error: valid ? void 0 : "Content hash mismatch"
64
+ };
65
+ }
66
+ export {
67
+ computeSha256,
68
+ generateBlobUri,
69
+ generateLinkUri,
70
+ isValidSha256Hash,
71
+ parseBlobUri,
72
+ validateLinkValue,
73
+ verifyBlobContent
74
+ };
@@ -39,23 +39,32 @@ var MemoryClient = class {
39
39
  this.storage = config.storage || /* @__PURE__ */ new Map();
40
40
  this.cleanup();
41
41
  }
42
- async write(uri, payload) {
42
+ /**
43
+ * Receive a transaction - the unified entry point for all state changes
44
+ * @param tx - Transaction tuple [uri, data]
45
+ * @returns ReceiveResult indicating acceptance
46
+ */
47
+ async receive(tx) {
48
+ const [uri, data] = tx;
49
+ if (!uri || typeof uri !== "string") {
50
+ return { accepted: false, error: "Transaction URI is required" };
51
+ }
43
52
  const result = target(uri, this.schema, this.storage);
44
53
  if (!result.success) {
45
- return result;
54
+ return { accepted: false, error: result.error };
46
55
  }
47
56
  const { program, node, parts } = result;
48
57
  const validator = this.schema[program];
49
- const validation = await validator({ uri, value: payload, read: this.read.bind(this) });
58
+ const validation = await validator({ uri, value: data, read: this.read.bind(this) });
50
59
  if (!validation.valid) {
51
60
  return {
52
- success: false,
61
+ accepted: false,
53
62
  error: validation.error || "Validation failed"
54
63
  };
55
64
  }
56
65
  const record = {
57
66
  ts: Date.now(),
58
- data: payload
67
+ data
59
68
  };
60
69
  let prev = node;
61
70
  parts.filter(Boolean).forEach((ns) => {
@@ -69,10 +78,7 @@ var MemoryClient = class {
69
78
  }
70
79
  });
71
80
  prev.value = record;
72
- return {
73
- success: true,
74
- record
75
- };
81
+ return { accepted: true };
76
82
  }
77
83
  read(uri) {
78
84
  const result = target(uri, this.schema, this.storage);
@@ -153,10 +159,21 @@ var MemoryClient = class {
153
159
  }
154
160
  });
155
161
  }
156
- let items = Array.from(current.children.entries()).map(([key, child]) => ({
157
- uri: path.endsWith("/") ? `${program}${path}${key}` : `${program}${path}/${key}`,
158
- type: child.value ? "file" : "directory"
159
- }));
162
+ const prefix = path.endsWith("/") ? `${program}${path}` : `${program}${path}/`;
163
+ let items = [];
164
+ function collectLeaves(node2, currentUri) {
165
+ if (node2.value !== void 0) {
166
+ items.push({ uri: currentUri });
167
+ }
168
+ if (node2.children) {
169
+ for (const [key, child] of node2.children) {
170
+ collectLeaves(child, `${currentUri}/${key}`);
171
+ }
172
+ }
173
+ }
174
+ for (const [key, child] of current.children) {
175
+ collectLeaves(child, `${prefix}${key}`);
176
+ }
160
177
  if (options?.pattern) {
161
178
  const regex = new RegExp(options.pattern);
162
179
  items = items.filter((item) => regex.test(item.uri));
@@ -0,0 +1,43 @@
1
+ // shared/encoding.ts
2
+ function encodeHex(bytes) {
3
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
4
+ }
5
+ function decodeHex(hex) {
6
+ if (hex.length % 2 !== 0) {
7
+ throw new Error("Invalid hex input");
8
+ }
9
+ const buffer = new ArrayBuffer(hex.length / 2);
10
+ const bytes = new Uint8Array(buffer);
11
+ for (let i = 0; i < hex.length; i += 2) {
12
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
13
+ }
14
+ return bytes;
15
+ }
16
+ function encodeBase64(bytes) {
17
+ const buf = typeof globalThis !== "undefined" && globalThis.Buffer || void 0;
18
+ if (buf) {
19
+ return buf.from(bytes).toString("base64");
20
+ }
21
+ let binary = "";
22
+ bytes.forEach((b) => binary += String.fromCharCode(b));
23
+ return btoa(binary);
24
+ }
25
+ function decodeBase64(b64) {
26
+ const buf = typeof globalThis !== "undefined" && globalThis.Buffer || void 0;
27
+ if (buf) {
28
+ return new Uint8Array(buf.from(b64, "base64"));
29
+ }
30
+ const binary = atob(b64);
31
+ const bytes = new Uint8Array(binary.length);
32
+ for (let i = 0; i < binary.length; i++) {
33
+ bytes[i] = binary.charCodeAt(i);
34
+ }
35
+ return bytes;
36
+ }
37
+
38
+ export {
39
+ encodeHex,
40
+ decodeHex,
41
+ encodeBase64,
42
+ decodeBase64
43
+ };
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  MemoryClient,
3
3
  createTestSchema
4
- } from "./chunk-O53KW746.js";
4
+ } from "./chunk-AOAPDYO2.js";
5
5
  import {
6
6
  WalletServerCore
7
- } from "./chunk-7PZMJECC.js";
7
+ } from "./chunk-USNS3YAB.js";
8
8
  import {
9
9
  createAuthenticatedMessageWithHex,
10
10
  exportPrivateKeyPem,
11
11
  generateEncryptionKeyPair,
12
12
  generateSigningKeyPair
13
- } from "./chunk-JN75UL5C.js";
13
+ } from "./chunk-O4U7NQO4.js";
14
14
 
15
15
  // wallet/client.ts
16
16
  var WalletClient = class {
@@ -737,7 +737,7 @@ async function createTestEnvironment(config = {}) {
737
737
  privateKeyHex: keypair.privateKeyHex
738
738
  };
739
739
  const sessionUri = `mutable://accounts/${appKey}/sessions/${sessionKeypair.publicKeyHex}`;
740
- await backend.write(sessionUri, 1);
740
+ await backend.receive([sessionUri, 1]);
741
741
  const session = await wallet.signup(appKey, sessionKeypair, { type: "password", username, password });
742
742
  wallet.setSession(session);
743
743
  const keys = await wallet.getPublicKeys(appKey);
@@ -750,7 +750,7 @@ async function createTestEnvironment(config = {}) {
750
750
  privateKeyHex: keypair.privateKeyHex
751
751
  };
752
752
  const sessionUri = `mutable://accounts/${appKey}/sessions/${sessionKeypair.publicKeyHex}`;
753
- await backend.write(sessionUri, 1);
753
+ await backend.receive([sessionUri, 1]);
754
754
  const session = await wallet.login(appKey, sessionKeypair, { type: "password", username, password });
755
755
  wallet.setSession(session);
756
756
  const keys = await wallet.getPublicKeys(appKey);
@@ -55,29 +55,35 @@ var LocalStorageClient = class {
55
55
  deserialize(data) {
56
56
  return this.config.serializer.deserialize(data);
57
57
  }
58
- async write(uri, value) {
58
+ /**
59
+ * Receive a transaction - the unified entry point for all state changes
60
+ * @param tx - Transaction tuple [uri, data]
61
+ * @returns ReceiveResult indicating acceptance
62
+ */
63
+ async receive(tx) {
64
+ const [uri, data] = tx;
65
+ if (!uri || typeof uri !== "string") {
66
+ return { accepted: false, error: "Transaction URI is required" };
67
+ }
59
68
  try {
60
- const validation = await this.validateWrite(uri, value);
69
+ const validation = await this.validateWrite(uri, data);
61
70
  if (!validation.valid) {
62
71
  return {
63
- success: false,
72
+ accepted: false,
64
73
  error: validation.error || "Validation failed"
65
74
  };
66
75
  }
67
76
  const key = this.getKey(uri);
68
77
  const record = {
69
78
  ts: Date.now(),
70
- data: value
79
+ data
71
80
  };
72
81
  const serialized = this.serialize(record);
73
82
  this.storage.setItem(key, serialized);
74
- return {
75
- success: true,
76
- record
77
- };
83
+ return { accepted: true };
78
84
  } catch (error) {
79
85
  return {
80
- success: false,
86
+ accepted: false,
81
87
  error: error instanceof Error ? error.message : String(error)
82
88
  };
83
89
  }
@@ -140,10 +146,8 @@ var LocalStorageClient = class {
140
146
  if (pattern && !uri2.includes(pattern)) {
141
147
  continue;
142
148
  }
143
- const isDirectory = this.hasChildren(uri2);
144
149
  items.push({
145
- uri: uri2,
146
- type: isDirectory ? "directory" : "file"
150
+ uri: uri2
147
151
  });
148
152
  }
149
153
  }
@@ -1,3 +1,9 @@
1
+ import {
2
+ decodeBase64,
3
+ decodeHex,
4
+ encodeBase64,
5
+ encodeHex
6
+ } from "./chunk-GRCTNUV3.js";
1
7
  import {
2
8
  __export
3
9
  } from "./chunk-MLKGABMK.js";
@@ -32,45 +38,6 @@ __export(mod_exports, {
32
38
  verifyAndDecryptMessage: () => verifyAndDecryptMessage,
33
39
  verifyPayload: () => verifyPayload
34
40
  });
35
-
36
- // shared/encoding.ts
37
- function encodeHex(bytes) {
38
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
39
- }
40
- function decodeHex(hex) {
41
- if (hex.length % 2 !== 0) {
42
- throw new Error("Invalid hex input");
43
- }
44
- const buffer = new ArrayBuffer(hex.length / 2);
45
- const bytes = new Uint8Array(buffer);
46
- for (let i = 0; i < hex.length; i += 2) {
47
- bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
48
- }
49
- return bytes;
50
- }
51
- function encodeBase64(bytes) {
52
- const buf = typeof globalThis !== "undefined" && globalThis.Buffer || void 0;
53
- if (buf) {
54
- return buf.from(bytes).toString("base64");
55
- }
56
- let binary = "";
57
- bytes.forEach((b) => binary += String.fromCharCode(b));
58
- return btoa(binary);
59
- }
60
- function decodeBase64(b64) {
61
- const buf = typeof globalThis !== "undefined" && globalThis.Buffer || void 0;
62
- if (buf) {
63
- return new Uint8Array(buf.from(b64, "base64"));
64
- }
65
- const binary = atob(b64);
66
- const bytes = new Uint8Array(binary.length);
67
- for (let i = 0; i < binary.length; i++) {
68
- bytes[i] = binary.charCodeAt(i);
69
- }
70
- return bytes;
71
- }
72
-
73
- // encrypt/mod.ts
74
41
  var IdentityKey = class _IdentityKey {
75
42
  constructor(privateKey, publicKeyHex) {
76
43
  this.privateKey = privateKey;
@@ -585,8 +552,6 @@ async function createSignedSymmetricMessage(data, signers, keyHex) {
585
552
  }
586
553
 
587
554
  export {
588
- encodeHex,
589
- decodeHex,
590
555
  IdentityKey,
591
556
  PublicEncryptionKey,
592
557
  SecretEncryptionKey,
@@ -1,15 +1,17 @@
1
1
  import {
2
2
  createAuthenticatedMessage,
3
3
  createSignedEncryptedMessage,
4
- decodeHex,
5
4
  decrypt,
6
- encodeHex,
7
5
  encrypt,
8
6
  verifyPayload
9
- } from "./chunk-JN75UL5C.js";
7
+ } from "./chunk-O4U7NQO4.js";
10
8
  import {
11
9
  HttpClient
12
- } from "./chunk-32YBATXQ.js";
10
+ } from "./chunk-WTXWILQE.js";
11
+ import {
12
+ decodeHex,
13
+ encodeHex
14
+ } from "./chunk-GRCTNUV3.js";
13
15
 
14
16
  // wallet-server/interfaces.ts
15
17
  var defaultLogger = {
@@ -285,10 +287,10 @@ async function generateUserKeys(client, serverPublicKey, username, serverIdentit
285
287
  serverIdentityPublicKeyHex,
286
288
  serverEncryptionPublicKeyHex
287
289
  );
288
- await client.write(
290
+ await client.receive([
289
291
  `mutable://accounts/${serverPublicKey}/${path}`,
290
292
  signed
291
- );
293
+ ]);
292
294
  })(),
293
295
  (async () => {
294
296
  const path = await deriveObfuscatedPath(
@@ -302,10 +304,10 @@ async function generateUserKeys(client, serverPublicKey, username, serverIdentit
302
304
  serverIdentityPublicKeyHex,
303
305
  serverEncryptionPublicKeyHex
304
306
  );
305
- await client.write(
307
+ await client.receive([
306
308
  `mutable://accounts/${serverPublicKey}/${path}`,
307
309
  signed
308
- );
310
+ ]);
309
311
  })()
310
312
  ]);
311
313
  return { accountKey, encryptionKey };
@@ -427,8 +429,8 @@ async function proxyWrite(proxyClient, credentialClient, serverPublicKey, userna
427
429
  } else {
428
430
  signedMessage = await createAuthenticatedMessage(request.data, [signer]);
429
431
  }
430
- const result = await proxyClient.write(resolvedUri, signedMessage);
431
- if (!result.success) {
432
+ const result = await proxyClient.receive([resolvedUri, signedMessage]);
433
+ if (!result.accepted) {
432
434
  return {
433
435
  success: false,
434
436
  error: result.error || "Write failed"
@@ -436,8 +438,7 @@ async function proxyWrite(proxyClient, credentialClient, serverPublicKey, userna
436
438
  }
437
439
  return {
438
440
  success: true,
439
- resolvedUri,
440
- record: result.record
441
+ resolvedUri
441
442
  };
442
443
  } catch (error) {
443
444
  return {
@@ -657,10 +658,10 @@ async function createUser(client, serverPublicKey, username, password, serverIde
657
658
  serverIdentityPublicKeyHex,
658
659
  serverEncryptionPublicKeyHex
659
660
  );
660
- await client.write(
661
+ await client.receive([
661
662
  `mutable://accounts/${serverPublicKey}/${profilePath}`,
662
663
  profileSigned
663
- );
664
+ ]);
664
665
  const passwordPath = await deriveObfuscatedPath(
665
666
  serverPublicKey,
666
667
  username,
@@ -674,10 +675,10 @@ async function createUser(client, serverPublicKey, username, password, serverIde
674
675
  serverIdentityPublicKeyHex,
675
676
  serverEncryptionPublicKeyHex
676
677
  );
677
- await client.write(
678
+ await client.receive([
678
679
  `mutable://accounts/${serverPublicKey}/${passwordPath}`,
679
680
  passwordSigned
680
- );
681
+ ]);
681
682
  return { salt, hash };
682
683
  }
683
684
  async function authenticateUser(client, serverPublicKey, username, password, serverEncryptionPrivateKeyPem, appScope, logger) {
@@ -733,10 +734,10 @@ async function changePassword(client, serverPublicKey, username, oldPassword, ne
733
734
  serverIdentityPublicKeyHex,
734
735
  serverEncryptionPublicKeyHex
735
736
  );
736
- await client.write(
737
+ await client.receive([
737
738
  `mutable://accounts/${serverPublicKey}/${passwordPath}`,
738
739
  passwordSigned
739
- );
740
+ ]);
740
741
  }
741
742
  async function createPasswordResetToken(client, serverPublicKey, username, ttlSeconds, serverIdentityPrivateKeyPem, serverIdentityPublicKeyHex, serverEncryptionPublicKeyHex, appScope) {
742
743
  if (!await userExists(client, serverPublicKey, username)) {
@@ -764,10 +765,10 @@ async function createPasswordResetToken(client, serverPublicKey, username, ttlSe
764
765
  serverIdentityPublicKeyHex,
765
766
  serverEncryptionPublicKeyHex
766
767
  );
767
- await client.write(
768
+ await client.receive([
768
769
  `mutable://accounts/${serverPublicKey}/${tokenPath}`,
769
770
  tokenSigned
770
- );
771
+ ]);
771
772
  return token;
772
773
  }
773
774
  async function resetPasswordWithToken(client, serverPublicKey, token, newPassword, serverIdentityPrivateKeyPem, serverIdentityPublicKeyHex, serverEncryptionPublicKeyHex, serverEncryptionPrivateKeyPem, username, appScope, logger) {
@@ -816,10 +817,10 @@ async function resetPasswordWithToken(client, serverPublicKey, token, newPasswor
816
817
  serverIdentityPublicKeyHex,
817
818
  serverEncryptionPublicKeyHex
818
819
  );
819
- await client.write(
820
+ await client.receive([
820
821
  `mutable://accounts/${serverPublicKey}/${passwordPath}`,
821
822
  passwordSigned
822
- );
823
+ ]);
823
824
  await client.delete(`mutable://accounts/${serverPublicKey}/${tokenPath}`);
824
825
  return tokenUsername;
825
826
  }
@@ -863,10 +864,10 @@ async function createGoogleUser(client, serverPublicKey, username, googlePayload
863
864
  serverIdentityPublicKeyHex,
864
865
  serverEncryptionPublicKeyHex
865
866
  );
866
- await client.write(
867
+ await client.receive([
867
868
  `mutable://accounts/${serverPublicKey}/${profilePath}`,
868
869
  profileSigned
869
- );
870
+ ]);
870
871
  const googleProfilePath = await deriveObfuscatedPath(
871
872
  serverPublicKey,
872
873
  googlePayload.sub,
@@ -885,10 +886,10 @@ async function createGoogleUser(client, serverPublicKey, username, googlePayload
885
886
  serverIdentityPublicKeyHex,
886
887
  serverEncryptionPublicKeyHex
887
888
  );
888
- await client.write(
889
+ await client.receive([
889
890
  `mutable://accounts/${serverPublicKey}/${googleProfilePath}`,
890
891
  googleProfileSigned
891
- );
892
+ ]);
892
893
  return { username, googleSub: googlePayload.sub };
893
894
  }
894
895
  async function authenticateGoogleUser(client, serverPublicKey, googleSub, serverEncryptionPrivateKeyPem, appScope, logger) {
@@ -1,4 +1,14 @@
1
+ import {
2
+ encodeBase64
3
+ } from "./chunk-GRCTNUV3.js";
4
+
1
5
  // clients/http/mod.ts
6
+ function serializeTxData(data) {
7
+ if (data instanceof Uint8Array) {
8
+ return { __b3nd_binary__: true, encoding: "base64", data: encodeBase64(data) };
9
+ }
10
+ return data;
11
+ }
2
12
  var HttpClient = class {
3
13
  constructor(config) {
4
14
  this.baseUrl = config.url.replace(/\/$/, "");
@@ -44,34 +54,38 @@ var HttpClient = class {
44
54
  path: url.pathname
45
55
  };
46
56
  }
47
- async write(uri, value) {
57
+ /**
58
+ * Receive a transaction (unified Node interface)
59
+ * POSTs to /api/v1/receive endpoint
60
+ * @param tx - Transaction tuple [uri, data]
61
+ * @returns ReceiveResult indicating acceptance
62
+ */
63
+ async receive(tx) {
64
+ const [uri] = tx;
65
+ if (!uri || typeof uri !== "string") {
66
+ return { accepted: false, error: "Transaction URI is required" };
67
+ }
48
68
  try {
49
- const { protocol, domain, path } = this.parseUri(uri);
50
- const requestPath = `/api/v1/write/${protocol}/${domain}${path}`;
51
- const isBinary = value instanceof Uint8Array;
52
- const body = isBinary ? value : JSON.stringify({ value });
53
- const contentType = isBinary ? "application/octet-stream" : "application/json";
54
- const response = await this.request(requestPath, {
69
+ const [uri2, data] = tx;
70
+ const serializedTx = [uri2, serializeTxData(data)];
71
+ const response = await this.request("/api/v1/receive", {
55
72
  method: "POST",
56
- body,
57
- headers: {
58
- "Content-Type": contentType
59
- }
73
+ body: JSON.stringify({ tx: serializedTx })
60
74
  });
61
75
  const result = await response.json();
62
76
  if (!response.ok) {
63
77
  return {
64
- success: false,
65
- error: `Write failed: ${result.error || response.statusText}`
78
+ accepted: false,
79
+ error: result.error || response.statusText
66
80
  };
67
81
  }
68
82
  return {
69
- success: true,
70
- record: result.record
83
+ accepted: result.accepted ?? true,
84
+ error: result.error
71
85
  };
72
86
  } catch (error) {
73
87
  return {
74
- success: false,
88
+ accepted: false,
75
89
  error: error instanceof Error ? error.message : String(error)
76
90
  };
77
91
  }
@@ -1,3 +1,35 @@
1
+ // src/binary.ts
2
+ var BINARY_MARKER = "__b3nd_binary__";
3
+ function isEncodedBinary(value) {
4
+ return typeof value === "object" && value !== null && BINARY_MARKER in value && value[BINARY_MARKER] === true;
5
+ }
6
+ function encodeBinaryForJson(value) {
7
+ if (value instanceof Uint8Array) {
8
+ return {
9
+ [BINARY_MARKER]: true,
10
+ data: btoa(String.fromCharCode(...value))
11
+ };
12
+ }
13
+ if (value instanceof ArrayBuffer) {
14
+ return {
15
+ [BINARY_MARKER]: true,
16
+ data: btoa(String.fromCharCode(...new Uint8Array(value)))
17
+ };
18
+ }
19
+ return value;
20
+ }
21
+ function decodeBinaryFromJson(value) {
22
+ if (isEncodedBinary(value)) {
23
+ const binary = atob(value.data);
24
+ const bytes = new Uint8Array(binary.length);
25
+ for (let i = 0; i < binary.length; i++) {
26
+ bytes[i] = binary.charCodeAt(i);
27
+ }
28
+ return bytes;
29
+ }
30
+ return value;
31
+ }
32
+
1
33
  // clients/websocket/mod.ts
2
34
  var WebSocketClient = class {
3
35
  constructor(config) {
@@ -173,13 +205,24 @@ var WebSocketClient = class {
173
205
  }
174
206
  });
175
207
  }
176
- async write(uri, value) {
208
+ /**
209
+ * Receive a transaction (unified Node interface)
210
+ * Sends "receive" message type with { tx } payload
211
+ * @param tx - Transaction tuple [uri, data]
212
+ * @returns ReceiveResult indicating acceptance
213
+ */
214
+ async receive(tx) {
215
+ const [uri] = tx;
216
+ if (!uri || typeof uri !== "string") {
217
+ return { accepted: false, error: "Transaction URI is required" };
218
+ }
177
219
  try {
178
- const result = await this.sendRequest("write", { uri, value });
220
+ const encodedTx = [uri, encodeBinaryForJson(tx[1])];
221
+ const result = await this.sendRequest("receive", { tx: encodedTx });
179
222
  return result;
180
223
  } catch (error) {
181
224
  return {
182
- success: false,
225
+ accepted: false,
183
226
  error: error instanceof Error ? error.message : String(error)
184
227
  };
185
228
  }
@@ -187,6 +230,9 @@ var WebSocketClient = class {
187
230
  async read(uri) {
188
231
  try {
189
232
  const result = await this.sendRequest("read", { uri });
233
+ if (result.success && result.record) {
234
+ result.record.data = decodeBinaryFromJson(result.record.data);
235
+ }
190
236
  return result;
191
237
  } catch (error) {
192
238
  return {
@@ -1,4 +1,5 @@
1
- import { N as NodeProtocolInterface, a as HttpClientConfig, g as WriteResult, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-uuvn4oKw.js';
1
+ import { N as NodeProtocolInterface, a as HttpClientConfig, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-72HsU7WT.js';
2
+ import { N as Node, T as Transaction, R as ReceiveResult } from '../../types-CdHovjru.js';
2
3
 
3
4
  /**
4
5
  * HttpClient - HTTP implementation of NodeProtocolInterface
@@ -7,7 +8,7 @@ import { N as NodeProtocolInterface, a as HttpClientConfig, g as WriteResult, R
7
8
  * No schema validation - validation happens server-side.
8
9
  */
9
10
 
10
- declare class HttpClient implements NodeProtocolInterface {
11
+ declare class HttpClient implements NodeProtocolInterface, Node {
11
12
  private baseUrl;
12
13
  private headers;
13
14
  private timeout;
@@ -21,7 +22,13 @@ declare class HttpClient implements NodeProtocolInterface {
21
22
  * Example: "users://alice/profile" -> { protocol: "users", domain: "alice", path: "/profile" }
22
23
  */
23
24
  private parseUri;
24
- write<T = unknown>(uri: string, value: T): Promise<WriteResult<T>>;
25
+ /**
26
+ * Receive a transaction (unified Node interface)
27
+ * POSTs to /api/v1/receive endpoint
28
+ * @param tx - Transaction tuple [uri, data]
29
+ * @returns ReceiveResult indicating acceptance
30
+ */
31
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
25
32
  read<T = unknown>(uri: string): Promise<ReadResult<T>>;
26
33
  readMulti<T = unknown>(uris: string[]): Promise<ReadMultiResult<T>>;
27
34
  private readMultiFallback;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  HttpClient
3
- } from "../../chunk-32YBATXQ.js";
3
+ } from "../../chunk-WTXWILQE.js";
4
+ import "../../chunk-GRCTNUV3.js";
4
5
  import "../../chunk-MLKGABMK.js";
5
6
  export {
6
7
  HttpClient
@@ -1,4 +1,5 @@
1
- import { N as NodeProtocolInterface, d as LocalStorageClientConfig, g as WriteResult, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-uuvn4oKw.js';
1
+ import { N as NodeProtocolInterface, d as LocalStorageClientConfig, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-72HsU7WT.js';
2
+ import { N as Node, T as Transaction, R as ReceiveResult } from '../../types-CdHovjru.js';
2
3
 
3
4
  /**
4
5
  * LocalStorageClient - Browser localStorage implementation of NodeProtocolInterface
@@ -7,7 +8,7 @@ import { N as NodeProtocolInterface, d as LocalStorageClientConfig, g as WriteRe
7
8
  * Supports schema validation and custom serialization.
8
9
  */
9
10
 
10
- declare class LocalStorageClient implements NodeProtocolInterface {
11
+ declare class LocalStorageClient implements NodeProtocolInterface, Node {
11
12
  private config;
12
13
  private schema;
13
14
  private storage;
@@ -32,7 +33,12 @@ declare class LocalStorageClient implements NodeProtocolInterface {
32
33
  * Deserialize data using configured serializer
33
34
  */
34
35
  private deserialize;
35
- write<T = unknown>(uri: string, value: T): Promise<WriteResult<T>>;
36
+ /**
37
+ * Receive a transaction - the unified entry point for all state changes
38
+ * @param tx - Transaction tuple [uri, data]
39
+ * @returns ReceiveResult indicating acceptance
40
+ */
41
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
36
42
  read<T = unknown>(uri: string): Promise<ReadResult<T>>;
37
43
  readMulti<T = unknown>(uris: string[]): Promise<ReadMultiResult<T>>;
38
44
  list(uri: string, options?: ListOptions): Promise<ListResult>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LocalStorageClient
3
- } from "../../chunk-PZFEKQ7F.js";
3
+ } from "../../chunk-LW6IWHDJ.js";
4
4
  import "../../chunk-MLKGABMK.js";
5
5
  export {
6
6
  LocalStorageClient
@@ -1,4 +1,5 @@
1
- import { N as NodeProtocolInterface, S as Schema, g as WriteResult, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, H as HealthStatus, D as DeleteResult } from '../../types-uuvn4oKw.js';
1
+ import { N as NodeProtocolInterface, S as Schema, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, H as HealthStatus, D as DeleteResult } from '../../types-72HsU7WT.js';
2
+ import { N as Node, T as Transaction, R as ReceiveResult } from '../../types-CdHovjru.js';
2
3
 
3
4
  type MemoryClientStorageNode<T> = {
4
5
  value?: T;
@@ -24,7 +25,7 @@ interface MemoryClientConfig {
24
25
  schema: Schema;
25
26
  storage?: MemoryClientStorage;
26
27
  }
27
- declare class MemoryClient implements NodeProtocolInterface {
28
+ declare class MemoryClient implements NodeProtocolInterface, Node {
28
29
  protected storage: MemoryClientStorage;
29
30
  protected schema: Schema;
30
31
  /**
@@ -34,7 +35,12 @@ declare class MemoryClient implements NodeProtocolInterface {
34
35
  * @throws Error if schema keys are not in "protocol://hostname" format
35
36
  */
36
37
  constructor(config: MemoryClientConfig);
37
- write<T = unknown>(uri: string, payload: T): Promise<WriteResult<T>>;
38
+ /**
39
+ * Receive a transaction - the unified entry point for all state changes
40
+ * @param tx - Transaction tuple [uri, data]
41
+ * @returns ReceiveResult indicating acceptance
42
+ */
43
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
38
44
  read<T>(uri: string): Promise<ReadResult<T>>;
39
45
  readMulti<T = unknown>(uris: string[]): Promise<ReadMultiResult<T>>;
40
46
  list(uri: string, options?: ListOptions): Promise<ListResult>;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MemoryClient,
3
3
  createTestSchema
4
- } from "../../chunk-O53KW746.js";
4
+ } from "../../chunk-AOAPDYO2.js";
5
5
  import "../../chunk-MLKGABMK.js";
6
6
  export {
7
7
  MemoryClient,
@@ -1,4 +1,5 @@
1
- import { N as NodeProtocolInterface, W as WebSocketClientConfig, g as WriteResult, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-uuvn4oKw.js';
1
+ import { N as NodeProtocolInterface, W as WebSocketClientConfig, R as ReadResult, h as ReadMultiResult, b as ListOptions, c as ListResult, D as DeleteResult, H as HealthStatus } from '../../types-72HsU7WT.js';
2
+ import { N as Node, T as Transaction, R as ReceiveResult } from '../../types-CdHovjru.js';
2
3
 
3
4
  /**
4
5
  * WebSocketClient - WebSocket implementation of NodeProtocolInterface
@@ -7,7 +8,7 @@ import { N as NodeProtocolInterface, W as WebSocketClientConfig, g as WriteResul
7
8
  * Handles reconnection and connection pooling.
8
9
  */
9
10
 
10
- declare class WebSocketClient implements NodeProtocolInterface {
11
+ declare class WebSocketClient implements NodeProtocolInterface, Node {
11
12
  private config;
12
13
  private ws;
13
14
  private connected;
@@ -50,7 +51,13 @@ declare class WebSocketClient implements NodeProtocolInterface {
50
51
  * Send request and wait for response
51
52
  */
52
53
  private sendRequest;
53
- write<T = unknown>(uri: string, value: T): Promise<WriteResult<T>>;
54
+ /**
55
+ * Receive a transaction (unified Node interface)
56
+ * Sends "receive" message type with { tx } payload
57
+ * @param tx - Transaction tuple [uri, data]
58
+ * @returns ReceiveResult indicating acceptance
59
+ */
60
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
54
61
  read<T = unknown>(uri: string): Promise<ReadResult<T>>;
55
62
  readMulti<T = unknown>(uris: string[]): Promise<ReadMultiResult<T>>;
56
63
  list(uri: string, options?: ListOptions): Promise<ListResult>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  WebSocketClient
3
- } from "../../chunk-UUHVOWVI.js";
3
+ } from "../../chunk-ZONW4WJ2.js";
4
4
  import "../../chunk-MLKGABMK.js";
5
5
  export {
6
6
  WebSocketClient
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { N as NodeProtocolInterface } from './types-uuvn4oKw.js';
2
+ import { N as NodeProtocolInterface } from './types-72HsU7WT.js';
3
3
 
4
4
  /**
5
5
  * Wallet Server Dependency Injection Interfaces
@@ -25,7 +25,8 @@ import {
25
25
  verify,
26
26
  verifyAndDecryptMessage,
27
27
  verifyPayload
28
- } from "../chunk-JN75UL5C.js";
28
+ } from "../chunk-O4U7NQO4.js";
29
+ import "../chunk-GRCTNUV3.js";
29
30
  import "../chunk-MLKGABMK.js";
30
31
  export {
31
32
  IdentityKey,
@@ -1,7 +1,8 @@
1
- export { C as ClientError, D as DeleteResult, H as HealthStatus, a as HttpClientConfig, L as ListItem, b as ListOptions, c as ListResult, d as LocalStorageClientConfig, N as NodeProtocolInterface, P as PersistenceRecord, R as ReadResult, S as Schema, V as ValidationFn, W as WebSocketClientConfig, e as WebSocketRequest, f as WebSocketResponse, g as WriteResult } from '../types-uuvn4oKw.js';
1
+ export { C as ClientError, D as DeleteResult, H as HealthStatus, a as HttpClientConfig, L as ListItem, b as ListOptions, c as ListResult, d as LocalStorageClientConfig, N as NodeProtocolInterface, P as PersistenceRecord, R as ReadResult, S as Schema, V as ValidationFn, W as WebSocketClientConfig, e as WebSocketRequest, f as WebSocketResponse, g as WriteResult } from '../types-72HsU7WT.js';
2
2
  export { HttpClient } from '../clients/http/mod.js';
3
3
  export { WebSocketClient } from '../clients/websocket/mod.js';
4
4
  export { LocalStorageClient } from '../clients/local-storage/mod.js';
5
5
  export { W as WalletClient } from '../client-DHCiJ9I7.js';
6
6
  export { AppsClient } from '../apps/mod.js';
7
7
  export { m as encrypt } from '../mod-CII9wqu2.js';
8
+ import '../types-CdHovjru.js';
@@ -1,23 +1,24 @@
1
+ import {
2
+ WebSocketClient
3
+ } from "../chunk-ZONW4WJ2.js";
1
4
  import {
2
5
  AppsClient
3
6
  } from "../chunk-VAZUCGED.js";
4
7
  import {
5
8
  WalletClient
6
- } from "../chunk-3U3TYM34.js";
7
- import "../chunk-O53KW746.js";
8
- import "../chunk-7PZMJECC.js";
9
+ } from "../chunk-KX2UV5B6.js";
10
+ import "../chunk-AOAPDYO2.js";
11
+ import "../chunk-USNS3YAB.js";
9
12
  import {
10
13
  mod_exports
11
- } from "../chunk-JN75UL5C.js";
14
+ } from "../chunk-O4U7NQO4.js";
12
15
  import {
13
16
  HttpClient
14
- } from "../chunk-32YBATXQ.js";
17
+ } from "../chunk-WTXWILQE.js";
18
+ import "../chunk-GRCTNUV3.js";
15
19
  import {
16
20
  LocalStorageClient
17
- } from "../chunk-PZFEKQ7F.js";
18
- import {
19
- WebSocketClient
20
- } from "../chunk-UUHVOWVI.js";
21
+ } from "../chunk-LW6IWHDJ.js";
21
22
  import "../chunk-MLKGABMK.js";
22
23
  export {
23
24
  AppsClient,
@@ -64,7 +64,6 @@ interface DeleteResult {
64
64
  */
65
65
  interface ListItem {
66
66
  uri: string;
67
- type: "file" | "directory";
68
67
  }
69
68
  /**
70
69
  * Options for list operations
@@ -115,6 +114,17 @@ type ValidationFn = (write: {
115
114
  * Schema mapping program keys to validation functions
116
115
  */
117
116
  type Schema = Record<string, ValidationFn>;
117
+ /**
118
+ * Result of a receive operation
119
+ */
120
+ interface ReceiveResult {
121
+ accepted: boolean;
122
+ error?: string;
123
+ }
124
+ /**
125
+ * Transaction type (re-exported from node/types.ts)
126
+ */
127
+ type Transaction<D = unknown> = [uri: string, data: D];
118
128
  /**
119
129
  * NodeProtocolInterface - The universal interface implemented by all clients
120
130
  *
@@ -122,8 +132,8 @@ type Schema = Record<string, ValidationFn>;
122
132
  * implement this interface, enabling recursive composition and uniform usage.
123
133
  */
124
134
  interface NodeProtocolWriteInterface {
125
- /** Write data to a URI */
126
- write<T = unknown>(uri: string, value: T): Promise<WriteResult<T>>;
135
+ /** Receive a transaction - the unified entry point for all state changes */
136
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
127
137
  /** Delete data at a URI */
128
138
  delete(uri: string): Promise<DeleteResult>;
129
139
  /** Health status */
@@ -240,7 +250,7 @@ declare class ClientError extends Error {
240
250
  */
241
251
  interface WebSocketRequest {
242
252
  id: string;
243
- type: "write" | "read" | "readMulti" | "list" | "delete" | "health" | "getSchema";
253
+ type: "receive" | "read" | "readMulti" | "list" | "delete" | "health" | "getSchema";
244
254
  payload: unknown;
245
255
  }
246
256
  interface WebSocketResponse {
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @module
3
+ * B3nd Unified Node Type System
4
+ *
5
+ * Core types for the unified node architecture where all state changes
6
+ * flow through a single `receive(tx)` interface.
7
+ */
8
+
9
+ /**
10
+ * Transaction: the minimal primitive
11
+ *
12
+ * A tuple of [uri, data]. URIs all the way down.
13
+ * The URI is the transaction's identity. The data is the transaction's content.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // A user transaction
18
+ * const tx: Transaction = ["mutable://users/alice/profile", { name: "Alice" }]
19
+ *
20
+ * // A transfer transaction
21
+ * const tx: Transaction = ["txn://alice/transfer/42", { inputs: [...], outputs: [...] }]
22
+ * ```
23
+ */
24
+ type Transaction<D = unknown> = [uri: string, data: D];
25
+ /**
26
+ * Result of a receive operation
27
+ */
28
+ interface ReceiveResult {
29
+ accepted: boolean;
30
+ error?: string;
31
+ }
32
+ /**
33
+ * Unified Node interface
34
+ *
35
+ * The single entry point for all state changes. Nodes receive transactions
36
+ * and decide what to do with them based on their configuration.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const node: Node = createNode({
41
+ * read: memoryClient,
42
+ * validate: schema(SCHEMA),
43
+ * process: store(memoryClient)
44
+ * })
45
+ *
46
+ * const result = await node.receive(["mutable://users/alice", { name: "Alice" }])
47
+ * ```
48
+ */
49
+ interface Node {
50
+ receive<D = unknown>(tx: Transaction<D>): Promise<ReceiveResult>;
51
+ cleanup(): Promise<void>;
52
+ }
53
+
54
+ export type { Node as N, ReceiveResult as R, Transaction as T };
@@ -1,9 +1,10 @@
1
1
  import { A as AuthSession, H as HealthResponse, S as SessionKeypair, U as UserCredentials, P as PasswordResetToken, a as UserPublicKeys, b as ProxyWriteRequest, c as ProxyWriteResponse, d as ProxyReadRequest, e as ProxyReadResponse, f as ProxyReadMultiRequest, g as ProxyReadMultiResponse } from '../client-DHCiJ9I7.js';
2
2
  export { l as ApiResponse, C as ChangePasswordResponse, G as GoogleAuthSession, q as GoogleLoginResponse, p as GoogleSignupResponse, L as LoginResponse, k as ProxyReadMultiResultItem, n as PublicKeysResponse, R as RequestPasswordResetResponse, o as ResetPasswordResponse, m as SignupResponse, W as WalletClient, j as WalletClientConfig, i as WalletClientInterface, h as generateSessionKeypair } from '../client-DHCiJ9I7.js';
3
- import { N as NodeProtocolInterface, S as Schema } from '../types-uuvn4oKw.js';
4
- import { S as ServerKeys, W as WalletServerCore } from '../core-BGUpkKnP.js';
3
+ import { N as NodeProtocolInterface, S as Schema } from '../types-72HsU7WT.js';
4
+ import { S as ServerKeys, W as WalletServerCore } from '../core-euL00biT.js';
5
5
  import { MemoryClient } from '../clients/memory/mod.js';
6
6
  import 'hono';
7
+ import '../types-CdHovjru.js';
7
8
 
8
9
  /**
9
10
  * Memory Wallet Client
@@ -59,7 +60,7 @@ interface MemoryWalletClientConfig {
59
60
  * const wallet = await MemoryWalletClient.create({ backend });
60
61
  *
61
62
  * // Both use the same storage
62
- * await backend.write("mutable://accounts/...", data);
63
+ * await backend.receive(["mutable://accounts/...", data]);
63
64
  * await wallet.proxyWrite({ uri: "mutable://...", data });
64
65
  * ```
65
66
  */
@@ -4,11 +4,12 @@ import {
4
4
  createTestEnvironment,
5
5
  generateSessionKeypair,
6
6
  generateTestServerKeys
7
- } from "../chunk-3U3TYM34.js";
8
- import "../chunk-O53KW746.js";
9
- import "../chunk-7PZMJECC.js";
10
- import "../chunk-JN75UL5C.js";
11
- import "../chunk-32YBATXQ.js";
7
+ } from "../chunk-KX2UV5B6.js";
8
+ import "../chunk-AOAPDYO2.js";
9
+ import "../chunk-USNS3YAB.js";
10
+ import "../chunk-O4U7NQO4.js";
11
+ import "../chunk-WTXWILQE.js";
12
+ import "../chunk-GRCTNUV3.js";
12
13
  import "../chunk-MLKGABMK.js";
13
14
  export {
14
15
  MemoryWalletClient,
@@ -1,7 +1,7 @@
1
- import { F as FileStorage, S as ServerKeys, W as WalletServerCore } from '../../core-BGUpkKnP.js';
2
- export { C as BrowserEnvironment, M as BrowserMemoryStorage } from '../../core-BGUpkKnP.js';
1
+ import { F as FileStorage, S as ServerKeys, W as WalletServerCore } from '../../core-euL00biT.js';
2
+ export { C as BrowserEnvironment, M as BrowserMemoryStorage } from '../../core-euL00biT.js';
3
3
  import 'hono';
4
- import '../../types-uuvn4oKw.js';
4
+ import '../../types-72HsU7WT.js';
5
5
 
6
6
  /**
7
7
  * Browser Adapter for Wallet Server
@@ -2,12 +2,13 @@ import {
2
2
  ConfigEnvironment,
3
3
  MemoryFileStorage,
4
4
  WalletServerCore
5
- } from "../../chunk-7PZMJECC.js";
6
- import "../../chunk-JN75UL5C.js";
7
- import "../../chunk-32YBATXQ.js";
5
+ } from "../../chunk-USNS3YAB.js";
6
+ import "../../chunk-O4U7NQO4.js";
7
+ import "../../chunk-WTXWILQE.js";
8
+ import "../../chunk-GRCTNUV3.js";
8
9
  import {
9
10
  LocalStorageClient
10
- } from "../../chunk-PZFEKQ7F.js";
11
+ } from "../../chunk-LW6IWHDJ.js";
11
12
  import "../../chunk-MLKGABMK.js";
12
13
 
13
14
  // wallet-server/adapters/browser.ts
@@ -1,6 +1,6 @@
1
- import { P as ProxyWriteRequest, a as ProxyWriteResponse, b as ProxyReadResponse, U as UserKeys, L as Logger, H as HttpFetch } from '../core-BGUpkKnP.js';
2
- export { A as AppBackendConfig, f as AuthSessionResponse, C as ConfigEnvironment, E as Environment, F as FileStorage, h as HealthResponse, M as MemoryFileStorage, g as PublicKeysResponse, R as ResolvedWalletServerConfig, e as ServerKeyPair, S as ServerKeys, i as ServerKeysResponse, c as WalletServerConfig, W as WalletServerCore, d as WalletServerDeps, j as defaultLogger } from '../core-BGUpkKnP.js';
3
- import { N as NodeProtocolInterface } from '../types-uuvn4oKw.js';
1
+ import { P as ProxyWriteRequest, a as ProxyWriteResponse, b as ProxyReadResponse, U as UserKeys, L as Logger, H as HttpFetch } from '../core-euL00biT.js';
2
+ export { A as AppBackendConfig, f as AuthSessionResponse, C as ConfigEnvironment, E as Environment, F as FileStorage, h as HealthResponse, M as MemoryFileStorage, g as PublicKeysResponse, R as ResolvedWalletServerConfig, e as ServerKeyPair, S as ServerKeys, i as ServerKeysResponse, c as WalletServerConfig, W as WalletServerCore, d as WalletServerDeps, j as defaultLogger } from '../core-euL00biT.js';
3
+ import { N as NodeProtocolInterface } from '../types-72HsU7WT.js';
4
4
  import { S as SignedEncryptedMessage, E as EncryptedPayload } from '../mod-CII9wqu2.js';
5
5
  import 'hono';
6
6
 
@@ -34,9 +34,10 @@ import {
34
34
  userExists,
35
35
  verifyGoogleIdToken,
36
36
  verifyJwt
37
- } from "../chunk-7PZMJECC.js";
38
- import "../chunk-JN75UL5C.js";
39
- import "../chunk-32YBATXQ.js";
37
+ } from "../chunk-USNS3YAB.js";
38
+ import "../chunk-O4U7NQO4.js";
39
+ import "../chunk-WTXWILQE.js";
40
+ import "../chunk-GRCTNUV3.js";
40
41
  import "../chunk-MLKGABMK.js";
41
42
  export {
42
43
  ConfigEnvironment,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bandeira-tech/b3nd-web",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Browser-focused B3nd SDK bundle",
5
5
  "type": "module",
6
6
  "main": "./dist/src/mod.web.js",
@@ -39,6 +39,10 @@
39
39
  "import": "./dist/apps/mod.js",
40
40
  "types": "./dist/apps/mod.d.ts"
41
41
  },
42
+ "./blob": {
43
+ "import": "./dist/blob/mod.js",
44
+ "types": "./dist/blob/mod.d.ts"
45
+ },
42
46
  "./wallet-server": {
43
47
  "import": "./dist/wallet-server/mod.js",
44
48
  "types": "./dist/wallet-server/mod.d.ts"
@@ -52,7 +56,7 @@
52
56
  "dist"
53
57
  ],
54
58
  "scripts": {
55
- "build": "tsup src/mod.web.ts wallet/mod.ts apps/mod.ts encrypt/mod.ts clients/http/mod.ts clients/local-storage/mod.ts clients/websocket/mod.ts clients/memory/mod.ts wallet-server/mod.ts wallet-server/adapters/browser.ts --dts --format esm --out-dir dist --clean --tsconfig tsconfig.web.json",
59
+ "build": "tsup src/mod.web.ts wallet/mod.ts apps/mod.ts encrypt/mod.ts blob/mod.ts clients/http/mod.ts clients/local-storage/mod.ts clients/websocket/mod.ts clients/memory/mod.ts wallet-server/mod.ts wallet-server/adapters/browser.ts --dts --format esm --out-dir dist --clean --tsconfig tsconfig.web.json",
56
60
  "clean": "rm -rf dist",
57
61
  "lint": "deno lint src/",
58
62
  "format": "deno fmt src/"