@reallyme/codec 0.2.3 → 0.3.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.
package/NOTICE CHANGED
@@ -1,5 +1,3 @@
1
- SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2
-
3
1
  ReallyMe Codec
4
2
  Copyright © 2026 ReallyMe LLC. All rights reserved.
5
3
 
package/README.md CHANGED
@@ -1,7 +1,3 @@
1
- <!--
2
- SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
3
- -->
4
-
5
1
  # @reallyme/codec
6
2
 
7
3
  `@reallyme/codec` is the TypeScript package for the Rust `reallyme-codec`
@@ -37,13 +33,16 @@ const encoded = ReallyMeCodec.base64urlEncode(new Uint8Array([1, 2, 3]));
37
33
  const decoded = ReallyMeCodec.base64urlDecode(encoded);
38
34
  ```
39
35
 
36
+ The installer accepts only this package's generated WASM module namespace.
37
+ Initialize that module with the bundled `.wasm` file before installing it.
38
+
40
39
  ## Surface
41
40
 
42
41
  | Family | APIs |
43
42
  |---|---|
44
43
  | Base encodings | `base64Encode`, `base64Decode`, `base64urlEncode`, `base64urlDecode`, `base64urlDecodeBytes`, `bytesToLowerHex`, `lowerHexToBytes` |
45
44
  | Multiformats | `base58btcEncode`, `base58btcDecode`, `multibase*`, `multicodec*`, `multikey*`, binding validation |
46
- | Deterministic CBOR | typed `deterministicCborEncode` and `deterministicCborDecode` for the bounded RFC 8949 profile |
45
+ | Deterministic CBOR | typed `deterministicCborEncode` and `deterministicCborDecode` for the bounded RFC 8949 §4.2.3 length-first profile |
47
46
  | DAG-CBOR and CID | `dagCborEncode`, `dagCborDecode`, `dagCborComputeCid`, `dagCborVerifyCid`, content hash and multihash helpers |
48
47
  | JCS | `canonicalizeJson`, `canonicalizeJsonText` |
49
48
  | PEM | wipeable `Uint8Array` armor through `encodePem`, `decodePem`, with strict label and size policy |
@@ -85,14 +84,23 @@ helpers; deterministic CBOR additionally supports integer-key maps and the
85
84
  complete documented `u64`/`i64` integer ranges. `Uint8Array` is the canonical
86
85
  mutable-byte boundary for browser, Node, and WASM callers. Pass ordinary
87
86
  `Uint8Array` views; subclasses (including Node `Buffer`), proxies, and overridden
88
- byte metadata or copy methods are rejected. Create a plain `Uint8Array` copy
87
+ byte metadata are rejected. The facade copies bytes through captured prototype
88
+ methods and does not invoke a caller-owned copy method. Create a plain `Uint8Array` copy
89
89
  when adapting other byte containers.
90
90
 
91
- JCS rejects duplicate properties, unpaired UTF-16 surrogates, and integer-valued
92
- numbers outside the exact JavaScript integer range. CID validation accepts
91
+ JCS is a strict RFC 8785 subset. It rejects duplicate properties, unpaired
92
+ UTF-16 surrogates, Unicode noncharacters, and integer-valued numbers outside
93
+ the exact JavaScript integer range; this includes the RFC example `1e19`.
94
+ CID validation accepts
93
95
  CIDv0 and supported multibase CIDv1 strings up to 1024 UTF-8 bytes; paths and
94
96
  trailing decoded bytes are rejected. CID computation uses DAG-CBOR/SHA-256
95
97
  CIDv1 in lowercase base32 and hashes the supplied bytes without parsing CBOR.
98
+ CID verification validates one canonical DAG-CBOR block before comparing the
99
+ CID and requires the supplied CID text to use that canonical lowercase base32
100
+ form. `dagCborVerifyCid` returns a boolean; `dagCborVerifyCidDetails` returns
101
+ the canonical CID diagnostics. Invalid DAG-CBOR returns a typed canonicalization
102
+ error. IPLD links and floating-point values outside this package's closed
103
+ DAG-CBOR model return `unsupported-ipld-value`.
96
104
 
97
105
  Encoded CBOR and decoded byte-string values can contain the complete sensitive
98
106
  document. Returned buffers belong to the caller and should be cleared with
@@ -1,19 +1,17 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
- import { asciiBytesToString, ensureBytesInput, ensureStringValue, readBytesOutput, readStringOutput, } from "./readOutput.js";
4
+ import { asciiBytesToString, ensureBytesInput, ensureStringValue, readBytesOutput, readStringOutput, withSnapshotBytesInput, } from "./readOutput.js";
5
5
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
6
6
  export const base64Encode = (bytes) => {
7
- ensureBytesInput(bytes);
8
- return readStringOutput(requireReallyMeCodecWasmProvider().base64Encode(bytes));
7
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().base64Encode(snapshot)));
9
8
  };
10
9
  export const base64Decode = (encoded) => {
11
10
  ensureStringValue(encoded);
12
11
  return readBytesOutput(requireReallyMeCodecWasmProvider().base64Decode(encoded));
13
12
  };
14
13
  export const base64urlEncode = (bytes) => {
15
- ensureBytesInput(bytes);
16
- return readStringOutput(requireReallyMeCodecWasmProvider().base64urlEncode(bytes));
14
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().base64urlEncode(snapshot)));
17
15
  };
18
16
  export const base64urlDecode = (encoded) => {
19
17
  ensureStringValue(encoded);
@@ -24,8 +22,7 @@ export const base64urlDecodeBytes = (encoded) => {
24
22
  return base64urlDecode(asciiBytesToString(encoded));
25
23
  };
26
24
  export const bytesToLowerHex = (bytes) => {
27
- ensureBytesInput(bytes);
28
- return readStringOutput(requireReallyMeCodecWasmProvider().bytesToLowerHex(bytes));
25
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().bytesToLowerHex(snapshot)));
29
26
  };
30
27
  export const lowerHexToBytes = (encoded) => {
31
28
  ensureStringValue(encoded);
package/dist/boundary.js CHANGED
@@ -1,4 +1,4 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  import { ReallyMeCodecError } from "./errors.js";
package/dist/cbor.d.ts CHANGED
@@ -97,7 +97,11 @@ export declare const dagCborDecode: (bytes: Uint8Array) => ReallyMeCborValue;
97
97
  export declare const deterministicCborEncode: (value: unknown) => Uint8Array;
98
98
  export declare const deterministicCborDecode: (bytes: Uint8Array) => ReallyMeDeterministicCborValue;
99
99
  export declare const dagCborComputeCid: (bytes: Uint8Array) => string;
100
- export declare const dagCborVerifyCid: (cid: string, bytes: Uint8Array) => ReallyMeDagCborCidVerification;
100
+ export declare const dagCborVerifyCidDetails: (cid: string, bytes: Uint8Array) => ReallyMeDagCborCidVerification;
101
+ /** Verify one CID and return a boolean that is safe to use directly in a condition. */
102
+ export declare const dagCborVerifyCid: (cid: string, bytes: Uint8Array) => boolean;
103
+ /** Alias for callers that prefer an explicit comparison name. */
104
+ export declare const dagCborCidMatches: typeof dagCborVerifyCid;
101
105
  export declare const dagCborSha256ContentHash: (bytes: Uint8Array) => Uint8Array;
102
106
  export declare const dagCborMultihash: (bytes: Uint8Array) => Uint8Array;
103
107
  export declare const isValidCidString: (cid: string) => boolean;
package/dist/cbor.js CHANGED
@@ -1,4 +1,4 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  import { create } from "@bufbuild/protobuf";
@@ -7,7 +7,7 @@ import { DETERMINISTIC_CBOR_I64_MIN, DETERMINISTIC_CBOR_NEGATIVE_MAX, DETERMINIS
7
7
  import { ReallyMeCodecError } from "./errors.js";
8
8
  import { CodecDagCborDecodeRequestSchema, CodecDagCborEncodeRequestSchema, CodecDagCborVerifyCidRequestSchema, CodecDeterministicCborArraySchema, CodecDeterministicCborBoolSchema, CodecDeterministicCborBytesSchema, CodecDeterministicCborDecodeRequestSchema, CodecDeterministicCborEncodeRequestSchema, CodecDeterministicCborIntegerSchema, CodecDeterministicCborMapEntrySchema, CodecDeterministicCborMapKeySchema, CodecDeterministicCborMapSchema, CodecDeterministicCborNegativeIntegerSchema, CodecDeterministicCborNullSchema, CodecDeterministicCborTextSchema, CodecDeterministicCborUnsignedIntegerSchema, CodecDeterministicCborValueSchema, CodecOperationRequestSchema, } from "./proto/generated/reallyme/codec/v1/codec_pb.js";
9
9
  import { clearGeneratedOperationResult, processGeneratedOperationRequest, } from "./operationContract.js";
10
- import { ensureBytesInput, ensureStringValue, readBytesOutput, readStringOutput, readNumberOutput, } from "./readOutput.js";
10
+ import { ensureBytesInput, ensureStringValue, readBytesOutput, readStringOutput, readNumberOutput, snapshotBoundedBytesInput, snapshotProviderBytes, } from "./readOutput.js";
11
11
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
12
12
  export const ReallyMeDeterministicCbor = {
13
13
  null() {
@@ -39,7 +39,7 @@ export const ReallyMeDeterministicCbor = {
39
39
  },
40
40
  bytes(value) {
41
41
  ensureBytesInput(value);
42
- return { type: "bytes", value: value.slice() };
42
+ return { type: "bytes", value: snapshotBoundedBytesInput(value) };
43
43
  },
44
44
  array(value) {
45
45
  return { type: "array", value: [...value] };
@@ -132,7 +132,7 @@ export const ReallyMeDagCbor = {
132
132
  },
133
133
  bytes(value) {
134
134
  ensureBytesInput(value);
135
- return { type: "bytes", value: value.slice() };
135
+ return { type: "bytes", value: snapshotBoundedBytesInput(value) };
136
136
  },
137
137
  array(value) {
138
138
  return { type: "array", value: [...value] };
@@ -305,7 +305,7 @@ const validateCborValue = (value, depth = 0, seen = new WeakSet(), state = { nod
305
305
  throw new ReallyMeCodecError("invalid-input");
306
306
  }
307
307
  state.byteStringBytes += child.length;
308
- return { type: "bytes", value: child.slice() };
308
+ return { type: "bytes", value: snapshotBoundedBytesInput(child) };
309
309
  }
310
310
  case "array": {
311
311
  const children = snapshotArray(readDataProperty(value, "value"), MAX_DETERMINISTIC_CBOR_NODES - state.nodes);
@@ -864,7 +864,7 @@ const deterministicCborValueFromProto = (value, depth, state) => {
864
864
  requireNoProviderUnknownFields(value.value.value);
865
865
  const bytes = value.value.value.value;
866
866
  state.byteStringBytes = consumeProviderDeterministicCborBudget(state.byteStringBytes, bytes.length, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
867
- const copy = bytes.slice();
867
+ const copy = snapshotProviderBytes(bytes, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
868
868
  state.ownedBytes.push(copy);
869
869
  return { type: "bytes", value: copy };
870
870
  }
@@ -1011,7 +1011,7 @@ const dagCborValueToProto = (value) => {
1011
1011
  },
1012
1012
  });
1013
1013
  case "bytes": {
1014
- const bytes = value.value.slice();
1014
+ const bytes = snapshotDeterministicCborBytes(value.value, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES);
1015
1015
  try {
1016
1016
  const bytesValue = create(CodecDeterministicCborBytesSchema, { value: bytes });
1017
1017
  return create(CodecDeterministicCborValueSchema, {
@@ -1101,7 +1101,10 @@ const dagCborValueFromDeterministic = (value) => {
1101
1101
  case "text":
1102
1102
  return { type: "string", value: value.value };
1103
1103
  case "bytes":
1104
- return { type: "bytes", value: value.value.slice() };
1104
+ return {
1105
+ type: "bytes",
1106
+ value: snapshotProviderBytes(value.value, MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES),
1107
+ };
1105
1108
  case "array": {
1106
1109
  const values = [];
1107
1110
  try {
@@ -1179,7 +1182,7 @@ export const dagCborEncode = (value) => {
1179
1182
  result.encoded.length > maxDagCborInputLength) {
1180
1183
  return providerFailure();
1181
1184
  }
1182
- return result.encoded.slice();
1185
+ return snapshotProviderBytes(result.encoded, maxDagCborInputLength);
1183
1186
  }
1184
1187
  catch (error) {
1185
1188
  if (error instanceof ReallyMeCodecError) {
@@ -1265,7 +1268,7 @@ export const deterministicCborEncode = (value) => {
1265
1268
  result.encoded.length > MAX_DETERMINISTIC_CBOR_OUTPUT_LEN) {
1266
1269
  throw new ReallyMeCodecError("provider-failure");
1267
1270
  }
1268
- return result.encoded.slice();
1271
+ return snapshotProviderBytes(result.encoded, MAX_DETERMINISTIC_CBOR_OUTPUT_LEN);
1269
1272
  }
1270
1273
  finally {
1271
1274
  result.encoded.fill(0);
@@ -1315,9 +1318,15 @@ export const deterministicCborDecode = (bytes) => {
1315
1318
  };
1316
1319
  export const dagCborComputeCid = (bytes) => {
1317
1320
  ensureBytesInput(bytes);
1318
- return readStringOutput(requireReallyMeCodecWasmProvider().dagCborComputeCid(bytes));
1321
+ const snapshot = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
1322
+ try {
1323
+ return readStringOutput(requireReallyMeCodecWasmProvider().dagCborComputeCid(snapshot));
1324
+ }
1325
+ finally {
1326
+ snapshot.fill(0);
1327
+ }
1319
1328
  };
1320
- export const dagCborVerifyCid = (cid, bytes) => {
1329
+ export const dagCborVerifyCidDetails = (cid, bytes) => {
1321
1330
  ensureStringValue(cid);
1322
1331
  ensureBytesInput(bytes);
1323
1332
  const payloadSnapshot = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
@@ -1339,6 +1348,10 @@ export const dagCborVerifyCid = (cid, bytes) => {
1339
1348
  payloadSnapshot.fill(0);
1340
1349
  }
1341
1350
  };
1351
+ /** Verify one CID and return a boolean that is safe to use directly in a condition. */
1352
+ export const dagCborVerifyCid = (cid, bytes) => dagCborVerifyCidDetails(cid, bytes).valid;
1353
+ /** Alias for callers that prefer an explicit comparison name. */
1354
+ export const dagCborCidMatches = dagCborVerifyCid;
1342
1355
  const dagCborVerifyCidRequest = (cid, bytes) => create(CodecOperationRequestSchema, {
1343
1356
  operation: {
1344
1357
  case: "dagCborVerifyCid",
@@ -1350,11 +1363,23 @@ const dagCborVerifyCidRequest = (cid, bytes) => create(CodecOperationRequestSche
1350
1363
  });
1351
1364
  export const dagCborSha256ContentHash = (bytes) => {
1352
1365
  ensureBytesInput(bytes);
1353
- return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborSha256ContentHash(bytes));
1366
+ const snapshot = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
1367
+ try {
1368
+ return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborSha256ContentHash(snapshot));
1369
+ }
1370
+ finally {
1371
+ snapshot.fill(0);
1372
+ }
1354
1373
  };
1355
1374
  export const dagCborMultihash = (bytes) => {
1356
1375
  ensureBytesInput(bytes);
1357
- return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborMultihash(bytes));
1376
+ const snapshot = snapshotDeterministicCborBytes(bytes, maxDagCborInputLength);
1377
+ try {
1378
+ return readBytesOutput(requireReallyMeCodecWasmProvider().dagCborMultihash(snapshot));
1379
+ }
1380
+ finally {
1381
+ snapshot.fill(0);
1382
+ }
1358
1383
  };
1359
1384
  export const isValidCidString = (cid) => {
1360
1385
  ensureStringValue(cid);
@@ -1365,11 +1390,19 @@ export const isValidCidString = (cid) => {
1365
1390
  return value;
1366
1391
  };
1367
1392
  export const tryParseCid = (cid) => {
1368
- ensureStringValue(cid);
1369
- const value = requireReallyMeCodecWasmProvider().tryParseCid(cid);
1370
- if (value === undefined) {
1371
- return undefined;
1393
+ try {
1394
+ ensureStringValue(cid);
1395
+ const value = requireReallyMeCodecWasmProvider().tryParseCid(cid);
1396
+ if (value === undefined) {
1397
+ return undefined;
1398
+ }
1399
+ return readStringOutput(value);
1400
+ }
1401
+ catch (error) {
1402
+ if (error instanceof ReallyMeCodecError && error.code === "invalid-input") {
1403
+ return undefined;
1404
+ }
1405
+ throw error;
1372
1406
  }
1373
- return readStringOutput(value);
1374
1407
  };
1375
1408
  export const dagCborCodecCode = () => readNumberOutput(requireReallyMeCodecWasmProvider().dagCborCodecCode());
@@ -5,7 +5,7 @@ export declare const MAX_DETERMINISTIC_CBOR_NODES = 65536;
5
5
  export declare const MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES = 16384;
6
6
  export declare const MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES = 1048576;
7
7
  export declare const MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES = 1048576;
8
- export declare const MAX_DETERMINISTIC_CBOR_PROTO_RECURSION_DEPTH: number;
8
+ export declare const MAX_DETERMINISTIC_CBOR_PROTO_RECURSION_DEPTH = 198;
9
9
  export declare const DETERMINISTIC_CBOR_U64_MAX: bigint;
10
10
  export declare const DETERMINISTIC_CBOR_I64_MIN: bigint;
11
11
  export declare const DETERMINISTIC_CBOR_NEGATIVE_MAX = -1n;
@@ -1,4 +1,4 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  export const MAX_DETERMINISTIC_CBOR_INPUT_LEN = 1_048_576;
@@ -9,9 +9,9 @@ export const MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES = 16_384;
9
9
  export const MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES = 1_048_576;
10
10
  export const MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES = 1_048_576;
11
11
  // A nested map expands to Value -> Map -> MapEntry on the protobuf wire. The
12
- // five additional layers cover the result/request and deepest scalar wrapper.
13
- // Buf's default recursion limit of 100 cannot represent semantic depth 64.
14
- export const MAX_DETERMINISTIC_CBOR_PROTO_RECURSION_DEPTH = MAX_DETERMINISTIC_CBOR_NESTING_DEPTH * 3 + 5;
12
+ // protobuf-es counts the root message in addition to the wire's five outer
13
+ // layers. Depth 64 maps therefore require one more level than Buffa.
14
+ export const MAX_DETERMINISTIC_CBOR_PROTO_RECURSION_DEPTH = 198;
15
15
  export const DETERMINISTIC_CBOR_U64_MAX = (1n << 64n) - 1n;
16
16
  export const DETERMINISTIC_CBOR_I64_MIN = -(1n << 63n);
17
17
  export const DETERMINISTIC_CBOR_NEGATIVE_MAX = -1n;
package/dist/errors.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Typed codec error codes. Errors intentionally carry no raw input bytes so
3
3
  * callers can log them without leaking request payloads.
4
4
  */
5
- export type ReallyMeCodecErrorCode = "invalid-input" | "non-canonical" | "provider-failure" | "unsupported-codec";
5
+ export type ReallyMeCodecErrorCode = "invalid-input" | "non-canonical" | "provider-failure" | "unsupported-codec" | "unsupported-ipld-value";
6
6
  export declare class ReallyMeCodecError extends Error {
7
7
  readonly code: ReallyMeCodecErrorCode;
8
8
  constructor(code: ReallyMeCodecErrorCode);
package/dist/errors.js CHANGED
@@ -1,4 +1,4 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  export class ReallyMeCodecError extends Error {
package/dist/index.d.ts CHANGED
@@ -3,16 +3,16 @@ export type { ReallyMeCodecErrorCode } from "./errors.js";
3
3
  export { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
4
4
  export { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
5
5
  export type { ReallyMeKeyMaterialKind, ReallyMeMulticodecLookupResult, ReallyMeMulticodecMetadata, ReallyMeMulticodecTable, ReallyMeMulticodecTag, ReallyMeParsedMultikey, } from "./multiformat.js";
6
- export { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
6
+ export { dagCborCodecCode, dagCborCidMatches, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidDetails, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
7
7
  export type { ReallyMeDeterministicCborInteger, ReallyMeDeterministicCborMapEntry, ReallyMeDeterministicCborMapKey, ReallyMeDeterministicCborValue, ReallyMeCborMapEntry, ReallyMeCborValue, ReallyMeDagCborCidVerification, } from "./cbor.js";
8
8
  export { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
9
9
  export { decodePem, encodePem } from "./pem.js";
10
10
  export { processOperation, processOperationJson } from "./operationContract.js";
11
11
  export type { ReallyMePemDecodePolicy, ReallyMePemDocument, ReallyMePemEncodeOptions, ReallyMePemLabel, ReallyMePemLineEnding, } from "./pem.js";
12
- export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, requireReallyMeCodecWasmProvider, } from "./wasmProvider.js";
12
+ export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, } from "./wasmProvider.js";
13
13
  export type { ReallyMeCodecWasmProvider } from "./wasmProvider.js";
14
14
  import { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes } from "./baseEncoding.js";
15
- import { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, deterministicCborDecode, deterministicCborEncode, isValidCidString, tryParseCid } from "./cbor.js";
15
+ import { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidDetails, deterministicCborDecode, deterministicCborEncode, isValidCidString, tryParseCid } from "./cbor.js";
16
16
  import { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
17
17
  import { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding } from "./multiformat.js";
18
18
  import { decodePem, encodePem } from "./pem.js";
@@ -40,12 +40,14 @@ export declare const ReallyMeCodec: {
40
40
  readonly requireSupportedMulticodec: typeof requireSupportedMulticodec;
41
41
  readonly validateKeyBinding: typeof validateKeyBinding;
42
42
  readonly dagCborCodecCode: typeof dagCborCodecCode;
43
+ readonly dagCborCidMatches: typeof dagCborVerifyCid;
43
44
  readonly dagCborComputeCid: typeof dagCborComputeCid;
44
45
  readonly dagCborDecode: typeof dagCborDecode;
45
46
  readonly dagCborEncode: typeof dagCborEncode;
46
47
  readonly dagCborMultihash: typeof dagCborMultihash;
47
48
  readonly dagCborSha256ContentHash: typeof dagCborSha256ContentHash;
48
49
  readonly dagCborVerifyCid: typeof dagCborVerifyCid;
50
+ readonly dagCborVerifyCidDetails: typeof dagCborVerifyCidDetails;
49
51
  readonly deterministicCborDecode: typeof deterministicCborDecode;
50
52
  readonly deterministicCborEncode: typeof deterministicCborEncode;
51
53
  readonly isValidCidString: typeof isValidCidString;
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  export { ReallyMeCodecError } from "./errors.js";
5
5
  export { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
6
6
  export { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
7
- export { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
7
+ export { dagCborCodecCode, dagCborCidMatches, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidDetails, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
8
8
  export { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
9
9
  export { decodePem, encodePem } from "./pem.js";
10
10
  export { processOperation, processOperationJson } from "./operationContract.js";
11
- export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, requireReallyMeCodecWasmProvider, } from "./wasmProvider.js";
11
+ export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, } from "./wasmProvider.js";
12
12
  import { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
13
- import { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
13
+ import { dagCborCodecCode, dagCborCidMatches, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidDetails, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
14
14
  import { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
15
15
  import { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
16
16
  import { decodePem, encodePem } from "./pem.js";
@@ -38,12 +38,14 @@ export const ReallyMeCodec = {
38
38
  requireSupportedMulticodec,
39
39
  validateKeyBinding,
40
40
  dagCborCodecCode,
41
+ dagCborCidMatches,
41
42
  dagCborComputeCid,
42
43
  dagCborDecode,
43
44
  dagCborEncode,
44
45
  dagCborMultihash,
45
46
  dagCborSha256ContentHash,
46
47
  dagCborVerifyCid,
48
+ dagCborVerifyCidDetails,
47
49
  deterministicCborDecode,
48
50
  deterministicCborEncode,
49
51
  isValidCidString,
package/dist/jcs.js CHANGED
@@ -1,4 +1,4 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  import { requireBoundaryUtf8String, stringifyBoundaryJson } from "./boundary.js";
@@ -1,11 +1,11 @@
1
- // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
1
+ // SPDX-FileCopyrightText: 2026 ReallyMe LLC
2
2
  //
3
3
  // SPDX-License-Identifier: MIT OR Apache-2.0
4
4
  import { create } from "@bufbuild/protobuf";
5
5
  import { ReallyMeCodecError } from "./errors.js";
6
6
  import { CodecMulticodecLookupPrefixRequestSchema, CodecMulticodecPrefixForNameRequestSchema, CodecMulticodecTableRequestSchema, CodecMultikeyParseRequestSchema, CodecOperationRequestSchema, CodecKeyMaterialKind, CodecTag, } from "./proto/generated/reallyme/codec/v1/codec_pb.js";
7
7
  import { clearGeneratedOperationResult, processGeneratedOperationRequest, } from "./operationContract.js";
8
- import { ensureBytesInput, ensureStringInput, ensureStringValue, readBooleanOutput, readBytesOutput, readStringOutput, snapshotBoundedBytesInput, } from "./readOutput.js";
8
+ import { ensureBytesInput, ensureStringInput, ensureStringValue, readBooleanOutput, readBytesOutput, readStringOutput, snapshotBoundedBytesInput, snapshotProviderBytes, withSnapshotBytesInput, } from "./readOutput.js";
9
9
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
10
10
  const MAX_MULTICODEC_TABLE_ENTRIES = 1_024;
11
11
  const requireNoProviderUnknownFields = (message) => {
@@ -52,7 +52,7 @@ const readMulticodecMetadata = (value) => {
52
52
  alg: value.algorithmName,
53
53
  tag: sdkTag(value.tag),
54
54
  keyMaterial: sdkKeyMaterial(value.keyMaterialKind),
55
- prefix: value.prefix.slice(),
55
+ prefix: snapshotProviderBytes(value.prefix),
56
56
  };
57
57
  if (value.variableLength || value.fixedLength === 0) {
58
58
  return metadata;
@@ -65,20 +65,17 @@ const validateMulticodecMetadata = (value) => {
65
65
  sdkKeyMaterial(value.keyMaterialKind);
66
66
  };
67
67
  export const base58btcEncode = (bytes) => {
68
- ensureBytesInput(bytes);
69
- return readStringOutput(requireReallyMeCodecWasmProvider().base58btcEncode(bytes));
68
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().base58btcEncode(snapshot)));
70
69
  };
71
70
  export const base58btcDecode = (encoded) => {
72
71
  ensureStringValue(encoded);
73
72
  return readBytesOutput(requireReallyMeCodecWasmProvider().base58btcDecode(encoded));
74
73
  };
75
74
  export const multibaseBase64urlEncode = (bytes) => {
76
- ensureBytesInput(bytes);
77
- return readStringOutput(requireReallyMeCodecWasmProvider().multibaseBase64urlEncode(bytes));
75
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().multibaseBase64urlEncode(snapshot)));
78
76
  };
79
77
  export const multibaseBase58btcEncode = (bytes) => {
80
- ensureBytesInput(bytes);
81
- return readStringOutput(requireReallyMeCodecWasmProvider().multibaseBase58btcEncode(bytes));
78
+ return withSnapshotBytesInput(bytes, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().multibaseBase58btcEncode(snapshot)));
82
79
  };
83
80
  export const multibaseDecode = (encoded) => {
84
81
  ensureStringInput(encoded);
@@ -144,8 +141,7 @@ const multicodecLookupPrefixRequest = (bytes) => create(CodecOperationRequestSch
144
141
  },
145
142
  });
146
143
  export const multicodecStripPrefix = (bytes) => {
147
- ensureBytesInput(bytes);
148
- return readBytesOutput(requireReallyMeCodecWasmProvider().multicodecStripPrefix(bytes));
144
+ return withSnapshotBytesInput(bytes, (snapshot) => readBytesOutput(requireReallyMeCodecWasmProvider().multicodecStripPrefix(snapshot)));
149
145
  };
150
146
  export const multicodecTable = () => {
151
147
  const operationResult = processGeneratedOperationRequest(multicodecTableRequest());
@@ -181,8 +177,7 @@ const multicodecTableRequest = () => create(CodecOperationRequestSchema, {
181
177
  });
182
178
  export const multikeyEncode = (codecName, publicKey) => {
183
179
  ensureStringInput(codecName);
184
- ensureBytesInput(publicKey);
185
- return readStringOutput(requireReallyMeCodecWasmProvider().multikeyEncode(codecName, publicKey));
180
+ return withSnapshotBytesInput(publicKey, (snapshot) => readStringOutput(requireReallyMeCodecWasmProvider().multikeyEncode(codecName, snapshot)));
186
181
  };
187
182
  export const multikeyParse = (multikey) => {
188
183
  ensureStringInput(multikey);
@@ -197,7 +192,7 @@ export const multikeyParse = (multikey) => {
197
192
  const parsed = {
198
193
  codecName: result.codecName,
199
194
  algorithmName: result.algorithmName,
200
- publicKey: result.publicKey.slice(),
195
+ publicKey: snapshotProviderBytes(result.publicKey),
201
196
  };
202
197
  if (result.variablePublicKeyLength || result.expectedPublicKeyLength === 0) {
203
198
  return parsed;
@@ -225,9 +220,14 @@ export const validateKeyBinding = (bindingType, algorithm, multikey) => {
225
220
  ensureStringInput(algorithm);
226
221
  }
227
222
  ensureStringInput(multikey);
228
- requireReallyMeCodecWasmProvider().validateKeyBinding(bindingType, algorithm, multikey);
223
+ requireVoidProviderOutput(requireReallyMeCodecWasmProvider().validateKeyBinding(bindingType, algorithm, multikey));
229
224
  };
230
225
  export const requireSupportedMulticodec = (codecName) => {
231
226
  ensureStringInput(codecName);
232
- requireReallyMeCodecWasmProvider().requireSupportedMulticodec(codecName);
227
+ requireVoidProviderOutput(requireReallyMeCodecWasmProvider().requireSupportedMulticodec(codecName));
228
+ };
229
+ const requireVoidProviderOutput = (value) => {
230
+ if (value !== undefined) {
231
+ throw new ReallyMeCodecError("provider-failure");
232
+ }
233
233
  };
@@ -3,9 +3,8 @@ import type { CodecOperationRequest, CodecOperationResult } from "./proto/genera
3
3
  * Execute one binary generated-protobuf request and return the fully
4
4
  * discriminated binary `CodecOperationResponse`.
5
5
  *
6
- * Oversized requests are rejected before the provider call. Malformed and
7
- * unsupported in-limit requests are represented by the response error oneof
8
- * rather than a boundary-local exception.
6
+ * Oversized and malformed requests are represented by the response error
7
+ * oneof. Caller-owned oversized bytes are not copied into WASM.
9
8
  */
10
9
  export declare const processOperation: (requestBytes: Uint8Array) => Uint8Array;
11
10
  /**