@totemsdk/edge 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 +21 -0
- package/README.md +258 -14
- package/dist/canonical.js +6 -2
- package/dist/capabilities.js +12 -6
- package/dist/constants.js +4 -1
- package/dist/device.js +10 -6
- package/dist/errors.js +5 -1
- package/dist/index.js +24 -7
- package/dist/ports.js +2 -1
- package/dist/provider.js +20 -14
- package/dist/receipts.js +11 -7
- package/dist/runtime.js +9 -6
- package/dist/types.js +2 -1
- package/package.json +29 -9
- package/src/__tests__/edge.test.ts +0 -370
- package/src/canonical.ts +0 -29
- package/src/capabilities.ts +0 -115
- package/src/constants.ts +0 -1
- package/src/device.ts +0 -30
- package/src/errors.ts +0 -15
- package/src/index.ts +0 -52
- package/src/ports.ts +0 -75
- package/src/provider.ts +0 -77
- package/src/receipts.ts +0 -60
- package/src/runtime.ts +0 -33
- package/src/types.ts +0 -73
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
|
@@ -2,23 +2,267 @@
|
|
|
2
2
|
|
|
3
3
|
Unified developer-facing runtime for Totem Edge.
|
|
4
4
|
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @totemsdk/edge
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> `@totemsdk/connect` is a **peer dependency** used only for the `edgeCapabilitiesFromTotemCapabilities` type bridge. It is imported with `import type` exclusively — no runtime import is emitted, so `@totemsdk/edge` is independently deployable without `@totemsdk/connect` installed.
|
|
12
|
+
|
|
5
13
|
## Design
|
|
6
14
|
|
|
7
|
-
`@totemsdk/edge` composes identity, manifest, wallet/payment/proof/lookup/policy capabilities
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
`@totemsdk/edge` composes identity, manifest, wallet/payment/proof/lookup/policy capabilities via injected port interfaces. It is adapter-neutral — no ROS2, no MQTT, no Python bindings, no direct proof implementation.
|
|
16
|
+
|
|
17
|
+
### Port injection pattern
|
|
18
|
+
|
|
19
|
+
All capability ports (`EdgePaymentPort`, `EdgeLiquidityPort`, `EdgeProofPort`, `EdgeLookupPort`, `EdgePolicyPort`, `EdgeIdentityPort`, `EdgeManifestPort`) are interfaces only. You implement the ports you need and inject them via `EdgeRuntimePorts` at startup. `@totemsdk/edge` ships no proof creation or verification implementations.
|
|
20
|
+
|
|
21
|
+
### Capability set
|
|
22
|
+
|
|
23
|
+
You declare capabilities up front in the `EdgeCapabilitySet`. The runtime does **not** automatically enforce capabilities before port calls — call `runtime.assertCapability(cap)` manually before invoking a port method. This gives fast, explicit failure rather than a cryptic `TypeError` from a missing port reference.
|
|
24
|
+
|
|
25
|
+
## Usage examples
|
|
26
|
+
|
|
27
|
+
### Wire up a runtime with mocked ports
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import {
|
|
31
|
+
createEdgeRuntime,
|
|
32
|
+
createEdgeDevice,
|
|
33
|
+
createCapabilitySet,
|
|
34
|
+
} from '@totemsdk/edge';
|
|
35
|
+
import type { EdgeRuntimePorts, EdgePaymentPort } from '@totemsdk/edge';
|
|
36
|
+
|
|
37
|
+
const paymentPort: EdgePaymentPort = {
|
|
38
|
+
async pay({ recipient, amount }) {
|
|
39
|
+
return { ok: true, data: { txpowId: 'mock-txpow-id' } };
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const ports: EdgeRuntimePorts = { payment: paymentPort };
|
|
44
|
+
const capabilities = createCapabilitySet(['payment:send', 'chain:hosted-provider']);
|
|
45
|
+
|
|
46
|
+
const device = createEdgeDevice({ kind: 'service' });
|
|
47
|
+
const runtime = createEdgeRuntime({ deviceId: device.deviceId, capabilities, ports });
|
|
48
|
+
|
|
49
|
+
runtime.assertCapability('payment:send'); // no-op — present
|
|
50
|
+
const result = await runtime.ports.payment!.pay({ recipient: 'MxABC...', amount: '10' });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Create and publish a service manifest
|
|
54
|
+
|
|
55
|
+
`createEdgeServiceManifest` is a thin wrapper around `signManifest` from `@totemsdk/manifest`. Build the `EdgeServiceManifest` object yourself, then pass it with your WOTS seed and key index.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { createEdgeServiceManifest, bindEdgeServiceIdentity } from '@totemsdk/edge';
|
|
59
|
+
import { computeManifestId } from '@totemsdk/manifest';
|
|
60
|
+
import type { EdgeServiceManifest } from '@totemsdk/manifest';
|
|
61
|
+
import { createIdentityDocument } from '@totemsdk/identity';
|
|
62
|
+
import type { IdentityGraph } from '@totemsdk/identity';
|
|
63
|
+
|
|
64
|
+
// 1. Build the EdgeServiceManifest object
|
|
65
|
+
const rawManifest: EdgeServiceManifest = {
|
|
66
|
+
type: 'edge-service',
|
|
67
|
+
serviceId: '', // filled below
|
|
68
|
+
name: 'temperature-monitor-v1',
|
|
69
|
+
version: '1.0.0',
|
|
70
|
+
operatorAddress: 'MxABC123...',
|
|
71
|
+
serviceType: 'sensor',
|
|
72
|
+
description: 'Real-time temperature telemetry over MQTT',
|
|
73
|
+
endpoints: [{ type: 'mqtt', uri: 'mqtt://edge.example.com:1883/temp' }],
|
|
74
|
+
capabilities: ['temperature:read', 'temperature:stream'],
|
|
75
|
+
tags: ['iot', 'sensor'],
|
|
76
|
+
};
|
|
77
|
+
rawManifest.serviceId = computeManifestId(rawManifest);
|
|
78
|
+
|
|
79
|
+
// 2. Sign — seed = 32-byte WOTS seed, keyIndex = reserved via @totemsdk/wots-lease
|
|
80
|
+
const signed = await createEdgeServiceManifest(rawManifest, seed, keyIndex);
|
|
81
|
+
|
|
82
|
+
// 3. Bind to an identity graph (optional but recommended)
|
|
83
|
+
const identityDoc = createIdentityDocument({
|
|
84
|
+
kind: 'service',
|
|
85
|
+
rootAddress: 'MxABC123...',
|
|
86
|
+
controllerAddress: 'MxABC123...',
|
|
87
|
+
});
|
|
88
|
+
const graph: IdentityGraph = { document: identityDoc, claims: [] };
|
|
89
|
+
const binding = await bindEdgeServiceIdentity(signed, graph);
|
|
90
|
+
// binding.valid — true when manifest signer matches the identity's authorized set
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Create and verify receipts
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { createEdgeReceipt, verifyEdgeReceipt } from '@totemsdk/edge';
|
|
97
|
+
|
|
98
|
+
const receipt = createEdgeReceipt({
|
|
99
|
+
kind: 'payment',
|
|
100
|
+
relatedManifestId: signed.manifest.serviceId,
|
|
101
|
+
payload: { recipient: 'MxDEF456...', amount: '10', txpowId: 'abc123...' },
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// verifyEdgeReceipt returns EdgeOperationResult<{ receipt: EdgeReceipt }> — never a bare boolean
|
|
105
|
+
const result = verifyEdgeReceipt(receipt);
|
|
106
|
+
if (result.ok) {
|
|
107
|
+
console.log('Valid receipt:', result.data!.receipt.receiptId);
|
|
108
|
+
} else {
|
|
109
|
+
console.error('Invalid receipt:', result.error);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API reference
|
|
114
|
+
|
|
115
|
+
### `createEdgeRuntime(opts)`
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
function createEdgeRuntime(opts: {
|
|
119
|
+
deviceId: string;
|
|
120
|
+
capabilities: EdgeCapabilitySet;
|
|
121
|
+
ports: EdgeRuntimePorts;
|
|
122
|
+
}): EdgeRuntime;
|
|
123
|
+
|
|
124
|
+
interface EdgeRuntime {
|
|
125
|
+
version: number;
|
|
126
|
+
deviceId: string;
|
|
127
|
+
capabilities: EdgeCapabilitySet;
|
|
128
|
+
ports: EdgeRuntimePorts;
|
|
129
|
+
hasCapability(cap: EdgeCapability): boolean;
|
|
130
|
+
assertCapability(cap: EdgeCapability): void; // throws EdgeCapabilityError
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `createEdgeDevice(opts)`
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
function createEdgeDevice(opts: {
|
|
138
|
+
kind: EdgeDeviceKind;
|
|
139
|
+
identityId?: string;
|
|
140
|
+
address?: string;
|
|
141
|
+
metadata?: Record<string, unknown>;
|
|
142
|
+
}): EdgeDevice;
|
|
143
|
+
|
|
144
|
+
type EdgeDeviceKind = 'device' | 'app' | 'agent' | 'sensor' | 'robot' | 'gateway' | 'service';
|
|
145
|
+
|
|
146
|
+
interface EdgeDevice {
|
|
147
|
+
deviceId: string; // edge:device:<hash> URI
|
|
148
|
+
kind: EdgeDeviceKind;
|
|
149
|
+
identityId?: string;
|
|
150
|
+
address?: string;
|
|
151
|
+
metadata?: Record<string, unknown>;
|
|
152
|
+
createdAt: number; // Unix ms
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### `createEdgeReceipt(opts)` / `verifyEdgeReceipt(receipt)`
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
function createEdgeReceipt(opts: {
|
|
160
|
+
kind: string;
|
|
161
|
+
relatedManifestId?: string;
|
|
162
|
+
relatedIdentityId?: string;
|
|
163
|
+
payload: Record<string, unknown>;
|
|
164
|
+
issuedAt?: number; // defaults to Date.now()
|
|
165
|
+
}): EdgeReceipt;
|
|
166
|
+
|
|
167
|
+
// Returns EdgeOperationResult<{ receipt: EdgeReceipt }> — never a bare boolean
|
|
168
|
+
function verifyEdgeReceipt(receipt: unknown): EdgeOperationResult<{ receipt: EdgeReceipt }>;
|
|
169
|
+
|
|
170
|
+
interface EdgeReceipt {
|
|
171
|
+
receiptId: string;
|
|
172
|
+
kind: string;
|
|
173
|
+
issuedAt: number;
|
|
174
|
+
relatedManifestId?: string;
|
|
175
|
+
relatedIdentityId?: string;
|
|
176
|
+
payload: Record<string, unknown>;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `createEdgeServiceManifest(manifest, seed, keyIndex)`
|
|
181
|
+
|
|
182
|
+
Thin wrapper around `signManifest` from `@totemsdk/manifest`. Takes a fully-constructed `EdgeServiceManifest` and returns a `SignedManifest`.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
function createEdgeServiceManifest(
|
|
186
|
+
manifest: EdgeServiceManifest,
|
|
187
|
+
seed: Uint8Array,
|
|
188
|
+
keyIndex: number,
|
|
189
|
+
): Promise<SignedManifest<EdgeServiceManifest>>;
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### `bindEdgeServiceIdentity(signedManifest, identityGraph)`
|
|
193
|
+
|
|
194
|
+
Verifies a signed `EdgeServiceManifest` against an `IdentityGraph`. Checks that the WOTS signature is valid and the signer address is authorized by the identity.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
function bindEdgeServiceIdentity(
|
|
198
|
+
signedManifest: SignedManifest<EdgeServiceManifest>,
|
|
199
|
+
identityGraph: IdentityGraph,
|
|
200
|
+
options?: { proofVerifiers?: Record<string, IdentityProofVerifier> },
|
|
201
|
+
): Promise<ManifestIdentityBinding>;
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### `createCapabilitySet` / `hasCapability` / `assertCapability`
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
function createCapabilitySet(caps: EdgeCapability[]): EdgeCapabilitySet;
|
|
208
|
+
function hasCapability(set: EdgeCapabilitySet, cap: EdgeCapability): boolean;
|
|
209
|
+
function assertCapability(set: EdgeCapabilitySet, cap: EdgeCapability): void;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `edgeCapabilitiesFromTotemCapabilities(caps)`
|
|
213
|
+
|
|
214
|
+
Maps a `TotemCapabilities` object from `@totemsdk/connect` to an `EdgeCapabilitySet`. Requires `@totemsdk/connect` to be installed as a peer.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
function edgeCapabilitiesFromTotemCapabilities(caps: TotemCapabilities): EdgeCapabilitySet;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Port interfaces
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface EdgePaymentPort {
|
|
224
|
+
pay(params: { recipient: string; amount: string; tokenId?: string; memo?: string }): Promise<EdgeOperationResult<{ txpowId?: string }>>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
interface EdgeLiquidityPort {
|
|
228
|
+
getBalance(address: string): Promise<EdgeOperationResult<{ balance: string; tokenId: string }>>;
|
|
229
|
+
getUtxos(address: string): Promise<EdgeOperationResult<{ utxos: unknown[] }>>;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface EdgeProofPort {
|
|
233
|
+
createProof(params: { subject: string; claims: unknown[]; context?: Record<string, unknown> }): Promise<EdgeOperationResult<{ proofId: string; proof: unknown }>>;
|
|
234
|
+
verifyProof(params: { proof: unknown; subject?: string }): Promise<EdgeOperationResult<{ valid: boolean; reason?: string }>>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
interface EdgeLookupPort {
|
|
238
|
+
lookup(params: { query: string; kind?: string }): Promise<EdgeOperationResult<{ results: unknown[] }>>;
|
|
239
|
+
watch(params: { address: string; onUpdate: (data: unknown) => void }): Promise<EdgeOperationResult<{ unsubscribe: () => void }>>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
interface EdgePolicyPort {
|
|
243
|
+
check(params: { action: string; subject: string; context?: Record<string, unknown> }): Promise<EdgeOperationResult<{ allowed: boolean; reason?: string }>>;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface EdgeIdentityPort {
|
|
247
|
+
resolve(identityId: string): Promise<EdgeOperationResult<{ identity: unknown }>>;
|
|
248
|
+
verify(proof: unknown): Promise<EdgeOperationResult<{ valid: boolean; address?: string }>>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
interface EdgeManifestPort {
|
|
252
|
+
sign(manifest: unknown, seed: Uint8Array, keyIndex: number): Promise<EdgeOperationResult<{ signed: unknown }>>;
|
|
253
|
+
verify(signed: unknown): Promise<EdgeOperationResult<{ valid: boolean; reason?: string }>>;
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`EdgeOperationResult<T>` is `{ ok: boolean; data?: T; error?: string; errorCode?: string }`.
|
|
10
258
|
|
|
11
|
-
##
|
|
259
|
+
## Related packages
|
|
12
260
|
|
|
13
|
-
`
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
independently deployable without `@totemsdk/connect` being installed at runtime.
|
|
261
|
+
- [`@totemsdk/manifest`](https://www.npmjs.com/package/@totemsdk/manifest) — manifest schemas and signing
|
|
262
|
+
- [`@totemsdk/identity`](https://www.npmjs.com/package/@totemsdk/identity) — identity documents and claims
|
|
263
|
+
- [`@totemsdk/core`](https://www.npmjs.com/package/@totemsdk/core) — WOTS signing primitives
|
|
264
|
+
- [`@totemsdk/wots-lease`](https://www.npmjs.com/package/@totemsdk/wots-lease) — WOTS key index reservation
|
|
18
265
|
|
|
19
|
-
##
|
|
266
|
+
## License
|
|
20
267
|
|
|
21
|
-
|
|
22
|
-
`EdgeLookupPort`, `EdgePolicyPort`, `EdgeIdentityPort`, `EdgeManifestPort`) are
|
|
23
|
-
interfaces only. Callers inject implementations at runtime via `EdgeRuntimePorts`.
|
|
24
|
-
`@totemsdk/edge` ships no proof creation/verification implementations.
|
|
268
|
+
MIT
|
package/dist/canonical.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toHex = toHex;
|
|
4
|
+
exports.canonicalJson = canonicalJson;
|
|
1
5
|
/**
|
|
2
6
|
* Plain hex encoder (no 0x prefix) for use in ID URIs and deterministic identifiers.
|
|
3
7
|
* bytesToHex from @totemsdk/core adds a 0x prefix — use this for URI-safe hex IDs.
|
|
4
8
|
*/
|
|
5
|
-
|
|
9
|
+
function toHex(bytes) {
|
|
6
10
|
return Array.from(bytes)
|
|
7
11
|
.map((b) => b.toString(16).padStart(2, '0'))
|
|
8
12
|
.join('');
|
|
@@ -14,7 +18,7 @@ export function toHex(bytes) {
|
|
|
14
18
|
* so both packages remain independently deployable. If a shared helper is
|
|
15
19
|
* extracted to a low-level package in a future task it can replace both copies.
|
|
16
20
|
*/
|
|
17
|
-
|
|
21
|
+
function canonicalJson(value) {
|
|
18
22
|
if (value === null || typeof value !== 'object') {
|
|
19
23
|
return JSON.stringify(value);
|
|
20
24
|
}
|
package/dist/capabilities.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Edge capability model.
|
|
3
4
|
*
|
|
@@ -5,16 +6,21 @@
|
|
|
5
6
|
* edgeCapabilitiesFromTotemCapabilities maps @totemsdk/connect's TotemCapabilities
|
|
6
7
|
* to an EdgeCapabilitySet without any runtime import of @totemsdk/connect.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createCapabilitySet = createCapabilitySet;
|
|
11
|
+
exports.hasCapability = hasCapability;
|
|
12
|
+
exports.assertCapability = assertCapability;
|
|
13
|
+
exports.edgeCapabilitiesFromTotemCapabilities = edgeCapabilitiesFromTotemCapabilities;
|
|
14
|
+
const errors_js_1 = require("./errors.js");
|
|
15
|
+
function createCapabilitySet(caps) {
|
|
10
16
|
return new Set(caps);
|
|
11
17
|
}
|
|
12
|
-
|
|
18
|
+
function hasCapability(set, cap) {
|
|
13
19
|
return set.has(cap);
|
|
14
20
|
}
|
|
15
|
-
|
|
21
|
+
function assertCapability(set, cap) {
|
|
16
22
|
if (!set.has(cap)) {
|
|
17
|
-
throw new EdgeCapabilityError(cap);
|
|
23
|
+
throw new errors_js_1.EdgeCapabilityError(cap);
|
|
18
24
|
}
|
|
19
25
|
}
|
|
20
26
|
/**
|
|
@@ -24,7 +30,7 @@ export function assertCapability(set, cap) {
|
|
|
24
30
|
* @totemsdk/connect is imported as a type-only import — no runtime import
|
|
25
31
|
* is emitted, preserving independent deployability of @totemsdk/edge.
|
|
26
32
|
*/
|
|
27
|
-
|
|
33
|
+
function edgeCapabilitiesFromTotemCapabilities(caps) {
|
|
28
34
|
const result = [];
|
|
29
35
|
const { wallet, account, chain, txpow, omnia, statechain, scripting, qvac } = caps;
|
|
30
36
|
if (wallet.selfCustody)
|
package/dist/constants.js
CHANGED
package/dist/device.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Edge device factory.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createEdgeDevice = createEdgeDevice;
|
|
7
|
+
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
8
|
+
const canonical_js_1 = require("./canonical.js");
|
|
9
|
+
function createEdgeDevice(opts) {
|
|
7
10
|
const { kind, identityId, address, metadata } = opts;
|
|
8
11
|
const ts = Date.now();
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
+
const nonce = Math.random().toString(36).slice(2, 10);
|
|
13
|
+
const raw = `edge-device\0${kind}\0${identityId ?? ''}\0${address ?? ''}\0${ts}\0${nonce}`;
|
|
14
|
+
const hash = (0, sha3_js_1.sha3_256)(new TextEncoder().encode(raw));
|
|
15
|
+
const deviceId = `edge:device:${(0, canonical_js_1.toHex)(hash)}`;
|
|
12
16
|
return {
|
|
13
17
|
deviceId,
|
|
14
18
|
kind,
|
package/dist/errors.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Typed errors for @totemsdk/edge.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EdgeCapabilityError = void 0;
|
|
7
|
+
class EdgeCapabilityError extends Error {
|
|
5
8
|
constructor(capability, message) {
|
|
6
9
|
super(message ?? `Capability not available: ${capability}`);
|
|
7
10
|
this.name = 'EdgeCapabilityError';
|
|
@@ -9,3 +12,4 @@ export class EdgeCapabilityError extends Error {
|
|
|
9
12
|
this.capability = capability;
|
|
10
13
|
}
|
|
11
14
|
}
|
|
15
|
+
exports.EdgeCapabilityError = EdgeCapabilityError;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module @totemsdk/edge
|
|
3
4
|
*
|
|
@@ -5,10 +6,26 @@
|
|
|
5
6
|
* Composes identity, manifest, wallet/payment/proof/lookup/policy capabilities
|
|
6
7
|
* via injected ports. Adapter-neutral.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.bindEdgeServiceIdentity = exports.createEdgeServiceManifest = exports.createEdgeServiceRegistration = exports.createEdgeProviderProfile = exports.verifyEdgeReceipt = exports.createEdgeReceipt = exports.createEdgeDevice = exports.createEdgeRuntime = exports.edgeCapabilitiesFromTotemCapabilities = exports.assertCapability = exports.hasCapability = exports.createCapabilitySet = exports.EdgeCapabilityError = exports.EDGE_VERSION = void 0;
|
|
11
|
+
var constants_js_1 = require("./constants.js");
|
|
12
|
+
Object.defineProperty(exports, "EDGE_VERSION", { enumerable: true, get: function () { return constants_js_1.EDGE_VERSION; } });
|
|
13
|
+
var errors_js_1 = require("./errors.js");
|
|
14
|
+
Object.defineProperty(exports, "EdgeCapabilityError", { enumerable: true, get: function () { return errors_js_1.EdgeCapabilityError; } });
|
|
15
|
+
var capabilities_js_1 = require("./capabilities.js");
|
|
16
|
+
Object.defineProperty(exports, "createCapabilitySet", { enumerable: true, get: function () { return capabilities_js_1.createCapabilitySet; } });
|
|
17
|
+
Object.defineProperty(exports, "hasCapability", { enumerable: true, get: function () { return capabilities_js_1.hasCapability; } });
|
|
18
|
+
Object.defineProperty(exports, "assertCapability", { enumerable: true, get: function () { return capabilities_js_1.assertCapability; } });
|
|
19
|
+
Object.defineProperty(exports, "edgeCapabilitiesFromTotemCapabilities", { enumerable: true, get: function () { return capabilities_js_1.edgeCapabilitiesFromTotemCapabilities; } });
|
|
20
|
+
var runtime_js_1 = require("./runtime.js");
|
|
21
|
+
Object.defineProperty(exports, "createEdgeRuntime", { enumerable: true, get: function () { return runtime_js_1.createEdgeRuntime; } });
|
|
22
|
+
var device_js_1 = require("./device.js");
|
|
23
|
+
Object.defineProperty(exports, "createEdgeDevice", { enumerable: true, get: function () { return device_js_1.createEdgeDevice; } });
|
|
24
|
+
var receipts_js_1 = require("./receipts.js");
|
|
25
|
+
Object.defineProperty(exports, "createEdgeReceipt", { enumerable: true, get: function () { return receipts_js_1.createEdgeReceipt; } });
|
|
26
|
+
Object.defineProperty(exports, "verifyEdgeReceipt", { enumerable: true, get: function () { return receipts_js_1.verifyEdgeReceipt; } });
|
|
27
|
+
var provider_js_1 = require("./provider.js");
|
|
28
|
+
Object.defineProperty(exports, "createEdgeProviderProfile", { enumerable: true, get: function () { return provider_js_1.createEdgeProviderProfile; } });
|
|
29
|
+
Object.defineProperty(exports, "createEdgeServiceRegistration", { enumerable: true, get: function () { return provider_js_1.createEdgeServiceRegistration; } });
|
|
30
|
+
Object.defineProperty(exports, "createEdgeServiceManifest", { enumerable: true, get: function () { return provider_js_1.createEdgeServiceManifest; } });
|
|
31
|
+
Object.defineProperty(exports, "bindEdgeServiceIdentity", { enumerable: true, get: function () { return provider_js_1.bindEdgeServiceIdentity; } });
|
package/dist/ports.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Port interfaces for @totemsdk/edge.
|
|
3
4
|
*
|
|
4
5
|
* All ports are interfaces only. Callers inject implementations at runtime.
|
|
5
6
|
* @totemsdk/edge ships no proof creation/verification implementations.
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/provider.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Provider helper functions for @totemsdk/edge.
|
|
3
4
|
*
|
|
@@ -5,16 +6,21 @@
|
|
|
5
6
|
* Registry, trust-index, watchlist, and lease-coordinator logic remain in
|
|
6
7
|
* @totemsdk/lookup-node and future @totemsdk/proofgraph.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createEdgeProviderProfile = createEdgeProviderProfile;
|
|
11
|
+
exports.createEdgeServiceRegistration = createEdgeServiceRegistration;
|
|
12
|
+
exports.createEdgeServiceManifest = createEdgeServiceManifest;
|
|
13
|
+
exports.bindEdgeServiceIdentity = bindEdgeServiceIdentity;
|
|
14
|
+
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
15
|
+
const canonical_js_1 = require("./canonical.js");
|
|
16
|
+
const manifest_1 = require("@totemsdk/manifest");
|
|
17
|
+
const identity_1 = require("@totemsdk/identity");
|
|
18
|
+
function createEdgeProviderProfile(opts) {
|
|
13
19
|
const { operatorAddress, name, description, tags } = opts;
|
|
14
20
|
const ts = Date.now();
|
|
15
21
|
const raw = `edge-provider\0${operatorAddress}\0${name}\0${ts}`;
|
|
16
|
-
const hash = sha3_256(new TextEncoder().encode(raw));
|
|
17
|
-
const profileId = `edge:provider:${toHex(hash)}`;
|
|
22
|
+
const hash = (0, sha3_js_1.sha3_256)(new TextEncoder().encode(raw));
|
|
23
|
+
const profileId = `edge:provider:${(0, canonical_js_1.toHex)(hash)}`;
|
|
18
24
|
return {
|
|
19
25
|
profileId,
|
|
20
26
|
operatorAddress,
|
|
@@ -24,12 +30,12 @@ export function createEdgeProviderProfile(opts) {
|
|
|
24
30
|
createdAt: ts,
|
|
25
31
|
};
|
|
26
32
|
}
|
|
27
|
-
|
|
33
|
+
function createEdgeServiceRegistration(opts) {
|
|
28
34
|
const { profileId, serviceId, operatorAddress, expiresAt, metadata } = opts;
|
|
29
35
|
const ts = Date.now();
|
|
30
36
|
const raw = `edge-svc-reg\0${profileId}\0${serviceId}\0${operatorAddress}\0${ts}`;
|
|
31
|
-
const hash = sha3_256(new TextEncoder().encode(raw));
|
|
32
|
-
const registrationId = `edge:registration:${toHex(hash)}`;
|
|
37
|
+
const hash = (0, sha3_js_1.sha3_256)(new TextEncoder().encode(raw));
|
|
38
|
+
const registrationId = `edge:registration:${(0, canonical_js_1.toHex)(hash)}`;
|
|
33
39
|
return {
|
|
34
40
|
registrationId,
|
|
35
41
|
profileId,
|
|
@@ -40,9 +46,9 @@ export function createEdgeServiceRegistration(opts) {
|
|
|
40
46
|
...(metadata !== undefined ? { metadata } : {}),
|
|
41
47
|
};
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
return signManifest(manifest, seed, keyIndex);
|
|
49
|
+
async function createEdgeServiceManifest(manifest, seed, keyIndex) {
|
|
50
|
+
return (0, manifest_1.signManifest)(manifest, seed, keyIndex);
|
|
45
51
|
}
|
|
46
|
-
|
|
47
|
-
return bindManifestToIdentity(signedManifest, identityGraph, options);
|
|
52
|
+
async function bindEdgeServiceIdentity(signedManifest, identityGraph, options) {
|
|
53
|
+
return (0, identity_1.bindManifestToIdentity)(signedManifest, identityGraph, options);
|
|
48
54
|
}
|
package/dist/receipts.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Edge receipt creation and verification.
|
|
3
4
|
*
|
|
@@ -7,14 +8,17 @@
|
|
|
7
8
|
*
|
|
8
9
|
* verifyEdgeReceipt always returns a structured EdgeOperationResult, never a bare boolean.
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createEdgeReceipt = createEdgeReceipt;
|
|
13
|
+
exports.verifyEdgeReceipt = verifyEdgeReceipt;
|
|
14
|
+
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
15
|
+
const canonical_js_1 = require("./canonical.js");
|
|
16
|
+
function createEdgeReceipt(opts) {
|
|
13
17
|
const { kind, payload, relatedManifestId, relatedIdentityId } = opts;
|
|
14
18
|
const issuedAt = opts.issuedAt ?? Date.now();
|
|
15
|
-
const canonical = canonicalJson({ kind, payload, relatedManifestId, relatedIdentityId, issuedAt });
|
|
16
|
-
const hash = sha3_256(new TextEncoder().encode(canonical));
|
|
17
|
-
const receiptId = `edge:receipt:${toHex(hash)}`;
|
|
19
|
+
const canonical = (0, canonical_js_1.canonicalJson)({ kind, payload, relatedManifestId, relatedIdentityId, issuedAt });
|
|
20
|
+
const hash = (0, sha3_js_1.sha3_256)(new TextEncoder().encode(canonical));
|
|
21
|
+
const receiptId = `edge:receipt:${(0, canonical_js_1.toHex)(hash)}`;
|
|
18
22
|
return {
|
|
19
23
|
receiptId,
|
|
20
24
|
kind,
|
|
@@ -24,7 +28,7 @@ export function createEdgeReceipt(opts) {
|
|
|
24
28
|
payload,
|
|
25
29
|
};
|
|
26
30
|
}
|
|
27
|
-
|
|
31
|
+
function verifyEdgeReceipt(receipt) {
|
|
28
32
|
if (!receipt || typeof receipt !== 'object') {
|
|
29
33
|
return { ok: false, error: 'receipt is not an object', errorCode: 'INVALID_RECEIPT' };
|
|
30
34
|
}
|
package/dist/runtime.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Edge runtime factory.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createEdgeRuntime = createEdgeRuntime;
|
|
7
|
+
const constants_js_1 = require("./constants.js");
|
|
8
|
+
const capabilities_js_1 = require("./capabilities.js");
|
|
9
|
+
function createEdgeRuntime(opts) {
|
|
7
10
|
const { deviceId, capabilities, ports } = opts;
|
|
8
11
|
return {
|
|
9
|
-
version: EDGE_VERSION,
|
|
12
|
+
version: constants_js_1.EDGE_VERSION,
|
|
10
13
|
deviceId,
|
|
11
14
|
capabilities,
|
|
12
15
|
ports,
|
|
13
16
|
hasCapability(cap) {
|
|
14
|
-
return hasCapability(capabilities, cap);
|
|
17
|
+
return (0, capabilities_js_1.hasCapability)(capabilities, cap);
|
|
15
18
|
},
|
|
16
19
|
assertCapability(cap) {
|
|
17
|
-
assertCapability(capabilities, cap);
|
|
20
|
+
(0, capabilities_js_1.assertCapability)(capabilities, cap);
|
|
18
21
|
},
|
|
19
22
|
};
|
|
20
23
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @totemsdk/edge — Type definitions
|
|
3
4
|
*
|
|
4
5
|
* Covers devices, apps, agents, sensors, robots, gateways, and services.
|
|
5
6
|
* Adapter-neutral — no ROS2, no MQTT, no Python bindings.
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|