Saltar al contenido principal

Self-Custody

Self-Custody es el modelo de ejecución real, en operación hoy en la plataforma — el único ExecutionCustodyMode que realmente puede seleccionarse para cualquier Environment, Sandbox o Production. Bajo Self-Custody, la plataforma nunca guarda una clave privada en su nombre — la wallet se genera y controla enteramente de su lado, a través de uno de los SDKs oficiales.

ExecutionCustodyMode también declara ManagedCustody, ExternalCustody y SmartContractEscrow a nivel de dominio — preservados arquitectónicamente (para que el historial propio de la plataforma y herramientas internas, como TreasuryReconciliation, sigan funcionando contra ese vocabulario), pero ninguno de ellos puede activarse: configurar el modo de un Environment en cualquier valor distinto de Self-Custody se rechaza de inmediato. Trate esos tres como reservados, no como opciones de configuración disponibles hoy.

Cómo funciona​

  1. Generación local de la wallet. El SDK genera un mnemonic BIP39 y deriva una clave extendida BIP32 localmente (ruta BIP44 m/44'/195'/0', coin_type de TRON = 195). La clave privada se crea y se usa enteramente dentro de su proceso — nunca se transmite, registra, ni persiste por el SDK por su cuenta (INV-SC-01).
  2. Registro público. Solo la clave pública extendida (xpub) resultante se envía a la API — POST /v1/applications/{applicationId}/wallets. La plataforma puede derivar direcciones a partir de ella, pero nunca puede firmar con ella.
  3. Asignación de dirección de depósito. La plataforma deriva una dirección TRON real de depósito a partir del xpub registrado (POST .../wallets/deposit-addresses) — el mismo SDK puede re-derivar y verificar esa dirección localmente, de forma independiente, como una verificación de defensa en profundidad contra un backend comprometido.
  4. Firma de múltiples Legs. Un SigningRequest describe una o más ExecutionLegs (por ejemplo, una Leg de Seller y una Leg de Platform Fee del mismo Settlement). Para cada Leg, el backend calcula un hash canónico determinístico del contenido exacto de la transacción; el SDK firma ese hash localmente con la clave privada y envía la firma de vuelta (POST .../legs/{executionLegId}/submit). El backend verifica cada firma de forma independiente contra el mismo hash canónico antes de aceptarla — un monto o destino alterado produce un hash distinto y es rechazado de inmediato.
  5. All-signatures gate. Ninguna Leg se transmite (broadcast) a la red hasta que todas las Legs del SigningRequest tengan una firma verificada. La primera firma sola nunca dispara un broadcast — solo la última lo dispara, para todas las Legs a la vez.

Financiamiento multi-source​

Un Settlement puede financiarse con más de una dirección de depósito confirmada — soportado: produce un SigningRequest por cada fuente física de financiamiento (SettlementResponse.signingRequestIds, plural), firma y confirma cada uno. Un Withdrawal siempre proviene de un único SigningRequest — el financiamiento multi-source no está soportado para Withdrawal hoy (Withdrawal.signingRequestId sigue siendo solo singular); no construyas una integración que asuma paridad aquí.

Lo que nunca sucede​

  • La clave privada nunca se envía a la API, en ninguna solicitud, en ninguna etapa.
  • Ninguna Leg se transmite antes de que todas las Legs estén firmadas y verificadas.
  • Una firma nunca se acepta sin recalcular y comparar el hash canónico de forma independiente en el servidor.

Errores​

Una firma enviada para una Leg cuyo hash recalculado no coincide se rechaza con SIGNED_TRANSACTION_MISMATCH — la Leg nunca se transmite. Una razón de discrepancia más granular (monto, participante, red o activo) es una extensión futura documentada; hoy la verificación es una única comparación de hash opaco, que ya cubre la invariante de seguridad central: una transacción alterada nunca pasa la verificación, sea cual sea el campo específico modificado.

Disponible hoy​

La generación de wallets Self-Custody, el registro, la asignación de dirección de depósito y el protocolo completo de firma de múltiples Legs — hash canónico, verificación de firma, el gate de todas-las-firmas y el broadcast — están implementados y validados de extremo a extremo en Sandbox, a través de los cuatro SDKs oficiales (Java, Node.js/TypeScript, Python, Go) — cada uno incluye un ejemplo completo y ejecutable (13-self-custody-signing). Vea la guía del recorrido de marketplace para este protocolo conectado de extremo a extremo con un pago real — registro, Payment Intent, depósito, y un payout firmado localmente — no solo el paso de firma de forma aislada.

La creación de SigningRequest ya está conectada automáticamente tanto a Settlement como a Withdrawals — confirmado en vivo: executeSettlement() y withdrawals.request() construyen el SigningRequest/las ExecutionLegs por su cuenta, a partir de los beneficiarios y montos ya presentes en el Settlement/Withdrawal; un integrador nunca construye un SigningRequest manualmente para esos flujos (la ruta directa POST .../signing-requests de abajo sigue existiendo para otros usos, de nivel más bajo). El seguimiento de confirmación de broadcast también es automático, orientado a eventos de extremo a extremo — en cuanto todas las Legs están firmadas y el all-signatures gate dispara el broadcast, la propia plataforma observa la confirmación (simulada en Sandbox) y mueve el Settlement/Withdrawal a su estado terminal; el integrador nunca hace polling directo a un nodo de blockchain para esto.

Dos cosas deben registrarse una vez por Organization/AssetNetwork antes de que la primera ejecución real en Self-Custody pueda completarse: un ExecutionDestination para cada beneficiario que recibe pago (incluyendo el propio Fee de la plataforma, bajo un Settlement), y un NetworkCostPayerAccount para cubrir los recursos de red reales que consume un broadcast (vea Transaction, Settlement, Split y Refund para ambos, y Network Execution para ExecutionSource — un tercer registro relacionado, fácil de confundir con los otros dos). La ejecución real de blockchain — una transacción que efectivamente llega a una red real — es exclusiva de Production y todavía no está disponible; el broadcast y la confirmación en Sandbox se simulan de extremo a extremo.

Rutas​

  • Registrar una wallet: POST /v1/applications/{applicationId}/wallets
  • Asignar una dirección de depósito: POST /v1/applications/{applicationId}/wallets/deposit-addresses
  • Obtener una wallet: GET /v1/wallets/{walletId} (y /public-material)
  • Crear un signing request: POST /v1/environments/{environmentId}/signing-requests
  • Obtener un signing request: GET /v1/signing-requests/{signingRequestId}
  • Enviar una Leg firmada: POST /v1/signing-requests/{signingRequestId}/legs/{executionLegId}/submit