# XBind (@private.me/xbind) — Complete API Reference

> Authenticated agent-to-agent messaging with information-theoretic security.

## Package Info
- npm: @private.me/xbind
- License: Apache-2.0
- Runtime: Node.js 18+ (Web Crypto API required)
- Dependencies: 0 npm (workspace: @private.me/shared, @private.me/crypto)
- Build: Dual ESM (dist/) + CJS (dist/cjs/)
- Sub-path: @private.me/xbind/verify (lightweight verify-only)

---

## Identity Module (src/identity.ts)

### Types
- AgentIdentity: { did, publicKey, privateKey, x25519PublicKey, x25519PrivateKey, rawPublicKey, rawX25519PublicKey }
- IdentityError: 'KEYGEN_FAILED' | 'SIGN_FAILED' | 'VERIFY_FAILED' | 'INVALID_DID' | 'INVALID_KEY_LENGTH' | 'EXPORT_FAILED' | 'IMPORT_FAILED'

### Functions
- generateIdentity(): Promise<Result<AgentIdentity, IdentityError>>
- sign(privateKey, data): Promise<Result<Uint8Array, IdentityError>>
- verify(publicKey, signature, data): Promise<Result<boolean, IdentityError>>
- importPublicKey(rawBytes): Promise<Result<CryptoKey, IdentityError>>
- publicKeyToDid(rawPublicKey): string
- didToPublicKeyBytes(did): Result<Uint8Array, IdentityError>
- exportPKCS8(privateKey): Promise<Result<Uint8Array, IdentityError>>
- exportX25519PKCS8(privateKey): Promise<Result<Uint8Array, IdentityError>>
- importFromPKCS8(edPkcs8, x25519Pkcs8): Promise<Result<AgentIdentity, IdentityError>>
- importIdentity(edPkcs8, x25519Pkcs8): Promise<Result<AgentIdentity, IdentityError>>
- identityFromSeed(seed: Uint8Array): Promise<Result<AgentIdentity, IdentityError>>
- extractRawEd25519(pkcs8): Result<Uint8Array, IdentityError>
- extractRawX25519(pkcs8): Result<Uint8Array, IdentityError>

---

## Envelope Module (src/envelope.ts)

### Types
- TransportEnvelope: { v:1, alg:'Ed25519', sender, recipient, timestamp, nonce, scope, payload, signature, ephemeralPub?, shareIndex?, shareTotal?, shareThreshold?, shareGroupId?, shareHmacKey?, shareHmacSig? }
- CreateEnvelopeOptions: { senderDid, recipientDid, scope, plaintext, privateKey, sharedKey, ephemeralPublicKey?, share* }
- CreateSignedEnvelopeOptions: { senderDid, recipientDid, scope, plaintext, privateKey }
- EnvelopeError: 'INVALID_VERSION' | 'INVALID_ALG' | 'INVALID_DID' | 'INVALID_NONCE' | 'INVALID_FIELDS' | 'ENCRYPT_FAILED' | 'DECRYPT_FAILED' | 'SIGN_FAILED' | 'VERIFY_FAILED' | 'PARSE_FAILED'

### Functions
- createEnvelope(opts): Promise<Result<TransportEnvelope, EnvelopeError>>
- decryptPayload(envelope, sharedKey): Promise<Result<Uint8Array, EnvelopeError>>
- serializeEnvelope(envelope): string
- deserializeEnvelope(json): Result<TransportEnvelope, EnvelopeError>
- validateEnvelope(input): Result<TransportEnvelope, EnvelopeError>
- generateSharedKey(pubA, pubB): Promise<CryptoKey>
- createSignedEnvelope(opts): Promise<Result<TransportEnvelope, EnvelopeError>>
- openSignedEnvelope(envelope): Result<Uint8Array, EnvelopeError>

---

## Agent Module (src/agent.ts)

### Types
- AgentCreateOptions: { name, registry, transport, nonceStore?, scopes?, timestampWindowMs? }
- AgentSendOptions: { to, payload, scope, splitChannel?, splitChannelConfig? }
- AgentMessage: { sender, payload, scope, timestamp }
- AgentReceiveOptions: { allowCleartext? }
- AgentErrorDetail: { code, subCode?, step? }
- AgentError: TransportError | 'IDENTITY_FAILED' | 'IDENTITY_FAILED:KEYGEN' | 'REGISTRATION_FAILED' | 'REGISTRATION_FAILED:ALREADY_REGISTERED' | 'REGISTRATION_FAILED:NETWORK_ERROR' | 'RECIPIENT_NOT_FOUND' | 'RECIPIENT_REVOKED' | 'KEY_AGREEMENT_FAILED' | 'ENVELOPE_FAILED' | 'ENVELOPE_FAILED:ENCRYPT' | 'ENVELOPE_FAILED:SIGN' | 'ENVELOPE_FAILED:SPLIT' | 'VERIFICATION_FAILED' | 'VERIFICATION_FAILED:UNSUPPORTED_VERSION' | 'VERIFICATION_FAILED:DID_NOT_IN_REGISTRY' | 'VERIFICATION_FAILED:KEY_IMPORT_FAILED' | 'VERIFICATION_FAILED:SIGNATURE_MISMATCH' | 'REPLAY_DETECTED' | 'SCOPE_DENIED' | 'TIMESTAMP_EXPIRED' | 'DECRYPT_FAILED' | 'DECRYPT_FAILED:KEY_AGREEMENT' | 'DECRYPT_FAILED:DECRYPTION' | 'DECRYPT_FAILED:PARSE' | 'SEND_FAILED:BELOW_THRESHOLD'

### Static Methods
- Agent.create(opts): Promise<Result<Agent, AgentError>>
- Agent.fromIdentity(identity, opts): Promise<Result<Agent, AgentError>>
- Agent.fromParts(identity, registry, transport, opts?): Agent
- Agent.fromSeed(seed, opts): Promise<Result<Agent, AgentError>>
- Agent.isSupported(): boolean

### Instance Methods
- agent.send(opts): Promise<Result<void, AgentError>>
- agent.receive(envelope, opts?): Promise<Result<AgentMessage, AgentError>>
- agent.receiveSigned(envelope): Promise<Result<AgentMessage, AgentError>>
- agent.receiveSplitShare(envelope): Promise<Result<AgentMessage | null, AgentError>>
- agent.verifySignature(envelope): Promise<Result<{sender, valid}, AgentError>>
- agent.exportSeeds(): Promise<Result<{ed25519, x25519}, AgentError>>
- agent.middleware(): ExpressMiddleware
- agent.isReady(): boolean
- agent.cleanup(): void — Clean up resources (timers, cache)
- agent.dispose(): void — Dispose of agent and all resources

### Instance Properties
- agent.did: string
- agent.name: string
- agent.identity: AgentIdentity
- agent.lastErrorDetail: string

### Standalone Functions
- parseAgentError(error): AgentErrorDetail

---

## Agent Call Module (src/agent-call.ts)

### Types
- AgentCallOptions: { mode?, ephemeral?, policy?, onProgress?, timeout? }
- PolicyConstraints: { allowedTools?, limits?, scopes?, dataFilters? }
- FieldFilter: { field, action: 'redact' | 'hash' | 'remove' }
- ProgressEvent: { step, progress, context? }
- AuditReceipt: { tool, agent, timestamp, policy, signature, transport? }
- CallResult<T>: { data: T, audit: AuditReceipt, formats: ResultFormats }
- ResultFormats: { multiline(), singleline(), json(), markdown() }

### Functions
- call<T>(tool, params, opts?): Promise<Result<CallResult<T>, AgentError>>
  - Simplified interface for AI agents to call tools/services
  - Auto-manages DID identity, transport, security policy
  - Includes HTTP transport with POST to tool endpoints
  - Signature verification for responses (Ed25519 + ML-DSA-65)
  - Returns structured result with audit receipt and format helpers
- batchCall<T>(calls): Promise<Result<CallResult<T>[], AgentError>>
  - Execute multiple tool calls in parallel
- stream(tool, params, opts): AsyncIterator<ProgressEvent>
  - Streaming interface for long-running operations
- setToolRegistry(registry): void
  - Configure global tool registry for discovery
- getToolRegistry(): ToolRegistry | null
  - Get current global tool registry

### Error Codes
- AgentErrorCode enum with 96+ error codes
- ERROR_DETAILS map with actionable error messages

### Internal Functions
- verifyEnvelopeSignature(envelope, registry): Promise<'valid' | 'invalid' | 'not_verified'>
  - Verify Ed25519 and ML-DSA-65 signatures on response envelopes
  - Validates envelope version (v1/v2/v3/v4) and algorithm
  - Resolves sender DID from trust registry
  - Used internally by call() for response validation

---

## Split-Channel Module (src/split-channel.ts)

### Types
- SplitChannelConfig: { totalShares: number, threshold: number }
- ChannelShare: { data, index, total, threshold, groupId, hmacKey, hmacSig }
- SplitChannelError: 'SPLIT_FAILED' | 'SPLIT_FAILED:INVALID_PARAMS' | 'SPLIT_FAILED:RECONSTRUCT' | 'INSUFFICIENT_SHARES' | 'INCONSISTENT_SHARES' | 'HMAC_VERIFICATION_FAILED' | 'UNPAD_FAILED' | 'INVALID_SHARE_DATA' | 'INVALID_SHARE_DATA:BASE64' | 'INVALID_SHARE_DATA:HMAC_DECODE'

### Functions
- splitForChannel(data, config): Promise<Result<ChannelShare[], SplitChannelError>>
- splitForChannelWithGroupId(data, config, groupId): Promise<Result<ChannelShare[], SplitChannelError>>
- reconstructFromChannel(shares): Promise<Result<Uint8Array, SplitChannelError>>
- DEFAULT_SPLIT_CONFIG: { totalShares: 3, threshold: 2 }

---

## Key Agreement Module (src/key-agreement.ts)

### Types
- EphemeralKeyPair: { publicKey, privateKey, rawPublicKey }
- KeyAgreementResult: { sharedKey, ephemeralPublicKey }
- KeyAgreementError: 'KEYGEN_FAILED' | 'DERIVE_FAILED' | 'IMPORT_FAILED' | 'INVALID_KEY_LENGTH' | 'INVALID_KEY_LENGTH:EXPECTED_32'

### Functions
- generateEphemeralKeyPair(): Promise<Result<EphemeralKeyPair, KeyAgreementError>>
- importX25519PublicKey(rawBytes): Promise<Result<CryptoKey, KeyAgreementError>>
- deriveSharedKeyECDH(privateKey, publicKey): Promise<Result<CryptoKey, KeyAgreementError>>
- senderKeyAgreement(recipientPublicKey): Promise<Result<KeyAgreementResult, KeyAgreementError>>
- receiverKeyAgreement(privateKey, ephemeralPubBytes): Promise<Result<CryptoKey, KeyAgreementError>>

---

## Nonce Store (src/nonce-store.ts)

### Interface
- NonceStore: { check(nonce, senderDid): Promise<boolean>, cleanup(): void, dispose(): void }

### Classes
- MemoryNonceStore: NonceStore (options: { ttlMs?, cleanupIntervalMs? })

---

## Redis Nonce Store (src/redis-nonce-store.ts)

### Types
- RedisClient: { set(key, value, opts): Promise<string|null> }
- RedisNonceStoreOptions: { client, prefix?, ttlSeconds? }

### Classes
- RedisNonceStore: NonceStore

---

## Trust Registry (src/trust-registry.ts)

### Interface
- TrustRegistry: { register(did, publicKey, name?, scopes?, x25519?), resolve(did), hasScope(did, scope), revoke(did), getEntry(did) }
- RegistryEntry: { did, publicKey, name?, scopes, x25519PublicKey?, revoked }
- RegistryError: 'NOT_FOUND' | 'ALREADY_REGISTERED' | 'REVOKED' | 'NETWORK_ERROR'

### Classes
- MemoryTrustRegistry: TrustRegistry
- HttpTrustRegistry: TrustRegistry (options: { baseUrl, authToken? })

---

## Transport (src/transport.ts)

### Interface
- XailTransportAdapter: { send(envelope, recipientDid), onReceive(handler), dispose() }
- TransportError: 'SEND_FAILED' | 'NETWORK_ERROR' | 'RECIPIENT_UNREACHABLE' | 'TIMEOUT'

### Classes
- HttpsTransportAdapter: XailTransportAdapter (options: { endpoint, timeout? })

---

## Gateway Transport (src/gateway-transport.ts)

### Types
- GatewayTransportOptions: { gatewayUrl, authToken?, timeout? }

### Classes
- GatewayTransport: XailTransportAdapter

---

## DID:web Resolver (src/did-web.ts)

### Types
- DidWebResolverOptions: { cacheTtlMs? }

### Functions
- didWebToUrl(did): string
- DidWebResolver: class with resolve(did) method

---

## Registry Middleware (src/registry-middleware.ts)

### Functions
- createRegistryAuthMiddleware(): Express middleware
  - Checks REGISTRY_ADMIN_TOKEN env var
  - Protects POST/PUT/DELETE, passes GET/HEAD

---

## Error Classes (src/errors.ts)

### Classes
- XBindError (base): { code, subCode?, docUrl?, message }
- XBindIdentityError extends XBindError
- XBindEnvelopeError extends XBindError
- XBindTransportError extends XBindError
- XBindRegistryError extends XBindError
- XBindKeyAgreementError extends XBindError
- XBindSplitChannelError extends XBindError
- XBindAgentError extends XBindError

### Functions
- toXBindError(code): XBindError — maps string code to typed class
- isXBindError(err): err is XBindError — type guard

---

## Verify Sub-Path (@private.me/xbind/verify)

Lightweight re-export for edge/serverless:
- verify, importPublicKey, didToPublicKeyBytes
- validateEnvelope, deserializeEnvelope, openSignedEnvelope
- Types: IdentityError, TransportEnvelope, EnvelopeError
