@reallyme/codec 0.1.21 → 0.2.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.
@@ -0,0 +1,11 @@
1
+ export declare const MAX_DETERMINISTIC_CBOR_INPUT_LEN = 1048576;
2
+ export declare const MAX_DETERMINISTIC_CBOR_OUTPUT_LEN = 1048576;
3
+ export declare const MAX_DETERMINISTIC_CBOR_NESTING_DEPTH = 64;
4
+ export declare const MAX_DETERMINISTIC_CBOR_NODES = 65536;
5
+ export declare const MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES = 16384;
6
+ export declare const MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES = 1048576;
7
+ export declare const MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES = 1048576;
8
+ export declare const MAX_DETERMINISTIC_CBOR_PROTO_RECURSION_DEPTH: number;
9
+ export declare const DETERMINISTIC_CBOR_U64_MAX: bigint;
10
+ export declare const DETERMINISTIC_CBOR_I64_MIN: bigint;
11
+ export declare const DETERMINISTIC_CBOR_NEGATIVE_MAX = -1n;
@@ -0,0 +1,17 @@
1
+ // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ export const MAX_DETERMINISTIC_CBOR_INPUT_LEN = 1_048_576;
5
+ export const MAX_DETERMINISTIC_CBOR_OUTPUT_LEN = 1_048_576;
6
+ export const MAX_DETERMINISTIC_CBOR_NESTING_DEPTH = 64;
7
+ export const MAX_DETERMINISTIC_CBOR_NODES = 65_536;
8
+ export const MAX_DETERMINISTIC_CBOR_CONTAINER_ENTRIES = 16_384;
9
+ export const MAX_DETERMINISTIC_CBOR_AGGREGATE_TEXT_BYTES = 1_048_576;
10
+ export const MAX_DETERMINISTIC_CBOR_AGGREGATE_BYTE_STRING_BYTES = 1_048_576;
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;
15
+ export const DETERMINISTIC_CBOR_U64_MAX = (1n << 64n) - 1n;
16
+ export const DETERMINISTIC_CBOR_I64_MIN = -(1n << 63n);
17
+ export const DETERMINISTIC_CBOR_NEGATIVE_MAX = -1n;
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export { ReallyMeCodecError } from "./errors.js";
2
2
  export type { ReallyMeCodecErrorCode } from "./errors.js";
3
3
  export { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
4
- export { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefixProto, multicodecLookupPrefixProtoResult, multicodecLookupPrefix, multicodecPrefixForNameProto, multicodecPrefixForNameProtoResult, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multicodecTableProto, multicodecTableProtoResult, multikeyEncode, multikeyParse, multikeyParseProto, multikeyParseProtoResult, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
5
- export type { ReallyMeKeyMaterialKind, ReallyMeMulticodecMetadata, ReallyMeMulticodecTag, ReallyMeParsedMultikey, } from "./multiformat.js";
6
- export { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidProto, dagCborVerifyCidProtoResult, isValidCidString, tryParseCid, } from "./cbor.js";
7
- export type { ReallyMeCborMapEntry, ReallyMeCborValue, ReallyMeDagCborCidVerification, } from "./cbor.js";
4
+ export { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
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";
7
+ export type { ReallyMeDeterministicCborInteger, ReallyMeDeterministicCborMapEntry, ReallyMeDeterministicCborMapKey, ReallyMeDeterministicCborValue, ReallyMeCborMapEntry, ReallyMeCborValue, ReallyMeDagCborCidVerification, } from "./cbor.js";
8
8
  export { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
9
- export { decodePem, decodePemProto, decodePemProtoResult, encodePem } from "./pem.js";
10
- export type { ReallyMeCodecProtoResult, ReallyMeCodecProtoStatus } from "./readOutput.js";
9
+ export { decodePem, encodePem } from "./pem.js";
10
+ export { processOperation, processOperationJson } from "./operationContract.js";
11
11
  export type { ReallyMePemDecodePolicy, ReallyMePemDocument, ReallyMePemEncodeOptions, ReallyMePemLabel, ReallyMePemLineEnding, } from "./pem.js";
12
12
  export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, requireReallyMeCodecWasmProvider, } from "./wasmProvider.js";
13
13
  export type { ReallyMeCodecWasmProvider } from "./wasmProvider.js";
@@ -25,20 +25,12 @@ export declare const ReallyMeCodec: {
25
25
  readonly multibaseBase58btcEncode: (bytes: Uint8Array) => string;
26
26
  readonly multibaseBase64urlEncode: (bytes: Uint8Array) => string;
27
27
  readonly multibaseDecode: (encoded: string) => Uint8Array;
28
- readonly multicodecLookupPrefixProto: (bytes: Uint8Array) => Uint8Array;
29
- readonly multicodecLookupPrefixProtoResult: (bytes: Uint8Array) => import("./readOutput.js").ReallyMeCodecProtoResult;
30
- readonly multicodecLookupPrefix: (bytes: Uint8Array) => import("./multiformat.js").ReallyMeMulticodecMetadata;
31
- readonly multicodecPrefixForNameProto: (codecName: string) => Uint8Array;
32
- readonly multicodecPrefixForNameProtoResult: (codecName: string) => import("./readOutput.js").ReallyMeCodecProtoResult;
28
+ readonly multicodecLookupPrefix: (bytes: Uint8Array) => import("./multiformat.js").ReallyMeMulticodecLookupResult;
33
29
  readonly multicodecPrefixForName: (codecName: string) => import("./multiformat.js").ReallyMeMulticodecMetadata;
34
30
  readonly multicodecStripPrefix: (bytes: Uint8Array) => Uint8Array;
35
- readonly multicodecTable: () => ReadonlyArray<import("./multiformat.js").ReallyMeMulticodecMetadata>;
36
- readonly multicodecTableProto: () => Uint8Array;
37
- readonly multicodecTableProtoResult: () => import("./readOutput.js").ReallyMeCodecProtoResult;
31
+ readonly multicodecTable: () => import("./multiformat.js").ReallyMeMulticodecTable;
38
32
  readonly multikeyEncode: (codecName: string, publicKey: Uint8Array) => string;
39
33
  readonly multikeyParse: (multikey: string) => import("./multiformat.js").ReallyMeParsedMultikey;
40
- readonly multikeyParseProto: (multikey: string) => Uint8Array;
41
- readonly multikeyParseProtoResult: (multikey: string) => import("./readOutput.js").ReallyMeCodecProtoResult;
42
34
  readonly requireSupportedMulticodec: (codecName: string) => void;
43
35
  readonly validateKeyBinding: (bindingType: string, algorithm: string | undefined, multikey: string) => void;
44
36
  readonly dagCborCodecCode: () => number;
@@ -48,14 +40,39 @@ export declare const ReallyMeCodec: {
48
40
  readonly dagCborMultihash: (bytes: Uint8Array) => Uint8Array;
49
41
  readonly dagCborSha256ContentHash: (bytes: Uint8Array) => Uint8Array;
50
42
  readonly dagCborVerifyCid: (cid: string, bytes: Uint8Array) => import("./cbor.js").ReallyMeDagCborCidVerification;
51
- readonly dagCborVerifyCidProto: (cid: string, bytes: Uint8Array) => Uint8Array;
52
- readonly dagCborVerifyCidProtoResult: (cid: string, bytes: Uint8Array) => import("./readOutput.js").ReallyMeCodecProtoResult;
43
+ readonly deterministicCborDecode: (bytes: Uint8Array) => import("./cbor.js").ReallyMeDeterministicCborValue;
44
+ readonly deterministicCborEncode: (value: unknown) => Uint8Array;
53
45
  readonly isValidCidString: (cid: string) => boolean;
46
+ readonly ReallyMeDagCbor: {
47
+ readonly null: () => import("./cbor.js").ReallyMeCborValue;
48
+ readonly bool: (value: boolean) => import("./cbor.js").ReallyMeCborValue;
49
+ readonly int: (value: number | bigint) => import("./cbor.js").ReallyMeCborValue;
50
+ readonly unsigned: (value: number | bigint) => import("./cbor.js").ReallyMeCborValue;
51
+ readonly negative: (value: number | bigint) => import("./cbor.js").ReallyMeCborValue;
52
+ readonly text: (value: string) => import("./cbor.js").ReallyMeCborValue;
53
+ readonly bytes: (value: Uint8Array) => import("./cbor.js").ReallyMeCborValue;
54
+ readonly array: (value: ReadonlyArray<import("./cbor.js").ReallyMeCborValue>) => import("./cbor.js").ReallyMeCborValue;
55
+ readonly mapText: (entries: ReadonlyArray<readonly [string, import("./cbor.js").ReallyMeCborValue]>) => import("./cbor.js").ReallyMeCborValue;
56
+ };
57
+ readonly ReallyMeDeterministicCbor: {
58
+ readonly null: () => import("./cbor.js").ReallyMeDeterministicCborValue;
59
+ readonly bool: (value: boolean) => import("./cbor.js").ReallyMeDeterministicCborValue;
60
+ readonly unsigned: (value: bigint) => import("./cbor.js").ReallyMeDeterministicCborValue;
61
+ readonly negative: (value: bigint) => import("./cbor.js").ReallyMeDeterministicCborValue;
62
+ readonly text: (value: string) => import("./cbor.js").ReallyMeDeterministicCborValue;
63
+ readonly bytes: (value: Uint8Array) => import("./cbor.js").ReallyMeDeterministicCborValue;
64
+ readonly array: (value: ReadonlyArray<import("./cbor.js").ReallyMeDeterministicCborValue>) => import("./cbor.js").ReallyMeDeterministicCborValue;
65
+ readonly mapInt: (entries: ReadonlyArray<readonly [bigint, import("./cbor.js").ReallyMeDeterministicCborValue]>) => import("./cbor.js").ReallyMeDeterministicCborValue;
66
+ readonly mapText: (entries: ReadonlyArray<readonly [string, import("./cbor.js").ReallyMeDeterministicCborValue]>) => import("./cbor.js").ReallyMeDeterministicCborValue;
67
+ readonly intKey: (value: bigint) => import("./cbor.js").ReallyMeDeterministicCborMapKey;
68
+ readonly textKey: (value: string) => import("./cbor.js").ReallyMeDeterministicCborMapKey;
69
+ readonly entry: (key: import("./cbor.js").ReallyMeDeterministicCborMapKey, value: import("./cbor.js").ReallyMeDeterministicCborValue) => import("./cbor.js").ReallyMeDeterministicCborMapEntry;
70
+ };
54
71
  readonly tryParseCid: (cid: string) => string | undefined;
55
72
  readonly canonicalizeJson: (value: unknown) => string;
56
73
  readonly canonicalizeJsonText: (json: string) => string;
57
- readonly decodePem: (input: string, policy?: import("./pem.js").ReallyMePemDecodePolicy) => import("./pem.js").ReallyMePemDocument;
58
- readonly decodePemProto: (input: string, policy?: import("./pem.js").ReallyMePemDecodePolicy) => Uint8Array;
59
- readonly decodePemProtoResult: (input: string, policy?: import("./pem.js").ReallyMePemDecodePolicy) => import("./readOutput.js").ReallyMeCodecProtoResult;
60
- readonly encodePem: (label: import("./pem.js").ReallyMePemLabel, der: Uint8Array, options?: import("./pem.js").ReallyMePemEncodeOptions) => string;
74
+ readonly decodePem: (input: Uint8Array, policy?: import("./pem.js").ReallyMePemDecodePolicy) => import("./pem.js").ReallyMePemDocument;
75
+ readonly encodePem: (label: import("./pem.js").ReallyMePemLabel, der: Uint8Array, options?: import("./pem.js").ReallyMePemEncodeOptions) => Uint8Array;
76
+ readonly processOperation: (requestBytes: Uint8Array) => Uint8Array;
77
+ readonly processOperationJson: (requestJson: Uint8Array) => Uint8Array;
61
78
  };
package/dist/index.js CHANGED
@@ -3,16 +3,18 @@
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
  export { ReallyMeCodecError } from "./errors.js";
5
5
  export { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
6
- export { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefixProto, multicodecLookupPrefixProtoResult, multicodecLookupPrefix, multicodecPrefixForNameProto, multicodecPrefixForNameProtoResult, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multicodecTableProto, multicodecTableProtoResult, multikeyEncode, multikeyParse, multikeyParseProto, multikeyParseProtoResult, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
7
- export { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidProto, dagCborVerifyCidProtoResult, isValidCidString, tryParseCid, } from "./cbor.js";
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";
8
8
  export { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
9
- export { decodePem, decodePemProto, decodePemProtoResult, encodePem } from "./pem.js";
9
+ export { decodePem, encodePem } from "./pem.js";
10
+ export { processOperation, processOperationJson } from "./operationContract.js";
10
11
  export { REALLYME_CODEC_WASM_EXPORTS, installReallyMeCodecWasmProvider, requireReallyMeCodecWasmProvider, } from "./wasmProvider.js";
11
12
  import { base64Decode, base64Encode, base64urlDecode, base64urlDecodeBytes, base64urlEncode, bytesToLowerHex, lowerHexToBytes, } from "./baseEncoding.js";
12
- import { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, dagCborVerifyCidProto, dagCborVerifyCidProtoResult, isValidCidString, tryParseCid, } from "./cbor.js";
13
+ import { dagCborCodecCode, dagCborComputeCid, dagCborDecode, dagCborEncode, dagCborMultihash, dagCborSha256ContentHash, dagCborVerifyCid, deterministicCborDecode, deterministicCborEncode, isValidCidString, ReallyMeDagCbor, ReallyMeDeterministicCbor, tryParseCid, } from "./cbor.js";
13
14
  import { canonicalizeJson, canonicalizeJsonText } from "./jcs.js";
14
- import { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefixProto, multicodecLookupPrefixProtoResult, multicodecLookupPrefix, multicodecPrefixForNameProto, multicodecPrefixForNameProtoResult, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multicodecTableProto, multicodecTableProtoResult, multikeyEncode, multikeyParse, multikeyParseProto, multikeyParseProtoResult, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
15
- import { decodePem, decodePemProto, decodePemProtoResult, encodePem } from "./pem.js";
15
+ import { base58btcDecode, base58btcEncode, bindingTypeMatchesCodec, multibaseBase58btcEncode, multibaseBase64urlEncode, multibaseDecode, multicodecLookupPrefix, multicodecPrefixForName, multicodecStripPrefix, multicodecTable, multikeyEncode, multikeyParse, requireSupportedMulticodec, validateKeyBinding, } from "./multiformat.js";
16
+ import { decodePem, encodePem } from "./pem.js";
17
+ import { processOperation, processOperationJson } from "./operationContract.js";
16
18
  export const ReallyMeCodec = {
17
19
  base64Decode,
18
20
  base64Encode,
@@ -27,20 +29,12 @@ export const ReallyMeCodec = {
27
29
  multibaseBase58btcEncode,
28
30
  multibaseBase64urlEncode,
29
31
  multibaseDecode,
30
- multicodecLookupPrefixProto,
31
- multicodecLookupPrefixProtoResult,
32
32
  multicodecLookupPrefix,
33
- multicodecPrefixForNameProto,
34
- multicodecPrefixForNameProtoResult,
35
33
  multicodecPrefixForName,
36
34
  multicodecStripPrefix,
37
35
  multicodecTable,
38
- multicodecTableProto,
39
- multicodecTableProtoResult,
40
36
  multikeyEncode,
41
37
  multikeyParse,
42
- multikeyParseProto,
43
- multikeyParseProtoResult,
44
38
  requireSupportedMulticodec,
45
39
  validateKeyBinding,
46
40
  dagCborCodecCode,
@@ -50,14 +44,16 @@ export const ReallyMeCodec = {
50
44
  dagCborMultihash,
51
45
  dagCborSha256ContentHash,
52
46
  dagCborVerifyCid,
53
- dagCborVerifyCidProto,
54
- dagCborVerifyCidProtoResult,
47
+ deterministicCborDecode,
48
+ deterministicCborEncode,
55
49
  isValidCidString,
50
+ ReallyMeDagCbor,
51
+ ReallyMeDeterministicCbor,
56
52
  tryParseCid,
57
53
  canonicalizeJson,
58
54
  canonicalizeJsonText,
59
55
  decodePem,
60
- decodePemProto,
61
- decodePemProtoResult,
62
56
  encodePem,
57
+ processOperation,
58
+ processOperationJson,
63
59
  };
package/dist/jcs.js CHANGED
@@ -1,71 +1,14 @@
1
1
  // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
- import { ReallyMeCodecError } from "./errors.js";
4
+ import { requireBoundaryUtf8String, stringifyBoundaryJson } from "./boundary.js";
5
5
  import { readStringOutput } from "./readOutput.js";
6
6
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
7
- const maxJsonContainerDepth = 128;
8
- const validateJsonCompatible = (value, depth = 0, seen = new WeakSet()) => {
9
- if (value === null) {
10
- return;
11
- }
12
- switch (typeof value) {
13
- case "boolean":
14
- case "string":
15
- return;
16
- case "number":
17
- if (!Number.isFinite(value)) {
18
- throw new ReallyMeCodecError("invalid-input");
19
- }
20
- return;
21
- case "bigint":
22
- case "function":
23
- case "symbol":
24
- case "undefined":
25
- throw new ReallyMeCodecError("invalid-input");
26
- case "object":
27
- break;
28
- }
29
- if (seen.has(value)) {
30
- throw new ReallyMeCodecError("invalid-input");
31
- }
32
- if (depth >= maxJsonContainerDepth) {
33
- throw new ReallyMeCodecError("invalid-input");
34
- }
35
- if (typeof Reflect.get(value, "toJSON") === "function") {
36
- throw new ReallyMeCodecError("invalid-input");
37
- }
38
- const prototype = Object.getPrototypeOf(value);
39
- if (prototype !== Object.prototype && prototype !== null && !Array.isArray(value)) {
40
- throw new ReallyMeCodecError("invalid-input");
41
- }
42
- seen.add(value);
43
- try {
44
- if (Array.isArray(value)) {
45
- for (const entry of value) {
46
- validateJsonCompatible(entry, depth + 1, seen);
47
- }
48
- return;
49
- }
50
- for (const key of Object.keys(value)) {
51
- validateJsonCompatible(Reflect.get(value, key), depth + 1, seen);
52
- }
53
- }
54
- finally {
55
- seen.delete(value);
56
- }
57
- };
58
7
  export const canonicalizeJson = (value) => {
59
- validateJsonCompatible(value);
60
- const encoded = JSON.stringify(value);
61
- if (encoded === undefined) {
62
- throw new ReallyMeCodecError("invalid-input");
63
- }
8
+ const encoded = stringifyBoundaryJson(value);
64
9
  return readStringOutput(requireReallyMeCodecWasmProvider().canonicalizeJson(encoded));
65
10
  };
66
11
  export const canonicalizeJsonText = (json) => {
67
- if (typeof json !== "string" || json.length === 0) {
68
- throw new ReallyMeCodecError("invalid-input");
69
- }
12
+ requireBoundaryUtf8String(json, false);
70
13
  return readStringOutput(requireReallyMeCodecWasmProvider().canonicalizeJson(json));
71
14
  };
@@ -1,4 +1,3 @@
1
- import type { ReallyMeCodecProtoResult } from "./readOutput.js";
2
1
  export type ReallyMeMulticodecTag = "encryption" | "hash" | "key" | "multihash" | "multikey";
3
2
  export type ReallyMeKeyMaterialKind = "not-key" | "public-key" | "private-key" | "symmetric-key";
4
3
  export type ReallyMeMulticodecMetadata = Readonly<{
@@ -9,32 +8,31 @@ export type ReallyMeMulticodecMetadata = Readonly<{
9
8
  prefix: Uint8Array;
10
9
  expectedKeyLength?: number;
11
10
  }>;
11
+ export type ReallyMeMulticodecLookupResult = Readonly<{
12
+ name: string;
13
+ prefixLength: number;
14
+ metadata: ReallyMeMulticodecMetadata;
15
+ }>;
16
+ export type ReallyMeMulticodecTable = Readonly<{
17
+ entries: ReadonlyArray<ReallyMeMulticodecMetadata>;
18
+ }>;
12
19
  export type ReallyMeParsedMultikey = Readonly<{
13
20
  codecName: string;
14
21
  algorithmName: string;
15
22
  publicKey: Uint8Array;
16
23
  expectedPublicKeyLength?: number;
17
24
  }>;
18
- export declare const readMulticodecMetadata: (value: unknown) => ReallyMeMulticodecMetadata;
19
25
  export declare const base58btcEncode: (bytes: Uint8Array) => string;
20
26
  export declare const base58btcDecode: (encoded: string) => Uint8Array;
21
27
  export declare const multibaseBase64urlEncode: (bytes: Uint8Array) => string;
22
28
  export declare const multibaseBase58btcEncode: (bytes: Uint8Array) => string;
23
29
  export declare const multibaseDecode: (encoded: string) => Uint8Array;
24
30
  export declare const multicodecPrefixForName: (codecName: string) => ReallyMeMulticodecMetadata;
25
- export declare const multicodecPrefixForNameProto: (codecName: string) => Uint8Array;
26
- export declare const multicodecPrefixForNameProtoResult: (codecName: string) => ReallyMeCodecProtoResult;
27
- export declare const multicodecLookupPrefix: (bytes: Uint8Array) => ReallyMeMulticodecMetadata;
28
- export declare const multicodecLookupPrefixProto: (bytes: Uint8Array) => Uint8Array;
29
- export declare const multicodecLookupPrefixProtoResult: (bytes: Uint8Array) => ReallyMeCodecProtoResult;
31
+ export declare const multicodecLookupPrefix: (bytes: Uint8Array) => ReallyMeMulticodecLookupResult;
30
32
  export declare const multicodecStripPrefix: (bytes: Uint8Array) => Uint8Array;
31
- export declare const multicodecTable: () => ReadonlyArray<ReallyMeMulticodecMetadata>;
32
- export declare const multicodecTableProto: () => Uint8Array;
33
- export declare const multicodecTableProtoResult: () => ReallyMeCodecProtoResult;
33
+ export declare const multicodecTable: () => ReallyMeMulticodecTable;
34
34
  export declare const multikeyEncode: (codecName: string, publicKey: Uint8Array) => string;
35
35
  export declare const multikeyParse: (multikey: string) => ReallyMeParsedMultikey;
36
- export declare const multikeyParseProto: (multikey: string) => Uint8Array;
37
- export declare const multikeyParseProtoResult: (multikey: string) => ReallyMeCodecProtoResult;
38
36
  export declare const bindingTypeMatchesCodec: (bindingType: string, codecName: string) => boolean;
39
37
  export declare const validateKeyBinding: (bindingType: string, algorithm: string | undefined, multikey: string) => void;
40
38
  export declare const requireSupportedMulticodec: (codecName: string) => void;
@@ -1,86 +1,68 @@
1
1
  // SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from "@bufbuild/protobuf";
4
5
  import { ReallyMeCodecError } from "./errors.js";
5
- import { ensureBytesInput, ensureStringInput, ensureStringValue, readBooleanOutput, readBytesOutput, readBytesProperty, readObjectOutput, readProtoResultOutput, readOptionalLengthProperty, readStringOutput, readStringProperty, } from "./readOutput.js";
6
+ import { CodecMulticodecLookupPrefixRequestSchema, CodecMulticodecPrefixForNameRequestSchema, CodecMulticodecTableRequestSchema, CodecMultikeyParseRequestSchema, CodecOperationRequestSchema, CodecKeyMaterialKind, CodecTag, } from "./proto/generated/reallyme/codec/v1/codec_pb.js";
7
+ import { clearGeneratedOperationResult, processGeneratedOperationRequest, } from "./operationContract.js";
8
+ import { ensureBytesInput, ensureStringInput, ensureStringValue, readBooleanOutput, readBytesOutput, readStringOutput, snapshotBoundedBytesInput, } from "./readOutput.js";
6
9
  import { requireReallyMeCodecWasmProvider } from "./wasmProvider.js";
7
- const validTags = new Set([
8
- "encryption",
9
- "hash",
10
- "key",
11
- "multihash",
12
- "multikey",
13
- ]);
14
- const validKeyMaterialKinds = new Set([
15
- "not-key",
16
- "public-key",
17
- "private-key",
18
- "symmetric-key",
19
- ]);
20
- const readTag = (object) => {
21
- const tag = readStringProperty(object, "tag");
22
- if (!validTags.has(tag)) {
10
+ const MAX_MULTICODEC_TABLE_ENTRIES = 1_024;
11
+ const requireNoProviderUnknownFields = (message) => {
12
+ if (message.$unknown !== undefined && message.$unknown.length !== 0) {
23
13
  throw new ReallyMeCodecError("provider-failure");
24
14
  }
15
+ };
16
+ const sdkTag = (tag) => {
25
17
  switch (tag) {
26
- case "encryption":
27
- case "hash":
28
- case "key":
29
- case "multihash":
30
- case "multikey":
31
- return tag;
18
+ case CodecTag.ENCRYPTION:
19
+ return "encryption";
20
+ case CodecTag.HASH:
21
+ return "hash";
22
+ case CodecTag.KEY:
23
+ return "key";
24
+ case CodecTag.MULTIHASH:
25
+ return "multihash";
26
+ case CodecTag.MULTIKEY:
27
+ return "multikey";
28
+ case CodecTag.UNSPECIFIED:
32
29
  default:
33
30
  throw new ReallyMeCodecError("provider-failure");
34
31
  }
35
32
  };
36
- const readKeyMaterial = (object) => {
37
- const keyMaterial = readStringProperty(object, "keyMaterial");
38
- if (!validKeyMaterialKinds.has(keyMaterial)) {
39
- throw new ReallyMeCodecError("provider-failure");
40
- }
33
+ const sdkKeyMaterial = (keyMaterial) => {
41
34
  switch (keyMaterial) {
42
- case "not-key":
43
- case "public-key":
44
- case "private-key":
45
- case "symmetric-key":
46
- return keyMaterial;
35
+ case CodecKeyMaterialKind.NOT_KEY:
36
+ return "not-key";
37
+ case CodecKeyMaterialKind.PUBLIC_KEY:
38
+ return "public-key";
39
+ case CodecKeyMaterialKind.PRIVATE_KEY:
40
+ return "private-key";
41
+ case CodecKeyMaterialKind.SYMMETRIC_KEY:
42
+ return "symmetric-key";
43
+ case CodecKeyMaterialKind.UNSPECIFIED:
47
44
  default:
48
45
  throw new ReallyMeCodecError("provider-failure");
49
46
  }
50
47
  };
51
- export const readMulticodecMetadata = (value) => {
52
- const object = readObjectOutput(value);
53
- const expectedKeyLength = readOptionalLengthProperty(object, "expectedKeyLength");
48
+ const readMulticodecMetadata = (value) => {
49
+ validateMulticodecMetadata(value);
54
50
  const metadata = {
55
- name: readStringProperty(object, "name"),
56
- alg: readStringProperty(object, "alg"),
57
- tag: readTag(object),
58
- keyMaterial: readKeyMaterial(object),
59
- prefix: readBytesProperty(object, "prefix"),
51
+ name: value.name,
52
+ alg: value.algorithmName,
53
+ tag: sdkTag(value.tag),
54
+ keyMaterial: sdkKeyMaterial(value.keyMaterialKind),
55
+ prefix: value.prefix.slice(),
60
56
  };
61
- if (expectedKeyLength === undefined) {
57
+ if (value.variableLength || value.fixedLength === 0) {
62
58
  return metadata;
63
59
  }
64
- return { ...metadata, expectedKeyLength };
65
- };
66
- const readParsedMultikey = (value) => {
67
- const object = readObjectOutput(value);
68
- const expectedPublicKeyLength = readOptionalLengthProperty(object, "expectedPublicKeyLength");
69
- const parsed = {
70
- codecName: readStringProperty(object, "codecName"),
71
- algorithmName: readStringProperty(object, "algorithmName"),
72
- publicKey: readBytesProperty(object, "publicKey"),
73
- };
74
- if (expectedPublicKeyLength === undefined) {
75
- return parsed;
76
- }
77
- return { ...parsed, expectedPublicKeyLength };
60
+ return { ...metadata, expectedKeyLength: value.fixedLength };
78
61
  };
79
- const readMulticodecTable = (value) => {
80
- if (!Array.isArray(value)) {
81
- throw new ReallyMeCodecError("provider-failure");
82
- }
83
- return value.map(readMulticodecMetadata);
62
+ const validateMulticodecMetadata = (value) => {
63
+ requireNoProviderUnknownFields(value);
64
+ sdkTag(value.tag);
65
+ sdkKeyMaterial(value.keyMaterialKind);
84
66
  };
85
67
  export const base58btcEncode = (bytes) => {
86
68
  ensureBytesInput(bytes);
@@ -104,35 +86,99 @@ export const multibaseDecode = (encoded) => {
104
86
  };
105
87
  export const multicodecPrefixForName = (codecName) => {
106
88
  ensureStringInput(codecName);
107
- return readMulticodecMetadata(requireReallyMeCodecWasmProvider().multicodecPrefixForName(codecName));
108
- };
109
- export const multicodecPrefixForNameProto = (codecName) => {
110
- ensureStringInput(codecName);
111
- return readBytesOutput(requireReallyMeCodecWasmProvider().multicodecPrefixForNameProto(codecName));
112
- };
113
- export const multicodecPrefixForNameProtoResult = (codecName) => {
114
- ensureStringInput(codecName);
115
- return readProtoResultOutput(requireReallyMeCodecWasmProvider().multicodecPrefixForNameProtoResult(codecName));
89
+ const result = processGeneratedOperationRequest(multicodecPrefixForNameRequest(codecName));
90
+ if (result.result.case !== "multicodecPrefixForName") {
91
+ clearGeneratedOperationResult(result);
92
+ throw new ReallyMeCodecError("provider-failure");
93
+ }
94
+ try {
95
+ return readMulticodecMetadata(result.result.value);
96
+ }
97
+ finally {
98
+ result.result.value.prefix.fill(0);
99
+ }
116
100
  };
101
+ const multicodecPrefixForNameRequest = (codecName) => create(CodecOperationRequestSchema, {
102
+ operation: {
103
+ case: "multicodecPrefixForName",
104
+ value: create(CodecMulticodecPrefixForNameRequestSchema, {
105
+ name: codecName,
106
+ }),
107
+ },
108
+ });
117
109
  export const multicodecLookupPrefix = (bytes) => {
118
110
  ensureBytesInput(bytes);
119
- return readMulticodecMetadata(requireReallyMeCodecWasmProvider().multicodecLookupPrefix(bytes));
120
- };
121
- export const multicodecLookupPrefixProto = (bytes) => {
122
- ensureBytesInput(bytes);
123
- return readBytesOutput(requireReallyMeCodecWasmProvider().multicodecLookupPrefixProto(bytes));
124
- };
125
- export const multicodecLookupPrefixProtoResult = (bytes) => {
126
- ensureBytesInput(bytes);
127
- return readProtoResultOutput(requireReallyMeCodecWasmProvider().multicodecLookupPrefixProtoResult(bytes));
111
+ const bytesSnapshot = snapshotBoundedBytesInput(bytes);
112
+ try {
113
+ const operationResult = processGeneratedOperationRequest(multicodecLookupPrefixRequest(bytesSnapshot));
114
+ if (operationResult.result.case !== "multicodecLookupPrefix") {
115
+ clearGeneratedOperationResult(operationResult);
116
+ throw new ReallyMeCodecError("provider-failure");
117
+ }
118
+ const result = operationResult.result.value;
119
+ try {
120
+ requireNoProviderUnknownFields(result);
121
+ if (result.metadata === undefined) {
122
+ throw new ReallyMeCodecError("provider-failure");
123
+ }
124
+ return {
125
+ name: result.name,
126
+ prefixLength: result.prefixLength,
127
+ metadata: readMulticodecMetadata(result.metadata),
128
+ };
129
+ }
130
+ finally {
131
+ result.metadata?.prefix.fill(0);
132
+ }
133
+ }
134
+ finally {
135
+ bytesSnapshot.fill(0);
136
+ }
128
137
  };
138
+ const multicodecLookupPrefixRequest = (bytes) => create(CodecOperationRequestSchema, {
139
+ operation: {
140
+ case: "multicodecLookupPrefix",
141
+ value: create(CodecMulticodecLookupPrefixRequestSchema, {
142
+ value: bytes,
143
+ }),
144
+ },
145
+ });
129
146
  export const multicodecStripPrefix = (bytes) => {
130
147
  ensureBytesInput(bytes);
131
148
  return readBytesOutput(requireReallyMeCodecWasmProvider().multicodecStripPrefix(bytes));
132
149
  };
133
- export const multicodecTable = () => readMulticodecTable(requireReallyMeCodecWasmProvider().multicodecTable());
134
- export const multicodecTableProto = () => readBytesOutput(requireReallyMeCodecWasmProvider().multicodecTableProto());
135
- export const multicodecTableProtoResult = () => readProtoResultOutput(requireReallyMeCodecWasmProvider().multicodecTableProtoResult());
150
+ export const multicodecTable = () => {
151
+ const operationResult = processGeneratedOperationRequest(multicodecTableRequest());
152
+ if (operationResult.result.case !== "multicodecTable") {
153
+ clearGeneratedOperationResult(operationResult);
154
+ throw new ReallyMeCodecError("provider-failure");
155
+ }
156
+ const result = operationResult.result.value;
157
+ try {
158
+ requireNoProviderUnknownFields(result);
159
+ if (result.entries.length > MAX_MULTICODEC_TABLE_ENTRIES) {
160
+ throw new ReallyMeCodecError("provider-failure");
161
+ }
162
+ // Validate every entry before making caller-owned byte copies. If one
163
+ // entry is malformed, no earlier prefix copy can become unreachable
164
+ // without an explicit wipe while the generated response is rejected.
165
+ for (const entry of result.entries) {
166
+ validateMulticodecMetadata(entry);
167
+ }
168
+ return { entries: result.entries.map((entry) => readMulticodecMetadata(entry)) };
169
+ }
170
+ finally {
171
+ for (const entry of result.entries) {
172
+ entry.prefix.fill(0);
173
+ }
174
+ }
175
+ };
176
+ const multicodecTableRequest = () => create(CodecOperationRequestSchema, {
177
+ operation: {
178
+ case: "multicodecTable",
179
+ value: create(CodecMulticodecTableRequestSchema),
180
+ },
181
+ });
136
182
  export const multikeyEncode = (codecName, publicKey) => {
137
183
  ensureStringInput(codecName);
138
184
  ensureBytesInput(publicKey);
@@ -140,16 +186,34 @@ export const multikeyEncode = (codecName, publicKey) => {
140
186
  };
141
187
  export const multikeyParse = (multikey) => {
142
188
  ensureStringInput(multikey);
143
- return readParsedMultikey(requireReallyMeCodecWasmProvider().multikeyParse(multikey));
144
- };
145
- export const multikeyParseProto = (multikey) => {
146
- ensureStringInput(multikey);
147
- return readBytesOutput(requireReallyMeCodecWasmProvider().multikeyParseProto(multikey));
148
- };
149
- export const multikeyParseProtoResult = (multikey) => {
150
- ensureStringInput(multikey);
151
- return readProtoResultOutput(requireReallyMeCodecWasmProvider().multikeyParseProtoResult(multikey));
189
+ const operationResult = processGeneratedOperationRequest(multikeyParseRequest(multikey));
190
+ if (operationResult.result.case !== "multikeyParse") {
191
+ clearGeneratedOperationResult(operationResult);
192
+ throw new ReallyMeCodecError("provider-failure");
193
+ }
194
+ const result = operationResult.result.value;
195
+ try {
196
+ requireNoProviderUnknownFields(result);
197
+ const parsed = {
198
+ codecName: result.codecName,
199
+ algorithmName: result.algorithmName,
200
+ publicKey: result.publicKey.slice(),
201
+ };
202
+ if (result.variablePublicKeyLength || result.expectedPublicKeyLength === 0) {
203
+ return parsed;
204
+ }
205
+ return { ...parsed, expectedPublicKeyLength: result.expectedPublicKeyLength };
206
+ }
207
+ finally {
208
+ result.publicKey.fill(0);
209
+ }
152
210
  };
211
+ const multikeyParseRequest = (multikey) => create(CodecOperationRequestSchema, {
212
+ operation: {
213
+ case: "multikeyParse",
214
+ value: create(CodecMultikeyParseRequestSchema, { multikey }),
215
+ },
216
+ });
153
217
  export const bindingTypeMatchesCodec = (bindingType, codecName) => {
154
218
  ensureStringInput(bindingType);
155
219
  ensureStringInput(codecName);
@@ -0,0 +1,31 @@
1
+ import type { CodecOperationRequest, CodecOperationResult } from "./proto/generated/reallyme/codec/v1/codec_pb.js";
2
+ /**
3
+ * Execute one binary generated-protobuf request and return the fully
4
+ * discriminated binary `CodecOperationResponse`.
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.
9
+ */
10
+ export declare const processOperation: (requestBytes: Uint8Array) => Uint8Array;
11
+ /**
12
+ * Execute one generated ProtoJSON request and return the same discriminated
13
+ * binary response used by `processOperation`.
14
+ */
15
+ export declare const processOperationJson: (requestJson: Uint8Array) => Uint8Array;
16
+ /**
17
+ * Execute a generated request through the fully discriminated response lane.
18
+ *
19
+ * Structured convenience methods use this boundary so a provider cannot
20
+ * return a valid payload of the wrong operation-specific result type.
21
+ */
22
+ export declare const processGeneratedOperationRequest: (request: CodecOperationRequest) => CodecOperationResult;
23
+ /**
24
+ * Clears mutable byte owners held by a generated operation result.
25
+ *
26
+ * Callers invoke this before rejecting an unexpected valid oneof variant and
27
+ * after copying a sensitive result into its public SDK owner. JavaScript
28
+ * strings remain subject to the managed-runtime memory model, but every
29
+ * mutable `Uint8Array` created by this adapter is released promptly.
30
+ */
31
+ export declare const clearGeneratedOperationResult: (result: CodecOperationResult) => void;