Saltar al contenido principal

Depósito y Retirada Programática

información

Esta guía está disponible en cuatro lenguajes de programación diferentes: Typescript, Kotlin, Flutter (Dart) y Swift. Puedes cambiar la versión mostrada en cada página mediante los botones de arriba.

El estándar SEP-6 define una forma en que los anchors y billeteras pueden interactuar en nombre de los usuarios. Las billeteras utilizan este estándar para facilitar intercambios entre activos on-chain (como stablecoins) y activos off-chain (como fiat, u otros activos de red como BTC).

Por favor, nota que esto es para depósitos y retiradas programáticas. Para depósitos y retiradas alojados, donde el anchor interactúa con billeteras de manera interactiva usando un popup, por favor consulta Depósito y Retirada Alojados.

Obtener Información del Anchor

Comencemos creando un objeto sep6, que usaremos para todas las interacciones SEP-6:

const sep6 = anchor.sep6();

Primero, obtengamos información sobre el soporte del ancla para SEP-6. Esta solicitud no requiere autenticación y devolverá información genérica, como las monedas admitidas y las funciones admitidas por el ancla. Puedes obtener una lista completa de campos devueltos en la especificación SEP-6.

const info = await sep6.info();

Iniciar un depósito

Antes de comenzar, asegúrate de haberte conectado al ancla y de haber recibido un token de autenticación, como se describe en la guía de billeteras de Autenticación Stellar. Usaremos authToken en los ejemplos a continuación como el token de autenticación SEP-10, obtenido anteriormente.

Para iniciar una operación, necesitamos conocer un activo. Puedes codificar esto de forma fija. Asegúrate de que sea uno que esté incluido en la respuesta de información anterior.

información

Antes de comenzar con el flujo de depósito, asegúrate de que la cuenta del usuario haya establecido una línea de confianza para el activo con el que estás trabajando.

Comencemos con un depósito básico. Usaremos account para representar la clave pública de nuestra cuenta.

const deposit = await sep6.deposit({
authToken,
params: {
asset_code,
account,
},
});

Hay varios tipos de respuestas, dependiendo de si el ancla necesita más información. Todos los depósitos y retiros tendrán estos mismos tipos de respuesta:

1. Respuesta exitosa

Si la respuesta es exitosa (HTTP 200), entonces el ancla está procesando el depósito. Si necesita información adicional, la comunicará al proporcionar la información de la transacción.

2. Aún procesando o denegado

Si se devuelve un HTTP 403 con datos: customer_info_status, significa que la acción aún se está procesando o no ha sido aceptada. En este caso, el campo more_info_url debería tener un enlace que describa los próximos pasos.

Un ejemplo de respuesta:

{
"type": "customer_info_status",
"status": "denied",
"more_info_url": "https://api.example.com/kycstatus?account=GACW7NONV43MZIFHCOKCQJAKSJSISSICFVUJ2C6EZIW5773OU3HD64VI"
}

3. Necesita más información KYC

Otra respuesta común es un HTTP 403, con la respuesta: non_interactive_customer_info_needed. En este caso, el ancla necesita más información KYC a través de SEP-12.

Un ejemplo de respuesta:

{
"type": "non_interactive_customer_info_needed",
"fields" : ["family_name", "given_name", "address", "tax_id"]
}

Mostremos cómo una billetera puede manejar esta situación. Primero, obtenemos el objeto de respuesta del depósito. Si la respuesta incluye este error, entonces podemos ver qué campos faltantes está requiriendo el ancla.

if (deposit.type === "non_interactive_customer_info_needed") {
// handle displaying the missing fields to the user
console.log(deposit.fields);
}

La billetera tendrá que manejar la visualización al usuario sobre qué campos están faltando. Y luego, para agregar esos campos, podemos usar la clase sep12 así:

const sep12 = await anchor.sep12(authToken);

// adding the missing kyc info (sample data)
await sep12.add({
sep9Info: {
family_name: "smith",
given_name: "john",
address: "123 street",
tax_id: "123",
},
});

Luego, podemos volver a llamar al método de depósito como antes y debería ser exitoso.

Más información sobre el envío de información KYC utilizando SEP-12 se puede encontrar en Proporcionar información KYC.

Proporcionar información KYC

Un ancla puede responder a una solicitud de depósito o retiro diciendo que necesita información KYC adicional. Para facilitar esto, SEP-6 admite agregar información KYC del cliente a través de SEP-12. El usuario puede enviar la información requerida utilizando el objeto sep12 como se muestra a continuación.

Vamos a agregar algo de información KYC para nuestra cuenta utilizando datos de ejemplo. Los datos binarios (por ejemplo, datos de imagen) deben enviarse en un campo separado. Los campos permitidos que se pueden enviar al ancla se describen en SEP-9.

const sep12 = await anchor.sep12(authToken);

await sep12.add({
sep9Info: {
first_name: "john",
last_name: "smith",
email_address: "[email protected]",
bank_number: "12345",
bank_account_number: "12345",
},
sep9BinaryInfo: {
photo_id_front: Buffer.from("./path/to/image/front"),
photo_id_back: Buffer.from("./path/to/image/back"),
},
});

Iniciar un retiro

Iniciar un retiro es similar a un depósito y tiene los mismos tipos de respuesta que se describieron anteriormente.

const resp = await sep6.withdraw({
authToken,
params: {
asset_code: "SRT",
account: accountKp.publicKey,
type: "bank_account",
dest: "123",
dest_extra: "12345",
},
});

Obtener información de intercambio

Si el ancla admite cotizaciones de SEP-38, puede admitir depósitos que hagan un puente entre activos no equivalentes. Por ejemplo, un ancla recibe BRL a través de transferencias bancarias y a cambio envía USDC (de valor equivalente menos tarifas) al usuario en Stellar.

Las funciones de intercambio sep6 permiten a un usuario iniciar un depósito o retiro de intercambio con el ancla, y el ancla puede comunicar los próximos pasos al usuario.

Primero, comencemos un depósito de intercambio con datos de ejemplo. Los activos se describen utilizando el esquema SEP-38.

const resp = await sep6.depositExchange({
authToken,
params: {
destination_asset:
"stellar:SRT:GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B",
source_asset: "iso4217:USD",
amount: "10",
},
});

La respuesta sigue los mismos tipos que todos los depósitos y retiros de SEP-6.

Ahora vamos a crear un retiro de intercambio, que sigue el mismo formato que el depósito de intercambio. También especificamos que es un retiro de cuenta bancaria utilizando el campo type.

const resp = await sep6.withdrawExchange({
authToken,
params: {
destination_asset: "iso4217:USD",
source_asset:
"stellar:SRT:GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B",
amount: "10",
type: "bank_account",
},
});

La respuesta sigue los mismos tipos que todos los depósitos y retiros de SEP-6.

Obteniendo información de transacción

En el flujo típico, la billetera obtendría datos de transacción para notificar a los usuarios sobre actualizaciones de estado. Esto se hace a través del SEP-6 GET /transaction y GET /transactions endpoint.

Seguimiento de transacción

Veamos cómo usar el sdk para rastrear los cambios en el estado de la transacción. Usaremos la clase Watcher para este propósito. Primero, inicialízala y comienza a rastrear una transacción.

const watcher = anchor.sep6().watcher();

const { stop, refresh } = watcher.watchOneTransaction({
authToken,
assetCode,
id: txId,
onSuccess,
onMessage,
onError,
});

Alternativamente, podemos rastrear múltiples transacciones para el mismo activo.

const watcher = anchor.sep6().watcher();

const { stop, refresh } = watcher.watchAllTransactions({
authToken,
assetCode,
onMessage,
onError,
});

Obteniendo transacción

Mientras que la clase Watcher ofrece potentes capacidades de seguimiento, a veces es necesario simplemente obtener una transacción (o transacciones) una vez. La clase Anchor te permite obtener una transacción por ID, ID de transacción Stellar o ID de transacción externa:

const transaction = await anchor
.sep6()
.getTransactionBy({ authToken, id: transactionId });

También es posible obtener transacciones por el activo.

const transactions = await anchor.sep6().getTransactionsForAsset({
authToken,
assetCode,
});