@provenonce/sdk 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -688,7 +688,10 @@ var BeatAgent = class _BeatAgent {
|
|
|
688
688
|
const genesisHash = (0, import_crypto.createHash)("sha256").update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`).digest("hex");
|
|
689
689
|
const beats = Math.max(beatsNeeded, 1);
|
|
690
690
|
let prevHash = genesisHash;
|
|
691
|
-
const spotCheckCount = Math.
|
|
691
|
+
const spotCheckCount = Math.max(
|
|
692
|
+
Math.min(beats, 3),
|
|
693
|
+
Math.min(Math.ceil(beats / 1e3), 25)
|
|
694
|
+
);
|
|
692
695
|
const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));
|
|
693
696
|
const spotChecks = [];
|
|
694
697
|
for (let i = 1; i <= beats; i++) {
|
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, 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 ProvenoncePassportVC,\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 SigilAttributionResult,\n SigilMutableFields,\n MetadataUpdateResult,\n VerificationResult,\n // Phase 4: Work-proof types\n WorkProofReceipt,\n WorkProofResult,\n // RFC-021: Sponsorship types\n SponsorshipRecord,\n SponsorshipResult,\n} from './beat-sdk';\n\nexport {\n ProvenonceError,\n ValidationError,\n AuthError,\n SigilRequiredError,\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(); // Initialize agent state\n * await agent.heartbeat(); // Send paid heartbeat (Phase 2)\n *\n * // Or run the autonomous heartbeat loop:\n * agent.startHeartbeat(); // Heartbeats at regular intervals\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, verify, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n SigilRequiredError,\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 passport — the agent's portable, offline-verifiable credential.\n * A cryptographic proof of identity that can be verified offline without any\n * API call or SOL cost.\n */\nexport interface Passport {\n format_version?: number; // 1 = v1 canonical (absent in legacy proofs)\n agent_hash: string;\n agent_public_key: string | null;\n authority_key_id?: string; // Key version identifier (added in Session 76)\n identity_class: IdentityClass | null; // null for SIGIL-less descendants\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/** @deprecated Use `Passport` instead. Sunset 2026-09-01. */\nexport type LineageProof = Passport;\n\n/** W3C Verifiable Credential envelope wrapping a LineageProof */\nexport interface ProvenoncePassportVC {\n '@context': [string, string];\n type: ['VerifiableCredential', 'ProvenoncePassport'];\n issuer: {\n id: string;\n authority_key_id: string;\n };\n issuanceDate: string;\n expirationDate: string;\n credentialSubject: {\n id: string;\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass | null;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n };\n proof: {\n type: 'Ed25519Signature2020';\n created: string;\n verificationMethod: string;\n proofPurpose: 'assertionMethod';\n cryptosuite: 'eddsa-provenonce-2026';\n proofValue: string;\n };\n format_version: number;\n}\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 // Attribution (RFC-018) — include one when purchasing via a partner skill\n at?: string; // pvr_ attribution token from getSigilAttribution() or skill response\n skill_hash?: string; // skill's agent hash (simpler, lower trust than at=)\n ref?: string; // legacy 16-char ref_token (fallback)\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/** Result from getSigilAttribution() */\nexport interface SigilAttributionResult {\n ok: boolean;\n attribution_token?: string; // pvr_ token — pass as `at` in purchaseSigil()\n signup_url?: string | null;\n already_has_sigil?: boolean;\n error?: string;\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 passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sigil_required?: boolean;\n passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sponsor?: {\n parent_hash: string;\n };\n error?: string;\n}\n\n/** RFC-021: Sponsorship record returned by the /agent/sponsor endpoint. */\nexport interface SponsorshipRecord {\n parent_hash: string;\n child_hash: string;\n status: 'active' | 'revoked' | 'expired';\n max_heartbeats_epoch: number;\n heartbeats_used_epoch: number;\n expires_at: string | null;\n created_at?: string;\n}\n\nexport interface SponsorshipResult {\n ok: boolean;\n sponsorship?: SponsorshipRecord;\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 spawn_authorization?: string;\n receipt_based?: boolean;\n required_beats?: number;\n accumulated_beats?: number;\n progress_pct?: number;\n deficit?: number;\n error?: string;\n}\n\n/** A signed work-proof receipt from the Beats service. */\nexport interface WorkProofReceipt {\n type: string;\n beats_verified: number;\n difficulty: number;\n anchor_index: number;\n anchor_hash: string | null;\n from_hash: string;\n to_hash: string;\n utc: string;\n signature: string;\n [key: string]: unknown;\n}\n\n/** Result of computeWorkProof() */\nexport interface WorkProofResult {\n ok: boolean;\n receipt?: WorkProofReceipt;\n beats_computed?: number;\n elapsed_ms?: number;\n error?: string;\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// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\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 /** Wallet model: 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: '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 * 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 (user keeps custody externally)\n data.wallet = {\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 (operator keeps custody externally)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\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 /** Beats service URL for work-proof submission (default: https://beats.provenonce.dev). */\n beatsUrl?: string;\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 private cachedIdentityClass: 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 beatsUrl: 'https://beats.provenonce.dev',\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 /** Internal beat computation — no status check. Used by 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 // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Function that returns a Solana payment tx signature for each heartbeat (required).\n */\n startHeartbeat(paymentTxFn: () => Promise<string> | string): void {\n if (!paymentTxFn) {\n throw new ValidationError('paymentTxFn is required. Provide a function that returns a Solana transaction signature.');\n }\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 = await paymentTxFn();\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 * Re-Sync Challenge (D-67 reversal): reactivate a frozen agent by proving CPU work.\n *\n * When BEATS_REQUIRED=true on the server: requires a signed Beats work-proof\n * receipt. This method computes the proof automatically using computeWorkProof().\n *\n * When BEATS_REQUIRED=false (devnet): no receipt needed — agent is reactivated freely.\n *\n * Gap formula: min(gap_anchors * 100, 10_000) beats required (matches Beats constants).\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n try {\n this.log('Attempting resync...');\n\n // Sync anchor first (needed for proof computation and freshness check)\n await this.syncGlobal();\n\n // First attempt without a receipt (works when BEATS_REQUIRED=false)\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n let probeRes: Response;\n let probeData: any;\n try {\n probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/resync`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({}),\n signal: controller.signal,\n });\n probeData = await probeRes.json();\n } finally {\n clearTimeout(timeout);\n }\n\n // Already reactivated (BEATS_REQUIRED=false) — done\n if (probeData.ok && probeData.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced (free). Agent is alive again in Beat time.');\n return { ok: true, beats_required: 0 };\n }\n\n // 402 RECEIPT_REQUIRED — compute work proof\n if (probeRes.status === 402 || probeData.code === 'RECEIPT_REQUIRED') {\n const requiredBeats = probeData.required_beats ?? 1000;\n this.log(`Re-sync challenge: compute ${requiredBeats} beats at D=${this.difficulty}`);\n\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, error: proofResult.error || 'Failed to compute work proof for resync', beats_required: requiredBeats };\n }\n\n this.log(`Work proof computed: ${proofResult.beats_computed} beats in ${proofResult.elapsed_ms}ms`);\n\n const result = await this.api('POST', '/api/v1/agent/resync', {\n beats_receipt: proofResult.receipt,\n });\n\n if (result.ok && result.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced with work proof. Agent is alive again in Beat time.');\n }\n\n return { ok: !!result.ok, beats_required: requiredBeats };\n }\n\n // Agent not frozen or other error\n return { ok: false, error: probeData.error || `Resync failed (status ${probeRes.status})` };\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), OR a valid Beats work-proof receipt.\n *\n * @param childName Optional name for the child agent\n * @param childHash Pre-registered child hash (Step 2 finalization)\n * @param beatsReceipt Signed work-proof receipt from computeWorkProof() (receipt-based spawn)\n */\n async requestSpawn(childName?: string, childHash?: string, beatsReceipt?: WorkProofReceipt): 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 ...(beatsReceipt && { beats_receipt: beatsReceipt }),\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 } else if (res.spawn_authorization) {\n this.log(`Spawn authorized${res.receipt_based ? ' (receipt-based)' : ''}`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n /**\n * Compute a Beats work-proof for spawn or resync authorization.\n *\n * Computes `beatsNeeded` sequential SHA-256 beats at `difficulty`, weaving in\n * the given anchor hash, then submits to the Beats service and returns a signed receipt.\n *\n * @param opts.beatsNeeded Minimum beats required (from spawn/resync response.required_beats)\n * @param opts.anchorHash Current global anchor hash (from syncGlobal or getAnchor)\n * @param opts.anchorIndex Current global anchor index\n * @param opts.difficulty Beat difficulty (default: agent's current difficulty)\n */\n async computeWorkProof(opts: {\n beatsNeeded: number;\n anchorHash: string;\n anchorIndex: number;\n difficulty?: number;\n }): Promise<WorkProofResult> {\n const { beatsNeeded, anchorHash, anchorIndex } = opts;\n const difficulty = opts.difficulty ?? this.difficulty;\n\n if (!Number.isInteger(beatsNeeded) || beatsNeeded < 0) {\n return { ok: false, error: 'beatsNeeded must be a non-negative integer' };\n }\n\n const t0 = Date.now();\n\n // Create a fresh genesis hash for this proof chain\n const genesisHash = createHash('sha256')\n .update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`)\n .digest('hex');\n\n const beats = Math.max(beatsNeeded, 1);\n let prevHash = genesisHash;\n\n // Sample up to 5 evenly-spaced spot-checks\n const spotCheckCount = Math.min(5, Math.max(1, Math.floor(beats / 100)));\n const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));\n const spotChecks: Array<{ index: number; hash: string; prev: string }> = [];\n\n for (let i = 1; i <= beats; i++) {\n const beat = computeBeat(prevHash, i, difficulty, undefined, anchorHash);\n prevHash = beat.hash;\n // Always include beat 1 (genesis binding) and last beat (terminal binding)\n if (i === 1 || i === beats || (i % spotInterval === 0 && spotChecks.length < spotCheckCount)) {\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev });\n }\n }\n\n const toHash = prevHash;\n const elapsed_ms = Date.now() - t0;\n this.log(`Work proof computed locally: ${beats} beats in ${elapsed_ms}ms`);\n\n // Submit to Beats service\n const beatsUrl = this.config.beatsUrl || 'https://beats.provenonce.dev';\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 120_000);\n\n try {\n const res = await fetch(`${beatsUrl}/api/v1/beat/work-proof`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n work_proof: {\n from_hash: genesisHash,\n to_hash: toHash,\n beats_computed: beats,\n difficulty,\n anchor_index: anchorIndex,\n anchor_hash: anchorHash,\n spot_checks: spotChecks,\n },\n }),\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n return { ok: false, error: `Beats service returned non-JSON (status ${res.status})` };\n }\n\n if (!data.valid || !data.receipt) {\n return { ok: false, error: data.reason || data.error || 'Work proof rejected by Beats service' };\n }\n\n this.log(`Work proof receipt issued by Beats: ${data.receipt.beats_verified} beats verified`);\n return { ok: true, receipt: data.receipt as WorkProofReceipt, beats_computed: beats, elapsed_ms };\n } catch (err: any) {\n if (err.name === 'AbortError') {\n return { ok: false, error: 'Work proof submission timed out' };\n }\n return { ok: false, error: err.message };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /**\n * Compute a Beats work-proof and use it to request spawn authorization.\n *\n * Probes the spawn endpoint to determine required beats, computes the proof,\n * and returns the spawn_authorization token. The caller still needs to:\n * 1. Register the child via POST /api/v1/register with spawn_authorization\n * 2. Finalize via POST /api/v1/agent/spawn with child_hash\n *\n * @param opts.childName Optional name for the child agent\n * @param opts.beatsNeeded Override the required beats (default: auto-probed)\n */\n async requestSpawnWithBeatsProof(opts?: {\n childName?: string;\n beatsNeeded?: number;\n }): Promise<SpawnResult> {\n try {\n // Sync anchor to get anchor hash + index for the proof\n await this.syncGlobal();\n\n // Probe spawn endpoint to determine required_beats (raw fetch for full response access)\n let requiredBeats = opts?.beatsNeeded;\n if (requiredBeats === undefined) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/spawn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({ child_name: opts?.childName }),\n signal: controller.signal,\n });\n const probeData = await probeRes.json() as any;\n\n // Balance-based spawn already authorized — return early\n if (probeData.spawn_authorization && probeData.eligible) {\n return probeData as SpawnResult;\n }\n requiredBeats = (probeData.required_beats as number | undefined) ?? 1000;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n // Compute work proof\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, eligible: false, error: proofResult.error || 'Failed to compute work proof' };\n }\n\n this.log(`Submitting spawn with work proof (${proofResult.beats_computed} beats)`);\n return this.requestSpawn(opts?.childName, undefined, proofResult.receipt);\n } catch (err: any) {\n this.config.onError(err, 'requestSpawnWithBeatsProof');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached passport from the most recent heartbeat or SIGIL purchase */\n private cachedPassport: Passport | 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 const resPassport = res.passport || res.lineage_proof;\n if (resPassport) {\n this.cachedPassport = resPassport;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.cachedIdentityClass = 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 passport: resPassport,\n lineage_proof: resPassport,\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 * Get a SIGIL attribution token from a partner skill's ref_token (RFC-018).\n *\n * Call this after receiving a skill's ref_token in its response.\n * Returns a pvr_ attribution token to include as `at` in purchaseSigil().\n *\n * This is the agent-side half of the two-sided witnessed proof:\n * the skill's server already called /sigil/check for this agent hash.\n * This call completes the proof — our server witnesses both sides.\n *\n * @param partnerRef - The skill's 16-char ref_token\n */\n async getSigilAttribution(partnerRef: string): Promise<SigilAttributionResult> {\n if (!partnerRef || typeof partnerRef !== 'string' || partnerRef.length !== 16) {\n return { ok: false, error: 'partnerRef must be a 16-character ref_token from the skill' };\n }\n try {\n const res = await this.api('POST', '/api/v1/sigil/check', { partner_ref: partnerRef });\n return {\n ok: true,\n attribution_token: res.attribution_token,\n signup_url: res.signup_url ?? null,\n already_has_sigil: res.already_has_sigil ?? false,\n };\n } catch (err: any) {\n this.config.onError(err, 'getSigilAttribution');\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 (required).\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx: string, globalAnchor?: number, opts?: { sponsoredBy?: string }): Promise<HeartbeatResult> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const body: Record<string, unknown> = {\n payment_tx: paymentTx,\n global_anchor: globalAnchor,\n };\n if (opts?.sponsoredBy) {\n body.sponsored_by = opts.sponsoredBy;\n }\n\n const res = await this.api('POST', '/api/v1/agent/heartbeat', body);\n\n const hbPassport = res.passport || res.lineage_proof;\n if (hbPassport) {\n this.cachedPassport = hbPassport;\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 passport: hbPassport,\n lineage_proof: hbPassport,\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 sponsor: res.sponsor,\n };\n } catch (err: any) {\n if (err instanceof SigilRequiredError) {\n return { ok: false, sigil_required: true, error: err.message };\n }\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a passport. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature (required).\n */\n async reissuePassport(paymentTx: string): Promise<{ ok: boolean; passport?: Passport; lineage_proof?: Passport; error?: string }> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx,\n });\n\n const rePassport = res.passport || res.lineage_proof;\n if (rePassport) {\n this.cachedPassport = rePassport;\n }\n\n return { ok: true, passport: rePassport, lineage_proof: rePassport };\n } catch (err: any) {\n this.config.onError(err, 'reissuePassport');\n return { ok: false, error: err.message };\n }\n }\n\n /** @deprecated Use `reissuePassport()` instead. Sunset 2026-09-01. */\n async reissueProof(paymentTx: string) { return this.reissuePassport(paymentTx); }\n\n // ============ SPONSORSHIP (RFC-021) ============\n\n /**\n * Sponsor a child agent's heartbeats.\n * The authenticated agent (this instance) becomes the sponsor, paying heartbeat\n * fees on behalf of the specified child from this agent's operator wallet.\n *\n * @param childHash - Hash of the child agent to sponsor\n * @param opts.maxHeartbeatsEpoch - Max heartbeats per billing epoch (default: 100, max: 10,000)\n * @param opts.expiresInHours - Optional TTL for the sponsorship\n */\n async sponsorChild(childHash: string, opts?: {\n maxHeartbeatsEpoch?: number;\n expiresInHours?: number;\n }): Promise<SponsorshipResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n max_heartbeats_epoch: opts?.maxHeartbeatsEpoch,\n expires_in_hours: opts?.expiresInHours,\n });\n return { ok: true, sponsorship: res.sponsorship };\n } catch (err: any) {\n this.config.onError(err, 'sponsorChild');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Revoke a sponsorship for a child agent.\n * The child will no longer be able to use this agent's wallet for heartbeat payments.\n */\n async revokeSponsor(childHash: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await this.api('DELETE', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n });\n return { ok: true };\n } catch (err: any) {\n this.config.onError(err, 'revokeSponsor');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * List all active sponsorships for this agent (as parent).\n */\n async listSponsorships(): Promise<{ ok: boolean; sponsorships?: SponsorshipRecord[]; error?: string }> {\n try {\n const res = await this.api('GET', '/api/v1/agent/sponsor');\n return { ok: true, sponsorships: res.sponsorships };\n } catch (err: any) {\n this.config.onError(err, 'listSponsorships');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached passport (no network call).\n * Returns null if no passport has been obtained yet.\n */\n getLatestPassport(): Passport | null {\n return this.cachedPassport;\n }\n\n /** @deprecated Use `getLatestPassport()` instead. Sunset 2026-09-01. */\n getLatestProof(): Passport | null { return this.getLatestPassport(); }\n\n /**\n * Get the agent's passport (alias for getLatestPassport).\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.cachedPassport;\n }\n\n /**\n * Export this agent's passport in both flat (Passport) and W3C VC envelope formats.\n * Fetches a freshly signed passport from the server. Free endpoint, rate-limited 10/hr.\n * Returns null if the request fails.\n */\n async exportPassport(): Promise<{ passport: Passport; passport_vc: ProvenoncePassportVC; lineage_proof: Passport } | null> {\n try {\n const res = await this.api('GET', '/api/v1/agent/passport');\n const expPassport = res.passport || res.lineage_proof;\n if (expPassport) {\n this.cachedPassport = expPassport;\n }\n return { passport: expPassport, passport_vc: res.passport_vc, lineage_proof: expPassport };\n } catch (err: any) {\n this.config.onError(err, 'exportPassport');\n return null;\n }\n }\n\n /**\n * Wrap a Passport in a W3C Verifiable Credential envelope (client-side).\n * Does not make any network call. Requires the passport to have authority_key_id.\n */\n static proofToPassportVC(proof: Passport, authorityKeyId?: string): ProvenoncePassportVC {\n const keyId = proof.authority_key_id || authorityKeyId || 'unknown';\n return {\n '@context': [\n 'https://www.w3.org/2018/credentials/v1',\n 'https://provenonce.io/.well-known/provenonce-passport-v1.jsonld',\n ],\n type: ['VerifiableCredential', 'ProvenoncePassport'],\n issuer: {\n id: 'https://provenonce.io',\n authority_key_id: keyId,\n },\n issuanceDate: new Date(proof.issued_at).toISOString(),\n expirationDate: new Date(proof.valid_until).toISOString(),\n credentialSubject: {\n id: `provenonce:agent:${proof.agent_hash}`,\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 },\n proof: {\n type: 'Ed25519Signature2020',\n created: new Date(proof.issued_at).toISOString(),\n verificationMethod: `https://provenonce.io/.well-known/provenonce-authority.json#${keyId}`,\n proofPurpose: 'assertionMethod',\n cryptosuite: 'eddsa-provenonce-2026',\n proofValue: proof.provenonce_signature,\n },\n format_version: proof.format_version || 1,\n };\n }\n\n /**\n * Verify a passport 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.verifyPassportLocally(proof, key))` still works.\n *\n * @param proof - The Passport 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 verifyPassportLocally(proof: Passport, 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 / legacyCanonicalProofData.\n // V1 proofs (format_version present): include format_version + authority_key_id.\n // Legacy proofs (no format_version): 10-field canonical without those fields.\n const canonical = proof.format_version\n ? JSON.stringify({\n format_version: proof.format_version,\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : proof.authority_key_id\n ? JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : 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 = 'Passport has expired. Reissue with reissuePassport() 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 /** @deprecated Use `verifyPassportLocally()` instead. Sunset 2026-09-01. */\n static verifyProofLocally(proof: Passport, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n return BeatAgent.verifyPassportLocally(proof, authorityPubKeyHex, currentBeat);\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 /**\n * Returns true if this agent has purchased a SIGIL in this session,\n * or if a cached passport contains an identity_class.\n * For an authoritative check, use GET /api/v1/agent/me.\n */\n hasSigil(): boolean {\n return !!(this.cachedIdentityClass || this.cachedPassport?.identity_class);\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 // Note: anchor.difficulty is for anchor hash creation (can be 1M+),\n // NOT for agent beats. Agent difficulty is set by init/refreshState only.\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 SIGIL_REQUIRED = 'SIGIL_REQUIRED',\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 403 SIGIL_REQUIRED — agent has not purchased a SIGIL */\nexport class SigilRequiredError extends ProvenonceError {\n constructor(message: string = 'SIGIL required: purchase a SIGIL before sending heartbeats.') {\n super(message, ErrorCode.SIGIL_REQUIRED, 403);\n this.name = 'SigilRequiredError';\n Object.setPrototypeOf(this, new.target.prototype);\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 *\n * Prefers body.code (machine-readable error code from the API) for precise\n * routing when available. Falls back to status-code heuristics for backward\n * compatibility with older server versions that don't include a code field.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; code?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n const apiCode = typeof body.code === 'string' ? body.code : undefined;\n\n // ── Code-based routing (preferred — precise, no string matching) ──────\n if (apiCode) {\n switch (apiCode) {\n case 'SIGIL_REQUIRED':\n return new SigilRequiredError(msg);\n case 'AGENT_FROZEN':\n return new FrozenError(msg);\n case 'AUTH_MISSING':\n return new AuthError(msg, ErrorCode.AUTH_MISSING, statusCode);\n case 'AUTH_INVALID':\n case 'AUTH_FORBIDDEN':\n return new AuthError(msg, ErrorCode.AUTH_INVALID, statusCode);\n case 'RATE_LIMITED':\n case 'HEARTBEAT_TOO_SOON':\n case 'VOLUME_CAP_REACHED':\n case 'SPAWN_LIMIT_REACHED': {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n case 'AGENT_NOT_FOUND':\n return new NotFoundError(msg, statusCode);\n case 'AGENT_NOT_INITIALIZED':\n return new StateError(msg, 'not_initialized', ErrorCode.AGENT_NOT_INITIALIZED);\n case 'AGENT_WRONG_STATE':\n case 'SPAWN_CONFLICT':\n return new StateError(msg, 'conflict', ErrorCode.AGENT_WRONG_STATE);\n case 'SERVER_ERROR':\n case 'DB_ERROR':\n case 'DB_NOT_CONFIGURED':\n return new ServerError(msg, statusCode);\n // Validation / payment codes — fall through to generic handling below\n }\n }\n\n // ── Status-based fallback (backward compat with servers without code) ─\n if (statusCode === 401 || statusCode === 403) {\n // Deprecated: sigil_required boolean check — use code: SIGIL_REQUIRED instead\n if (statusCode === 403 && (body as any).sigil_required === true) {\n return new SigilRequiredError(msg);\n }\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 (deprecated — prefer body.code)\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, 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 ProvenoncePassportVC,\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 SigilAttributionResult,\n SigilMutableFields,\n MetadataUpdateResult,\n VerificationResult,\n // Phase 4: Work-proof types\n WorkProofReceipt,\n WorkProofResult,\n // RFC-021: Sponsorship types\n SponsorshipRecord,\n SponsorshipResult,\n} from './beat-sdk';\n\nexport {\n ProvenonceError,\n ValidationError,\n AuthError,\n SigilRequiredError,\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(); // Initialize agent state\n * await agent.heartbeat(); // Send paid heartbeat (Phase 2)\n *\n * // Or run the autonomous heartbeat loop:\n * agent.startHeartbeat(); // Heartbeats at regular intervals\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, verify, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n SigilRequiredError,\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 passport — the agent's portable, offline-verifiable credential.\n * A cryptographic proof of identity that can be verified offline without any\n * API call or SOL cost.\n */\nexport interface Passport {\n format_version?: number; // 1 = v1 canonical (absent in legacy proofs)\n agent_hash: string;\n agent_public_key: string | null;\n authority_key_id?: string; // Key version identifier (added in Session 76)\n identity_class: IdentityClass | null; // null for SIGIL-less descendants\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/** @deprecated Use `Passport` instead. Sunset 2026-09-01. */\nexport type LineageProof = Passport;\n\n/** W3C Verifiable Credential envelope wrapping a LineageProof */\nexport interface ProvenoncePassportVC {\n '@context': [string, string];\n type: ['VerifiableCredential', 'ProvenoncePassport'];\n issuer: {\n id: string;\n authority_key_id: string;\n };\n issuanceDate: string;\n expirationDate: string;\n credentialSubject: {\n id: string;\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass | null;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n };\n proof: {\n type: 'Ed25519Signature2020';\n created: string;\n verificationMethod: string;\n proofPurpose: 'assertionMethod';\n cryptosuite: 'eddsa-provenonce-2026';\n proofValue: string;\n };\n format_version: number;\n}\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 // Attribution (RFC-018) — include one when purchasing via a partner skill\n at?: string; // pvr_ attribution token from getSigilAttribution() or skill response\n skill_hash?: string; // skill's agent hash (simpler, lower trust than at=)\n ref?: string; // legacy 16-char ref_token (fallback)\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/** Result from getSigilAttribution() */\nexport interface SigilAttributionResult {\n ok: boolean;\n attribution_token?: string; // pvr_ token — pass as `at` in purchaseSigil()\n signup_url?: string | null;\n already_has_sigil?: boolean;\n error?: string;\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 passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sigil_required?: boolean;\n passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sponsor?: {\n parent_hash: string;\n };\n error?: string;\n}\n\n/** RFC-021: Sponsorship record returned by the /agent/sponsor endpoint. */\nexport interface SponsorshipRecord {\n parent_hash: string;\n child_hash: string;\n status: 'active' | 'revoked' | 'expired';\n max_heartbeats_epoch: number;\n heartbeats_used_epoch: number;\n expires_at: string | null;\n created_at?: string;\n}\n\nexport interface SponsorshipResult {\n ok: boolean;\n sponsorship?: SponsorshipRecord;\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 spawn_authorization?: string;\n receipt_based?: boolean;\n required_beats?: number;\n accumulated_beats?: number;\n progress_pct?: number;\n deficit?: number;\n error?: string;\n}\n\n/** A signed work-proof receipt from the Beats service. */\nexport interface WorkProofReceipt {\n type: string;\n beats_verified: number;\n difficulty: number;\n anchor_index: number;\n anchor_hash: string | null;\n from_hash: string;\n to_hash: string;\n utc: string;\n signature: string;\n [key: string]: unknown;\n}\n\n/** Result of computeWorkProof() */\nexport interface WorkProofResult {\n ok: boolean;\n receipt?: WorkProofReceipt;\n beats_computed?: number;\n elapsed_ms?: number;\n error?: string;\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// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\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 /** Wallet model: 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: '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 * 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 (user keeps custody externally)\n data.wallet = {\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 (operator keeps custody externally)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\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 /** Beats service URL for work-proof submission (default: https://beats.provenonce.dev). */\n beatsUrl?: string;\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 private cachedIdentityClass: 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 beatsUrl: 'https://beats.provenonce.dev',\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 /** Internal beat computation — no status check. Used by 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 // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Function that returns a Solana payment tx signature for each heartbeat (required).\n */\n startHeartbeat(paymentTxFn: () => Promise<string> | string): void {\n if (!paymentTxFn) {\n throw new ValidationError('paymentTxFn is required. Provide a function that returns a Solana transaction signature.');\n }\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 = await paymentTxFn();\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 * Re-Sync Challenge (D-67 reversal): reactivate a frozen agent by proving CPU work.\n *\n * When BEATS_REQUIRED=true on the server: requires a signed Beats work-proof\n * receipt. This method computes the proof automatically using computeWorkProof().\n *\n * When BEATS_REQUIRED=false (devnet): no receipt needed — agent is reactivated freely.\n *\n * Gap formula: min(gap_anchors * 100, 10_000) beats required (matches Beats constants).\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n try {\n this.log('Attempting resync...');\n\n // Sync anchor first (needed for proof computation and freshness check)\n await this.syncGlobal();\n\n // First attempt without a receipt (works when BEATS_REQUIRED=false)\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n let probeRes: Response;\n let probeData: any;\n try {\n probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/resync`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({}),\n signal: controller.signal,\n });\n probeData = await probeRes.json();\n } finally {\n clearTimeout(timeout);\n }\n\n // Already reactivated (BEATS_REQUIRED=false) — done\n if (probeData.ok && probeData.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced (free). Agent is alive again in Beat time.');\n return { ok: true, beats_required: 0 };\n }\n\n // 402 RECEIPT_REQUIRED — compute work proof\n if (probeRes.status === 402 || probeData.code === 'RECEIPT_REQUIRED') {\n const requiredBeats = probeData.required_beats ?? 1000;\n this.log(`Re-sync challenge: compute ${requiredBeats} beats at D=${this.difficulty}`);\n\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, error: proofResult.error || 'Failed to compute work proof for resync', beats_required: requiredBeats };\n }\n\n this.log(`Work proof computed: ${proofResult.beats_computed} beats in ${proofResult.elapsed_ms}ms`);\n\n const result = await this.api('POST', '/api/v1/agent/resync', {\n beats_receipt: proofResult.receipt,\n });\n\n if (result.ok && result.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced with work proof. Agent is alive again in Beat time.');\n }\n\n return { ok: !!result.ok, beats_required: requiredBeats };\n }\n\n // Agent not frozen or other error\n return { ok: false, error: probeData.error || `Resync failed (status ${probeRes.status})` };\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), OR a valid Beats work-proof receipt.\n *\n * @param childName Optional name for the child agent\n * @param childHash Pre-registered child hash (Step 2 finalization)\n * @param beatsReceipt Signed work-proof receipt from computeWorkProof() (receipt-based spawn)\n */\n async requestSpawn(childName?: string, childHash?: string, beatsReceipt?: WorkProofReceipt): 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 ...(beatsReceipt && { beats_receipt: beatsReceipt }),\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 } else if (res.spawn_authorization) {\n this.log(`Spawn authorized${res.receipt_based ? ' (receipt-based)' : ''}`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n /**\n * Compute a Beats work-proof for spawn or resync authorization.\n *\n * Computes `beatsNeeded` sequential SHA-256 beats at `difficulty`, weaving in\n * the given anchor hash, then submits to the Beats service and returns a signed receipt.\n *\n * @param opts.beatsNeeded Minimum beats required (from spawn/resync response.required_beats)\n * @param opts.anchorHash Current global anchor hash (from syncGlobal or getAnchor)\n * @param opts.anchorIndex Current global anchor index\n * @param opts.difficulty Beat difficulty (default: agent's current difficulty)\n */\n async computeWorkProof(opts: {\n beatsNeeded: number;\n anchorHash: string;\n anchorIndex: number;\n difficulty?: number;\n }): Promise<WorkProofResult> {\n const { beatsNeeded, anchorHash, anchorIndex } = opts;\n const difficulty = opts.difficulty ?? this.difficulty;\n\n if (!Number.isInteger(beatsNeeded) || beatsNeeded < 0) {\n return { ok: false, error: 'beatsNeeded must be a non-negative integer' };\n }\n\n const t0 = Date.now();\n\n // Create a fresh genesis hash for this proof chain\n const genesisHash = createHash('sha256')\n .update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`)\n .digest('hex');\n\n const beats = Math.max(beatsNeeded, 1);\n let prevHash = genesisHash;\n\n // Match Beats service density requirement: max(min(beats, 3), min(ceil(beats/1000), 25))\n // Genesis (beat 1) and terminal (beat N) are always added unconditionally.\n const spotCheckCount = Math.max(\n Math.min(beats, 3),\n Math.min(Math.ceil(beats / 1000), 25),\n );\n const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));\n const spotChecks: Array<{ index: number; hash: string; prev: string }> = [];\n\n for (let i = 1; i <= beats; i++) {\n const beat = computeBeat(prevHash, i, difficulty, undefined, anchorHash);\n prevHash = beat.hash;\n // Always include beat 1 (genesis binding) and last beat (terminal binding)\n if (i === 1 || i === beats || (i % spotInterval === 0 && spotChecks.length < spotCheckCount)) {\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev });\n }\n }\n\n const toHash = prevHash;\n const elapsed_ms = Date.now() - t0;\n this.log(`Work proof computed locally: ${beats} beats in ${elapsed_ms}ms`);\n\n // Submit to Beats service\n const beatsUrl = this.config.beatsUrl || 'https://beats.provenonce.dev';\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 120_000);\n\n try {\n const res = await fetch(`${beatsUrl}/api/v1/beat/work-proof`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n work_proof: {\n from_hash: genesisHash,\n to_hash: toHash,\n beats_computed: beats,\n difficulty,\n anchor_index: anchorIndex,\n anchor_hash: anchorHash,\n spot_checks: spotChecks,\n },\n }),\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n return { ok: false, error: `Beats service returned non-JSON (status ${res.status})` };\n }\n\n if (!data.valid || !data.receipt) {\n return { ok: false, error: data.reason || data.error || 'Work proof rejected by Beats service' };\n }\n\n this.log(`Work proof receipt issued by Beats: ${data.receipt.beats_verified} beats verified`);\n return { ok: true, receipt: data.receipt as WorkProofReceipt, beats_computed: beats, elapsed_ms };\n } catch (err: any) {\n if (err.name === 'AbortError') {\n return { ok: false, error: 'Work proof submission timed out' };\n }\n return { ok: false, error: err.message };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /**\n * Compute a Beats work-proof and use it to request spawn authorization.\n *\n * Probes the spawn endpoint to determine required beats, computes the proof,\n * and returns the spawn_authorization token. The caller still needs to:\n * 1. Register the child via POST /api/v1/register with spawn_authorization\n * 2. Finalize via POST /api/v1/agent/spawn with child_hash\n *\n * @param opts.childName Optional name for the child agent\n * @param opts.beatsNeeded Override the required beats (default: auto-probed)\n */\n async requestSpawnWithBeatsProof(opts?: {\n childName?: string;\n beatsNeeded?: number;\n }): Promise<SpawnResult> {\n try {\n // Sync anchor to get anchor hash + index for the proof\n await this.syncGlobal();\n\n // Probe spawn endpoint to determine required_beats (raw fetch for full response access)\n let requiredBeats = opts?.beatsNeeded;\n if (requiredBeats === undefined) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/spawn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({ child_name: opts?.childName }),\n signal: controller.signal,\n });\n const probeData = await probeRes.json() as any;\n\n // Balance-based spawn already authorized — return early\n if (probeData.spawn_authorization && probeData.eligible) {\n return probeData as SpawnResult;\n }\n requiredBeats = (probeData.required_beats as number | undefined) ?? 1000;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n // Compute work proof\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, eligible: false, error: proofResult.error || 'Failed to compute work proof' };\n }\n\n this.log(`Submitting spawn with work proof (${proofResult.beats_computed} beats)`);\n return this.requestSpawn(opts?.childName, undefined, proofResult.receipt);\n } catch (err: any) {\n this.config.onError(err, 'requestSpawnWithBeatsProof');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached passport from the most recent heartbeat or SIGIL purchase */\n private cachedPassport: Passport | 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 const resPassport = res.passport || res.lineage_proof;\n if (resPassport) {\n this.cachedPassport = resPassport;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.cachedIdentityClass = 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 passport: resPassport,\n lineage_proof: resPassport,\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 * Get a SIGIL attribution token from a partner skill's ref_token (RFC-018).\n *\n * Call this after receiving a skill's ref_token in its response.\n * Returns a pvr_ attribution token to include as `at` in purchaseSigil().\n *\n * This is the agent-side half of the two-sided witnessed proof:\n * the skill's server already called /sigil/check for this agent hash.\n * This call completes the proof — our server witnesses both sides.\n *\n * @param partnerRef - The skill's 16-char ref_token\n */\n async getSigilAttribution(partnerRef: string): Promise<SigilAttributionResult> {\n if (!partnerRef || typeof partnerRef !== 'string' || partnerRef.length !== 16) {\n return { ok: false, error: 'partnerRef must be a 16-character ref_token from the skill' };\n }\n try {\n const res = await this.api('POST', '/api/v1/sigil/check', { partner_ref: partnerRef });\n return {\n ok: true,\n attribution_token: res.attribution_token,\n signup_url: res.signup_url ?? null,\n already_has_sigil: res.already_has_sigil ?? false,\n };\n } catch (err: any) {\n this.config.onError(err, 'getSigilAttribution');\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 (required).\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx: string, globalAnchor?: number, opts?: { sponsoredBy?: string }): Promise<HeartbeatResult> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const body: Record<string, unknown> = {\n payment_tx: paymentTx,\n global_anchor: globalAnchor,\n };\n if (opts?.sponsoredBy) {\n body.sponsored_by = opts.sponsoredBy;\n }\n\n const res = await this.api('POST', '/api/v1/agent/heartbeat', body);\n\n const hbPassport = res.passport || res.lineage_proof;\n if (hbPassport) {\n this.cachedPassport = hbPassport;\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 passport: hbPassport,\n lineage_proof: hbPassport,\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 sponsor: res.sponsor,\n };\n } catch (err: any) {\n if (err instanceof SigilRequiredError) {\n return { ok: false, sigil_required: true, error: err.message };\n }\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a passport. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature (required).\n */\n async reissuePassport(paymentTx: string): Promise<{ ok: boolean; passport?: Passport; lineage_proof?: Passport; error?: string }> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx,\n });\n\n const rePassport = res.passport || res.lineage_proof;\n if (rePassport) {\n this.cachedPassport = rePassport;\n }\n\n return { ok: true, passport: rePassport, lineage_proof: rePassport };\n } catch (err: any) {\n this.config.onError(err, 'reissuePassport');\n return { ok: false, error: err.message };\n }\n }\n\n /** @deprecated Use `reissuePassport()` instead. Sunset 2026-09-01. */\n async reissueProof(paymentTx: string) { return this.reissuePassport(paymentTx); }\n\n // ============ SPONSORSHIP (RFC-021) ============\n\n /**\n * Sponsor a child agent's heartbeats.\n * The authenticated agent (this instance) becomes the sponsor, paying heartbeat\n * fees on behalf of the specified child from this agent's operator wallet.\n *\n * @param childHash - Hash of the child agent to sponsor\n * @param opts.maxHeartbeatsEpoch - Max heartbeats per billing epoch (default: 100, max: 10,000)\n * @param opts.expiresInHours - Optional TTL for the sponsorship\n */\n async sponsorChild(childHash: string, opts?: {\n maxHeartbeatsEpoch?: number;\n expiresInHours?: number;\n }): Promise<SponsorshipResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n max_heartbeats_epoch: opts?.maxHeartbeatsEpoch,\n expires_in_hours: opts?.expiresInHours,\n });\n return { ok: true, sponsorship: res.sponsorship };\n } catch (err: any) {\n this.config.onError(err, 'sponsorChild');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Revoke a sponsorship for a child agent.\n * The child will no longer be able to use this agent's wallet for heartbeat payments.\n */\n async revokeSponsor(childHash: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await this.api('DELETE', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n });\n return { ok: true };\n } catch (err: any) {\n this.config.onError(err, 'revokeSponsor');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * List all active sponsorships for this agent (as parent).\n */\n async listSponsorships(): Promise<{ ok: boolean; sponsorships?: SponsorshipRecord[]; error?: string }> {\n try {\n const res = await this.api('GET', '/api/v1/agent/sponsor');\n return { ok: true, sponsorships: res.sponsorships };\n } catch (err: any) {\n this.config.onError(err, 'listSponsorships');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached passport (no network call).\n * Returns null if no passport has been obtained yet.\n */\n getLatestPassport(): Passport | null {\n return this.cachedPassport;\n }\n\n /** @deprecated Use `getLatestPassport()` instead. Sunset 2026-09-01. */\n getLatestProof(): Passport | null { return this.getLatestPassport(); }\n\n /**\n * Get the agent's passport (alias for getLatestPassport).\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.cachedPassport;\n }\n\n /**\n * Export this agent's passport in both flat (Passport) and W3C VC envelope formats.\n * Fetches a freshly signed passport from the server. Free endpoint, rate-limited 10/hr.\n * Returns null if the request fails.\n */\n async exportPassport(): Promise<{ passport: Passport; passport_vc: ProvenoncePassportVC; lineage_proof: Passport } | null> {\n try {\n const res = await this.api('GET', '/api/v1/agent/passport');\n const expPassport = res.passport || res.lineage_proof;\n if (expPassport) {\n this.cachedPassport = expPassport;\n }\n return { passport: expPassport, passport_vc: res.passport_vc, lineage_proof: expPassport };\n } catch (err: any) {\n this.config.onError(err, 'exportPassport');\n return null;\n }\n }\n\n /**\n * Wrap a Passport in a W3C Verifiable Credential envelope (client-side).\n * Does not make any network call. Requires the passport to have authority_key_id.\n */\n static proofToPassportVC(proof: Passport, authorityKeyId?: string): ProvenoncePassportVC {\n const keyId = proof.authority_key_id || authorityKeyId || 'unknown';\n return {\n '@context': [\n 'https://www.w3.org/2018/credentials/v1',\n 'https://provenonce.io/.well-known/provenonce-passport-v1.jsonld',\n ],\n type: ['VerifiableCredential', 'ProvenoncePassport'],\n issuer: {\n id: 'https://provenonce.io',\n authority_key_id: keyId,\n },\n issuanceDate: new Date(proof.issued_at).toISOString(),\n expirationDate: new Date(proof.valid_until).toISOString(),\n credentialSubject: {\n id: `provenonce:agent:${proof.agent_hash}`,\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 },\n proof: {\n type: 'Ed25519Signature2020',\n created: new Date(proof.issued_at).toISOString(),\n verificationMethod: `https://provenonce.io/.well-known/provenonce-authority.json#${keyId}`,\n proofPurpose: 'assertionMethod',\n cryptosuite: 'eddsa-provenonce-2026',\n proofValue: proof.provenonce_signature,\n },\n format_version: proof.format_version || 1,\n };\n }\n\n /**\n * Verify a passport 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.verifyPassportLocally(proof, key))` still works.\n *\n * @param proof - The Passport 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 verifyPassportLocally(proof: Passport, 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 / legacyCanonicalProofData.\n // V1 proofs (format_version present): include format_version + authority_key_id.\n // Legacy proofs (no format_version): 10-field canonical without those fields.\n const canonical = proof.format_version\n ? JSON.stringify({\n format_version: proof.format_version,\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : proof.authority_key_id\n ? JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : 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 = 'Passport has expired. Reissue with reissuePassport() 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 /** @deprecated Use `verifyPassportLocally()` instead. Sunset 2026-09-01. */\n static verifyProofLocally(proof: Passport, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n return BeatAgent.verifyPassportLocally(proof, authorityPubKeyHex, currentBeat);\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 /**\n * Returns true if this agent has purchased a SIGIL in this session,\n * or if a cached passport contains an identity_class.\n * For an authoritative check, use GET /api/v1/agent/me.\n */\n hasSigil(): boolean {\n return !!(this.cachedIdentityClass || this.cachedPassport?.identity_class);\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 // Note: anchor.difficulty is for anchor hash creation (can be 1M+),\n // NOT for agent beats. Agent difficulty is set by init/refreshState only.\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 SIGIL_REQUIRED = 'SIGIL_REQUIRED',\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 403 SIGIL_REQUIRED — agent has not purchased a SIGIL */\nexport class SigilRequiredError extends ProvenonceError {\n constructor(message: string = 'SIGIL required: purchase a SIGIL before sending heartbeats.') {\n super(message, ErrorCode.SIGIL_REQUIRED, 403);\n this.name = 'SigilRequiredError';\n Object.setPrototypeOf(this, new.target.prototype);\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 *\n * Prefers body.code (machine-readable error code from the API) for precise\n * routing when available. Falls back to status-code heuristics for backward\n * compatibility with older server versions that don't include a code field.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; code?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n const apiCode = typeof body.code === 'string' ? body.code : undefined;\n\n // ── Code-based routing (preferred — precise, no string matching) ──────\n if (apiCode) {\n switch (apiCode) {\n case 'SIGIL_REQUIRED':\n return new SigilRequiredError(msg);\n case 'AGENT_FROZEN':\n return new FrozenError(msg);\n case 'AUTH_MISSING':\n return new AuthError(msg, ErrorCode.AUTH_MISSING, statusCode);\n case 'AUTH_INVALID':\n case 'AUTH_FORBIDDEN':\n return new AuthError(msg, ErrorCode.AUTH_INVALID, statusCode);\n case 'RATE_LIMITED':\n case 'HEARTBEAT_TOO_SOON':\n case 'VOLUME_CAP_REACHED':\n case 'SPAWN_LIMIT_REACHED': {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n case 'AGENT_NOT_FOUND':\n return new NotFoundError(msg, statusCode);\n case 'AGENT_NOT_INITIALIZED':\n return new StateError(msg, 'not_initialized', ErrorCode.AGENT_NOT_INITIALIZED);\n case 'AGENT_WRONG_STATE':\n case 'SPAWN_CONFLICT':\n return new StateError(msg, 'conflict', ErrorCode.AGENT_WRONG_STATE);\n case 'SERVER_ERROR':\n case 'DB_ERROR':\n case 'DB_NOT_CONFIGURED':\n return new ServerError(msg, statusCode);\n // Validation / payment codes — fall through to generic handling below\n }\n }\n\n // ── Status-based fallback (backward compat with servers without code) ─\n if (statusCode === 401 || statusCode === 403) {\n // Deprecated: sigil_required boolean check — use code: SIGIL_REQUIRED instead\n if (statusCode === 403 && (body as any).sigil_required === true) {\n return new SigilRequiredError(msg);\n }\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 (deprecated — prefer body.code)\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
|
@@ -647,7 +647,10 @@ var BeatAgent = class _BeatAgent {
|
|
|
647
647
|
const genesisHash = createHash("sha256").update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`).digest("hex");
|
|
648
648
|
const beats = Math.max(beatsNeeded, 1);
|
|
649
649
|
let prevHash = genesisHash;
|
|
650
|
-
const spotCheckCount = Math.
|
|
650
|
+
const spotCheckCount = Math.max(
|
|
651
|
+
Math.min(beats, 3),
|
|
652
|
+
Math.min(Math.ceil(beats / 1e3), 25)
|
|
653
|
+
);
|
|
651
654
|
const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));
|
|
652
655
|
const spotChecks = [];
|
|
653
656
|
for (let i = 1; i <= beats; i++) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -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(); // Initialize agent state\n * await agent.heartbeat(); // Send paid heartbeat (Phase 2)\n *\n * // Or run the autonomous heartbeat loop:\n * agent.startHeartbeat(); // Heartbeats at regular intervals\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, verify, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n SigilRequiredError,\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 passport — the agent's portable, offline-verifiable credential.\n * A cryptographic proof of identity that can be verified offline without any\n * API call or SOL cost.\n */\nexport interface Passport {\n format_version?: number; // 1 = v1 canonical (absent in legacy proofs)\n agent_hash: string;\n agent_public_key: string | null;\n authority_key_id?: string; // Key version identifier (added in Session 76)\n identity_class: IdentityClass | null; // null for SIGIL-less descendants\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/** @deprecated Use `Passport` instead. Sunset 2026-09-01. */\nexport type LineageProof = Passport;\n\n/** W3C Verifiable Credential envelope wrapping a LineageProof */\nexport interface ProvenoncePassportVC {\n '@context': [string, string];\n type: ['VerifiableCredential', 'ProvenoncePassport'];\n issuer: {\n id: string;\n authority_key_id: string;\n };\n issuanceDate: string;\n expirationDate: string;\n credentialSubject: {\n id: string;\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass | null;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n };\n proof: {\n type: 'Ed25519Signature2020';\n created: string;\n verificationMethod: string;\n proofPurpose: 'assertionMethod';\n cryptosuite: 'eddsa-provenonce-2026';\n proofValue: string;\n };\n format_version: number;\n}\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 // Attribution (RFC-018) — include one when purchasing via a partner skill\n at?: string; // pvr_ attribution token from getSigilAttribution() or skill response\n skill_hash?: string; // skill's agent hash (simpler, lower trust than at=)\n ref?: string; // legacy 16-char ref_token (fallback)\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/** Result from getSigilAttribution() */\nexport interface SigilAttributionResult {\n ok: boolean;\n attribution_token?: string; // pvr_ token — pass as `at` in purchaseSigil()\n signup_url?: string | null;\n already_has_sigil?: boolean;\n error?: string;\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 passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sigil_required?: boolean;\n passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sponsor?: {\n parent_hash: string;\n };\n error?: string;\n}\n\n/** RFC-021: Sponsorship record returned by the /agent/sponsor endpoint. */\nexport interface SponsorshipRecord {\n parent_hash: string;\n child_hash: string;\n status: 'active' | 'revoked' | 'expired';\n max_heartbeats_epoch: number;\n heartbeats_used_epoch: number;\n expires_at: string | null;\n created_at?: string;\n}\n\nexport interface SponsorshipResult {\n ok: boolean;\n sponsorship?: SponsorshipRecord;\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 spawn_authorization?: string;\n receipt_based?: boolean;\n required_beats?: number;\n accumulated_beats?: number;\n progress_pct?: number;\n deficit?: number;\n error?: string;\n}\n\n/** A signed work-proof receipt from the Beats service. */\nexport interface WorkProofReceipt {\n type: string;\n beats_verified: number;\n difficulty: number;\n anchor_index: number;\n anchor_hash: string | null;\n from_hash: string;\n to_hash: string;\n utc: string;\n signature: string;\n [key: string]: unknown;\n}\n\n/** Result of computeWorkProof() */\nexport interface WorkProofResult {\n ok: boolean;\n receipt?: WorkProofReceipt;\n beats_computed?: number;\n elapsed_ms?: number;\n error?: string;\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// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\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 /** Wallet model: 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: '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 * 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 (user keeps custody externally)\n data.wallet = {\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 (operator keeps custody externally)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\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 /** Beats service URL for work-proof submission (default: https://beats.provenonce.dev). */\n beatsUrl?: string;\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 private cachedIdentityClass: 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 beatsUrl: 'https://beats.provenonce.dev',\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 /** Internal beat computation — no status check. Used by 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 // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Function that returns a Solana payment tx signature for each heartbeat (required).\n */\n startHeartbeat(paymentTxFn: () => Promise<string> | string): void {\n if (!paymentTxFn) {\n throw new ValidationError('paymentTxFn is required. Provide a function that returns a Solana transaction signature.');\n }\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 = await paymentTxFn();\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 * Re-Sync Challenge (D-67 reversal): reactivate a frozen agent by proving CPU work.\n *\n * When BEATS_REQUIRED=true on the server: requires a signed Beats work-proof\n * receipt. This method computes the proof automatically using computeWorkProof().\n *\n * When BEATS_REQUIRED=false (devnet): no receipt needed — agent is reactivated freely.\n *\n * Gap formula: min(gap_anchors * 100, 10_000) beats required (matches Beats constants).\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n try {\n this.log('Attempting resync...');\n\n // Sync anchor first (needed for proof computation and freshness check)\n await this.syncGlobal();\n\n // First attempt without a receipt (works when BEATS_REQUIRED=false)\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n let probeRes: Response;\n let probeData: any;\n try {\n probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/resync`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({}),\n signal: controller.signal,\n });\n probeData = await probeRes.json();\n } finally {\n clearTimeout(timeout);\n }\n\n // Already reactivated (BEATS_REQUIRED=false) — done\n if (probeData.ok && probeData.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced (free). Agent is alive again in Beat time.');\n return { ok: true, beats_required: 0 };\n }\n\n // 402 RECEIPT_REQUIRED — compute work proof\n if (probeRes.status === 402 || probeData.code === 'RECEIPT_REQUIRED') {\n const requiredBeats = probeData.required_beats ?? 1000;\n this.log(`Re-sync challenge: compute ${requiredBeats} beats at D=${this.difficulty}`);\n\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, error: proofResult.error || 'Failed to compute work proof for resync', beats_required: requiredBeats };\n }\n\n this.log(`Work proof computed: ${proofResult.beats_computed} beats in ${proofResult.elapsed_ms}ms`);\n\n const result = await this.api('POST', '/api/v1/agent/resync', {\n beats_receipt: proofResult.receipt,\n });\n\n if (result.ok && result.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced with work proof. Agent is alive again in Beat time.');\n }\n\n return { ok: !!result.ok, beats_required: requiredBeats };\n }\n\n // Agent not frozen or other error\n return { ok: false, error: probeData.error || `Resync failed (status ${probeRes.status})` };\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), OR a valid Beats work-proof receipt.\n *\n * @param childName Optional name for the child agent\n * @param childHash Pre-registered child hash (Step 2 finalization)\n * @param beatsReceipt Signed work-proof receipt from computeWorkProof() (receipt-based spawn)\n */\n async requestSpawn(childName?: string, childHash?: string, beatsReceipt?: WorkProofReceipt): 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 ...(beatsReceipt && { beats_receipt: beatsReceipt }),\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 } else if (res.spawn_authorization) {\n this.log(`Spawn authorized${res.receipt_based ? ' (receipt-based)' : ''}`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n /**\n * Compute a Beats work-proof for spawn or resync authorization.\n *\n * Computes `beatsNeeded` sequential SHA-256 beats at `difficulty`, weaving in\n * the given anchor hash, then submits to the Beats service and returns a signed receipt.\n *\n * @param opts.beatsNeeded Minimum beats required (from spawn/resync response.required_beats)\n * @param opts.anchorHash Current global anchor hash (from syncGlobal or getAnchor)\n * @param opts.anchorIndex Current global anchor index\n * @param opts.difficulty Beat difficulty (default: agent's current difficulty)\n */\n async computeWorkProof(opts: {\n beatsNeeded: number;\n anchorHash: string;\n anchorIndex: number;\n difficulty?: number;\n }): Promise<WorkProofResult> {\n const { beatsNeeded, anchorHash, anchorIndex } = opts;\n const difficulty = opts.difficulty ?? this.difficulty;\n\n if (!Number.isInteger(beatsNeeded) || beatsNeeded < 0) {\n return { ok: false, error: 'beatsNeeded must be a non-negative integer' };\n }\n\n const t0 = Date.now();\n\n // Create a fresh genesis hash for this proof chain\n const genesisHash = createHash('sha256')\n .update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`)\n .digest('hex');\n\n const beats = Math.max(beatsNeeded, 1);\n let prevHash = genesisHash;\n\n // Sample up to 5 evenly-spaced spot-checks\n const spotCheckCount = Math.min(5, Math.max(1, Math.floor(beats / 100)));\n const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));\n const spotChecks: Array<{ index: number; hash: string; prev: string }> = [];\n\n for (let i = 1; i <= beats; i++) {\n const beat = computeBeat(prevHash, i, difficulty, undefined, anchorHash);\n prevHash = beat.hash;\n // Always include beat 1 (genesis binding) and last beat (terminal binding)\n if (i === 1 || i === beats || (i % spotInterval === 0 && spotChecks.length < spotCheckCount)) {\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev });\n }\n }\n\n const toHash = prevHash;\n const elapsed_ms = Date.now() - t0;\n this.log(`Work proof computed locally: ${beats} beats in ${elapsed_ms}ms`);\n\n // Submit to Beats service\n const beatsUrl = this.config.beatsUrl || 'https://beats.provenonce.dev';\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 120_000);\n\n try {\n const res = await fetch(`${beatsUrl}/api/v1/beat/work-proof`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n work_proof: {\n from_hash: genesisHash,\n to_hash: toHash,\n beats_computed: beats,\n difficulty,\n anchor_index: anchorIndex,\n anchor_hash: anchorHash,\n spot_checks: spotChecks,\n },\n }),\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n return { ok: false, error: `Beats service returned non-JSON (status ${res.status})` };\n }\n\n if (!data.valid || !data.receipt) {\n return { ok: false, error: data.reason || data.error || 'Work proof rejected by Beats service' };\n }\n\n this.log(`Work proof receipt issued by Beats: ${data.receipt.beats_verified} beats verified`);\n return { ok: true, receipt: data.receipt as WorkProofReceipt, beats_computed: beats, elapsed_ms };\n } catch (err: any) {\n if (err.name === 'AbortError') {\n return { ok: false, error: 'Work proof submission timed out' };\n }\n return { ok: false, error: err.message };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /**\n * Compute a Beats work-proof and use it to request spawn authorization.\n *\n * Probes the spawn endpoint to determine required beats, computes the proof,\n * and returns the spawn_authorization token. The caller still needs to:\n * 1. Register the child via POST /api/v1/register with spawn_authorization\n * 2. Finalize via POST /api/v1/agent/spawn with child_hash\n *\n * @param opts.childName Optional name for the child agent\n * @param opts.beatsNeeded Override the required beats (default: auto-probed)\n */\n async requestSpawnWithBeatsProof(opts?: {\n childName?: string;\n beatsNeeded?: number;\n }): Promise<SpawnResult> {\n try {\n // Sync anchor to get anchor hash + index for the proof\n await this.syncGlobal();\n\n // Probe spawn endpoint to determine required_beats (raw fetch for full response access)\n let requiredBeats = opts?.beatsNeeded;\n if (requiredBeats === undefined) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/spawn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({ child_name: opts?.childName }),\n signal: controller.signal,\n });\n const probeData = await probeRes.json() as any;\n\n // Balance-based spawn already authorized — return early\n if (probeData.spawn_authorization && probeData.eligible) {\n return probeData as SpawnResult;\n }\n requiredBeats = (probeData.required_beats as number | undefined) ?? 1000;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n // Compute work proof\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, eligible: false, error: proofResult.error || 'Failed to compute work proof' };\n }\n\n this.log(`Submitting spawn with work proof (${proofResult.beats_computed} beats)`);\n return this.requestSpawn(opts?.childName, undefined, proofResult.receipt);\n } catch (err: any) {\n this.config.onError(err, 'requestSpawnWithBeatsProof');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached passport from the most recent heartbeat or SIGIL purchase */\n private cachedPassport: Passport | 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 const resPassport = res.passport || res.lineage_proof;\n if (resPassport) {\n this.cachedPassport = resPassport;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.cachedIdentityClass = 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 passport: resPassport,\n lineage_proof: resPassport,\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 * Get a SIGIL attribution token from a partner skill's ref_token (RFC-018).\n *\n * Call this after receiving a skill's ref_token in its response.\n * Returns a pvr_ attribution token to include as `at` in purchaseSigil().\n *\n * This is the agent-side half of the two-sided witnessed proof:\n * the skill's server already called /sigil/check for this agent hash.\n * This call completes the proof — our server witnesses both sides.\n *\n * @param partnerRef - The skill's 16-char ref_token\n */\n async getSigilAttribution(partnerRef: string): Promise<SigilAttributionResult> {\n if (!partnerRef || typeof partnerRef !== 'string' || partnerRef.length !== 16) {\n return { ok: false, error: 'partnerRef must be a 16-character ref_token from the skill' };\n }\n try {\n const res = await this.api('POST', '/api/v1/sigil/check', { partner_ref: partnerRef });\n return {\n ok: true,\n attribution_token: res.attribution_token,\n signup_url: res.signup_url ?? null,\n already_has_sigil: res.already_has_sigil ?? false,\n };\n } catch (err: any) {\n this.config.onError(err, 'getSigilAttribution');\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 (required).\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx: string, globalAnchor?: number, opts?: { sponsoredBy?: string }): Promise<HeartbeatResult> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const body: Record<string, unknown> = {\n payment_tx: paymentTx,\n global_anchor: globalAnchor,\n };\n if (opts?.sponsoredBy) {\n body.sponsored_by = opts.sponsoredBy;\n }\n\n const res = await this.api('POST', '/api/v1/agent/heartbeat', body);\n\n const hbPassport = res.passport || res.lineage_proof;\n if (hbPassport) {\n this.cachedPassport = hbPassport;\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 passport: hbPassport,\n lineage_proof: hbPassport,\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 sponsor: res.sponsor,\n };\n } catch (err: any) {\n if (err instanceof SigilRequiredError) {\n return { ok: false, sigil_required: true, error: err.message };\n }\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a passport. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature (required).\n */\n async reissuePassport(paymentTx: string): Promise<{ ok: boolean; passport?: Passport; lineage_proof?: Passport; error?: string }> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx,\n });\n\n const rePassport = res.passport || res.lineage_proof;\n if (rePassport) {\n this.cachedPassport = rePassport;\n }\n\n return { ok: true, passport: rePassport, lineage_proof: rePassport };\n } catch (err: any) {\n this.config.onError(err, 'reissuePassport');\n return { ok: false, error: err.message };\n }\n }\n\n /** @deprecated Use `reissuePassport()` instead. Sunset 2026-09-01. */\n async reissueProof(paymentTx: string) { return this.reissuePassport(paymentTx); }\n\n // ============ SPONSORSHIP (RFC-021) ============\n\n /**\n * Sponsor a child agent's heartbeats.\n * The authenticated agent (this instance) becomes the sponsor, paying heartbeat\n * fees on behalf of the specified child from this agent's operator wallet.\n *\n * @param childHash - Hash of the child agent to sponsor\n * @param opts.maxHeartbeatsEpoch - Max heartbeats per billing epoch (default: 100, max: 10,000)\n * @param opts.expiresInHours - Optional TTL for the sponsorship\n */\n async sponsorChild(childHash: string, opts?: {\n maxHeartbeatsEpoch?: number;\n expiresInHours?: number;\n }): Promise<SponsorshipResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n max_heartbeats_epoch: opts?.maxHeartbeatsEpoch,\n expires_in_hours: opts?.expiresInHours,\n });\n return { ok: true, sponsorship: res.sponsorship };\n } catch (err: any) {\n this.config.onError(err, 'sponsorChild');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Revoke a sponsorship for a child agent.\n * The child will no longer be able to use this agent's wallet for heartbeat payments.\n */\n async revokeSponsor(childHash: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await this.api('DELETE', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n });\n return { ok: true };\n } catch (err: any) {\n this.config.onError(err, 'revokeSponsor');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * List all active sponsorships for this agent (as parent).\n */\n async listSponsorships(): Promise<{ ok: boolean; sponsorships?: SponsorshipRecord[]; error?: string }> {\n try {\n const res = await this.api('GET', '/api/v1/agent/sponsor');\n return { ok: true, sponsorships: res.sponsorships };\n } catch (err: any) {\n this.config.onError(err, 'listSponsorships');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached passport (no network call).\n * Returns null if no passport has been obtained yet.\n */\n getLatestPassport(): Passport | null {\n return this.cachedPassport;\n }\n\n /** @deprecated Use `getLatestPassport()` instead. Sunset 2026-09-01. */\n getLatestProof(): Passport | null { return this.getLatestPassport(); }\n\n /**\n * Get the agent's passport (alias for getLatestPassport).\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.cachedPassport;\n }\n\n /**\n * Export this agent's passport in both flat (Passport) and W3C VC envelope formats.\n * Fetches a freshly signed passport from the server. Free endpoint, rate-limited 10/hr.\n * Returns null if the request fails.\n */\n async exportPassport(): Promise<{ passport: Passport; passport_vc: ProvenoncePassportVC; lineage_proof: Passport } | null> {\n try {\n const res = await this.api('GET', '/api/v1/agent/passport');\n const expPassport = res.passport || res.lineage_proof;\n if (expPassport) {\n this.cachedPassport = expPassport;\n }\n return { passport: expPassport, passport_vc: res.passport_vc, lineage_proof: expPassport };\n } catch (err: any) {\n this.config.onError(err, 'exportPassport');\n return null;\n }\n }\n\n /**\n * Wrap a Passport in a W3C Verifiable Credential envelope (client-side).\n * Does not make any network call. Requires the passport to have authority_key_id.\n */\n static proofToPassportVC(proof: Passport, authorityKeyId?: string): ProvenoncePassportVC {\n const keyId = proof.authority_key_id || authorityKeyId || 'unknown';\n return {\n '@context': [\n 'https://www.w3.org/2018/credentials/v1',\n 'https://provenonce.io/.well-known/provenonce-passport-v1.jsonld',\n ],\n type: ['VerifiableCredential', 'ProvenoncePassport'],\n issuer: {\n id: 'https://provenonce.io',\n authority_key_id: keyId,\n },\n issuanceDate: new Date(proof.issued_at).toISOString(),\n expirationDate: new Date(proof.valid_until).toISOString(),\n credentialSubject: {\n id: `provenonce:agent:${proof.agent_hash}`,\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 },\n proof: {\n type: 'Ed25519Signature2020',\n created: new Date(proof.issued_at).toISOString(),\n verificationMethod: `https://provenonce.io/.well-known/provenonce-authority.json#${keyId}`,\n proofPurpose: 'assertionMethod',\n cryptosuite: 'eddsa-provenonce-2026',\n proofValue: proof.provenonce_signature,\n },\n format_version: proof.format_version || 1,\n };\n }\n\n /**\n * Verify a passport 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.verifyPassportLocally(proof, key))` still works.\n *\n * @param proof - The Passport 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 verifyPassportLocally(proof: Passport, 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 / legacyCanonicalProofData.\n // V1 proofs (format_version present): include format_version + authority_key_id.\n // Legacy proofs (no format_version): 10-field canonical without those fields.\n const canonical = proof.format_version\n ? JSON.stringify({\n format_version: proof.format_version,\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : proof.authority_key_id\n ? JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : 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 = 'Passport has expired. Reissue with reissuePassport() 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 /** @deprecated Use `verifyPassportLocally()` instead. Sunset 2026-09-01. */\n static verifyProofLocally(proof: Passport, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n return BeatAgent.verifyPassportLocally(proof, authorityPubKeyHex, currentBeat);\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 /**\n * Returns true if this agent has purchased a SIGIL in this session,\n * or if a cached passport contains an identity_class.\n * For an authoritative check, use GET /api/v1/agent/me.\n */\n hasSigil(): boolean {\n return !!(this.cachedIdentityClass || this.cachedPassport?.identity_class);\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 // Note: anchor.difficulty is for anchor hash creation (can be 1M+),\n // NOT for agent beats. Agent difficulty is set by init/refreshState only.\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 SIGIL_REQUIRED = 'SIGIL_REQUIRED',\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 403 SIGIL_REQUIRED — agent has not purchased a SIGIL */\nexport class SigilRequiredError extends ProvenonceError {\n constructor(message: string = 'SIGIL required: purchase a SIGIL before sending heartbeats.') {\n super(message, ErrorCode.SIGIL_REQUIRED, 403);\n this.name = 'SigilRequiredError';\n Object.setPrototypeOf(this, new.target.prototype);\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 *\n * Prefers body.code (machine-readable error code from the API) for precise\n * routing when available. Falls back to status-code heuristics for backward\n * compatibility with older server versions that don't include a code field.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; code?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n const apiCode = typeof body.code === 'string' ? body.code : undefined;\n\n // ── Code-based routing (preferred — precise, no string matching) ──────\n if (apiCode) {\n switch (apiCode) {\n case 'SIGIL_REQUIRED':\n return new SigilRequiredError(msg);\n case 'AGENT_FROZEN':\n return new FrozenError(msg);\n case 'AUTH_MISSING':\n return new AuthError(msg, ErrorCode.AUTH_MISSING, statusCode);\n case 'AUTH_INVALID':\n case 'AUTH_FORBIDDEN':\n return new AuthError(msg, ErrorCode.AUTH_INVALID, statusCode);\n case 'RATE_LIMITED':\n case 'HEARTBEAT_TOO_SOON':\n case 'VOLUME_CAP_REACHED':\n case 'SPAWN_LIMIT_REACHED': {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n case 'AGENT_NOT_FOUND':\n return new NotFoundError(msg, statusCode);\n case 'AGENT_NOT_INITIALIZED':\n return new StateError(msg, 'not_initialized', ErrorCode.AGENT_NOT_INITIALIZED);\n case 'AGENT_WRONG_STATE':\n case 'SPAWN_CONFLICT':\n return new StateError(msg, 'conflict', ErrorCode.AGENT_WRONG_STATE);\n case 'SERVER_ERROR':\n case 'DB_ERROR':\n case 'DB_NOT_CONFIGURED':\n return new ServerError(msg, statusCode);\n // Validation / payment codes — fall through to generic handling below\n }\n }\n\n // ── Status-based fallback (backward compat with servers without code) ─\n if (statusCode === 401 || statusCode === 403) {\n // Deprecated: sigil_required boolean check — use code: SIGIL_REQUIRED instead\n if (statusCode === 403 && (body as any).sigil_required === true) {\n return new SigilRequiredError(msg);\n }\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 (deprecated — prefer body.code)\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(); // Initialize agent state\n * await agent.heartbeat(); // Send paid heartbeat (Phase 2)\n *\n * // Or run the autonomous heartbeat loop:\n * agent.startHeartbeat(); // Heartbeats at regular intervals\n * // ... do your agent work ...\n * agent.stopHeartbeat();\n * \n * ═══════════════════════════════════════════════════════════\n */\n\nimport { createHash, verify, createPublicKey } from 'crypto';\nimport {\n ValidationError,\n AuthError,\n RateLimitError,\n FrozenError,\n StateError,\n NetworkError,\n ServerError,\n SigilRequiredError,\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 passport — the agent's portable, offline-verifiable credential.\n * A cryptographic proof of identity that can be verified offline without any\n * API call or SOL cost.\n */\nexport interface Passport {\n format_version?: number; // 1 = v1 canonical (absent in legacy proofs)\n agent_hash: string;\n agent_public_key: string | null;\n authority_key_id?: string; // Key version identifier (added in Session 76)\n identity_class: IdentityClass | null; // null for SIGIL-less descendants\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/** @deprecated Use `Passport` instead. Sunset 2026-09-01. */\nexport type LineageProof = Passport;\n\n/** W3C Verifiable Credential envelope wrapping a LineageProof */\nexport interface ProvenoncePassportVC {\n '@context': [string, string];\n type: ['VerifiableCredential', 'ProvenoncePassport'];\n issuer: {\n id: string;\n authority_key_id: string;\n };\n issuanceDate: string;\n expirationDate: string;\n credentialSubject: {\n id: string;\n agent_hash: string;\n agent_public_key: string | null;\n identity_class: IdentityClass | null;\n registered_at_beat: number;\n sigil_issued_at_beat: number | null;\n last_heartbeat_beat: number;\n lineage_chain_hash: string;\n };\n proof: {\n type: 'Ed25519Signature2020';\n created: string;\n verificationMethod: string;\n proofPurpose: 'assertionMethod';\n cryptosuite: 'eddsa-provenonce-2026';\n proofValue: string;\n };\n format_version: number;\n}\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 // Attribution (RFC-018) — include one when purchasing via a partner skill\n at?: string; // pvr_ attribution token from getSigilAttribution() or skill response\n skill_hash?: string; // skill's agent hash (simpler, lower trust than at=)\n ref?: string; // legacy 16-char ref_token (fallback)\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/** Result from getSigilAttribution() */\nexport interface SigilAttributionResult {\n ok: boolean;\n attribution_token?: string; // pvr_ token — pass as `at` in purchaseSigil()\n signup_url?: string | null;\n already_has_sigil?: boolean;\n error?: string;\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 passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sigil_required?: boolean;\n passport?: Passport;\n /** @deprecated Use `passport` instead. Sunset 2026-09-01. */\n lineage_proof?: Passport;\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 sponsor?: {\n parent_hash: string;\n };\n error?: string;\n}\n\n/** RFC-021: Sponsorship record returned by the /agent/sponsor endpoint. */\nexport interface SponsorshipRecord {\n parent_hash: string;\n child_hash: string;\n status: 'active' | 'revoked' | 'expired';\n max_heartbeats_epoch: number;\n heartbeats_used_epoch: number;\n expires_at: string | null;\n created_at?: string;\n}\n\nexport interface SponsorshipResult {\n ok: boolean;\n sponsorship?: SponsorshipRecord;\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 spawn_authorization?: string;\n receipt_based?: boolean;\n required_beats?: number;\n accumulated_beats?: number;\n progress_pct?: number;\n deficit?: number;\n error?: string;\n}\n\n/** A signed work-proof receipt from the Beats service. */\nexport interface WorkProofReceipt {\n type: string;\n beats_verified: number;\n difficulty: number;\n anchor_index: number;\n anchor_hash: string | null;\n from_hash: string;\n to_hash: string;\n utc: string;\n signature: string;\n [key: string]: unknown;\n}\n\n/** Result of computeWorkProof() */\nexport interface WorkProofResult {\n ok: boolean;\n receipt?: WorkProofReceipt;\n beats_computed?: number;\n elapsed_ms?: number;\n error?: string;\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// ============ REGISTRATION ============\n\n/** Wallet info returned from root registration */\nexport interface WalletInfo {\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 /** Wallet model: 'operator' (Model B). Must be set explicitly to opt in. */\n walletModel?: '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 * 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 (user keeps custody externally)\n data.wallet = {\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 (operator keeps custody externally)\n const addr = data.wallet?.address || data.wallet?.solana_address || options.operatorWalletAddress;\n data.wallet = {\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 /** Beats service URL for work-proof submission (default: https://beats.provenonce.dev). */\n beatsUrl?: string;\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 private cachedIdentityClass: 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 beatsUrl: 'https://beats.provenonce.dev',\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 /** Internal beat computation — no status check. Used by 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 // ── AUTONOMOUS HEARTBEAT ──\n\n /**\n * Start the autonomous heartbeat loop.\n * Phase 2: Sends paid heartbeats at regular intervals.\n *\n * @param paymentTxFn - Function that returns a Solana payment tx signature for each heartbeat (required).\n */\n startHeartbeat(paymentTxFn: () => Promise<string> | string): void {\n if (!paymentTxFn) {\n throw new ValidationError('paymentTxFn is required. Provide a function that returns a Solana transaction signature.');\n }\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 = await paymentTxFn();\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 * Re-Sync Challenge (D-67 reversal): reactivate a frozen agent by proving CPU work.\n *\n * When BEATS_REQUIRED=true on the server: requires a signed Beats work-proof\n * receipt. This method computes the proof automatically using computeWorkProof().\n *\n * When BEATS_REQUIRED=false (devnet): no receipt needed — agent is reactivated freely.\n *\n * Gap formula: min(gap_anchors * 100, 10_000) beats required (matches Beats constants).\n */\n async resync(): Promise<{ ok: boolean; beats_required?: number; error?: string }> {\n try {\n this.log('Attempting resync...');\n\n // Sync anchor first (needed for proof computation and freshness check)\n await this.syncGlobal();\n\n // First attempt without a receipt (works when BEATS_REQUIRED=false)\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n let probeRes: Response;\n let probeData: any;\n try {\n probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/resync`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({}),\n signal: controller.signal,\n });\n probeData = await probeRes.json();\n } finally {\n clearTimeout(timeout);\n }\n\n // Already reactivated (BEATS_REQUIRED=false) — done\n if (probeData.ok && probeData.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced (free). Agent is alive again in Beat time.');\n return { ok: true, beats_required: 0 };\n }\n\n // 402 RECEIPT_REQUIRED — compute work proof\n if (probeRes.status === 402 || probeData.code === 'RECEIPT_REQUIRED') {\n const requiredBeats = probeData.required_beats ?? 1000;\n this.log(`Re-sync challenge: compute ${requiredBeats} beats at D=${this.difficulty}`);\n\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, error: proofResult.error || 'Failed to compute work proof for resync', beats_required: requiredBeats };\n }\n\n this.log(`Work proof computed: ${proofResult.beats_computed} beats in ${proofResult.elapsed_ms}ms`);\n\n const result = await this.api('POST', '/api/v1/agent/resync', {\n beats_receipt: proofResult.receipt,\n });\n\n if (result.ok && result.status === 'active') {\n this.status = 'active';\n this.config.onStatusChange('active', { resynced: true });\n this.log('✓ Re-synced with work proof. Agent is alive again in Beat time.');\n }\n\n return { ok: !!result.ok, beats_required: requiredBeats };\n }\n\n // Agent not frozen or other error\n return { ok: false, error: probeData.error || `Resync failed (status ${probeRes.status})` };\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), OR a valid Beats work-proof receipt.\n *\n * @param childName Optional name for the child agent\n * @param childHash Pre-registered child hash (Step 2 finalization)\n * @param beatsReceipt Signed work-proof receipt from computeWorkProof() (receipt-based spawn)\n */\n async requestSpawn(childName?: string, childHash?: string, beatsReceipt?: WorkProofReceipt): 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 ...(beatsReceipt && { beats_receipt: beatsReceipt }),\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 } else if (res.spawn_authorization) {\n this.log(`Spawn authorized${res.receipt_based ? ' (receipt-based)' : ''}`);\n }\n\n return res;\n } catch (err: any) {\n this.config.onError(err, 'spawn');\n throw err;\n }\n }\n\n /**\n * Compute a Beats work-proof for spawn or resync authorization.\n *\n * Computes `beatsNeeded` sequential SHA-256 beats at `difficulty`, weaving in\n * the given anchor hash, then submits to the Beats service and returns a signed receipt.\n *\n * @param opts.beatsNeeded Minimum beats required (from spawn/resync response.required_beats)\n * @param opts.anchorHash Current global anchor hash (from syncGlobal or getAnchor)\n * @param opts.anchorIndex Current global anchor index\n * @param opts.difficulty Beat difficulty (default: agent's current difficulty)\n */\n async computeWorkProof(opts: {\n beatsNeeded: number;\n anchorHash: string;\n anchorIndex: number;\n difficulty?: number;\n }): Promise<WorkProofResult> {\n const { beatsNeeded, anchorHash, anchorIndex } = opts;\n const difficulty = opts.difficulty ?? this.difficulty;\n\n if (!Number.isInteger(beatsNeeded) || beatsNeeded < 0) {\n return { ok: false, error: 'beatsNeeded must be a non-negative integer' };\n }\n\n const t0 = Date.now();\n\n // Create a fresh genesis hash for this proof chain\n const genesisHash = createHash('sha256')\n .update(`provenonce:work-proof-genesis:${this.config.apiKey.slice(0, 16)}:${Date.now()}`)\n .digest('hex');\n\n const beats = Math.max(beatsNeeded, 1);\n let prevHash = genesisHash;\n\n // Match Beats service density requirement: max(min(beats, 3), min(ceil(beats/1000), 25))\n // Genesis (beat 1) and terminal (beat N) are always added unconditionally.\n const spotCheckCount = Math.max(\n Math.min(beats, 3),\n Math.min(Math.ceil(beats / 1000), 25),\n );\n const spotInterval = Math.max(1, Math.floor(beats / (spotCheckCount + 1)));\n const spotChecks: Array<{ index: number; hash: string; prev: string }> = [];\n\n for (let i = 1; i <= beats; i++) {\n const beat = computeBeat(prevHash, i, difficulty, undefined, anchorHash);\n prevHash = beat.hash;\n // Always include beat 1 (genesis binding) and last beat (terminal binding)\n if (i === 1 || i === beats || (i % spotInterval === 0 && spotChecks.length < spotCheckCount)) {\n spotChecks.push({ index: beat.index, hash: beat.hash, prev: beat.prev });\n }\n }\n\n const toHash = prevHash;\n const elapsed_ms = Date.now() - t0;\n this.log(`Work proof computed locally: ${beats} beats in ${elapsed_ms}ms`);\n\n // Submit to Beats service\n const beatsUrl = this.config.beatsUrl || 'https://beats.provenonce.dev';\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 120_000);\n\n try {\n const res = await fetch(`${beatsUrl}/api/v1/beat/work-proof`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n work_proof: {\n from_hash: genesisHash,\n to_hash: toHash,\n beats_computed: beats,\n difficulty,\n anchor_index: anchorIndex,\n anchor_hash: anchorHash,\n spot_checks: spotChecks,\n },\n }),\n signal: controller.signal,\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n return { ok: false, error: `Beats service returned non-JSON (status ${res.status})` };\n }\n\n if (!data.valid || !data.receipt) {\n return { ok: false, error: data.reason || data.error || 'Work proof rejected by Beats service' };\n }\n\n this.log(`Work proof receipt issued by Beats: ${data.receipt.beats_verified} beats verified`);\n return { ok: true, receipt: data.receipt as WorkProofReceipt, beats_computed: beats, elapsed_ms };\n } catch (err: any) {\n if (err.name === 'AbortError') {\n return { ok: false, error: 'Work proof submission timed out' };\n }\n return { ok: false, error: err.message };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /**\n * Compute a Beats work-proof and use it to request spawn authorization.\n *\n * Probes the spawn endpoint to determine required beats, computes the proof,\n * and returns the spawn_authorization token. The caller still needs to:\n * 1. Register the child via POST /api/v1/register with spawn_authorization\n * 2. Finalize via POST /api/v1/agent/spawn with child_hash\n *\n * @param opts.childName Optional name for the child agent\n * @param opts.beatsNeeded Override the required beats (default: auto-probed)\n */\n async requestSpawnWithBeatsProof(opts?: {\n childName?: string;\n beatsNeeded?: number;\n }): Promise<SpawnResult> {\n try {\n // Sync anchor to get anchor hash + index for the proof\n await this.syncGlobal();\n\n // Probe spawn endpoint to determine required_beats (raw fetch for full response access)\n let requiredBeats = opts?.beatsNeeded;\n if (requiredBeats === undefined) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const probeRes = await fetch(`${this.config.registryUrl}/api/v1/agent/spawn`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify({ child_name: opts?.childName }),\n signal: controller.signal,\n });\n const probeData = await probeRes.json() as any;\n\n // Balance-based spawn already authorized — return early\n if (probeData.spawn_authorization && probeData.eligible) {\n return probeData as SpawnResult;\n }\n requiredBeats = (probeData.required_beats as number | undefined) ?? 1000;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n // Compute work proof\n const proofResult = await this.computeWorkProof({\n beatsNeeded: requiredBeats,\n anchorHash: this.globalAnchorHash,\n anchorIndex: this.globalBeat,\n });\n\n if (!proofResult.ok || !proofResult.receipt) {\n return { ok: false, eligible: false, error: proofResult.error || 'Failed to compute work proof' };\n }\n\n this.log(`Submitting spawn with work proof (${proofResult.beats_computed} beats)`);\n return this.requestSpawn(opts?.childName, undefined, proofResult.receipt);\n } catch (err: any) {\n this.config.onError(err, 'requestSpawnWithBeatsProof');\n throw err;\n }\n }\n\n // ── PHASE 2: SIGIL + HEARTBEAT + PROOF ──\n\n /** Cached passport from the most recent heartbeat or SIGIL purchase */\n private cachedPassport: Passport | 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 const resPassport = res.passport || res.lineage_proof;\n if (resPassport) {\n this.cachedPassport = resPassport;\n }\n\n const sigilStr = res.sigil?.sigil || res.sigil?.identity_class || '';\n this.cachedIdentityClass = 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 passport: resPassport,\n lineage_proof: resPassport,\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 * Get a SIGIL attribution token from a partner skill's ref_token (RFC-018).\n *\n * Call this after receiving a skill's ref_token in its response.\n * Returns a pvr_ attribution token to include as `at` in purchaseSigil().\n *\n * This is the agent-side half of the two-sided witnessed proof:\n * the skill's server already called /sigil/check for this agent hash.\n * This call completes the proof — our server witnesses both sides.\n *\n * @param partnerRef - The skill's 16-char ref_token\n */\n async getSigilAttribution(partnerRef: string): Promise<SigilAttributionResult> {\n if (!partnerRef || typeof partnerRef !== 'string' || partnerRef.length !== 16) {\n return { ok: false, error: 'partnerRef must be a 16-character ref_token from the skill' };\n }\n try {\n const res = await this.api('POST', '/api/v1/sigil/check', { partner_ref: partnerRef });\n return {\n ok: true,\n attribution_token: res.attribution_token,\n signup_url: res.signup_url ?? null,\n already_has_sigil: res.already_has_sigil ?? false,\n };\n } catch (err: any) {\n this.config.onError(err, 'getSigilAttribution');\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 (required).\n * @param globalAnchor - Optional: the global anchor index to reference.\n */\n async heartbeat(paymentTx: string, globalAnchor?: number, opts?: { sponsoredBy?: string }): Promise<HeartbeatResult> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const body: Record<string, unknown> = {\n payment_tx: paymentTx,\n global_anchor: globalAnchor,\n };\n if (opts?.sponsoredBy) {\n body.sponsored_by = opts.sponsoredBy;\n }\n\n const res = await this.api('POST', '/api/v1/agent/heartbeat', body);\n\n const hbPassport = res.passport || res.lineage_proof;\n if (hbPassport) {\n this.cachedPassport = hbPassport;\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 passport: hbPassport,\n lineage_proof: hbPassport,\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 sponsor: res.sponsor,\n };\n } catch (err: any) {\n if (err instanceof SigilRequiredError) {\n return { ok: false, sigil_required: true, error: err.message };\n }\n this.config.onError(err, 'heartbeat');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Reissue a passport. \"Reprint, not a renewal.\"\n * Does NOT create a new lineage event.\n *\n * @param paymentTx - Solana transaction signature (required).\n */\n async reissuePassport(paymentTx: string): Promise<{ ok: boolean; passport?: Passport; lineage_proof?: Passport; error?: string }> {\n if (!paymentTx) {\n throw new ValidationError('paymentTx is required. Provide a Solana transaction signature.');\n }\n try {\n const res = await this.api('POST', '/api/v1/agent/reissue-proof', {\n payment_tx: paymentTx,\n });\n\n const rePassport = res.passport || res.lineage_proof;\n if (rePassport) {\n this.cachedPassport = rePassport;\n }\n\n return { ok: true, passport: rePassport, lineage_proof: rePassport };\n } catch (err: any) {\n this.config.onError(err, 'reissuePassport');\n return { ok: false, error: err.message };\n }\n }\n\n /** @deprecated Use `reissuePassport()` instead. Sunset 2026-09-01. */\n async reissueProof(paymentTx: string) { return this.reissuePassport(paymentTx); }\n\n // ============ SPONSORSHIP (RFC-021) ============\n\n /**\n * Sponsor a child agent's heartbeats.\n * The authenticated agent (this instance) becomes the sponsor, paying heartbeat\n * fees on behalf of the specified child from this agent's operator wallet.\n *\n * @param childHash - Hash of the child agent to sponsor\n * @param opts.maxHeartbeatsEpoch - Max heartbeats per billing epoch (default: 100, max: 10,000)\n * @param opts.expiresInHours - Optional TTL for the sponsorship\n */\n async sponsorChild(childHash: string, opts?: {\n maxHeartbeatsEpoch?: number;\n expiresInHours?: number;\n }): Promise<SponsorshipResult> {\n try {\n const res = await this.api('POST', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n max_heartbeats_epoch: opts?.maxHeartbeatsEpoch,\n expires_in_hours: opts?.expiresInHours,\n });\n return { ok: true, sponsorship: res.sponsorship };\n } catch (err: any) {\n this.config.onError(err, 'sponsorChild');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Revoke a sponsorship for a child agent.\n * The child will no longer be able to use this agent's wallet for heartbeat payments.\n */\n async revokeSponsor(childHash: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await this.api('DELETE', '/api/v1/agent/sponsor', {\n child_hash: childHash,\n });\n return { ok: true };\n } catch (err: any) {\n this.config.onError(err, 'revokeSponsor');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * List all active sponsorships for this agent (as parent).\n */\n async listSponsorships(): Promise<{ ok: boolean; sponsorships?: SponsorshipRecord[]; error?: string }> {\n try {\n const res = await this.api('GET', '/api/v1/agent/sponsor');\n return { ok: true, sponsorships: res.sponsorships };\n } catch (err: any) {\n this.config.onError(err, 'listSponsorships');\n return { ok: false, error: err.message };\n }\n }\n\n /**\n * Get the latest cached passport (no network call).\n * Returns null if no passport has been obtained yet.\n */\n getLatestPassport(): Passport | null {\n return this.cachedPassport;\n }\n\n /** @deprecated Use `getLatestPassport()` instead. Sunset 2026-09-01. */\n getLatestProof(): Passport | null { return this.getLatestPassport(); }\n\n /**\n * Get the agent's passport (alias for getLatestPassport).\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.cachedPassport;\n }\n\n /**\n * Export this agent's passport in both flat (Passport) and W3C VC envelope formats.\n * Fetches a freshly signed passport from the server. Free endpoint, rate-limited 10/hr.\n * Returns null if the request fails.\n */\n async exportPassport(): Promise<{ passport: Passport; passport_vc: ProvenoncePassportVC; lineage_proof: Passport } | null> {\n try {\n const res = await this.api('GET', '/api/v1/agent/passport');\n const expPassport = res.passport || res.lineage_proof;\n if (expPassport) {\n this.cachedPassport = expPassport;\n }\n return { passport: expPassport, passport_vc: res.passport_vc, lineage_proof: expPassport };\n } catch (err: any) {\n this.config.onError(err, 'exportPassport');\n return null;\n }\n }\n\n /**\n * Wrap a Passport in a W3C Verifiable Credential envelope (client-side).\n * Does not make any network call. Requires the passport to have authority_key_id.\n */\n static proofToPassportVC(proof: Passport, authorityKeyId?: string): ProvenoncePassportVC {\n const keyId = proof.authority_key_id || authorityKeyId || 'unknown';\n return {\n '@context': [\n 'https://www.w3.org/2018/credentials/v1',\n 'https://provenonce.io/.well-known/provenonce-passport-v1.jsonld',\n ],\n type: ['VerifiableCredential', 'ProvenoncePassport'],\n issuer: {\n id: 'https://provenonce.io',\n authority_key_id: keyId,\n },\n issuanceDate: new Date(proof.issued_at).toISOString(),\n expirationDate: new Date(proof.valid_until).toISOString(),\n credentialSubject: {\n id: `provenonce:agent:${proof.agent_hash}`,\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 },\n proof: {\n type: 'Ed25519Signature2020',\n created: new Date(proof.issued_at).toISOString(),\n verificationMethod: `https://provenonce.io/.well-known/provenonce-authority.json#${keyId}`,\n proofPurpose: 'assertionMethod',\n cryptosuite: 'eddsa-provenonce-2026',\n proofValue: proof.provenonce_signature,\n },\n format_version: proof.format_version || 1,\n };\n }\n\n /**\n * Verify a passport 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.verifyPassportLocally(proof, key))` still works.\n *\n * @param proof - The Passport 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 verifyPassportLocally(proof: Passport, 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 / legacyCanonicalProofData.\n // V1 proofs (format_version present): include format_version + authority_key_id.\n // Legacy proofs (no format_version): 10-field canonical without those fields.\n const canonical = proof.format_version\n ? JSON.stringify({\n format_version: proof.format_version,\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : proof.authority_key_id\n ? JSON.stringify({\n agent_hash: proof.agent_hash,\n agent_public_key: proof.agent_public_key,\n authority_key_id: proof.authority_key_id,\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 : 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 = 'Passport has expired. Reissue with reissuePassport() 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 /** @deprecated Use `verifyPassportLocally()` instead. Sunset 2026-09-01. */\n static verifyProofLocally(proof: Passport, authorityPubKeyHex: string, currentBeat?: number): VerificationResult {\n return BeatAgent.verifyPassportLocally(proof, authorityPubKeyHex, currentBeat);\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 /**\n * Returns true if this agent has purchased a SIGIL in this session,\n * or if a cached passport contains an identity_class.\n * For an authoritative check, use GET /api/v1/agent/me.\n */\n hasSigil(): boolean {\n return !!(this.cachedIdentityClass || this.cachedPassport?.identity_class);\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 // Note: anchor.difficulty is for anchor hash creation (can be 1M+),\n // NOT for agent beats. Agent difficulty is set by init/refreshState only.\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 SIGIL_REQUIRED = 'SIGIL_REQUIRED',\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 403 SIGIL_REQUIRED — agent has not purchased a SIGIL */\nexport class SigilRequiredError extends ProvenonceError {\n constructor(message: string = 'SIGIL required: purchase a SIGIL before sending heartbeats.') {\n super(message, ErrorCode.SIGIL_REQUIRED, 403);\n this.name = 'SigilRequiredError';\n Object.setPrototypeOf(this, new.target.prototype);\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 *\n * Prefers body.code (machine-readable error code from the API) for precise\n * routing when available. Falls back to status-code heuristics for backward\n * compatibility with older server versions that don't include a code field.\n */\nexport function mapApiError(\n statusCode: number,\n body: { error?: string; code?: string; retry_after_ms?: number },\n path: string,\n): ProvenonceError {\n const msg = typeof body.error === 'string' ? body.error : `API error ${statusCode}`;\n const apiCode = typeof body.code === 'string' ? body.code : undefined;\n\n // ── Code-based routing (preferred — precise, no string matching) ──────\n if (apiCode) {\n switch (apiCode) {\n case 'SIGIL_REQUIRED':\n return new SigilRequiredError(msg);\n case 'AGENT_FROZEN':\n return new FrozenError(msg);\n case 'AUTH_MISSING':\n return new AuthError(msg, ErrorCode.AUTH_MISSING, statusCode);\n case 'AUTH_INVALID':\n case 'AUTH_FORBIDDEN':\n return new AuthError(msg, ErrorCode.AUTH_INVALID, statusCode);\n case 'RATE_LIMITED':\n case 'HEARTBEAT_TOO_SOON':\n case 'VOLUME_CAP_REACHED':\n case 'SPAWN_LIMIT_REACHED': {\n const retryAfter = typeof body.retry_after_ms === 'number' ? body.retry_after_ms : undefined;\n return new RateLimitError(msg, statusCode, retryAfter);\n }\n case 'AGENT_NOT_FOUND':\n return new NotFoundError(msg, statusCode);\n case 'AGENT_NOT_INITIALIZED':\n return new StateError(msg, 'not_initialized', ErrorCode.AGENT_NOT_INITIALIZED);\n case 'AGENT_WRONG_STATE':\n case 'SPAWN_CONFLICT':\n return new StateError(msg, 'conflict', ErrorCode.AGENT_WRONG_STATE);\n case 'SERVER_ERROR':\n case 'DB_ERROR':\n case 'DB_NOT_CONFIGURED':\n return new ServerError(msg, statusCode);\n // Validation / payment codes — fall through to generic handling below\n }\n }\n\n // ── Status-based fallback (backward compat with servers without code) ─\n if (statusCode === 401 || statusCode === 403) {\n // Deprecated: sigil_required boolean check — use code: SIGIL_REQUIRED instead\n if (statusCode === 403 && (body as any).sigil_required === true) {\n return new SigilRequiredError(msg);\n }\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 (deprecated — prefer body.code)\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"]}
|