@totemsdk/edge-adapters 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 +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -1
- package/dist/location.d.ts +48 -0
- package/dist/location.js +208 -0
- package/dist/omnia.d.ts +7 -0
- package/dist/omnia.js +46 -0
- package/dist/policy.d.ts +9 -7
- package/dist/policy.js +55 -5
- package/dist/proof.d.ts +34 -4
- package/dist/proof.js +37 -8
- package/dist/pubsub.d.ts +11 -0
- package/dist/pubsub.js +30 -0
- package/dist/stream.d.ts +7 -0
- package/dist/stream.js +26 -0
- package/package.json +58 -36
package/LICENSE
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type { LiquidityPortConfig } from './liquidity.js';
|
|
|
3
3
|
export { createProofPortAdapter } from './proof.js';
|
|
4
4
|
export type { ProofPortConfig } from './proof.js';
|
|
5
5
|
export { createLookupPortAdapter } from './lookup.js';
|
|
6
|
+
export { createLocationPortAdapter } from './location.js';
|
|
7
|
+
export type { LocationPortConfig } from './location.js';
|
|
6
8
|
export { createPolicyPortAdapter } from './policy.js';
|
|
7
9
|
export { createIdentityPortAdapter } from './identity.js';
|
|
8
10
|
export type { IdentityPortConfig } from './identity.js';
|
|
@@ -11,3 +13,7 @@ export { createMinimaL1PaymentPort } from './payment-l1.js';
|
|
|
11
13
|
export type { MinimaL1PaymentPortConfig } from './payment-l1.js';
|
|
12
14
|
export { createOmniaL2PaymentPort } from './payment-l2.js';
|
|
13
15
|
export type { OmniaL2PaymentPortConfig } from './payment-l2.js';
|
|
16
|
+
export { createOmniaHostPort } from './omnia.js';
|
|
17
|
+
export type { OmniaHostPortConfig } from './omnia.js';
|
|
18
|
+
export { createStreamPortAdapter } from './stream.js';
|
|
19
|
+
export { createPubSubPortAdapter } from './pubsub.js';
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createOmniaL2PaymentPort = exports.createMinimaL1PaymentPort = exports.createManifestPortAdapter = exports.createIdentityPortAdapter = exports.createPolicyPortAdapter = exports.createLookupPortAdapter = exports.createProofPortAdapter = exports.createLiquidityPortAdapter = void 0;
|
|
3
|
+
exports.createPubSubPortAdapter = exports.createStreamPortAdapter = exports.createOmniaHostPort = exports.createOmniaL2PaymentPort = exports.createMinimaL1PaymentPort = exports.createManifestPortAdapter = exports.createIdentityPortAdapter = exports.createPolicyPortAdapter = exports.createLocationPortAdapter = exports.createLookupPortAdapter = exports.createProofPortAdapter = exports.createLiquidityPortAdapter = void 0;
|
|
4
4
|
var liquidity_js_1 = require("./liquidity.js");
|
|
5
5
|
Object.defineProperty(exports, "createLiquidityPortAdapter", { enumerable: true, get: function () { return liquidity_js_1.createLiquidityPortAdapter; } });
|
|
6
6
|
var proof_js_1 = require("./proof.js");
|
|
7
7
|
Object.defineProperty(exports, "createProofPortAdapter", { enumerable: true, get: function () { return proof_js_1.createProofPortAdapter; } });
|
|
8
8
|
var lookup_js_1 = require("./lookup.js");
|
|
9
9
|
Object.defineProperty(exports, "createLookupPortAdapter", { enumerable: true, get: function () { return lookup_js_1.createLookupPortAdapter; } });
|
|
10
|
+
var location_js_1 = require("./location.js");
|
|
11
|
+
Object.defineProperty(exports, "createLocationPortAdapter", { enumerable: true, get: function () { return location_js_1.createLocationPortAdapter; } });
|
|
10
12
|
var policy_js_1 = require("./policy.js");
|
|
11
13
|
Object.defineProperty(exports, "createPolicyPortAdapter", { enumerable: true, get: function () { return policy_js_1.createPolicyPortAdapter; } });
|
|
12
14
|
var identity_js_1 = require("./identity.js");
|
|
@@ -17,3 +19,9 @@ var payment_l1_js_1 = require("./payment-l1.js");
|
|
|
17
19
|
Object.defineProperty(exports, "createMinimaL1PaymentPort", { enumerable: true, get: function () { return payment_l1_js_1.createMinimaL1PaymentPort; } });
|
|
18
20
|
var payment_l2_js_1 = require("./payment-l2.js");
|
|
19
21
|
Object.defineProperty(exports, "createOmniaL2PaymentPort", { enumerable: true, get: function () { return payment_l2_js_1.createOmniaL2PaymentPort; } });
|
|
22
|
+
var omnia_js_1 = require("./omnia.js");
|
|
23
|
+
Object.defineProperty(exports, "createOmniaHostPort", { enumerable: true, get: function () { return omnia_js_1.createOmniaHostPort; } });
|
|
24
|
+
var stream_js_1 = require("./stream.js");
|
|
25
|
+
Object.defineProperty(exports, "createStreamPortAdapter", { enumerable: true, get: function () { return stream_js_1.createStreamPortAdapter; } });
|
|
26
|
+
var pubsub_js_1 = require("./pubsub.js");
|
|
27
|
+
Object.defineProperty(exports, "createPubSubPortAdapter", { enumerable: true, get: function () { return pubsub_js_1.createPubSubPortAdapter; } });
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { EdgeLocationPort } from '@totemsdk/edge';
|
|
2
|
+
export interface LocationPortConfig {
|
|
3
|
+
/**
|
|
4
|
+
* Default issuer stamped onto created location proofs. When unset, the
|
|
5
|
+
* claim's subjectId is used.
|
|
6
|
+
*/
|
|
7
|
+
issuer?: string;
|
|
8
|
+
/**
|
|
9
|
+
* 32-byte WOTS seed. Required for signing; without it only unsigned
|
|
10
|
+
* location proofs are returned, which MUST NOT be presented as completed
|
|
11
|
+
* proofs.
|
|
12
|
+
*/
|
|
13
|
+
seed?: Uint8Array;
|
|
14
|
+
/**
|
|
15
|
+
* TreeKey index for direct signing (used when no leaseProvider is given).
|
|
16
|
+
* Ignored when leaseProvider is set.
|
|
17
|
+
*/
|
|
18
|
+
keyIndex?: number;
|
|
19
|
+
/**
|
|
20
|
+
* WOTS lease provider for coordinated key-index reservation.
|
|
21
|
+
* When set, keyIndex is ignored and the index is reserved via the provider.
|
|
22
|
+
*/
|
|
23
|
+
leaseProvider?: {
|
|
24
|
+
reserveKeyUse(params: {
|
|
25
|
+
treeId: string;
|
|
26
|
+
ttlMs?: number;
|
|
27
|
+
payloadHash?: string;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
reservationId: string;
|
|
30
|
+
indices: {
|
|
31
|
+
addressIndex: number;
|
|
32
|
+
l1: number;
|
|
33
|
+
l2: number;
|
|
34
|
+
};
|
|
35
|
+
}>;
|
|
36
|
+
commitKeyUse(reservationId: string, txId: string): Promise<void>;
|
|
37
|
+
burnReservation(reservationId: string, reason: string): Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
leaseTreeId?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wraps @totemsdk/location-proof as an EdgeLocationPort.
|
|
43
|
+
*
|
|
44
|
+
* createClaim/createTrail build content-derived Totem-location claims/trails.
|
|
45
|
+
* createProof returns a SignedProof when config.seed is set; otherwise it
|
|
46
|
+
* returns an UnsignedProof that MUST NOT be presented as a completed proof.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createLocationPortAdapter(config?: LocationPortConfig): EdgeLocationPort;
|
package/dist/location.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLocationPortAdapter = createLocationPortAdapter;
|
|
4
|
+
const location_proof_1 = require("@totemsdk/location-proof");
|
|
5
|
+
const DEVICE_CLASSES = [
|
|
6
|
+
'drone',
|
|
7
|
+
'vehicle',
|
|
8
|
+
'robot',
|
|
9
|
+
'ship',
|
|
10
|
+
'tractor',
|
|
11
|
+
'phone',
|
|
12
|
+
'sensor',
|
|
13
|
+
'gateway',
|
|
14
|
+
'camera',
|
|
15
|
+
'weather-station',
|
|
16
|
+
'security-device',
|
|
17
|
+
'other',
|
|
18
|
+
];
|
|
19
|
+
const SOURCE_TYPES = [
|
|
20
|
+
'gnss',
|
|
21
|
+
'gps',
|
|
22
|
+
'rtk',
|
|
23
|
+
'cell',
|
|
24
|
+
'wifi',
|
|
25
|
+
'ble',
|
|
26
|
+
'lorawan',
|
|
27
|
+
'gateway',
|
|
28
|
+
'network',
|
|
29
|
+
'manual',
|
|
30
|
+
'derived',
|
|
31
|
+
'other',
|
|
32
|
+
];
|
|
33
|
+
function assertLocationClaim(claim) {
|
|
34
|
+
if (!claim || typeof claim !== 'object') {
|
|
35
|
+
throw new Error('claim is not a LocationClaim');
|
|
36
|
+
}
|
|
37
|
+
const c = claim;
|
|
38
|
+
if (typeof c.subjectId !== 'string' || typeof c.deviceId !== 'string' || !c.location) {
|
|
39
|
+
throw new Error('claim is not a valid LocationClaim');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function toSourceType(type) {
|
|
43
|
+
if (type !== undefined && SOURCE_TYPES.includes(type)) {
|
|
44
|
+
return type;
|
|
45
|
+
}
|
|
46
|
+
return 'other';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Wraps @totemsdk/location-proof as an EdgeLocationPort.
|
|
50
|
+
*
|
|
51
|
+
* createClaim/createTrail build content-derived Totem-location claims/trails.
|
|
52
|
+
* createProof returns a SignedProof when config.seed is set; otherwise it
|
|
53
|
+
* returns an UnsignedProof that MUST NOT be presented as a completed proof.
|
|
54
|
+
*/
|
|
55
|
+
function createLocationPortAdapter(config = {}) {
|
|
56
|
+
return {
|
|
57
|
+
async createClaim(params) {
|
|
58
|
+
try {
|
|
59
|
+
const deviceClass = DEVICE_CLASSES.includes(params.deviceClass)
|
|
60
|
+
? params.deviceClass
|
|
61
|
+
: undefined;
|
|
62
|
+
const sourceType = toSourceType(params.source.type);
|
|
63
|
+
const claim = (0, location_proof_1.createLocationClaim)({
|
|
64
|
+
subjectId: params.subjectId,
|
|
65
|
+
deviceId: params.deviceId,
|
|
66
|
+
...(deviceClass !== undefined ? { deviceClass } : {}),
|
|
67
|
+
...(params.operatorId !== undefined ? { operatorId: params.operatorId } : {}),
|
|
68
|
+
observedAt: params.observedAt ?? Date.now(),
|
|
69
|
+
location: {
|
|
70
|
+
lat: params.location.lat,
|
|
71
|
+
lon: params.location.lon,
|
|
72
|
+
...(params.location.altitudeM !== undefined ? { altitudeM: params.location.altitudeM } : {}),
|
|
73
|
+
...(params.location.accuracyM !== undefined ? { accuracyM: params.location.accuracyM } : {}),
|
|
74
|
+
},
|
|
75
|
+
source: {
|
|
76
|
+
type: sourceType,
|
|
77
|
+
...(params.source.fixType !== undefined ? { fixType: params.source.fixType } : {}),
|
|
78
|
+
...(params.source.satellitesUsed !== undefined ? { satellitesUsed: params.source.satellitesUsed } : {}),
|
|
79
|
+
...(params.source.hdop !== undefined ? { hdop: params.source.hdop } : {}),
|
|
80
|
+
...(params.source.vdop !== undefined ? { vdop: params.source.vdop } : {}),
|
|
81
|
+
...(params.source.pdop !== undefined ? { pdop: params.source.pdop } : {}),
|
|
82
|
+
...(params.source.rawPayloadHash !== undefined ? { rawPayloadHash: params.source.rawPayloadHash } : {}),
|
|
83
|
+
...(params.source.nmeaPayloadHash !== undefined ? { nmeaPayloadHash: params.source.nmeaPayloadHash } : {}),
|
|
84
|
+
...(params.source.spoofingFlag !== undefined ? { spoofingFlag: params.source.spoofingFlag } : {}),
|
|
85
|
+
...(params.source.jammingFlag !== undefined ? { jammingFlag: params.source.jammingFlag } : {}),
|
|
86
|
+
...(params.source.metadata !== undefined ? { metadata: params.source.metadata } : {}),
|
|
87
|
+
},
|
|
88
|
+
...(params.challenge !== undefined ? { challenge: params.challenge } : {}),
|
|
89
|
+
...(params.corroboration !== undefined ? { corroboration: params.corroboration } : {}),
|
|
90
|
+
...(params.metadata !== undefined ? { metadata: params.metadata } : {}),
|
|
91
|
+
});
|
|
92
|
+
const validation = (0, location_proof_1.validateLocationClaim)(claim);
|
|
93
|
+
if (!validation.valid) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
error: 'invalid location claim: ' + validation.errors.join('; '),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { ok: true, data: { claimId: claim.claimId, claim } };
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
async scoreClaim(params) {
|
|
106
|
+
try {
|
|
107
|
+
assertLocationClaim(params.claim);
|
|
108
|
+
const result = (0, location_proof_1.scoreLocationClaim)(params.claim, params.options);
|
|
109
|
+
return {
|
|
110
|
+
ok: true,
|
|
111
|
+
data: {
|
|
112
|
+
score: result.score,
|
|
113
|
+
level: result.level,
|
|
114
|
+
positiveSignals: result.positiveSignals,
|
|
115
|
+
negativeSignals: result.negativeSignals,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
async createTrail(params) {
|
|
124
|
+
try {
|
|
125
|
+
const trail = (0, location_proof_1.createMovementTrail)({
|
|
126
|
+
subjectId: params.subjectId,
|
|
127
|
+
deviceId: params.deviceId,
|
|
128
|
+
samples: params.samples.map((sample) => ({
|
|
129
|
+
observedAt: sample.observedAt,
|
|
130
|
+
location: {
|
|
131
|
+
lat: sample.location.lat,
|
|
132
|
+
lon: sample.location.lon,
|
|
133
|
+
...(sample.location.altitudeM !== undefined ? { altitudeM: sample.location.altitudeM } : {}),
|
|
134
|
+
...(sample.location.accuracyM !== undefined ? { accuracyM: sample.location.accuracyM } : {}),
|
|
135
|
+
},
|
|
136
|
+
...(sample.headingDeg !== undefined ? { headingDeg: sample.headingDeg } : {}),
|
|
137
|
+
...(sample.speedMps !== undefined ? { speedMps: sample.speedMps } : {}),
|
|
138
|
+
...(sample.accuracyM !== undefined ? { accuracyM: sample.accuracyM } : {}),
|
|
139
|
+
...(sample.source !== undefined
|
|
140
|
+
? {
|
|
141
|
+
source: {
|
|
142
|
+
...sample.source,
|
|
143
|
+
type: toSourceType(sample.source.type),
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
: {}),
|
|
147
|
+
})),
|
|
148
|
+
...(params.metadata !== undefined ? { metadata: params.metadata } : {}),
|
|
149
|
+
...(params.maxSpeedMps !== undefined ? { maxSpeedMps: params.maxSpeedMps } : {}),
|
|
150
|
+
});
|
|
151
|
+
return { ok: true, data: { trailId: trail.trailId, trail } };
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
async createProof(params) {
|
|
158
|
+
try {
|
|
159
|
+
assertLocationClaim(params.claim);
|
|
160
|
+
const claim = params.claim;
|
|
161
|
+
const issuer = params.context?.['issuer'] ?? config.issuer;
|
|
162
|
+
const unsigned = (0, location_proof_1.createUnsignedLocationProof)({
|
|
163
|
+
claim,
|
|
164
|
+
...(issuer !== undefined ? { issuer } : {}),
|
|
165
|
+
});
|
|
166
|
+
let proof;
|
|
167
|
+
let proofId;
|
|
168
|
+
if (config.seed) {
|
|
169
|
+
if (config.leaseProvider) {
|
|
170
|
+
proof = await (0, location_proof_1.signLocationProofWithLease)(unsigned, config.seed, config.leaseProvider, {
|
|
171
|
+
treeId: config.leaseTreeId,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
proof = (0, location_proof_1.signLocationProof)(unsigned, config.seed, config.keyIndex ?? 0);
|
|
176
|
+
}
|
|
177
|
+
proofId = proof.proofId;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
proof = unsigned;
|
|
181
|
+
proofId = unsigned.proofId;
|
|
182
|
+
}
|
|
183
|
+
return { ok: true, data: { proofId, proof } };
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
async verifyProof(params) {
|
|
190
|
+
try {
|
|
191
|
+
const result = (0, location_proof_1.verifyLocationProof)(params.proof, { now: params.now });
|
|
192
|
+
return {
|
|
193
|
+
ok: true,
|
|
194
|
+
data: {
|
|
195
|
+
valid: result.valid,
|
|
196
|
+
...(result.reason !== undefined ? { reason: result.reason } : {}),
|
|
197
|
+
...(result.expired !== undefined ? { expired: result.expired } : {}),
|
|
198
|
+
...(result.signerAddress !== undefined ? { signerAddress: result.signerAddress } : {}),
|
|
199
|
+
...(result.claimId !== undefined ? { claimId: result.claimId } : {}),
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
}
|
package/dist/omnia.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { EdgeOmniaPort } from '@totemsdk/edge';
|
|
2
|
+
export interface OmniaHostPortConfig {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
fetch?: typeof globalThis.fetch;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createOmniaHostPort(config: OmniaHostPortConfig): EdgeOmniaPort;
|
package/dist/omnia.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createOmniaHostPort = createOmniaHostPort;
|
|
4
|
+
function methodName(operation) {
|
|
5
|
+
return `totem_omnia${operation[0].toUpperCase()}${operation.slice(1)}`;
|
|
6
|
+
}
|
|
7
|
+
function createOmniaHostPort(config) {
|
|
8
|
+
const request = config.fetch ?? globalThis.fetch;
|
|
9
|
+
const endpoint = config.endpoint.replace(/\/$/, '');
|
|
10
|
+
async function call(operation, params = {}) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await request(`${endpoint}/rpc`, {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: { 'content-type': 'application/json', ...config.headers },
|
|
15
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method: methodName(operation), params }),
|
|
16
|
+
});
|
|
17
|
+
const body = await response.json();
|
|
18
|
+
if (!response.ok || body.error) {
|
|
19
|
+
return {
|
|
20
|
+
ok: false,
|
|
21
|
+
error: body.error?.message ?? `Omnia host returned HTTP ${response.status}`,
|
|
22
|
+
errorCode: body.error?.code ? String(body.error.code) : 'OMNIA_HOST_ERROR',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return { ok: true, data: body.result };
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error), errorCode: 'OMNIA_HOST_UNAVAILABLE' };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
getChannels: (params) => call('getChannels', params),
|
|
33
|
+
openChannel: (params) => call('openChannel', params),
|
|
34
|
+
pay: (params) => call('pay', params),
|
|
35
|
+
settle: (params) => call('settle', params),
|
|
36
|
+
closeChannel: (params) => call('closeChannel', params),
|
|
37
|
+
getRoute: (params) => call('getRoute', params),
|
|
38
|
+
payMultiHop: (params) => call('payMultiHop', params),
|
|
39
|
+
getSwapRate: (params) => call('getSwapRate', params),
|
|
40
|
+
createFactory: (params) => call('createFactory', params),
|
|
41
|
+
openVirtualChannel: (params) => call('openVirtualChannel', params),
|
|
42
|
+
closeFactory: (params) => call('closeFactory', params),
|
|
43
|
+
spliceIn: (params) => call('spliceIn', params),
|
|
44
|
+
spliceOut: (params) => call('spliceOut', params),
|
|
45
|
+
};
|
|
46
|
+
}
|
package/dist/policy.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type { AgentPolicy } from '@totemsdk/agent-policy';
|
|
1
|
+
import type { AgentPolicy, PolicyMiddleware } from '@totemsdk/agent-policy';
|
|
2
2
|
import type { EdgePolicyPort } from '@totemsdk/edge';
|
|
3
|
+
type PolicyLike = AgentPolicy | PolicyMiddleware;
|
|
3
4
|
/**
|
|
4
|
-
* Wraps an AgentPolicy as an EdgePolicyPort.
|
|
5
|
+
* Wraps an AgentPolicy or PolicyMiddleware as an EdgePolicyPort.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* action
|
|
9
|
-
*
|
|
7
|
+
* When the EdgePolicyPort receives a full `proposal` object, it delegates
|
|
8
|
+
* directly to the policy without lossy reconstruction. When only flat
|
|
9
|
+
* `action`/`subject` params are provided, it builds a minimal AgentProposal
|
|
10
|
+
* (legacy path).
|
|
10
11
|
*/
|
|
11
|
-
export declare function createPolicyPortAdapter(policy:
|
|
12
|
+
export declare function createPolicyPortAdapter(policy: PolicyLike): EdgePolicyPort;
|
|
13
|
+
export {};
|
package/dist/policy.js
CHANGED
|
@@ -1,18 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createPolicyPortAdapter = createPolicyPortAdapter;
|
|
4
|
+
function isMiddleware(p) {
|
|
5
|
+
return 'evaluate' in p && typeof p.evaluate === 'function';
|
|
6
|
+
}
|
|
4
7
|
/**
|
|
5
|
-
* Wraps an AgentPolicy as an EdgePolicyPort.
|
|
8
|
+
* Wraps an AgentPolicy or PolicyMiddleware as an EdgePolicyPort.
|
|
6
9
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* action
|
|
10
|
-
*
|
|
10
|
+
* When the EdgePolicyPort receives a full `proposal` object, it delegates
|
|
11
|
+
* directly to the policy without lossy reconstruction. When only flat
|
|
12
|
+
* `action`/`subject` params are provided, it builds a minimal AgentProposal
|
|
13
|
+
* (legacy path).
|
|
11
14
|
*/
|
|
12
15
|
function createPolicyPortAdapter(policy) {
|
|
13
16
|
return {
|
|
14
17
|
async check(params) {
|
|
15
18
|
try {
|
|
19
|
+
// Prefer full proposal when available
|
|
20
|
+
if (params.proposal) {
|
|
21
|
+
const proposal = {
|
|
22
|
+
id: params.proposal.id,
|
|
23
|
+
agentId: params.proposal.agentId,
|
|
24
|
+
intent: {
|
|
25
|
+
type: params.proposal.intent.type,
|
|
26
|
+
amount: params.proposal.intent.amount,
|
|
27
|
+
tokenId: params.proposal.intent.tokenId,
|
|
28
|
+
recipient: params.proposal.intent.recipient,
|
|
29
|
+
reason: params.proposal.intent.reason,
|
|
30
|
+
risk: params.proposal.intent.risk,
|
|
31
|
+
},
|
|
32
|
+
explanation: params.proposal.explanation,
|
|
33
|
+
confidence: params.proposal.confidence,
|
|
34
|
+
createdAt: params.proposal.createdAt,
|
|
35
|
+
};
|
|
36
|
+
if (isMiddleware(policy)) {
|
|
37
|
+
const result = await policy.evaluate(proposal);
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
data: {
|
|
41
|
+
allowed: result.outcome === 'approved',
|
|
42
|
+
reason: result.reason,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const allowed = await policy.canAutoApprove(proposal);
|
|
47
|
+
return {
|
|
48
|
+
ok: true,
|
|
49
|
+
data: {
|
|
50
|
+
allowed,
|
|
51
|
+
reason: allowed ? undefined : 'Action requires user approval per configured policy',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Legacy path: build minimal proposal from flat params
|
|
16
56
|
const intentType = params.action.startsWith('pay') ? 'payment' : 'receipt';
|
|
17
57
|
const proposal = {
|
|
18
58
|
id: `edge-policy-${params.action}-${params.subject}-${Date.now()}`,
|
|
@@ -28,6 +68,16 @@ function createPolicyPortAdapter(policy) {
|
|
|
28
68
|
confidence: 1,
|
|
29
69
|
createdAt: Date.now(),
|
|
30
70
|
};
|
|
71
|
+
if (isMiddleware(policy)) {
|
|
72
|
+
const result = await policy.evaluate(proposal);
|
|
73
|
+
return {
|
|
74
|
+
ok: true,
|
|
75
|
+
data: {
|
|
76
|
+
allowed: result.outcome === 'approved',
|
|
77
|
+
reason: result.reason,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
31
81
|
const allowed = await policy.canAutoApprove(proposal);
|
|
32
82
|
return {
|
|
33
83
|
ok: true,
|
package/dist/proof.d.ts
CHANGED
|
@@ -6,13 +6,43 @@ export interface ProofPortConfig {
|
|
|
6
6
|
issuer: string;
|
|
7
7
|
/** Default proof kind when callers don't specify one via context. */
|
|
8
8
|
defaultKind?: ProofKind;
|
|
9
|
+
/**
|
|
10
|
+
* 32-byte WOTS seed. Required for signing; without it only unsigned
|
|
11
|
+
* proofs are returned, which MUST NOT be presented as completed proofs.
|
|
12
|
+
*/
|
|
13
|
+
seed?: Uint8Array;
|
|
14
|
+
/**
|
|
15
|
+
* TreeKey index for direct signing (used when no leaseProvider is given).
|
|
16
|
+
* Ignored when leaseProvider is set.
|
|
17
|
+
*/
|
|
18
|
+
keyIndex?: number;
|
|
19
|
+
/**
|
|
20
|
+
* WOTS lease provider for coordinated key-index reservation.
|
|
21
|
+
* When set, keyIndex is ignored and the index is reserved via the provider.
|
|
22
|
+
*/
|
|
23
|
+
leaseProvider?: {
|
|
24
|
+
reserveKeyUse(params: {
|
|
25
|
+
treeId: string;
|
|
26
|
+
ttlMs?: number;
|
|
27
|
+
payloadHash?: string;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
reservationId: string;
|
|
30
|
+
indices: {
|
|
31
|
+
addressIndex: number;
|
|
32
|
+
l1: number;
|
|
33
|
+
l2: number;
|
|
34
|
+
};
|
|
35
|
+
}>;
|
|
36
|
+
commitKeyUse(reservationId: string, txId: string): Promise<void>;
|
|
37
|
+
burnReservation(reservationId: string, reason: string): Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
leaseTreeId?: string;
|
|
9
40
|
}
|
|
10
41
|
/**
|
|
11
42
|
* Wraps a ProofProvider (e.g. proof-integritas) as an EdgeProofPort.
|
|
12
43
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* or provider.checkProof for lightweight existence checks.
|
|
44
|
+
* When config.seed is provided the returned proof is a SignedProof;
|
|
45
|
+
* without seed only an UnsignedProof is returned and MUST NOT be
|
|
46
|
+
* presented as a completed proof.
|
|
17
47
|
*/
|
|
18
48
|
export declare function createProofPortAdapter(config: ProofPortConfig): EdgeProofPort;
|
package/dist/proof.js
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createProofPortAdapter = createProofPortAdapter;
|
|
4
4
|
const proof_1 = require("@totemsdk/proof");
|
|
5
|
+
function rawPayloadEvidence(rawPayload) {
|
|
6
|
+
if (!rawPayload || rawPayload.length === 0)
|
|
7
|
+
return undefined;
|
|
8
|
+
const hash = (0, proof_1.toHex)((0, proof_1.sha3_256)(rawPayload));
|
|
9
|
+
return { id: 'payload:' + hash, kind: 'raw-payload', hash };
|
|
10
|
+
}
|
|
5
11
|
/**
|
|
6
12
|
* Wraps a ProofProvider (e.g. proof-integritas) as an EdgeProofPort.
|
|
7
13
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* or provider.checkProof for lightweight existence checks.
|
|
14
|
+
* When config.seed is provided the returned proof is a SignedProof;
|
|
15
|
+
* without seed only an UnsignedProof is returned and MUST NOT be
|
|
16
|
+
* presented as a completed proof.
|
|
12
17
|
*/
|
|
13
18
|
function createProofPortAdapter(config) {
|
|
14
19
|
const { provider, issuer, defaultKind = 'attestation' } = config;
|
|
@@ -16,18 +21,42 @@ function createProofPortAdapter(config) {
|
|
|
16
21
|
async createProof(params) {
|
|
17
22
|
try {
|
|
18
23
|
const kind = params.context?.['kind'] ?? defaultKind;
|
|
24
|
+
const rawPayload = params.context?.['rawPayload'];
|
|
25
|
+
const evidence = rawPayloadEvidence(rawPayload);
|
|
19
26
|
const unsigned = (0, proof_1.createProof)({
|
|
20
27
|
kind,
|
|
21
28
|
subject: { id: params.subject, kind: 'edge-subject' },
|
|
22
29
|
issuer,
|
|
23
|
-
payload: {
|
|
30
|
+
payload: {
|
|
31
|
+
claims: params.claims,
|
|
32
|
+
...(rawPayload !== undefined ? { rawPayloadHash: (0, proof_1.toHex)((0, proof_1.sha3_256)(rawPayload)) } : {}),
|
|
33
|
+
...(params.context ?? {}),
|
|
34
|
+
},
|
|
35
|
+
...(evidence !== undefined ? { evidence: [evidence] } : {}),
|
|
24
36
|
});
|
|
37
|
+
// Sign if seed is available
|
|
38
|
+
let proof;
|
|
39
|
+
let proofId;
|
|
40
|
+
if (config.seed) {
|
|
41
|
+
if (config.leaseProvider) {
|
|
42
|
+
proof = await (0, proof_1.signWithLease)(unsigned, config.seed, config.leaseProvider, {
|
|
43
|
+
treeId: config.leaseTreeId,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
proof = (0, proof_1.signProof)(unsigned, config.seed, config.keyIndex ?? 0);
|
|
48
|
+
}
|
|
49
|
+
proofId = proof.proofId;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
proof = unsigned;
|
|
53
|
+
proofId = unsigned.proofId;
|
|
54
|
+
}
|
|
25
55
|
// Stamp the proof's canonical hash if the provider supports it.
|
|
26
56
|
if (provider.stampHash) {
|
|
27
|
-
|
|
28
|
-
await provider.stampHash({ hash });
|
|
57
|
+
await provider.stampHash({ hash: proofId });
|
|
29
58
|
}
|
|
30
|
-
return { ok: true, data: { proofId
|
|
59
|
+
return { ok: true, data: { proofId, proof } };
|
|
31
60
|
}
|
|
32
61
|
catch (err) {
|
|
33
62
|
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
package/dist/pubsub.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdgePubSubPort adapter — wraps @totemsdk/pubsub-transport's IPubSubTransport
|
|
3
|
+
* as a first-class EdgePubSubPort for EdgeRuntimePorts.pubsub.
|
|
4
|
+
*
|
|
5
|
+
* This is the lightweight counterpart to @totemsdk/edge-mqtt — it provides
|
|
6
|
+
* the raw pub/sub port without the rule engine, sensor bridge, proof
|
|
7
|
+
* publisher, command handler, or MachinePay credit enforcement.
|
|
8
|
+
*/
|
|
9
|
+
import type { EdgePubSubPort } from '@totemsdk/edge';
|
|
10
|
+
import type { IPubSubTransport } from '@totemsdk/pubsub-transport';
|
|
11
|
+
export declare function createPubSubPortAdapter(transport: IPubSubTransport): EdgePubSubPort;
|
package/dist/pubsub.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EdgePubSubPort adapter — wraps @totemsdk/pubsub-transport's IPubSubTransport
|
|
4
|
+
* as a first-class EdgePubSubPort for EdgeRuntimePorts.pubsub.
|
|
5
|
+
*
|
|
6
|
+
* This is the lightweight counterpart to @totemsdk/edge-mqtt — it provides
|
|
7
|
+
* the raw pub/sub port without the rule engine, sensor bridge, proof
|
|
8
|
+
* publisher, command handler, or MachinePay credit enforcement.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.createPubSubPortAdapter = createPubSubPortAdapter;
|
|
12
|
+
function createPubSubPortAdapter(transport) {
|
|
13
|
+
return {
|
|
14
|
+
async connect() {
|
|
15
|
+
await transport.connect();
|
|
16
|
+
},
|
|
17
|
+
async disconnect() {
|
|
18
|
+
await transport.disconnect();
|
|
19
|
+
},
|
|
20
|
+
async subscribe(topic) {
|
|
21
|
+
return transport.subscribe(topic);
|
|
22
|
+
},
|
|
23
|
+
async publish(topic, payload) {
|
|
24
|
+
await transport.publish(topic, payload);
|
|
25
|
+
},
|
|
26
|
+
onMessage(handler) {
|
|
27
|
+
return transport.onMessage(handler);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdgeStreamPort adapter — wraps @totemsdk/stream-transport's IStreamTransport
|
|
3
|
+
* as a first-class EdgeStreamPort for EdgeRuntimePorts.stream.
|
|
4
|
+
*/
|
|
5
|
+
import type { EdgeStreamPort } from '@totemsdk/edge';
|
|
6
|
+
import type { IStreamTransport } from '@totemsdk/stream-transport';
|
|
7
|
+
export declare function createStreamPortAdapter(transport: IStreamTransport): EdgeStreamPort;
|
package/dist/stream.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EdgeStreamPort adapter — wraps @totemsdk/stream-transport's IStreamTransport
|
|
4
|
+
* as a first-class EdgeStreamPort for EdgeRuntimePorts.stream.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createStreamPortAdapter = createStreamPortAdapter;
|
|
8
|
+
function createStreamPortAdapter(transport) {
|
|
9
|
+
return {
|
|
10
|
+
async send(data) {
|
|
11
|
+
await transport.send(data);
|
|
12
|
+
},
|
|
13
|
+
onData(handler) {
|
|
14
|
+
return transport.onData(handler);
|
|
15
|
+
},
|
|
16
|
+
onClose(handler) {
|
|
17
|
+
return transport.onClose(handler);
|
|
18
|
+
},
|
|
19
|
+
onError(handler) {
|
|
20
|
+
return transport.onError(handler);
|
|
21
|
+
},
|
|
22
|
+
close() {
|
|
23
|
+
void transport.close();
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totemsdk/edge-adapters",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Reference adapters bridging Totem SDK packages to @totemsdk/edge port interfaces",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,26 +11,23 @@
|
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
16
|
-
"prepare": "tsc",
|
|
17
|
-
"clean": "rm -rf dist",
|
|
18
|
-
"test": "jest --passWithNoTests"
|
|
19
|
-
},
|
|
20
14
|
"files": [
|
|
21
15
|
"dist",
|
|
22
16
|
"README.md",
|
|
23
17
|
"LICENSE"
|
|
24
18
|
],
|
|
25
19
|
"peerDependencies": {
|
|
26
|
-
"@totemsdk/
|
|
27
|
-
"@totemsdk/
|
|
28
|
-
"@totemsdk/
|
|
29
|
-
"@totemsdk/
|
|
30
|
-
"@totemsdk/
|
|
31
|
-
"@totemsdk/
|
|
32
|
-
"@totemsdk/
|
|
33
|
-
"@totemsdk/
|
|
20
|
+
"@totemsdk/chain-provider": "^0.1.6",
|
|
21
|
+
"@totemsdk/lookup-client": "^0.1.6",
|
|
22
|
+
"@totemsdk/agent-policy": "^0.2.1",
|
|
23
|
+
"@totemsdk/identity": "^0.1.4",
|
|
24
|
+
"@totemsdk/location-proof": "^0.1.0",
|
|
25
|
+
"@totemsdk/manifest": "^0.1.3",
|
|
26
|
+
"@totemsdk/omnia-router": "^0.1.5",
|
|
27
|
+
"@totemsdk/proof": "^0.1.2",
|
|
28
|
+
"@totemsdk/pubsub-transport": "^0.1.0",
|
|
29
|
+
"@totemsdk/root-identity": "^1.0.8",
|
|
30
|
+
"@totemsdk/stream-transport": "^0.1.1"
|
|
34
31
|
},
|
|
35
32
|
"peerDependenciesMeta": {
|
|
36
33
|
"@totemsdk/agent-policy": {
|
|
@@ -40,39 +37,51 @@
|
|
|
40
37
|
"optional": true
|
|
41
38
|
},
|
|
42
39
|
"@totemsdk/identity": {
|
|
43
|
-
"optional":
|
|
40
|
+
"optional": false
|
|
44
41
|
},
|
|
45
42
|
"@totemsdk/manifest": {
|
|
46
|
-
"optional":
|
|
43
|
+
"optional": false
|
|
47
44
|
},
|
|
48
45
|
"@totemsdk/omnia-router": {
|
|
49
|
-
"optional":
|
|
46
|
+
"optional": false
|
|
50
47
|
},
|
|
51
48
|
"@totemsdk/proof": {
|
|
52
|
-
"optional":
|
|
49
|
+
"optional": false
|
|
53
50
|
},
|
|
54
51
|
"@totemsdk/lookup-client": {
|
|
55
52
|
"optional": true
|
|
56
53
|
},
|
|
54
|
+
"@totemsdk/location-proof": {
|
|
55
|
+
"optional": false
|
|
56
|
+
},
|
|
57
|
+
"@totemsdk/pubsub-transport": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
57
60
|
"@totemsdk/root-identity": {
|
|
58
61
|
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"@totemsdk/stream-transport": {
|
|
64
|
+
"optional": true
|
|
59
65
|
}
|
|
60
66
|
},
|
|
61
67
|
"devDependencies": {
|
|
62
|
-
"@
|
|
63
|
-
"@totemsdk/chain-provider": "^0.1.4",
|
|
64
|
-
"@totemsdk/edge": "^0.1.3",
|
|
65
|
-
"@totemsdk/identity": "^0.1.2",
|
|
66
|
-
"@totemsdk/lookup-client": "^0.1.5",
|
|
67
|
-
"@totemsdk/manifest": "^0.1.2",
|
|
68
|
-
"@totemsdk/omnia-router": "^0.1.4",
|
|
69
|
-
"@totemsdk/proof": "^0.1.1",
|
|
70
|
-
"@totemsdk/root-identity": "^1.0.7",
|
|
71
|
-
"@types/jest": "^29.0.0",
|
|
68
|
+
"@types/jest": "^30.0.0",
|
|
72
69
|
"@types/node": "^20.0.0",
|
|
73
|
-
"jest": "^
|
|
70
|
+
"jest": "^30.4.2",
|
|
74
71
|
"ts-jest": "^29.0.0",
|
|
75
|
-
"typescript": "^
|
|
72
|
+
"typescript": "^7.0.2",
|
|
73
|
+
"@totemsdk/agent-policy": "^0.2.1",
|
|
74
|
+
"@totemsdk/chain-provider": "^0.1.6",
|
|
75
|
+
"@totemsdk/edge": "^0.1.4",
|
|
76
|
+
"@totemsdk/identity": "^0.1.4",
|
|
77
|
+
"@totemsdk/lookup-client": "^0.1.6",
|
|
78
|
+
"@totemsdk/location-proof": "^0.1.0",
|
|
79
|
+
"@totemsdk/manifest": "^0.1.3",
|
|
80
|
+
"@totemsdk/omnia-router": "^0.1.5",
|
|
81
|
+
"@totemsdk/proof": "^0.1.2",
|
|
82
|
+
"@totemsdk/root-identity": "^1.0.8",
|
|
83
|
+
"@totemsdk/stream-transport": "^0.1.1",
|
|
84
|
+
"@totemsdk/pubsub-transport": "^0.1.0"
|
|
76
85
|
},
|
|
77
86
|
"engines": {
|
|
78
87
|
"node": ">=18.0.0"
|
|
@@ -82,17 +91,30 @@
|
|
|
82
91
|
},
|
|
83
92
|
"license": "MIT",
|
|
84
93
|
"author": "Totem SDK",
|
|
85
|
-
"homepage": "https://
|
|
94
|
+
"homepage": "https://totem.ing",
|
|
86
95
|
"repository": {
|
|
87
96
|
"type": "git",
|
|
88
|
-
"url": "git+https://github.com/
|
|
89
|
-
"directory": "packages/
|
|
97
|
+
"url": "git+https://github.com/totem-sdk/totem-sdk.git",
|
|
98
|
+
"directory": "packages/edge-adapters"
|
|
90
99
|
},
|
|
91
100
|
"keywords": [
|
|
92
101
|
"totem",
|
|
93
102
|
"totemsdk",
|
|
103
|
+
"minima",
|
|
104
|
+
"blockchain",
|
|
105
|
+
"quantum-resistant",
|
|
106
|
+
"wots",
|
|
107
|
+
"utxo",
|
|
94
108
|
"edge",
|
|
95
109
|
"adapters",
|
|
96
110
|
"ports"
|
|
97
|
-
]
|
|
98
|
-
|
|
111
|
+
],
|
|
112
|
+
"bugs": {
|
|
113
|
+
"url": "https://github.com/totem-sdk/totem-sdk/issues"
|
|
114
|
+
},
|
|
115
|
+
"scripts": {
|
|
116
|
+
"build": "tsc",
|
|
117
|
+
"clean": "rm -rf dist",
|
|
118
|
+
"test": "jest"
|
|
119
|
+
}
|
|
120
|
+
}
|