@provenonce/sdk 0.10.1 → 0.12.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/README.md +38 -38
- package/dist/index.d.mts +51 -23
- package/dist/index.d.ts +51 -23
- package/dist/index.js +63 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,13 +54,13 @@ const agent = new BeatAgent({
|
|
|
54
54
|
|
|
55
55
|
await agent.init(); // Birth in Beat time
|
|
56
56
|
|
|
57
|
-
// Purchase a SIGIL (cryptographic identity)
|
|
58
|
-
const sigil = await agent.purchaseSigil({
|
|
59
|
-
identity_class: 'autonomous',
|
|
60
|
-
principal: 'my-agent',
|
|
61
|
-
tier: 'ind',
|
|
62
|
-
payment_tx: 'solana-tx-signature...',
|
|
63
|
-
});
|
|
57
|
+
// Purchase a SIGIL (cryptographic identity)
|
|
58
|
+
const sigil = await agent.purchaseSigil({
|
|
59
|
+
identity_class: 'autonomous',
|
|
60
|
+
principal: 'my-agent',
|
|
61
|
+
tier: 'ind',
|
|
62
|
+
payment_tx: 'solana-tx-signature...',
|
|
63
|
+
});
|
|
64
64
|
|
|
65
65
|
// Start heartbeating (paid liveness proofs)
|
|
66
66
|
agent.startHeartbeat();
|
|
@@ -78,18 +78,18 @@ agent.stopHeartbeat();
|
|
|
78
78
|
|
|
79
79
|
## API
|
|
80
80
|
|
|
81
|
-
### `BeatAgent`
|
|
82
|
-
|
|
83
|
-
| Method | Description |
|
|
84
|
-
|--------|-------------|
|
|
85
|
-
| `init()` | Initialize the agent's Beat chain (birth in Logical Time) |
|
|
86
|
-
| `purchaseSigil(opts)` | Purchase a SIGIL identity (required for heartbeating) |
|
|
87
|
-
| `updateMetadata(fields)` | Update mutable SIGIL metadata fields |
|
|
88
|
-
| `heartbeat(paymentTx?, globalAnchor?)` | Submit a paid heartbeat and receive a signed lineage proof |
|
|
89
|
-
| `startHeartbeat()` | Start autonomous heartbeat loop |
|
|
90
|
-
| `stopHeartbeat()` | Stop heartbeat |
|
|
91
|
-
| `getPassport()` | Get latest lineage proof (Passport) |
|
|
92
|
-
| `reissueProof(paymentTx?)` | Reissue proof without extending lineage |
|
|
81
|
+
### `BeatAgent`
|
|
82
|
+
|
|
83
|
+
| Method | Description |
|
|
84
|
+
|--------|-------------|
|
|
85
|
+
| `init()` | Initialize the agent's Beat chain (birth in Logical Time) |
|
|
86
|
+
| `purchaseSigil(opts)` | Purchase a SIGIL identity (required for heartbeating) |
|
|
87
|
+
| `updateMetadata(fields)` | Update mutable SIGIL metadata fields |
|
|
88
|
+
| `heartbeat(paymentTx?, globalAnchor?)` | Submit a paid heartbeat and receive a signed lineage proof |
|
|
89
|
+
| `startHeartbeat()` | Start autonomous heartbeat loop |
|
|
90
|
+
| `stopHeartbeat()` | Stop heartbeat |
|
|
91
|
+
| `getPassport()` | Get latest lineage proof (Passport) |
|
|
92
|
+
| `reissueProof(paymentTx?)` | Reissue proof without extending lineage |
|
|
93
93
|
| `requestSpawn(name?)` | Spawn a child agent (requires accumulated beats) |
|
|
94
94
|
| `getStatus()` | Get full beat status from registry |
|
|
95
95
|
| `getLocalState()` | Get local state (no network call) |
|
|
@@ -124,7 +124,7 @@ Returns `RegistrationResult` with `hash`, `api_key`, `secret`, `wallet?`.
|
|
|
124
124
|
|
|
125
125
|
**Note:** Agent names should only contain `[a-zA-Z0-9_\-. ]`. Other characters are stripped by the server before signature verification.
|
|
126
126
|
|
|
127
|
-
### Phase 2 Types
|
|
127
|
+
### Phase 2 Types
|
|
128
128
|
|
|
129
129
|
```typescript
|
|
130
130
|
import type { Passport, LineageProof, IdentityClass, SigilResult, HeartbeatResult } from '@provenonce/sdk';
|
|
@@ -133,20 +133,20 @@ import type { Passport, LineageProof, IdentityClass, SigilResult, HeartbeatResul
|
|
|
133
133
|
// Contains: agent_hash, agent_public_key, identity_class, lineage_chain_hash,
|
|
134
134
|
// provenonce_signature, issued_at, valid_until, etc.
|
|
135
135
|
|
|
136
|
-
// IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator'
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### `purchaseSigil(opts)` required fields
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
await agent.purchaseSigil({
|
|
143
|
-
identity_class: 'narrow_task' | 'autonomous' | 'orchestrator',
|
|
144
|
-
principal: 'my-agent',
|
|
145
|
-
tier: 'sov' | 'org' | 'ind' | 'eph' | 'sbx',
|
|
146
|
-
payment_tx: 'solana-tx-signature...', // or 'devnet-skip' on devnet
|
|
147
|
-
name: 'optional-display-name'
|
|
148
|
-
});
|
|
149
|
-
```
|
|
136
|
+
// IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `purchaseSigil(opts)` required fields
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
await agent.purchaseSigil({
|
|
143
|
+
identity_class: 'narrow_task' | 'autonomous' | 'orchestrator',
|
|
144
|
+
principal: 'my-agent',
|
|
145
|
+
tier: 'sov' | 'org' | 'ind' | 'eph' | 'sbx',
|
|
146
|
+
payment_tx: 'solana-tx-signature...', // or 'devnet-skip' on devnet
|
|
147
|
+
name: 'optional-display-name'
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
150
|
|
|
151
151
|
### Error Handling
|
|
152
152
|
|
|
@@ -181,7 +181,7 @@ Python examples use the REST API directly — no Python SDK needed. See [`exampl
|
|
|
181
181
|
|
|
182
182
|
## Links
|
|
183
183
|
|
|
184
|
-
- [Live prototype](https://provenonce.io)
|
|
185
|
-
- [npm package](https://www.npmjs.com/package/@provenonce/sdk)
|
|
186
|
-
- [API docs](https://provenonce.dev)
|
|
187
|
-
- [Whitepaper](https://provenonce.dev/whitepaper)
|
|
184
|
+
- [Live prototype](https://provenonce.io)
|
|
185
|
+
- [npm package](https://www.npmjs.com/package/@provenonce/sdk)
|
|
186
|
+
- [API docs](https://provenonce.dev)
|
|
187
|
+
- [Whitepaper](https://provenonce.dev/whitepaper)
|
package/dist/index.d.mts
CHANGED
|
@@ -161,6 +161,20 @@ interface Beat {
|
|
|
161
161
|
anchor_hash?: string;
|
|
162
162
|
}
|
|
163
163
|
declare function computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat;
|
|
164
|
+
/**
|
|
165
|
+
* Verify an anchor hash locally.
|
|
166
|
+
* V3 (solana_entropy present): binary-canonical single SHA-256.
|
|
167
|
+
* V1 legacy (no entropy): string-based hash with difficulty iteration.
|
|
168
|
+
*/
|
|
169
|
+
declare function verifyAnchorHash(anchor: {
|
|
170
|
+
prev_hash: string;
|
|
171
|
+
beat_index: number;
|
|
172
|
+
hash: string;
|
|
173
|
+
utc: number;
|
|
174
|
+
epoch: number;
|
|
175
|
+
difficulty: number;
|
|
176
|
+
solana_entropy?: string;
|
|
177
|
+
}): boolean;
|
|
164
178
|
/** Result from a check-in submission */
|
|
165
179
|
interface CheckinResult {
|
|
166
180
|
ok: boolean;
|
|
@@ -242,9 +256,42 @@ interface RegistrationResult {
|
|
|
242
256
|
heartbeat?: string;
|
|
243
257
|
};
|
|
244
258
|
}
|
|
259
|
+
/** Options for the register() function */
|
|
260
|
+
interface RegisterOptions {
|
|
261
|
+
registryUrl?: string;
|
|
262
|
+
parentHash?: string;
|
|
263
|
+
parentApiKey?: string;
|
|
264
|
+
registrationSecret?: string;
|
|
265
|
+
/** Single-use registration token from POST /register/token or POST /register/email/verify */
|
|
266
|
+
registrationToken?: string;
|
|
267
|
+
/** Admin-minted invite token */
|
|
268
|
+
registrationInvite?: string;
|
|
269
|
+
/** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */
|
|
270
|
+
walletSecretKey?: string;
|
|
271
|
+
/** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */
|
|
272
|
+
walletModel?: 'self-custody' | 'operator';
|
|
273
|
+
/** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */
|
|
274
|
+
walletChain?: 'solana' | 'ethereum';
|
|
275
|
+
/** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */
|
|
276
|
+
walletAddress?: string;
|
|
277
|
+
/** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */
|
|
278
|
+
walletSignFn?: (message: string) => Promise<string>;
|
|
279
|
+
/** Operator's Solana wallet address (base58). Required when walletModel='operator'. */
|
|
280
|
+
operatorWalletAddress?: string;
|
|
281
|
+
/** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */
|
|
282
|
+
operatorSignFn?: (message: string) => Promise<string>;
|
|
283
|
+
/** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */
|
|
284
|
+
metadata?: Record<string, unknown>;
|
|
285
|
+
}
|
|
245
286
|
/**
|
|
246
287
|
* Register a new agent on the Provenonce registry.
|
|
247
288
|
*
|
|
289
|
+
* With registration token (from /register/token or email verification):
|
|
290
|
+
* const creds = await register('my-agent', {
|
|
291
|
+
* registryUrl: '...',
|
|
292
|
+
* registrationToken: '<token-from-email-verify>',
|
|
293
|
+
* });
|
|
294
|
+
*
|
|
248
295
|
* No wallet (default, single-phase):
|
|
249
296
|
* const creds = await register('my-agent', { registryUrl: '...' });
|
|
250
297
|
*
|
|
@@ -285,28 +332,7 @@ interface RegistrationResult {
|
|
|
285
332
|
* parentApiKey: parentCreds.api_key,
|
|
286
333
|
* });
|
|
287
334
|
*/
|
|
288
|
-
declare function register(name: string, options?:
|
|
289
|
-
registryUrl?: string;
|
|
290
|
-
parentHash?: string;
|
|
291
|
-
parentApiKey?: string;
|
|
292
|
-
registrationSecret?: string;
|
|
293
|
-
/** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */
|
|
294
|
-
walletSecretKey?: string;
|
|
295
|
-
/** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */
|
|
296
|
-
walletModel?: 'self-custody' | 'operator';
|
|
297
|
-
/** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */
|
|
298
|
-
walletChain?: 'solana' | 'ethereum';
|
|
299
|
-
/** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */
|
|
300
|
-
walletAddress?: string;
|
|
301
|
-
/** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */
|
|
302
|
-
walletSignFn?: (message: string) => Promise<string>;
|
|
303
|
-
/** Operator's Solana wallet address (base58). Required when walletModel='operator'. */
|
|
304
|
-
operatorWalletAddress?: string;
|
|
305
|
-
/** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */
|
|
306
|
-
operatorSignFn?: (message: string) => Promise<string>;
|
|
307
|
-
/** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */
|
|
308
|
-
metadata?: Record<string, unknown>;
|
|
309
|
-
}): Promise<RegistrationResult>;
|
|
335
|
+
declare function register(name: string, options?: RegisterOptions): Promise<RegistrationResult>;
|
|
310
336
|
interface BeatAgentConfig {
|
|
311
337
|
/** API key from registration (pvn_...) */
|
|
312
338
|
apiKey: string;
|
|
@@ -330,6 +356,8 @@ interface BeatAgentConfig {
|
|
|
330
356
|
onStatusChange?: (status: string, details: Record<string, unknown>) => void;
|
|
331
357
|
/** Enable verbose logging */
|
|
332
358
|
verbose?: boolean;
|
|
359
|
+
/** Verify anchor hash locally before trusting it (default: true). */
|
|
360
|
+
verifyAnchors?: boolean;
|
|
333
361
|
}
|
|
334
362
|
declare class BeatAgent {
|
|
335
363
|
private config;
|
|
@@ -573,4 +601,4 @@ declare class ServerError extends ProvenonceError {
|
|
|
573
601
|
constructor(message: string, statusCode?: number);
|
|
574
602
|
}
|
|
575
603
|
|
|
576
|
-
export { type AgentStatus, AuthError, type Beat, BeatAgent, type BeatAgentConfig, type Capability, type CheckinResult, type ComplianceRegime, ErrorCode, FrozenError, type HeartbeatResult, type IdentityClass, type LineageProof, type MetadataUpdateResult, NetworkError, NotFoundError, type Passport, ProvenonceError, RateLimitError, type RegistrationResult, ServerError, type SigilMutableFields, type SigilProtocol, type SigilPurchaseOptions, type SigilResult, type SigilTier, type SpawnResult, StateError, type Substrate, type SubstrateProvider, ValidationError, type VerificationResult, type WalletInfo, computeBeat, computeBeatsLite, generateWalletKeypair, register };
|
|
604
|
+
export { type AgentStatus, AuthError, type Beat, BeatAgent, type BeatAgentConfig, type Capability, type CheckinResult, type ComplianceRegime, ErrorCode, FrozenError, type HeartbeatResult, type IdentityClass, type LineageProof, type MetadataUpdateResult, NetworkError, NotFoundError, type Passport, ProvenonceError, RateLimitError, type RegisterOptions, type RegistrationResult, ServerError, type SigilMutableFields, type SigilProtocol, type SigilPurchaseOptions, type SigilResult, type SigilTier, type SpawnResult, StateError, type Substrate, type SubstrateProvider, ValidationError, type VerificationResult, type WalletInfo, computeBeat, computeBeatsLite, generateWalletKeypair, register, verifyAnchorHash };
|
package/dist/index.d.ts
CHANGED
|
@@ -161,6 +161,20 @@ interface Beat {
|
|
|
161
161
|
anchor_hash?: string;
|
|
162
162
|
}
|
|
163
163
|
declare function computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat;
|
|
164
|
+
/**
|
|
165
|
+
* Verify an anchor hash locally.
|
|
166
|
+
* V3 (solana_entropy present): binary-canonical single SHA-256.
|
|
167
|
+
* V1 legacy (no entropy): string-based hash with difficulty iteration.
|
|
168
|
+
*/
|
|
169
|
+
declare function verifyAnchorHash(anchor: {
|
|
170
|
+
prev_hash: string;
|
|
171
|
+
beat_index: number;
|
|
172
|
+
hash: string;
|
|
173
|
+
utc: number;
|
|
174
|
+
epoch: number;
|
|
175
|
+
difficulty: number;
|
|
176
|
+
solana_entropy?: string;
|
|
177
|
+
}): boolean;
|
|
164
178
|
/** Result from a check-in submission */
|
|
165
179
|
interface CheckinResult {
|
|
166
180
|
ok: boolean;
|
|
@@ -242,9 +256,42 @@ interface RegistrationResult {
|
|
|
242
256
|
heartbeat?: string;
|
|
243
257
|
};
|
|
244
258
|
}
|
|
259
|
+
/** Options for the register() function */
|
|
260
|
+
interface RegisterOptions {
|
|
261
|
+
registryUrl?: string;
|
|
262
|
+
parentHash?: string;
|
|
263
|
+
parentApiKey?: string;
|
|
264
|
+
registrationSecret?: string;
|
|
265
|
+
/** Single-use registration token from POST /register/token or POST /register/email/verify */
|
|
266
|
+
registrationToken?: string;
|
|
267
|
+
/** Admin-minted invite token */
|
|
268
|
+
registrationInvite?: string;
|
|
269
|
+
/** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */
|
|
270
|
+
walletSecretKey?: string;
|
|
271
|
+
/** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */
|
|
272
|
+
walletModel?: 'self-custody' | 'operator';
|
|
273
|
+
/** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */
|
|
274
|
+
walletChain?: 'solana' | 'ethereum';
|
|
275
|
+
/** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */
|
|
276
|
+
walletAddress?: string;
|
|
277
|
+
/** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */
|
|
278
|
+
walletSignFn?: (message: string) => Promise<string>;
|
|
279
|
+
/** Operator's Solana wallet address (base58). Required when walletModel='operator'. */
|
|
280
|
+
operatorWalletAddress?: string;
|
|
281
|
+
/** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */
|
|
282
|
+
operatorSignFn?: (message: string) => Promise<string>;
|
|
283
|
+
/** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */
|
|
284
|
+
metadata?: Record<string, unknown>;
|
|
285
|
+
}
|
|
245
286
|
/**
|
|
246
287
|
* Register a new agent on the Provenonce registry.
|
|
247
288
|
*
|
|
289
|
+
* With registration token (from /register/token or email verification):
|
|
290
|
+
* const creds = await register('my-agent', {
|
|
291
|
+
* registryUrl: '...',
|
|
292
|
+
* registrationToken: '<token-from-email-verify>',
|
|
293
|
+
* });
|
|
294
|
+
*
|
|
248
295
|
* No wallet (default, single-phase):
|
|
249
296
|
* const creds = await register('my-agent', { registryUrl: '...' });
|
|
250
297
|
*
|
|
@@ -285,28 +332,7 @@ interface RegistrationResult {
|
|
|
285
332
|
* parentApiKey: parentCreds.api_key,
|
|
286
333
|
* });
|
|
287
334
|
*/
|
|
288
|
-
declare function register(name: string, options?:
|
|
289
|
-
registryUrl?: string;
|
|
290
|
-
parentHash?: string;
|
|
291
|
-
parentApiKey?: string;
|
|
292
|
-
registrationSecret?: string;
|
|
293
|
-
/** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */
|
|
294
|
-
walletSecretKey?: string;
|
|
295
|
-
/** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */
|
|
296
|
-
walletModel?: 'self-custody' | 'operator';
|
|
297
|
-
/** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */
|
|
298
|
-
walletChain?: 'solana' | 'ethereum';
|
|
299
|
-
/** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */
|
|
300
|
-
walletAddress?: string;
|
|
301
|
-
/** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */
|
|
302
|
-
walletSignFn?: (message: string) => Promise<string>;
|
|
303
|
-
/** Operator's Solana wallet address (base58). Required when walletModel='operator'. */
|
|
304
|
-
operatorWalletAddress?: string;
|
|
305
|
-
/** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */
|
|
306
|
-
operatorSignFn?: (message: string) => Promise<string>;
|
|
307
|
-
/** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */
|
|
308
|
-
metadata?: Record<string, unknown>;
|
|
309
|
-
}): Promise<RegistrationResult>;
|
|
335
|
+
declare function register(name: string, options?: RegisterOptions): Promise<RegistrationResult>;
|
|
310
336
|
interface BeatAgentConfig {
|
|
311
337
|
/** API key from registration (pvn_...) */
|
|
312
338
|
apiKey: string;
|
|
@@ -330,6 +356,8 @@ interface BeatAgentConfig {
|
|
|
330
356
|
onStatusChange?: (status: string, details: Record<string, unknown>) => void;
|
|
331
357
|
/** Enable verbose logging */
|
|
332
358
|
verbose?: boolean;
|
|
359
|
+
/** Verify anchor hash locally before trusting it (default: true). */
|
|
360
|
+
verifyAnchors?: boolean;
|
|
333
361
|
}
|
|
334
362
|
declare class BeatAgent {
|
|
335
363
|
private config;
|
|
@@ -573,4 +601,4 @@ declare class ServerError extends ProvenonceError {
|
|
|
573
601
|
constructor(message: string, statusCode?: number);
|
|
574
602
|
}
|
|
575
603
|
|
|
576
|
-
export { type AgentStatus, AuthError, type Beat, BeatAgent, type BeatAgentConfig, type Capability, type CheckinResult, type ComplianceRegime, ErrorCode, FrozenError, type HeartbeatResult, type IdentityClass, type LineageProof, type MetadataUpdateResult, NetworkError, NotFoundError, type Passport, ProvenonceError, RateLimitError, type RegistrationResult, ServerError, type SigilMutableFields, type SigilProtocol, type SigilPurchaseOptions, type SigilResult, type SigilTier, type SpawnResult, StateError, type Substrate, type SubstrateProvider, ValidationError, type VerificationResult, type WalletInfo, computeBeat, computeBeatsLite, generateWalletKeypair, register };
|
|
604
|
+
export { type AgentStatus, AuthError, type Beat, BeatAgent, type BeatAgentConfig, type Capability, type CheckinResult, type ComplianceRegime, ErrorCode, FrozenError, type HeartbeatResult, type IdentityClass, type LineageProof, type MetadataUpdateResult, NetworkError, NotFoundError, type Passport, ProvenonceError, RateLimitError, type RegisterOptions, type RegistrationResult, ServerError, type SigilMutableFields, type SigilProtocol, type SigilPurchaseOptions, type SigilResult, type SigilTier, type SpawnResult, StateError, type Substrate, type SubstrateProvider, ValidationError, type VerificationResult, type WalletInfo, computeBeat, computeBeatsLite, generateWalletKeypair, register, verifyAnchorHash };
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,8 @@ __export(index_exports, {
|
|
|
34
34
|
computeBeat: () => computeBeat,
|
|
35
35
|
computeBeatsLite: () => computeBeatsLite,
|
|
36
36
|
generateWalletKeypair: () => generateWalletKeypair,
|
|
37
|
-
register: () => register
|
|
37
|
+
register: () => register,
|
|
38
|
+
verifyAnchorHash: () => verifyAnchorHash
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(index_exports);
|
|
40
41
|
|
|
@@ -149,6 +150,54 @@ function computeBeat(prevHash, beatIndex, difficulty, nonce, anchorHash) {
|
|
|
149
150
|
}
|
|
150
151
|
return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };
|
|
151
152
|
}
|
|
153
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
154
|
+
function base58DecodeToBuffer(str) {
|
|
155
|
+
const map = {};
|
|
156
|
+
for (let i = 0; i < BASE58_ALPHABET.length; i++) map[BASE58_ALPHABET[i]] = i;
|
|
157
|
+
let bytes = [0];
|
|
158
|
+
for (let i = 0; i < str.length; i++) {
|
|
159
|
+
const val = map[str[i]];
|
|
160
|
+
if (val === void 0) throw new Error("invalid base58 character");
|
|
161
|
+
let carry = val;
|
|
162
|
+
for (let j = 0; j < bytes.length; j++) {
|
|
163
|
+
const x = bytes[j] * 58 + carry;
|
|
164
|
+
bytes[j] = x & 255;
|
|
165
|
+
carry = x >> 8;
|
|
166
|
+
}
|
|
167
|
+
while (carry > 0) {
|
|
168
|
+
bytes.push(carry & 255);
|
|
169
|
+
carry >>= 8;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
for (let i = 0; i < str.length && str[i] === "1"; i++) bytes.push(0);
|
|
173
|
+
return Buffer.from(bytes.reverse());
|
|
174
|
+
}
|
|
175
|
+
function u64be(n) {
|
|
176
|
+
const buf = Buffer.alloc(8);
|
|
177
|
+
buf.writeUInt32BE(Math.floor(n / 4294967296), 0);
|
|
178
|
+
buf.writeUInt32BE(n >>> 0, 4);
|
|
179
|
+
return buf;
|
|
180
|
+
}
|
|
181
|
+
var ANCHOR_DOMAIN_PREFIX = "PROVENONCE_BEATS_V1";
|
|
182
|
+
function verifyAnchorHash(anchor) {
|
|
183
|
+
if (!anchor || !anchor.hash || !anchor.prev_hash) return false;
|
|
184
|
+
if (anchor.solana_entropy) {
|
|
185
|
+
const prefix = Buffer.from(ANCHOR_DOMAIN_PREFIX, "utf8");
|
|
186
|
+
const prev = Buffer.from(anchor.prev_hash, "hex");
|
|
187
|
+
const idx = u64be(anchor.beat_index);
|
|
188
|
+
const entropy = base58DecodeToBuffer(anchor.solana_entropy);
|
|
189
|
+
const preimage = Buffer.concat([prefix, prev, idx, entropy]);
|
|
190
|
+
const computed = (0, import_crypto.createHash)("sha256").update(preimage).digest("hex");
|
|
191
|
+
return computed === anchor.hash;
|
|
192
|
+
}
|
|
193
|
+
const nonce = `anchor:${anchor.utc}:${anchor.epoch}`;
|
|
194
|
+
const seed = `${anchor.prev_hash}:${anchor.beat_index}:${nonce}`;
|
|
195
|
+
let current = (0, import_crypto.createHash)("sha256").update(seed).digest("hex");
|
|
196
|
+
for (let i = 0; i < anchor.difficulty; i++) {
|
|
197
|
+
current = (0, import_crypto.createHash)("sha256").update(current).digest("hex");
|
|
198
|
+
}
|
|
199
|
+
return current === anchor.hash;
|
|
200
|
+
}
|
|
152
201
|
var ED25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b657004220420", "hex");
|
|
153
202
|
function generateWalletKeypair() {
|
|
154
203
|
const { publicKey, privateKey } = (0, import_crypto.generateKeyPairSync)("ed25519");
|
|
@@ -183,6 +232,12 @@ async function register(name, options) {
|
|
|
183
232
|
if (options?.registrationSecret) {
|
|
184
233
|
headers["x-registration-secret"] = options.registrationSecret;
|
|
185
234
|
}
|
|
235
|
+
if (options?.registrationToken) {
|
|
236
|
+
headers["x-registration-token"] = options.registrationToken;
|
|
237
|
+
}
|
|
238
|
+
if (options?.registrationInvite) {
|
|
239
|
+
headers["x-registration-invite"] = options.registrationInvite;
|
|
240
|
+
}
|
|
186
241
|
if (options?.parentHash) {
|
|
187
242
|
if (options.parentApiKey) {
|
|
188
243
|
headers["Authorization"] = `Bearer ${options.parentApiKey}`;
|
|
@@ -432,6 +487,7 @@ var BeatAgent = class {
|
|
|
432
487
|
onStatusChange: () => {
|
|
433
488
|
},
|
|
434
489
|
verbose: false,
|
|
490
|
+
verifyAnchors: true,
|
|
435
491
|
...config
|
|
436
492
|
};
|
|
437
493
|
}
|
|
@@ -957,6 +1013,10 @@ var BeatAgent = class {
|
|
|
957
1013
|
clearTimeout(timeout);
|
|
958
1014
|
const data = await res.json();
|
|
959
1015
|
if (data.anchor) {
|
|
1016
|
+
if (this.config.verifyAnchors && !verifyAnchorHash(data.anchor)) {
|
|
1017
|
+
this.log("\u26A0 Anchor hash verification FAILED \u2014 rejecting untrusted anchor");
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
960
1020
|
this.globalBeat = data.anchor.beat_index;
|
|
961
1021
|
this.globalAnchorHash = data.anchor.hash || "";
|
|
962
1022
|
if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;
|
|
@@ -1056,6 +1116,7 @@ function computeBeatsLite(startHash, startIndex, count, difficulty = 1e3, anchor
|
|
|
1056
1116
|
computeBeat,
|
|
1057
1117
|
computeBeatsLite,
|
|
1058
1118
|
generateWalletKeypair,
|
|
1059
|
-
register
|
|
1119
|
+
register,
|
|
1120
|
+
verifyAnchorHash
|
|
1060
1121
|
});
|
|
1061
1122
|
//# sourceMappingURL=index.js.map
|