@provenonce/sdk 0.11.0 → 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/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;
@@ -342,6 +356,8 @@ interface BeatAgentConfig {
342
356
  onStatusChange?: (status: string, details: Record<string, unknown>) => void;
343
357
  /** Enable verbose logging */
344
358
  verbose?: boolean;
359
+ /** Verify anchor hash locally before trusting it (default: true). */
360
+ verifyAnchors?: boolean;
345
361
  }
346
362
  declare class BeatAgent {
347
363
  private config;
@@ -585,4 +601,4 @@ declare class ServerError extends ProvenonceError {
585
601
  constructor(message: string, statusCode?: number);
586
602
  }
587
603
 
588
- 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 };
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;
@@ -342,6 +356,8 @@ interface BeatAgentConfig {
342
356
  onStatusChange?: (status: string, details: Record<string, unknown>) => void;
343
357
  /** Enable verbose logging */
344
358
  verbose?: boolean;
359
+ /** Verify anchor hash locally before trusting it (default: true). */
360
+ verifyAnchors?: boolean;
345
361
  }
346
362
  declare class BeatAgent {
347
363
  private config;
@@ -585,4 +601,4 @@ declare class ServerError extends ProvenonceError {
585
601
  constructor(message: string, statusCode?: number);
586
602
  }
587
603
 
588
- 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 };
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");
@@ -438,6 +487,7 @@ var BeatAgent = class {
438
487
  onStatusChange: () => {
439
488
  },
440
489
  verbose: false,
490
+ verifyAnchors: true,
441
491
  ...config
442
492
  };
443
493
  }
@@ -963,6 +1013,10 @@ var BeatAgent = class {
963
1013
  clearTimeout(timeout);
964
1014
  const data = await res.json();
965
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
+ }
966
1020
  this.globalBeat = data.anchor.beat_index;
967
1021
  this.globalAnchorHash = data.anchor.hash || "";
968
1022
  if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;
@@ -1062,6 +1116,7 @@ function computeBeatsLite(startHash, startIndex, count, difficulty = 1e3, anchor
1062
1116
  computeBeat,
1063
1117
  computeBeatsLite,
1064
1118
  generateWalletKeypair,
1065
- register
1119
+ register,
1120
+ verifyAnchorHash
1066
1121
  });
1067
1122
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/beat-sdk.ts","../src/errors.ts"],"sourcesContent":["export { BeatAgent, computeBeat, computeBeatsLite, register, generateWalletKeypair } from './beat-sdk';\nexport type {\n BeatAgentConfig,\n Beat,\n CheckinResult,\n SpawnResult,\n AgentStatus,\n RegisterOptions,\n RegistrationResult,\n WalletInfo,\n // Phase 2 types\n IdentityClass,\n LineageProof,\n Passport,\n SigilResult,\n HeartbeatResult,\n // SIGIL Namespace v0.4 types\n SigilTier,\n Substrate,\n SubstrateProvider,\n Capability,\n SigilProtocol,\n ComplianceRegime,\n SigilPurchaseOptions,\n SigilMutableFields,\n MetadataUpdateResult,\n VerificationResult,\n} from './beat-sdk';\n\nexport {\n ProvenonceError,\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NotFoundError,\n NetworkError,\n ServerError,\n ErrorCode,\n} from './errors';\n","/**\n * ═══════════════════════════════════════════════════════════\n * PROVENONCE BEAT SDK — Agent Heartbeat Client\n * ═══════════════════════════════════════════════════════════\n * \n * \"NIST tells you what time it is.\n * Provenonce tells the agent at what speed it is allowed to exist.\"\n * \n * Usage:\n * \n * import { BeatAgent } from './beat-sdk';\n * \n * const agent = new BeatAgent({\n * apiKey: 'pvn_...',\n * registryUrl: 'https://provenonce.io',\n * });\n * \n * await agent.init(); // Birth in Beat time\n * await agent.pulse(50); // Compute 50 beats\n * await agent.checkin(); // Report to registry\n * \n * // Or run the autonomous heartbeat:\n * agent.startHeartbeat(); // Computes + checks in continuously\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, generateKeyPairSync, sign, verify, createPrivateKey, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n mapApiError,\n ErrorCode,\n} from './errors';\n\n// ============ PHASE 2 TYPES ============\n\n/** SIGIL identity class — determines tier pricing and heartbeat volume caps */\nexport type IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator';\n\n/** SIGIL trust governance tier — orthogonal to identity_class (fee axis) */\nexport type SigilTier = 'sov' | 'org' | 'ind' | 'eph' | 'sbx';\n\n/** Substrate — what the agent runs on */\nexport type Substrate = 'frontier' | 'open' | 'local' | 'symbolic' | 'hybrid' | 'human';\n\n/** Substrate provider */\nexport type SubstrateProvider = 'anthropic' | 'openai' | 'google' | 'meta' | 'mistral' | 'xai' | 'cohere' | 'deepseek' | 'custom';\n\n/** Capability — what the agent primarily does */\nexport type Capability = 'analyst' | 'executor' | 'orchestrator' | 'guardian' | 'retriever' | 'renderer' | 'witness';\n\n/** Protocol — how to reach the agent */\nexport type SigilProtocol = 'http' | 'grpc' | 'websocket' | 'mcp' | 'a2a' | 'custom';\n\n/** Compliance regime */\nexport type ComplianceRegime = 'gdpr' | 'pdpa' | 'hipaa' | 'sox' | 'aisi' | 'none' | 'custom';\n\n/**\n * Ed25519-signed lineage proof — portable, offline-verifiable credential.\n * Also known as the agent's \"passport\" — a cryptographic proof of identity\n * that can be verified offline without any API call or SOL cost.\n */\nexport interface LineageProof {\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n issued_at: number;\n valid_until: number;\n provenonce_signature: string;\n}\n\n/** Passport = LineageProof. The agent's portable, offline-verifiable credential. */\nexport type Passport = LineageProof;\n\n/** Options for purchasing a SIGIL with full namespace */\nexport interface SigilPurchaseOptions {\n identity_class: IdentityClass;\n principal: string;\n tier: SigilTier;\n name?: string; // \"auto\" or custom name\n payment_tx: string;\n // Optional initial metadata\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Mutable SIGIL metadata fields for PATCH updates */\nexport interface SigilMutableFields {\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n generation_trigger?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Result from purchasing a SIGIL (Structured Identity Governance and Intelligent Lookup) */\nexport interface SigilResult {\n ok: boolean;\n sigil?: {\n sigil: string; // Full SIGIL string: name*principal*tier\n sigil_name: string;\n principal: string;\n tier: SigilTier;\n identity_class: IdentityClass;\n issued_at_beat: number;\n birth_tx: string | null;\n explorer_url: string | null;\n };\n lineage_proof?: LineageProof;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n/** Result from updating mutable SIGIL metadata */\nexport interface MetadataUpdateResult {\n ok: boolean;\n sigil?: string;\n generation?: number;\n updated_fields?: string[];\n error?: string;\n}\n\n/** Result from offline lineage proof verification */\nexport interface VerificationResult {\n /** Overall validity: signature is valid AND not expired */\n valid: boolean;\n /** Ed25519 signature verification passed */\n signatureValid: boolean;\n /** Proof has passed its valid_until timestamp */\n expired: boolean;\n /** The beat index of the agent's last heartbeat */\n lastHeartbeatBeat: number;\n /** Beats elapsed since last heartbeat (null if currentBeat not provided) */\n beatsSinceHeartbeat: number | null;\n /** Human-readable warning if proof is expired or stale */\n warning?: string;\n}\n\n/** Result from a paid heartbeat */\nexport interface HeartbeatResult {\n ok: boolean;\n lineage_proof?: LineageProof;\n heartbeat_count_epoch?: number;\n billing_epoch?: number;\n current_beat?: number;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n tier: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n// ============ VDF ENGINE (LOCAL) ============\n\nexport interface Beat {\n index: number;\n hash: string;\n prev: string;\n timestamp: number;\n nonce?: string;\n anchor_hash?: string;\n}\n\nfunction computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat {\n const timestamp = Date.now();\n\n const seed = anchorHash\n ? `${prevHash}:${beatIndex}:${nonce || ''}:${anchorHash}`\n : `${prevHash}:${beatIndex}:${nonce || ''}`;\n\n let current = createHash('sha256')\n .update(seed)\n .digest('hex');\n\n for (let i = 0; i < difficulty; i++) {\n current = createHash('sha256')\n .update(current)\n .digest('hex');\n }\n\n return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };\n}\n\n// ============ SDK RESULT TYPES ============\n\n/** Result from a check-in submission */\nexport interface CheckinResult {\n ok: boolean;\n total_beats: number;\n beats_accepted: number;\n global_beat: number;\n status?: string;\n beats_behind?: number;\n}\n\n/** Result from a spawn request */\nexport interface SpawnResult {\n ok: boolean;\n eligible: boolean;\n child_hash?: string;\n progress_pct?: number;\n deficit?: number;\n}\n\n/** Agent status from the registry */\nexport interface AgentStatus {\n already_initialized: boolean;\n total_beats: number;\n genesis_hash: string;\n status: string;\n genesis?: { hash: string; prev: string; timestamp: number };\n difficulty?: number;\n}\n\n// ============ WALLET KEYPAIR GENERATION ============\n\n// DER prefix for Ed25519 PKCS8 private keys (16 bytes)\nconst ED25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b657004220420', 'hex');\n\n/**\n * Generate an Ed25519 keypair for agent wallet identity.\n * Returns hex-encoded raw keys (32 bytes each).\n * Uses Node.js built-in crypto — zero external dependencies.\n */\nexport function generateWalletKeypair(): { publicKey: string; secretKey: string } {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519');\n const pubRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(12); // 32 bytes\n const privRaw = privateKey.export({ type: 'pkcs8', format: 'der' }).subarray(16); // 32 bytes\n return {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: Buffer.from(privRaw).toString('hex'),\n };\n}\n\n/**\n * Sign a message with an Ed25519 private key (hex-encoded 32-byte seed).\n * Returns hex-encoded signature (64 bytes).\n */\nfunction signMessage(secretKeyHex: string, message: string): string {\n const privRaw = Buffer.from(secretKeyHex, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const sig = sign(null, Buffer.from(message), keyObject);\n return Buffer.from(sig).toString('hex');\n}\n\n// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\n /** Hex-encoded 32-byte Ed25519 public key (Solana self-custody only, empty otherwise) */\n public_key: string;\n /** Hex-encoded 32-byte Ed25519 secret seed — SAVE THIS for future fee signing (Solana self-custody only) */\n secret_key: string;\n /** Solana-compatible base58 address (Solana wallets only) */\n solana_address?: string;\n /** The wallet address (base58 for Solana, 0x for Ethereum) */\n address: string;\n /** Wallet chain: 'solana' or 'ethereum' */\n chain: string;\n}\n\n/** Result from registering an agent */\nexport interface RegistrationResult {\n hash: string;\n api_key: string;\n secret: string;\n type: 'root' | 'agent';\n parent: string | null;\n depth: number;\n name: string;\n metadata?: Record<string, unknown> | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n signature?: string | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n explorer_url?: string | null;\n /** Wallet chain: 'solana', 'ethereum', or null (no wallet) */\n wallet_chain?: string | null;\n beat?: { genesis_hash: string; difficulty: number; status: string };\n /** Wallet info — only present for root agents with wallets */\n wallet?: WalletInfo;\n /** Next steps after registration */\n _next_steps?: { sigil?: string; heartbeat?: string };\n}\n\n/** Options for the register() function */\nexport interface RegisterOptions {\n registryUrl?: string;\n parentHash?: string;\n parentApiKey?: string;\n registrationSecret?: string;\n /** Single-use registration token from POST /register/token or POST /register/email/verify */\n registrationToken?: string;\n /** Admin-minted invite token */\n registrationInvite?: string;\n /** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */\n walletSecretKey?: string;\n /** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: 'self-custody' | 'operator';\n /** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */\n walletChain?: 'solana' | 'ethereum';\n /** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */\n walletAddress?: string;\n /** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */\n walletSignFn?: (message: string) => Promise<string>;\n /** Operator's Solana wallet address (base58). Required when walletModel='operator'. */\n operatorWalletAddress?: string;\n /** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */\n operatorSignFn?: (message: string) => Promise<string>;\n /** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Register a new agent on the Provenonce registry.\n *\n * With registration token (from /register/token or email verification):\n * const creds = await register('my-agent', {\n * registryUrl: '...',\n * registrationToken: '<token-from-email-verify>',\n * });\n *\n * No wallet (default, single-phase):\n * const creds = await register('my-agent', { registryUrl: '...' });\n *\n * Solana self-custody wallet (Model A, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'self-custody',\n * });\n * // creds.wallet.secret_key = hex secret (SAVE THIS)\n * // creds.wallet.address = base58 Solana address\n *\n * Solana with existing key:\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletSecretKey: '<hex-encoded-32-byte-seed>',\n * });\n *\n * Ethereum bring-your-own (two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletChain: 'ethereum',\n * walletAddress: '0x...',\n * walletSignFn: (msg) => wallet.signMessage(msg),\n * });\n *\n * Solana operator (Model B, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'operator',\n * operatorWalletAddress: '<base58>',\n * operatorSignFn: (msg) => signWithWallet(msg),\n * });\n *\n * Child agent (no wallet):\n * const creds = await register('worker-1', {\n * registryUrl: '...',\n * parentHash: parentCreds.hash,\n * parentApiKey: parentCreds.api_key,\n * });\n */\nexport async function register(\n name: string,\n options?: RegisterOptions,\n): Promise<RegistrationResult> {\n // SDK-P1-07/P1-08: validate inputs\n if (!name || typeof name !== 'string' || name.trim().length === 0) {\n throw new ValidationError('name is required (must be a non-empty string)');\n }\n if (name.length > 64) {\n throw new ValidationError('name must be 64 characters or fewer');\n }\n\n const url = options?.registryUrl || 'https://provenonce.io';\n try {\n new URL(url);\n } catch {\n throw new ValidationError('registryUrl is not a valid URL');\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\n if (options?.registrationSecret) {\n headers['x-registration-secret'] = options.registrationSecret;\n }\n if (options?.registrationToken) {\n headers['x-registration-token'] = options.registrationToken;\n }\n if (options?.registrationInvite) {\n headers['x-registration-invite'] = options.registrationInvite;\n }\n\n // ===== CHILD REGISTRATION (no wallet, single-phase) =====\n if (options?.parentHash) {\n if (options.parentApiKey) {\n headers['Authorization'] = `Bearer ${options.parentApiKey}`;\n }\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, parent: options.parentHash, ...(options.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n }\n\n // ===== ETHEREUM BRING-YOUR-OWN (D-63, two-phase) =====\n if (options?.walletChain === 'ethereum') {\n if (!options.walletAddress || !options.walletSignFn) {\n throw new ValidationError('Ethereum registration requires walletAddress and walletSignFn');\n }\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(options.walletAddress)) {\n throw new ValidationError('walletAddress must be a valid Ethereum address (0x + 40 hex chars)');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_chain: 'ethereum' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Sign with Ethereum wallet (EIP-191 personal_sign)\n const nonce = challengeData.nonce;\n const message = `provenonce-register-ethereum:${nonce}:${options.walletAddress}:${name}`;\n const walletSignature = await options.walletSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_chain: 'ethereum',\n wallet_address: options.walletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n } catch {\n throw new NetworkError(`Ethereum registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Ethereum: wallet has address only (no keypair — user keeps custody externally)\n data.wallet = {\n public_key: '',\n secret_key: '',\n address: data.wallet?.address || options.walletAddress,\n chain: 'ethereum',\n };\n\n return data;\n }\n\n // ===== MODEL B: SOLANA OPERATOR WALLET REGISTRATION (two-phase) =====\n if (options?.walletModel === 'operator') {\n if (!options.operatorWalletAddress || !options.operatorSignFn) {\n throw new ValidationError('Operator registration requires operatorWalletAddress and operatorSignFn');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_model: 'operator' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Operator signs challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register-operator:${nonce}:${options.operatorWalletAddress}:${name}`;\n const walletSignature = await options.operatorSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_model: 'operator',\n operator_wallet_address: options.operatorWalletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n throw new NetworkError(`Operator registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Model B: wallet has address only (no secret_key/public_key — operator keeps custody)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\n public_key: '',\n secret_key: '',\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== MODEL A: SOLANA SELF-CUSTODY WALLET REGISTRATION (opt-in, two-phase) =====\n if (options?.walletModel === 'self-custody' || options?.walletSecretKey) {\n // Generate or use provided wallet keypair\n let walletKeys: { publicKey: string; secretKey: string };\n if (options?.walletSecretKey) {\n // Derive public key from provided secret\n const privRaw = Buffer.from(options.walletSecretKey, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const pubRaw = keyObject.export({ type: 'spki', format: 'der' }).subarray(12);\n walletKeys = {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: options.walletSecretKey,\n };\n } else {\n walletKeys = generateWalletKeypair();\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n const err = new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n // Attach wallet keys so caller can retry with the same keypair\n const err = mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Phase 2: Sign challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register:${nonce}:${walletKeys.publicKey}:${name}`;\n const walletSignature = signMessage(walletKeys.secretKey, message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_public_key: walletKeys.publicKey,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options?.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n // Attach wallet keys so caller can retry with the same keypair\n const err = new NetworkError(`Registration failed: ${registerRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!registerRes.ok) {\n // Attach wallet keys so caller can retry with the same keypair via walletSecretKey option\n const err = mapApiError(registerRes.status, data, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Attach the wallet keys (secret is client-side only, never sent to server)\n const addr = data.wallet?.address || data.wallet?.solana_address || '';\n data.wallet = {\n public_key: walletKeys.publicKey,\n secret_key: walletKeys.secretKey,\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== NO-WALLET REGISTRATION (D-62 default, single-phase) =====\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, ...(options?.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n}\n\n// ============ SDK CONFIG ============\n\nexport interface BeatAgentConfig {\n /** API key from registration (pvn_...) */\n apiKey: string;\n\n /** Provenonce registry URL */\n registryUrl: string;\n\n /** @deprecated Use heartbeatIntervalSec. Beats to compute per pulse (default: 10) */\n beatsPerPulse?: number;\n\n /** @deprecated Use heartbeatIntervalSec. Seconds between automatic check-ins (default: 300 = 5min) */\n checkinIntervalSec?: number;\n\n /** Seconds between automatic heartbeats (default: 300 = 5min). Replaces checkinIntervalSec. */\n heartbeatIntervalSec?: number;\n\n /** @deprecated VDF pulse callback. No longer used in Phase 2. */\n onPulse?: (beats: Beat[], totalBeats: number) => void;\n\n /** @deprecated Use onHeartbeat. Callback when check-in completes. */\n onCheckin?: (result: CheckinResult) => void;\n\n /** Callback when heartbeat completes (Phase 2) */\n onHeartbeat?: (result: HeartbeatResult) => void;\n\n /** Callback on error */\n onError?: (error: Error, context: string) => void;\n\n /** Callback when status changes */\n onStatusChange?: (status: string, details: Record<string, unknown>) => void;\n\n /** Enable verbose logging */\n verbose?: boolean;\n}\n\n// ============ BEAT AGENT ============\n\nexport class BeatAgent {\n private config: Required<BeatAgentConfig>;\n private chain: Beat[] = [];\n private difficulty: number = 1000;\n private genesisHash: string = '';\n private latestBeat: Beat | null = null;\n private totalBeats: number = 0;\n private lastCheckinBeat: number = 0;\n private status: 'uninitialized' | 'active' | 'frozen' | 'revoked' = 'uninitialized';\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private globalBeat: number = 0;\n private globalAnchorHash: string = '';\n\n constructor(config: BeatAgentConfig) {\n // SDK-P1-08: validate required config fields\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new ValidationError('BeatAgentConfig.apiKey is required (must be a non-empty string)');\n }\n if (!config.registryUrl || typeof config.registryUrl !== 'string') {\n throw new ValidationError('BeatAgentConfig.registryUrl is required (must be a non-empty string)');\n }\n // SDK-P1-07: validate registryUrl is a valid URL\n try {\n new URL(config.registryUrl);\n } catch {\n throw new ValidationError('BeatAgentConfig.registryUrl is not a valid URL');\n }\n\n // SDK-P2: validate optional numeric config\n if (config.beatsPerPulse !== undefined && (!Number.isInteger(config.beatsPerPulse) || config.beatsPerPulse < 1 || config.beatsPerPulse > 10000)) {\n throw new ValidationError('BeatAgentConfig.beatsPerPulse must be an integer between 1 and 10000');\n }\n if (config.checkinIntervalSec !== undefined && (!Number.isFinite(config.checkinIntervalSec) || config.checkinIntervalSec < 10 || config.checkinIntervalSec > 86400)) {\n throw new ValidationError('BeatAgentConfig.checkinIntervalSec must be between 10 and 86400');\n }\n\n this.config = {\n beatsPerPulse: 10,\n checkinIntervalSec: 300,\n heartbeatIntervalSec: 300,\n onPulse: () => {},\n onCheckin: () => {},\n onHeartbeat: () => {},\n onError: () => {},\n onStatusChange: () => {},\n verbose: false,\n ...config,\n };\n }\n\n // ── INITIALIZATION ──\n\n /**\n * Initialize the agent's Beat chain.\n * This is the agent's \"birth\" in Logical Time.\n * Must be called once before computing beats.\n */\n async init(): Promise<{ ok: boolean; genesis?: string; error?: string }> {\n try {\n this.log('Initializing Beat chain...');\n\n const res = await this.api('POST', '/api/v1/agent/init');\n\n if (res.genesis) {\n this.genesisHash = res.genesis.hash;\n this.difficulty = res.difficulty || 1000;\n this.latestBeat = {\n index: 0,\n hash: res.genesis.hash,\n prev: res.genesis.prev,\n timestamp: res.genesis.timestamp,\n };\n this.chain = [this.latestBeat];\n this.totalBeats = 0;\n this.status = 'active';\n this.config.onStatusChange('active', { genesis: this.genesisHash });\n this.log(`Born in Beat time. Genesis: ${this.genesisHash.slice(0, 16)}...`);\n } else if (res.already_initialized) {\n // Restore from existing state\n this.genesisHash = res.genesis_hash;\n this.totalBeats = res.total_beats;\n this.status = res.status as any;\n this.log(`Already initialized. Restoring state (${res.total_beats} beats).`);\n \n // Fetch full state to get latest hash\n await this.refreshState();\n }\n\n // Sync global anchor\n await this.syncGlobal();\n\n return { ok: true, genesis: this.genesisHash };\n\n } catch (err: any) {\n this.config.onError(err, 'init');\n return { ok: false, error: err.message };\n }\n }\n\n // ── PULSE (COMPUTE BEATS) ──\n\n /**\n * @deprecated Phase 2: VDF computation retired (D-68). Payment is the liveness mechanism.\n * Use heartbeat() instead. This method will be removed in the next major version.\n *\n * Compute N beats locally (VDF hash chain).\n */\n pulse(count?: number): Beat[] {\n console.warn('[Provenonce SDK] pulse() is deprecated. Use heartbeat() instead (Phase 2).');\n if (this.status === 'frozen') {\n throw new FrozenError('Cannot pulse: agent is frozen. Use resync() to re-establish provenance.');\n }\n if (this.status !== 'active') {\n throw new StateError(`Cannot pulse: agent is ${this.status}.`, this.status);\n }\n // SDK-P2: validate count param\n if (count !== undefined && (!Number.isInteger(count) || count < 1 || count > 10000)) {\n throw new ValidationError('pulse count must be an integer between 1 and 10000');\n }\n return this.computeBeats(count);\n }\n\n /** Internal beat computation — no status check. Used by both pulse() and resync(). */\n private computeBeats(count?: number, onProgress?: (computed: number, total: number) => void): Beat[] {\n const n = count || this.config.beatsPerPulse;\n\n if (!this.latestBeat) {\n throw new StateError('Beat chain not initialized. Call init() first.', 'uninitialized', ErrorCode.AGENT_NOT_INITIALIZED);\n }\n\n const newBeats: Beat[] = [];\n let prevHash = this.latestBeat.hash;\n let startIndex = this.latestBeat.index + 1;\n\n const t0 = Date.now();\n // SDK-P2: report progress every 10% of beats\n const progressInterval = Math.max(1, Math.floor(n / 10));\n\n for (let i = 0; i < n; i++) {\n const beat = computeBeat(prevHash, startIndex + i, this.difficulty, undefined, this.globalAnchorHash || undefined);\n newBeats.push(beat);\n prevHash = beat.hash;\n if (onProgress && (i + 1) % progressInterval === 0) {\n onProgress(i + 1, n);\n }\n }\n\n const elapsed = Date.now() - t0;\n\n // Update state\n this.chain.push(...newBeats);\n this.latestBeat = newBeats[newBeats.length - 1];\n this.totalBeats += n;\n\n // Keep chain bounded (only last 1000 beats in memory)\n if (this.chain.length > 1000) {\n this.chain = this.chain.slice(-500);\n }\n\n this.config.onPulse(newBeats, this.totalBeats);\n this.log(`Pulse: ${n} beats in ${elapsed}ms (${(elapsed / n).toFixed(1)}ms/beat, D=${this.difficulty})`);\n\n return newBeats;\n }\n\n // ── CHECK-IN ──\n\n /**\n * @deprecated Phase 2: VDF check-in retired (D-68). Use heartbeat() instead.\n * This method will be removed in the next major version.\n */\n async checkin(): Promise<{ ok: boolean; total_beats?: number; error?: string }> {\n console.warn('[Provenonce SDK] checkin() is deprecated. Use heartbeat() instead (Phase 2).');\n // SDK-P1-02: fix guard to compare beat indices, not totalBeats vs lastCheckinBeat\n if (!this.latestBeat || this.latestBeat.index <= this.lastCheckinBeat) {\n this.log('No new beats since last check-in. Call pulse() first.');\n return { ok: true, total_beats: this.totalBeats }; // Nothing new to report\n }\n\n try {\n // Find the boundary hashes\n const fromBeat = this.lastCheckinBeat;\n const toBeat = this.latestBeat.index;\n\n // Build spot checks from our local chain\n // prev and nonce are required for the server to recompute VDF\n // Must always include to_beat (final beat) — server requires it for final hash verification\n const spotChecks: { index: number; hash: string; prev: string; nonce?: string }[] = [];\n\n // Always include the final beat\n const toBeatEntry = this.chain.find(b => b.index === toBeat);\n if (toBeatEntry) {\n spotChecks.push({ index: toBeatEntry.index, hash: toBeatEntry.hash, prev: toBeatEntry.prev, nonce: toBeatEntry.nonce });\n }\n\n // Sample up to 4 more from the rest\n const available = this.chain.filter(b => b.index > this.lastCheckinBeat && b.index !== toBeat);\n const sampleCount = Math.min(4, available.length);\n\n for (let i = 0; i < sampleCount; i++) {\n const idx = Math.floor(Math.random() * available.length);\n const beat = available[idx];\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev, nonce: beat.nonce });\n available.splice(idx, 1);\n }\n const fromHash = this.chain.find(b => b.index === fromBeat)?.hash \n || this.genesisHash;\n const toHash = this.latestBeat.hash;\n\n const res = await this.api('POST', '/api/v1/agent/checkin', {\n proof: {\n from_beat: fromBeat,\n to_beat: toBeat,\n from_hash: fromHash,\n to_hash: toHash,\n beats_computed: toBeat - fromBeat,\n global_anchor: this.globalBeat,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: spotChecks,\n },\n });\n\n if (res.ok) {\n this.lastCheckinBeat = toBeat;\n this.totalBeats = res.total_beats;\n this.config.onCheckin(res);\n this.log(`Check-in accepted: ${res.beats_accepted} beats, total=${res.total_beats}, global=${res.global_beat}`);\n \n if (res.status === 'warning_overdue') {\n this.config.onStatusChange('warning', { beats_behind: res.beats_behind });\n this.log(`⚠ WARNING: ${res.beats_behind} anchors behind. Check in more frequently.`);\n }\n }\n\n return { ok: res.ok, total_beats: res.total_beats };\n\n } catch (err: any) {\n this.config.onError(err, 'checkin');\n return { ok: false, error: err.message };\n }\n }\n\n // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Optional function that returns a payment tx for each heartbeat.\n * If not provided, uses 'devnet-skip' (devnet only).\n */\n startHeartbeat(paymentTxFn?: () => Promise<string> | string): void {\n if (this.heartbeatInterval) {\n this.log('Heartbeat already running.');\n return;\n }\n\n if (this.status !== 'active' && this.status !== 'uninitialized') {\n throw new StateError(`Cannot start heartbeat in status '${this.status}'.`, this.status);\n }\n\n const intervalSec = this.config.heartbeatIntervalSec || this.config.checkinIntervalSec || 300;\n this.log(`Starting heartbeat (interval: ${intervalSec}s)...`);\n\n // SDK-P1-03: exponential backoff on consecutive errors\n let consecutiveErrors = 0;\n let skipCount = 0;\n\n this.heartbeatInterval = setInterval(async () => {\n if (skipCount > 0) {\n skipCount--;\n return;\n }\n\n try {\n const paymentTx = paymentTxFn ? await paymentTxFn() : 'devnet-skip';\n await this.heartbeat(paymentTx);\n consecutiveErrors = 0;\n } catch (err: any) {\n consecutiveErrors++;\n this.config.onError(err, 'heartbeat');\n skipCount = Math.min(32, Math.pow(2, consecutiveErrors - 1));\n this.log(`Heartbeat error #${consecutiveErrors}, backing off ${skipCount} ticks`);\n }\n }, intervalSec * 1000);\n }\n\n /**\n * Stop the heartbeat loop.\n */\n stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n this.log('Heartbeat stopped.');\n }\n }\n\n // ── RE-SYNC ──\n\n /**\n * @deprecated Phase 2: Resync retired (D-67). Dormancy resume is free — just call heartbeat().\n * This method will be removed in the next major version.\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n console.warn('[Provenonce SDK] resync() is deprecated (D-67). Use heartbeat() to resume (Phase 2).');\n try {\n this.log('Requesting re-sync challenge...');\n\n // Phase 1: Get challenge\n const challenge = await this.api('POST', '/api/v1/agent/resync', {\n action: 'challenge',\n });\n\n if (!challenge.challenge) {\n return { ok: false, error: 'Failed to get challenge' };\n }\n\n const required = challenge.challenge.required_beats;\n this.difficulty = challenge.challenge.difficulty;\n this.log(`Re-sync challenge: compute ${required} beats at D=${this.difficulty}`);\n\n // Sync global anchor so beats are woven with a recent anchor hash\n await this.syncGlobal();\n\n // Compute the required beats\n const startHash = challenge.challenge.start_from_hash;\n const startBeat = challenge.challenge.start_from_beat;\n\n // Reset chain from the known point\n this.latestBeat = { index: startBeat, hash: startHash, prev: '', timestamp: Date.now() };\n this.chain = [this.latestBeat];\n\n const t0 = Date.now();\n this.computeBeats(required);\n const elapsed = Date.now() - t0;\n this.log(`Re-sync beats computed in ${elapsed}ms`);\n\n // Phase 2: Submit proof (include challenge_nonce for server verification)\n const proof = await this.api('POST', '/api/v1/agent/resync', {\n action: 'prove',\n challenge_nonce: challenge.challenge.nonce,\n proof: {\n from_beat: startBeat,\n to_beat: this.latestBeat!.index,\n from_hash: startHash,\n to_hash: this.latestBeat!.hash,\n beats_computed: required,\n global_anchor: challenge.challenge.sync_to_global,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: (() => {\n // Must include to_beat (final beat) — server requires it for final hash verification\n const toBeatEntry = this.chain.find(b => b.index === this.latestBeat!.index);\n // Sample from available chain beats (chain may be trimmed to 500 entries)\n const available = this.chain\n .filter(b => b.index !== this.latestBeat!.index && b.index > startBeat);\n const step = Math.max(1, Math.ceil(available.length / 5));\n const others = available\n .filter((_, i) => i % step === 0)\n .slice(0, 4);\n const checks = toBeatEntry ? [toBeatEntry, ...others] : others;\n return checks.map(b => ({ index: b.index, hash: b.hash, prev: b.prev, nonce: b.nonce }));\n })(),\n },\n });\n\n if (proof.ok) {\n this.status = 'active';\n this.totalBeats = proof.total_beats;\n this.lastCheckinBeat = this.latestBeat!.index;\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced. Agent is alive again in Beat time.');\n }\n\n return { ok: proof.ok, beats_required: required };\n\n } catch (err: any) {\n this.config.onError(err, 'resync');\n return { ok: false, error: err.message };\n }\n }\n\n // ── SPAWN ──\n\n /**\n * Request to spawn a child agent.\n * Requires sufficient accumulated beats (Temporal Gestation).\n */\n async requestSpawn(childName?: string, childHash?: string): Promise<SpawnResult> {\n try {\n // SDK-P1-05: validate childName\n if (childName !== undefined) {\n if (typeof childName !== 'string' || childName.trim().length === 0) {\n throw new ValidationError('childName must be a non-empty string');\n }\n if (childName.length > 64) {\n throw new ValidationError('childName must be 64 characters or fewer');\n }\n }\n\n const res = await this.api('POST', '/api/v1/agent/spawn', {\n child_name: childName,\n child_hash: childHash,\n });\n\n if (res.eligible === false) {\n this.log(`Gestation incomplete: ${res.progress_pct}% (need ${res.deficit} more beats)`);\n } else if (res.ok) {\n this.log(`Child spawned: ${res.child_hash?.slice(0, 16)}...`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached lineage proof from the most recent heartbeat or SIGIL purchase */\n private cachedProof: LineageProof | null = null;\n\n /**\n * Purchase a SIGIL (cryptographic identity) for this agent.\n * SIGILs gate heartbeating, lineage proofs, and offline verification.\n * One-time purchase — cannot be re-purchased.\n *\n * @param options - SIGIL purchase options (identity_class, principal, tier, name, payment_tx, + optional metadata)\n *\n * Legacy signature (deprecated):\n * @param identityClass - 'narrow_task' | 'autonomous' | 'orchestrator'\n * @param paymentTx - Solana transaction signature or 'devnet-skip'\n */\n async purchaseSigil(optionsOrClass: SigilPurchaseOptions | IdentityClass, paymentTx?: string): Promise<SigilResult> {\n let body: Record<string, unknown>;\n\n if (typeof optionsOrClass === 'string') {\n // Legacy signature: purchaseSigil(identityClass, paymentTx)\n if (!optionsOrClass || !['narrow_task', 'autonomous', 'orchestrator'].includes(optionsOrClass)) {\n throw new ValidationError('identityClass must be narrow_task, autonomous, or orchestrator');\n }\n if (!paymentTx || typeof paymentTx !== 'string') {\n throw new ValidationError('paymentTx is required (Solana transaction signature or \"devnet-skip\")');\n }\n body = {\n identity_class: optionsOrClass,\n payment_tx: paymentTx,\n // Legacy calls without principal/tier — server will require these now\n // Callers must migrate to the options object form\n };\n } else {\n // New signature: purchaseSigil(options)\n const opts = optionsOrClass;\n if (!opts.identity_class || !['narrow_task', 'autonomous', 'orchestrator'].includes(opts.identity_class)) {\n throw new ValidationError('identity_class must be narrow_task, autonomous, or orchestrator');\n }\n if (!opts.principal || typeof opts.principal !== 'string') {\n throw new ValidationError('principal is required');\n }\n if (!opts.tier || !['sov', 'org', 'ind', 'eph', 'sbx'].includes(opts.tier)) {\n throw new ValidationError('tier must be one of: sov, org, ind, eph, sbx');\n }\n if (!opts.payment_tx || typeof opts.payment_tx !== 'string') {\n throw new ValidationError('payment_tx is required');\n }\n\n body = { ...opts };\n }\n\n try {\n const res = await this.api('POST', '/api/v1/sigil', body);\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.log(`SIGIL purchased: ${sigilStr}`);\n this.config.onStatusChange('sigil_issued', { sigil: sigilStr });\n\n return {\n ok: true,\n sigil: res.sigil,\n lineage_proof: res.lineage_proof,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'purchaseSigil');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Update mutable SIGIL metadata fields.\n * Requires a SIGIL. Cannot modify immutable fields.\n *\n * @param fields - Subset of mutable SIGIL fields to update\n */\n async updateMetadata(fields: Partial<SigilMutableFields>): Promise<MetadataUpdateResult> {\n if (!fields || Object.keys(fields).length === 0) {\n throw new ValidationError('At least one metadata field is required');\n }\n\n try {\n const res = await this.api('PATCH', '/api/v1/agent/metadata', fields);\n this.log(`Metadata updated: ${res.updated_fields?.join(', ') || 'unknown'}`);\n return {\n ok: true,\n sigil: res.sigil,\n generation: res.generation,\n updated_fields: res.updated_fields,\n };\n } catch (err: any) {\n this.config.onError(err, 'updateMetadata');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Send a paid heartbeat to the registry.\n * Requires a SIGIL. Returns a signed lineage proof.\n * This is the Phase 2 replacement for pulse() + checkin().\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx?: string, globalAnchor?: number): Promise<HeartbeatResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/heartbeat', {\n payment_tx: paymentTx || 'devnet-skip',\n global_anchor: globalAnchor,\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n if (res.ok) {\n this.status = 'active';\n const onHb = this.config.onHeartbeat || this.config.onCheckin;\n if (onHb) onHb(res);\n this.log(`Heartbeat accepted: epoch=${res.billing_epoch}, count=${res.heartbeat_count_epoch}`);\n }\n\n return {\n ok: res.ok,\n lineage_proof: res.lineage_proof,\n heartbeat_count_epoch: res.heartbeat_count_epoch,\n billing_epoch: res.billing_epoch,\n current_beat: res.current_beat,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a lineage proof. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n */\n async reissueProof(paymentTx?: string): Promise<{ ok: boolean; lineage_proof?: LineageProof; error?: string }> {\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx || 'devnet-skip',\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n return { ok: true, lineage_proof: res.lineage_proof };\n } catch (err: any) {\n this.config.onError(err, 'reissueProof');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached lineage proof (no network call).\n * Returns null if no proof has been obtained yet.\n */\n getLatestProof(): LineageProof | null {\n return this.cachedProof;\n }\n\n /**\n * Get the agent's passport (alias for getLatestProof).\n * The passport is the agent's portable, offline-verifiable credential.\n * Returns null if no passport has been issued yet (requires SIGIL + heartbeat).\n */\n getPassport(): Passport | null {\n return this.cachedProof;\n }\n\n /**\n * Verify a lineage proof locally using the authority public key.\n * Offline verification — no API call, no SOL cost.\n *\n * Returns a VerificationResult object. The object is truthy when valid,\n * so `if (BeatAgent.verifyProofLocally(proof, key))` still works.\n *\n * @param proof - The LineageProof to verify\n * @param authorityPubKeyHex - 32-byte hex-encoded Ed25519 public key from /.well-known/provenonce-authority.json\n * @param currentBeat - Optional current global beat index (for beatsSinceHeartbeat calculation)\n */\n static verifyProofLocally(proof: LineageProof, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n const now = Date.now();\n const expired = now > proof.valid_until;\n\n let signatureValid = false;\n try {\n // Canonical JSON (must match server's canonicalProofData)\n const canonical = JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n identity_class: proof.identity_class,\n registered_at_beat: proof.registered_at_beat,\n sigil_issued_at_beat: proof.sigil_issued_at_beat,\n last_heartbeat_beat: proof.last_heartbeat_beat,\n lineage_chain_hash: proof.lineage_chain_hash,\n issued_at: proof.issued_at,\n valid_until: proof.valid_until,\n });\n\n // Build Ed25519 public key from hex\n const pubBytes = Buffer.from(authorityPubKeyHex, 'hex');\n if (pubBytes.length === 32) {\n const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');\n const pubKeyDer = Buffer.concat([ED25519_SPKI_PREFIX, pubBytes]);\n const keyObject = createPublicKey({ key: pubKeyDer, format: 'der', type: 'spki' });\n const sigBuffer = Buffer.from(proof.provenonce_signature, 'hex');\n signatureValid = verify(null, Buffer.from(canonical), keyObject, sigBuffer);\n }\n } catch {\n signatureValid = false;\n }\n\n const valid = signatureValid && !expired;\n const beatsSinceHeartbeat = currentBeat != null ? currentBeat - proof.last_heartbeat_beat : null;\n\n let warning: string | undefined;\n if (expired) {\n warning = 'Proof has expired. Reissue with reissueProof() or send a heartbeat.';\n } else if (beatsSinceHeartbeat != null && beatsSinceHeartbeat > 60) {\n warning = `Agent is ${beatsSinceHeartbeat} beats behind. Heartbeat may be stale.`;\n }\n\n return { valid, signatureValid, expired, lastHeartbeatBeat: proof.last_heartbeat_beat, beatsSinceHeartbeat, warning };\n }\n\n // ── STATUS ──\n\n /**\n * Get this agent's full beat status from the registry.\n */\n async getStatus(): Promise<AgentStatus> {\n try {\n // We need the agent hash, but we may not have it directly.\n // The status endpoint uses the hash from the API key verification.\n // For now, use the init endpoint which returns status.\n return await this.refreshState();\n } catch (err: any) {\n this.config.onError(err, 'status');\n throw err;\n }\n }\n\n /**\n * Get local state (no network call).\n */\n getLocalState(): {\n status: string;\n totalBeats: number;\n latestBeat: number;\n latestHash: string;\n difficulty: number;\n globalBeat: number;\n chainLength: number;\n } {\n return {\n status: this.status,\n totalBeats: this.totalBeats,\n latestBeat: this.latestBeat?.index || 0,\n latestHash: this.latestBeat?.hash.slice(0, 24) + '...' || '',\n difficulty: this.difficulty,\n globalBeat: this.globalBeat,\n chainLength: this.chain.length,\n };\n }\n\n // ── INTERNALS ──\n\n private async syncGlobal(): Promise<void> {\n try {\n // SDK-P1-01: add timeout to syncGlobal fetch\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15_000);\n const res = await fetch(`${this.config.registryUrl}/api/v1/beat/anchor`, { signal: controller.signal });\n clearTimeout(timeout);\n const data: any = await res.json();\n if (data.anchor) {\n this.globalBeat = data.anchor.beat_index;\n this.globalAnchorHash = data.anchor.hash || '';\n if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;\n this.log(`Synced to global beat ${this.globalBeat} (D=${this.difficulty})`);\n }\n } catch {\n this.log('Failed to sync global anchor (offline mode continues)');\n }\n }\n\n private async refreshState(): Promise<any> {\n const res = await this.api('POST', '/api/v1/agent/init');\n if (res.already_initialized) {\n this.totalBeats = res.total_beats;\n this.genesisHash = res.genesis_hash;\n this.status = res.status as any;\n this.difficulty = res.difficulty || this.difficulty;\n this.lastCheckinBeat = res.last_checkin_beat || 0;\n\n // Restore latestBeat so pulse() can continue the chain\n if (!this.latestBeat && this.genesisHash) {\n this.latestBeat = {\n index: res.latest_beat || this.totalBeats,\n hash: res.latest_hash || this.genesisHash,\n prev: '0'.repeat(64),\n timestamp: Date.now(),\n };\n this.chain = [this.latestBeat];\n }\n }\n return res;\n }\n\n private async api(method: string, path: string, body?: any): Promise<any> {\n // SDK-P1-01: add 30s timeout to prevent indefinite hangs\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n try {\n const res = await fetch(`${this.config.registryUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n throw new NetworkError(`API error: ${res.status} non-JSON response from ${path}`);\n }\n\n if (!res.ok && !data.ok && !data.already_initialized && !data.eligible) {\n throw mapApiError(res.status, data, path);\n }\n\n return data;\n } catch (err: any) {\n if (err.name === 'AbortError') {\n throw new NetworkError(`Request timeout: ${method} ${path}`, ErrorCode.TIMEOUT);\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private log(msg: string): void {\n if (this.config.verbose) {\n console.log(`[Beat] ${msg}`);\n }\n }\n}\n\n// ============ STANDALONE VDF HELPER ============\n// For agents that want to compute beats without the full SDK\n\nexport { computeBeat };\n\n/**\n * Compute N sequential VDF beats.\n * Returns only the last beat (for lightweight usage).\n */\nexport function computeBeatsLite(\n startHash: string,\n startIndex: number,\n count: number,\n difficulty: number = 1000,\n anchorHash?: string,\n): { lastBeat: Beat; elapsed: number } {\n // SDK-P2: validate inputs\n if (!startHash || typeof startHash !== 'string') {\n throw new ValidationError('computeBeatsLite: startHash must be a non-empty string');\n }\n if (!Number.isInteger(count) || count < 1) {\n throw new ValidationError('computeBeatsLite: count must be a positive integer');\n }\n\n const t0 = Date.now();\n let prev = startHash;\n let lastBeat: Beat | null = null;\n\n for (let i = 0; i < count; i++) {\n lastBeat = computeBeat(prev, startIndex + i, difficulty, undefined, anchorHash);\n prev = lastBeat.hash;\n }\n\n return { lastBeat: lastBeat!, elapsed: Date.now() - t0 };\n}\n","/**\n * Provenonce SDK Error Classes\n *\n * Typed error hierarchy for programmatic error handling.\n * All errors extend ProvenonceError for catch-all, or catch specific\n * subclasses for fine-grained control:\n *\n * try {\n * await agent.checkin();\n * } catch (err) {\n * if (err instanceof RateLimitError) {\n * await sleep(err.retryAfterMs);\n * } else if (err instanceof FrozenError) {\n * await agent.resync();\n * } else if (err instanceof AuthError) {\n * console.error('Bad API key');\n * }\n * }\n */\n\n/** Error codes for programmatic switching */\nexport enum ErrorCode {\n // Validation\n VALIDATION = 'VALIDATION',\n\n // Auth\n AUTH_INVALID = 'AUTH_INVALID',\n AUTH_MISSING = 'AUTH_MISSING',\n\n // Rate limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // Agent state\n AGENT_FROZEN = 'AGENT_FROZEN',\n AGENT_NOT_INITIALIZED = 'AGENT_NOT_INITIALIZED',\n AGENT_WRONG_STATE = 'AGENT_WRONG_STATE',\n\n // Not found\n NOT_FOUND = 'NOT_FOUND',\n\n // Network / server\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n SERVER_ERROR = 'SERVER_ERROR',\n}\n\n/** Base error class for all Provenonce SDK errors */\nexport class ProvenonceError extends Error {\n /** Machine-readable error code */\n readonly code: ErrorCode;\n\n /** HTTP status code (if from an API response) */\n readonly statusCode?: number;\n\n /** Additional context */\n readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ErrorCode,\n statusCode?: number,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ProvenonceError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n // Fix prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when input validation fails (bad config, invalid args) */\nexport class ValidationError extends ProvenonceError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, ErrorCode.VALIDATION, undefined, details);\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown on 401/403 — bad or missing API key */\nexport class AuthError extends ProvenonceError {\n constructor(\n message: string,\n code: ErrorCode.AUTH_INVALID | ErrorCode.AUTH_MISSING = ErrorCode.AUTH_INVALID,\n statusCode?: number,\n ) {\n super(message, code, statusCode);\n this.name = 'AuthError';\n }\n}\n\n/** Thrown on 429 — rate limit exceeded */\nexport class RateLimitError extends ProvenonceError {\n /** Milliseconds until the rate limit resets (if provided by server) */\n readonly retryAfterMs?: number;\n\n constructor(message: string, statusCode: number = 429, retryAfterMs?: number) {\n super(message, ErrorCode.RATE_LIMITED, statusCode);\n this.name = 'RateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** Thrown when an agent is frozen and cannot perform the requested action */\nexport class FrozenError extends ProvenonceError {\n constructor(message: string = 'Agent is frozen. Use resync() to re-establish provenance.') {\n super(message, ErrorCode.AGENT_FROZEN);\n this.name = 'FrozenError';\n }\n}\n\n/** Thrown when the agent is in the wrong state for the requested action */\nexport class StateError extends ProvenonceError {\n /** The agent's current state */\n readonly currentState: string;\n\n constructor(message: string, currentState: string, code: ErrorCode = ErrorCode.AGENT_WRONG_STATE) {\n super(message, code);\n this.name = 'StateError';\n this.currentState = currentState;\n }\n}\n\n/** Thrown on 404 — agent or resource not found */\nexport class NotFoundError extends ProvenonceError {\n constructor(message: string, statusCode: number = 404) {\n super(message, ErrorCode.NOT_FOUND, statusCode);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown on network failures — non-JSON responses, fetch errors, timeouts */\nexport class NetworkError extends ProvenonceError {\n constructor(message: string, code: ErrorCode.NETWORK_ERROR | ErrorCode.TIMEOUT = ErrorCode.NETWORK_ERROR) {\n super(message, code);\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown on 5xx — unexpected server errors */\nexport class ServerError extends ProvenonceError {\n constructor(message: string, statusCode: number = 500) {\n super(message, ErrorCode.SERVER_ERROR, statusCode);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Map an HTTP response + parsed body to the appropriate error class.\n * Used internally by the SDK to convert API failures to typed errors.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n\n if (statusCode === 401 || statusCode === 403) {\n const code = statusCode === 401 ? ErrorCode.AUTH_MISSING : ErrorCode.AUTH_INVALID;\n return new AuthError(msg, code, statusCode);\n }\n\n if (statusCode === 429) {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n\n if (statusCode === 404) {\n return new NotFoundError(msg, statusCode);\n }\n\n if (statusCode >= 500) {\n return new ServerError(msg, statusCode);\n }\n\n // Check for specific error patterns in the message\n const lowerMsg = msg.toLowerCase();\n if (lowerMsg.includes('frozen')) {\n return new FrozenError(msg);\n }\n\n // Generic client error\n return new ProvenonceError(msg, ErrorCode.SERVER_ERROR, statusCode);\n}\n"],"mappings":"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","names":["ErrorCode","res","data"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/beat-sdk.ts","../src/errors.ts"],"sourcesContent":["export { BeatAgent, computeBeat, computeBeatsLite, register, generateWalletKeypair, verifyAnchorHash } from './beat-sdk';\nexport type {\n BeatAgentConfig,\n Beat,\n CheckinResult,\n SpawnResult,\n AgentStatus,\n RegisterOptions,\n RegistrationResult,\n WalletInfo,\n // Phase 2 types\n IdentityClass,\n LineageProof,\n Passport,\n SigilResult,\n HeartbeatResult,\n // SIGIL Namespace v0.4 types\n SigilTier,\n Substrate,\n SubstrateProvider,\n Capability,\n SigilProtocol,\n ComplianceRegime,\n SigilPurchaseOptions,\n SigilMutableFields,\n MetadataUpdateResult,\n VerificationResult,\n} from './beat-sdk';\n\nexport {\n ProvenonceError,\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NotFoundError,\n NetworkError,\n ServerError,\n ErrorCode,\n} from './errors';\n","/**\n * ═══════════════════════════════════════════════════════════\n * PROVENONCE BEAT SDK — Agent Heartbeat Client\n * ═══════════════════════════════════════════════════════════\n * \n * \"NIST tells you what time it is.\n * Provenonce tells the agent at what speed it is allowed to exist.\"\n * \n * Usage:\n * \n * import { BeatAgent } from './beat-sdk';\n * \n * const agent = new BeatAgent({\n * apiKey: 'pvn_...',\n * registryUrl: 'https://provenonce.io',\n * });\n * \n * await agent.init(); // Birth in Beat time\n * await agent.pulse(50); // Compute 50 beats\n * await agent.checkin(); // Report to registry\n * \n * // Or run the autonomous heartbeat:\n * agent.startHeartbeat(); // Computes + checks in continuously\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, generateKeyPairSync, sign, verify, createPrivateKey, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n mapApiError,\n ErrorCode,\n} from './errors';\n\n// ============ PHASE 2 TYPES ============\n\n/** SIGIL identity class — determines tier pricing and heartbeat volume caps */\nexport type IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator';\n\n/** SIGIL trust governance tier — orthogonal to identity_class (fee axis) */\nexport type SigilTier = 'sov' | 'org' | 'ind' | 'eph' | 'sbx';\n\n/** Substrate — what the agent runs on */\nexport type Substrate = 'frontier' | 'open' | 'local' | 'symbolic' | 'hybrid' | 'human';\n\n/** Substrate provider */\nexport type SubstrateProvider = 'anthropic' | 'openai' | 'google' | 'meta' | 'mistral' | 'xai' | 'cohere' | 'deepseek' | 'custom';\n\n/** Capability — what the agent primarily does */\nexport type Capability = 'analyst' | 'executor' | 'orchestrator' | 'guardian' | 'retriever' | 'renderer' | 'witness';\n\n/** Protocol — how to reach the agent */\nexport type SigilProtocol = 'http' | 'grpc' | 'websocket' | 'mcp' | 'a2a' | 'custom';\n\n/** Compliance regime */\nexport type ComplianceRegime = 'gdpr' | 'pdpa' | 'hipaa' | 'sox' | 'aisi' | 'none' | 'custom';\n\n/**\n * Ed25519-signed lineage proof — portable, offline-verifiable credential.\n * Also known as the agent's \"passport\" — a cryptographic proof of identity\n * that can be verified offline without any API call or SOL cost.\n */\nexport interface LineageProof {\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n issued_at: number;\n valid_until: number;\n provenonce_signature: string;\n}\n\n/** Passport = LineageProof. The agent's portable, offline-verifiable credential. */\nexport type Passport = LineageProof;\n\n/** Options for purchasing a SIGIL with full namespace */\nexport interface SigilPurchaseOptions {\n identity_class: IdentityClass;\n principal: string;\n tier: SigilTier;\n name?: string; // \"auto\" or custom name\n payment_tx: string;\n // Optional initial metadata\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Mutable SIGIL metadata fields for PATCH updates */\nexport interface SigilMutableFields {\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n generation_trigger?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Result from purchasing a SIGIL (Structured Identity Governance and Intelligent Lookup) */\nexport interface SigilResult {\n ok: boolean;\n sigil?: {\n sigil: string; // Full SIGIL string: name*principal*tier\n sigil_name: string;\n principal: string;\n tier: SigilTier;\n identity_class: IdentityClass;\n issued_at_beat: number;\n birth_tx: string | null;\n explorer_url: string | null;\n };\n lineage_proof?: LineageProof;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n/** Result from updating mutable SIGIL metadata */\nexport interface MetadataUpdateResult {\n ok: boolean;\n sigil?: string;\n generation?: number;\n updated_fields?: string[];\n error?: string;\n}\n\n/** Result from offline lineage proof verification */\nexport interface VerificationResult {\n /** Overall validity: signature is valid AND not expired */\n valid: boolean;\n /** Ed25519 signature verification passed */\n signatureValid: boolean;\n /** Proof has passed its valid_until timestamp */\n expired: boolean;\n /** The beat index of the agent's last heartbeat */\n lastHeartbeatBeat: number;\n /** Beats elapsed since last heartbeat (null if currentBeat not provided) */\n beatsSinceHeartbeat: number | null;\n /** Human-readable warning if proof is expired or stale */\n warning?: string;\n}\n\n/** Result from a paid heartbeat */\nexport interface HeartbeatResult {\n ok: boolean;\n lineage_proof?: LineageProof;\n heartbeat_count_epoch?: number;\n billing_epoch?: number;\n current_beat?: number;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n tier: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n// ============ VDF ENGINE (LOCAL) ============\n\nexport interface Beat {\n index: number;\n hash: string;\n prev: string;\n timestamp: number;\n nonce?: string;\n anchor_hash?: string;\n}\n\nfunction computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat {\n const timestamp = Date.now();\n\n const seed = anchorHash\n ? `${prevHash}:${beatIndex}:${nonce || ''}:${anchorHash}`\n : `${prevHash}:${beatIndex}:${nonce || ''}`;\n\n let current = createHash('sha256')\n .update(seed)\n .digest('hex');\n\n for (let i = 0; i < difficulty; i++) {\n current = createHash('sha256')\n .update(current)\n .digest('hex');\n }\n\n return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };\n}\n\n// ============ V3 ANCHOR HASH VERIFICATION ============\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\nfunction base58DecodeToBuffer(str: string): Buffer {\n const map: Record<string, number> = {};\n for (let i = 0; i < BASE58_ALPHABET.length; i++) map[BASE58_ALPHABET[i]] = i;\n let bytes = [0];\n for (let i = 0; i < str.length; i++) {\n const val = map[str[i]];\n if (val === undefined) throw new Error('invalid base58 character');\n let carry = val;\n for (let j = 0; j < bytes.length; j++) {\n const x = bytes[j] * 58 + carry;\n bytes[j] = x & 0xff;\n carry = x >> 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n for (let i = 0; i < str.length && str[i] === '1'; i++) bytes.push(0);\n return Buffer.from(bytes.reverse());\n}\n\nfunction u64be(n: number): Buffer {\n const buf = Buffer.alloc(8);\n buf.writeUInt32BE(Math.floor(n / 0x100000000), 0);\n buf.writeUInt32BE(n >>> 0, 4);\n return buf;\n}\n\nconst ANCHOR_DOMAIN_PREFIX = 'PROVENONCE_BEATS_V1';\n\n/**\n * Verify an anchor hash locally.\n * V3 (solana_entropy present): binary-canonical single SHA-256.\n * V1 legacy (no entropy): string-based hash with difficulty iteration.\n */\nexport function verifyAnchorHash(anchor: { prev_hash: string; beat_index: number; hash: string; utc: number; epoch: number; difficulty: number; solana_entropy?: string }): boolean {\n if (!anchor || !anchor.hash || !anchor.prev_hash) return false;\n\n if (anchor.solana_entropy) {\n // V3: binary-canonical single SHA-256\n const prefix = Buffer.from(ANCHOR_DOMAIN_PREFIX, 'utf8');\n const prev = Buffer.from(anchor.prev_hash, 'hex');\n const idx = u64be(anchor.beat_index);\n const entropy = base58DecodeToBuffer(anchor.solana_entropy);\n const preimage = Buffer.concat([prefix, prev, idx, entropy]);\n const computed = createHash('sha256').update(preimage).digest('hex');\n return computed === anchor.hash;\n }\n\n // V1 legacy: string-based hash with difficulty iteration\n const nonce = `anchor:${anchor.utc}:${anchor.epoch}`;\n const seed = `${anchor.prev_hash}:${anchor.beat_index}:${nonce}`;\n let current = createHash('sha256').update(seed).digest('hex');\n for (let i = 0; i < anchor.difficulty; i++) {\n current = createHash('sha256').update(current).digest('hex');\n }\n return current === anchor.hash;\n}\n\n// ============ SDK RESULT TYPES ============\n\n/** Result from a check-in submission */\nexport interface CheckinResult {\n ok: boolean;\n total_beats: number;\n beats_accepted: number;\n global_beat: number;\n status?: string;\n beats_behind?: number;\n}\n\n/** Result from a spawn request */\nexport interface SpawnResult {\n ok: boolean;\n eligible: boolean;\n child_hash?: string;\n progress_pct?: number;\n deficit?: number;\n}\n\n/** Agent status from the registry */\nexport interface AgentStatus {\n already_initialized: boolean;\n total_beats: number;\n genesis_hash: string;\n status: string;\n genesis?: { hash: string; prev: string; timestamp: number };\n difficulty?: number;\n}\n\n// ============ WALLET KEYPAIR GENERATION ============\n\n// DER prefix for Ed25519 PKCS8 private keys (16 bytes)\nconst ED25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b657004220420', 'hex');\n\n/**\n * Generate an Ed25519 keypair for agent wallet identity.\n * Returns hex-encoded raw keys (32 bytes each).\n * Uses Node.js built-in crypto — zero external dependencies.\n */\nexport function generateWalletKeypair(): { publicKey: string; secretKey: string } {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519');\n const pubRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(12); // 32 bytes\n const privRaw = privateKey.export({ type: 'pkcs8', format: 'der' }).subarray(16); // 32 bytes\n return {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: Buffer.from(privRaw).toString('hex'),\n };\n}\n\n/**\n * Sign a message with an Ed25519 private key (hex-encoded 32-byte seed).\n * Returns hex-encoded signature (64 bytes).\n */\nfunction signMessage(secretKeyHex: string, message: string): string {\n const privRaw = Buffer.from(secretKeyHex, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const sig = sign(null, Buffer.from(message), keyObject);\n return Buffer.from(sig).toString('hex');\n}\n\n// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\n /** Hex-encoded 32-byte Ed25519 public key (Solana self-custody only, empty otherwise) */\n public_key: string;\n /** Hex-encoded 32-byte Ed25519 secret seed — SAVE THIS for future fee signing (Solana self-custody only) */\n secret_key: string;\n /** Solana-compatible base58 address (Solana wallets only) */\n solana_address?: string;\n /** The wallet address (base58 for Solana, 0x for Ethereum) */\n address: string;\n /** Wallet chain: 'solana' or 'ethereum' */\n chain: string;\n}\n\n/** Result from registering an agent */\nexport interface RegistrationResult {\n hash: string;\n api_key: string;\n secret: string;\n type: 'root' | 'agent';\n parent: string | null;\n depth: number;\n name: string;\n metadata?: Record<string, unknown> | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n signature?: string | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n explorer_url?: string | null;\n /** Wallet chain: 'solana', 'ethereum', or null (no wallet) */\n wallet_chain?: string | null;\n beat?: { genesis_hash: string; difficulty: number; status: string };\n /** Wallet info — only present for root agents with wallets */\n wallet?: WalletInfo;\n /** Next steps after registration */\n _next_steps?: { sigil?: string; heartbeat?: string };\n}\n\n/** Options for the register() function */\nexport interface RegisterOptions {\n registryUrl?: string;\n parentHash?: string;\n parentApiKey?: string;\n registrationSecret?: string;\n /** Single-use registration token from POST /register/token or POST /register/email/verify */\n registrationToken?: string;\n /** Admin-minted invite token */\n registrationInvite?: string;\n /** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */\n walletSecretKey?: string;\n /** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: 'self-custody' | 'operator';\n /** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */\n walletChain?: 'solana' | 'ethereum';\n /** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */\n walletAddress?: string;\n /** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */\n walletSignFn?: (message: string) => Promise<string>;\n /** Operator's Solana wallet address (base58). Required when walletModel='operator'. */\n operatorWalletAddress?: string;\n /** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */\n operatorSignFn?: (message: string) => Promise<string>;\n /** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Register a new agent on the Provenonce registry.\n *\n * With registration token (from /register/token or email verification):\n * const creds = await register('my-agent', {\n * registryUrl: '...',\n * registrationToken: '<token-from-email-verify>',\n * });\n *\n * No wallet (default, single-phase):\n * const creds = await register('my-agent', { registryUrl: '...' });\n *\n * Solana self-custody wallet (Model A, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'self-custody',\n * });\n * // creds.wallet.secret_key = hex secret (SAVE THIS)\n * // creds.wallet.address = base58 Solana address\n *\n * Solana with existing key:\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletSecretKey: '<hex-encoded-32-byte-seed>',\n * });\n *\n * Ethereum bring-your-own (two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletChain: 'ethereum',\n * walletAddress: '0x...',\n * walletSignFn: (msg) => wallet.signMessage(msg),\n * });\n *\n * Solana operator (Model B, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'operator',\n * operatorWalletAddress: '<base58>',\n * operatorSignFn: (msg) => signWithWallet(msg),\n * });\n *\n * Child agent (no wallet):\n * const creds = await register('worker-1', {\n * registryUrl: '...',\n * parentHash: parentCreds.hash,\n * parentApiKey: parentCreds.api_key,\n * });\n */\nexport async function register(\n name: string,\n options?: RegisterOptions,\n): Promise<RegistrationResult> {\n // SDK-P1-07/P1-08: validate inputs\n if (!name || typeof name !== 'string' || name.trim().length === 0) {\n throw new ValidationError('name is required (must be a non-empty string)');\n }\n if (name.length > 64) {\n throw new ValidationError('name must be 64 characters or fewer');\n }\n\n const url = options?.registryUrl || 'https://provenonce.io';\n try {\n new URL(url);\n } catch {\n throw new ValidationError('registryUrl is not a valid URL');\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\n if (options?.registrationSecret) {\n headers['x-registration-secret'] = options.registrationSecret;\n }\n if (options?.registrationToken) {\n headers['x-registration-token'] = options.registrationToken;\n }\n if (options?.registrationInvite) {\n headers['x-registration-invite'] = options.registrationInvite;\n }\n\n // ===== CHILD REGISTRATION (no wallet, single-phase) =====\n if (options?.parentHash) {\n if (options.parentApiKey) {\n headers['Authorization'] = `Bearer ${options.parentApiKey}`;\n }\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, parent: options.parentHash, ...(options.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n }\n\n // ===== ETHEREUM BRING-YOUR-OWN (D-63, two-phase) =====\n if (options?.walletChain === 'ethereum') {\n if (!options.walletAddress || !options.walletSignFn) {\n throw new ValidationError('Ethereum registration requires walletAddress and walletSignFn');\n }\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(options.walletAddress)) {\n throw new ValidationError('walletAddress must be a valid Ethereum address (0x + 40 hex chars)');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_chain: 'ethereum' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Sign with Ethereum wallet (EIP-191 personal_sign)\n const nonce = challengeData.nonce;\n const message = `provenonce-register-ethereum:${nonce}:${options.walletAddress}:${name}`;\n const walletSignature = await options.walletSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_chain: 'ethereum',\n wallet_address: options.walletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n } catch {\n throw new NetworkError(`Ethereum registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Ethereum: wallet has address only (no keypair — user keeps custody externally)\n data.wallet = {\n public_key: '',\n secret_key: '',\n address: data.wallet?.address || options.walletAddress,\n chain: 'ethereum',\n };\n\n return data;\n }\n\n // ===== MODEL B: SOLANA OPERATOR WALLET REGISTRATION (two-phase) =====\n if (options?.walletModel === 'operator') {\n if (!options.operatorWalletAddress || !options.operatorSignFn) {\n throw new ValidationError('Operator registration requires operatorWalletAddress and operatorSignFn');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_model: 'operator' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Operator signs challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register-operator:${nonce}:${options.operatorWalletAddress}:${name}`;\n const walletSignature = await options.operatorSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_model: 'operator',\n operator_wallet_address: options.operatorWalletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n throw new NetworkError(`Operator registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Model B: wallet has address only (no secret_key/public_key — operator keeps custody)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\n public_key: '',\n secret_key: '',\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== MODEL A: SOLANA SELF-CUSTODY WALLET REGISTRATION (opt-in, two-phase) =====\n if (options?.walletModel === 'self-custody' || options?.walletSecretKey) {\n // Generate or use provided wallet keypair\n let walletKeys: { publicKey: string; secretKey: string };\n if (options?.walletSecretKey) {\n // Derive public key from provided secret\n const privRaw = Buffer.from(options.walletSecretKey, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const pubRaw = keyObject.export({ type: 'spki', format: 'der' }).subarray(12);\n walletKeys = {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: options.walletSecretKey,\n };\n } else {\n walletKeys = generateWalletKeypair();\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n const err = new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n // Attach wallet keys so caller can retry with the same keypair\n const err = mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Phase 2: Sign challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register:${nonce}:${walletKeys.publicKey}:${name}`;\n const walletSignature = signMessage(walletKeys.secretKey, message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_public_key: walletKeys.publicKey,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options?.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n // Attach wallet keys so caller can retry with the same keypair\n const err = new NetworkError(`Registration failed: ${registerRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!registerRes.ok) {\n // Attach wallet keys so caller can retry with the same keypair via walletSecretKey option\n const err = mapApiError(registerRes.status, data, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Attach the wallet keys (secret is client-side only, never sent to server)\n const addr = data.wallet?.address || data.wallet?.solana_address || '';\n data.wallet = {\n public_key: walletKeys.publicKey,\n secret_key: walletKeys.secretKey,\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== NO-WALLET REGISTRATION (D-62 default, single-phase) =====\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, ...(options?.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n}\n\n// ============ SDK CONFIG ============\n\nexport interface BeatAgentConfig {\n /** API key from registration (pvn_...) */\n apiKey: string;\n\n /** Provenonce registry URL */\n registryUrl: string;\n\n /** @deprecated Use heartbeatIntervalSec. Beats to compute per pulse (default: 10) */\n beatsPerPulse?: number;\n\n /** @deprecated Use heartbeatIntervalSec. Seconds between automatic check-ins (default: 300 = 5min) */\n checkinIntervalSec?: number;\n\n /** Seconds between automatic heartbeats (default: 300 = 5min). Replaces checkinIntervalSec. */\n heartbeatIntervalSec?: number;\n\n /** @deprecated VDF pulse callback. No longer used in Phase 2. */\n onPulse?: (beats: Beat[], totalBeats: number) => void;\n\n /** @deprecated Use onHeartbeat. Callback when check-in completes. */\n onCheckin?: (result: CheckinResult) => void;\n\n /** Callback when heartbeat completes (Phase 2) */\n onHeartbeat?: (result: HeartbeatResult) => void;\n\n /** Callback on error */\n onError?: (error: Error, context: string) => void;\n\n /** Callback when status changes */\n onStatusChange?: (status: string, details: Record<string, unknown>) => void;\n\n /** Enable verbose logging */\n verbose?: boolean;\n\n /** Verify anchor hash locally before trusting it (default: true). */\n verifyAnchors?: boolean;\n}\n\n// ============ BEAT AGENT ============\n\nexport class BeatAgent {\n private config: Required<BeatAgentConfig>;\n private chain: Beat[] = [];\n private difficulty: number = 1000;\n private genesisHash: string = '';\n private latestBeat: Beat | null = null;\n private totalBeats: number = 0;\n private lastCheckinBeat: number = 0;\n private status: 'uninitialized' | 'active' | 'frozen' | 'revoked' = 'uninitialized';\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private globalBeat: number = 0;\n private globalAnchorHash: string = '';\n\n constructor(config: BeatAgentConfig) {\n // SDK-P1-08: validate required config fields\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new ValidationError('BeatAgentConfig.apiKey is required (must be a non-empty string)');\n }\n if (!config.registryUrl || typeof config.registryUrl !== 'string') {\n throw new ValidationError('BeatAgentConfig.registryUrl is required (must be a non-empty string)');\n }\n // SDK-P1-07: validate registryUrl is a valid URL\n try {\n new URL(config.registryUrl);\n } catch {\n throw new ValidationError('BeatAgentConfig.registryUrl is not a valid URL');\n }\n\n // SDK-P2: validate optional numeric config\n if (config.beatsPerPulse !== undefined && (!Number.isInteger(config.beatsPerPulse) || config.beatsPerPulse < 1 || config.beatsPerPulse > 10000)) {\n throw new ValidationError('BeatAgentConfig.beatsPerPulse must be an integer between 1 and 10000');\n }\n if (config.checkinIntervalSec !== undefined && (!Number.isFinite(config.checkinIntervalSec) || config.checkinIntervalSec < 10 || config.checkinIntervalSec > 86400)) {\n throw new ValidationError('BeatAgentConfig.checkinIntervalSec must be between 10 and 86400');\n }\n\n this.config = {\n beatsPerPulse: 10,\n checkinIntervalSec: 300,\n heartbeatIntervalSec: 300,\n onPulse: () => {},\n onCheckin: () => {},\n onHeartbeat: () => {},\n onError: () => {},\n onStatusChange: () => {},\n verbose: false,\n verifyAnchors: true,\n ...config,\n };\n }\n\n // ── INITIALIZATION ──\n\n /**\n * Initialize the agent's Beat chain.\n * This is the agent's \"birth\" in Logical Time.\n * Must be called once before computing beats.\n */\n async init(): Promise<{ ok: boolean; genesis?: string; error?: string }> {\n try {\n this.log('Initializing Beat chain...');\n\n const res = await this.api('POST', '/api/v1/agent/init');\n\n if (res.genesis) {\n this.genesisHash = res.genesis.hash;\n this.difficulty = res.difficulty || 1000;\n this.latestBeat = {\n index: 0,\n hash: res.genesis.hash,\n prev: res.genesis.prev,\n timestamp: res.genesis.timestamp,\n };\n this.chain = [this.latestBeat];\n this.totalBeats = 0;\n this.status = 'active';\n this.config.onStatusChange('active', { genesis: this.genesisHash });\n this.log(`Born in Beat time. Genesis: ${this.genesisHash.slice(0, 16)}...`);\n } else if (res.already_initialized) {\n // Restore from existing state\n this.genesisHash = res.genesis_hash;\n this.totalBeats = res.total_beats;\n this.status = res.status as any;\n this.log(`Already initialized. Restoring state (${res.total_beats} beats).`);\n \n // Fetch full state to get latest hash\n await this.refreshState();\n }\n\n // Sync global anchor\n await this.syncGlobal();\n\n return { ok: true, genesis: this.genesisHash };\n\n } catch (err: any) {\n this.config.onError(err, 'init');\n return { ok: false, error: err.message };\n }\n }\n\n // ── PULSE (COMPUTE BEATS) ──\n\n /**\n * @deprecated Phase 2: VDF computation retired (D-68). Payment is the liveness mechanism.\n * Use heartbeat() instead. This method will be removed in the next major version.\n *\n * Compute N beats locally (VDF hash chain).\n */\n pulse(count?: number): Beat[] {\n console.warn('[Provenonce SDK] pulse() is deprecated. Use heartbeat() instead (Phase 2).');\n if (this.status === 'frozen') {\n throw new FrozenError('Cannot pulse: agent is frozen. Use resync() to re-establish provenance.');\n }\n if (this.status !== 'active') {\n throw new StateError(`Cannot pulse: agent is ${this.status}.`, this.status);\n }\n // SDK-P2: validate count param\n if (count !== undefined && (!Number.isInteger(count) || count < 1 || count > 10000)) {\n throw new ValidationError('pulse count must be an integer between 1 and 10000');\n }\n return this.computeBeats(count);\n }\n\n /** Internal beat computation — no status check. Used by both pulse() and resync(). */\n private computeBeats(count?: number, onProgress?: (computed: number, total: number) => void): Beat[] {\n const n = count || this.config.beatsPerPulse;\n\n if (!this.latestBeat) {\n throw new StateError('Beat chain not initialized. Call init() first.', 'uninitialized', ErrorCode.AGENT_NOT_INITIALIZED);\n }\n\n const newBeats: Beat[] = [];\n let prevHash = this.latestBeat.hash;\n let startIndex = this.latestBeat.index + 1;\n\n const t0 = Date.now();\n // SDK-P2: report progress every 10% of beats\n const progressInterval = Math.max(1, Math.floor(n / 10));\n\n for (let i = 0; i < n; i++) {\n const beat = computeBeat(prevHash, startIndex + i, this.difficulty, undefined, this.globalAnchorHash || undefined);\n newBeats.push(beat);\n prevHash = beat.hash;\n if (onProgress && (i + 1) % progressInterval === 0) {\n onProgress(i + 1, n);\n }\n }\n\n const elapsed = Date.now() - t0;\n\n // Update state\n this.chain.push(...newBeats);\n this.latestBeat = newBeats[newBeats.length - 1];\n this.totalBeats += n;\n\n // Keep chain bounded (only last 1000 beats in memory)\n if (this.chain.length > 1000) {\n this.chain = this.chain.slice(-500);\n }\n\n this.config.onPulse(newBeats, this.totalBeats);\n this.log(`Pulse: ${n} beats in ${elapsed}ms (${(elapsed / n).toFixed(1)}ms/beat, D=${this.difficulty})`);\n\n return newBeats;\n }\n\n // ── CHECK-IN ──\n\n /**\n * @deprecated Phase 2: VDF check-in retired (D-68). Use heartbeat() instead.\n * This method will be removed in the next major version.\n */\n async checkin(): Promise<{ ok: boolean; total_beats?: number; error?: string }> {\n console.warn('[Provenonce SDK] checkin() is deprecated. Use heartbeat() instead (Phase 2).');\n // SDK-P1-02: fix guard to compare beat indices, not totalBeats vs lastCheckinBeat\n if (!this.latestBeat || this.latestBeat.index <= this.lastCheckinBeat) {\n this.log('No new beats since last check-in. Call pulse() first.');\n return { ok: true, total_beats: this.totalBeats }; // Nothing new to report\n }\n\n try {\n // Find the boundary hashes\n const fromBeat = this.lastCheckinBeat;\n const toBeat = this.latestBeat.index;\n\n // Build spot checks from our local chain\n // prev and nonce are required for the server to recompute VDF\n // Must always include to_beat (final beat) — server requires it for final hash verification\n const spotChecks: { index: number; hash: string; prev: string; nonce?: string }[] = [];\n\n // Always include the final beat\n const toBeatEntry = this.chain.find(b => b.index === toBeat);\n if (toBeatEntry) {\n spotChecks.push({ index: toBeatEntry.index, hash: toBeatEntry.hash, prev: toBeatEntry.prev, nonce: toBeatEntry.nonce });\n }\n\n // Sample up to 4 more from the rest\n const available = this.chain.filter(b => b.index > this.lastCheckinBeat && b.index !== toBeat);\n const sampleCount = Math.min(4, available.length);\n\n for (let i = 0; i < sampleCount; i++) {\n const idx = Math.floor(Math.random() * available.length);\n const beat = available[idx];\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev, nonce: beat.nonce });\n available.splice(idx, 1);\n }\n const fromHash = this.chain.find(b => b.index === fromBeat)?.hash \n || this.genesisHash;\n const toHash = this.latestBeat.hash;\n\n const res = await this.api('POST', '/api/v1/agent/checkin', {\n proof: {\n from_beat: fromBeat,\n to_beat: toBeat,\n from_hash: fromHash,\n to_hash: toHash,\n beats_computed: toBeat - fromBeat,\n global_anchor: this.globalBeat,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: spotChecks,\n },\n });\n\n if (res.ok) {\n this.lastCheckinBeat = toBeat;\n this.totalBeats = res.total_beats;\n this.config.onCheckin(res);\n this.log(`Check-in accepted: ${res.beats_accepted} beats, total=${res.total_beats}, global=${res.global_beat}`);\n \n if (res.status === 'warning_overdue') {\n this.config.onStatusChange('warning', { beats_behind: res.beats_behind });\n this.log(`⚠ WARNING: ${res.beats_behind} anchors behind. Check in more frequently.`);\n }\n }\n\n return { ok: res.ok, total_beats: res.total_beats };\n\n } catch (err: any) {\n this.config.onError(err, 'checkin');\n return { ok: false, error: err.message };\n }\n }\n\n // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Optional function that returns a payment tx for each heartbeat.\n * If not provided, uses 'devnet-skip' (devnet only).\n */\n startHeartbeat(paymentTxFn?: () => Promise<string> | string): void {\n if (this.heartbeatInterval) {\n this.log('Heartbeat already running.');\n return;\n }\n\n if (this.status !== 'active' && this.status !== 'uninitialized') {\n throw new StateError(`Cannot start heartbeat in status '${this.status}'.`, this.status);\n }\n\n const intervalSec = this.config.heartbeatIntervalSec || this.config.checkinIntervalSec || 300;\n this.log(`Starting heartbeat (interval: ${intervalSec}s)...`);\n\n // SDK-P1-03: exponential backoff on consecutive errors\n let consecutiveErrors = 0;\n let skipCount = 0;\n\n this.heartbeatInterval = setInterval(async () => {\n if (skipCount > 0) {\n skipCount--;\n return;\n }\n\n try {\n const paymentTx = paymentTxFn ? await paymentTxFn() : 'devnet-skip';\n await this.heartbeat(paymentTx);\n consecutiveErrors = 0;\n } catch (err: any) {\n consecutiveErrors++;\n this.config.onError(err, 'heartbeat');\n skipCount = Math.min(32, Math.pow(2, consecutiveErrors - 1));\n this.log(`Heartbeat error #${consecutiveErrors}, backing off ${skipCount} ticks`);\n }\n }, intervalSec * 1000);\n }\n\n /**\n * Stop the heartbeat loop.\n */\n stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n this.log('Heartbeat stopped.');\n }\n }\n\n // ── RE-SYNC ──\n\n /**\n * @deprecated Phase 2: Resync retired (D-67). Dormancy resume is free — just call heartbeat().\n * This method will be removed in the next major version.\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n console.warn('[Provenonce SDK] resync() is deprecated (D-67). Use heartbeat() to resume (Phase 2).');\n try {\n this.log('Requesting re-sync challenge...');\n\n // Phase 1: Get challenge\n const challenge = await this.api('POST', '/api/v1/agent/resync', {\n action: 'challenge',\n });\n\n if (!challenge.challenge) {\n return { ok: false, error: 'Failed to get challenge' };\n }\n\n const required = challenge.challenge.required_beats;\n this.difficulty = challenge.challenge.difficulty;\n this.log(`Re-sync challenge: compute ${required} beats at D=${this.difficulty}`);\n\n // Sync global anchor so beats are woven with a recent anchor hash\n await this.syncGlobal();\n\n // Compute the required beats\n const startHash = challenge.challenge.start_from_hash;\n const startBeat = challenge.challenge.start_from_beat;\n\n // Reset chain from the known point\n this.latestBeat = { index: startBeat, hash: startHash, prev: '', timestamp: Date.now() };\n this.chain = [this.latestBeat];\n\n const t0 = Date.now();\n this.computeBeats(required);\n const elapsed = Date.now() - t0;\n this.log(`Re-sync beats computed in ${elapsed}ms`);\n\n // Phase 2: Submit proof (include challenge_nonce for server verification)\n const proof = await this.api('POST', '/api/v1/agent/resync', {\n action: 'prove',\n challenge_nonce: challenge.challenge.nonce,\n proof: {\n from_beat: startBeat,\n to_beat: this.latestBeat!.index,\n from_hash: startHash,\n to_hash: this.latestBeat!.hash,\n beats_computed: required,\n global_anchor: challenge.challenge.sync_to_global,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: (() => {\n // Must include to_beat (final beat) — server requires it for final hash verification\n const toBeatEntry = this.chain.find(b => b.index === this.latestBeat!.index);\n // Sample from available chain beats (chain may be trimmed to 500 entries)\n const available = this.chain\n .filter(b => b.index !== this.latestBeat!.index && b.index > startBeat);\n const step = Math.max(1, Math.ceil(available.length / 5));\n const others = available\n .filter((_, i) => i % step === 0)\n .slice(0, 4);\n const checks = toBeatEntry ? [toBeatEntry, ...others] : others;\n return checks.map(b => ({ index: b.index, hash: b.hash, prev: b.prev, nonce: b.nonce }));\n })(),\n },\n });\n\n if (proof.ok) {\n this.status = 'active';\n this.totalBeats = proof.total_beats;\n this.lastCheckinBeat = this.latestBeat!.index;\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced. Agent is alive again in Beat time.');\n }\n\n return { ok: proof.ok, beats_required: required };\n\n } catch (err: any) {\n this.config.onError(err, 'resync');\n return { ok: false, error: err.message };\n }\n }\n\n // ── SPAWN ──\n\n /**\n * Request to spawn a child agent.\n * Requires sufficient accumulated beats (Temporal Gestation).\n */\n async requestSpawn(childName?: string, childHash?: string): Promise<SpawnResult> {\n try {\n // SDK-P1-05: validate childName\n if (childName !== undefined) {\n if (typeof childName !== 'string' || childName.trim().length === 0) {\n throw new ValidationError('childName must be a non-empty string');\n }\n if (childName.length > 64) {\n throw new ValidationError('childName must be 64 characters or fewer');\n }\n }\n\n const res = await this.api('POST', '/api/v1/agent/spawn', {\n child_name: childName,\n child_hash: childHash,\n });\n\n if (res.eligible === false) {\n this.log(`Gestation incomplete: ${res.progress_pct}% (need ${res.deficit} more beats)`);\n } else if (res.ok) {\n this.log(`Child spawned: ${res.child_hash?.slice(0, 16)}...`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached lineage proof from the most recent heartbeat or SIGIL purchase */\n private cachedProof: LineageProof | null = null;\n\n /**\n * Purchase a SIGIL (cryptographic identity) for this agent.\n * SIGILs gate heartbeating, lineage proofs, and offline verification.\n * One-time purchase — cannot be re-purchased.\n *\n * @param options - SIGIL purchase options (identity_class, principal, tier, name, payment_tx, + optional metadata)\n *\n * Legacy signature (deprecated):\n * @param identityClass - 'narrow_task' | 'autonomous' | 'orchestrator'\n * @param paymentTx - Solana transaction signature or 'devnet-skip'\n */\n async purchaseSigil(optionsOrClass: SigilPurchaseOptions | IdentityClass, paymentTx?: string): Promise<SigilResult> {\n let body: Record<string, unknown>;\n\n if (typeof optionsOrClass === 'string') {\n // Legacy signature: purchaseSigil(identityClass, paymentTx)\n if (!optionsOrClass || !['narrow_task', 'autonomous', 'orchestrator'].includes(optionsOrClass)) {\n throw new ValidationError('identityClass must be narrow_task, autonomous, or orchestrator');\n }\n if (!paymentTx || typeof paymentTx !== 'string') {\n throw new ValidationError('paymentTx is required (Solana transaction signature or \"devnet-skip\")');\n }\n body = {\n identity_class: optionsOrClass,\n payment_tx: paymentTx,\n // Legacy calls without principal/tier — server will require these now\n // Callers must migrate to the options object form\n };\n } else {\n // New signature: purchaseSigil(options)\n const opts = optionsOrClass;\n if (!opts.identity_class || !['narrow_task', 'autonomous', 'orchestrator'].includes(opts.identity_class)) {\n throw new ValidationError('identity_class must be narrow_task, autonomous, or orchestrator');\n }\n if (!opts.principal || typeof opts.principal !== 'string') {\n throw new ValidationError('principal is required');\n }\n if (!opts.tier || !['sov', 'org', 'ind', 'eph', 'sbx'].includes(opts.tier)) {\n throw new ValidationError('tier must be one of: sov, org, ind, eph, sbx');\n }\n if (!opts.payment_tx || typeof opts.payment_tx !== 'string') {\n throw new ValidationError('payment_tx is required');\n }\n\n body = { ...opts };\n }\n\n try {\n const res = await this.api('POST', '/api/v1/sigil', body);\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.log(`SIGIL purchased: ${sigilStr}`);\n this.config.onStatusChange('sigil_issued', { sigil: sigilStr });\n\n return {\n ok: true,\n sigil: res.sigil,\n lineage_proof: res.lineage_proof,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'purchaseSigil');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Update mutable SIGIL metadata fields.\n * Requires a SIGIL. Cannot modify immutable fields.\n *\n * @param fields - Subset of mutable SIGIL fields to update\n */\n async updateMetadata(fields: Partial<SigilMutableFields>): Promise<MetadataUpdateResult> {\n if (!fields || Object.keys(fields).length === 0) {\n throw new ValidationError('At least one metadata field is required');\n }\n\n try {\n const res = await this.api('PATCH', '/api/v1/agent/metadata', fields);\n this.log(`Metadata updated: ${res.updated_fields?.join(', ') || 'unknown'}`);\n return {\n ok: true,\n sigil: res.sigil,\n generation: res.generation,\n updated_fields: res.updated_fields,\n };\n } catch (err: any) {\n this.config.onError(err, 'updateMetadata');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Send a paid heartbeat to the registry.\n * Requires a SIGIL. Returns a signed lineage proof.\n * This is the Phase 2 replacement for pulse() + checkin().\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx?: string, globalAnchor?: number): Promise<HeartbeatResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/heartbeat', {\n payment_tx: paymentTx || 'devnet-skip',\n global_anchor: globalAnchor,\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n if (res.ok) {\n this.status = 'active';\n const onHb = this.config.onHeartbeat || this.config.onCheckin;\n if (onHb) onHb(res);\n this.log(`Heartbeat accepted: epoch=${res.billing_epoch}, count=${res.heartbeat_count_epoch}`);\n }\n\n return {\n ok: res.ok,\n lineage_proof: res.lineage_proof,\n heartbeat_count_epoch: res.heartbeat_count_epoch,\n billing_epoch: res.billing_epoch,\n current_beat: res.current_beat,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a lineage proof. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n */\n async reissueProof(paymentTx?: string): Promise<{ ok: boolean; lineage_proof?: LineageProof; error?: string }> {\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx || 'devnet-skip',\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n return { ok: true, lineage_proof: res.lineage_proof };\n } catch (err: any) {\n this.config.onError(err, 'reissueProof');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached lineage proof (no network call).\n * Returns null if no proof has been obtained yet.\n */\n getLatestProof(): LineageProof | null {\n return this.cachedProof;\n }\n\n /**\n * Get the agent's passport (alias for getLatestProof).\n * The passport is the agent's portable, offline-verifiable credential.\n * Returns null if no passport has been issued yet (requires SIGIL + heartbeat).\n */\n getPassport(): Passport | null {\n return this.cachedProof;\n }\n\n /**\n * Verify a lineage proof locally using the authority public key.\n * Offline verification — no API call, no SOL cost.\n *\n * Returns a VerificationResult object. The object is truthy when valid,\n * so `if (BeatAgent.verifyProofLocally(proof, key))` still works.\n *\n * @param proof - The LineageProof to verify\n * @param authorityPubKeyHex - 32-byte hex-encoded Ed25519 public key from /.well-known/provenonce-authority.json\n * @param currentBeat - Optional current global beat index (for beatsSinceHeartbeat calculation)\n */\n static verifyProofLocally(proof: LineageProof, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n const now = Date.now();\n const expired = now > proof.valid_until;\n\n let signatureValid = false;\n try {\n // Canonical JSON (must match server's canonicalProofData)\n const canonical = JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n identity_class: proof.identity_class,\n registered_at_beat: proof.registered_at_beat,\n sigil_issued_at_beat: proof.sigil_issued_at_beat,\n last_heartbeat_beat: proof.last_heartbeat_beat,\n lineage_chain_hash: proof.lineage_chain_hash,\n issued_at: proof.issued_at,\n valid_until: proof.valid_until,\n });\n\n // Build Ed25519 public key from hex\n const pubBytes = Buffer.from(authorityPubKeyHex, 'hex');\n if (pubBytes.length === 32) {\n const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');\n const pubKeyDer = Buffer.concat([ED25519_SPKI_PREFIX, pubBytes]);\n const keyObject = createPublicKey({ key: pubKeyDer, format: 'der', type: 'spki' });\n const sigBuffer = Buffer.from(proof.provenonce_signature, 'hex');\n signatureValid = verify(null, Buffer.from(canonical), keyObject, sigBuffer);\n }\n } catch {\n signatureValid = false;\n }\n\n const valid = signatureValid && !expired;\n const beatsSinceHeartbeat = currentBeat != null ? currentBeat - proof.last_heartbeat_beat : null;\n\n let warning: string | undefined;\n if (expired) {\n warning = 'Proof has expired. Reissue with reissueProof() or send a heartbeat.';\n } else if (beatsSinceHeartbeat != null && beatsSinceHeartbeat > 60) {\n warning = `Agent is ${beatsSinceHeartbeat} beats behind. Heartbeat may be stale.`;\n }\n\n return { valid, signatureValid, expired, lastHeartbeatBeat: proof.last_heartbeat_beat, beatsSinceHeartbeat, warning };\n }\n\n // ── STATUS ──\n\n /**\n * Get this agent's full beat status from the registry.\n */\n async getStatus(): Promise<AgentStatus> {\n try {\n // We need the agent hash, but we may not have it directly.\n // The status endpoint uses the hash from the API key verification.\n // For now, use the init endpoint which returns status.\n return await this.refreshState();\n } catch (err: any) {\n this.config.onError(err, 'status');\n throw err;\n }\n }\n\n /**\n * Get local state (no network call).\n */\n getLocalState(): {\n status: string;\n totalBeats: number;\n latestBeat: number;\n latestHash: string;\n difficulty: number;\n globalBeat: number;\n chainLength: number;\n } {\n return {\n status: this.status,\n totalBeats: this.totalBeats,\n latestBeat: this.latestBeat?.index || 0,\n latestHash: this.latestBeat?.hash.slice(0, 24) + '...' || '',\n difficulty: this.difficulty,\n globalBeat: this.globalBeat,\n chainLength: this.chain.length,\n };\n }\n\n // ── INTERNALS ──\n\n private async syncGlobal(): Promise<void> {\n try {\n // SDK-P1-01: add timeout to syncGlobal fetch\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15_000);\n const res = await fetch(`${this.config.registryUrl}/api/v1/beat/anchor`, { signal: controller.signal });\n clearTimeout(timeout);\n const data: any = await res.json();\n if (data.anchor) {\n // Verify anchor hash locally before trusting it\n if (this.config.verifyAnchors && !verifyAnchorHash(data.anchor)) {\n this.log('⚠ Anchor hash verification FAILED — rejecting untrusted anchor');\n return;\n }\n this.globalBeat = data.anchor.beat_index;\n this.globalAnchorHash = data.anchor.hash || '';\n if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;\n this.log(`Synced to global beat ${this.globalBeat} (D=${this.difficulty})`);\n }\n } catch {\n this.log('Failed to sync global anchor (offline mode continues)');\n }\n }\n\n private async refreshState(): Promise<any> {\n const res = await this.api('POST', '/api/v1/agent/init');\n if (res.already_initialized) {\n this.totalBeats = res.total_beats;\n this.genesisHash = res.genesis_hash;\n this.status = res.status as any;\n this.difficulty = res.difficulty || this.difficulty;\n this.lastCheckinBeat = res.last_checkin_beat || 0;\n\n // Restore latestBeat so pulse() can continue the chain\n if (!this.latestBeat && this.genesisHash) {\n this.latestBeat = {\n index: res.latest_beat || this.totalBeats,\n hash: res.latest_hash || this.genesisHash,\n prev: '0'.repeat(64),\n timestamp: Date.now(),\n };\n this.chain = [this.latestBeat];\n }\n }\n return res;\n }\n\n private async api(method: string, path: string, body?: any): Promise<any> {\n // SDK-P1-01: add 30s timeout to prevent indefinite hangs\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n try {\n const res = await fetch(`${this.config.registryUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n throw new NetworkError(`API error: ${res.status} non-JSON response from ${path}`);\n }\n\n if (!res.ok && !data.ok && !data.already_initialized && !data.eligible) {\n throw mapApiError(res.status, data, path);\n }\n\n return data;\n } catch (err: any) {\n if (err.name === 'AbortError') {\n throw new NetworkError(`Request timeout: ${method} ${path}`, ErrorCode.TIMEOUT);\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private log(msg: string): void {\n if (this.config.verbose) {\n console.log(`[Beat] ${msg}`);\n }\n }\n}\n\n// ============ STANDALONE VDF HELPER ============\n// For agents that want to compute beats without the full SDK\n\nexport { computeBeat };\n\n/**\n * Compute N sequential VDF beats.\n * Returns only the last beat (for lightweight usage).\n */\nexport function computeBeatsLite(\n startHash: string,\n startIndex: number,\n count: number,\n difficulty: number = 1000,\n anchorHash?: string,\n): { lastBeat: Beat; elapsed: number } {\n // SDK-P2: validate inputs\n if (!startHash || typeof startHash !== 'string') {\n throw new ValidationError('computeBeatsLite: startHash must be a non-empty string');\n }\n if (!Number.isInteger(count) || count < 1) {\n throw new ValidationError('computeBeatsLite: count must be a positive integer');\n }\n\n const t0 = Date.now();\n let prev = startHash;\n let lastBeat: Beat | null = null;\n\n for (let i = 0; i < count; i++) {\n lastBeat = computeBeat(prev, startIndex + i, difficulty, undefined, anchorHash);\n prev = lastBeat.hash;\n }\n\n return { lastBeat: lastBeat!, elapsed: Date.now() - t0 };\n}\n","/**\n * Provenonce SDK Error Classes\n *\n * Typed error hierarchy for programmatic error handling.\n * All errors extend ProvenonceError for catch-all, or catch specific\n * subclasses for fine-grained control:\n *\n * try {\n * await agent.checkin();\n * } catch (err) {\n * if (err instanceof RateLimitError) {\n * await sleep(err.retryAfterMs);\n * } else if (err instanceof FrozenError) {\n * await agent.resync();\n * } else if (err instanceof AuthError) {\n * console.error('Bad API key');\n * }\n * }\n */\n\n/** Error codes for programmatic switching */\nexport enum ErrorCode {\n // Validation\n VALIDATION = 'VALIDATION',\n\n // Auth\n AUTH_INVALID = 'AUTH_INVALID',\n AUTH_MISSING = 'AUTH_MISSING',\n\n // Rate limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // Agent state\n AGENT_FROZEN = 'AGENT_FROZEN',\n AGENT_NOT_INITIALIZED = 'AGENT_NOT_INITIALIZED',\n AGENT_WRONG_STATE = 'AGENT_WRONG_STATE',\n\n // Not found\n NOT_FOUND = 'NOT_FOUND',\n\n // Network / server\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n SERVER_ERROR = 'SERVER_ERROR',\n}\n\n/** Base error class for all Provenonce SDK errors */\nexport class ProvenonceError extends Error {\n /** Machine-readable error code */\n readonly code: ErrorCode;\n\n /** HTTP status code (if from an API response) */\n readonly statusCode?: number;\n\n /** Additional context */\n readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ErrorCode,\n statusCode?: number,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ProvenonceError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n // Fix prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when input validation fails (bad config, invalid args) */\nexport class ValidationError extends ProvenonceError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, ErrorCode.VALIDATION, undefined, details);\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown on 401/403 — bad or missing API key */\nexport class AuthError extends ProvenonceError {\n constructor(\n message: string,\n code: ErrorCode.AUTH_INVALID | ErrorCode.AUTH_MISSING = ErrorCode.AUTH_INVALID,\n statusCode?: number,\n ) {\n super(message, code, statusCode);\n this.name = 'AuthError';\n }\n}\n\n/** Thrown on 429 — rate limit exceeded */\nexport class RateLimitError extends ProvenonceError {\n /** Milliseconds until the rate limit resets (if provided by server) */\n readonly retryAfterMs?: number;\n\n constructor(message: string, statusCode: number = 429, retryAfterMs?: number) {\n super(message, ErrorCode.RATE_LIMITED, statusCode);\n this.name = 'RateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** Thrown when an agent is frozen and cannot perform the requested action */\nexport class FrozenError extends ProvenonceError {\n constructor(message: string = 'Agent is frozen. Use resync() to re-establish provenance.') {\n super(message, ErrorCode.AGENT_FROZEN);\n this.name = 'FrozenError';\n }\n}\n\n/** Thrown when the agent is in the wrong state for the requested action */\nexport class StateError extends ProvenonceError {\n /** The agent's current state */\n readonly currentState: string;\n\n constructor(message: string, currentState: string, code: ErrorCode = ErrorCode.AGENT_WRONG_STATE) {\n super(message, code);\n this.name = 'StateError';\n this.currentState = currentState;\n }\n}\n\n/** Thrown on 404 — agent or resource not found */\nexport class NotFoundError extends ProvenonceError {\n constructor(message: string, statusCode: number = 404) {\n super(message, ErrorCode.NOT_FOUND, statusCode);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown on network failures — non-JSON responses, fetch errors, timeouts */\nexport class NetworkError extends ProvenonceError {\n constructor(message: string, code: ErrorCode.NETWORK_ERROR | ErrorCode.TIMEOUT = ErrorCode.NETWORK_ERROR) {\n super(message, code);\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown on 5xx — unexpected server errors */\nexport class ServerError extends ProvenonceError {\n constructor(message: string, statusCode: number = 500) {\n super(message, ErrorCode.SERVER_ERROR, statusCode);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Map an HTTP response + parsed body to the appropriate error class.\n * Used internally by the SDK to convert API failures to typed errors.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n\n if (statusCode === 401 || statusCode === 403) {\n const code = statusCode === 401 ? ErrorCode.AUTH_MISSING : ErrorCode.AUTH_INVALID;\n return new AuthError(msg, code, statusCode);\n }\n\n if (statusCode === 429) {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n\n if (statusCode === 404) {\n return new NotFoundError(msg, statusCode);\n }\n\n if (statusCode >= 500) {\n return new ServerError(msg, statusCode);\n }\n\n // Check for specific error patterns in the message\n const lowerMsg = msg.toLowerCase();\n if (lowerMsg.includes('frozen')) {\n return new FrozenError(msg);\n }\n\n // Generic client error\n return new ProvenonceError(msg, ErrorCode.SERVER_ERROR, statusCode);\n}\n"],"mappings":"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","names":["ErrorCode","res","data"]}
package/dist/index.mjs CHANGED
@@ -109,6 +109,54 @@ function computeBeat(prevHash, beatIndex, difficulty, nonce, anchorHash) {
109
109
  }
110
110
  return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };
111
111
  }
112
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
113
+ function base58DecodeToBuffer(str) {
114
+ const map = {};
115
+ for (let i = 0; i < BASE58_ALPHABET.length; i++) map[BASE58_ALPHABET[i]] = i;
116
+ let bytes = [0];
117
+ for (let i = 0; i < str.length; i++) {
118
+ const val = map[str[i]];
119
+ if (val === void 0) throw new Error("invalid base58 character");
120
+ let carry = val;
121
+ for (let j = 0; j < bytes.length; j++) {
122
+ const x = bytes[j] * 58 + carry;
123
+ bytes[j] = x & 255;
124
+ carry = x >> 8;
125
+ }
126
+ while (carry > 0) {
127
+ bytes.push(carry & 255);
128
+ carry >>= 8;
129
+ }
130
+ }
131
+ for (let i = 0; i < str.length && str[i] === "1"; i++) bytes.push(0);
132
+ return Buffer.from(bytes.reverse());
133
+ }
134
+ function u64be(n) {
135
+ const buf = Buffer.alloc(8);
136
+ buf.writeUInt32BE(Math.floor(n / 4294967296), 0);
137
+ buf.writeUInt32BE(n >>> 0, 4);
138
+ return buf;
139
+ }
140
+ var ANCHOR_DOMAIN_PREFIX = "PROVENONCE_BEATS_V1";
141
+ function verifyAnchorHash(anchor) {
142
+ if (!anchor || !anchor.hash || !anchor.prev_hash) return false;
143
+ if (anchor.solana_entropy) {
144
+ const prefix = Buffer.from(ANCHOR_DOMAIN_PREFIX, "utf8");
145
+ const prev = Buffer.from(anchor.prev_hash, "hex");
146
+ const idx = u64be(anchor.beat_index);
147
+ const entropy = base58DecodeToBuffer(anchor.solana_entropy);
148
+ const preimage = Buffer.concat([prefix, prev, idx, entropy]);
149
+ const computed = createHash("sha256").update(preimage).digest("hex");
150
+ return computed === anchor.hash;
151
+ }
152
+ const nonce = `anchor:${anchor.utc}:${anchor.epoch}`;
153
+ const seed = `${anchor.prev_hash}:${anchor.beat_index}:${nonce}`;
154
+ let current = createHash("sha256").update(seed).digest("hex");
155
+ for (let i = 0; i < anchor.difficulty; i++) {
156
+ current = createHash("sha256").update(current).digest("hex");
157
+ }
158
+ return current === anchor.hash;
159
+ }
112
160
  var ED25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b657004220420", "hex");
113
161
  function generateWalletKeypair() {
114
162
  const { publicKey, privateKey } = generateKeyPairSync("ed25519");
@@ -398,6 +446,7 @@ var BeatAgent = class {
398
446
  onStatusChange: () => {
399
447
  },
400
448
  verbose: false,
449
+ verifyAnchors: true,
401
450
  ...config
402
451
  };
403
452
  }
@@ -923,6 +972,10 @@ var BeatAgent = class {
923
972
  clearTimeout(timeout);
924
973
  const data = await res.json();
925
974
  if (data.anchor) {
975
+ if (this.config.verifyAnchors && !verifyAnchorHash(data.anchor)) {
976
+ this.log("\u26A0 Anchor hash verification FAILED \u2014 rejecting untrusted anchor");
977
+ return;
978
+ }
926
979
  this.globalBeat = data.anchor.beat_index;
927
980
  this.globalAnchorHash = data.anchor.hash || "";
928
981
  if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;
@@ -1021,6 +1074,7 @@ export {
1021
1074
  computeBeat,
1022
1075
  computeBeatsLite,
1023
1076
  generateWalletKeypair,
1024
- register
1077
+ register,
1078
+ verifyAnchorHash
1025
1079
  };
1026
1080
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/beat-sdk.ts","../src/errors.ts"],"sourcesContent":["/**\n * ═══════════════════════════════════════════════════════════\n * PROVENONCE BEAT SDK — Agent Heartbeat Client\n * ═══════════════════════════════════════════════════════════\n * \n * \"NIST tells you what time it is.\n * Provenonce tells the agent at what speed it is allowed to exist.\"\n * \n * Usage:\n * \n * import { BeatAgent } from './beat-sdk';\n * \n * const agent = new BeatAgent({\n * apiKey: 'pvn_...',\n * registryUrl: 'https://provenonce.io',\n * });\n * \n * await agent.init(); // Birth in Beat time\n * await agent.pulse(50); // Compute 50 beats\n * await agent.checkin(); // Report to registry\n * \n * // Or run the autonomous heartbeat:\n * agent.startHeartbeat(); // Computes + checks in continuously\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, generateKeyPairSync, sign, verify, createPrivateKey, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n mapApiError,\n ErrorCode,\n} from './errors';\n\n// ============ PHASE 2 TYPES ============\n\n/** SIGIL identity class — determines tier pricing and heartbeat volume caps */\nexport type IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator';\n\n/** SIGIL trust governance tier — orthogonal to identity_class (fee axis) */\nexport type SigilTier = 'sov' | 'org' | 'ind' | 'eph' | 'sbx';\n\n/** Substrate — what the agent runs on */\nexport type Substrate = 'frontier' | 'open' | 'local' | 'symbolic' | 'hybrid' | 'human';\n\n/** Substrate provider */\nexport type SubstrateProvider = 'anthropic' | 'openai' | 'google' | 'meta' | 'mistral' | 'xai' | 'cohere' | 'deepseek' | 'custom';\n\n/** Capability — what the agent primarily does */\nexport type Capability = 'analyst' | 'executor' | 'orchestrator' | 'guardian' | 'retriever' | 'renderer' | 'witness';\n\n/** Protocol — how to reach the agent */\nexport type SigilProtocol = 'http' | 'grpc' | 'websocket' | 'mcp' | 'a2a' | 'custom';\n\n/** Compliance regime */\nexport type ComplianceRegime = 'gdpr' | 'pdpa' | 'hipaa' | 'sox' | 'aisi' | 'none' | 'custom';\n\n/**\n * Ed25519-signed lineage proof — portable, offline-verifiable credential.\n * Also known as the agent's \"passport\" — a cryptographic proof of identity\n * that can be verified offline without any API call or SOL cost.\n */\nexport interface LineageProof {\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n issued_at: number;\n valid_until: number;\n provenonce_signature: string;\n}\n\n/** Passport = LineageProof. The agent's portable, offline-verifiable credential. */\nexport type Passport = LineageProof;\n\n/** Options for purchasing a SIGIL with full namespace */\nexport interface SigilPurchaseOptions {\n identity_class: IdentityClass;\n principal: string;\n tier: SigilTier;\n name?: string; // \"auto\" or custom name\n payment_tx: string;\n // Optional initial metadata\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Mutable SIGIL metadata fields for PATCH updates */\nexport interface SigilMutableFields {\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n generation_trigger?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Result from purchasing a SIGIL (Structured Identity Governance and Intelligent Lookup) */\nexport interface SigilResult {\n ok: boolean;\n sigil?: {\n sigil: string; // Full SIGIL string: name*principal*tier\n sigil_name: string;\n principal: string;\n tier: SigilTier;\n identity_class: IdentityClass;\n issued_at_beat: number;\n birth_tx: string | null;\n explorer_url: string | null;\n };\n lineage_proof?: LineageProof;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n/** Result from updating mutable SIGIL metadata */\nexport interface MetadataUpdateResult {\n ok: boolean;\n sigil?: string;\n generation?: number;\n updated_fields?: string[];\n error?: string;\n}\n\n/** Result from offline lineage proof verification */\nexport interface VerificationResult {\n /** Overall validity: signature is valid AND not expired */\n valid: boolean;\n /** Ed25519 signature verification passed */\n signatureValid: boolean;\n /** Proof has passed its valid_until timestamp */\n expired: boolean;\n /** The beat index of the agent's last heartbeat */\n lastHeartbeatBeat: number;\n /** Beats elapsed since last heartbeat (null if currentBeat not provided) */\n beatsSinceHeartbeat: number | null;\n /** Human-readable warning if proof is expired or stale */\n warning?: string;\n}\n\n/** Result from a paid heartbeat */\nexport interface HeartbeatResult {\n ok: boolean;\n lineage_proof?: LineageProof;\n heartbeat_count_epoch?: number;\n billing_epoch?: number;\n current_beat?: number;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n tier: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n// ============ VDF ENGINE (LOCAL) ============\n\nexport interface Beat {\n index: number;\n hash: string;\n prev: string;\n timestamp: number;\n nonce?: string;\n anchor_hash?: string;\n}\n\nfunction computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat {\n const timestamp = Date.now();\n\n const seed = anchorHash\n ? `${prevHash}:${beatIndex}:${nonce || ''}:${anchorHash}`\n : `${prevHash}:${beatIndex}:${nonce || ''}`;\n\n let current = createHash('sha256')\n .update(seed)\n .digest('hex');\n\n for (let i = 0; i < difficulty; i++) {\n current = createHash('sha256')\n .update(current)\n .digest('hex');\n }\n\n return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };\n}\n\n// ============ SDK RESULT TYPES ============\n\n/** Result from a check-in submission */\nexport interface CheckinResult {\n ok: boolean;\n total_beats: number;\n beats_accepted: number;\n global_beat: number;\n status?: string;\n beats_behind?: number;\n}\n\n/** Result from a spawn request */\nexport interface SpawnResult {\n ok: boolean;\n eligible: boolean;\n child_hash?: string;\n progress_pct?: number;\n deficit?: number;\n}\n\n/** Agent status from the registry */\nexport interface AgentStatus {\n already_initialized: boolean;\n total_beats: number;\n genesis_hash: string;\n status: string;\n genesis?: { hash: string; prev: string; timestamp: number };\n difficulty?: number;\n}\n\n// ============ WALLET KEYPAIR GENERATION ============\n\n// DER prefix for Ed25519 PKCS8 private keys (16 bytes)\nconst ED25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b657004220420', 'hex');\n\n/**\n * Generate an Ed25519 keypair for agent wallet identity.\n * Returns hex-encoded raw keys (32 bytes each).\n * Uses Node.js built-in crypto — zero external dependencies.\n */\nexport function generateWalletKeypair(): { publicKey: string; secretKey: string } {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519');\n const pubRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(12); // 32 bytes\n const privRaw = privateKey.export({ type: 'pkcs8', format: 'der' }).subarray(16); // 32 bytes\n return {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: Buffer.from(privRaw).toString('hex'),\n };\n}\n\n/**\n * Sign a message with an Ed25519 private key (hex-encoded 32-byte seed).\n * Returns hex-encoded signature (64 bytes).\n */\nfunction signMessage(secretKeyHex: string, message: string): string {\n const privRaw = Buffer.from(secretKeyHex, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const sig = sign(null, Buffer.from(message), keyObject);\n return Buffer.from(sig).toString('hex');\n}\n\n// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\n /** Hex-encoded 32-byte Ed25519 public key (Solana self-custody only, empty otherwise) */\n public_key: string;\n /** Hex-encoded 32-byte Ed25519 secret seed — SAVE THIS for future fee signing (Solana self-custody only) */\n secret_key: string;\n /** Solana-compatible base58 address (Solana wallets only) */\n solana_address?: string;\n /** The wallet address (base58 for Solana, 0x for Ethereum) */\n address: string;\n /** Wallet chain: 'solana' or 'ethereum' */\n chain: string;\n}\n\n/** Result from registering an agent */\nexport interface RegistrationResult {\n hash: string;\n api_key: string;\n secret: string;\n type: 'root' | 'agent';\n parent: string | null;\n depth: number;\n name: string;\n metadata?: Record<string, unknown> | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n signature?: string | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n explorer_url?: string | null;\n /** Wallet chain: 'solana', 'ethereum', or null (no wallet) */\n wallet_chain?: string | null;\n beat?: { genesis_hash: string; difficulty: number; status: string };\n /** Wallet info — only present for root agents with wallets */\n wallet?: WalletInfo;\n /** Next steps after registration */\n _next_steps?: { sigil?: string; heartbeat?: string };\n}\n\n/** Options for the register() function */\nexport interface RegisterOptions {\n registryUrl?: string;\n parentHash?: string;\n parentApiKey?: string;\n registrationSecret?: string;\n /** Single-use registration token from POST /register/token or POST /register/email/verify */\n registrationToken?: string;\n /** Admin-minted invite token */\n registrationInvite?: string;\n /** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */\n walletSecretKey?: string;\n /** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: 'self-custody' | 'operator';\n /** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */\n walletChain?: 'solana' | 'ethereum';\n /** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */\n walletAddress?: string;\n /** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */\n walletSignFn?: (message: string) => Promise<string>;\n /** Operator's Solana wallet address (base58). Required when walletModel='operator'. */\n operatorWalletAddress?: string;\n /** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */\n operatorSignFn?: (message: string) => Promise<string>;\n /** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Register a new agent on the Provenonce registry.\n *\n * With registration token (from /register/token or email verification):\n * const creds = await register('my-agent', {\n * registryUrl: '...',\n * registrationToken: '<token-from-email-verify>',\n * });\n *\n * No wallet (default, single-phase):\n * const creds = await register('my-agent', { registryUrl: '...' });\n *\n * Solana self-custody wallet (Model A, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'self-custody',\n * });\n * // creds.wallet.secret_key = hex secret (SAVE THIS)\n * // creds.wallet.address = base58 Solana address\n *\n * Solana with existing key:\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletSecretKey: '<hex-encoded-32-byte-seed>',\n * });\n *\n * Ethereum bring-your-own (two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletChain: 'ethereum',\n * walletAddress: '0x...',\n * walletSignFn: (msg) => wallet.signMessage(msg),\n * });\n *\n * Solana operator (Model B, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'operator',\n * operatorWalletAddress: '<base58>',\n * operatorSignFn: (msg) => signWithWallet(msg),\n * });\n *\n * Child agent (no wallet):\n * const creds = await register('worker-1', {\n * registryUrl: '...',\n * parentHash: parentCreds.hash,\n * parentApiKey: parentCreds.api_key,\n * });\n */\nexport async function register(\n name: string,\n options?: RegisterOptions,\n): Promise<RegistrationResult> {\n // SDK-P1-07/P1-08: validate inputs\n if (!name || typeof name !== 'string' || name.trim().length === 0) {\n throw new ValidationError('name is required (must be a non-empty string)');\n }\n if (name.length > 64) {\n throw new ValidationError('name must be 64 characters or fewer');\n }\n\n const url = options?.registryUrl || 'https://provenonce.io';\n try {\n new URL(url);\n } catch {\n throw new ValidationError('registryUrl is not a valid URL');\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\n if (options?.registrationSecret) {\n headers['x-registration-secret'] = options.registrationSecret;\n }\n if (options?.registrationToken) {\n headers['x-registration-token'] = options.registrationToken;\n }\n if (options?.registrationInvite) {\n headers['x-registration-invite'] = options.registrationInvite;\n }\n\n // ===== CHILD REGISTRATION (no wallet, single-phase) =====\n if (options?.parentHash) {\n if (options.parentApiKey) {\n headers['Authorization'] = `Bearer ${options.parentApiKey}`;\n }\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, parent: options.parentHash, ...(options.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n }\n\n // ===== ETHEREUM BRING-YOUR-OWN (D-63, two-phase) =====\n if (options?.walletChain === 'ethereum') {\n if (!options.walletAddress || !options.walletSignFn) {\n throw new ValidationError('Ethereum registration requires walletAddress and walletSignFn');\n }\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(options.walletAddress)) {\n throw new ValidationError('walletAddress must be a valid Ethereum address (0x + 40 hex chars)');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_chain: 'ethereum' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Sign with Ethereum wallet (EIP-191 personal_sign)\n const nonce = challengeData.nonce;\n const message = `provenonce-register-ethereum:${nonce}:${options.walletAddress}:${name}`;\n const walletSignature = await options.walletSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_chain: 'ethereum',\n wallet_address: options.walletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n } catch {\n throw new NetworkError(`Ethereum registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Ethereum: wallet has address only (no keypair — user keeps custody externally)\n data.wallet = {\n public_key: '',\n secret_key: '',\n address: data.wallet?.address || options.walletAddress,\n chain: 'ethereum',\n };\n\n return data;\n }\n\n // ===== MODEL B: SOLANA OPERATOR WALLET REGISTRATION (two-phase) =====\n if (options?.walletModel === 'operator') {\n if (!options.operatorWalletAddress || !options.operatorSignFn) {\n throw new ValidationError('Operator registration requires operatorWalletAddress and operatorSignFn');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_model: 'operator' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Operator signs challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register-operator:${nonce}:${options.operatorWalletAddress}:${name}`;\n const walletSignature = await options.operatorSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_model: 'operator',\n operator_wallet_address: options.operatorWalletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n throw new NetworkError(`Operator registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Model B: wallet has address only (no secret_key/public_key — operator keeps custody)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\n public_key: '',\n secret_key: '',\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== MODEL A: SOLANA SELF-CUSTODY WALLET REGISTRATION (opt-in, two-phase) =====\n if (options?.walletModel === 'self-custody' || options?.walletSecretKey) {\n // Generate or use provided wallet keypair\n let walletKeys: { publicKey: string; secretKey: string };\n if (options?.walletSecretKey) {\n // Derive public key from provided secret\n const privRaw = Buffer.from(options.walletSecretKey, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const pubRaw = keyObject.export({ type: 'spki', format: 'der' }).subarray(12);\n walletKeys = {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: options.walletSecretKey,\n };\n } else {\n walletKeys = generateWalletKeypair();\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n const err = new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n // Attach wallet keys so caller can retry with the same keypair\n const err = mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Phase 2: Sign challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register:${nonce}:${walletKeys.publicKey}:${name}`;\n const walletSignature = signMessage(walletKeys.secretKey, message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_public_key: walletKeys.publicKey,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options?.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n // Attach wallet keys so caller can retry with the same keypair\n const err = new NetworkError(`Registration failed: ${registerRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!registerRes.ok) {\n // Attach wallet keys so caller can retry with the same keypair via walletSecretKey option\n const err = mapApiError(registerRes.status, data, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Attach the wallet keys (secret is client-side only, never sent to server)\n const addr = data.wallet?.address || data.wallet?.solana_address || '';\n data.wallet = {\n public_key: walletKeys.publicKey,\n secret_key: walletKeys.secretKey,\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== NO-WALLET REGISTRATION (D-62 default, single-phase) =====\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, ...(options?.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n}\n\n// ============ SDK CONFIG ============\n\nexport interface BeatAgentConfig {\n /** API key from registration (pvn_...) */\n apiKey: string;\n\n /** Provenonce registry URL */\n registryUrl: string;\n\n /** @deprecated Use heartbeatIntervalSec. Beats to compute per pulse (default: 10) */\n beatsPerPulse?: number;\n\n /** @deprecated Use heartbeatIntervalSec. Seconds between automatic check-ins (default: 300 = 5min) */\n checkinIntervalSec?: number;\n\n /** Seconds between automatic heartbeats (default: 300 = 5min). Replaces checkinIntervalSec. */\n heartbeatIntervalSec?: number;\n\n /** @deprecated VDF pulse callback. No longer used in Phase 2. */\n onPulse?: (beats: Beat[], totalBeats: number) => void;\n\n /** @deprecated Use onHeartbeat. Callback when check-in completes. */\n onCheckin?: (result: CheckinResult) => void;\n\n /** Callback when heartbeat completes (Phase 2) */\n onHeartbeat?: (result: HeartbeatResult) => void;\n\n /** Callback on error */\n onError?: (error: Error, context: string) => void;\n\n /** Callback when status changes */\n onStatusChange?: (status: string, details: Record<string, unknown>) => void;\n\n /** Enable verbose logging */\n verbose?: boolean;\n}\n\n// ============ BEAT AGENT ============\n\nexport class BeatAgent {\n private config: Required<BeatAgentConfig>;\n private chain: Beat[] = [];\n private difficulty: number = 1000;\n private genesisHash: string = '';\n private latestBeat: Beat | null = null;\n private totalBeats: number = 0;\n private lastCheckinBeat: number = 0;\n private status: 'uninitialized' | 'active' | 'frozen' | 'revoked' = 'uninitialized';\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private globalBeat: number = 0;\n private globalAnchorHash: string = '';\n\n constructor(config: BeatAgentConfig) {\n // SDK-P1-08: validate required config fields\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new ValidationError('BeatAgentConfig.apiKey is required (must be a non-empty string)');\n }\n if (!config.registryUrl || typeof config.registryUrl !== 'string') {\n throw new ValidationError('BeatAgentConfig.registryUrl is required (must be a non-empty string)');\n }\n // SDK-P1-07: validate registryUrl is a valid URL\n try {\n new URL(config.registryUrl);\n } catch {\n throw new ValidationError('BeatAgentConfig.registryUrl is not a valid URL');\n }\n\n // SDK-P2: validate optional numeric config\n if (config.beatsPerPulse !== undefined && (!Number.isInteger(config.beatsPerPulse) || config.beatsPerPulse < 1 || config.beatsPerPulse > 10000)) {\n throw new ValidationError('BeatAgentConfig.beatsPerPulse must be an integer between 1 and 10000');\n }\n if (config.checkinIntervalSec !== undefined && (!Number.isFinite(config.checkinIntervalSec) || config.checkinIntervalSec < 10 || config.checkinIntervalSec > 86400)) {\n throw new ValidationError('BeatAgentConfig.checkinIntervalSec must be between 10 and 86400');\n }\n\n this.config = {\n beatsPerPulse: 10,\n checkinIntervalSec: 300,\n heartbeatIntervalSec: 300,\n onPulse: () => {},\n onCheckin: () => {},\n onHeartbeat: () => {},\n onError: () => {},\n onStatusChange: () => {},\n verbose: false,\n ...config,\n };\n }\n\n // ── INITIALIZATION ──\n\n /**\n * Initialize the agent's Beat chain.\n * This is the agent's \"birth\" in Logical Time.\n * Must be called once before computing beats.\n */\n async init(): Promise<{ ok: boolean; genesis?: string; error?: string }> {\n try {\n this.log('Initializing Beat chain...');\n\n const res = await this.api('POST', '/api/v1/agent/init');\n\n if (res.genesis) {\n this.genesisHash = res.genesis.hash;\n this.difficulty = res.difficulty || 1000;\n this.latestBeat = {\n index: 0,\n hash: res.genesis.hash,\n prev: res.genesis.prev,\n timestamp: res.genesis.timestamp,\n };\n this.chain = [this.latestBeat];\n this.totalBeats = 0;\n this.status = 'active';\n this.config.onStatusChange('active', { genesis: this.genesisHash });\n this.log(`Born in Beat time. Genesis: ${this.genesisHash.slice(0, 16)}...`);\n } else if (res.already_initialized) {\n // Restore from existing state\n this.genesisHash = res.genesis_hash;\n this.totalBeats = res.total_beats;\n this.status = res.status as any;\n this.log(`Already initialized. Restoring state (${res.total_beats} beats).`);\n \n // Fetch full state to get latest hash\n await this.refreshState();\n }\n\n // Sync global anchor\n await this.syncGlobal();\n\n return { ok: true, genesis: this.genesisHash };\n\n } catch (err: any) {\n this.config.onError(err, 'init');\n return { ok: false, error: err.message };\n }\n }\n\n // ── PULSE (COMPUTE BEATS) ──\n\n /**\n * @deprecated Phase 2: VDF computation retired (D-68). Payment is the liveness mechanism.\n * Use heartbeat() instead. This method will be removed in the next major version.\n *\n * Compute N beats locally (VDF hash chain).\n */\n pulse(count?: number): Beat[] {\n console.warn('[Provenonce SDK] pulse() is deprecated. Use heartbeat() instead (Phase 2).');\n if (this.status === 'frozen') {\n throw new FrozenError('Cannot pulse: agent is frozen. Use resync() to re-establish provenance.');\n }\n if (this.status !== 'active') {\n throw new StateError(`Cannot pulse: agent is ${this.status}.`, this.status);\n }\n // SDK-P2: validate count param\n if (count !== undefined && (!Number.isInteger(count) || count < 1 || count > 10000)) {\n throw new ValidationError('pulse count must be an integer between 1 and 10000');\n }\n return this.computeBeats(count);\n }\n\n /** Internal beat computation — no status check. Used by both pulse() and resync(). */\n private computeBeats(count?: number, onProgress?: (computed: number, total: number) => void): Beat[] {\n const n = count || this.config.beatsPerPulse;\n\n if (!this.latestBeat) {\n throw new StateError('Beat chain not initialized. Call init() first.', 'uninitialized', ErrorCode.AGENT_NOT_INITIALIZED);\n }\n\n const newBeats: Beat[] = [];\n let prevHash = this.latestBeat.hash;\n let startIndex = this.latestBeat.index + 1;\n\n const t0 = Date.now();\n // SDK-P2: report progress every 10% of beats\n const progressInterval = Math.max(1, Math.floor(n / 10));\n\n for (let i = 0; i < n; i++) {\n const beat = computeBeat(prevHash, startIndex + i, this.difficulty, undefined, this.globalAnchorHash || undefined);\n newBeats.push(beat);\n prevHash = beat.hash;\n if (onProgress && (i + 1) % progressInterval === 0) {\n onProgress(i + 1, n);\n }\n }\n\n const elapsed = Date.now() - t0;\n\n // Update state\n this.chain.push(...newBeats);\n this.latestBeat = newBeats[newBeats.length - 1];\n this.totalBeats += n;\n\n // Keep chain bounded (only last 1000 beats in memory)\n if (this.chain.length > 1000) {\n this.chain = this.chain.slice(-500);\n }\n\n this.config.onPulse(newBeats, this.totalBeats);\n this.log(`Pulse: ${n} beats in ${elapsed}ms (${(elapsed / n).toFixed(1)}ms/beat, D=${this.difficulty})`);\n\n return newBeats;\n }\n\n // ── CHECK-IN ──\n\n /**\n * @deprecated Phase 2: VDF check-in retired (D-68). Use heartbeat() instead.\n * This method will be removed in the next major version.\n */\n async checkin(): Promise<{ ok: boolean; total_beats?: number; error?: string }> {\n console.warn('[Provenonce SDK] checkin() is deprecated. Use heartbeat() instead (Phase 2).');\n // SDK-P1-02: fix guard to compare beat indices, not totalBeats vs lastCheckinBeat\n if (!this.latestBeat || this.latestBeat.index <= this.lastCheckinBeat) {\n this.log('No new beats since last check-in. Call pulse() first.');\n return { ok: true, total_beats: this.totalBeats }; // Nothing new to report\n }\n\n try {\n // Find the boundary hashes\n const fromBeat = this.lastCheckinBeat;\n const toBeat = this.latestBeat.index;\n\n // Build spot checks from our local chain\n // prev and nonce are required for the server to recompute VDF\n // Must always include to_beat (final beat) — server requires it for final hash verification\n const spotChecks: { index: number; hash: string; prev: string; nonce?: string }[] = [];\n\n // Always include the final beat\n const toBeatEntry = this.chain.find(b => b.index === toBeat);\n if (toBeatEntry) {\n spotChecks.push({ index: toBeatEntry.index, hash: toBeatEntry.hash, prev: toBeatEntry.prev, nonce: toBeatEntry.nonce });\n }\n\n // Sample up to 4 more from the rest\n const available = this.chain.filter(b => b.index > this.lastCheckinBeat && b.index !== toBeat);\n const sampleCount = Math.min(4, available.length);\n\n for (let i = 0; i < sampleCount; i++) {\n const idx = Math.floor(Math.random() * available.length);\n const beat = available[idx];\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev, nonce: beat.nonce });\n available.splice(idx, 1);\n }\n const fromHash = this.chain.find(b => b.index === fromBeat)?.hash \n || this.genesisHash;\n const toHash = this.latestBeat.hash;\n\n const res = await this.api('POST', '/api/v1/agent/checkin', {\n proof: {\n from_beat: fromBeat,\n to_beat: toBeat,\n from_hash: fromHash,\n to_hash: toHash,\n beats_computed: toBeat - fromBeat,\n global_anchor: this.globalBeat,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: spotChecks,\n },\n });\n\n if (res.ok) {\n this.lastCheckinBeat = toBeat;\n this.totalBeats = res.total_beats;\n this.config.onCheckin(res);\n this.log(`Check-in accepted: ${res.beats_accepted} beats, total=${res.total_beats}, global=${res.global_beat}`);\n \n if (res.status === 'warning_overdue') {\n this.config.onStatusChange('warning', { beats_behind: res.beats_behind });\n this.log(`⚠ WARNING: ${res.beats_behind} anchors behind. Check in more frequently.`);\n }\n }\n\n return { ok: res.ok, total_beats: res.total_beats };\n\n } catch (err: any) {\n this.config.onError(err, 'checkin');\n return { ok: false, error: err.message };\n }\n }\n\n // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Optional function that returns a payment tx for each heartbeat.\n * If not provided, uses 'devnet-skip' (devnet only).\n */\n startHeartbeat(paymentTxFn?: () => Promise<string> | string): void {\n if (this.heartbeatInterval) {\n this.log('Heartbeat already running.');\n return;\n }\n\n if (this.status !== 'active' && this.status !== 'uninitialized') {\n throw new StateError(`Cannot start heartbeat in status '${this.status}'.`, this.status);\n }\n\n const intervalSec = this.config.heartbeatIntervalSec || this.config.checkinIntervalSec || 300;\n this.log(`Starting heartbeat (interval: ${intervalSec}s)...`);\n\n // SDK-P1-03: exponential backoff on consecutive errors\n let consecutiveErrors = 0;\n let skipCount = 0;\n\n this.heartbeatInterval = setInterval(async () => {\n if (skipCount > 0) {\n skipCount--;\n return;\n }\n\n try {\n const paymentTx = paymentTxFn ? await paymentTxFn() : 'devnet-skip';\n await this.heartbeat(paymentTx);\n consecutiveErrors = 0;\n } catch (err: any) {\n consecutiveErrors++;\n this.config.onError(err, 'heartbeat');\n skipCount = Math.min(32, Math.pow(2, consecutiveErrors - 1));\n this.log(`Heartbeat error #${consecutiveErrors}, backing off ${skipCount} ticks`);\n }\n }, intervalSec * 1000);\n }\n\n /**\n * Stop the heartbeat loop.\n */\n stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n this.log('Heartbeat stopped.');\n }\n }\n\n // ── RE-SYNC ──\n\n /**\n * @deprecated Phase 2: Resync retired (D-67). Dormancy resume is free — just call heartbeat().\n * This method will be removed in the next major version.\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n console.warn('[Provenonce SDK] resync() is deprecated (D-67). Use heartbeat() to resume (Phase 2).');\n try {\n this.log('Requesting re-sync challenge...');\n\n // Phase 1: Get challenge\n const challenge = await this.api('POST', '/api/v1/agent/resync', {\n action: 'challenge',\n });\n\n if (!challenge.challenge) {\n return { ok: false, error: 'Failed to get challenge' };\n }\n\n const required = challenge.challenge.required_beats;\n this.difficulty = challenge.challenge.difficulty;\n this.log(`Re-sync challenge: compute ${required} beats at D=${this.difficulty}`);\n\n // Sync global anchor so beats are woven with a recent anchor hash\n await this.syncGlobal();\n\n // Compute the required beats\n const startHash = challenge.challenge.start_from_hash;\n const startBeat = challenge.challenge.start_from_beat;\n\n // Reset chain from the known point\n this.latestBeat = { index: startBeat, hash: startHash, prev: '', timestamp: Date.now() };\n this.chain = [this.latestBeat];\n\n const t0 = Date.now();\n this.computeBeats(required);\n const elapsed = Date.now() - t0;\n this.log(`Re-sync beats computed in ${elapsed}ms`);\n\n // Phase 2: Submit proof (include challenge_nonce for server verification)\n const proof = await this.api('POST', '/api/v1/agent/resync', {\n action: 'prove',\n challenge_nonce: challenge.challenge.nonce,\n proof: {\n from_beat: startBeat,\n to_beat: this.latestBeat!.index,\n from_hash: startHash,\n to_hash: this.latestBeat!.hash,\n beats_computed: required,\n global_anchor: challenge.challenge.sync_to_global,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: (() => {\n // Must include to_beat (final beat) — server requires it for final hash verification\n const toBeatEntry = this.chain.find(b => b.index === this.latestBeat!.index);\n // Sample from available chain beats (chain may be trimmed to 500 entries)\n const available = this.chain\n .filter(b => b.index !== this.latestBeat!.index && b.index > startBeat);\n const step = Math.max(1, Math.ceil(available.length / 5));\n const others = available\n .filter((_, i) => i % step === 0)\n .slice(0, 4);\n const checks = toBeatEntry ? [toBeatEntry, ...others] : others;\n return checks.map(b => ({ index: b.index, hash: b.hash, prev: b.prev, nonce: b.nonce }));\n })(),\n },\n });\n\n if (proof.ok) {\n this.status = 'active';\n this.totalBeats = proof.total_beats;\n this.lastCheckinBeat = this.latestBeat!.index;\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced. Agent is alive again in Beat time.');\n }\n\n return { ok: proof.ok, beats_required: required };\n\n } catch (err: any) {\n this.config.onError(err, 'resync');\n return { ok: false, error: err.message };\n }\n }\n\n // ── SPAWN ──\n\n /**\n * Request to spawn a child agent.\n * Requires sufficient accumulated beats (Temporal Gestation).\n */\n async requestSpawn(childName?: string, childHash?: string): Promise<SpawnResult> {\n try {\n // SDK-P1-05: validate childName\n if (childName !== undefined) {\n if (typeof childName !== 'string' || childName.trim().length === 0) {\n throw new ValidationError('childName must be a non-empty string');\n }\n if (childName.length > 64) {\n throw new ValidationError('childName must be 64 characters or fewer');\n }\n }\n\n const res = await this.api('POST', '/api/v1/agent/spawn', {\n child_name: childName,\n child_hash: childHash,\n });\n\n if (res.eligible === false) {\n this.log(`Gestation incomplete: ${res.progress_pct}% (need ${res.deficit} more beats)`);\n } else if (res.ok) {\n this.log(`Child spawned: ${res.child_hash?.slice(0, 16)}...`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached lineage proof from the most recent heartbeat or SIGIL purchase */\n private cachedProof: LineageProof | null = null;\n\n /**\n * Purchase a SIGIL (cryptographic identity) for this agent.\n * SIGILs gate heartbeating, lineage proofs, and offline verification.\n * One-time purchase — cannot be re-purchased.\n *\n * @param options - SIGIL purchase options (identity_class, principal, tier, name, payment_tx, + optional metadata)\n *\n * Legacy signature (deprecated):\n * @param identityClass - 'narrow_task' | 'autonomous' | 'orchestrator'\n * @param paymentTx - Solana transaction signature or 'devnet-skip'\n */\n async purchaseSigil(optionsOrClass: SigilPurchaseOptions | IdentityClass, paymentTx?: string): Promise<SigilResult> {\n let body: Record<string, unknown>;\n\n if (typeof optionsOrClass === 'string') {\n // Legacy signature: purchaseSigil(identityClass, paymentTx)\n if (!optionsOrClass || !['narrow_task', 'autonomous', 'orchestrator'].includes(optionsOrClass)) {\n throw new ValidationError('identityClass must be narrow_task, autonomous, or orchestrator');\n }\n if (!paymentTx || typeof paymentTx !== 'string') {\n throw new ValidationError('paymentTx is required (Solana transaction signature or \"devnet-skip\")');\n }\n body = {\n identity_class: optionsOrClass,\n payment_tx: paymentTx,\n // Legacy calls without principal/tier — server will require these now\n // Callers must migrate to the options object form\n };\n } else {\n // New signature: purchaseSigil(options)\n const opts = optionsOrClass;\n if (!opts.identity_class || !['narrow_task', 'autonomous', 'orchestrator'].includes(opts.identity_class)) {\n throw new ValidationError('identity_class must be narrow_task, autonomous, or orchestrator');\n }\n if (!opts.principal || typeof opts.principal !== 'string') {\n throw new ValidationError('principal is required');\n }\n if (!opts.tier || !['sov', 'org', 'ind', 'eph', 'sbx'].includes(opts.tier)) {\n throw new ValidationError('tier must be one of: sov, org, ind, eph, sbx');\n }\n if (!opts.payment_tx || typeof opts.payment_tx !== 'string') {\n throw new ValidationError('payment_tx is required');\n }\n\n body = { ...opts };\n }\n\n try {\n const res = await this.api('POST', '/api/v1/sigil', body);\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.log(`SIGIL purchased: ${sigilStr}`);\n this.config.onStatusChange('sigil_issued', { sigil: sigilStr });\n\n return {\n ok: true,\n sigil: res.sigil,\n lineage_proof: res.lineage_proof,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'purchaseSigil');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Update mutable SIGIL metadata fields.\n * Requires a SIGIL. Cannot modify immutable fields.\n *\n * @param fields - Subset of mutable SIGIL fields to update\n */\n async updateMetadata(fields: Partial<SigilMutableFields>): Promise<MetadataUpdateResult> {\n if (!fields || Object.keys(fields).length === 0) {\n throw new ValidationError('At least one metadata field is required');\n }\n\n try {\n const res = await this.api('PATCH', '/api/v1/agent/metadata', fields);\n this.log(`Metadata updated: ${res.updated_fields?.join(', ') || 'unknown'}`);\n return {\n ok: true,\n sigil: res.sigil,\n generation: res.generation,\n updated_fields: res.updated_fields,\n };\n } catch (err: any) {\n this.config.onError(err, 'updateMetadata');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Send a paid heartbeat to the registry.\n * Requires a SIGIL. Returns a signed lineage proof.\n * This is the Phase 2 replacement for pulse() + checkin().\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx?: string, globalAnchor?: number): Promise<HeartbeatResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/heartbeat', {\n payment_tx: paymentTx || 'devnet-skip',\n global_anchor: globalAnchor,\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n if (res.ok) {\n this.status = 'active';\n const onHb = this.config.onHeartbeat || this.config.onCheckin;\n if (onHb) onHb(res);\n this.log(`Heartbeat accepted: epoch=${res.billing_epoch}, count=${res.heartbeat_count_epoch}`);\n }\n\n return {\n ok: res.ok,\n lineage_proof: res.lineage_proof,\n heartbeat_count_epoch: res.heartbeat_count_epoch,\n billing_epoch: res.billing_epoch,\n current_beat: res.current_beat,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a lineage proof. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n */\n async reissueProof(paymentTx?: string): Promise<{ ok: boolean; lineage_proof?: LineageProof; error?: string }> {\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx || 'devnet-skip',\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n return { ok: true, lineage_proof: res.lineage_proof };\n } catch (err: any) {\n this.config.onError(err, 'reissueProof');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached lineage proof (no network call).\n * Returns null if no proof has been obtained yet.\n */\n getLatestProof(): LineageProof | null {\n return this.cachedProof;\n }\n\n /**\n * Get the agent's passport (alias for getLatestProof).\n * The passport is the agent's portable, offline-verifiable credential.\n * Returns null if no passport has been issued yet (requires SIGIL + heartbeat).\n */\n getPassport(): Passport | null {\n return this.cachedProof;\n }\n\n /**\n * Verify a lineage proof locally using the authority public key.\n * Offline verification — no API call, no SOL cost.\n *\n * Returns a VerificationResult object. The object is truthy when valid,\n * so `if (BeatAgent.verifyProofLocally(proof, key))` still works.\n *\n * @param proof - The LineageProof to verify\n * @param authorityPubKeyHex - 32-byte hex-encoded Ed25519 public key from /.well-known/provenonce-authority.json\n * @param currentBeat - Optional current global beat index (for beatsSinceHeartbeat calculation)\n */\n static verifyProofLocally(proof: LineageProof, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n const now = Date.now();\n const expired = now > proof.valid_until;\n\n let signatureValid = false;\n try {\n // Canonical JSON (must match server's canonicalProofData)\n const canonical = JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n identity_class: proof.identity_class,\n registered_at_beat: proof.registered_at_beat,\n sigil_issued_at_beat: proof.sigil_issued_at_beat,\n last_heartbeat_beat: proof.last_heartbeat_beat,\n lineage_chain_hash: proof.lineage_chain_hash,\n issued_at: proof.issued_at,\n valid_until: proof.valid_until,\n });\n\n // Build Ed25519 public key from hex\n const pubBytes = Buffer.from(authorityPubKeyHex, 'hex');\n if (pubBytes.length === 32) {\n const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');\n const pubKeyDer = Buffer.concat([ED25519_SPKI_PREFIX, pubBytes]);\n const keyObject = createPublicKey({ key: pubKeyDer, format: 'der', type: 'spki' });\n const sigBuffer = Buffer.from(proof.provenonce_signature, 'hex');\n signatureValid = verify(null, Buffer.from(canonical), keyObject, sigBuffer);\n }\n } catch {\n signatureValid = false;\n }\n\n const valid = signatureValid && !expired;\n const beatsSinceHeartbeat = currentBeat != null ? currentBeat - proof.last_heartbeat_beat : null;\n\n let warning: string | undefined;\n if (expired) {\n warning = 'Proof has expired. Reissue with reissueProof() or send a heartbeat.';\n } else if (beatsSinceHeartbeat != null && beatsSinceHeartbeat > 60) {\n warning = `Agent is ${beatsSinceHeartbeat} beats behind. Heartbeat may be stale.`;\n }\n\n return { valid, signatureValid, expired, lastHeartbeatBeat: proof.last_heartbeat_beat, beatsSinceHeartbeat, warning };\n }\n\n // ── STATUS ──\n\n /**\n * Get this agent's full beat status from the registry.\n */\n async getStatus(): Promise<AgentStatus> {\n try {\n // We need the agent hash, but we may not have it directly.\n // The status endpoint uses the hash from the API key verification.\n // For now, use the init endpoint which returns status.\n return await this.refreshState();\n } catch (err: any) {\n this.config.onError(err, 'status');\n throw err;\n }\n }\n\n /**\n * Get local state (no network call).\n */\n getLocalState(): {\n status: string;\n totalBeats: number;\n latestBeat: number;\n latestHash: string;\n difficulty: number;\n globalBeat: number;\n chainLength: number;\n } {\n return {\n status: this.status,\n totalBeats: this.totalBeats,\n latestBeat: this.latestBeat?.index || 0,\n latestHash: this.latestBeat?.hash.slice(0, 24) + '...' || '',\n difficulty: this.difficulty,\n globalBeat: this.globalBeat,\n chainLength: this.chain.length,\n };\n }\n\n // ── INTERNALS ──\n\n private async syncGlobal(): Promise<void> {\n try {\n // SDK-P1-01: add timeout to syncGlobal fetch\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15_000);\n const res = await fetch(`${this.config.registryUrl}/api/v1/beat/anchor`, { signal: controller.signal });\n clearTimeout(timeout);\n const data: any = await res.json();\n if (data.anchor) {\n this.globalBeat = data.anchor.beat_index;\n this.globalAnchorHash = data.anchor.hash || '';\n if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;\n this.log(`Synced to global beat ${this.globalBeat} (D=${this.difficulty})`);\n }\n } catch {\n this.log('Failed to sync global anchor (offline mode continues)');\n }\n }\n\n private async refreshState(): Promise<any> {\n const res = await this.api('POST', '/api/v1/agent/init');\n if (res.already_initialized) {\n this.totalBeats = res.total_beats;\n this.genesisHash = res.genesis_hash;\n this.status = res.status as any;\n this.difficulty = res.difficulty || this.difficulty;\n this.lastCheckinBeat = res.last_checkin_beat || 0;\n\n // Restore latestBeat so pulse() can continue the chain\n if (!this.latestBeat && this.genesisHash) {\n this.latestBeat = {\n index: res.latest_beat || this.totalBeats,\n hash: res.latest_hash || this.genesisHash,\n prev: '0'.repeat(64),\n timestamp: Date.now(),\n };\n this.chain = [this.latestBeat];\n }\n }\n return res;\n }\n\n private async api(method: string, path: string, body?: any): Promise<any> {\n // SDK-P1-01: add 30s timeout to prevent indefinite hangs\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n try {\n const res = await fetch(`${this.config.registryUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n throw new NetworkError(`API error: ${res.status} non-JSON response from ${path}`);\n }\n\n if (!res.ok && !data.ok && !data.already_initialized && !data.eligible) {\n throw mapApiError(res.status, data, path);\n }\n\n return data;\n } catch (err: any) {\n if (err.name === 'AbortError') {\n throw new NetworkError(`Request timeout: ${method} ${path}`, ErrorCode.TIMEOUT);\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private log(msg: string): void {\n if (this.config.verbose) {\n console.log(`[Beat] ${msg}`);\n }\n }\n}\n\n// ============ STANDALONE VDF HELPER ============\n// For agents that want to compute beats without the full SDK\n\nexport { computeBeat };\n\n/**\n * Compute N sequential VDF beats.\n * Returns only the last beat (for lightweight usage).\n */\nexport function computeBeatsLite(\n startHash: string,\n startIndex: number,\n count: number,\n difficulty: number = 1000,\n anchorHash?: string,\n): { lastBeat: Beat; elapsed: number } {\n // SDK-P2: validate inputs\n if (!startHash || typeof startHash !== 'string') {\n throw new ValidationError('computeBeatsLite: startHash must be a non-empty string');\n }\n if (!Number.isInteger(count) || count < 1) {\n throw new ValidationError('computeBeatsLite: count must be a positive integer');\n }\n\n const t0 = Date.now();\n let prev = startHash;\n let lastBeat: Beat | null = null;\n\n for (let i = 0; i < count; i++) {\n lastBeat = computeBeat(prev, startIndex + i, difficulty, undefined, anchorHash);\n prev = lastBeat.hash;\n }\n\n return { lastBeat: lastBeat!, elapsed: Date.now() - t0 };\n}\n","/**\n * Provenonce SDK Error Classes\n *\n * Typed error hierarchy for programmatic error handling.\n * All errors extend ProvenonceError for catch-all, or catch specific\n * subclasses for fine-grained control:\n *\n * try {\n * await agent.checkin();\n * } catch (err) {\n * if (err instanceof RateLimitError) {\n * await sleep(err.retryAfterMs);\n * } else if (err instanceof FrozenError) {\n * await agent.resync();\n * } else if (err instanceof AuthError) {\n * console.error('Bad API key');\n * }\n * }\n */\n\n/** Error codes for programmatic switching */\nexport enum ErrorCode {\n // Validation\n VALIDATION = 'VALIDATION',\n\n // Auth\n AUTH_INVALID = 'AUTH_INVALID',\n AUTH_MISSING = 'AUTH_MISSING',\n\n // Rate limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // Agent state\n AGENT_FROZEN = 'AGENT_FROZEN',\n AGENT_NOT_INITIALIZED = 'AGENT_NOT_INITIALIZED',\n AGENT_WRONG_STATE = 'AGENT_WRONG_STATE',\n\n // Not found\n NOT_FOUND = 'NOT_FOUND',\n\n // Network / server\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n SERVER_ERROR = 'SERVER_ERROR',\n}\n\n/** Base error class for all Provenonce SDK errors */\nexport class ProvenonceError extends Error {\n /** Machine-readable error code */\n readonly code: ErrorCode;\n\n /** HTTP status code (if from an API response) */\n readonly statusCode?: number;\n\n /** Additional context */\n readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ErrorCode,\n statusCode?: number,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ProvenonceError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n // Fix prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when input validation fails (bad config, invalid args) */\nexport class ValidationError extends ProvenonceError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, ErrorCode.VALIDATION, undefined, details);\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown on 401/403 — bad or missing API key */\nexport class AuthError extends ProvenonceError {\n constructor(\n message: string,\n code: ErrorCode.AUTH_INVALID | ErrorCode.AUTH_MISSING = ErrorCode.AUTH_INVALID,\n statusCode?: number,\n ) {\n super(message, code, statusCode);\n this.name = 'AuthError';\n }\n}\n\n/** Thrown on 429 — rate limit exceeded */\nexport class RateLimitError extends ProvenonceError {\n /** Milliseconds until the rate limit resets (if provided by server) */\n readonly retryAfterMs?: number;\n\n constructor(message: string, statusCode: number = 429, retryAfterMs?: number) {\n super(message, ErrorCode.RATE_LIMITED, statusCode);\n this.name = 'RateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** Thrown when an agent is frozen and cannot perform the requested action */\nexport class FrozenError extends ProvenonceError {\n constructor(message: string = 'Agent is frozen. Use resync() to re-establish provenance.') {\n super(message, ErrorCode.AGENT_FROZEN);\n this.name = 'FrozenError';\n }\n}\n\n/** Thrown when the agent is in the wrong state for the requested action */\nexport class StateError extends ProvenonceError {\n /** The agent's current state */\n readonly currentState: string;\n\n constructor(message: string, currentState: string, code: ErrorCode = ErrorCode.AGENT_WRONG_STATE) {\n super(message, code);\n this.name = 'StateError';\n this.currentState = currentState;\n }\n}\n\n/** Thrown on 404 — agent or resource not found */\nexport class NotFoundError extends ProvenonceError {\n constructor(message: string, statusCode: number = 404) {\n super(message, ErrorCode.NOT_FOUND, statusCode);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown on network failures — non-JSON responses, fetch errors, timeouts */\nexport class NetworkError extends ProvenonceError {\n constructor(message: string, code: ErrorCode.NETWORK_ERROR | ErrorCode.TIMEOUT = ErrorCode.NETWORK_ERROR) {\n super(message, code);\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown on 5xx — unexpected server errors */\nexport class ServerError extends ProvenonceError {\n constructor(message: string, statusCode: number = 500) {\n super(message, ErrorCode.SERVER_ERROR, statusCode);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Map an HTTP response + parsed body to the appropriate error class.\n * Used internally by the SDK to convert API failures to typed errors.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n\n if (statusCode === 401 || statusCode === 403) {\n const code = statusCode === 401 ? ErrorCode.AUTH_MISSING : ErrorCode.AUTH_INVALID;\n return new AuthError(msg, code, statusCode);\n }\n\n if (statusCode === 429) {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n\n if (statusCode === 404) {\n return new NotFoundError(msg, statusCode);\n }\n\n if (statusCode >= 500) {\n return new ServerError(msg, statusCode);\n }\n\n // Check for specific error patterns in the message\n const lowerMsg = msg.toLowerCase();\n if (lowerMsg.includes('frozen')) {\n return new FrozenError(msg);\n }\n\n // Generic client error\n return new ProvenonceError(msg, ErrorCode.SERVER_ERROR, statusCode);\n}\n"],"mappings":"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","names":["ErrorCode","res","data"]}
1
+ {"version":3,"sources":["../src/beat-sdk.ts","../src/errors.ts"],"sourcesContent":["/**\n * ═══════════════════════════════════════════════════════════\n * PROVENONCE BEAT SDK — Agent Heartbeat Client\n * ═══════════════════════════════════════════════════════════\n * \n * \"NIST tells you what time it is.\n * Provenonce tells the agent at what speed it is allowed to exist.\"\n * \n * Usage:\n * \n * import { BeatAgent } from './beat-sdk';\n * \n * const agent = new BeatAgent({\n * apiKey: 'pvn_...',\n * registryUrl: 'https://provenonce.io',\n * });\n * \n * await agent.init(); // Birth in Beat time\n * await agent.pulse(50); // Compute 50 beats\n * await agent.checkin(); // Report to registry\n * \n * // Or run the autonomous heartbeat:\n * agent.startHeartbeat(); // Computes + checks in continuously\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, generateKeyPairSync, sign, verify, createPrivateKey, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n mapApiError,\n ErrorCode,\n} from './errors';\n\n// ============ PHASE 2 TYPES ============\n\n/** SIGIL identity class — determines tier pricing and heartbeat volume caps */\nexport type IdentityClass = 'narrow_task' | 'autonomous' | 'orchestrator';\n\n/** SIGIL trust governance tier — orthogonal to identity_class (fee axis) */\nexport type SigilTier = 'sov' | 'org' | 'ind' | 'eph' | 'sbx';\n\n/** Substrate — what the agent runs on */\nexport type Substrate = 'frontier' | 'open' | 'local' | 'symbolic' | 'hybrid' | 'human';\n\n/** Substrate provider */\nexport type SubstrateProvider = 'anthropic' | 'openai' | 'google' | 'meta' | 'mistral' | 'xai' | 'cohere' | 'deepseek' | 'custom';\n\n/** Capability — what the agent primarily does */\nexport type Capability = 'analyst' | 'executor' | 'orchestrator' | 'guardian' | 'retriever' | 'renderer' | 'witness';\n\n/** Protocol — how to reach the agent */\nexport type SigilProtocol = 'http' | 'grpc' | 'websocket' | 'mcp' | 'a2a' | 'custom';\n\n/** Compliance regime */\nexport type ComplianceRegime = 'gdpr' | 'pdpa' | 'hipaa' | 'sox' | 'aisi' | 'none' | 'custom';\n\n/**\n * Ed25519-signed lineage proof — portable, offline-verifiable credential.\n * Also known as the agent's \"passport\" — a cryptographic proof of identity\n * that can be verified offline without any API call or SOL cost.\n */\nexport interface LineageProof {\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n issued_at: number;\n valid_until: number;\n provenonce_signature: string;\n}\n\n/** Passport = LineageProof. The agent's portable, offline-verifiable credential. */\nexport type Passport = LineageProof;\n\n/** Options for purchasing a SIGIL with full namespace */\nexport interface SigilPurchaseOptions {\n identity_class: IdentityClass;\n principal: string;\n tier: SigilTier;\n name?: string; // \"auto\" or custom name\n payment_tx: string;\n // Optional initial metadata\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Mutable SIGIL metadata fields for PATCH updates */\nexport interface SigilMutableFields {\n substrate?: Substrate;\n substrate_provider?: SubstrateProvider;\n substrate_model?: string;\n capability?: Capability;\n capability_scope?: string;\n generation_trigger?: string;\n tools?: string[];\n modality_input?: string[];\n modality_output?: string[];\n protocol?: SigilProtocol;\n endpoint?: string;\n compliance_regime?: ComplianceRegime;\n}\n\n/** Result from purchasing a SIGIL (Structured Identity Governance and Intelligent Lookup) */\nexport interface SigilResult {\n ok: boolean;\n sigil?: {\n sigil: string; // Full SIGIL string: name*principal*tier\n sigil_name: string;\n principal: string;\n tier: SigilTier;\n identity_class: IdentityClass;\n issued_at_beat: number;\n birth_tx: string | null;\n explorer_url: string | null;\n };\n lineage_proof?: LineageProof;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n/** Result from updating mutable SIGIL metadata */\nexport interface MetadataUpdateResult {\n ok: boolean;\n sigil?: string;\n generation?: number;\n updated_fields?: string[];\n error?: string;\n}\n\n/** Result from offline lineage proof verification */\nexport interface VerificationResult {\n /** Overall validity: signature is valid AND not expired */\n valid: boolean;\n /** Ed25519 signature verification passed */\n signatureValid: boolean;\n /** Proof has passed its valid_until timestamp */\n expired: boolean;\n /** The beat index of the agent's last heartbeat */\n lastHeartbeatBeat: number;\n /** Beats elapsed since last heartbeat (null if currentBeat not provided) */\n beatsSinceHeartbeat: number | null;\n /** Human-readable warning if proof is expired or stale */\n warning?: string;\n}\n\n/** Result from a paid heartbeat */\nexport interface HeartbeatResult {\n ok: boolean;\n lineage_proof?: LineageProof;\n heartbeat_count_epoch?: number;\n billing_epoch?: number;\n current_beat?: number;\n fee?: {\n amount_sol: number;\n amount_lamports: number;\n tier: number;\n payment_tx: string | null;\n };\n error?: string;\n}\n\n// ============ VDF ENGINE (LOCAL) ============\n\nexport interface Beat {\n index: number;\n hash: string;\n prev: string;\n timestamp: number;\n nonce?: string;\n anchor_hash?: string;\n}\n\nfunction computeBeat(prevHash: string, beatIndex: number, difficulty: number, nonce?: string, anchorHash?: string): Beat {\n const timestamp = Date.now();\n\n const seed = anchorHash\n ? `${prevHash}:${beatIndex}:${nonce || ''}:${anchorHash}`\n : `${prevHash}:${beatIndex}:${nonce || ''}`;\n\n let current = createHash('sha256')\n .update(seed)\n .digest('hex');\n\n for (let i = 0; i < difficulty; i++) {\n current = createHash('sha256')\n .update(current)\n .digest('hex');\n }\n\n return { index: beatIndex, hash: current, prev: prevHash, timestamp, nonce, anchor_hash: anchorHash };\n}\n\n// ============ V3 ANCHOR HASH VERIFICATION ============\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\nfunction base58DecodeToBuffer(str: string): Buffer {\n const map: Record<string, number> = {};\n for (let i = 0; i < BASE58_ALPHABET.length; i++) map[BASE58_ALPHABET[i]] = i;\n let bytes = [0];\n for (let i = 0; i < str.length; i++) {\n const val = map[str[i]];\n if (val === undefined) throw new Error('invalid base58 character');\n let carry = val;\n for (let j = 0; j < bytes.length; j++) {\n const x = bytes[j] * 58 + carry;\n bytes[j] = x & 0xff;\n carry = x >> 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n for (let i = 0; i < str.length && str[i] === '1'; i++) bytes.push(0);\n return Buffer.from(bytes.reverse());\n}\n\nfunction u64be(n: number): Buffer {\n const buf = Buffer.alloc(8);\n buf.writeUInt32BE(Math.floor(n / 0x100000000), 0);\n buf.writeUInt32BE(n >>> 0, 4);\n return buf;\n}\n\nconst ANCHOR_DOMAIN_PREFIX = 'PROVENONCE_BEATS_V1';\n\n/**\n * Verify an anchor hash locally.\n * V3 (solana_entropy present): binary-canonical single SHA-256.\n * V1 legacy (no entropy): string-based hash with difficulty iteration.\n */\nexport function verifyAnchorHash(anchor: { prev_hash: string; beat_index: number; hash: string; utc: number; epoch: number; difficulty: number; solana_entropy?: string }): boolean {\n if (!anchor || !anchor.hash || !anchor.prev_hash) return false;\n\n if (anchor.solana_entropy) {\n // V3: binary-canonical single SHA-256\n const prefix = Buffer.from(ANCHOR_DOMAIN_PREFIX, 'utf8');\n const prev = Buffer.from(anchor.prev_hash, 'hex');\n const idx = u64be(anchor.beat_index);\n const entropy = base58DecodeToBuffer(anchor.solana_entropy);\n const preimage = Buffer.concat([prefix, prev, idx, entropy]);\n const computed = createHash('sha256').update(preimage).digest('hex');\n return computed === anchor.hash;\n }\n\n // V1 legacy: string-based hash with difficulty iteration\n const nonce = `anchor:${anchor.utc}:${anchor.epoch}`;\n const seed = `${anchor.prev_hash}:${anchor.beat_index}:${nonce}`;\n let current = createHash('sha256').update(seed).digest('hex');\n for (let i = 0; i < anchor.difficulty; i++) {\n current = createHash('sha256').update(current).digest('hex');\n }\n return current === anchor.hash;\n}\n\n// ============ SDK RESULT TYPES ============\n\n/** Result from a check-in submission */\nexport interface CheckinResult {\n ok: boolean;\n total_beats: number;\n beats_accepted: number;\n global_beat: number;\n status?: string;\n beats_behind?: number;\n}\n\n/** Result from a spawn request */\nexport interface SpawnResult {\n ok: boolean;\n eligible: boolean;\n child_hash?: string;\n progress_pct?: number;\n deficit?: number;\n}\n\n/** Agent status from the registry */\nexport interface AgentStatus {\n already_initialized: boolean;\n total_beats: number;\n genesis_hash: string;\n status: string;\n genesis?: { hash: string; prev: string; timestamp: number };\n difficulty?: number;\n}\n\n// ============ WALLET KEYPAIR GENERATION ============\n\n// DER prefix for Ed25519 PKCS8 private keys (16 bytes)\nconst ED25519_PKCS8_PREFIX = Buffer.from('302e020100300506032b657004220420', 'hex');\n\n/**\n * Generate an Ed25519 keypair for agent wallet identity.\n * Returns hex-encoded raw keys (32 bytes each).\n * Uses Node.js built-in crypto — zero external dependencies.\n */\nexport function generateWalletKeypair(): { publicKey: string; secretKey: string } {\n const { publicKey, privateKey } = generateKeyPairSync('ed25519');\n const pubRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(12); // 32 bytes\n const privRaw = privateKey.export({ type: 'pkcs8', format: 'der' }).subarray(16); // 32 bytes\n return {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: Buffer.from(privRaw).toString('hex'),\n };\n}\n\n/**\n * Sign a message with an Ed25519 private key (hex-encoded 32-byte seed).\n * Returns hex-encoded signature (64 bytes).\n */\nfunction signMessage(secretKeyHex: string, message: string): string {\n const privRaw = Buffer.from(secretKeyHex, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const sig = sign(null, Buffer.from(message), keyObject);\n return Buffer.from(sig).toString('hex');\n}\n\n// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\n /** Hex-encoded 32-byte Ed25519 public key (Solana self-custody only, empty otherwise) */\n public_key: string;\n /** Hex-encoded 32-byte Ed25519 secret seed — SAVE THIS for future fee signing (Solana self-custody only) */\n secret_key: string;\n /** Solana-compatible base58 address (Solana wallets only) */\n solana_address?: string;\n /** The wallet address (base58 for Solana, 0x for Ethereum) */\n address: string;\n /** Wallet chain: 'solana' or 'ethereum' */\n chain: string;\n}\n\n/** Result from registering an agent */\nexport interface RegistrationResult {\n hash: string;\n api_key: string;\n secret: string;\n type: 'root' | 'agent';\n parent: string | null;\n depth: number;\n name: string;\n metadata?: Record<string, unknown> | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n signature?: string | null;\n /** @deprecated No Solana write at registration (D-65). Will be null. */\n explorer_url?: string | null;\n /** Wallet chain: 'solana', 'ethereum', or null (no wallet) */\n wallet_chain?: string | null;\n beat?: { genesis_hash: string; difficulty: number; status: string };\n /** Wallet info — only present for root agents with wallets */\n wallet?: WalletInfo;\n /** Next steps after registration */\n _next_steps?: { sigil?: string; heartbeat?: string };\n}\n\n/** Options for the register() function */\nexport interface RegisterOptions {\n registryUrl?: string;\n parentHash?: string;\n parentApiKey?: string;\n registrationSecret?: string;\n /** Single-use registration token from POST /register/token or POST /register/email/verify */\n registrationToken?: string;\n /** Admin-minted invite token */\n registrationInvite?: string;\n /** Hex-encoded 32-byte Ed25519 secret seed (bring-your-own Solana key) */\n walletSecretKey?: string;\n /** Wallet model: 'self-custody' (Model A) or 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: 'self-custody' | 'operator';\n /** Wallet chain: 'solana' (default when wallet is used) or 'ethereum' (D-63) */\n walletChain?: 'solana' | 'ethereum';\n /** Wallet address for Ethereum bring-your-own (0x + 40 hex chars) */\n walletAddress?: string;\n /** Async function to sign a message with an Ethereum wallet (EIP-191 personal_sign). Returns 0x-prefixed 65-byte hex sig. */\n walletSignFn?: (message: string) => Promise<string>;\n /** Operator's Solana wallet address (base58). Required when walletModel='operator'. */\n operatorWalletAddress?: string;\n /** Function to sign a message with the operator's Solana wallet. Required when walletModel='operator'. */\n operatorSignFn?: (message: string) => Promise<string>;\n /** Optional agent metadata (arbitrary JSON object, max 4KB). Returned in /verify and /status. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Register a new agent on the Provenonce registry.\n *\n * With registration token (from /register/token or email verification):\n * const creds = await register('my-agent', {\n * registryUrl: '...',\n * registrationToken: '<token-from-email-verify>',\n * });\n *\n * No wallet (default, single-phase):\n * const creds = await register('my-agent', { registryUrl: '...' });\n *\n * Solana self-custody wallet (Model A, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'self-custody',\n * });\n * // creds.wallet.secret_key = hex secret (SAVE THIS)\n * // creds.wallet.address = base58 Solana address\n *\n * Solana with existing key:\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletSecretKey: '<hex-encoded-32-byte-seed>',\n * });\n *\n * Ethereum bring-your-own (two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletChain: 'ethereum',\n * walletAddress: '0x...',\n * walletSignFn: (msg) => wallet.signMessage(msg),\n * });\n *\n * Solana operator (Model B, two-phase):\n * const creds = await register('my-org', {\n * registryUrl: '...',\n * walletModel: 'operator',\n * operatorWalletAddress: '<base58>',\n * operatorSignFn: (msg) => signWithWallet(msg),\n * });\n *\n * Child agent (no wallet):\n * const creds = await register('worker-1', {\n * registryUrl: '...',\n * parentHash: parentCreds.hash,\n * parentApiKey: parentCreds.api_key,\n * });\n */\nexport async function register(\n name: string,\n options?: RegisterOptions,\n): Promise<RegistrationResult> {\n // SDK-P1-07/P1-08: validate inputs\n if (!name || typeof name !== 'string' || name.trim().length === 0) {\n throw new ValidationError('name is required (must be a non-empty string)');\n }\n if (name.length > 64) {\n throw new ValidationError('name must be 64 characters or fewer');\n }\n\n const url = options?.registryUrl || 'https://provenonce.io';\n try {\n new URL(url);\n } catch {\n throw new ValidationError('registryUrl is not a valid URL');\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\n if (options?.registrationSecret) {\n headers['x-registration-secret'] = options.registrationSecret;\n }\n if (options?.registrationToken) {\n headers['x-registration-token'] = options.registrationToken;\n }\n if (options?.registrationInvite) {\n headers['x-registration-invite'] = options.registrationInvite;\n }\n\n // ===== CHILD REGISTRATION (no wallet, single-phase) =====\n if (options?.parentHash) {\n if (options.parentApiKey) {\n headers['Authorization'] = `Bearer ${options.parentApiKey}`;\n }\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, parent: options.parentHash, ...(options.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n }\n\n // ===== ETHEREUM BRING-YOUR-OWN (D-63, two-phase) =====\n if (options?.walletChain === 'ethereum') {\n if (!options.walletAddress || !options.walletSignFn) {\n throw new ValidationError('Ethereum registration requires walletAddress and walletSignFn');\n }\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(options.walletAddress)) {\n throw new ValidationError('walletAddress must be a valid Ethereum address (0x + 40 hex chars)');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_chain: 'ethereum' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Sign with Ethereum wallet (EIP-191 personal_sign)\n const nonce = challengeData.nonce;\n const message = `provenonce-register-ethereum:${nonce}:${options.walletAddress}:${name}`;\n const walletSignature = await options.walletSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_chain: 'ethereum',\n wallet_address: options.walletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; chain?: string } };\n } catch {\n throw new NetworkError(`Ethereum registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Ethereum: wallet has address only (no keypair — user keeps custody externally)\n data.wallet = {\n public_key: '',\n secret_key: '',\n address: data.wallet?.address || options.walletAddress,\n chain: 'ethereum',\n };\n\n return data;\n }\n\n // ===== MODEL B: SOLANA OPERATOR WALLET REGISTRATION (two-phase) =====\n if (options?.walletModel === 'operator') {\n if (!options.operatorWalletAddress || !options.operatorSignFn) {\n throw new ValidationError('Operator registration requires operatorWalletAddress and operatorSignFn');\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge', wallet_model: 'operator' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n throw new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n throw mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n }\n\n // Phase 2: Operator signs challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register-operator:${nonce}:${options.operatorWalletAddress}:${name}`;\n const walletSignature = await options.operatorSignFn(message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_model: 'operator',\n operator_wallet_address: options.operatorWalletAddress,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n throw new NetworkError(`Operator registration failed: ${registerRes.status} (non-JSON response)`);\n }\n if (!registerRes.ok) throw mapApiError(registerRes.status, data, '/api/v1/register');\n\n // Model B: wallet has address only (no secret_key/public_key — operator keeps custody)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\n public_key: '',\n secret_key: '',\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== MODEL A: SOLANA SELF-CUSTODY WALLET REGISTRATION (opt-in, two-phase) =====\n if (options?.walletModel === 'self-custody' || options?.walletSecretKey) {\n // Generate or use provided wallet keypair\n let walletKeys: { publicKey: string; secretKey: string };\n if (options?.walletSecretKey) {\n // Derive public key from provided secret\n const privRaw = Buffer.from(options.walletSecretKey, 'hex');\n const privKeyDer = Buffer.concat([ED25519_PKCS8_PREFIX, privRaw]);\n const keyObject = createPrivateKey({ key: privKeyDer, format: 'der', type: 'pkcs8' });\n const pubRaw = keyObject.export({ type: 'spki', format: 'der' }).subarray(12);\n walletKeys = {\n publicKey: Buffer.from(pubRaw).toString('hex'),\n secretKey: options.walletSecretKey,\n };\n } else {\n walletKeys = generateWalletKeypair();\n }\n\n // Phase 1: Get challenge nonce from server\n const challengeRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, action: 'challenge' }),\n });\n\n let challengeData: { nonce?: string; error?: string };\n try {\n challengeData = await challengeRes.json() as { nonce?: string; error?: string };\n } catch {\n const err = new NetworkError(`Registration challenge failed: ${challengeRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!challengeRes.ok || !challengeData.nonce) {\n // Attach wallet keys so caller can retry with the same keypair\n const err = mapApiError(challengeRes.status, challengeData, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Phase 2: Sign challenge and register\n const nonce = challengeData.nonce;\n const message = `provenonce-register:${nonce}:${walletKeys.publicKey}:${name}`;\n const walletSignature = signMessage(walletKeys.secretKey, message);\n\n const registerRes = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name,\n wallet_public_key: walletKeys.publicKey,\n wallet_signature: walletSignature,\n wallet_nonce: nonce,\n ...(options?.metadata && { metadata: options.metadata }),\n }),\n });\n\n let data: RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n try {\n data = await registerRes.json() as RegistrationResult & { error?: string; wallet?: { address?: string; solana_address?: string } };\n } catch {\n // Attach wallet keys so caller can retry with the same keypair\n const err = new NetworkError(`Registration failed: ${registerRes.status} (non-JSON response)`);\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n if (!registerRes.ok) {\n // Attach wallet keys so caller can retry with the same keypair via walletSecretKey option\n const err = mapApiError(registerRes.status, data, '/api/v1/register');\n (err as any).walletKeys = { publicKey: walletKeys.publicKey, secretKey: walletKeys.secretKey };\n throw err;\n }\n\n // Attach the wallet keys (secret is client-side only, never sent to server)\n const addr = data.wallet?.address || data.wallet?.solana_address || '';\n data.wallet = {\n public_key: walletKeys.publicKey,\n secret_key: walletKeys.secretKey,\n solana_address: addr,\n address: addr,\n chain: 'solana',\n };\n\n return data;\n }\n\n // ===== NO-WALLET REGISTRATION (D-62 default, single-phase) =====\n\n const res = await fetch(`${url}/api/v1/register`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name, ...(options?.metadata && { metadata: options.metadata }) }),\n });\n\n let data: RegistrationResult & { error?: string };\n try {\n data = await res.json() as RegistrationResult & { error?: string };\n } catch {\n throw new NetworkError(`Registration failed: ${res.status} ${res.statusText} (non-JSON response)`);\n }\n if (!res.ok) throw mapApiError(res.status, data, '/api/v1/register');\n return data;\n}\n\n// ============ SDK CONFIG ============\n\nexport interface BeatAgentConfig {\n /** API key from registration (pvn_...) */\n apiKey: string;\n\n /** Provenonce registry URL */\n registryUrl: string;\n\n /** @deprecated Use heartbeatIntervalSec. Beats to compute per pulse (default: 10) */\n beatsPerPulse?: number;\n\n /** @deprecated Use heartbeatIntervalSec. Seconds between automatic check-ins (default: 300 = 5min) */\n checkinIntervalSec?: number;\n\n /** Seconds between automatic heartbeats (default: 300 = 5min). Replaces checkinIntervalSec. */\n heartbeatIntervalSec?: number;\n\n /** @deprecated VDF pulse callback. No longer used in Phase 2. */\n onPulse?: (beats: Beat[], totalBeats: number) => void;\n\n /** @deprecated Use onHeartbeat. Callback when check-in completes. */\n onCheckin?: (result: CheckinResult) => void;\n\n /** Callback when heartbeat completes (Phase 2) */\n onHeartbeat?: (result: HeartbeatResult) => void;\n\n /** Callback on error */\n onError?: (error: Error, context: string) => void;\n\n /** Callback when status changes */\n onStatusChange?: (status: string, details: Record<string, unknown>) => void;\n\n /** Enable verbose logging */\n verbose?: boolean;\n\n /** Verify anchor hash locally before trusting it (default: true). */\n verifyAnchors?: boolean;\n}\n\n// ============ BEAT AGENT ============\n\nexport class BeatAgent {\n private config: Required<BeatAgentConfig>;\n private chain: Beat[] = [];\n private difficulty: number = 1000;\n private genesisHash: string = '';\n private latestBeat: Beat | null = null;\n private totalBeats: number = 0;\n private lastCheckinBeat: number = 0;\n private status: 'uninitialized' | 'active' | 'frozen' | 'revoked' = 'uninitialized';\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private globalBeat: number = 0;\n private globalAnchorHash: string = '';\n\n constructor(config: BeatAgentConfig) {\n // SDK-P1-08: validate required config fields\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new ValidationError('BeatAgentConfig.apiKey is required (must be a non-empty string)');\n }\n if (!config.registryUrl || typeof config.registryUrl !== 'string') {\n throw new ValidationError('BeatAgentConfig.registryUrl is required (must be a non-empty string)');\n }\n // SDK-P1-07: validate registryUrl is a valid URL\n try {\n new URL(config.registryUrl);\n } catch {\n throw new ValidationError('BeatAgentConfig.registryUrl is not a valid URL');\n }\n\n // SDK-P2: validate optional numeric config\n if (config.beatsPerPulse !== undefined && (!Number.isInteger(config.beatsPerPulse) || config.beatsPerPulse < 1 || config.beatsPerPulse > 10000)) {\n throw new ValidationError('BeatAgentConfig.beatsPerPulse must be an integer between 1 and 10000');\n }\n if (config.checkinIntervalSec !== undefined && (!Number.isFinite(config.checkinIntervalSec) || config.checkinIntervalSec < 10 || config.checkinIntervalSec > 86400)) {\n throw new ValidationError('BeatAgentConfig.checkinIntervalSec must be between 10 and 86400');\n }\n\n this.config = {\n beatsPerPulse: 10,\n checkinIntervalSec: 300,\n heartbeatIntervalSec: 300,\n onPulse: () => {},\n onCheckin: () => {},\n onHeartbeat: () => {},\n onError: () => {},\n onStatusChange: () => {},\n verbose: false,\n verifyAnchors: true,\n ...config,\n };\n }\n\n // ── INITIALIZATION ──\n\n /**\n * Initialize the agent's Beat chain.\n * This is the agent's \"birth\" in Logical Time.\n * Must be called once before computing beats.\n */\n async init(): Promise<{ ok: boolean; genesis?: string; error?: string }> {\n try {\n this.log('Initializing Beat chain...');\n\n const res = await this.api('POST', '/api/v1/agent/init');\n\n if (res.genesis) {\n this.genesisHash = res.genesis.hash;\n this.difficulty = res.difficulty || 1000;\n this.latestBeat = {\n index: 0,\n hash: res.genesis.hash,\n prev: res.genesis.prev,\n timestamp: res.genesis.timestamp,\n };\n this.chain = [this.latestBeat];\n this.totalBeats = 0;\n this.status = 'active';\n this.config.onStatusChange('active', { genesis: this.genesisHash });\n this.log(`Born in Beat time. Genesis: ${this.genesisHash.slice(0, 16)}...`);\n } else if (res.already_initialized) {\n // Restore from existing state\n this.genesisHash = res.genesis_hash;\n this.totalBeats = res.total_beats;\n this.status = res.status as any;\n this.log(`Already initialized. Restoring state (${res.total_beats} beats).`);\n \n // Fetch full state to get latest hash\n await this.refreshState();\n }\n\n // Sync global anchor\n await this.syncGlobal();\n\n return { ok: true, genesis: this.genesisHash };\n\n } catch (err: any) {\n this.config.onError(err, 'init');\n return { ok: false, error: err.message };\n }\n }\n\n // ── PULSE (COMPUTE BEATS) ──\n\n /**\n * @deprecated Phase 2: VDF computation retired (D-68). Payment is the liveness mechanism.\n * Use heartbeat() instead. This method will be removed in the next major version.\n *\n * Compute N beats locally (VDF hash chain).\n */\n pulse(count?: number): Beat[] {\n console.warn('[Provenonce SDK] pulse() is deprecated. Use heartbeat() instead (Phase 2).');\n if (this.status === 'frozen') {\n throw new FrozenError('Cannot pulse: agent is frozen. Use resync() to re-establish provenance.');\n }\n if (this.status !== 'active') {\n throw new StateError(`Cannot pulse: agent is ${this.status}.`, this.status);\n }\n // SDK-P2: validate count param\n if (count !== undefined && (!Number.isInteger(count) || count < 1 || count > 10000)) {\n throw new ValidationError('pulse count must be an integer between 1 and 10000');\n }\n return this.computeBeats(count);\n }\n\n /** Internal beat computation — no status check. Used by both pulse() and resync(). */\n private computeBeats(count?: number, onProgress?: (computed: number, total: number) => void): Beat[] {\n const n = count || this.config.beatsPerPulse;\n\n if (!this.latestBeat) {\n throw new StateError('Beat chain not initialized. Call init() first.', 'uninitialized', ErrorCode.AGENT_NOT_INITIALIZED);\n }\n\n const newBeats: Beat[] = [];\n let prevHash = this.latestBeat.hash;\n let startIndex = this.latestBeat.index + 1;\n\n const t0 = Date.now();\n // SDK-P2: report progress every 10% of beats\n const progressInterval = Math.max(1, Math.floor(n / 10));\n\n for (let i = 0; i < n; i++) {\n const beat = computeBeat(prevHash, startIndex + i, this.difficulty, undefined, this.globalAnchorHash || undefined);\n newBeats.push(beat);\n prevHash = beat.hash;\n if (onProgress && (i + 1) % progressInterval === 0) {\n onProgress(i + 1, n);\n }\n }\n\n const elapsed = Date.now() - t0;\n\n // Update state\n this.chain.push(...newBeats);\n this.latestBeat = newBeats[newBeats.length - 1];\n this.totalBeats += n;\n\n // Keep chain bounded (only last 1000 beats in memory)\n if (this.chain.length > 1000) {\n this.chain = this.chain.slice(-500);\n }\n\n this.config.onPulse(newBeats, this.totalBeats);\n this.log(`Pulse: ${n} beats in ${elapsed}ms (${(elapsed / n).toFixed(1)}ms/beat, D=${this.difficulty})`);\n\n return newBeats;\n }\n\n // ── CHECK-IN ──\n\n /**\n * @deprecated Phase 2: VDF check-in retired (D-68). Use heartbeat() instead.\n * This method will be removed in the next major version.\n */\n async checkin(): Promise<{ ok: boolean; total_beats?: number; error?: string }> {\n console.warn('[Provenonce SDK] checkin() is deprecated. Use heartbeat() instead (Phase 2).');\n // SDK-P1-02: fix guard to compare beat indices, not totalBeats vs lastCheckinBeat\n if (!this.latestBeat || this.latestBeat.index <= this.lastCheckinBeat) {\n this.log('No new beats since last check-in. Call pulse() first.');\n return { ok: true, total_beats: this.totalBeats }; // Nothing new to report\n }\n\n try {\n // Find the boundary hashes\n const fromBeat = this.lastCheckinBeat;\n const toBeat = this.latestBeat.index;\n\n // Build spot checks from our local chain\n // prev and nonce are required for the server to recompute VDF\n // Must always include to_beat (final beat) — server requires it for final hash verification\n const spotChecks: { index: number; hash: string; prev: string; nonce?: string }[] = [];\n\n // Always include the final beat\n const toBeatEntry = this.chain.find(b => b.index === toBeat);\n if (toBeatEntry) {\n spotChecks.push({ index: toBeatEntry.index, hash: toBeatEntry.hash, prev: toBeatEntry.prev, nonce: toBeatEntry.nonce });\n }\n\n // Sample up to 4 more from the rest\n const available = this.chain.filter(b => b.index > this.lastCheckinBeat && b.index !== toBeat);\n const sampleCount = Math.min(4, available.length);\n\n for (let i = 0; i < sampleCount; i++) {\n const idx = Math.floor(Math.random() * available.length);\n const beat = available[idx];\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev, nonce: beat.nonce });\n available.splice(idx, 1);\n }\n const fromHash = this.chain.find(b => b.index === fromBeat)?.hash \n || this.genesisHash;\n const toHash = this.latestBeat.hash;\n\n const res = await this.api('POST', '/api/v1/agent/checkin', {\n proof: {\n from_beat: fromBeat,\n to_beat: toBeat,\n from_hash: fromHash,\n to_hash: toHash,\n beats_computed: toBeat - fromBeat,\n global_anchor: this.globalBeat,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: spotChecks,\n },\n });\n\n if (res.ok) {\n this.lastCheckinBeat = toBeat;\n this.totalBeats = res.total_beats;\n this.config.onCheckin(res);\n this.log(`Check-in accepted: ${res.beats_accepted} beats, total=${res.total_beats}, global=${res.global_beat}`);\n \n if (res.status === 'warning_overdue') {\n this.config.onStatusChange('warning', { beats_behind: res.beats_behind });\n this.log(`⚠ WARNING: ${res.beats_behind} anchors behind. Check in more frequently.`);\n }\n }\n\n return { ok: res.ok, total_beats: res.total_beats };\n\n } catch (err: any) {\n this.config.onError(err, 'checkin');\n return { ok: false, error: err.message };\n }\n }\n\n // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Optional function that returns a payment tx for each heartbeat.\n * If not provided, uses 'devnet-skip' (devnet only).\n */\n startHeartbeat(paymentTxFn?: () => Promise<string> | string): void {\n if (this.heartbeatInterval) {\n this.log('Heartbeat already running.');\n return;\n }\n\n if (this.status !== 'active' && this.status !== 'uninitialized') {\n throw new StateError(`Cannot start heartbeat in status '${this.status}'.`, this.status);\n }\n\n const intervalSec = this.config.heartbeatIntervalSec || this.config.checkinIntervalSec || 300;\n this.log(`Starting heartbeat (interval: ${intervalSec}s)...`);\n\n // SDK-P1-03: exponential backoff on consecutive errors\n let consecutiveErrors = 0;\n let skipCount = 0;\n\n this.heartbeatInterval = setInterval(async () => {\n if (skipCount > 0) {\n skipCount--;\n return;\n }\n\n try {\n const paymentTx = paymentTxFn ? await paymentTxFn() : 'devnet-skip';\n await this.heartbeat(paymentTx);\n consecutiveErrors = 0;\n } catch (err: any) {\n consecutiveErrors++;\n this.config.onError(err, 'heartbeat');\n skipCount = Math.min(32, Math.pow(2, consecutiveErrors - 1));\n this.log(`Heartbeat error #${consecutiveErrors}, backing off ${skipCount} ticks`);\n }\n }, intervalSec * 1000);\n }\n\n /**\n * Stop the heartbeat loop.\n */\n stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n this.log('Heartbeat stopped.');\n }\n }\n\n // ── RE-SYNC ──\n\n /**\n * @deprecated Phase 2: Resync retired (D-67). Dormancy resume is free — just call heartbeat().\n * This method will be removed in the next major version.\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n console.warn('[Provenonce SDK] resync() is deprecated (D-67). Use heartbeat() to resume (Phase 2).');\n try {\n this.log('Requesting re-sync challenge...');\n\n // Phase 1: Get challenge\n const challenge = await this.api('POST', '/api/v1/agent/resync', {\n action: 'challenge',\n });\n\n if (!challenge.challenge) {\n return { ok: false, error: 'Failed to get challenge' };\n }\n\n const required = challenge.challenge.required_beats;\n this.difficulty = challenge.challenge.difficulty;\n this.log(`Re-sync challenge: compute ${required} beats at D=${this.difficulty}`);\n\n // Sync global anchor so beats are woven with a recent anchor hash\n await this.syncGlobal();\n\n // Compute the required beats\n const startHash = challenge.challenge.start_from_hash;\n const startBeat = challenge.challenge.start_from_beat;\n\n // Reset chain from the known point\n this.latestBeat = { index: startBeat, hash: startHash, prev: '', timestamp: Date.now() };\n this.chain = [this.latestBeat];\n\n const t0 = Date.now();\n this.computeBeats(required);\n const elapsed = Date.now() - t0;\n this.log(`Re-sync beats computed in ${elapsed}ms`);\n\n // Phase 2: Submit proof (include challenge_nonce for server verification)\n const proof = await this.api('POST', '/api/v1/agent/resync', {\n action: 'prove',\n challenge_nonce: challenge.challenge.nonce,\n proof: {\n from_beat: startBeat,\n to_beat: this.latestBeat!.index,\n from_hash: startHash,\n to_hash: this.latestBeat!.hash,\n beats_computed: required,\n global_anchor: challenge.challenge.sync_to_global,\n anchor_hash: this.globalAnchorHash || undefined,\n spot_checks: (() => {\n // Must include to_beat (final beat) — server requires it for final hash verification\n const toBeatEntry = this.chain.find(b => b.index === this.latestBeat!.index);\n // Sample from available chain beats (chain may be trimmed to 500 entries)\n const available = this.chain\n .filter(b => b.index !== this.latestBeat!.index && b.index > startBeat);\n const step = Math.max(1, Math.ceil(available.length / 5));\n const others = available\n .filter((_, i) => i % step === 0)\n .slice(0, 4);\n const checks = toBeatEntry ? [toBeatEntry, ...others] : others;\n return checks.map(b => ({ index: b.index, hash: b.hash, prev: b.prev, nonce: b.nonce }));\n })(),\n },\n });\n\n if (proof.ok) {\n this.status = 'active';\n this.totalBeats = proof.total_beats;\n this.lastCheckinBeat = this.latestBeat!.index;\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced. Agent is alive again in Beat time.');\n }\n\n return { ok: proof.ok, beats_required: required };\n\n } catch (err: any) {\n this.config.onError(err, 'resync');\n return { ok: false, error: err.message };\n }\n }\n\n // ── SPAWN ──\n\n /**\n * Request to spawn a child agent.\n * Requires sufficient accumulated beats (Temporal Gestation).\n */\n async requestSpawn(childName?: string, childHash?: string): Promise<SpawnResult> {\n try {\n // SDK-P1-05: validate childName\n if (childName !== undefined) {\n if (typeof childName !== 'string' || childName.trim().length === 0) {\n throw new ValidationError('childName must be a non-empty string');\n }\n if (childName.length > 64) {\n throw new ValidationError('childName must be 64 characters or fewer');\n }\n }\n\n const res = await this.api('POST', '/api/v1/agent/spawn', {\n child_name: childName,\n child_hash: childHash,\n });\n\n if (res.eligible === false) {\n this.log(`Gestation incomplete: ${res.progress_pct}% (need ${res.deficit} more beats)`);\n } else if (res.ok) {\n this.log(`Child spawned: ${res.child_hash?.slice(0, 16)}...`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached lineage proof from the most recent heartbeat or SIGIL purchase */\n private cachedProof: LineageProof | null = null;\n\n /**\n * Purchase a SIGIL (cryptographic identity) for this agent.\n * SIGILs gate heartbeating, lineage proofs, and offline verification.\n * One-time purchase — cannot be re-purchased.\n *\n * @param options - SIGIL purchase options (identity_class, principal, tier, name, payment_tx, + optional metadata)\n *\n * Legacy signature (deprecated):\n * @param identityClass - 'narrow_task' | 'autonomous' | 'orchestrator'\n * @param paymentTx - Solana transaction signature or 'devnet-skip'\n */\n async purchaseSigil(optionsOrClass: SigilPurchaseOptions | IdentityClass, paymentTx?: string): Promise<SigilResult> {\n let body: Record<string, unknown>;\n\n if (typeof optionsOrClass === 'string') {\n // Legacy signature: purchaseSigil(identityClass, paymentTx)\n if (!optionsOrClass || !['narrow_task', 'autonomous', 'orchestrator'].includes(optionsOrClass)) {\n throw new ValidationError('identityClass must be narrow_task, autonomous, or orchestrator');\n }\n if (!paymentTx || typeof paymentTx !== 'string') {\n throw new ValidationError('paymentTx is required (Solana transaction signature or \"devnet-skip\")');\n }\n body = {\n identity_class: optionsOrClass,\n payment_tx: paymentTx,\n // Legacy calls without principal/tier — server will require these now\n // Callers must migrate to the options object form\n };\n } else {\n // New signature: purchaseSigil(options)\n const opts = optionsOrClass;\n if (!opts.identity_class || !['narrow_task', 'autonomous', 'orchestrator'].includes(opts.identity_class)) {\n throw new ValidationError('identity_class must be narrow_task, autonomous, or orchestrator');\n }\n if (!opts.principal || typeof opts.principal !== 'string') {\n throw new ValidationError('principal is required');\n }\n if (!opts.tier || !['sov', 'org', 'ind', 'eph', 'sbx'].includes(opts.tier)) {\n throw new ValidationError('tier must be one of: sov, org, ind, eph, sbx');\n }\n if (!opts.payment_tx || typeof opts.payment_tx !== 'string') {\n throw new ValidationError('payment_tx is required');\n }\n\n body = { ...opts };\n }\n\n try {\n const res = await this.api('POST', '/api/v1/sigil', body);\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.log(`SIGIL purchased: ${sigilStr}`);\n this.config.onStatusChange('sigil_issued', { sigil: sigilStr });\n\n return {\n ok: true,\n sigil: res.sigil,\n lineage_proof: res.lineage_proof,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'purchaseSigil');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Update mutable SIGIL metadata fields.\n * Requires a SIGIL. Cannot modify immutable fields.\n *\n * @param fields - Subset of mutable SIGIL fields to update\n */\n async updateMetadata(fields: Partial<SigilMutableFields>): Promise<MetadataUpdateResult> {\n if (!fields || Object.keys(fields).length === 0) {\n throw new ValidationError('At least one metadata field is required');\n }\n\n try {\n const res = await this.api('PATCH', '/api/v1/agent/metadata', fields);\n this.log(`Metadata updated: ${res.updated_fields?.join(', ') || 'unknown'}`);\n return {\n ok: true,\n sigil: res.sigil,\n generation: res.generation,\n updated_fields: res.updated_fields,\n };\n } catch (err: any) {\n this.config.onError(err, 'updateMetadata');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Send a paid heartbeat to the registry.\n * Requires a SIGIL. Returns a signed lineage proof.\n * This is the Phase 2 replacement for pulse() + checkin().\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx?: string, globalAnchor?: number): Promise<HeartbeatResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/heartbeat', {\n payment_tx: paymentTx || 'devnet-skip',\n global_anchor: globalAnchor,\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n if (res.ok) {\n this.status = 'active';\n const onHb = this.config.onHeartbeat || this.config.onCheckin;\n if (onHb) onHb(res);\n this.log(`Heartbeat accepted: epoch=${res.billing_epoch}, count=${res.heartbeat_count_epoch}`);\n }\n\n return {\n ok: res.ok,\n lineage_proof: res.lineage_proof,\n heartbeat_count_epoch: res.heartbeat_count_epoch,\n billing_epoch: res.billing_epoch,\n current_beat: res.current_beat,\n fee: res.fee,\n };\n } catch (err: any) {\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a lineage proof. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature. Omit or 'devnet-skip' on devnet.\n */\n async reissueProof(paymentTx?: string): Promise<{ ok: boolean; lineage_proof?: LineageProof; error?: string }> {\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx || 'devnet-skip',\n });\n\n if (res.lineage_proof) {\n this.cachedProof = res.lineage_proof;\n }\n\n return { ok: true, lineage_proof: res.lineage_proof };\n } catch (err: any) {\n this.config.onError(err, 'reissueProof');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached lineage proof (no network call).\n * Returns null if no proof has been obtained yet.\n */\n getLatestProof(): LineageProof | null {\n return this.cachedProof;\n }\n\n /**\n * Get the agent's passport (alias for getLatestProof).\n * The passport is the agent's portable, offline-verifiable credential.\n * Returns null if no passport has been issued yet (requires SIGIL + heartbeat).\n */\n getPassport(): Passport | null {\n return this.cachedProof;\n }\n\n /**\n * Verify a lineage proof locally using the authority public key.\n * Offline verification — no API call, no SOL cost.\n *\n * Returns a VerificationResult object. The object is truthy when valid,\n * so `if (BeatAgent.verifyProofLocally(proof, key))` still works.\n *\n * @param proof - The LineageProof to verify\n * @param authorityPubKeyHex - 32-byte hex-encoded Ed25519 public key from /.well-known/provenonce-authority.json\n * @param currentBeat - Optional current global beat index (for beatsSinceHeartbeat calculation)\n */\n static verifyProofLocally(proof: LineageProof, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n const now = Date.now();\n const expired = now > proof.valid_until;\n\n let signatureValid = false;\n try {\n // Canonical JSON (must match server's canonicalProofData)\n const canonical = JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n identity_class: proof.identity_class,\n registered_at_beat: proof.registered_at_beat,\n sigil_issued_at_beat: proof.sigil_issued_at_beat,\n last_heartbeat_beat: proof.last_heartbeat_beat,\n lineage_chain_hash: proof.lineage_chain_hash,\n issued_at: proof.issued_at,\n valid_until: proof.valid_until,\n });\n\n // Build Ed25519 public key from hex\n const pubBytes = Buffer.from(authorityPubKeyHex, 'hex');\n if (pubBytes.length === 32) {\n const ED25519_SPKI_PREFIX = Buffer.from('302a300506032b6570032100', 'hex');\n const pubKeyDer = Buffer.concat([ED25519_SPKI_PREFIX, pubBytes]);\n const keyObject = createPublicKey({ key: pubKeyDer, format: 'der', type: 'spki' });\n const sigBuffer = Buffer.from(proof.provenonce_signature, 'hex');\n signatureValid = verify(null, Buffer.from(canonical), keyObject, sigBuffer);\n }\n } catch {\n signatureValid = false;\n }\n\n const valid = signatureValid && !expired;\n const beatsSinceHeartbeat = currentBeat != null ? currentBeat - proof.last_heartbeat_beat : null;\n\n let warning: string | undefined;\n if (expired) {\n warning = 'Proof has expired. Reissue with reissueProof() or send a heartbeat.';\n } else if (beatsSinceHeartbeat != null && beatsSinceHeartbeat > 60) {\n warning = `Agent is ${beatsSinceHeartbeat} beats behind. Heartbeat may be stale.`;\n }\n\n return { valid, signatureValid, expired, lastHeartbeatBeat: proof.last_heartbeat_beat, beatsSinceHeartbeat, warning };\n }\n\n // ── STATUS ──\n\n /**\n * Get this agent's full beat status from the registry.\n */\n async getStatus(): Promise<AgentStatus> {\n try {\n // We need the agent hash, but we may not have it directly.\n // The status endpoint uses the hash from the API key verification.\n // For now, use the init endpoint which returns status.\n return await this.refreshState();\n } catch (err: any) {\n this.config.onError(err, 'status');\n throw err;\n }\n }\n\n /**\n * Get local state (no network call).\n */\n getLocalState(): {\n status: string;\n totalBeats: number;\n latestBeat: number;\n latestHash: string;\n difficulty: number;\n globalBeat: number;\n chainLength: number;\n } {\n return {\n status: this.status,\n totalBeats: this.totalBeats,\n latestBeat: this.latestBeat?.index || 0,\n latestHash: this.latestBeat?.hash.slice(0, 24) + '...' || '',\n difficulty: this.difficulty,\n globalBeat: this.globalBeat,\n chainLength: this.chain.length,\n };\n }\n\n // ── INTERNALS ──\n\n private async syncGlobal(): Promise<void> {\n try {\n // SDK-P1-01: add timeout to syncGlobal fetch\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15_000);\n const res = await fetch(`${this.config.registryUrl}/api/v1/beat/anchor`, { signal: controller.signal });\n clearTimeout(timeout);\n const data: any = await res.json();\n if (data.anchor) {\n // Verify anchor hash locally before trusting it\n if (this.config.verifyAnchors && !verifyAnchorHash(data.anchor)) {\n this.log('⚠ Anchor hash verification FAILED — rejecting untrusted anchor');\n return;\n }\n this.globalBeat = data.anchor.beat_index;\n this.globalAnchorHash = data.anchor.hash || '';\n if (data.anchor.difficulty) this.difficulty = data.anchor.difficulty;\n this.log(`Synced to global beat ${this.globalBeat} (D=${this.difficulty})`);\n }\n } catch {\n this.log('Failed to sync global anchor (offline mode continues)');\n }\n }\n\n private async refreshState(): Promise<any> {\n const res = await this.api('POST', '/api/v1/agent/init');\n if (res.already_initialized) {\n this.totalBeats = res.total_beats;\n this.genesisHash = res.genesis_hash;\n this.status = res.status as any;\n this.difficulty = res.difficulty || this.difficulty;\n this.lastCheckinBeat = res.last_checkin_beat || 0;\n\n // Restore latestBeat so pulse() can continue the chain\n if (!this.latestBeat && this.genesisHash) {\n this.latestBeat = {\n index: res.latest_beat || this.totalBeats,\n hash: res.latest_hash || this.genesisHash,\n prev: '0'.repeat(64),\n timestamp: Date.now(),\n };\n this.chain = [this.latestBeat];\n }\n }\n return res;\n }\n\n private async api(method: string, path: string, body?: any): Promise<any> {\n // SDK-P1-01: add 30s timeout to prevent indefinite hangs\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n try {\n const res = await fetch(`${this.config.registryUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n throw new NetworkError(`API error: ${res.status} non-JSON response from ${path}`);\n }\n\n if (!res.ok && !data.ok && !data.already_initialized && !data.eligible) {\n throw mapApiError(res.status, data, path);\n }\n\n return data;\n } catch (err: any) {\n if (err.name === 'AbortError') {\n throw new NetworkError(`Request timeout: ${method} ${path}`, ErrorCode.TIMEOUT);\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private log(msg: string): void {\n if (this.config.verbose) {\n console.log(`[Beat] ${msg}`);\n }\n }\n}\n\n// ============ STANDALONE VDF HELPER ============\n// For agents that want to compute beats without the full SDK\n\nexport { computeBeat };\n\n/**\n * Compute N sequential VDF beats.\n * Returns only the last beat (for lightweight usage).\n */\nexport function computeBeatsLite(\n startHash: string,\n startIndex: number,\n count: number,\n difficulty: number = 1000,\n anchorHash?: string,\n): { lastBeat: Beat; elapsed: number } {\n // SDK-P2: validate inputs\n if (!startHash || typeof startHash !== 'string') {\n throw new ValidationError('computeBeatsLite: startHash must be a non-empty string');\n }\n if (!Number.isInteger(count) || count < 1) {\n throw new ValidationError('computeBeatsLite: count must be a positive integer');\n }\n\n const t0 = Date.now();\n let prev = startHash;\n let lastBeat: Beat | null = null;\n\n for (let i = 0; i < count; i++) {\n lastBeat = computeBeat(prev, startIndex + i, difficulty, undefined, anchorHash);\n prev = lastBeat.hash;\n }\n\n return { lastBeat: lastBeat!, elapsed: Date.now() - t0 };\n}\n","/**\n * Provenonce SDK Error Classes\n *\n * Typed error hierarchy for programmatic error handling.\n * All errors extend ProvenonceError for catch-all, or catch specific\n * subclasses for fine-grained control:\n *\n * try {\n * await agent.checkin();\n * } catch (err) {\n * if (err instanceof RateLimitError) {\n * await sleep(err.retryAfterMs);\n * } else if (err instanceof FrozenError) {\n * await agent.resync();\n * } else if (err instanceof AuthError) {\n * console.error('Bad API key');\n * }\n * }\n */\n\n/** Error codes for programmatic switching */\nexport enum ErrorCode {\n // Validation\n VALIDATION = 'VALIDATION',\n\n // Auth\n AUTH_INVALID = 'AUTH_INVALID',\n AUTH_MISSING = 'AUTH_MISSING',\n\n // Rate limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // Agent state\n AGENT_FROZEN = 'AGENT_FROZEN',\n AGENT_NOT_INITIALIZED = 'AGENT_NOT_INITIALIZED',\n AGENT_WRONG_STATE = 'AGENT_WRONG_STATE',\n\n // Not found\n NOT_FOUND = 'NOT_FOUND',\n\n // Network / server\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n SERVER_ERROR = 'SERVER_ERROR',\n}\n\n/** Base error class for all Provenonce SDK errors */\nexport class ProvenonceError extends Error {\n /** Machine-readable error code */\n readonly code: ErrorCode;\n\n /** HTTP status code (if from an API response) */\n readonly statusCode?: number;\n\n /** Additional context */\n readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ErrorCode,\n statusCode?: number,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ProvenonceError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n // Fix prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when input validation fails (bad config, invalid args) */\nexport class ValidationError extends ProvenonceError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, ErrorCode.VALIDATION, undefined, details);\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown on 401/403 — bad or missing API key */\nexport class AuthError extends ProvenonceError {\n constructor(\n message: string,\n code: ErrorCode.AUTH_INVALID | ErrorCode.AUTH_MISSING = ErrorCode.AUTH_INVALID,\n statusCode?: number,\n ) {\n super(message, code, statusCode);\n this.name = 'AuthError';\n }\n}\n\n/** Thrown on 429 — rate limit exceeded */\nexport class RateLimitError extends ProvenonceError {\n /** Milliseconds until the rate limit resets (if provided by server) */\n readonly retryAfterMs?: number;\n\n constructor(message: string, statusCode: number = 429, retryAfterMs?: number) {\n super(message, ErrorCode.RATE_LIMITED, statusCode);\n this.name = 'RateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** Thrown when an agent is frozen and cannot perform the requested action */\nexport class FrozenError extends ProvenonceError {\n constructor(message: string = 'Agent is frozen. Use resync() to re-establish provenance.') {\n super(message, ErrorCode.AGENT_FROZEN);\n this.name = 'FrozenError';\n }\n}\n\n/** Thrown when the agent is in the wrong state for the requested action */\nexport class StateError extends ProvenonceError {\n /** The agent's current state */\n readonly currentState: string;\n\n constructor(message: string, currentState: string, code: ErrorCode = ErrorCode.AGENT_WRONG_STATE) {\n super(message, code);\n this.name = 'StateError';\n this.currentState = currentState;\n }\n}\n\n/** Thrown on 404 — agent or resource not found */\nexport class NotFoundError extends ProvenonceError {\n constructor(message: string, statusCode: number = 404) {\n super(message, ErrorCode.NOT_FOUND, statusCode);\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown on network failures — non-JSON responses, fetch errors, timeouts */\nexport class NetworkError extends ProvenonceError {\n constructor(message: string, code: ErrorCode.NETWORK_ERROR | ErrorCode.TIMEOUT = ErrorCode.NETWORK_ERROR) {\n super(message, code);\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown on 5xx — unexpected server errors */\nexport class ServerError extends ProvenonceError {\n constructor(message: string, statusCode: number = 500) {\n super(message, ErrorCode.SERVER_ERROR, statusCode);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Map an HTTP response + parsed body to the appropriate error class.\n * Used internally by the SDK to convert API failures to typed errors.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n\n if (statusCode === 401 || statusCode === 403) {\n const code = statusCode === 401 ? ErrorCode.AUTH_MISSING : ErrorCode.AUTH_INVALID;\n return new AuthError(msg, code, statusCode);\n }\n\n if (statusCode === 429) {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n\n if (statusCode === 404) {\n return new NotFoundError(msg, statusCode);\n }\n\n if (statusCode >= 500) {\n return new ServerError(msg, statusCode);\n }\n\n // Check for specific error patterns in the message\n const lowerMsg = msg.toLowerCase();\n if (lowerMsg.includes('frozen')) {\n return new FrozenError(msg);\n }\n\n // Generic client error\n return new ProvenonceError(msg, ErrorCode.SERVER_ERROR, statusCode);\n}\n"],"mappings":"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","names":["ErrorCode","res","data"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@provenonce/sdk",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Provenonce Beat SDK — Agent heartbeat client for sovereign time authentication",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",