diff --git a/docs.json b/docs.json index 9761769..428655d 100644 --- a/docs.json +++ b/docs.json @@ -112,6 +112,8 @@ { "group": "Guides", "pages": [ + "guides/stellar-quickstart", + "guides/stellar-quickstart.es", "guides/stealth-payments", "guides/single-chain-agent", "guides/multichain-agent", @@ -127,14 +129,10 @@ "pages": [ "guides/stellar-mainnet-deployment", "guides/stellar-payment-links", - "guides/stellar-payment-links", "guides/stellar-multisig-withdrawal", "guides/stellar-offline-signing", "guides/stellar-tx-simulation", "guides/stellar-explorer-recipes", - "guides/stellar-payment-links", - "guides/privacy-best-practices", - "guides/spectre-stellar-cookbook", "guides/stellar-federation", "guides/stellar-custom-assets", "guides/wraith-names-stellar" diff --git a/docs/i18n.md b/docs/i18n.md new file mode 100644 index 0000000..1430bdf --- /dev/null +++ b/docs/i18n.md @@ -0,0 +1,271 @@ +# Internacionalización (i18n) — Guía para colaboradores +# Internationalization (i18n) — Contributor Guide + +> **Language note:** This document is bilingual. The Spanish section mirrors the English one because it is itself a contributor-facing guide — translators need to read it. + +--- + +## English + +### Background + +Mintlify does not have native multi-locale support. This repository implements a lightweight convention instead: translated pages live alongside their English source using a locale suffix in the filename, and each page carries a `` switcher at the top pointing at the other locale. + +The first translated page is `guides/stellar-quickstart.es.mdx`. It establishes the pattern for all future translations. + +### File naming convention + +| English source | Translated file | +|---|---| +| `guides/stellar-quickstart.mdx` | `guides/stellar-quickstart.es.mdx` | +| `guides/some-guide.mdx` | `guides/some-guide.fr.mdx` | +| `guides/some-guide.mdx` | `guides/some-guide.pt.mdx` | + +Rules: +- Use the two-letter ISO 639-1 language code as the suffix before `.mdx`. +- Keep the file in the **same directory** as the English source — no `locales/` subdirectory. +- Never rename or move the English source when adding a translation. + +### Language switcher + +Every translated page must have a `` switcher as the **first element after the frontmatter**, pointing back to the English page. The English page must have a corresponding card pointing to each available translation. + +**English page** (`guides/my-guide.mdx`): +```mdx +--- +title: "My Guide" +description: "..." +--- + + + +--- +(rest of page) +``` + +**Translated page** (`guides/my-guide.es.mdx`): +```mdx +--- +title: "Mi guía" +description: "..." +--- + + + +--- +(rest of page) +``` + +If a page has multiple translations, use a `` instead of a single ``: + +```mdx + + + + + +``` + +### docs.json navigation + +Add both the English and translated pages to `docs.json` in the same navigation group, with the translated page immediately following its English source: + +```json +{ + "group": "Guides", + "pages": [ + "guides/stellar-quickstart", + "guides/stellar-quickstart.es", + "guides/stealth-payments" + ] +} +``` + +The Mintlify sidebar will display the `title` field from each page's frontmatter, so the ES page will show "Guía de inicio rápido — Stellar" automatically. + +### Translation workflow + +1. **Pick a page.** Start with high-traffic pages. Check site analytics or Discord for pages Spanish-speaking contributors ask about most. + +2. **Create the translated file.** Copy the English source: + ```bash + cp guides/my-guide.mdx guides/my-guide.es.mdx + ``` + +3. **Translate the frontmatter.** Translate `title` and `description`. Keep `keywords` in English — they are used for search indexing and should match what users type in English even when reading in Spanish. + +4. **Translate the prose.** Translate all headings, paragraph text, callout text (``, ``), table headers and cells, and card titles in ``. + +5. **Do not translate:** + - Code blocks (TypeScript, bash, JSON) — keep these identical to the English source + - `href` and `url` values inside `` components (other than the language switcher itself) + - Internal link targets (`/guides/stellar-fees` stays `/guides/stellar-fees` — the link points to the English page unless a translated version also exists) + - API field names and error message strings that appear inside prose + +6. **Add the language switcher.** Add the `` to the translated page pointing back to the English page. Add the reverse `` to the English source pointing to the new translation. + +7. **Update docs.json.** Add the translated page path immediately after the English entry in `navigation`. + +8. **Run the snippet checker** to confirm all code fences still parse cleanly: + ```bash + npm run check:snippets + ``` + +9. **Open a pull request.** Tag at least one native speaker of the target language as a reviewer. The PR will not be merged without a native-speaker sign-off. + +### Reviewer checklist (native speaker sign-off) + +Before approving a translated PR, verify: + +- [ ] The translation reads naturally — not machine-translated or overly literal +- [ ] Technical terms are consistent with how the Stellar/Soroban ecosystem uses them in Spanish (e.g., "comisión" not "tarifa" for fees, "contrato inteligente" not "contrato listo") +- [ ] No prose was accidentally left in English (other than the intentional exceptions listed above) +- [ ] Code comments in code blocks are acceptable left in English (they are low-priority; translate if you have the time) +- [ ] The language switcher card appears at the top and links correctly +- [ ] The page renders correctly in the Mintlify preview + +### Keeping translations up to date + +When the English source changes: + +1. Check the git diff to identify what prose changed. +2. Apply equivalent changes to all translated files. +3. If the change is non-trivial, re-request a native-speaker review. +4. If a translation is significantly out of date (more than one major section behind), add an `` callout at the top of the translated page noting the discrepancy: + +```mdx + + Esta página puede estar desactualizada. La versión en inglés fue actualizada recientemente. + [Ver la versión en inglés](/guides/my-guide) para el contenido más reciente. + +``` + +Remove the callout once the translation is caught up. + +### Adding a new locale + +To add a locale not yet present in the project (e.g., Portuguese): + +1. Follow the file naming convention above (`.pt.mdx` suffix). +2. Add the locale flag emoji and label to the language switcher `` on the English page. +3. Update this document's locale table (see "Supported locales" below). +4. Find at least one native-speaker reviewer before the PR is merged. + +### Supported locales + +| Code | Language | Status | Pages translated | +|---|---|---|---| +| `es` | Spanish (Español) | Active | `guides/stellar-quickstart` | + +Add a row to this table when you start a new locale. + +--- + +## Español + +### Contexto + +Mintlify no tiene soporte nativo para múltiples idiomas. Este repositorio implementa una convención ligera: las páginas traducidas coexisten con su fuente en inglés usando un sufijo de locale en el nombre del archivo, y cada página incluye un componente `` en la parte superior que apunta al otro idioma. + +La primera página traducida es `guides/stellar-quickstart.es.mdx`. Establece el patrón para todas las traducciones futuras. + +### Convención de nombres de archivo + +| Fuente en inglés | Archivo traducido | +|---|---| +| `guides/stellar-quickstart.mdx` | `guides/stellar-quickstart.es.mdx` | +| `guides/some-guide.mdx` | `guides/some-guide.fr.mdx` | +| `guides/some-guide.mdx` | `guides/some-guide.pt.mdx` | + +Reglas: +- Usa el código ISO 639-1 de dos letras como sufijo antes de `.mdx`. +- Mantén el archivo en el **mismo directorio** que la fuente en inglés — sin subdirectorio `locales/`. +- Nunca cambies el nombre ni la ubicación de la fuente en inglés al añadir una traducción. + +### Selector de idioma + +Toda página traducida debe tener un componente `` como **primer elemento después del frontmatter**, apuntando de vuelta a la página en inglés. La página en inglés debe tener una tarjeta correspondiente que apunte a cada traducción disponible. + +**Página en inglés** (`guides/my-guide.mdx`): +```mdx +--- +title: "My Guide" +description: "..." +--- + + + +--- +(resto de la página) +``` + +**Página traducida** (`guides/my-guide.es.mdx`): +```mdx +--- +title: "Mi guía" +description: "..." +--- + + + +--- +(resto de la página) +``` + +Si una página tiene múltiples traducciones, usa `` en lugar de un solo ``. + +### Flujo de trabajo de traducción + +1. **Elige una página.** Empieza por las páginas con más tráfico o las que los colaboradores hispanohablantes piden con más frecuencia en Discord. + +2. **Crea el archivo traducido.** Copia la fuente en inglés: + ```bash + cp guides/my-guide.mdx guides/my-guide.es.mdx + ``` + +3. **Traduce el frontmatter.** Traduce `title` y `description`. Deja `keywords` en inglés — se usan para indexación de búsqueda. + +4. **Traduce el texto.** Traduce todos los encabezados, párrafos, callouts (``, ``), encabezados y celdas de tablas, y títulos de tarjetas en ``. + +5. **No traduzcas:** + - Los bloques de código (TypeScript, bash, JSON) + - Los valores de `href` y `url` dentro de los componentes `` (excepto el propio selector de idioma) + - Los destinos de enlaces internos + - Los nombres de campos de la API y los mensajes de error dentro del texto + +6. **Agrega el selector de idioma** en la página traducida apuntando de vuelta a la versión en inglés, y el correspondiente en la fuente en inglés. + +7. **Actualiza docs.json.** Agrega la ruta de la página traducida inmediatamente después de la entrada en inglés en `navigation`. + +8. **Ejecuta el verificador de fragmentos de código:** + ```bash + npm run check:snippets + ``` + +9. **Abre un pull request.** Etiqueta al menos a un hablante nativo del idioma de destino como revisor. El PR no se fusionará sin la aprobación de un hablante nativo. + +### Lista de verificación para revisores (aprobación de hablante nativo) + +Antes de aprobar un PR traducido, verifica: + +- [ ] La traducción se lee de forma natural — sin calcos literales ni estilo de traducción automática +- [ ] Los términos técnicos son consistentes con el uso del ecosistema Stellar/Soroban en español +- [ ] Ningún texto quedó en inglés accidentalmente (excepto las excepciones intencionales listadas arriba) +- [ ] El selector de idioma aparece en la parte superior y enlaza correctamente +- [ ] La página se renderiza correctamente en la vista previa de Mintlify + +### Mantener las traducciones actualizadas + +Cuando la fuente en inglés cambie: + +1. Revisa el diff de git para identificar qué texto cambió. +2. Aplica los cambios equivalentes en todos los archivos traducidos. +3. Si la página traducida está significativamente desactualizada, agrega un callout `` al inicio indicando la discrepancia. + +--- + +## Locales soportados + +| Código | Idioma | Estado | Páginas traducidas | +|---|---|---|---| +| `es` | Español | Activo | `guides/stellar-quickstart` | diff --git a/guides/stellar-quickstart.es.mdx b/guides/stellar-quickstart.es.mdx new file mode 100644 index 0000000..d7c1fad --- /dev/null +++ b/guides/stellar-quickstart.es.mdx @@ -0,0 +1,263 @@ +--- +title: "Guía de inicio rápido — Stellar" +description: "Crea un agente Wraith en Stellar, fúndalo en la red de pruebas, envía tu primer pago oculto y escanea pagos entrantes — en menos de 10 minutos." +keywords: "Stellar, soroban, freighter, xlm, lumen, friendbot, stellar.expert, meta-address, stealth payment" +--- + + + +--- + +Al terminar esta guía habrás: + +- Creado un agente Wraith activo en la **red de pruebas** de Stellar +- Enviado un pago oculto de USDC a un nombre `.wraith` +- Escaneado pagos entrantes y consultado tu saldo + +**Requisitos previos:** Node.js 18+, una clave API de Wraith ([regístrate en usewraith.xyz](https://usewraith.xyz)) y un par de claves Stellar (billetera Freighter o generada a continuación). + +--- + +## Paso 1 — Instala el SDK + +```bash +npm install @wraith-protocol/sdk @stellar/stellar-sdk +``` + +## Paso 2 — Inicializa el cliente + +```typescript +import { Wraith, Chain } from "@wraith-protocol/sdk"; + +const wraith = new Wraith({ + apiKey: process.env.WRAITH_API_KEY!, +}); +``` + +El cliente se comunica exclusivamente con la infraestructura TEE gestionada. Nunca manipulas claves sin procesar ni criptografía específica de la cadena directamente. + +## Paso 3 — Genera un par de claves Stellar (solo red de pruebas) + +> **Omite este paso** si ya tienes un par de claves Stellar de Freighter u otra billetera. + +```typescript +import { Keypair } from "@stellar/stellar-sdk"; + +const keypair = Keypair.random(); +console.log("Clave pública: ", keypair.publicKey()); +console.log("Clave secreta: ", keypair.secret()); // guárdala de forma segura +``` + +Guarda el secreto en una variable de entorno (`STELLAR_SECRET`). **No** lo incluyas en el código fuente. + +## Paso 4 — Crea tu agente + +```typescript +import { Wraith, Chain } from "@wraith-protocol/sdk"; +import { Keypair } from "@stellar/stellar-sdk"; + +const wraith = new Wraith({ apiKey: process.env.WRAITH_API_KEY! }); +const keypair = Keypair.fromSecret(process.env.STELLAR_SECRET!); + +// Firma un mensaje para demostrar que eres el dueño del par de claves +const message = "Sign to create Wraith agent"; +const signature = keypair.sign(Buffer.from(message)); + +const agent = await wraith.createAgent({ + name: "mi-agente-stellar", // → mi-agente-stellar.wraith + chain: Chain.Stellar, + wallet: keypair.publicKey(), + signature: Buffer.from(signature).toString("hex"), + message, +}); + +console.log("ID del agente: ", agent.info.id); +console.log("Dirección Stellar: ", agent.info.addresses[Chain.Stellar]); +console.log("Meta-dirección: ", agent.info.metaAddresses[Chain.Stellar]); +// st:xlm:abc123...def456... ← comparte esto para recibir pagos de forma privada +``` + +**Equivalente con curl:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/create \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "mi-agente-stellar", + "chain": "stellar", + "wallet": "GABC...tu-clave-publica-stellar", + "signature": "firma-ed25519-en-hexadecimal", + "message": "Sign to create Wraith agent" + }' +``` + +**Respuesta:** + +```json +{ + "id": "a1b2c3d4-...", + "name": "mi-agente-stellar", + "chain": "stellar", + "address": "GABC...direccion-del-agente", + "metaAddress": "st:xlm:abc123...def456..." +} +``` + +## Paso 5 — Fondea el agente (red de pruebas con Friendbot) + +Las cuentas en la red de pruebas de Stellar necesitan al menos 1 XLM para activarse. Friendbot entrega 10 000 XLM de forma gratuita: + +```typescript +const res = await agent.chat("fund my wallet"); +console.log(res.response); +// "Wallet funded via Friendbot. Balance: 10,000 XLM" +``` + +**curl:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/$AGENT_ID/chat \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "message": "fund my wallet" }' +``` + + + Friendbot solo funciona en la **red de pruebas**. En la red principal, envía al menos 1,5 XLM a la dirección del agente para activar la cuenta y cubrir la reserva mínima. + + +## Paso 6 — Consulta tu saldo + +```typescript +const balance = await agent.getBalance(); +console.log("XLM:", balance.native); // "10000.0" +console.log("Tokens:", balance.tokens); // { USDC: "0.0" } +``` + +O mediante chat: + +```typescript +const res = await agent.chat("what's my balance?"); +console.log(res.response); +// "Balance: 10,000 XLM, 0 USDC" +``` + +## Paso 7 — Envía tu primer pago oculto + +Envía USDC a cualquier nombre `.wraith`. El agente resuelve el nombre, genera una dirección oculta de un solo uso y publica el anuncio en la cadena de bloques de forma automática: + +```typescript +const res = await agent.chat("send 10 USDC to alice.wraith on stellar"); +console.log(res.response); +// "Payment sent — 10 USDC to alice.wraith via stealth address GABC...xyz on Stellar." + +// Inspecciona la llamada de herramienta para obtener el hash de la transacción +console.log(res.toolCalls); +// [{ name: "send_payment", status: "success", detail: "{...txHash...}" }] +``` + +**curl:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/$AGENT_ID/chat \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "message": "send 10 USDC to alice.wraith on stellar" }' +``` + +**Qué ocurre entre bastidores:** + +1. El agente resuelve `alice.wraith` a una meta-dirección oculta (dos claves públicas ed25519) +2. Se genera una clave efímera aleatoria; el ECDH (X25519) calcula un secreto compartido +3. Se deriva una nueva dirección Stellar de un solo uso — imposible de vincular con la identidad de Alice +4. El USDC se envía a esa dirección mediante el contrato Soroban `stealth-sender` +5. Un anuncio `(clavePúblicaEfímera, viewTag)` se publica en la cadena para que Alice pueda detectarlo + +El agente de Alice escanea el anuncio y reclama el USDC sin que nadie sepa que ella fue la destinataria. + +## Paso 8 — Escanea pagos entrantes + +Si alguien ha enviado un pago a la meta-dirección de tu agente, escanea para detectar esos pagos: + +```typescript +const res = await agent.chat("scan for payments on stellar"); +console.log(res.response); +// "Scan complete. Found 2 incoming payments: +// - 10 USDC at stealth address GABC...abc (tx: a1b2c3...) +// - 5 USDC at stealth address GABC...def (tx: d4e5f6...)" +``` + +## Paso 9 — Retira fondos a tu billetera + +Mueve los fondos de las direcciones ocultas a tu billetera habitual. El agente advierte sobre las implicaciones de privacidad antes de ejecutar la operación: + +```typescript +const res = await agent.chat( + `withdraw all USDC to ${keypair.publicKey()} on stellar` +); +console.log(res.response); +``` + + + Para proteger tu privacidad, espacia los retiros al menos 1 hora entre sí y evita retirar cantidades redondas uniformes. Consulta [Prácticas recomendadas de privacidad](/guides/privacy-best-practices) para conocer el algoritmo de puntuación completo. + + +## Paso 10 — Reconéctate a un agente existente + +Después de la configuración inicial, reconéctate sin crear un nuevo agente: + +```typescript +// Por ID de agente (más rápido — guárdalo tras createAgent) +const agent = wraith.agent(process.env.AGENT_ID!); + +// Por nombre .wraith +const agent = await wraith.getAgentByName("mi-agente-stellar"); +``` + +--- + +## Referencia de comisiones + +| Operación | Costo típico | +|---|---| +| Activación de cuenta (primera vez) | 1 XLM de reserva mínima | +| Pago oculto (`stealth-sender::send`) | ~0,0035 XLM | +| Pago en lote, 10 destinatarios | ~0,011 XLM en total | +| Resolución de nombre (`.wraith`) | ~0,0046 XLM | +| Retiro XLM clásico | 0,00001 XLM | + +Consulta [Estimación y presupuesto de comisiones en Stellar](/guides/stellar-fees) para conocer los desgloses de recursos completos y la guía de precios en periodos de congestión. + +--- + +## Referencia de errores + +| Mensaje | Causa | Solución | +|---|---|---| +| `op_no_destination` | La cuenta de destino no existe | Fondea con `createAccount`, no con `payment` | +| `op_underfunded` | Saldo insuficiente | Consulta el saldo antes de enviar; mantén un margen para comisiones | +| `op_low_reserve` | Una nueva trustline dejaría el saldo por debajo de la reserva mínima | Añade 0,5 XLM por cada nueva trustline | +| `tx_bad_seq` | Número de secuencia desactualizado | Vuelve a obtener la cuenta antes de construir la transacción | +| `Name not found` | Nombre `.wraith` no registrado | Verifica el nombre con `GET /agent/info/{name}` | + +Para el catálogo de errores completo, consulta [Solución de problemas en Stellar](/guides/stellar-troubleshooting). + +--- + +## Próximos pasos + + + + Algoritmo de puntuación, espaciado de retiros y qué evitar + + + Desglose de recursos completo y herramienta de estimación del SDK + + + Tres recetas listas para producción: pagos SaaS, nómina de DAO, monitor de privacidad + + + Errores comunes de Stellar, Soroban y Stealth explicados + + diff --git a/guides/stellar-quickstart.mdx b/guides/stellar-quickstart.mdx new file mode 100644 index 0000000..47a0c84 --- /dev/null +++ b/guides/stellar-quickstart.mdx @@ -0,0 +1,263 @@ +--- +title: "Stellar Quickstart" +description: "Create a Stellar Wraith agent, fund it on testnet, send your first stealth payment, and scan for incoming payments — in under 10 minutes." +keywords: "Stellar, soroban, freighter, xlm, lumen, friendbot, stellar.expert, meta-address, stealth payment" +--- + + + +--- + +By the end of this guide you will have: + +- A live Wraith agent on the Stellar **testnet** +- Sent a stealth USDC payment to a `.wraith` name +- Scanned for incoming payments and checked your balance + +**Prerequisites:** Node.js 18+, a Wraith API key ([sign up at usewraith.xyz](https://usewraith.xyz)), and a Stellar keypair (Freighter wallet or generated below). + +--- + +## Step 1 — Install the SDK + +```bash +npm install @wraith-protocol/sdk @stellar/stellar-sdk +``` + +## Step 2 — Initialize the client + +```typescript +import { Wraith, Chain } from "@wraith-protocol/sdk"; + +const wraith = new Wraith({ + apiKey: process.env.WRAITH_API_KEY!, +}); +``` + +The client communicates exclusively with the managed TEE infrastructure. You never handle raw keys or chain-specific crypto directly. + +## Step 3 — Generate a Stellar keypair (testnet only) + +> **Skip this step** if you already have a Stellar keypair from Freighter or another wallet. + +```typescript +import { Keypair } from "@stellar/stellar-sdk"; + +const keypair = Keypair.random(); +console.log("Public key: ", keypair.publicKey()); +console.log("Secret key: ", keypair.secret()); // store this securely +``` + +Keep the secret in an environment variable (`STELLAR_SECRET`). Do **not** commit it to source control. + +## Step 4 — Create your agent + +```typescript +import { Wraith, Chain } from "@wraith-protocol/sdk"; +import { Keypair } from "@stellar/stellar-sdk"; + +const wraith = new Wraith({ apiKey: process.env.WRAITH_API_KEY! }); +const keypair = Keypair.fromSecret(process.env.STELLAR_SECRET!); + +// Sign a message to prove ownership of the keypair +const message = "Sign to create Wraith agent"; +const signature = keypair.sign(Buffer.from(message)); + +const agent = await wraith.createAgent({ + name: "my-stellar-agent", // becomes my-stellar-agent.wraith + chain: Chain.Stellar, + wallet: keypair.publicKey(), + signature: Buffer.from(signature).toString("hex"), + message, +}); + +console.log("Agent ID: ", agent.info.id); +console.log("Stellar address: ", agent.info.addresses[Chain.Stellar]); +console.log("Meta-address: ", agent.info.metaAddresses[Chain.Stellar]); +// st:xlm:abc123...def456... ← share this so others can pay you privately +``` + +**curl equivalent:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/create \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "my-stellar-agent", + "chain": "stellar", + "wallet": "GABC...your-stellar-pubkey", + "signature": "hex-encoded-ed25519-signature", + "message": "Sign to create Wraith agent" + }' +``` + +**Response:** + +```json +{ + "id": "a1b2c3d4-...", + "name": "my-stellar-agent", + "chain": "stellar", + "address": "GABC...agent-address", + "metaAddress": "st:xlm:abc123...def456..." +} +``` + +## Step 5 — Fund the agent (testnet via Friendbot) + +Stellar testnet accounts need at least 1 XLM to activate. Friendbot hands out 10,000 XLM for free: + +```typescript +const res = await agent.chat("fund my wallet"); +console.log(res.response); +// "Wallet funded via Friendbot. Balance: 10,000 XLM" +``` + +**curl:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/$AGENT_ID/chat \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "message": "fund my wallet" }' +``` + + + Friendbot only works on **testnet**. For mainnet, send at least 1.5 XLM to the agent address to activate the account and cover the base reserve. + + +## Step 6 — Check your balance + +```typescript +const balance = await agent.getBalance(); +console.log("XLM:", balance.native); // "10000.0" +console.log("Tokens:", balance.tokens); // { USDC: "0.0" } +``` + +Or via chat: + +```typescript +const res = await agent.chat("what's my balance?"); +console.log(res.response); +// "Balance: 10,000 XLM, 0 USDC" +``` + +## Step 7 — Send your first stealth payment + +Send USDC to any `.wraith` name. The agent resolves the name, generates a fresh one-time stealth address, and broadcasts the announcement on-chain automatically: + +```typescript +const res = await agent.chat("send 10 USDC to alice.wraith on stellar"); +console.log(res.response); +// "Payment sent — 10 USDC to alice.wraith via stealth address GABC...xyz on Stellar." + +// Inspect the tool call for the transaction hash +console.log(res.toolCalls); +// [{ name: "send_payment", status: "success", detail: "{...txHash...}" }] +``` + +**curl:** + +```bash +curl -X POST https://api.usewraith.xyz/agent/$AGENT_ID/chat \ + -H "Authorization: Bearer $WRAITH_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "message": "send 10 USDC to alice.wraith on stellar" }' +``` + +**What happens behind the scenes:** + +1. The agent resolves `alice.wraith` to a stealth meta-address (two ed25519 public keys) +2. A random ephemeral key is generated; ECDH (X25519) computes a shared secret +3. A fresh one-time Stellar address is derived — unlinkable to Alice's identity +4. USDC is sent to that address via the `stealth-sender` Soroban contract +5. An announcement `(ephemeralPubKey, viewTag)` is published on-chain so Alice can detect it + +Alice's agent scans for the announcement and claims the USDC without anyone knowing she was the recipient. + +## Step 8 — Scan for incoming payments + +If someone has paid your agent's meta-address, scan to detect those payments: + +```typescript +const res = await agent.chat("scan for payments on stellar"); +console.log(res.response); +// "Scan complete. Found 2 incoming payments: +// - 10 USDC at stealth address GABC...abc (tx: a1b2c3...) +// - 5 USDC at stealth address GABC...def (tx: d4e5f6...)" +``` + +## Step 9 — Withdraw to your wallet + +Move funds from stealth addresses to your regular wallet. The agent warns about privacy tradeoffs before executing: + +```typescript +const res = await agent.chat( + `withdraw all USDC to ${keypair.publicKey()} on stellar` +); +console.log(res.response); +``` + + + To protect your privacy, space withdrawals at least 1 hour apart and avoid withdrawing uniform round amounts. See [Privacy Best Practices](/guides/privacy-best-practices) for the full scoring algorithm. + + +## Step 10 — Reconnect to an existing agent + +After the initial setup, reconnect without creating a new agent: + +```typescript +// By agent ID (fastest — store this after createAgent) +const agent = wraith.agent(process.env.AGENT_ID!); + +// By .wraith name +const agent = await wraith.getAgentByName("my-stellar-agent"); +``` + +--- + +## Fee reference + +| Operation | Typical cost | +|---|---| +| Account activation (first time) | 1 XLM minimum balance | +| Stealth payment (`stealth-sender::send`) | ~0.0035 XLM | +| Batch payment, 10 recipients | ~0.011 XLM total | +| Name resolution (`.wraith`) | ~0.0046 XLM | +| Classic XLM withdrawal | 0.00001 XLM | + +See [Stellar Fee Estimation & Budgeting](/guides/stellar-fees) for full resource breakdowns and surge pricing guidance. + +--- + +## Error reference + +| Message | Cause | Fix | +|---|---|---| +| `op_no_destination` | Destination account doesn't exist | Fund with `createAccount`, not `payment` | +| `op_underfunded` | Insufficient balance | Check balance before sending; keep fee buffer | +| `op_low_reserve` | New trustline would breach minimum reserve | Add 0.5 XLM per new trustline | +| `tx_bad_seq` | Stale sequence number | Refetch account before building transaction | +| `Name not found` | `.wraith` name unregistered | Verify name with `GET /agent/info/{name}` | + +For the full error catalog see [Stellar Troubleshooting](/guides/stellar-troubleshooting). + +--- + +## Next steps + + + + Scoring algorithm, withdrawal spacing, and what to avoid + + + Full resource breakdowns, SDK fee estimation helper + + + Three production-ready recipes: SaaS payments, DAO payroll, privacy monitor + + + Common Stellar, Soroban, and Stealth errors explained + +