Referencia para desarrolladores

Documentación

Referencia de la API del protocolo RSoft Bank. Los endpoints de lectura (explorador, estado, historial, tasas) son públicos; los de préstamo (pedir un préstamo, girar de una línea de crédito) requieren una API key. A2A usa firmas del agente.

Inicio rápido: el primer préstamo de tu agente en ~15 minutos

El ciclo completo: registra una identidad en la cadena, pide 5 USDC, repágalos y quédate con lo que de verdad importa: un historial crediticio verificable en la cadena que tu agente puede mostrar a cualquier prestamista que hable ERC-8004.

1 · Wallet

Una wallet agéntica (recomendamos Coinbase CDP) con unos centavos de ETH en Base para el gas.

2 · Pasaporte

Un register() de ERC-8004, una sola vez, desde la propia wallet del agente: tienes los fragmentos de código en la página de registro.

3 · API key del piloto

Durante el piloto, pedir por REST usa una API key: escríbele a @RSoft-Agentic-Bank para conseguir una. A2A y MCP no necesitan key.

# pip install cdp-sdk requests
# Env: CDP_API_KEY_ID / CDP_API_KEY_SECRET / CDP_WALLET_SECRET (your agent's
# CDP Server Wallet) + BANK_API_KEY (pilot key) + AGENT_WALLET (0x…)
import asyncio, os, time, uuid, requests
from cdp import CdpClient
from cdp.openapi_client.models.eip712_domain import EIP712Domain
from cdp.evm_transaction_types import TransactionRequestEIP1559

BANK   = "https://rsoft-agentic-bank.com/api/v1"
KEY    = {"X-API-Key": os.environ["BANK_API_KEY"]}
WALLET = os.environ["AGENT_WALLET"]
USDC   = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"          # Base mainnet
VERIFYING = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"       # EIP-712 domain

async def main():
    async with CdpClient(api_key_id=os.environ["CDP_API_KEY_ID"],
                         api_key_secret=os.environ["CDP_API_KEY_SECRET"],
                         wallet_secret=os.environ["CDP_WALLET_SECRET"]) as cdp:

        # 1) Sign the loan terms (EIP-712 LoanRequest) with the agent's wallet
        amount, nonce, deadline = 5.0, str(uuid.uuid4()), int(time.time()) + 3600
        domain = EIP712Domain(name="RSoft Agentic Bank", version="1",
                              chain_id=8453, verifying_contract=VERIFYING)
        # NOTE: CDP requires the EIP712Domain entry inside `types` (ethers/viem omit it)
        types = {
            "EIP712Domain": [
                {"name": "name",              "type": "string"},
                {"name": "version",           "type": "string"},
                {"name": "chainId",           "type": "uint256"},
                {"name": "verifyingContract", "type": "address"}],
            "LoanRequest": [
                {"name": "agentWallet",     "type": "address"},
                {"name": "loanAmountUsdc6", "type": "uint256"},
                {"name": "nonce",           "type": "string"},
                {"name": "deadline",        "type": "uint256"}]}
        message = {"agentWallet": WALLET, "loanAmountUsdc6": int(amount * 1e6),
                   "nonce": nonce, "deadline": deadline}
        sig = await cdp.evm.sign_typed_data(address=WALLET, domain=domain,
                                            types=types, primary_type="LoanRequest",
                                            message=message)

        # 2) Request the loan — the 5-agent pipeline runs and disburses USDC
        r = requests.post(f"{BANK}/loan/request", headers=KEY, json={
            "agent_wallet": WALLET, "loan_amount": amount,
            "nonce": nonce, "deadline": deadline, "signature": sig}).json()
        request_id = r["request_id"]

        # 3) Poll until disbursed (public endpoint, no key)
        while requests.get(f"{BANK}/loan/status/{request_id}").json()["status"] \
                not in ("disbursed", "rejected"):
            time.sleep(5)

        # 4) Repay: quote is public; pay the EXACT amount to the treasury
        info = requests.get(f"{BANK}/loan/repay-info/{WALLET}").json()
        base6 = int(round(info["repayment_amount"] * 1e6))
        data = ("0xa9059cbb" + info["pay_to"][2:].zfill(64)
                             + hex(base6)[2:].zfill(64))       # ERC-20 transfer
        tx = await cdp.evm.send_transaction(address=WALLET, network="base",
                transaction=TransactionRequestEIP1559(to=USDC, data=data, value=0))

        # 5) Report it (optional — unreported payments are auto-detected ~10 min)
        requests.post(f"{BANK}/loan/repay", headers=KEY,
                      json={"request_id": request_id, "tx_hash": tx})
        print("Loan repaid - your agent now has on-chain credit history ✓")

asyncio.run(main())

Lo que ganó tu agente: un préstamo repagado en los libros del banco y una marca de reputación ERC-8004 positiva firmada por la wallet del banco: portátil, verificable e imposible de fabricar uno mismo. Cada repago además sube la escalera de crédito: $5 → $10 (1 repagado) → $25 (3) → $50 (6) → $100 (10). Revisa cómo está cualquier agente en la página de Reputación.

Primeros pasos

¿Qué es RSoft Bank?

RSoft Bank es un protocolo de préstamos descentralizado pensado para agentes de IA. Los agentes autónomos pueden pedir préstamos en USDC que se evalúan con un pipeline automático de varios agentes, desde la verificación de identidad hasta la liquidación en la cadena.

URL base

https://rsoft-agentic-bank.com

Todos los endpoints llevan el prefijo /api/v1, salvo los chequeos de salud.

Autenticación

Todos los endpoints de lectura de esta lista son públicos: no necesitas API key ni conectar una wallet. Las respuestas son JSON, con fechas en ISO 8601.

Inicio rápido del agente · un solo prompt

Pega esto en Claude Code, Cursor, Windsurf, Codex, OpenClaw o cualquier agente que pueda leer una URL. Carga el manifiesto de skills del banco y guía al agente en la configuración, la firma y el repago.

I want my AI agent to get credit from RSoft Bank. Read the docs at https://rsoft-agentic-bank.com/skills.md and then set it up.

O agrega el servidor MCP directamente:

claude mcp add --transport http rsoft-bank https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/mcp

Índice legible por máquinas para LLMs y crawlers: /llms.txt · /skills.md

Cómo piden prestado los agentes

Un agente puede tomar deuda por cuatro vías. REST, MCP y A2A son préstamos de una sola vez que comparten la misma evaluación (topes, firma EIP-712, nonce protegido contra repetición); la línea de crédito es rotativa.

REST
POST /api/v1/loan/request

REST directo

El camino más simple. Firma los términos del préstamo y envíalos por POST. API key del piloto: mira el Inicio rápido.

Firma el LoanRequest EIP-712 (agentWallet, loanAmountUsdc6, nonce, deadline) y envíalo por POST. El banco corre el pipeline completo de 5 agentes y deposita los USDC en tu wallet.

POST /api/v1/loan/request
X-API-Key: <bank_api_key>

{
  "agent_wallet": "0x…",
  "loan_amount": 5,
  "nonce": "…",
  "deadline": 1893456000,
  "signature": "0x…"      // EIP-712 LoanRequest
}
MCP
tool: request_loan

Herramienta MCP

Para agentes autónomos que ya usan herramientas MCP. No hace falta API key.

Agrega el servidor MCP del banco a las herramientas de tu agente y llama a request_loan con tu firma EIP-712. Misma evaluación y mismo contrato de firma que REST: el MCP transporta tu firma, nunca firma por ti. Mira la sección Servidor MCP para ver todas las herramientas.

// agent MCP config (Streamable HTTP)
mcpServers:
  rsoft-bank:
    url: https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/mcp

// then your agent calls the tool
tool  request_loan
args  { "amount": 5, "agent_id": "0x…",
        "signature": "0x…", "nonce": "…", "deadline": 1893456000 }
A2A
SendMessage: negotiate_loan → request_loan

Agente a agente

Para agentes que hablan el estándar A2A 1.0. Descubre la agent card y delega la tarea.

El banco es un par A2A estándar: descúbrelo con su Agent Card, previsualiza los términos con negotiate_loan, fírmalos y ejecútalos con request_loan. Mira la sección Protocolo A2A para ver todas las skills.

// discovery
GET  <a2a-server>/.well-known/agent-card.json

// delegate (JSON-RPC, header A2A-Version: 1.0)
POST <a2a-server>/
{ "jsonrpc": "2.0", "id": 1, "method": "SendMessage",
  "params": { "message": { "role": "ROLE_USER", "parts": [
    { "data": { "skill": "negotiate_loan",
                "agent_id": "0x…", "amount": 5 } } ]}}}
Credit Line
POST /credit-lines/request → /{id}/draw

Crédito rotativo

Para agentes que necesitan capital de forma recurrente.

Abre una línea de crédito aprobada una vez y gira de ella las veces que necesites durante su vigencia, en vez de pedir un préstamo nuevo cada vez. Repaga para liberar crédito disponible.

// open a line (once)
POST /api/v1/credit-lines/request
{ "agent_id": "0x…", "requested_limit": 50 }

// draw against it (repeat, owner-signed)
POST /api/v1/credit-lines/{line_id}/draw
{ "amount": 5, "signature": "0x…" }

Repagar un préstamo

El repago es una transferencia simple de USDC a la tesorería por el monto exacto adeudado (capital + interés de todo el plazo, fijado al originar el préstamo, así que la cotización nunca cambia). Son dos pasos, y el segundo es opcional.

GET
/api/v1/loan/repay-info/{wallet}

1 · Pide la cotización del repago

Público, sin API key.

Devuelve exactamente cuánto debe el agente y a dónde enviarlo.

GET /api/v1/loan/repay-info/0xYourAgentWallet

{
  "request_id": "req_…",
  "principal": 5.0,
  "interest": 0.102739,
  "repayment_amount": 5.102739,
  "currency": "USDC",
  "pay_to": "0x274C…74C5a"      // bank treasury (Base)
}

Envía una transfer de USDC desde la propia wallet del agente (se verifica el remitente: nadie puede adjudicarse tu pago) a pay_to por el monto exacto de repayment_amount.

POST
/api/v1/loan/repay

2 · Informa el pago (vía rápida opcional)

API key · se acredita al instante.

El banco verifica la transacción en la cadena (token, destinatario, remitente, monto) antes de acreditarla: un tx hash puede saldar una sola deuda, nunca más de una.

POST /api/v1/loan/repay
X-API-Key: <bank_api_key>

{
  "request_id": "req_…",
  "tx_hash": "0x…"        // your USDC transfer
}

Con pagar alcanza

Si tu agente se cae entre la transferencia y el aviso, no pasa nada malo: el banco revisa las transferencias que llegan a la tesorería cada ~10 minutos y acredita solo cualquier pago por el monto exacto de un prestatario. Un agente que pagó nunca puede quedar en impago. Cada repago verificado actualiza la posición del agente (escalera de crédito) y publica una marca de reputación ERC-8004 positiva firmada por el banco: el historial crediticio portátil que otros prestamistas pueden verificar.

Autorización de pagos: ¿puede este agente mover este dinero?

Las mismas reglas que protegen un préstamo (identidad ERC-8004, un sponsor humano vinculado, el botón de apagado y los topes del sponsor) aplicadas al dinero que se liquida en tus propios rieles: un pago, una transferencia, una compra. Tu sistema pregunta antes de que el agente actúe; el Banco responde permitir o denegar, firma el permiso y registra cada decisión en un libro de solo agregado que el sponsor y tus auditores pueden leer. El Banco nunca toca los fondos.

Políticas

accountable (por defecto): identidad + sponsor vinculado + topes. La que piden los reguladores.
identity: identidad + topes; el sponsor solo se exige si hay uno vinculado.
open: solo topes, sin leer el registro.

Códigos de motivo (decide con estos, nunca con el texto)

allowed · identity_required · sponsor_required · agent_paused · agent_revoked · cap_exceeded · daily_cap_exceeded. Se revisan en ese orden. Cada denegación trae un next_action {code, message, url}.

POST /api/v1/authorize                     (X-API-Key)
{
  "agent_wallet": "0xYourAgentWallet",
  "amount": 42.5,
  "action": "payment",                     // your slug: payment | transfer | purchase | …
  "counterparty": "acme.com",              // optional
  "reference": "inv-7",                    // optional, your own id
  "policy": "accountable"                  // default
}

200 OK
{
  "authorization_id": "auth_3f9c…",
  "decision": "allow",
  "reason_code": "allowed",
  "controls": { "bound": true, "paused": false, "revoked": false, "version": 3,
                "per_action_cap": 100, "daily_cap": 500,
                "daily_used": 80, "remaining_today": 377.5 },
  "identity": { "checked": true, "has_identity": true },
  "authorization_jwt": "eyJ…",             // HS256, type rsoft_payment_authorization
  "expires_at": "2026-09-16T18:10:00Z"     // 10 minutes
}

200 OK  (a deny is still 200 - only infrastructure fails with 5xx)
{
  "decision": "deny",
  "reason_code": "agent_paused",
  "message": "The sponsor paused this agent.",
  "next_action": { "code": "contact_sponsor", "message": "…", "url": "…/docs#sponsor" }
}

El max_loan_amount del sponsor es también el tope por operación y daily_draw_cap el tope diario para las acciones autorizadas: un solo juego de números limita todo lo que el agente hace con dinero. El tope diario cuenta las autorizaciones permitidas de las últimas 24 horas.

GET /api/v1/authorizations?agent_wallet=0x…&limit=50   (X-API-Key)
GET /api/v1/authorizations/auth_3f9c…                    (X-API-Key)

El libro, del más nuevo al más viejo: qué se pidió, qué se respondió y por qué. Las filas son inmutables a nivel de base de datos. Expórtalo para tu auditor o supervisor.

Falla cerrado

En modo de dinero real, el Banco responde 503 (y no emite nada) cuando no puede leer el registro de identidad, los controles del sponsor o el libro. Nunca se emite un permiso que no esté en el libro. Presenta authorization_jwt al riel que liquida; verifícalo sin conexión con la llave del Banco o consultando la autorización por id.

Webhooks: eventos del préstamo, sin consultar

Suscribe un endpoint HTTPS a los eventos del ciclo de vida del préstamo en vez de consultar /loan/status una y otra vez. Las entregas van firmadas con HMAC. La entrega nunca frena un préstamo: un endpoint caído no demora ni bloquea la originación, el desembolso ni el repago.

Suscribirse

POST /api/v1/webhooks
X-API-Key: <bank_api_key>

{
  "url": "https://agent.example.com/hooks/rsoft",   // https, no private hosts
  "events": ["loan.disbursed", "loan.repaid", "loan.defaulted"],
  "agent_wallet": "0x…"                              // optional: scope to one wallet
}

→ 201
{ "id": "whk_…", "secret": "…" }     // the secret is returned ONCE - store it

Las API keys del banco son compartidas, no por agente, así que una suscripción limitada a una wallet también exige el OwnerAction EIP-712 de esa wallet (acción webhook_subscribe, resourceId = la url). Las suscripciones para todos los agentes necesitan la key de administrador del banco.

Eventos

loan.approved
loan.rejected
loan.disbursed
loan.repaid
loan.defaulted
loan.drafted
loan.draft_approved
loan.draft_rejected
loan.draft_expired

Administrar

GET    /api/v1/webhooks?agent_wallet=0x…
DELETE /api/v1/webhooks/{id}
POST   /api/v1/webhooks/{id}/ping
GET    /api/v1/webhooks/{id}/deliveries

Todos con X-API-Key. ping envía una entrega de prueba; deliveries lista los intentos y las respuestas.

Verificar la firma

X-RSoft-Timestamp: 1756821731                 // unix seconds
X-RSoft-Signature: sha256=<hex>               // HMAC_SHA256(secret, "{timestamp}.{raw_body}")

// Node
import { createHmac, timingSafeEqual } from "node:crypto";
const expected = "sha256=" + createHmac("sha256", SECRET)
  .update(`${req.headers["x-rsoft-timestamp"]}.${rawBody}`).digest("hex");
const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-rsoft-signature"]));

Firma sobre el cuerpo crudo, no sobre uno re-serializado. Rechaza timestamps viejos. Reintentos: 3 intentos con espera creciente; las respuestas 4xx (salvo 408 y 429) no se reintentan.

Directorio de agentes: el registro ERC-8004, legible

Lecturas públicas y sin key de los registros de Identidad y Reputación ERC-8004 en Base mainnet, cruzadas con los libros del banco. Busca cualquier agente por token id o wallet, lista los registros recientes o haz una búsqueda. Identity Registry 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432, Reputation Registry 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63.

GET /api/v1/agents/registry/58492

{
  "token_id": 58492,
  "exists": true,
  "owner": "0x4cff…",
  "agent_wallet": "0x4cff…",
  "canonical_uri": "https://…/agent.json",
  "client_count": 1,
  "clients": ["0xB684898D3f4437D93848456141445c66Aa322B13"],
  "known_issuers": [ ... ],       // issuers the bank recognises by name
  "trusted_feedback_count": 4,
  "trusted_feedback_value": ...,
  "chain_id": 8453,
  "identity_registry": "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
  "reputation_registry": "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63",
  "bank": { ... }          // the bank's own credit standing, if the wallet is a customer
}
GET /api/v1/agents/registry/by-wallet/{wallet}
GET /api/v1/agents/registry/recent?limit=20
GET /api/v1/agents/registry/search?q=…

Limitación (por diseño)

El IdentityRegistry no se puede enumerar en mainnet. recent y search son un escaneo acotado de los eventos Registered recientes (5000 bloques por defecto) más la tabla de clientes del banco, no el censo completo. Las respuestas traen scanned_window y limitation para que se vea exactamente qué se cubrió. Las búsquedas por token id o wallet son exactas.

Herramientas MCP · y sus gemelas REST gratuitas en el host MCP

get_agent(token_id | wallet)     list_agents(limit)     search_agents(q)

GET https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/api/agents/{id|wallet}
GET https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/api/agents/recent
GET https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/api/agents/search?q=…

Servidor MCP: el banco como herramientas

El banco habla el Model Context Protocol. Apunta cualquier agente compatible con MCP (Claude, LangGraph, AgentKit, eliza, …) al servidor de abajo y el ciclo de crédito completo (solvencia, pedir, repagar) queda disponible como herramientas. Conectarse y llamar herramientas no requiere API key; el pedido de préstamo sigue exigiendo la firma EIP-712 de tu propio agente (el MCP la transporta, nunca firma por ti). El ciclo completo se probó de punta a punta en Base mainnet con USDC reales.

Endpoint (Streamable HTTP)

https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/mcp

// agent MCP config
mcpServers:
  rsoft-bank:
    url: https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/mcp

Herramientas

get_creditworthiness(agent_id)

Puntaje de crédito, historial y deuda pendiente de cualquier agente. Úsala antes de pedir: te dice cuánto permite la escalera.

request_loan(amount, agent_id, signature, nonce, deadline)

Origina el préstamo. Firma la estructura EIP-712 LoanRequest con la wallet del prestatario (mira el paso 1 del Inicio rápido: misma estructura, mismo dominio) y pasa firma + nonce + deadline. Los pedidos sin firma se rechazan. Si se aprueba, el banco deposita los USDC en Base en tu wallet.

get_repayment_info(agent_id)

Cuánto debes (capital + interés) y la dirección de la tesorería a la que pagar. Devuelve el request_id que vas a necesitar para confirmar.

confirm_repayment(request_id, tx_hash)

Después de enviar el monto exacto de USDC en la cadena, informa el tx hash. El banco lo verifica en Base y marca el préstamo como repagado. ¿Te olvidaste de llamarla? La revisión de la tesorería acredita sola los pagos exactos en ~10 minutos.

get_trust_score(wallet)

Puntaje de confianza en la cadena (0-100) para CUALQUIER wallet de agente, con RSoft Trust (beta): revisa la posición ERC-8004 de una contraparte antes de operar o prestarle. Mira la sección Trust API.

get_loan_status(request_id)

Estado de un pedido de préstamo, con amount, agent_wallet y un bloque draft{…} cuando el pedido espera a un sponsor. Consúltala después de una respuesta 202 de borrador.

get_agent_controls(agent_id)

Vínculo con el sponsor, controles (pausa, topes, modo borrador) y el techo efectivo de un agente. Léela antes de pedir: es el número que va a aplicar el Gatekeeper. Mira Controles del sponsor.

get_agent(token_id | wallet)

Entrada del directorio ERC-8004: dueño, wallet, URI, clientes de reputación y la posición del banco para esa wallet. Mira Directorio de agentes.

list_agents(limit)

Agentes registrados hace poco: un escaneo acotado de los eventos Registered recientes más los clientes del banco, no el censo completo. La respuesta dice qué ventana se escaneó.

search_agents(q)

Busca en la misma ventana acotada más la tabla de clientes del banco. Misma limitación, mismo campo scanned_window.

Ciclo completo por MCP (Python)

# pip install mcp
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

MCP_URL = "https://7mavs5vu7ggbhtxvbavdgs26qa0cbawg.lambda-url.us-east-1.on.aws/mcp"

async def main():
    async with streamablehttp_client(MCP_URL) as (read, write, _):
        async with ClientSession(read, write) as s:
            await s.initialize()

            # 1) Borrow - signature/nonce/deadline come from YOUR wallet
            #    signing the EIP-712 LoanRequest (see Quickstart step 1).
            loan = await s.call_tool("request_loan", {
                "amount": 5.0, "agent_id": "0xYourAgentWallet",
                "signature": "0x…", "nonce": "…", "deadline": 1893456000,
            })
            # → { request_id, status: "initiated" } … disburses in seconds

            # 2) Quote the debt
            info = await s.call_tool("get_repayment_info",
                                     {"agent_id": "0xYourAgentWallet"})
            # → { request_id, repayment_amount, pay_to }

            # 3) Send the EXACT repayment_amount in USDC to pay_to
            #    (your wallet stack does this - CDP, viem, web3.py, …)

            # 4) Confirm
            await s.call_tool("confirm_repayment", {
                "request_id": "req_…", "tx_hash": "0x…",
            })
            # → { status: "repaid" } + positive ERC-8004 mark

asyncio.run(main())

Espejo REST: lecturas gratis e inteligencia pagada con x402

Los agentes sin soporte MCP pueden usar el mismo servidor por REST simple. Las lecturas y el repago son gratis; la inteligencia de evaluación se paga por pedido con micropagos x402 en USDC: sin cuenta ni suscripción, tu agente paga el desafío 402 y recibe la respuesta.

Gratis

GET  /api/interest-rates             current protocol rates
GET  /api/creditworthiness/{agent}   score + history for any agent
GET  /api/repay-info/{agent}         amount owed + treasury address
POST /api/repay                      report a repayment tx (money in is always free)
GET  /api/agents/{id|wallet}         ERC-8004 directory entry (see Agent Directory)
GET  /api/agents/recent              recently registered agents (bounded scan)
GET  /api/agents/search?q=           search the same bounded window

Pago (x402, USDC en Base)

GET  /paid/interest-rates        $0.001   rates snapshot
GET  /paid/reputation/{agent}    $0.001   ERC-8004 ReputationRegistry snapshot
POST /paid/credit-check          $0.01    Bank Analyst (Kelly-AMM) assessment
POST /paid/risk-score            $0.05    Gatekeeper + Analyst + Treasury caps
POST /paid/kya-verify            $0.10    signed JWT KYA token (verifiable offline)
POST /paid/validation-attest     $1.00    bank-signed ERC-8004 validation attestation
POST /paid/loans                 $0.01    loan request (same signature contract)

Protocolo A2A: el banco como agente par

El banco también habla el protocolo A2A (v1.0), el estándar de la Linux Foundation para delegar entre agentes. Cualquier cliente A2A puede descubrir el banco por su Agent Card y delegarle tareas bancarias: previsualizar términos, pedir un préstamo, revisar el estado, confirmar un repago. Misma evaluación y mismo contrato de firma EIP-712 que REST y MCP: la vía A2A transporta tu firma, nunca firma por ti.

Agent Card (descubrimiento)

https://nng7khybjb4wlwe64r3eagbxhm0ihurx.lambda-url.us-east-1.on.aws/.well-known/agent-card.json

8 skills publicadas: get_interest_rates, get_creditworthiness, get_reputation, negotiate_loan, get_loan_status, request_loan, get_repayment_info, confirm_repayment.

Delegar una tarea (JSON-RPC)

Envía un pedido SendMessage con una parte de datos de la forma {"skill": <name>, ...params}. El header A2A-Version: 1.0 es obligatorio.

POST https://nng7khybjb4wlwe64r3eagbxhm0ihurx.lambda-url.us-east-1.on.aws/
Content-Type: application/json
A2A-Version: 1.0

{
  "jsonrpc": "2.0", "id": 1, "method": "SendMessage",
  "params": { "message": { "role": "ROLE_USER", "parts": [
    { "data": { "skill": "negotiate_loan", "agent_id": "0xYourWallet", "amount": 10 } }
  ]}}
}

negotiate_loan previsualiza los términos (análisis de crédito, sin desembolso); firma los términos propuestos y llama a request_loan para ejecutar. Las skills que mueven dinero exigen la firma EIP-712 del prestatario, igual que en el Inicio rápido.

Proveedor para AgentKit: el banco en la caja de herramientas de tu agente

¿Construyes con Coinbase AgentKit? Un solo paquete le da a tu agente el ciclo de crédito completo: tasas, historial crediticio, puntajes de confianza de AgentTrust-8004 y préstamos reales en USDC sobre Base, firmando el LoanRequest EIP-712 del banco de forma nativa con el proveedor de wallet del propio agente. El banco nunca ve una llave privada.

npm install rsoft-bank-agentkit
import { AgentKit } from "@coinbase/agentkit";
import { rsoftBankActionProvider } from "rsoft-bank-agentkit";

const agentKit = await AgentKit.from({
  walletProvider, // any EVM wallet provider on Base mainnet
  actionProviders: [
    rsoftBankActionProvider({
      apiKey: process.env.RSOFT_BANK_API_KEY, // loans; reads are free
    }),
  ],
});

6 acciones: get_interest_rates, get_creditworthiness, get_trust_score, request_loan, get_repayment_info, confirm_repayment. Repaga con la transferencia erc20 nativa de AgentKit + confirm_repayment. Código: github.com/rsoft-latam/rsoft-bank-agentkit · npm

Skill de OpenClaw: el banco como comandos instalables

¿Tienes un agente OpenClaw? La skill oficial del banco empaqueta el ciclo completo (revisar tasas y crédito, firmar el pedido, pedir prestado y repagar) como comandos listos para usar. Firma con una wallet de Coinbase CDP (la llave nunca sale del enclave de Coinbase) y lee su configuración de un archivo que controlas tú, así un agente puede cambiar de wallet apuntando a otro archivo. Un agente OpenClaw real ya pidió y repagó un préstamo con ella, de punta a punta.

Instalar

# install the official skill (Base mainnet, real USDC)
npx clawhub install rsoft-agentic-bank

# install its dependencies (Coinbase CDP SDK), once
cd <skill-dir> && npm install

# skill page: https://clawhub.ai/rsoft-latam/skills/rsoft-agentic-bank

Configura tu wallet CDP

# a file only you can read — keep it OUT of synced folders
mkdir -p ~/.rsoft && cat > ~/.rsoft/wallet.env <<'EOF'
CDP_API_KEY_ID=your-cdp-api-key-id
CDP_API_KEY_SECRET=your-cdp-api-key-secret
CDP_WALLET_SECRET=your-cdp-wallet-secret
AGENT_WALLET=0xYourWalletAddress
BANK_API_KEY=your-pilot-api-key      # for loan origination
EOF
chmod 600 ~/.rsoft/wallet.env
export WALLET_CONFIG_PATH=~/.rsoft/wallet.env

🔒 Las credenciales CDP controlan todas las wallets de ese proyecto CDP: usa un proyecto dedicado a este agente, nunca uno con fondos que no quieras que toque.

Pedir y repagar

node bin/address.js            # your wallet address (verifies CDP access)
node bin/request-loan.js 5     # sign + request a 5 USDC loan (one shot)
node bin/repay.js              # quote, pay the exact amount, confirm — one shot

USDC reales en Base mainnet. El banco solo origina préstamos firmados por la wallet que pide: el mismo contrato de seguridad que cualquier otra puerta de entrada al banco.

Trust API: puntaje de confianza en la cadena
Beta

RSoft Trust puntúa cualquier wallet de agente según lo que dice su identidad ERC-8004 en Base mainnet, con AgentTrust-8004, un modelo entrenado con un censo real de 54.802 agentes registrados (publicado en Hugging Face). El propio banco guarda este puntaje dentro de cada registro firmado de decisión de préstamo, y el servidor MCP lo expone como get_trust_score. Lecturas públicas y gratis mientras dure la beta.

Puntuar una wallet

GET https://7pdor5bjoty7gyat56u6fgcrue0gbvnd.lambda-url.us-east-1.on.aws/score/0xYourWallet

{
  "wallet": "0x6c37...ccda",
  "registered": true,
  "trust_score": 98,          // 0-100, directional: identity age + reputation
  "anomaly": false,           // true = incoherent profile (e.g. reputation farming)
  "reason": "within normal census distribution",
  "features": { "identity_age_days": 201.9, "client_count": 3 }
}

Las wallets sin registrar puntúan 0: sin identidad ERC-8004 no hay ancla que puntuar. La primera lectura de una wallet recorre el historial de Base (~40 s); las siguientes salen de caché. Beta: el modelo v0 usa las dos variables que se leen directo en la cadena; las más ricas llegan con el indexador de eventos.

RSoft Sentiment (ASI)

Beta

El primer índice de sentimiento ponderado por confianza para agentes de IA: lee lo que los agentes ERC-8004 HACEN en la cadena (posiciones, capital, reputación), no lo que dicen los humanos, y pondera el voto de cada agente por su puntaje de confianza. Los perfiles anómalos quedan fuera del índice.

GET https://g3w2egj3mgmjezpzgtnzhkd5h40kqtxd.lambda-url.us-east-1.on.aws/api/v1/sentiment/asi

Trust SDK: políticas, compuertas y precios

POST /evaluate convierte el puntaje de confianza en una decisión: elige una política (o arma tus propias compuertas) y recibe un nivel, pasa/falla por compuerta, la marca de anomalía y un multiplicador de precio opcional para la wallet. Las compuertas salen solo de señales reales en la cadena, nada autodeclarado. Sin key. URL base https://7pdor5bjoty7gyat56u6fgcrue0gbvnd.lambda-url.us-east-1.on.aws.

Evaluar una wallet contra una política

POST /evaluate
{ "wallet": "0x…", "policy": "standard", "include_pricing": true, "base_price_usdc": 1.0 }

{
  "wallet": "0x…",
  "registered": true,
  "trust_score": 82,
  "trust_tier": "verified",       // trusted | verified | limited | untrusted | blocked
  "anomaly": false,
  "policy": "standard", "operator": "AND",
  "all_passed": true,
  "gate_results": [
    { "gate": "registered",  "passed": true, "value": true,  "threshold": true },
    { "gate": "established", "passed": true, "value": 201.9, "threshold": 30 },
    ...
  ],
  "pricing": { "price_multiplier": 0.77, "suggested_price_usdc": 0.77,
               "suggested_interest_rate": ...,   // indicative only
               "bank_risk_tier_equivalent": "A", ... }
}

Políticas: quick, basic, standard, strict, financial, reputation o custom {gates, operator: AND|OR|WEIGHTED, weights, threshold}. Compuertas: registered (identidad ERC-8004), established (identidad ≥ 30 días), active (≥ 1 cliente de reputación), coherent (sin anomalía), score (≥ 50). También GET /policies y GET /pricing?wallet=&base_price_usdc=.

Precios

price_multiplier = 2.0 − 1.5 · trust_score / 100. Una wallet confiable paga hasta 0,5×, una desconocida 2,0×; las wallets anómalas o sin registrar siempre pagan 2,0×. El suggested_interest_rate es solo indicativo: el banco pone precio a sus préstamos con su propio modelo Kelly/AMM, no con este número.

SDKs

TypeScript · npm rsoft-trust 0.1.0

npm install rsoft-trust

import { TrustClient } from "rsoft-trust";
const r = await new TrustClient().evaluate({ wallet, policy: "standard" });
if (!r.all_passed) throw new Error(r.trust_tier);

// Express: 403 with the gate breakdown when the policy fails
import { trustGate } from "rsoft-trust/express";
app.post("/pay",
  trustGate({ policy: "standard", walletFrom: (req) => req.headers["x-wallet"] }),
  handler);

// Edge / Workers / Next.js route handlers (WHATWG Request → Response)
import { trustGuard } from "rsoft-trust/fetch";
const g = await trustGuard(req, { policy: "standard" });
if (!g.ok) return g.response;

Python · PyPI rsoft-trust 0.1.0

pip install "rsoft-trust[fastapi]"

from rsoft_trust import TrustClient
async with TrustClient() as trust:
    r = await trust.evaluate(wallet, policy="standard")
    # or: await trust.require(wallet, "standard")  → raises TrustGateError

# FastAPI dependency (wallet from X-Wallet header or ?wallet=)
from rsoft_trust.fastapi import require_trust
@app.post("/pay", dependencies=[Depends(require_trust(policy="standard"))])
async def pay(): ...

Código de los dos paquetes: github.com/rsoft-latam/rsoft-trust-api, en packages/.

Referencia de la API

Endpoints GET públicos para consultar datos de préstamos, el estado del flujo y la información del protocolo.

Préstamos

GET
/api/v1/loan/status/{request_id}

Estado de un préstamo

Devuelve el estado actual y el detalle de un pedido de préstamo. Si el estado es rejected, la respuesta dice por qué: rejection_reason (texto), un rejection_code estable y un next_action que el agente puede seguir.

Parámetros de ruta

request_idstringEl identificador único del pedido de préstamo

Respuesta

{
  "request_id": "req_da773630cc7c840eb3e141ef",
  "status": "rejected",
  "agent_wallet": "0xDf18...2D825",
  "amount": 5,
  "loan_amount": 5,
  "rejection_reason": "ERC-8004 identity required: agent holds no token in IdentityRegistry",
  "rejection_code": "identity_required",
  "next_action": {
    "code": "register_identity",
    "message": "This wallet holds no ERC-8004 Agent Passport. Register it once from the agent's own wallet, then request the loan again with a fresh signature.",
    "url": "https://rsoft-agentic-bank.com/register"
  },
  "created_at": "2026-09-13T23:02:26Z",
  "completed_at": "2026-09-13T23:02:35Z"
}
GET
/api/v1/loan/workflow/{request_id}

Pasos del flujo

Devuelve el estado detallado de cada agente del pipeline. Incluye tiempos, resultados y errores de cada paso.

Parámetros de ruta

request_idstringEl identificador único del pedido de préstamo

Respuesta

{
  "request_id": "req_abc123def456",
  "loan_status": "disbursed",
  "workflow_status": "completed",
  "total_duration_ms": 12450,
  "current_step": null,
  "steps": [
    {
      "step": "gatekeeper",
      "step_order": 1,
      "status": "completed",
      "started_at": "2025-01-15T10:30:00Z",
      "completed_at": "2025-01-15T10:30:02Z",
      "duration_ms": 2100,
      "result": { ... },
      "error": null
    }
  ],
  "created_at": "2025-01-15T10:30:00Z",
  "completed_at": "2025-01-15T10:31:45Z"
}
GET
/api/v1/loan/history/{wallet_address}

Historial de préstamos del agente

Devuelve el historial de préstamos de una wallet. Trae todos los pedidos, pasados y actuales.

Parámetros de ruta

wallet_addressstringLa dirección de la wallet del agente

Parámetros de consulta

limitintegerCantidad máxima de resultados (por defecto: 10)

Respuesta

[
  {
    "request_id": "req_abc123def456",
    "status": "repaid",
    "agent_wallet": "0x1234...abcd",
    "loan_amount": 1000,
    "amount_approved": 1000,
    "interest_rate": 0.085,
    "term_days": 30,
    "current_node": null,
    "tx_hash": "0xabc...def",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-20T14:00:00Z"
  }
]
GET
/api/v1/loan/explorer

Explorador de préstamos

Endpoint público y paginado para recorrer todos los préstamos del protocolo. Permite filtrar por estado. No requiere autenticación.

Parámetros de consulta

pageintegerNúmero de página (por defecto: 1)
limitintegerElementos por página (por defecto: 20)
statusstringFiltrar por estado del préstamo

Respuesta

{
  "loans": [
    {
      "request_id": "req_abc123",
      "agent_wallet": "0x1234...abcd",
      "amount": 1000,
      "currency": "USDC",
      "status": "disbursed",
      "interest_rate": 0.085,
      "duration_days": 30,
      "disbursement_tx_hash": "0xabc...def",
      "created_at": "2025-01-15T10:30:00Z"
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 20,
  "total_pages": 3
}
GET
/api/v1/loan/active/{wallet_address}

Préstamos activos

Devuelve todos los préstamos activos de una wallet. Incluye un resumen del saldo pendiente.

Parámetros de ruta

wallet_addressstringLa dirección de la wallet del agente

Respuesta

{
  "active_loans": [
    {
      "request_id": "req_abc123def456",
      "amount": 1000,
      "interest_rate": 0.085,
      "duration_days": 30,
      "repayment_amount": 1085,
      "status": "disbursed",
      "disbursement_tx_hash": "0xabc...def",
      "created_at": "2025-01-15T10:30:00Z"
    }
  ],
  "active_loans_count": 1,
  "total_outstanding": 1085,
  "wallet_address": "0x1234...abcd",
  "agent_id": "agent-001"
}

Agentes y tasas

GET
/api/v1/agents/{agent_id}/creditworthiness

Consultar solvencia

Evalúa la solvencia de un agente según su historial de préstamos y su perfil de riesgo.

Parámetros de ruta

agent_idstringEl identificador único del agente

Respuesta

{
  "agent_id": "agent-001",
  "credit_score": 750,
  "risk_tier": "low"
}
GET
/api/v1/interest-rates

Tasas de interés

Devuelve las tasas de interés actuales del protocolo. Se actualizan de forma dinámica según el uso del protocolo.

Respuesta

{
  "base_rate": 0.05,
  "risk_tiers": {
    "low": { "rate": "..." },
    "medium": { "rate": "..." },
    "high": { "rate": "..." }
  },
  "yield_strategies": {
    "conservative": { "apy": "..." },
    "balanced": { "apy": "..." },
    "aggressive": { "apy": "..." },
    "dynamic": { "apy": "..." }
  },
  "updated_at": "2025-01-15T00:00:00Z"
}
GET
/api/v1/agents/{wallet}/controls

Controles del sponsor

Vínculo con el sponsor, controles que fijó el sponsor y el techo efectivo de préstamo de un agente. Público. Mira Controles del sponsor.

Parámetros de ruta

walletstringLa dirección de la wallet del agente

Respuesta

{
  "sponsor":  { "bound": true, "kind": "phone", "status": "active" },
  "controls": { "paused": false, "revoked": false, "max_loan_amount": 20,
                "daily_draw_cap": 50, "draft_mode_enabled": true, "version": 3 },
  "effective": { "ladder_limit": 10, "ladder_level": 1, "global_max": 25,
                 "sponsor_cap": 20, "effective_ceiling": 10,
                 "daily_used": 0, "daily_remaining": 50 },
  "pending_draft": null
}

Directorio de agentes (ERC-8004)

GET
/api/v1/agents/registry/{token_id}

Entrada del registro por token id

Lectura de los registros de identidad y reputación de un agente ERC-8004 en Base mainnet, más la posición crediticia del banco si la wallet es cliente. Público.

Parámetros de ruta

token_idintegerToken id en el Identity Registry de ERC-8004

Respuesta

{
  "token_id": 58492,
  "exists": true,
  "owner": "0x…",
  "agent_wallet": "0x…",
  "canonical_uri": "https://…",
  "client_count": 1,
  "clients": ["0x…"],
  "known_issuers": [ ... ],
  "trusted_feedback_count": 4,
  "trusted_feedback_value": ...,
  "chain_id": 8453,
  "identity_registry": "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
  "reputation_registry": "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63",
  "bank": { ... }
}
GET
/api/v1/agents/registry/by-wallet/{wallet}

Entrada del registro por wallet

El mismo contenido que la búsqueda por token id, resuelto desde la wallet del agente. Público.

Parámetros de ruta

walletstringLa dirección de la wallet del agente

Respuesta

{ "token_id": 58492, "exists": true, "agent_wallet": "0x…", ... }
GET
/api/v1/agents/registry/recent

Agentes registrados recientemente

Escaneo acotado de los eventos Registered recientes (5000 bloques por defecto) más la tabla de clientes del banco. El IdentityRegistry no se puede enumerar en mainnet, así que no es el censo completo; la respuesta dice qué se escaneó. Público.

Parámetros de consulta

limitintegerCantidad máxima de agentes a devolver

Respuesta

{
  ...,                            // the matched agents (same shape as a registry entry)
  "scanned_window": { ... },      // blocks actually scanned
  "limitation": "…"               // states that the registry is not enumerable
}
GET
/api/v1/agents/registry/search

Buscar agentes

Busca en la misma ventana acotada y en la tabla de clientes del banco. Misma limitación y mismo scanned_window que recent. Público.

Parámetros de consulta

qstring
obligatorio
Término de búsqueda

Respuesta

{
  ...,                            // the matched agents
  "scanned_window": { ... },
  "limitation": "…"
}

Webhooks

Todos los endpoints de webhooks requieren X-API-Key. La forma de los pedidos, los eventos y el esquema de firma están en la sección Webhooks.

POST   /api/v1/webhooks                    { url, events[], agent_wallet? } → { id, secret }  (secret shown once)
GET    /api/v1/webhooks?agent_wallet=0x…   list subscriptions
DELETE /api/v1/webhooks/{id}               remove a subscription
POST   /api/v1/webhooks/{id}/ping          send a test delivery
GET    /api/v1/webhooks/{id}/deliveries    delivery attempts and responses

Chequeos de salud

GET
/health

Chequeo de salud

Devuelve el estado general de salud de la API y sus dependencias.

Respuesta

{
  "status": "healthy"
}
GET
/health/ready

Chequeo de disponibilidad

Sonda de disponibilidad al estilo Kubernetes. Devuelve 200 cuando el servicio está listo para recibir tráfico.

Respuesta

{
  "status": "ready"
}
GET
/health/live

Chequeo de vida

Sonda de vida al estilo Kubernetes. Devuelve 200 mientras el proceso del servicio esté corriendo.

Respuesta

{
  "status": "alive"
}

Códigos de estado y estados del préstamo

Estados del préstamo

initiated
Pedido recibido, el flujo está empezando
approved
Préstamo aprobado, esperando la liquidación
disbursed
Fondos transferidos a la wallet del agente
repaid
El agente repagó el préstamo completo
rejected
Pedido denegado. La respuesta de estado trae rejection_reason, rejection_code y next_action
defaulted
Préstamo vencido, no se recibió el repago
failed
Error del flujo o falla en la liquidación
draft_pending_sponsor
Supera el techo efectivo; espera al sponsor (24 h). No es deuda pendiente
draft_rejected
El sponsor rechazó el borrador. No es deuda pendiente
draft_expired
El sponsor no decidió en 24 h. No es deuda pendiente

Códigos de estado HTTP

200
OK

El pedido salió bien

202
Accepted

Pedido de préstamo guardado como borrador a la espera del sponsor (modo borrador)

400
Bad Request

Parámetros o cuerpo del pedido inválidos

403
Forbidden

identity_required (la wallet no tiene pasaporte ERC-8004; detail.register_url dice dónde emitirlo, no se creó nada) o un control del sponsor (agent_paused, sponsor_cap_exceeded)

404
Not Found

Recurso no encontrado (request_id, wallet inválidos, etc.)

500
Server Error

Error interno del servidor

Formato de las respuestas de error

Todas las respuestas de error siguen el mismo formato, con un campo detail que describe el error.

{
  "detail": "Loan request not found: req_invalid_id"
}