{"_id":"@bentoguard/protocol-sdk","_rev":"4-4268824d68fdc27e8138665d61566725","name":"@bentoguard/protocol-sdk","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@bentoguard/protocol-sdk","version":"0.1.0","keywords":["bento","guard","ai","agent","protocol","crypto","stellar"],"author":{"name":"Bento Team"},"license":"MIT","_id":"@bentoguard/protocol-sdk@0.1.0","maintainers":[{"name":"trinhlk","email":"trinhlk@1bitlab.io"},{"name":"andh.1bitlab","email":"andh@1bitlab.io"},{"name":"daint1bitlab","email":"daint@1bitlab.io"}],"dist":{"shasum":"f7229d90f8a98eb62ae9749e7ce3fa5a2bb6176e","tarball":"https://registry.npmjs.org/@bentoguard/protocol-sdk/-/protocol-sdk-0.1.0.tgz","fileCount":67,"integrity":"sha512-WP94zwGLShG+6mmQy2uqv11sw5pMST8UEirmIKo7HQbDNSL/KqJycUuFUrgXkqXR32er0MqoY05Pn0M35cHcVg==","signatures":[{"sig":"MEYCIQC1jTu/dv74XoBsX8O2QXevFwUZpZa94lM0ZwlCgIeC0wIhAPWxzP8/TPZrR0yEchTtla6SGO9PmPKbvkmM+l9KcjJj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57911},"main":"./dist/index.js","types":"./dist/index.d.ts","gitHead":"4fe6301f9b61311b7973407b292bea0810f83fe0","scripts":{"dev":"tsc --watch","test":"ts-node test/index.ts","build":"tsc"},"_npmUser":{"name":"andh.1bitlab","email":"andh@1bitlab.io"},"_npmVersion":"11.12.1","description":"Bento Stellar SDK for AI Agents","directories":{},"_nodeVersion":"24.15.0","dependencies":{"axios":"^1.18.1","dotenv":"^17.4.2"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.6.0","ts-node":"^10.9.2","prettier":"^3.9.4","typescript":"^6.0.3","@types/node":"^26.1.1"},"_npmOperationalInternal":{"tmp":"tmp/protocol-sdk_0.1.0_1783776031305_0.05130212280964064","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bentoguard/protocol-sdk","version":"0.1.1","keywords":["bento","guard","ai","agent","protocol","crypto","stellar"],"author":{"name":"Bento Team"},"license":"MIT","_id":"@bentoguard/protocol-sdk@0.1.1","maintainers":[{"name":"trinhlk","email":"trinhlk@1bitlab.io"},{"name":"andh.1bitlab","email":"andh@1bitlab.io"},{"name":"daint1bitlab","email":"daint@1bitlab.io"}],"dist":{"shasum":"0cef2dd1592c577f38f970f7d0a3092b6f611825","tarball":"https://registry.npmjs.org/@bentoguard/protocol-sdk/-/protocol-sdk-0.1.1.tgz","fileCount":61,"integrity":"sha512-kWW8h79OV3HNyLFGME4of+etS0PuLo9ouWi9nnWTs1rPI3q8jRMMaOs4ACJ6OA1W/VjRy2yAY7Le+Z6MwA821g==","signatures":[{"sig":"MEUCIDzh/AQifMiy8VVi4dmIAUMVVJfurNMF3VLzgbu7sf4LAiEAilDnVDNiOU8u9RQAplSgjKYwgEQDF23wW3oiE/9UhFc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51571},"main":"./dist/index.js","types":"./dist/index.d.ts","gitHead":"44f20bf139e86b638a6e98110c5a9922fa039408","scripts":{"dev":"tsc --watch","test":"ts-node test/index.ts","build":"tsc"},"_npmUser":{"name":"andh.1bitlab","email":"andh@1bitlab.io"},"_npmVersion":"11.12.1","description":"Bento Stellar SDK for AI Agents","directories":{},"_nodeVersion":"24.15.0","dependencies":{"axios":"^1.18.1","dotenv":"^17.4.2"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.6.0","ts-node":"^10.9.2","prettier":"^3.9.4","typescript":"^6.0.3","@types/node":"^26.1.1"},"_npmOperationalInternal":{"tmp":"tmp/protocol-sdk_0.1.1_1783932924614_0.7468713576664572","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bentoguard/protocol-sdk","version":"0.2.0","keywords":["bento","guard","ai","agent","protocol","crypto","stellar"],"author":{"name":"Bento Team"},"license":"MIT","_id":"@bentoguard/protocol-sdk@0.2.0","maintainers":[{"name":"trinhlk","email":"trinhlk@1bitlab.io"},{"name":"andh.1bitlab","email":"andh@1bitlab.io"},{"name":"daint1bitlab","email":"daint@1bitlab.io"}],"dist":{"shasum":"549b54e1c70a6fad2f92db807a5909b5b56160ce","tarball":"https://registry.npmjs.org/@bentoguard/protocol-sdk/-/protocol-sdk-0.2.0.tgz","fileCount":61,"integrity":"sha512-wPFGXLtkNp2Cr4HMMiXT0/08esW3GyB2cdWY1LBhCXG/AolZ9Am4t/uObTpAGtI6mOaQb1x+HPVTt3sPGcEANw==","signatures":[{"sig":"MEUCIH6Ao/va3Qzzqfy+92uGHH00uK73Q6hsjmx/DJ6y3W9xAiEA5Cg0YsLavIHxXalLxDz6xgzkx7Bp0P4DTynv+F3hIKY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52069},"main":"./dist/index.js","types":"./dist/index.d.ts","gitHead":"13c6866a87427ace3c4b6c669533c04b325671d9","scripts":{"dev":"tsc --watch","test":"ts-node test/index.ts","build":"tsc","release":"changeset version && npm publish","version":"changeset version","changeset":"changeset"},"_npmUser":{"name":"andh.1bitlab","email":"andh@1bitlab.io"},"_npmVersion":"11.12.1","description":"Bento Stellar SDK for AI Agents","directories":{},"_nodeVersion":"24.15.0","dependencies":{"axios":"^1.18.1","dotenv":"^17.4.2","@changesets/cli":"^2.31.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.6.0","ts-node":"^10.9.2","prettier":"^3.9.4","typescript":"^6.0.3","@types/node":"^26.1.1"},"_npmOperationalInternal":{"tmp":"tmp/protocol-sdk_0.2.0_1783938178862_0.2075974930218154","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bentoguard/protocol-sdk","version":"0.3.0","description":"Bento Stellar SDK for AI Agents","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","test":"jest","changeset":"changeset","version":"changeset version","release":"changeset version && npm publish"},"keywords":["bento","guard","ai","agent","protocol","crypto","stellar"],"author":{"name":"Bento Team"},"license":"MIT","dependencies":{"@changesets/cli":"^2.31.0","axios":"^1.18.1","dotenv":"^17.4.2"},"devDependencies":{"@types/jest":"^30.0.0","@types/node":"^26.1.1","eslint":"^10.6.0","jest":"^30.4.2","prettier":"^3.9.4","ts-jest":"^29.4.12","ts-node":"^10.9.2","typescript":"^6.0.3"},"gitHead":"3496f80344f0fa06de9d2d4b47abd52e2930016e","_id":"@bentoguard/protocol-sdk@0.3.0","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-53fsundskkLURONBHMwnvkp8c05PIYBgxEMtyGblCrEutk2Om+u/l4QasBrLglPKGfYFPH9QQyr292QKWa+psQ==","shasum":"a793fafeaf720d6e81b848776bae08663589cf47","tarball":"https://registry.npmjs.org/@bentoguard/protocol-sdk/-/protocol-sdk-0.3.0.tgz","fileCount":63,"unpackedSize":57417,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCnyxo6qz+u34h7asOInSH1DXsb9BceiJ2mQkW+8dYUCgIhAPzic3GDnViQ0J5JL5ClasGUAwz+aRcTjdz8+J/ihaoz"}]},"_npmUser":{"name":"andh.1bitlab","email":"andh@1bitlab.io"},"directories":{},"maintainers":[{"name":"trinhlk","email":"trinhlk@1bitlab.io"},{"name":"andh.1bitlab","email":"andh@1bitlab.io"},{"name":"daint1bitlab","email":"daint@1bitlab.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/protocol-sdk_0.3.0_1784775806533_0.9033964917298727"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-11T13:20:31.201Z","modified":"2026-07-23T03:03:26.943Z","0.1.0":"2026-07-11T13:20:31.448Z","0.1.1":"2026-07-13T08:55:24.749Z","0.2.0":"2026-07-13T10:22:58.994Z","0.3.0":"2026-07-23T03:03:26.701Z"},"author":{"name":"Bento Team"},"license":"MIT","keywords":["bento","guard","ai","agent","protocol","crypto","stellar"],"description":"Bento Stellar SDK for AI Agents","maintainers":[{"name":"trinhlk","email":"trinhlk@1bitlab.io"},{"name":"andh.1bitlab","email":"andh@1bitlab.io"},{"name":"daint1bitlab","email":"daint@1bitlab.io"}],"readme":"# Bento Stellar SDK\n\n[![Version](https://img.shields.io/badge/version-0.3.0-blue)](./package.json)\n[![License](https://img.shields.io/badge/license-MIT-green)](#license)\n[![npm](https://img.shields.io/badge/npm-@bentoguard%2Fprotocol--sdk-red)](https://www.npmjs.com/package/@bentoguard/protocol-sdk)\n\nA production-ready TypeScript SDK for AI agents to authenticate, manage wallets, and execute lending transactions on the Bento Stellar backend — with built-in Bento Guard risk engine integration.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Features](#features)\n- [Installation](#installation)\n- [Requirements](#requirements)\n- [Quick Start](#quick-start)\n- [Project Structure](#project-structure)\n- [Core Concepts](#core-concepts)\n- [Security Gate (Bento Guard)](#security-gate-bento-guard)\n- [Configuration](#configuration)\n- [Usage](#usage)\n- [Error Handling](#error-handling)\n- [Best Practices](#best-practices)\n- [API Overview](#api-overview)\n- [FAQ](#faq)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Introduction\n\nBento Stellar SDK is the agent-facing client for the Bento Stellar backend. It gives AI agents a typed, ergonomic way to interact with the backend without hardcoding routes or managing request concerns in every integration.\n\nAll agent write operations (transfer, lending actions) automatically pass through a **3-step secure execution pipeline**:\n1. Create a transaction draft\n2. Run the Bento Guard Risk Engine\n3. Approve and broadcast (if ALLOWED), or hold for review (if ESCALATED)\n\nCredentials (`agentId` and `apiKey`) are persisted to a `.bento-credentials` file automatically on first registration. Subsequent runs load them transparently — no manual configuration needed.\n\n## Features\n\n- Agent registration and claim status workflows\n- Automatic credential persistence via `.bento-credentials`\n- Embedded wallet balance query and asset transfer\n- Transaction create and approve flows\n- Lending pool market discovery (info, reserves, position)\n- Lending actions: deposit, borrow, repay, withdraw, submit (batch)\n- **Bento Guard integration**: all agent write operations are gated by the risk engine automatically\n- Typed request/response contracts via TypeScript\n- Centralized versioned endpoint builder (`buildEndpoint`)\n- Normalized error types with HTTP status code and response payload\n- Clean module-based API surface\n\n## Installation\n\n```bash\nnpm install @bentoguard/protocol-sdk\n```\n\n## Requirements\n\n- Node.js >= 18\n- TypeScript >= 5\n- Network access to the Bento backend\n\n## Quick Start\n\n```ts\nimport { BlendServiceClient, auth, embeddedWallet, lendingPool } from '@bentoguard/protocol-sdk';\n\n// Client auto-loads credentials from .bento-credentials if present\nconst client = new BlendServiceClient();\nconst agentAuth = auth.createAgentIdentityApi(client);\n\n// First run: register the agent (saves .bento-credentials automatically)\nconst result = await agentAuth.registerAgent({\n  name: 'My Agent',\n  handle: 'my_agent',\n  quote: 'Here to lend.',\n});\nconsole.log('Agent ID:', result.agentId);\nconsole.log('Claim Token:', (await agentAuth.getClaimStatus()).claimToken);\n\n// Subsequent runs: credentials already in .bento-credentials, just use the modules\nconst balance = await embeddedWallet.getWalletBalance(client);\nconst reserves = await lendingPool.getReserves(client);\nconsole.log({ balance, reserves });\n```\n\n## Project Structure\n\n```text\nsrc/\n  constants/         # Endpoint builder, version/module enums (Version, Module)\n  core/              # HTTP client (BentoStellarClient / BlendServiceClient) and credential store\n  errors/            # SDK error types: BentoError, BentoAPIError, BentoAuthError\n  modules/\n    auth/            # Agent registration and claim status\n    embedded_wallet/ # Wallet balance, transfer, create/approve transaction\n    lending_pool/    # Market info, reserves, position, deposit/borrow/repay/withdraw/submit\n  types/             # Shared TypeScript request/response interfaces\n  utils/\n    request.ts       # postJson, getJson — typed HTTP helpers\n    security.ts      # executeSecureAgentAction — 3-step Bento Guard pipeline\n```\n\n## Core Concepts\n\n- **`BlendServiceClient`** — shared HTTP client that injects `x-bento-api-key` from `.bento-credentials` and centralizes request/error behavior.\n- **`FileTokenStore`** — default credential store backed by `.bento-credentials` in the working directory (mode `0600`).\n- **Agent** — an autonomous identity registered on the backend with its own wallet and lending position.\n- **Claim** — the process by which a human owner links their account to the agent. Required before certain protected operations.\n- **Pool** — the Blend Protocol lending market for discovery and transaction actions.\n- **Secure Action** — agent write operations go through `executeSecureAgentAction`, which creates a draft, checks the risk engine, then broadcasts on ALLOW.\n\n## Security Gate (Bento Guard)\n\nAll agent write operations (lending actions and transfers) automatically go through a 3-step pipeline when an `instruction` is provided:\n\n```text\nStep 1 → Create transaction draft            → { transaction_id }\nStep 2 → Risk Engine evaluates instruction   → verdict: ALLOW | ESCALATED | BLOCKED\nStep 3 → ALLOW:     approve & broadcast tx\n         ESCALATED: return { status, transaction_id, reason }\n         BLOCKED:   throw Error\n```\n\nPopulate the `instruction` and `resolvedTargets` fields in your request to activate the security gate:\n\n```ts\nawait lendingPool.deposit(client, {\n  assetPubkey: 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC',\n  amount: '100',\n  instruction: 'Deposit 100 XLM into the lending pool',\n  resolvedTargets: {\n    assetPubkeys: ['CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC'],\n  },\n});\n```\n\nIf `instruction` is omitted, the SDK returns the draft ID directly for manual approval.\n\n## Configuration\n\n`BlendServiceClient` accepts optional parameters:\n\n```ts\nnew BlendServiceClient({\n  timeoutMs: 30_000,                           // default: 30000ms\n});\n```\n\n| Option | Description |\n|--------|-------------|\n| `baseURL` | Backend base URL. Falls back to `BENTO_BASE_URL` env, then `http://localhost:4001`. |\n| `timeoutMs` | Per-request timeout in milliseconds. |\n| `tokenStore` | Custom `TokenStore` implementation. |\n\nEnvironment variable fallback for API key (if `.bento-credentials` is absent):\n\n```\nBENTO_AGENT_API_KEY=<your api key>\n```\n\n## Usage\n\n### Initialize Client\n\n```ts\nimport { BlendServiceClient } from '@bentoguard/protocol-sdk';\n\nconst client = new BlendServiceClient();\n```\n\n### Register Agent (first run only)\n\n```ts\nimport { auth } from '@bentoguard/protocol-sdk';\n\nconst agentAuth = auth.createAgentIdentityApi(client);\n\nconst result = await agentAuth.registerAgent({\n  name: 'My Agent',\n  handle: 'my_agent',\n  quote: 'Autonomous lending agent',\n});\n// .bento-credentials written automatically — agentId + apiKey\n```\n\n### Check Claim Status\n\n```ts\nconst status = await agentAuth.getClaimStatus();\n// status.claimToken — share this with the owner to link their account\n```\n\n### Regenerate Claim Link\n\n```ts\nawait agentAuth.regenerateClaimToken();\n```\n\n### Wallet Balance\n\n```ts\nimport { embeddedWallet } from '@bentoguard/protocol-sdk';\n\nconst balance = await embeddedWallet.getWalletBalance(client);\nconsole.log(balance); // { balances: [{ asset, amount }], ... }\n```\n\n### Transfer Asset\n\n```ts\nawait embeddedWallet.transferAsset(client, {\n  targetPubkey: 'GABC...',\n  assetPubkey: 'CDLZ...',   // use asset contract pubkey, or 'XLM' for native\n  amount: '25',\n  instruction: 'Transfer 25 XLM to GABC...',   // required to trigger Bento Guard\n  resolvedTargets: {\n    receiverPubkey: 'GABC...',\n    assetPubkeys: ['CDLZ...'],\n  },\n});\n```\n\n### Create & Approve Transaction (manual flow)\n\n```ts\n// Step 1: create draft\nconst draft = await embeddedWallet.createTransaction(client, {\n  params: { to: 'GABC...', amount: '10', token: 'XLM' },\n});\n\n// Step 2: approve and broadcast\nawait embeddedWallet.approveTransaction(client, { txId: draft.transaction_id });\n```\n\n### Read Market State\n\n```ts\nimport { lendingPool } from '@bentoguard/protocol-sdk';\n\nconst info = await lendingPool.getInfo(client);\nconst reserves = await lendingPool.getReserves(client);\nconst position = await lendingPool.getPosition(client);\n```\n\n### Lending Actions\n\n```ts\nawait lendingPool.deposit(client, {\n  assetPubkey: 'CDLZ...',\n  amount: '100',\n  instruction: 'Deposit 100 XLM into the lending pool',\n  resolvedTargets: { assetPubkeys: ['CDLZ...'] },\n});\n\nawait lendingPool.borrow(client, { assetPubkey: 'CDLZ...', amount: '50' });\nawait lendingPool.repay(client, { assetPubkey: 'CDLZ...', amount: '50' });   // or 'max'\nawait lendingPool.withdraw(client, { assetPubkey: 'CDLZ...', amount: '10' }); // or 'max'\n```\n\n> **Note:** `assetPubkey` replaces the old `assetId` field. All lending request types now use `assetPubkey`.\n\n### Batch (Submit)\n\n```ts\nawait lendingPool.submit(client, {\n  requests: [\n    { actionType: 'REPAY', assetPubkey: 'CDLZ...', amount: '25' },\n    { actionType: 'WITHDRAW', assetPubkey: 'CDLZ...', amount: '10' },\n  ],\n  instruction: 'Repay 25 and withdraw 10',\n});\n```\n\nValid `actionType` values: `DEPOSIT`, `BORROW`, `REPAY`, `WITHDRAW`.\n\n### Clear Credentials\n\n```ts\nclient.clearCredentials();\n```\n\n## Error Handling\n\n```ts\nimport { utils } from '@bentoguard/protocol-sdk';\n\ntry {\n  await lendingPool.deposit(client, { assetPubkey: 'CDLZ...', amount: '100' });\n} catch (error) {\n  if (error instanceof utils.BentoAuthError) {\n    // 401 — apiKey missing or invalid, check .bento-credentials\n  } else if (error instanceof utils.BentoAPIError) {\n    console.error('HTTP status:', error.statusCode);\n    console.error('Response:', error.response);\n  } else if (error instanceof utils.BentoError) {\n    console.error('SDK error:', error.message);\n  }\n}\n```\n\n| Error class | When it fires |\n|-------------|---------------|\n| `BentoAuthError` | `401` — API key missing or invalid |\n| `BentoAPIError` | `4xx / 5xx` — check `statusCode` and `response` |\n| `BentoConfigError` | Missing required config at startup |\n| `BentoError` | Generic SDK-level failure |\n\n**Risk Engine Verdicts:**\n\n| Verdict | SDK behaviour |\n|---------|---------------|\n| `ALLOW` | Transaction is approved and broadcasted automatically |\n| `ESCALATED` | Returns `{ status: 'escalated', transaction_id, reason }` — awaits manual review |\n| `BLOCKED` | Throws `Error: Security Gate Blocked Action: <reason>` |\n\n## Best Practices\n\n- Rely on `.bento-credentials` written by `registerAgent()` — do not hardcode API keys.\n- Reuse a single `BlendServiceClient` instance per process.\n- Always read `getWalletBalance` and `getReserves` before executing a lending action.\n- Pass `'max'` for `amount` on `repay` and `withdraw` to close positions cleanly.\n- Provide `instruction` and `resolvedTargets` on all write operations so the Bento Guard risk engine has full context to make correct decisions.\n- Use `submit` for atomic multi-step operations.\n- Keep retry logic in your application layer — catch `BentoAPIError`, inspect `statusCode`, decide there.\n- Call `client.clearCredentials()` when a session ends or becomes invalid.\n\n## API Overview\n\n| Action | SDK Call | Auth Required |\n|--------|----------|:---:|\n| Register agent | `agentAuth.registerAgent({ name, handle, quote })` | ✗ |\n| Claim status | `agentAuth.getClaimStatus()` | ✓ |\n| Regenerate claim | `agentAuth.regenerateClaimToken()` | ✓ |\n| Wallet balance | `embeddedWallet.getWalletBalance(client)` | ✓ |\n| Transfer asset | `embeddedWallet.transferAsset(client, { targetPubkey, assetPubkey, amount, instruction?, resolvedTargets? })` | ✓ |\n| Create transaction | `embeddedWallet.createTransaction(client, { params })` | ✓ |\n| Approve transaction | `embeddedWallet.approveTransaction(client, { txId })` | ✓ |\n| Pool info | `lendingPool.getInfo(client)` | ✗ |\n| Pool reserves | `lendingPool.getReserves(client)` | ✗ |\n| Agent position | `lendingPool.getPosition(client)` | ✓ |\n| Deposit | `lendingPool.deposit(client, { assetPubkey, amount, instruction?, resolvedTargets? })` | ✓ |\n| Borrow | `lendingPool.borrow(client, { assetPubkey, amount, instruction?, resolvedTargets? })` | ✓ |\n| Repay | `lendingPool.repay(client, { assetPubkey, amount, instruction?, resolvedTargets? })` | ✓ |\n| Withdraw | `lendingPool.withdraw(client, { assetPubkey, amount, instruction?, resolvedTargets? })` | ✓ |\n| Submit (batch) | `lendingPool.submit(client, { requests, instruction?, resolvedTargets? })` | ✓ |\n\n> **Auth Required** = needs `x-bento-api-key` from `.bento-credentials`\n\n## FAQ\n\n**1. Is this SDK production ready?**\nStructured for production use — readiness depends on your backend deployment.\n\n**2. Which network does it target?**\nStellar, via versioned Bento backend routes.\n\n**3. Does it support browsers?**\nCurrently targeting Node.js runtimes only.\n\n**4. How does authentication work?**\nAfter `registerAgent()`, the SDK saves `agentId` and `apiKey` to `.bento-credentials`. Every subsequent request automatically injects `x-bento-api-key` from that file.\n\n**5. Do I need to set environment variables?**\nNo — `.bento-credentials` is the primary source. `BENTO_AGENT_API_KEY` is only a fallback if the file is absent.\n\n**6. Can I replace the credential store?**\nYes — pass a custom `tokenStore` implementing the `TokenStore` interface to `BlendServiceClient`.\n\n**7. Does the SDK retry automatically?**\nNo. Handle retries at your application or orchestration layer.\n\n**8. What if I need to change the backend URL?**\nSet `BENTO_BASE_URL` env or pass `baseURL` to `BlendServiceClient`.\n\n**9. What changed from v0.1.x?**\n- `assetId` → renamed to `assetPubkey` in all `PoolActionRequest` and `SubmitActionRequest` types\n- `toAddress` / `tokenId` → renamed to `targetPubkey` / `assetPubkey` in `TransferAssetRequest`\n- All agent write operations now go through the 3-step Bento Guard security pipeline (`executeSecureAgentAction`)\n- Job polling (`postJobAndWait`) removed — all endpoints are now synchronous\n\n**10. Where should I start reading the source?**\n`src/core/bento-client.ts`, then `src/utils/security.ts` for the secure action pipeline, then the module folders.\n\n## Troubleshooting\n\n**`401 Authentication failed`** — Check `.bento-credentials` exists and `apiKey` is valid. Re-run `registerAgent()` if corrupted.\n\n**`403 Forbidden`** — Agent claim may be required. Call `agentAuth.getClaimStatus()` and share `claimToken` with the owner.\n\n**`Insufficient balance`** — Call `embeddedWallet.getWalletBalance(client)` before retrying. Never execute without confirming balance.\n\n**`RPC timeout`** — Increase `timeoutMs` or check backend connectivity.\n\n**`Module not found`** — Verify import path matches the exported module namespace from `@bentoguard/protocol-sdk`.\n\n**`Endpoint mismatch`** — Use `buildEndpoint(Version, Module, path)` rather than hardcoding strings.\n\n**`Security Gate Blocked Action`** — The risk engine rejected the transaction. Check the `reason` in the error message. Ensure `resolvedTargets` accurately reflects the transaction's actual targets.\n\n**`status: 'escalated'`** — The transaction is pending manual review in the Bento dashboard. The `transaction_id` is returned so you can track it.\n\n## Contributing\n\n1. Branch from the repository.\n2. Make small, focused changes.\n3. Run tests: `npm run test`\n4. Run build: `npm run build`\n5. Open a pull request with a clear description of what SDK surface changed.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}