@totemsdk/manifest 0.1.0 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Totem SDK Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -217,7 +217,7 @@ interface EdgeServiceManifest {
217
217
 
218
218
  ## See also
219
219
 
220
- - [`@totemsdk/core`](../core) — WOTS signing primitives used internally
221
- - [`@totemsdk/lookup-protocol`](../lookup-protocol) — embeds `encodeManifest()` output in `APP_ANNOUNCE` / `AGENT_ANNOUNCE` messages
222
- - [`@totemsdk/wots-lease`](../wots-lease) — manage WOTS key index reservation before calling `signManifest`
223
- - [`@totemsdk/root-identity`](../root-identity) — optional `rootIdentityProof` field for chain-of-custody linking
220
+ - [`@totemsdk/core`](https://www.npmjs.com/package/@totemsdk/core) — WOTS signing primitives used internally
221
+ - [`@totemsdk/lookup-protocol`](https://www.npmjs.com/package/@totemsdk/lookup-protocol) — embeds `encodeManifest()` output in `APP_ANNOUNCE` / `AGENT_ANNOUNCE` messages
222
+ - [`@totemsdk/wots-lease`](https://www.npmjs.com/package/@totemsdk/wots-lease) — manage WOTS key index reservation before calling `signManifest`
223
+ - [`@totemsdk/root-identity`](https://www.npmjs.com/package/@totemsdk/root-identity) — optional `rootIdentityProof` field for chain-of-custody linking
package/dist/constants.js CHANGED
@@ -1,11 +1,14 @@
1
- export const MANIFEST_VERSION = 1;
2
- export const MANIFEST_TYPE_BYTE = {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANIFEST_BYTE_TO_TYPE = exports.MANIFEST_TYPE_BYTE = exports.MANIFEST_VERSION = void 0;
4
+ exports.MANIFEST_VERSION = 1;
5
+ exports.MANIFEST_TYPE_BYTE = {
3
6
  app: 0x01,
4
7
  capability: 0x02,
5
8
  dapp: 0x03,
6
9
  'edge-service': 0x04,
7
10
  };
8
- export const MANIFEST_BYTE_TO_TYPE = {
11
+ exports.MANIFEST_BYTE_TO_TYPE = {
9
12
  0x01: 'app',
10
13
  0x02: 'capability',
11
14
  0x03: 'dapp',
package/dist/encoding.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * Wire encoding/decoding for SignedManifest.
3
4
  *
@@ -12,15 +13,18 @@
12
13
  * The trailing WOTS signature bytes are stored separately for easy extraction by
13
14
  * the DHT / lookup-protocol layer without needing to parse the JSON.
14
15
  */
15
- import { MANIFEST_VERSION, MANIFEST_TYPE_BYTE, MANIFEST_BYTE_TO_TYPE } from './constants.js';
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.encodeManifest = encodeManifest;
18
+ exports.decodeManifest = decodeManifest;
19
+ const constants_js_1 = require("./constants.js");
16
20
  function manifestTypeByte(type) {
17
- const byte = MANIFEST_TYPE_BYTE[type];
21
+ const byte = constants_js_1.MANIFEST_TYPE_BYTE[type];
18
22
  if (byte === undefined) {
19
23
  throw new Error(`encodeManifest: unknown manifest type: ${type}`);
20
24
  }
21
25
  return byte;
22
26
  }
23
- export function encodeManifest(signed) {
27
+ function encodeManifest(signed) {
24
28
  const enc = new TextEncoder();
25
29
  const json = JSON.stringify(signed);
26
30
  const jsonBytes = enc.encode(json);
@@ -28,7 +32,7 @@ export function encodeManifest(signed) {
28
32
  const len = jsonBytes.length;
29
33
  const out = new Uint8Array(1 + 1 + 4 + len + sigBytes.length);
30
34
  let offset = 0;
31
- out[offset++] = MANIFEST_VERSION;
35
+ out[offset++] = constants_js_1.MANIFEST_VERSION;
32
36
  out[offset++] = manifestTypeByte(signed.manifest.type);
33
37
  out[offset++] = (len >>> 24) & 0xff;
34
38
  out[offset++] = (len >>> 16) & 0xff;
@@ -39,16 +43,16 @@ export function encodeManifest(signed) {
39
43
  out.set(sigBytes, offset);
40
44
  return out;
41
45
  }
42
- export function decodeManifest(bytes) {
46
+ function decodeManifest(bytes) {
43
47
  if (bytes.length < 6) {
44
48
  throw new Error('decodeManifest: buffer too short (< 6 bytes)');
45
49
  }
46
50
  const version = bytes[0];
47
- if (version !== MANIFEST_VERSION) {
51
+ if (version !== constants_js_1.MANIFEST_VERSION) {
48
52
  throw new Error(`decodeManifest: unsupported MANIFEST_VERSION ${version}`);
49
53
  }
50
54
  const typeByte = bytes[1];
51
- const expectedType = MANIFEST_BYTE_TO_TYPE[typeByte];
55
+ const expectedType = constants_js_1.MANIFEST_BYTE_TO_TYPE[typeByte];
52
56
  if (!expectedType) {
53
57
  throw new Error(`decodeManifest: unknown type discriminant 0x${typeByte.toString(16).padStart(2, '0')}`);
54
58
  }
package/dist/guards.js CHANGED
@@ -1,7 +1,13 @@
1
+ "use strict";
1
2
  /**
2
3
  * Type guards for manifest kinds.
3
4
  * Each guard accepts a raw Manifest or a SignedManifest.
4
5
  */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isAppManifest = isAppManifest;
8
+ exports.isCapabilityManifest = isCapabilityManifest;
9
+ exports.isDAppManifest = isDAppManifest;
10
+ exports.isEdgeServiceManifest = isEdgeServiceManifest;
5
11
  function getRawManifest(input) {
6
12
  if (!input || typeof input !== 'object')
7
13
  return null;
@@ -12,15 +18,15 @@ function getRawManifest(input) {
12
18
  return input;
13
19
  return null;
14
20
  }
15
- export function isAppManifest(input) {
21
+ function isAppManifest(input) {
16
22
  return getRawManifest(input)?.type === 'app';
17
23
  }
18
- export function isCapabilityManifest(input) {
24
+ function isCapabilityManifest(input) {
19
25
  return getRawManifest(input)?.type === 'capability';
20
26
  }
21
- export function isDAppManifest(input) {
27
+ function isDAppManifest(input) {
22
28
  return getRawManifest(input)?.type === 'dapp';
23
29
  }
24
- export function isEdgeServiceManifest(input) {
30
+ function isEdgeServiceManifest(input) {
25
31
  return getRawManifest(input)?.type === 'edge-service';
26
32
  }
package/dist/id.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * computeManifestId — deterministic stable ID for any manifest.
3
4
  *
@@ -10,13 +11,15 @@
10
11
  * DAppManifest → "dapp" + authorAddress + contractHash
11
12
  * EdgeServiceManifest → "edge-service" + operatorAddress + serviceType + name
12
13
  */
13
- import { sha3_256 } from '@noble/hashes/sha3.js';
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.computeManifestId = computeManifestId;
16
+ const sha3_js_1 = require("@noble/hashes/sha3.js");
14
17
  function bytesToHex(b) {
15
18
  return Array.from(b)
16
19
  .map((x) => x.toString(16).padStart(2, '0'))
17
20
  .join('');
18
21
  }
19
- export function computeManifestId(manifest) {
22
+ function computeManifestId(manifest) {
20
23
  let stableKey;
21
24
  switch (manifest.type) {
22
25
  case 'app':
@@ -36,5 +39,5 @@ export function computeManifestId(manifest) {
36
39
  throw new Error(`computeManifestId: unknown manifest type: ${JSON.stringify(_exhaustive)}`);
37
40
  }
38
41
  }
39
- return bytesToHex(sha3_256(new TextEncoder().encode(stableKey)));
42
+ return bytesToHex((0, sha3_js_1.sha3_256)(new TextEncoder().encode(stableKey)));
40
43
  }
package/dist/index.js CHANGED
@@ -1,6 +1,19 @@
1
- export { MANIFEST_VERSION } from './constants.js';
2
- export { computeManifestId } from './id.js';
3
- export { signManifest } from './sign.js';
4
- export { verifyManifest } from './verify.js';
5
- export { encodeManifest, decodeManifest } from './encoding.js';
6
- export { isAppManifest, isCapabilityManifest, isDAppManifest, isEdgeServiceManifest, } from './guards.js';
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEdgeServiceManifest = exports.isDAppManifest = exports.isCapabilityManifest = exports.isAppManifest = exports.decodeManifest = exports.encodeManifest = exports.verifyManifest = exports.signManifest = exports.computeManifestId = exports.MANIFEST_VERSION = void 0;
4
+ var constants_js_1 = require("./constants.js");
5
+ Object.defineProperty(exports, "MANIFEST_VERSION", { enumerable: true, get: function () { return constants_js_1.MANIFEST_VERSION; } });
6
+ var id_js_1 = require("./id.js");
7
+ Object.defineProperty(exports, "computeManifestId", { enumerable: true, get: function () { return id_js_1.computeManifestId; } });
8
+ var sign_js_1 = require("./sign.js");
9
+ Object.defineProperty(exports, "signManifest", { enumerable: true, get: function () { return sign_js_1.signManifest; } });
10
+ var verify_js_1 = require("./verify.js");
11
+ Object.defineProperty(exports, "verifyManifest", { enumerable: true, get: function () { return verify_js_1.verifyManifest; } });
12
+ var encoding_js_1 = require("./encoding.js");
13
+ Object.defineProperty(exports, "encodeManifest", { enumerable: true, get: function () { return encoding_js_1.encodeManifest; } });
14
+ Object.defineProperty(exports, "decodeManifest", { enumerable: true, get: function () { return encoding_js_1.decodeManifest; } });
15
+ var guards_js_1 = require("./guards.js");
16
+ Object.defineProperty(exports, "isAppManifest", { enumerable: true, get: function () { return guards_js_1.isAppManifest; } });
17
+ Object.defineProperty(exports, "isCapabilityManifest", { enumerable: true, get: function () { return guards_js_1.isCapabilityManifest; } });
18
+ Object.defineProperty(exports, "isDAppManifest", { enumerable: true, get: function () { return guards_js_1.isDAppManifest; } });
19
+ Object.defineProperty(exports, "isEdgeServiceManifest", { enumerable: true, get: function () { return guards_js_1.isEdgeServiceManifest; } });
package/dist/sign.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * signManifest — signs a manifest with a WOTS key.
3
4
  *
@@ -14,8 +15,11 @@
14
15
  * The caller is responsible for reserving the WOTS key index before calling
15
16
  * this function. This package does NOT depend on @totemsdk/wots-lease.
16
17
  */
17
- import { sha3_256 } from '@noble/hashes/sha3.js';
18
- import { wotsSign, wotsKeypairFromSeed, wotsAddressFromKeypair, bytesToHex, } from '@totemsdk/core';
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.manifestDigest = manifestDigest;
20
+ exports.signManifest = signManifest;
21
+ const sha3_js_1 = require("@noble/hashes/sha3.js");
22
+ const core_1 = require("@totemsdk/core");
19
23
  /** Produce a deterministic canonical JSON string with sorted keys (recursive). */
20
24
  function canonicalJson(value) {
21
25
  if (value === null || typeof value !== 'object') {
@@ -29,20 +33,20 @@ function canonicalJson(value) {
29
33
  const pairs = keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(obj[k])}`);
30
34
  return '{' + pairs.join(',') + '}';
31
35
  }
32
- export function manifestDigest(manifest) {
36
+ function manifestDigest(manifest) {
33
37
  const canonical = canonicalJson(manifest);
34
- return sha3_256(new TextEncoder().encode(canonical));
38
+ return (0, sha3_js_1.sha3_256)(new TextEncoder().encode(canonical));
35
39
  }
36
- export async function signManifest(manifest, seed, keyIndex) {
40
+ async function signManifest(manifest, seed, keyIndex) {
37
41
  const digest = manifestDigest(manifest);
38
- const sigBytes = wotsSign(seed, keyIndex, digest);
39
- const kp = wotsKeypairFromSeed(seed, keyIndex);
40
- const address = wotsAddressFromKeypair(kp);
42
+ const sigBytes = (0, core_1.wotsSign)(seed, keyIndex, digest);
43
+ const kp = (0, core_1.wotsKeypairFromSeed)(seed, keyIndex);
44
+ const address = (0, core_1.wotsAddressFromKeypair)(kp);
41
45
  return {
42
46
  manifest,
43
47
  authorAddress: address,
44
- signerPublicKey: bytesToHex(kp.pk),
48
+ signerPublicKey: (0, core_1.bytesToHex)(kp.pk),
45
49
  signedAt: Date.now(),
46
- signature: bytesToHex(sigBytes),
50
+ signature: (0, core_1.bytesToHex)(sigBytes),
47
51
  };
48
52
  }
package/dist/types.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * @totemsdk/manifest — Manifest type definitions
3
4
  *
@@ -9,4 +10,4 @@
9
10
  *
10
11
  * No network, no blockchain, no Hyperswarm — pure schema.
11
12
  */
12
- export {};
13
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/verify.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * verifyManifest — verifies a SignedManifest without external state.
3
4
  *
@@ -11,8 +12,10 @@
11
12
  * stores the 32-byte WOTS PKdigest as returned by wotsKeypairFromSeed.kp.pk.
12
13
  * The full 1088-byte key is not stored in SignedManifest to keep it compact.
13
14
  */
14
- import { wotsVerifyDigest, hexToBytes } from '@totemsdk/core';
15
- import { manifestDigest } from './sign.js';
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.verifyManifest = verifyManifest;
17
+ const core_1 = require("@totemsdk/core");
18
+ const sign_js_1 = require("./sign.js");
16
19
  function manifestAddressField(manifest) {
17
20
  switch (manifest.type) {
18
21
  case 'app': return manifest.authorAddress;
@@ -25,21 +28,21 @@ function manifestAddressField(manifest) {
25
28
  }
26
29
  }
27
30
  }
28
- export function verifyManifest(signed) {
31
+ function verifyManifest(signed) {
29
32
  const { manifest, signature, signerPublicKey, authorAddress } = signed;
30
33
  let sigBytes;
31
34
  let pkDigest;
32
35
  try {
33
- sigBytes = hexToBytes(signature);
34
- pkDigest = hexToBytes(signerPublicKey);
36
+ sigBytes = (0, core_1.hexToBytes)(signature);
37
+ pkDigest = (0, core_1.hexToBytes)(signerPublicKey);
35
38
  }
36
39
  catch (e) {
37
40
  return { valid: false, reason: `hex decode failed: ${String(e)}`, signerAddress: authorAddress };
38
41
  }
39
- const digest = manifestDigest(manifest);
42
+ const digest = (0, sign_js_1.manifestDigest)(manifest);
40
43
  let sigValid;
41
44
  try {
42
- sigValid = wotsVerifyDigest(sigBytes, digest, pkDigest);
45
+ sigValid = (0, core_1.wotsVerifyDigest)(sigBytes, digest, pkDigest);
43
46
  }
44
47
  catch (e) {
45
48
  return { valid: false, reason: `WOTS verify threw: ${String(e)}`, signerAddress: authorAddress };
package/package.json CHANGED
@@ -1,25 +1,26 @@
1
1
  {
2
2
  "name": "@totemsdk/manifest",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Canonical signed declaration format for Totem Edge entities — apps, agent capabilities, dApps, and edge services",
5
- "type": "module",
6
5
  "main": "dist/index.js",
7
6
  "types": "dist/index.d.ts",
8
7
  "exports": {
9
8
  ".": {
10
9
  "types": "./dist/index.d.ts",
10
+ "require": "./dist/index.js",
11
11
  "import": "./dist/index.js"
12
12
  }
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
- "src"
16
+ "README.md",
17
+ "LICENSE"
17
18
  ],
18
19
  "dependencies": {
19
20
  "@totemsdk/core": "1.0.9"
20
21
  },
21
22
  "peerDependencies": {
22
- "@noble/hashes": ">=1.3.0 <2.0.0"
23
+ "@noble/hashes": ">=1.3.0"
23
24
  },
24
25
  "peerDependenciesMeta": {
25
26
  "@noble/hashes": {
@@ -27,7 +28,7 @@
27
28
  }
28
29
  },
29
30
  "devDependencies": {
30
- "@noble/hashes": "^1.3.0",
31
+ "@noble/hashes": "^2.2.0",
31
32
  "@types/jest": "^29.0.0",
32
33
  "@types/node": "^20.0.0",
33
34
  "jest": "^29.0.0",
@@ -41,6 +42,26 @@
41
42
  "access": "public"
42
43
  },
43
44
  "license": "MIT",
45
+ "author": "Totem SDK",
46
+ "homepage": "https://totemsdk.com",
47
+ "bugs": {
48
+ "url": "https://github.com/MrGheek/axia-totem/issues"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/MrGheek/axia-totem.git",
53
+ "directory": "packages/totem-sdk/packages/manifest"
54
+ },
55
+ "keywords": [
56
+ "totem",
57
+ "totemsdk",
58
+ "minima",
59
+ "blockchain",
60
+ "quantum-resistant",
61
+ "wots",
62
+ "kissvm",
63
+ "utxo"
64
+ ],
44
65
  "scripts": {
45
66
  "build": "tsc",
46
67
  "clean": "rm -rf dist",
@@ -1,185 +0,0 @@
1
- /**
2
- * encoding.test.ts
3
- * encode → decode round-trips for all four manifest types.
4
- */
5
-
6
- import { signManifest } from '../sign.js';
7
- import { encodeManifest, decodeManifest } from '../encoding.js';
8
- import { MANIFEST_VERSION, MANIFEST_TYPE_BYTE } from '../constants.js';
9
- import type {
10
- AppManifest,
11
- CapabilityManifest,
12
- DAppManifest,
13
- EdgeServiceManifest,
14
- } from '../types.js';
15
-
16
- jest.setTimeout(60_000);
17
-
18
- const TEST_SEED = new Uint8Array(32).fill(0x11);
19
- const KEY_INDEX = 0;
20
-
21
- let resolvedAddress: string;
22
-
23
- beforeAll(async () => {
24
- const tmp = await signManifest(
25
- {
26
- type: 'app',
27
- appId: '',
28
- name: 'init',
29
- version: '1.0.0',
30
- authorAddress: 'MxINIT',
31
- pearTopicKey: 'a'.repeat(64),
32
- price: '0',
33
- category: [],
34
- permissions: [],
35
- description: '',
36
- minTotemVersion: '0.1.0',
37
- } satisfies AppManifest,
38
- TEST_SEED,
39
- KEY_INDEX,
40
- );
41
- resolvedAddress = tmp.authorAddress;
42
- });
43
-
44
- describe('encodeManifest / decodeManifest', () => {
45
- it('round-trips AppManifest and preserves manifest type', async () => {
46
- const manifest: AppManifest = {
47
- type: 'app',
48
- appId: 'abc123',
49
- name: 'My App',
50
- version: '1.0.0',
51
- authorAddress: resolvedAddress,
52
- pearTopicKey: 'f'.repeat(64),
53
- price: '0',
54
- category: ['finance'],
55
- permissions: ['wallet:read-balance'],
56
- description: 'Test',
57
- minTotemVersion: '0.1.0',
58
- };
59
- const signed = await signManifest(manifest, TEST_SEED, KEY_INDEX);
60
- const encoded = encodeManifest(signed);
61
- const decoded = decodeManifest(encoded);
62
-
63
- expect(decoded.manifest.type).toBe('app');
64
- expect(decoded.manifest.type).toBe(signed.manifest.type);
65
- expect((decoded.manifest as AppManifest).name).toBe('My App');
66
- expect(decoded.signature).toBe(signed.signature);
67
- });
68
-
69
- it('round-trips CapabilityManifest', async () => {
70
- const manifest: CapabilityManifest = {
71
- type: 'capability',
72
- capabilityId: 'cap1',
73
- capabilityName: 'price-oracle',
74
- agentAddress: resolvedAddress,
75
- agentIdentityKey: 'e'.repeat(64),
76
- description: 'Price oracle',
77
- inputSchema: { type: 'object' },
78
- outputSchema: { type: 'object' },
79
- pricePerCall: '2',
80
- expiresAt: Date.now() + 3600_000,
81
- tags: ['oracle'],
82
- };
83
- const signed = await signManifest(manifest, TEST_SEED, KEY_INDEX);
84
- const encoded = encodeManifest(signed);
85
- const decoded = decodeManifest(encoded);
86
-
87
- expect(decoded.manifest.type).toBe('capability');
88
- expect((decoded.manifest as CapabilityManifest).capabilityName).toBe('price-oracle');
89
- });
90
-
91
- it('round-trips DAppManifest', async () => {
92
- const manifest: DAppManifest = {
93
- type: 'dapp',
94
- dappId: 'dapp1',
95
- name: 'Swap dApp',
96
- version: '2.0.0',
97
- authorAddress: resolvedAddress,
98
- contractHash: 'd'.repeat(64),
99
- abi: [],
100
- price: '5',
101
- category: ['defi'],
102
- description: 'A swap contract',
103
- };
104
- const signed = await signManifest(manifest, TEST_SEED, KEY_INDEX);
105
- const encoded = encodeManifest(signed);
106
- const decoded = decodeManifest(encoded);
107
-
108
- expect(decoded.manifest.type).toBe('dapp');
109
- expect((decoded.manifest as DAppManifest).name).toBe('Swap dApp');
110
- });
111
-
112
- it('round-trips EdgeServiceManifest', async () => {
113
- const manifest: EdgeServiceManifest = {
114
- type: 'edge-service',
115
- serviceId: 'edge1',
116
- name: 'DHT Relay',
117
- version: '1.0.0',
118
- operatorAddress: resolvedAddress,
119
- serviceType: 'omnia-router',
120
- description: 'Omnia routing node',
121
- capabilities: ['relay'],
122
- tags: ['infrastructure'],
123
- };
124
- const signed = await signManifest(manifest, TEST_SEED, KEY_INDEX);
125
- const encoded = encodeManifest(signed);
126
- const decoded = decodeManifest(encoded);
127
-
128
- expect(decoded.manifest.type).toBe('edge-service');
129
- expect((decoded.manifest as EdgeServiceManifest).serviceType).toBe('omnia-router');
130
- });
131
-
132
- it('first byte is MANIFEST_VERSION', async () => {
133
- const manifest: AppManifest = {
134
- type: 'app',
135
- appId: '',
136
- name: 'v-test',
137
- version: '1.0.0',
138
- authorAddress: resolvedAddress,
139
- pearTopicKey: 'a'.repeat(64),
140
- price: '0',
141
- category: [],
142
- permissions: [],
143
- description: '',
144
- minTotemVersion: '0.1.0',
145
- };
146
- const signed = await signManifest(manifest, TEST_SEED, KEY_INDEX);
147
- const encoded = encodeManifest(signed);
148
- expect(encoded[0]).toBe(MANIFEST_VERSION);
149
- });
150
-
151
- it('second byte is correct type discriminant', async () => {
152
- const appSigned = await signManifest(
153
- { type: 'app', appId: '', name: 'x', version: '1.0.0', authorAddress: resolvedAddress, pearTopicKey: 'a'.repeat(64), price: '0', category: [], permissions: [], description: '', minTotemVersion: '0.1.0' } satisfies AppManifest,
154
- TEST_SEED, KEY_INDEX,
155
- );
156
- expect(encodeManifest(appSigned)[1]).toBe(MANIFEST_TYPE_BYTE.app);
157
-
158
- const capSigned = await signManifest(
159
- { type: 'capability', capabilityId: '', capabilityName: 'x', agentAddress: resolvedAddress, agentIdentityKey: 'e'.repeat(64), description: '', inputSchema: {}, outputSchema: {}, pricePerCall: '1', expiresAt: 0, tags: [] } satisfies CapabilityManifest,
160
- TEST_SEED, KEY_INDEX,
161
- );
162
- expect(encodeManifest(capSigned)[1]).toBe(MANIFEST_TYPE_BYTE.capability);
163
-
164
- const edgeSigned = await signManifest(
165
- { type: 'edge-service', serviceId: '', name: 'x', version: '1.0.0', operatorAddress: resolvedAddress, serviceType: 'sensor', description: '', capabilities: [], tags: [] } satisfies EdgeServiceManifest,
166
- TEST_SEED, KEY_INDEX,
167
- );
168
- expect(encodeManifest(edgeSigned)[1]).toBe(MANIFEST_TYPE_BYTE['edge-service']);
169
- });
170
-
171
- it('throws on unknown type discriminant byte', () => {
172
- const bad = new Uint8Array([1, 0xff, 0, 0, 0, 5, 104, 101, 108, 108, 111]);
173
- expect(() => decodeManifest(bad)).toThrow(/unknown type discriminant/);
174
- });
175
-
176
- it('throws on buffer too short', () => {
177
- expect(() => decodeManifest(new Uint8Array([1, 1, 0, 0]))).toThrow(/too short/);
178
- });
179
-
180
- it('throws on MANIFEST_VERSION mismatch', () => {
181
- const bad = new Uint8Array(10).fill(0);
182
- bad[0] = 255;
183
- expect(() => decodeManifest(bad)).toThrow(/unsupported MANIFEST_VERSION/);
184
- });
185
- });