An open-source, serverless and agentic design for pay-per-use AI content generation using USDC stablecoin payments via x402, featuring browser wallet and autonomous agent flows on AWS.
sample-agentic-serverless-payments is an early-stage JavaScript project in the AI payments / x402 ecosystem, focused on agentic, agentic-payments, ai-agents, aws. It currently has 8 GitHub stars and 3 forks, and sits alongside related tools like dna-x402, piprail, Sentinel.
Author: Chris Wajule and Simon Goldberg
Disclaimer: This is a sample and reference implementation intended for demonstration, learning, and prototyping. It is not production-ready as shipped and is provided without warranty. It runs entirely on test networks (Base Sepolia and Solana Devnet) with test-only USDC and no real funds move. Before any production use you must conduct your own security, privacy, compliance, and reliability review, scope all IAM policies to least privilege for your environment, and validate the solution against your organization's requirements. Amazon Bedrock AgentCore payments is a preview capability and its APIs may change. Nothing here is legal, financial, or compliance advice.
This solution shows how to build pay-per-use AI services with Amazon Bedrock AgentCore payments and the open x402 payment protocol. Users sign in through Amazon Cognito, provision an embedded crypto wallet backed by either Coinbase CDP or Stripe/Privy as the credential provider, grant the agent a scoped spending session, and then chat with a voice and text agent (Anthropic Claude Sonnet for text and Amazon Nova Sonic for voice, built on the Strands Agents framework). The agent pays x402 sellers, an AI image generator powered by Amazon Nova Canvas and an agent-economy storefront, settling USDC on Base Sepolia or Solana Devnet through the Amazon Bedrock AgentCore payments ProcessPayment API, with the x402 facilitator verifying signatures and posting settlements on-chain. The AgentCorePaymentsPlugin is the canonical payment path: it intercepts each HTTP 402 and runs ProcessPayment automatically, so the agent never assembles a payment by hand. Administrators manage the AgentCore payments control plane from the included admin surface (creating and rotating credential providers, payment managers, and connectors for both vendors, and provisioning the storefront seller's payout wallet), while the storefront itself originates refunds as the payer. The patterns map directly to ecommerce, retail, and digital-asset use cases: an autonomous buyer paying per request, a storefront that sells physical and digital goods and issues refunds, and a seller that monetizes content and AI generation. Together the user surface, agent runtime, and seller endpoints provide an end-to-end reference for teams building agents that transact on behalf of users.
Autonomous payments
AgentCorePaymentsPlugin as the canonical payer: it intercepts each HTTP 402, runs ProcessPayment, and retries with the signed proof, so the agent never assembles a payment by hand.Conversational agent
/invocations fallback for text-only callers.check_balance, list_products, buy_product, generate_image, list_orders, cancel_order.context_update message to switch instrument, session, or network without reconnecting.Wallets and credential providers (two vendors)
GetPaymentInstrumentBalance), and soft delete.Agent-economy storefront (seller)
Image generation (seller)
Refunds (seller as payer)
Security and operations
The solution has two sides. The buyer side (main diagram) is an Admin Flow that configures payment infrastructure once on the control plane and a User Flow where the agent discovers and pays for services on the data plane. The seller side (seller diagram) provisions the storefront seller and serves paid requests: image generation, storefront orders, and refunds. Sellers are a black box in the main diagram and are broken out in the seller diagram.

The numbered steps trace each arrow in the diagram, grouped by phase.
Authentication
admin group, enforced in-Lambda with require_admin.Admin setup: control plane (one-time)
Admin requests flow from Amplify to API Gateway to the admin Lambdas, which call the Amazon Bedrock AgentCore payments control plane (bedrock-agentcore-control).
create_payment_credential_provider(). CoinbaseCDP stores the CDP API key ID, API key secret, and wallet secret; StripePrivy stores the Privy app credentials. Vendor secrets live in AWS Secrets Manager; only the secret ARNs return to the UI, and rotation (UpdatePaymentCredentialProvider) preserves the provider ARN so connectors and instruments keep working.create_payment_manager(), backed by an IAM service role that AgentCore payments assumes to reach the Token Vault and sign payments.create_payment_connector() to bind a manager to a credential provider; the connector type matches the provider vendor. Quick Setup runs steps 3 to 5 in one pass per vendor.create_* calls run against bedrock-agentcore-control, which provisions the credential provider, manager, and connector and stores the vendor secrets in Secrets Manager through the Token Vault.User setup: data plane
User requests flow from API Gateway to the user Lambdas, which call the AgentCore payments data plane (bedrock-agentcore). Non-admin users discover the manager ARN and connector through the read-only /user/payment-options endpoint.
create_payment_instrument() to register an embedded crypto wallet for ETHEREUM (Base Sepolia) or SOLANA (Solana Devnet), linked to the manager and connector. Coinbase instruments capture the user's CDP end-user UUID from an email OTP and forward it as the userId; for Privy instruments the user opens the Connect Agent page and attaches the AgentCore payments authorization-key quorum as a session signer (addSessionSigners) across their Privy wallets.create_payment_session() with a USDC maxSpendAmount and a 15 to 480 minute expiry. The session caps everything the agent can spend.list_payment_managers and list_payment_connectors lets non-admin users find the manager ARN and connector they need for steps 7 and 8.bedrock-agentcore; the Instruments page reads live balances through GetPaymentInstrumentBalance.Conversation
InvokeAgentRuntimeWithWebsocketStream to mint a SigV4-signed WSS URL and returns it with the session id.userId, managerArn, instrumentId, sessionId, connectorId, network, mode), then messages. The Payer Agent runs on Anthropic Claude Sonnet for text (with the AgentCorePaymentsPlugin attached) and Amazon Nova Sonic for voice, on Strands Agents, and selects a tool: check_balance, list_products, buy_product, generate_image, list_orders, or cancel_order. A context_update message can switch instrument, session, or network without reconnecting.Payment
generate_image or buy_product) sends its first request to the seller without a proof and receives HTTP 402 with the payment terms: price in USDC, the seller payTo address, the facilitator URL, and the supported networks.AgentCorePaymentsPlugin intercepts the 402 and calls AgentCore payments ProcessPayment, which signs the payload through the Token Vault (EIP-3009 for EVM, SPL token transfer for Solana) and returns a proof (PROOF_GENERATED). The plugin retries with the PAYMENT-SIGNATURE header; the seller verifies and settles through the x402 facilitator, which posts the on-chain USDC transfer.buyerUserId index) and the library bucket in Amazon S3.Agent build pipeline (deploy time)

The seller diagram has four panels. Each panel's numbered flow is below.
POST /admin/storefront/seller/setup (main Cognito API, behind require_admin), routing to the seller-setup Lambda.create_payment_credential_provider() (Coinbase CDP), create_payment_manager() (AWS_IAM service role), create_payment_connector(), and create_payment_instrument() twice, one Base Sepolia and one Solana Devnet payout instrument, both scoped to the seller service userId.READY) to Amazon DynamoDB and returns the Coinbase Wallet Hub delegation links plus a one-time Solana USDC funding note. The image generator and the storefront both read their payout address from this single config.list_products calls GET /products → the products Lambda → the catalog in Amazon DynamoDB (free, no payment).buy_product calls POST /orders without a proof → the orders Lambda returns HTTP 402 with the payTo from the seller config.AgentCorePaymentsPlugin runs ProcessPayment from the buyer's session and retries /orders with the proof.CONFIRMED. Goods are delivered only after settlement succeeds.generate_image calls POST /image-gen without a proof → the image-gen Lambda reads its payout address from the seller config (DynamoDB) and returns HTTP 402.ProcessPayment from the buyer's session and retries with the proof.list_orders (a buyer-scoped GET /orders?userId= lookup via the buyerUserId index), confirms the match, then cancel_order calls POST /orders/{id}/refund (consume-gated, so a downloaded item is non-refundable and the agent cannot force it; an admin can force via POST /admin/storefront/orders/{id}/refund from the Seller Orders page).refundOrder calls settlePayout, which creates a per-refund payment session capped at exactly the refund amount, scoped to the seller userId.ProcessPayment with the seller's instrument for the order's network as the payer, then settles seller→buyer through the x402 facilitator.REFUNDED, inventory is restocked, and the buyer's library copy is removed.Every paid action converges on the AgentCore payments ProcessPayment call, driven by the AgentCorePaymentsPlugin.
| Path | Tool | Price | How it works |
|---|---|---|---|
| Image generation | generate_image |
0.04 USDC | The seller Lambda returns HTTP 402; the plugin runs ProcessPayment and retries with the proof; the seller settles and renders the image with Amazon Nova Canvas |
| Storefront order | buy_product |
per product | The storefront returns HTTP 402; the plugin pays; the order Lambda verifies, reserves inventory, settles, and fulfils |
| Refund | cancel_order |
reverse | The order Lambda creates a per-refund spend-capped session and calls ProcessPayment with the seller as the payer, settling USDC back to the buyer |
| Balance | check_balance |
free | GetPaymentInstrumentBalance on the active instrument; no payment |
| Order lookup | list_orders |
free | Buyer-scoped GET /orders?userId= on the storefront (via the buyerUserId index); lets the agent find an order id to refund across sessions |
Canonical plugin path: In text and REST modes the AgentCorePaymentsPlugin is attached to the agent. A paid tool issues its first request with no proof; on an HTTP 402 it returns a PAYMENT_REQUIRED marker that the plugin intercepts, running the tagged ProcessPayment and retrying the tool with the PAYMENT-SIGNATURE header injected. The agent never assembles a payment by hand, and the base64 image never enters the model context. Voice mode (BidiAgent) uses an equivalent in-tool pay-and-retry fallback. Both paths call the same ProcessPayment with the session ID, instrument ID, the payment requirements from the 402, and the vendor-matched userId.
Payment credentials (manager ARN, instrument ID, session ID, wallet address, network, and the vendor-matched userId) are threaded to the agent per session through the WebSocket init frame (or the REST body), so the agent does not read a database at connection time. The agent injects them into the tool layer through set_payment_credentials(). For Coinbase instruments the CDP UUID is the effective userId; for Stripe/Privy instruments the Cognito sub is used. The network field (ETHEREUM or SOLANA) selects the x402 scheme and the balance lookup. A context_update message lets the frontend switch instrument, session, or network without reconnecting.
| Mode | Model | Payment path |
|---|---|---|
| Text | Anthropic Claude Sonnet (us.anthropic.claude-sonnet-4-6) via Strands Agents |
AgentCorePaymentsPlugin (canonical) |
| Voice | Amazon Nova Sonic (amazon.nova-2-sonic-v1:0) via BidiAgent |
in-tool pay-and-retry fallback |
Both modes share the same tools and payment infrastructure. AgentCore Memory persists conversation across sessions.
The x402-enabled seller endpoints run as Lambda functions behind their own API Gateways. The x402 payment proof is the authentication, so no Cognito is required. Both accept Base Sepolia and Solana Devnet and resolve their payout address from the provisioned seller config.
| Endpoint | Function | Price | Response |
|---|---|---|---|
POST /image-gen |
AI image generation via Amazon Nova Canvas | 0.04 USDC | Base64-encoded PNG, returned to the agent, which stores it in Amazon S3 |
POST /orders |
Agent-economy storefront order (verify → reserve inventory → settle → fulfil) | per product | Order confirmation; digital file/license or physical-order email |
GET /products |
Storefront catalog (free, no payment) | n/a | Product list/detail from Amazon DynamoDB |
The storefront also exposes POST /orders/{id}/refund (consume-gated, agent-callable) and, on the main authenticated API, an admin force-refund. A refund makes the seller the payer through a per-refund spend-capped session.
npm install -g [email protected])The setup scripts handle everything from a clean clone: .env creation, dependency installation, CDK bootstrap, deployment, and automatic .env injection of stack outputs.
Move into the project directory:
cd agentcore-payments
Create your .env from the template:
cp .env-sample .env
Optional: if you plan to use Stripe/Privy wallets, open .env and fill in the two public Privy IDs (VITE_PRIVY_APP_ID and VITE_PRIVY_SIGNER_ID) from the Privy Dashboard. These are the only values you set by hand; everything else is auto-detected or injected by the setup scripts. You can skip this and add them later if you are only using Coinbase CDP. See Obtaining Wallet Provider Credentials for where to find them.
Deploy the backend (installs dependencies, deploys the CDK stack, and injects outputs):
npm run setup:backend
Deploy the frontend:
npm run setup:amplify
There is no seller wallet to set in .env. The seller's payout wallet (EVM and
Solana) is provisioned by AgentCore payments from the admin Seller Setup page
after deploy, and every paid endpoint (storefront orders and the image-gen
seller) receives payments to that one provisioned wallet.
setup:backend:
.env-sample → .env if missing.AWS_ACCOUNT_ID and AWS_REGION from your CLI config.COGNITO_USER_POOL_ID, API_URL, SELLER_API_URL, MEMORY_ID, and their VITE_-prefixed counterparts) into .env.setup:amplify:
AMPLIFY_APP_ID to .env.Re-running setup:amplify updates the same deployment; it never creates duplicates.
StripePrivy-backed wallets require attaching the AgentCore authorization-key quorum as a session signer before ProcessPayment can sign on the user's behalf. The Instruments page exposes an Add Signer action per Privy instrument that runs a one-time Privy email OTP and then calls addSessionSigners. To enable the flow, set two public values in .env:
| Variable | Source |
|---|---|
VITE_PRIVY_APP_ID |
Privy Dashboard → App → App ID |
VITE_PRIVY_SIGNER_ID |
Privy Dashboard → Wallet infrastructure → Authorization keys → key ID |
Both values are public identifiers; the private key and app secret stay on the backend and are entered directly in the admin surface (Credential Providers page).
Important — the signer and the credential provider must use the same authorization key.
VITE_PRIVY_SIGNER_IDmust be the same Privy authorization key whose private key you later paste as the Credential Provider's Authorization Private Key — i.e. the credential provider's Authorization Key ID must equalVITE_PRIVY_SIGNER_ID. The Add Signer flow grants your wallet delegation toVITE_PRIVY_SIGNER_ID, and the agent signs with the credential provider's key; if they are different keys,ProcessPaymentwill be rejected by Privy at signing time even though everything appears configured.
If you prefer to deploy step by step:
cp .env-sample .env
The setup script auto-detects or injects every value; there is nothing to fill in manually. The seller payout wallet is provisioned later from the admin Seller Setup page, not set here.
| Variable | Required | Source |
|---|---|---|
AWS_REGION |
No | AWS CLI config |
AWS_ACCOUNT_ID |
No | aws sts get-caller-identity |
CP_ENDPOINT / DP_ENDPOINT |
No | Derived from AWS_REGION |
COGNITO_USER_POOL_ID |
No | Injected by setup:backend |
COGNITO_CLIENT_ID |
No | Injected by setup:backend |
API_URL |
No | Injected by setup:backend |
SELLER_API_URL |
No | Injected by setup:backend |
MEMORY_ID |
No | Injected by setup:backend |
VITE_PRIVY_APP_ID |
No | Privy Dashboard (only needed for StripePrivy Add Signer flow) |
VITE_PRIVY_SIGNER_ID |
No | Privy Dashboard (only needed for StripePrivy Add Signer flow) |
After deploy, run Seller Setup from the admin page to provision the seller payout wallet. The setup page surfaces the Solana payout address with funding guidance: fund it once with USDC on Solana Devnet through the Circle Faucet so its token account exists, which the x402 facilitator needs to settle Solana payments. EVM needs no such step.
Install the backend (CDK) dependencies:
cd backend && npm ci && cd ..
Install the image generation seller dependencies:
cd backend/lambdas/sellers/image-gen && npm ci && cd ../../../..
Install the storefront seller dependencies:
cd backend/lambdas/sellers/storefront && npm ci && cd ../../../..
Install the frontend dependencies:
cd frontend && npm ci && cd ..
Bootstrap CDK (first time per account and Region):
cd backend && npm run cdk -- bootstrap "aws://$AWS_ACCOUNT_ID/$AWS_REGION"
Deploy the stack:
npm run cdk -- deploy --require-approval never --outputs-file ../cdk-outputs.json
Copy the values from cdk-outputs.json into .env, or run setup:backend, which does this automatically.
npm run setup:amplify
Or run the frontend locally:
cd frontend && npm run dev
Sign in as an admin. setup:backend seeds a demo admin user ([email protected]) in the admin group, so you can reach the admin pages immediately. The password is generated once during deployment and stored in AWS Secrets Manager (never in this repo, logs, or stack outputs). Retrieve it using the secret name from the AdminCredentialsSecretName stack output, which setup:backend also injects into .env as ADMIN_SECRET_NAME:
aws secretsmanager get-secret-value --secret-id "$ADMIN_SECRET_NAME" --query SecretString --output text
Rotate or remove this demo account before any real exposure. Otherwise, sign up your own account (the first user is auto-assigned to the user group) and add it to the admin group in the Cognito console.
Quick Setup (recommended): From the Admin > Overview page, click Quick Setup and pick a vendor tab (Coinbase CDP or Stripe/Privy). Fill in the vendor credentials and a manager and connector name. The UI runs all three create calls in order. See Obtaining Wallet Provider Credentials for how to get each vendor's values.
Manual setup (for finer control or adding a second vendor):
type is inferred from the provider vendor.Editing and rotating:
UpdatePaymentCredentialProvider is a full replace of providerConfigurationInput, so the dialog resubmits the full secret set for the chosen vendor. The provider ARN stays the same, so connectors and instruments continue to work without migration.Create an Instrument: Navigate to Instruments. Pick a network (ETHEREUM for Base Sepolia or SOLANA for Solana Devnet), select a connector, and click Create.
Grant signing permission (Coinbase only): Click Grant Delegation on the Instruments page to authorize AgentCore to sign x402 payments on your behalf for 24 hours. Revoke at any time.
Create a Payment Session: In the Agent Chat page, click New Payment Session. Set a spending limit (for example, 1.0 USD) and expiry (15 to 480 minutes). Sessions are network-agnostic, so the same session works with any instrument under the selected payment manager.
Select your wallet from the dropdown in the chat header. The network is detected from the instrument.
Fund your wallet with USDC from the Circle Faucet: pick Base Sepolia for EVM instruments or Solana Devnet for Solana instruments.
Connect: Click Text for text mode or Voice for voice mode.
Chat with the agent:
User: What's my wallet balance?
Agent: [check_balance]
Your wallet has 4.85 USDC on Base Sepolia.
User: What's for sale?
Agent: [list_products]
Here is each product with its price, stock, and description...
User: Buy the stock photo pack
Agent: [buy_product]
Your Stock Photo Pack purchase is confirmed, 7.99 USDC on Solana Devnet.
It's available in your Library.
User: Generate an image of a whale swimming in space
Agent: [generate_image]
Your image is ready, 0.04 USDC. It's shown here and saved to your Library.
User: Cancel that order
Agent: [cancel_order]
The order was cancelled and 7.99 USDC was refunded to your wallet.
User: (new session) Actually, refund the stock photo pack I bought earlier
Agent: [list_orders]
I found your Stock Photo Pack order for 7.99 USDC on Solana Devnet.
[cancel_order]
Done, 7.99 USDC was refunded to your wallet.
Install dependencies:
cd payment-agent && pip install -r requirements.txt
Run the agent:
python agent.py
The agent runs on port 8080 with /ping, /health, /invocations (REST), and /ws (WebSocket) endpoints.
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-d '{"prompt": "What is for sale in the storefront?", "userId": "test-user"}'
Install dependencies and start the dev server:
cd frontend && npm ci && npm run dev
Build for production:
npm run build
The React frontend uses Vite and connects to the API Gateway URL in VITE_API_URL.
Install dependencies:
cd backend && npm ci
Synthesize the CloudFormation template:
npm run cdk -- synth
Preview changes against the deployed stack:
npm run cdk -- diff
Deploy:
npm run cdk -- deploy
agentcore-payments/
├── payment-agent/ # Agent container (deployed to AgentCore Runtime)
│ ├── agent.py # FastAPI server, text/voice streaming, WebSocket handler
│ ├── tools.py # check_balance, generate_image, list_products, buy_product,
│ │ # list_orders, cancel_order; x402 + AgentCore payments ProcessPayment
│ ├── config.py # Centralized environment configuration
│ ├── Dockerfile # Python 3.12 slim container
│ └── requirements.txt # strands-agents, bedrock-agentcore (Payments plugin), fastapi, boto3
├── backend/
│ ├── lib/
│ │ └── payment-agent-stack.ts # CDK stack (Cognito, DynamoDB, Lambda, API GW, ECR,
│ │ # CodeBuild, AgentCore Runtime + Memory, S3)
│ └── lambdas/
│ ├── admin/ # Credential providers, payment managers, payment connectors
│ ├── user/ # Instruments, sessions, payment options, agent WebSocket URL
│ ├── sellers/
│ │ ├── image-gen/ # x402 seller: Nova Canvas image generation (0.04 USDC)
│ │ └── storefront/ # x402 agent-economy storefront: products, orders (x402 +
│ │ # refunds), seller setup, library; deliverables + static site
│ └── shared/ # AgentCore payments client, response helpers
├── frontend/
│ └── src/
│ ├── pages/
│ │ ├── admin/ # Overview, credential providers, managers, connectors,
│ │ │ # seller setup, seller orders, how it works
│ │ └── user/ # Connect agent, agent chat, instruments, sessions,
│ │ # orders, library, information
│ ├── components/ # Reusable UI components
│ ├── providers/ # PrivyProvider (Privy embedded wallets)
│ └── lib/ # API client, auth, balance utilities
├── test/integration/ # setup_backend.sh, setup_amplify.sh, cleanup.sh,
│ # delete_payment_resources.py
├── .env-sample # Environment variable template
├── package.json # Top-level scripts (setup, cleanup)
└── amplify.yml # AWS Amplify build configuration
npm run cleanup
This deletes the Amplify app (from the saved AMPLIFY_APP_ID), runs an account-scoped teardown of the runtime AgentCore payments resources created via the admin console and Seller Setup (managers, connectors, credential providers, instruments, sessions), destroys the CDK stack, removes CloudWatch log groups, cleans the Amazon ECR repository, and deletes local build artifacts. It prompts for confirmation, with a separate confirmation for the account-wide payment resource sweep (skip that step if you run cleanup in a shared account).
Delete resources in reverse order of creation.
1. Delete the Amplify app:
APP_ID=$(aws amplify list-apps --query "apps[?name=='agentcore-payments'].appId" --output text)
aws amplify delete-app --app-id $APP_ID
2. Delete the runtime AgentCore payments resources (managers, connectors, credential providers, instruments, sessions) created via the admin console and Seller Setup. These are not part of the CDK stack, so do this before destroying the stack:
python3 test/integration/delete_payment_resources.py --yes
3. Destroy the CDK stack:
cd backend && npm run cdk -- destroy --force && cd ..
4. Delete CloudWatch log groups:
for prefix in "/aws/lambda/agentcore-payments" "/aws/lambda/x402-seller" "/aws/lambda/x402-storefront" "/aws/codebuild/agentcore-payments" "/aws/bedrock-agentcore/runtimes"; do
aws logs describe-log-groups --log-group-name-prefix "$prefix" \
--query 'logGroups[*].logGroupName' --output text | \
xargs -n1 aws logs delete-log-group --log-group-name 2>/dev/null
done
5. Delete ECR images:
aws ecr delete-repository --repository-name agentcore-payments-agent --force
6. Remove local files:
rm -rf backend/node_modules/ backend/cdk.out/ frontend/node_modules/ frontend/dist/
| Issue | Cause | Solution |
|---|---|---|
401 Unauthorized on API calls |
Cognito token expired or missing | Log out and log back in; verify VITE_COGNITO_USER_POOL_ID and VITE_COGNITO_CLIENT_ID match CDK outputs |
403 Forbidden on admin routes |
User not in admin group |
Add the user to the admin group in the Cognito console |
Payment session expired |
Session exceeded its expiry | Create a new session (15–480 minutes) |
Insufficient balance |
Session spending limit reached | Create a new session with a higher USDC spending limit |
Payment instrument not found on Coinbase |
Instrument created before the CDP UUID identity fix, or a stale session created under a different identity | Recreate the Coinbase instrument and create a fresh session |
ProcessPayment succeeds but transfer fails on Privy |
Authorization-key quorum is not attached as a signer on the wallet | Click Add Signer on the Privy instrument row and complete the Privy email OTP |
Solana payments fail with empty {} error |
The provisioned seller wallet has no USDC token account on devnet | Fund the seller's Solana payout address (shown on the admin Seller Setup page) with USDC through the Circle Faucet on Solana Devnet |
| Solana payments fail, wrong network selected | Agent picks EVM accept instead of Solana | Rebuild the agent container (npm run setup:backend). The seller session registers only the user's active network |
| Agent not responding | AgentCore Runtime not deployed or unhealthy | Check that AgentRuntimeArn exists; verify the CodeBuild project succeeded |
| Images not displaying | S3 presigned URL expired or media bucket missing | URLs expire after 30 minutes; verify MEDIA_BUCKET on the Runtime |
| Voice mode no audio | Nova Sonic not enabled | Enable amazon.nova-2-sonic-v1:0 in the Bedrock console for your region |
| WebSocket disconnects on large responses | 128 KB frame limit | Large responses chunk automatically; this is an API Gateway limit |
| CDK deploy fails on CodeBuild | Docker not available or ECR permissions missing | Ensure the CodeBuild project has privileged: true and ECR push permissions |
ModuleNotFoundError in agent |
Missing dependency in container | Verify requirements.txt includes all packages; redeploy through cdk deploy |
The CDK app runs cdk-nag AwsSolutionsChecks on every synth and deploy, so infrastructure is linted against the AWS Solutions rule pack. Genuine improvements are applied in the stack (S3 enforceSSL, DynamoDB point-in-time recovery, and CloudFront origin access control). The remaining findings are intentional sample trade-offs (for example, x402 seller APIs use payment proofs instead of a JWT authorizer, and AgentCore payments preview actions are not yet resource-scopeable) and carry inline NagSuppressions with a documented reason for each. Run CDK_NAG=0 npm run cdk -- synth to skip the checks during fast local iteration.
This sample runs a conversational agent that can take actions on a user's behalf, including test-network payments. It is built with responsible AI safeguards, and you should extend them for production:
userId, injected server-side into the tool layer. The model does not choose whose funds to spend.Deploying an autonomous agent that transacts on a user's behalf is a high-responsibility use case. Review the AWS Responsible AI guidance and apply controls appropriate to your risk tolerance before moving beyond test networks.
This sample does not process or store cardholder data. Payments are settled in stablecoin (USDC) over the x402 protocol using wallet signatures, and Stripe/Privy is used here as a wallet credential provider, not as a card processor, so PCI-DSS does not apply to this implementation. If you extend this solution to accept card payments, you become responsible for PCI-DSS compliance; see the AWS PCI-DSS compliance resources for guidance. Nothing here is legal or compliance advice.
This library is licensed under the MIT-0 License. See the LICENSE file.
DNA — Payment rails for AI agents. x402 micropayment protocol on Solana. Netting, transfer, stream settlement. Receipt anchoring on-chain.
x402 (HTTP 402 Payment Required) SDK + MCP server: let any API charge for itself and any AI agent pay for itself, USDC & stablecoins across EVM, Solana & 8 more chain families, in a couple of lines. Backendless, no fee, self-custodial, paid straight to your wallet. TypeScript, MIT.
Enterprise audit, compliance & budget enforcement layer for the x402 payment protocol