@totemsdk/provider-bond 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Totem SDK
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 ADDED
@@ -0,0 +1,233 @@
1
+ # @totemsdk/provider-bond
2
+
3
+ Provider trust layer for Totem Edge — prove, record, score and filter infrastructure providers.
4
+
5
+ ## What provider-bond is
6
+
7
+ `@totemsdk/provider-bond` is a **small, production-shaped v0.1 provider trust package**. It answers:
8
+
9
+ - Who is this provider?
10
+ - What service do they operate?
11
+ - Is their manifest signed?
12
+ - Is their manifest bound to an identity?
13
+ - What bond do they claim?
14
+ - Is there a proof attached?
15
+ - What probes/incidents exist?
16
+ - What score does the provider have?
17
+ - Should a client use this provider under a policy?
18
+
19
+ ## What provider-bond is NOT
20
+
21
+ - A liquidity pool or LP accounting package
22
+ - An Omnia channel/factory/splice execution engine
23
+ - A KISSVM covenant enforcement layer
24
+ - A live Minima node verifier
25
+ - A wallet or key manager
26
+ - A transport/networking layer
27
+
28
+ ## Provider-bond vs liquidity-bond
29
+
30
+ | | provider-bond | liquidity-bond (future) |
31
+ |---|---|---|
32
+ | **Scope** | Provider trust, identity, reputation | LP deposits, shares, rewards, withdrawals |
33
+ | **Bonds** | Declared MINIMA hard collateral | Productive liquidity positions |
34
+ | **Scoring** | Identity + bond + reliability + incidents | LP performance, fee generation |
35
+ | **Policy** | Provider selection and filtering | Liquidity allocation and routing |
36
+
37
+ `liquidityBondRefs` are string references to a future `@totemsdk/liquidity-bond` package. They do not count as collateral in v0.1.
38
+
39
+ ## MINIMA-first provider trust model
40
+
41
+ - `MINIMA` is the default hard-collateral and bond asset
42
+ - `TOTEM` cannot satisfy MINIMA hard-collateral policy
43
+ - `TOTEM` may satisfy service-level or reputation policies only if explicitly accepted
44
+ - Other tokens cannot satisfy MINIMA hard-collateral policy unless explicitly accepted
45
+ - Liquidity references do not count as bond collateral in v0.1
46
+
47
+ ## Manifest compatibility
48
+
49
+ Provider-bond wraps `@totemsdk/manifest` `EdgeServiceManifest` + `SignedManifest<T>`. Provider-bond-specific fields (bondId, bondStack, bondProofs, score, incidentSummary) go in a `ProviderBondExtension` metadata block.
50
+
51
+ ## Identity binding
52
+
53
+ Provider-bond uses `@totemsdk/identity` to cryptographically bind provider manifests to identity documents. The verification flow is layered:
54
+
55
+ 1. Verify the base `SignedManifest` via `@totemsdk/manifest`
56
+ 2. Verify the manifest signer is authorised by the claimed identity via `@totemsdk/identity`
57
+ 3. Verify the provider-bond extension hash matches
58
+ 4. Verify all claimed operational addresses (bond owner, recovery, probe signer, incident signer, score signer) are authorised by the identity
59
+
60
+ ## Bond proof attachment
61
+
62
+ Bond proofs are attached as `BondProofRef` records. MVP supports:
63
+
64
+ - `manual` — structurally valid declarations
65
+ - `declared` — structurally valid declarations
66
+ - `visible-balance` — requires a verifier
67
+ - `totem-proof` — uses `@totemsdk/proof`
68
+ - `future-live-chain` — returns `REQUIRES_LIVE_VERIFIER` unless verifier supplied
69
+
70
+ ## Probe and incident records
71
+
72
+ Probes track provider health: heartbeat, endpoint, latency, service-capability, bond-proof-freshness, manual-observation.
73
+
74
+ Incidents track provider issues: downtime, high-latency, failed-probe, invalid-response, invalid-bond-proof, manual-dispute. Incidents can be acknowledged, resolved, or rejected.
75
+
76
+ ## Provider scoring
77
+
78
+ Scores are computed deterministically from four components:
79
+
80
+ - **Identity** (25%) — is an identity address declared?
81
+ - **Bond** (30%) — is there an active MINIMA hard-collateral bond with proof?
82
+ - **Reliability** (30%) — probe success rate and latency
83
+ - **Incidents** (15%) — open, critical, and high-severity incidents
84
+
85
+ Recommendations: `recommended` (80+), `acceptable` (60+), `risky` (40+), `avoid` (20+), `unbonded`, `offline`.
86
+
87
+ ## Policy filtering
88
+
89
+ Policies filter providers by: service type, minimum score, identity requirement, active bond requirement, MINIMA hard collateral requirement, minimum bond amount, accepted assets/purposes, maximum incident severity, and maximum heartbeat age.
90
+
91
+ ## Pear/Bare compatibility
92
+
93
+ The package is runtime-neutral. It avoids `node:crypto`, `fs`, `path`, `net`, `http`, `https`, `child_process`, DOM APIs, hidden `Date.now()`, hidden randomness, and side effects at module import time. It uses `Uint8Array`, injected `now`/`height`, pure functions, and deterministic serialization.
94
+
95
+ ## Examples
96
+
97
+ ### Create provider manifest
98
+
99
+ ```ts
100
+ import { createProviderBondManifest } from '@totemsdk/provider-bond';
101
+
102
+ const manifest = createProviderBondManifest({
103
+ edgeService: {
104
+ type: 'edge-service',
105
+ serviceId: 'my-lookup-node',
106
+ name: 'My Lookup Node',
107
+ version: '1.0.0',
108
+ operatorAddress: 'MxRoot...',
109
+ serviceType: 'lookup-provider',
110
+ description: 'Personal lookup node',
111
+ capabilities: ['lookup'],
112
+ tags: ['production'],
113
+ },
114
+ providerBond: {
115
+ providerId: 'prov-001',
116
+ bondOwnerAddress: 'MxRoot...',
117
+ bondStack: [{
118
+ bondId: 'bond-001',
119
+ asset: 'MINIMA',
120
+ amount: 100000n,
121
+ purpose: 'hard-collateral',
122
+ lockType: 'manual-attestation',
123
+ status: 'active',
124
+ }],
125
+ },
126
+ });
127
+ ```
128
+
129
+ ### Verify provider manifest
130
+
131
+ ```ts
132
+ import { verifyProviderBondManifest } from '@totemsdk/provider-bond';
133
+
134
+ const result = verifyProviderBondManifest({ manifest, now: Date.now() });
135
+ if (!result.ok) {
136
+ console.error(result.code, result.reason);
137
+ }
138
+ ```
139
+
140
+ ### Attach MINIMA bond proof
141
+
142
+ ```ts
143
+ import { attachBondProof } from '@totemsdk/provider-bond';
144
+
145
+ let state = createEmptyProviderBondRegistryState();
146
+ state = registerProvider(state, manifest);
147
+ state = attachBondProof(state, 'prov-001', {
148
+ proofId: 'proof-001',
149
+ bondId: 'bond-001',
150
+ providerId: 'prov-001',
151
+ proofType: 'manual',
152
+ asset: 'MINIMA',
153
+ amount: 100000n,
154
+ });
155
+ ```
156
+
157
+ ### Record heartbeat
158
+
159
+ ```ts
160
+ import { recordHeartbeat, recordProviderProbe } from '@totemsdk/provider-bond';
161
+
162
+ const probe = recordHeartbeat('prov-001');
163
+ state = recordProviderProbe(state, 'prov-001', probe);
164
+ ```
165
+
166
+ ### Record incident
167
+
168
+ ```ts
169
+ import { recordIncident, recordProviderIncident } from '@totemsdk/provider-bond';
170
+
171
+ const incident = recordIncident({
172
+ providerId: 'prov-001',
173
+ type: 'downtime',
174
+ severity: 'high',
175
+ });
176
+ state = recordProviderIncident(state, 'prov-001', incident);
177
+ ```
178
+
179
+ ### Compute score
180
+
181
+ ```ts
182
+ import { computeProviderScore, updateProviderScore } from '@totemsdk/provider-bond';
183
+
184
+ const score = computeProviderScore({
185
+ provider: manifest,
186
+ bondProofs: state.bondProofs['prov-001'],
187
+ probes: state.probes['prov-001'],
188
+ incidents: state.incidents['prov-001'],
189
+ });
190
+ state = updateProviderScore(state, 'prov-001', score);
191
+ console.log(score.recommendation); // 'recommended'
192
+ ```
193
+
194
+ ### Filter providers by policy
195
+
196
+ ```ts
197
+ import { filterProvidersByPolicy } from '@totemsdk/provider-bond';
198
+
199
+ const matches = filterProvidersByPolicy(state, {
200
+ requireMinimaHardCollateral: true,
201
+ minScore: 60,
202
+ maxIncidentSeverity: 'medium',
203
+ });
204
+ const passing = matches.filter(m => m.matched);
205
+ ```
206
+
207
+ ### Serialize registry state
208
+
209
+ ```ts
210
+ import { serializeProviderBondState, parseProviderBondState } from '@totemsdk/provider-bond';
211
+
212
+ const json = serializeProviderBondState(state);
213
+ const restored = parseProviderBondState(json);
214
+ ```
215
+
216
+ ## Security limitations
217
+
218
+ - MVP does not verify live Minima chain state
219
+ - Manual and declared proofs are structurally validated only
220
+ - No automatic slashing or penalty execution
221
+ - No custody of funds or private key management
222
+ - Identity binding requires an identity graph to be supplied
223
+
224
+ ## Roadmap
225
+
226
+ - `@totemsdk/liquidity-bond` — LP deposits, shares, rewards, withdrawals
227
+ - KISSVM bond covenant enforcement
228
+ - MAST branch descriptors for bond scripts
229
+ - Live chain-provider integration for bond verification
230
+ - Omnia channel/factory liquidity integration
231
+ - Transport layer for provider announcements and queries
232
+ - TOTEM service-level bond support
233
+ - DAO governance integration
@@ -0,0 +1,4 @@
1
+ import type { BondProofRef, ProviderBondVerifyResult, BondProofVerifier, VerifyBondStackParams } from './types.js';
2
+ export declare function verifyBondProof(proof: BondProofRef, verifier?: BondProofVerifier): ProviderBondVerifyResult;
3
+ export declare function assertBondMeetsMinimum(proof: BondProofRef, minAmount: bigint): ProviderBondVerifyResult;
4
+ export declare function verifyBondStack(params: VerifyBondStackParams): ProviderBondVerifyResult;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyBondProof = verifyBondProof;
4
+ exports.assertBondMeetsMinimum = assertBondMeetsMinimum;
5
+ exports.verifyBondStack = verifyBondStack;
6
+ function verifyBondProof(proof, verifier) {
7
+ switch (proof.proofType) {
8
+ case 'manual':
9
+ case 'declared':
10
+ if (!proof.amount || proof.amount <= 0n) {
11
+ return { ok: false, reason: 'Bond proof amount is missing or zero', code: 'BOND_AMOUNT_INSUFFICIENT' };
12
+ }
13
+ return { ok: true, code: 'OK' };
14
+ case 'visible-balance':
15
+ if (verifier) {
16
+ return { ok: true, code: 'OK', requiresLiveVerifier: false };
17
+ }
18
+ return { ok: false, reason: 'Visible-balance proof requires a verifier', code: 'REQUIRES_LIVE_VERIFIER', requiresLiveVerifier: true };
19
+ case 'totem-proof':
20
+ if (proof.proof) {
21
+ return { ok: true, code: 'OK' };
22
+ }
23
+ return { ok: false, reason: 'Totem proof is missing proof data', code: 'BOND_PROOF_INVALID' };
24
+ case 'future-live-chain':
25
+ if (verifier) {
26
+ return { ok: true, code: 'OK', requiresLiveVerifier: false };
27
+ }
28
+ return { ok: false, reason: 'Live chain proof requires a verifier', code: 'REQUIRES_LIVE_VERIFIER', requiresLiveVerifier: true };
29
+ default:
30
+ return { ok: false, reason: `Unsupported proof type: ${proof.proofType}`, code: 'UNSUPPORTED_PROOF_TYPE' };
31
+ }
32
+ }
33
+ function assertBondMeetsMinimum(proof, minAmount) {
34
+ if (!proof.amount || proof.amount < minAmount) {
35
+ return {
36
+ ok: false,
37
+ reason: `Bond amount ${proof.amount?.toString() ?? '0'} is less than minimum ${minAmount.toString()}`,
38
+ code: 'BOND_AMOUNT_INSUFFICIENT',
39
+ };
40
+ }
41
+ return { ok: true, code: 'OK' };
42
+ }
43
+ function verifyBondStack(params) {
44
+ const { bondStack, bondProofs, verifier } = params;
45
+ if (!bondStack || bondStack.length === 0) {
46
+ return { ok: false, reason: 'Bond stack is empty', code: 'BOND_AMOUNT_INSUFFICIENT' };
47
+ }
48
+ const proofMap = new Map();
49
+ if (bondProofs) {
50
+ for (const p of bondProofs) {
51
+ proofMap.set(p.bondId, p);
52
+ }
53
+ }
54
+ for (const declaration of bondStack) {
55
+ const proof = proofMap.get(declaration.bondId);
56
+ if (proof) {
57
+ const result = verifyBondProof(proof, verifier);
58
+ if (!result.ok)
59
+ return result;
60
+ }
61
+ }
62
+ return { ok: true, code: 'OK' };
63
+ }
@@ -0,0 +1,16 @@
1
+ export declare const DEFAULT_MINIMA_TOKEN_ID = "0x00";
2
+ export declare const PROVIDER_BOND_TOPIC_PREFIX = "totem.provider-bond.v1";
3
+ export declare const DEFAULT_PROVIDER_SCORING_WEIGHTS: {
4
+ readonly identity: 0.25;
5
+ readonly bond: 0.3;
6
+ readonly reliability: 0.3;
7
+ readonly incidents: 0.15;
8
+ };
9
+ export declare const SEVERITY_ORDER: Record<string, number>;
10
+ export declare const RECOMMENDATION_THRESHOLDS: {
11
+ readonly recommended: 80;
12
+ readonly acceptable: 60;
13
+ readonly risky: 40;
14
+ readonly avoid: 20;
15
+ };
16
+ export declare const MAX_HEARTBEAT_AGE_MS_DEFAULT = 120000;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_HEARTBEAT_AGE_MS_DEFAULT = exports.RECOMMENDATION_THRESHOLDS = exports.SEVERITY_ORDER = exports.DEFAULT_PROVIDER_SCORING_WEIGHTS = exports.PROVIDER_BOND_TOPIC_PREFIX = exports.DEFAULT_MINIMA_TOKEN_ID = void 0;
4
+ exports.DEFAULT_MINIMA_TOKEN_ID = '0x00';
5
+ exports.PROVIDER_BOND_TOPIC_PREFIX = 'totem.provider-bond.v1';
6
+ exports.DEFAULT_PROVIDER_SCORING_WEIGHTS = {
7
+ identity: 0.25,
8
+ bond: 0.30,
9
+ reliability: 0.30,
10
+ incidents: 0.15,
11
+ };
12
+ exports.SEVERITY_ORDER = {
13
+ low: 0,
14
+ medium: 1,
15
+ high: 2,
16
+ critical: 3,
17
+ };
18
+ exports.RECOMMENDATION_THRESHOLDS = {
19
+ recommended: 80,
20
+ acceptable: 60,
21
+ risky: 40,
22
+ avoid: 20,
23
+ };
24
+ exports.MAX_HEARTBEAT_AGE_MS_DEFAULT = 120000;
@@ -0,0 +1,32 @@
1
+ export declare class ProviderBondError extends Error {
2
+ code?: string;
3
+ details?: unknown;
4
+ constructor(message: string, code?: string, details?: unknown);
5
+ }
6
+ export declare class ProviderManifestError extends ProviderBondError {
7
+ constructor(message: string, code?: string, details?: unknown);
8
+ }
9
+ export declare class ProviderIdentityError extends ProviderBondError {
10
+ constructor(message: string, code?: string, details?: unknown);
11
+ }
12
+ export declare class BondProofError extends ProviderBondError {
13
+ constructor(message: string, code?: string, details?: unknown);
14
+ }
15
+ export declare class ProbeError extends ProviderBondError {
16
+ constructor(message: string, code?: string, details?: unknown);
17
+ }
18
+ export declare class IncidentError extends ProviderBondError {
19
+ constructor(message: string, code?: string, details?: unknown);
20
+ }
21
+ export declare class ProviderScoreError extends ProviderBondError {
22
+ constructor(message: string, code?: string, details?: unknown);
23
+ }
24
+ export declare class ProviderPolicyError extends ProviderBondError {
25
+ constructor(message: string, code?: string, details?: unknown);
26
+ }
27
+ export declare class ProviderRegistryError extends ProviderBondError {
28
+ constructor(message: string, code?: string, details?: unknown);
29
+ }
30
+ export declare class ProviderSerializationError extends ProviderBondError {
31
+ constructor(message: string, code?: string, details?: unknown);
32
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderSerializationError = exports.ProviderRegistryError = exports.ProviderPolicyError = exports.ProviderScoreError = exports.IncidentError = exports.ProbeError = exports.BondProofError = exports.ProviderIdentityError = exports.ProviderManifestError = exports.ProviderBondError = void 0;
4
+ class ProviderBondError extends Error {
5
+ constructor(message, code, details) {
6
+ super(message);
7
+ this.name = 'ProviderBondError';
8
+ this.code = code;
9
+ this.details = details;
10
+ }
11
+ }
12
+ exports.ProviderBondError = ProviderBondError;
13
+ class ProviderManifestError extends ProviderBondError {
14
+ constructor(message, code, details) {
15
+ super(message, code, details);
16
+ this.name = 'ProviderManifestError';
17
+ }
18
+ }
19
+ exports.ProviderManifestError = ProviderManifestError;
20
+ class ProviderIdentityError extends ProviderBondError {
21
+ constructor(message, code, details) {
22
+ super(message, code, details);
23
+ this.name = 'ProviderIdentityError';
24
+ }
25
+ }
26
+ exports.ProviderIdentityError = ProviderIdentityError;
27
+ class BondProofError extends ProviderBondError {
28
+ constructor(message, code, details) {
29
+ super(message, code, details);
30
+ this.name = 'BondProofError';
31
+ }
32
+ }
33
+ exports.BondProofError = BondProofError;
34
+ class ProbeError extends ProviderBondError {
35
+ constructor(message, code, details) {
36
+ super(message, code, details);
37
+ this.name = 'ProbeError';
38
+ }
39
+ }
40
+ exports.ProbeError = ProbeError;
41
+ class IncidentError extends ProviderBondError {
42
+ constructor(message, code, details) {
43
+ super(message, code, details);
44
+ this.name = 'IncidentError';
45
+ }
46
+ }
47
+ exports.IncidentError = IncidentError;
48
+ class ProviderScoreError extends ProviderBondError {
49
+ constructor(message, code, details) {
50
+ super(message, code, details);
51
+ this.name = 'ProviderScoreError';
52
+ }
53
+ }
54
+ exports.ProviderScoreError = ProviderScoreError;
55
+ class ProviderPolicyError extends ProviderBondError {
56
+ constructor(message, code, details) {
57
+ super(message, code, details);
58
+ this.name = 'ProviderPolicyError';
59
+ }
60
+ }
61
+ exports.ProviderPolicyError = ProviderPolicyError;
62
+ class ProviderRegistryError extends ProviderBondError {
63
+ constructor(message, code, details) {
64
+ super(message, code, details);
65
+ this.name = 'ProviderRegistryError';
66
+ }
67
+ }
68
+ exports.ProviderRegistryError = ProviderRegistryError;
69
+ class ProviderSerializationError extends ProviderBondError {
70
+ constructor(message, code, details) {
71
+ super(message, code, details);
72
+ this.name = 'ProviderSerializationError';
73
+ }
74
+ }
75
+ exports.ProviderSerializationError = ProviderSerializationError;
@@ -0,0 +1,5 @@
1
+ import type { ProviderBondVerifyResult, BindProviderManifestToIdentityParams, VerifyProviderManifestIdentityParams, VerifyProviderBondAddressesParams, AssertProviderControlsAddressParams } from './types.js';
2
+ export declare function bindProviderManifestToIdentity(params: BindProviderManifestToIdentityParams): unknown;
3
+ export declare function verifyProviderManifestIdentity(params: VerifyProviderManifestIdentityParams): ProviderBondVerifyResult;
4
+ export declare function verifyProviderBondAddresses(params: VerifyProviderBondAddressesParams): ProviderBondVerifyResult;
5
+ export declare function assertProviderControlsAddress(params: AssertProviderControlsAddressParams): ProviderBondVerifyResult;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bindProviderManifestToIdentity = bindProviderManifestToIdentity;
4
+ exports.verifyProviderManifestIdentity = verifyProviderManifestIdentity;
5
+ exports.verifyProviderBondAddresses = verifyProviderBondAddresses;
6
+ exports.assertProviderControlsAddress = assertProviderControlsAddress;
7
+ function isIdentityGraph(value) {
8
+ if (!value || typeof value !== 'object')
9
+ return false;
10
+ const g = value;
11
+ return typeof g.document === 'object' && g.document !== null && Array.isArray(g.claims);
12
+ }
13
+ function getAuthorisedAddresses(identityGraph) {
14
+ if (!isIdentityGraph(identityGraph))
15
+ return [];
16
+ const addresses = new Set();
17
+ const doc = identityGraph.document;
18
+ if (doc.rootAddress)
19
+ addresses.add(doc.rootAddress);
20
+ if (doc.controllerAddress)
21
+ addresses.add(doc.controllerAddress);
22
+ for (const c of identityGraph.claims) {
23
+ if (c.claim.type === 'delegates_to' && c.proof?.address) {
24
+ addresses.add(c.proof.address);
25
+ }
26
+ }
27
+ return Array.from(addresses);
28
+ }
29
+ function bindProviderManifestToIdentity(params) {
30
+ return {
31
+ manifestId: params.manifest.edgeServiceManifestId,
32
+ identityGraph: params.identityGraph,
33
+ bound: true,
34
+ };
35
+ }
36
+ function verifyProviderManifestIdentity(params) {
37
+ const { manifest, identityGraph } = params;
38
+ if (!isIdentityGraph(identityGraph)) {
39
+ return { ok: false, reason: 'Invalid identity graph', code: 'IDENTITY_NOT_AUTHORISED' };
40
+ }
41
+ const signerAddress = manifest.signedEdgeService?.authorAddress;
42
+ if (!signerAddress) {
43
+ return { ok: false, reason: 'No signer address in manifest', code: 'IDENTITY_NOT_AUTHORISED' };
44
+ }
45
+ const authorised = getAuthorisedAddresses(identityGraph);
46
+ if (!authorised.includes(signerAddress)) {
47
+ return { ok: false, reason: 'Manifest signer is not authorised by identity', code: 'IDENTITY_NOT_AUTHORISED' };
48
+ }
49
+ return { ok: true, code: 'OK' };
50
+ }
51
+ function verifyProviderBondAddresses(params) {
52
+ const { manifest, identityGraph } = params;
53
+ if (!isIdentityGraph(identityGraph)) {
54
+ return { ok: false, reason: 'Invalid identity graph', code: 'IDENTITY_NOT_AUTHORISED' };
55
+ }
56
+ const authorised = getAuthorisedAddresses(identityGraph);
57
+ const pb = manifest.providerBond;
58
+ const checks = [
59
+ { address: pb.bondOwnerAddress, code: 'BOND_OWNER_NOT_AUTHORISED', label: 'bond owner' },
60
+ { address: pb.bondRecoveryAddress, code: 'BOND_RECOVERY_NOT_AUTHORISED', label: 'bond recovery' },
61
+ { address: pb.probeSignerAddress, code: 'PROBE_SIGNER_NOT_AUTHORISED', label: 'probe signer' },
62
+ { address: pb.incidentSignerAddress, code: 'INCIDENT_SIGNER_NOT_AUTHORISED', label: 'incident signer' },
63
+ { address: pb.scoreSignerAddress, code: 'SCORE_SIGNER_NOT_AUTHORISED', label: 'score signer' },
64
+ ];
65
+ for (const check of checks) {
66
+ if (check.address && !authorised.includes(check.address)) {
67
+ return {
68
+ ok: false,
69
+ reason: `${check.label} address is not authorised by identity`,
70
+ code: check.code,
71
+ };
72
+ }
73
+ }
74
+ return { ok: true, code: 'OK' };
75
+ }
76
+ function assertProviderControlsAddress(params) {
77
+ const { manifest, address, identityGraph } = params;
78
+ if (!isIdentityGraph(identityGraph)) {
79
+ return { ok: false, reason: 'Invalid identity graph', code: 'IDENTITY_NOT_AUTHORISED' };
80
+ }
81
+ const authorised = getAuthorisedAddresses(identityGraph);
82
+ if (!authorised.includes(address)) {
83
+ return { ok: false, reason: 'Address is not authorised by identity', code: 'IDENTITY_NOT_AUTHORISED' };
84
+ }
85
+ return { ok: true, code: 'OK' };
86
+ }
@@ -0,0 +1,5 @@
1
+ import type { IncidentRecord, RecordIncidentParams } from './types.js';
2
+ export declare function recordIncident(params: RecordIncidentParams): IncidentRecord;
3
+ export declare function acknowledgeIncident(incident: IncidentRecord, now?: number): IncidentRecord;
4
+ export declare function resolveIncident(incident: IncidentRecord, now?: number): IncidentRecord;
5
+ export declare function rejectIncident(incident: IncidentRecord, reason: string, now?: number): IncidentRecord;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordIncident = recordIncident;
4
+ exports.acknowledgeIncident = acknowledgeIncident;
5
+ exports.resolveIncident = resolveIncident;
6
+ exports.rejectIncident = rejectIncident;
7
+ let incidentCounter = 0;
8
+ function recordIncident(params) {
9
+ const now = params.now ?? Date.now();
10
+ incidentCounter++;
11
+ return {
12
+ incidentId: `incident-${now}-${incidentCounter}`,
13
+ providerId: params.providerId,
14
+ type: params.type,
15
+ severity: params.severity,
16
+ status: 'open',
17
+ createdAt: now,
18
+ message: params.message,
19
+ metadata: params.metadata,
20
+ };
21
+ }
22
+ function acknowledgeIncident(incident, now) {
23
+ return {
24
+ ...incident,
25
+ status: 'acknowledged',
26
+ resolvedAt: now ?? Date.now(),
27
+ };
28
+ }
29
+ function resolveIncident(incident, now) {
30
+ return {
31
+ ...incident,
32
+ status: 'resolved',
33
+ resolvedAt: now ?? Date.now(),
34
+ };
35
+ }
36
+ function rejectIncident(incident, reason, now) {
37
+ return {
38
+ ...incident,
39
+ status: 'rejected',
40
+ resolvedAt: now ?? Date.now(),
41
+ message: incident.message ? `${incident.message} (rejected: ${reason})` : `Rejected: ${reason}`,
42
+ };
43
+ }
@@ -0,0 +1,13 @@
1
+ export type { BondAsset, BondPurpose, BondStatus, BondLockType, ProviderBondVerifyCode, ProviderRecommendation, ProbeType, IncidentType, IncidentSeverity, IncidentStatus, BondProofType, ProviderBondVerifyResult, BondStatusContext, ProviderBondAssetDeclaration, BondProofRef, ProviderBondExtension, ProviderBondManifest, ProviderScore, IncidentSummary, ProbeResult, IncidentRecord, ProviderPolicy, PolicyMatch, ProviderBondRegistryState, ProviderScoringWeights, ComputeProviderScoreParams, CreateProviderBondManifestParams, VerifyProviderBondManifestParams, BindProviderManifestToIdentityParams, VerifyProviderManifestIdentityParams, VerifyProviderBondAddressesParams, AssertProviderControlsAddressParams, BondProofVerifier, VerifyBondStackParams, RecordProbeParams, RecordIncidentParams, } from './types.js';
2
+ export { ProviderBondError, ProviderManifestError, ProviderIdentityError, BondProofError, ProbeError, IncidentError, ProviderScoreError, ProviderPolicyError, ProviderRegistryError, ProviderSerializationError, } from './errors.js';
3
+ export { DEFAULT_MINIMA_TOKEN_ID, PROVIDER_BOND_TOPIC_PREFIX, DEFAULT_PROVIDER_SCORING_WEIGHTS, } from './constants.js';
4
+ export { serializeProviderBondState, parseProviderBondState, serializeProviderBondRecord, parseProviderBondRecord, } from './serialization.js';
5
+ export { createProviderBondManifest, computeProviderBondExtensionHash, computeProviderBondManifestHash, verifyProviderBondManifest, assertManifestNotExpired, } from './manifest.js';
6
+ export { bindProviderManifestToIdentity, verifyProviderManifestIdentity, verifyProviderBondAddresses, assertProviderControlsAddress, } from './identity.js';
7
+ export { verifyBondProof, assertBondMeetsMinimum, verifyBondStack, } from './bond-proof.js';
8
+ export { recordProbe, recordHeartbeat, } from './probes.js';
9
+ export { recordIncident, acknowledgeIncident, resolveIncident, rejectIncident, } from './incidents.js';
10
+ export { computeProviderScore, computeProviderRecommendation, } from './scoring.js';
11
+ export { filterProvidersByPolicy, rankProvidersByPolicy, explainProviderPolicyMatch, } from './policy.js';
12
+ export { createEmptyProviderBondRegistryState, registerProvider, updateProviderManifest, attachBondProof, recordProviderProbe, recordProviderIncident, updateProviderScore, listProviders, getProvider, listProvidersByServiceType, listRiskyProviders, listOfflineProviders, } from './registry.js';
13
+ export { MemoryProviderBondStore } from './memory-store.js';