Enviar y recibir pagos
La mayor parte del tiempo, estarás enviando dinero a alguien más que tiene su propia cuenta. Sin embargo, para este tutorial, necesitarás una segunda cuenta para realizar transacciones. Así que antes de continuar, sigue los pasos descritos en Crear una Cuenta para hacer dos cuentas: una para enviar y una para recibir.
Acerca de Operaciones y Transacciones
Las acciones que hacen cosas en Stellar — como enviar pagos o hacer ofertas de compra o venta — se llaman operaciones. Para enviar una operación a la red, la agrupas en una transacción, que es un grupo de entre 1 y 100 operaciones acompañadas de información adicional, como qué cuenta está realizando la transacción y una firma criptográfica para verificar que la transacción es auténtica.
Las transacciones son atómicas, lo que significa que si alguna operación en una transacción falla, todas fallan. Supongamos que tienes 100 lumens y realizas dos operaciones de pago de 60 lumens cada una. Si realizas dos transacciones (cada una con una operación), la primera tendrá éxito y la segunda fallará porque no tienes suficientes lumens. Te quedará con 40 lumens. Sin embargo, si agrupas los dos pagos en una única transacción, ambos fallarán y te quedarás con los 100 lumens completos todavía en tu cuenta.
Cada transacción también incurre en una pequeña tarifa. Al igual que el saldo mínimo en las cuentas, esta tarifa disuade el spam y evita que las personas sobrecarguen el sistema. Esta tarifa base es muy baja — 100 stroops por operación donde un stroop equivale a 1 * 10 ^-7 XLM — y se cobra por cada operación en una transacción. Una transacción con dos operaciones, por ejemplo, costaría 200 stroops.
En los siguientes ejemplos de código, se omite la verificación de errores adecuada por brevedad. Sin embargo, debes siempre validar tus resultados, ya que hay muchas formas en que las solicitudes pueden fallar. Debes consultar la guía sobre Manejo de Errores para consejos sobre estrategias de gestión de errores.
Enviar un Pago
Stellar almacena y comunica datos de transacciones en un formato binario llamado XDR, que está optimizado para el rendimiento de la red pero es ilegible para el ojo humano. Afortunadamente, Horizon, la API de Stellar, y los SDK de Stellar convierten los XDR en formatos más amigables. Así es como podrías enviar 10 lumens a una cuenta:
- JavaScript
- Java
- Go
- Python
var StellarSdk = require("stellar-sdk");
var server = new StellarSdk.Horizon.Server(
"https://horizon-testnet.stellar.org",
);
var sourceKeys = StellarSdk.Keypair.fromSecret(
"SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4",
);
var destinationId = "GA2C5RFPE6GCKMY3US5PAB6UZLKIGSPIUKSLRB6Q723BM2OARMDUYEJ5";
// Transaction will hold a built transaction we can resubmit if the result is unknown.
var transaction;
// First, check to make sure that the destination account exists.
// You could skip this, but if the account does not exist, you will be charged
// the transaction fee when the transaction fails.
server
.loadAccount(destinationId)
// If the account is not found, surface a nicer error message for logging.
.catch(function (error) {
if (error instanceof StellarSdk.NotFoundError) {
throw new Error("The destination account does not exist!");
} else return error;
})
// If there was no error, load up-to-date information on your account.
.then(function () {
return server.loadAccount(sourceKeys.publicKey());
})
.then(function (sourceAccount) {
// Start building the transaction.
transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.payment({
destination: destinationId,
// Because Stellar allows transaction in many currencies, you must
// specify the asset type. The special "native" asset represents Lumens.
asset: StellarSdk.Asset.native(),
amount: "10",
}),
)
// A memo allows you to add your own metadata to a transaction. It's
// optional and does not affect how Stellar treats the transaction.
.addMemo(StellarSdk.Memo.text("Test Transaction"))
// Wait a maximum of three minutes for the transaction
.setTimeout(180)
.build();
// Sign the transaction to prove you are actually the person sending it.
transaction.sign(sourceKeys);
// And finally, send it off to Stellar!
return server.submitTransaction(transaction);
})
.then(function (result) {
console.log("Success! Results:", result);
})
.catch(function (error) {
console.error("Something went wrong!", error);
// If the result is unknown (no response body, timeout etc.) we simply resubmit
// already built transaction:
// server.submitTransaction(transaction);
});
Server server = new Server("https://horizon-testnet.stellar.org");
KeyPair source = KeyPair.fromSecretSeed("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4");
KeyPair destination = KeyPair.fromAccountId("GA2C5RFPE6GCKMY3US5PAB6UZLKIGSPIUKSLRB6Q723BM2OARMDUYEJ5");
// First, check to make sure that the destination account exists.
// You could skip this, but if the account does not exist, you will be charged
// the transaction fee when the transaction fails.
// It will throw HttpResponseException if account does not exist or there was another error.
server.accounts().account(destination.getAccountId());
// If there was no error, load up-to-date information on your account.
AccountResponse sourceAccount = server.accounts().account(source.getAccountId());
// Start building the transaction.
Transaction transaction = new Transaction.Builder(sourceAccount, Network.TESTNET)
.addOperation(new PaymentOperation.Builder(destination.getAccountId(), new AssetTypeNative(), "10").build())
// A memo allows you to add your own metadata to a transaction. It's
// optional and does not affect how Stellar treats the transaction.
.addMemo(Memo.text("Test Transaction"))
// Wait a maximum of three minutes for the transaction
.setTimeout(180)
// Set the amount of lumens you're willing to pay per operation to submit your transaction
.setBaseFee(Transaction.MIN_BASE_FEE)
.build();
// Sign the transaction to prove you are actually the person sending it.
transaction.sign(source);
// And finally, send it off to Stellar!
try {
SubmitTransactionResponse response = server.submitTransaction(transaction);
System.out.println("Success!");
System.out.println(response);
} catch (Exception e) {
System.out.println("Something went wrong!");
System.out.println(e.getMessage());
// If the result is unknown (no response body, timeout etc.) we simply resubmit
// already built transaction:
// SubmitTransactionResponse response = server.submitTransaction(transaction);
}
package main
import (
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/txnbuild"
"github.com/stellar/go/clients/horizonclient"
"fmt"
)
func main () {
source := "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4"
destination := "GA2C5RFPE6GCKMY3US5PAB6UZLKIGSPIUKSLRB6Q723BM2OARMDUYEJ5"
client := horizonclient.DefaultTestNetClient
// Make sure destination account exists
destAccountRequest := horizonclient.AccountRequest{AccountID: destination}
destinationAccount, err := client.AccountDetail(destAccountRequest)
if err != nil {
panic(err)
}
fmt.Println("Destination Account", destinationAccount)
// Load the source account
sourceKP := keypair.MustParseFull(source)
sourceAccountRequest := horizonclient.AccountRequest{AccountID: sourceKP.Address()}
sourceAccount, err := client.AccountDetail(sourceAccountRequest)
if err != nil {
panic(err)
}
// Build transaction
tx, err := txnbuild.NewTransaction(
txnbuild.TransactionParams{
SourceAccount: &sourceAccount,
IncrementSequenceNum: true,
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production!
},
Operations: []txnbuild.Operation{
&txnbuild.Payment{
Destination: destination,
Amount: "10",
Asset: txnbuild.NativeAsset{},
},
},
},
)
if err != nil {
panic(err)
}
// Sign the transaction to prove you are actually the person sending it.
tx, err = tx.Sign(network.TestNetworkPassphrase, sourceKP)
if err != nil {
panic(err)
}
// And finally, send it off to Stellar!
resp, err := horizonclient.DefaultTestNetClient.SubmitTransaction(tx)
if err != nil {
panic(err)
}
fmt.Println("Successful Transaction:")
fmt.Println("Ledger:", resp.Ledger)
fmt.Println("Hash:", resp.Hash)
}
from stellar_sdk import Asset, Keypair, Network, Server, TransactionBuilder
from stellar_sdk.exceptions import NotFoundError, BadResponseError, BadRequestError
server = Server("https://horizon-testnet.stellar.org")
source_key = Keypair.from_secret("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4")
destination_id = "GA2C5RFPE6GCKMY3US5PAB6UZLKIGSPIUKSLRB6Q723BM2OARMDUYEJ5"
# First, check to make sure that the destination account exists.
# You could skip this, but if the account does not exist, you will be charged
# the transaction fee when the transaction fails.
try:
server.load_account(destination_id)
except NotFoundError:
# If the account is not found, surface an error message for logging.
raise Exception("The destination account does not exist!")
# If there was no error, load up-to-date information on your account.
source_account = server.load_account(source_key.public_key)
# Let's fetch base_fee from network
base_fee = server.fetch_base_fee()
# Start building the transaction.
transaction = (
TransactionBuilder(
source_account=source_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=base_fee,
)
# Because Stellar allows transaction in many currencies, you must specify the asset type.
# Here we are sending Lumens.
.append_payment_op(destination=destination_id, asset=Asset.native(), amount="10")
# A memo allows you to add your own metadata to a transaction. It's
# optional and does not affect how Stellar treats the transaction.
.add_text_memo("Test Transaction")
# Wait a maximum of three minutes for the transaction
.set_timeout(10)
.build()
)
# Sign the transaction to prove you are actually the person sending it.
transaction.sign(source_key)
try:
# And finally, send it off to Stellar!
response = server.submit_transaction(transaction)
print(f"Response: {response}")
except (BadRequestError, BadResponseError) as err:
print(f"Something went wrong!\n{err}")
¿Qué exactamente sucedió allí? Desglosemoslo.
- Confirma que la ID de cuenta (también conocida como la clave pública) a la que envías realmente existe cargando los datos de la cuenta asociada desde la red Stellar. Está bien omitir este paso, pero te da la oportunidad de evitar hacer una transacción que inevitablemente fallará.
- JavaScript
- Java
- Go
- Python
server.loadAccount(destinationId).then(function (account) {
/* validate the account */
});
server.accounts().account(destination.getAccountId());
destAccountRequest := horizonclient.AccountRequest{AccountID: destination}
destinationAccount, err := client.AccountDetail(destAccountRequest)
if err != nil {
panic(err)
}
fmt.Println("Destination Account", destinationAccount)
server.load_account(destination_id)
- Carga los datos de la cuenta desde la que estás enviando. Una cuenta solo puede realizar una transacción a la vez y tiene algo llamado un número de secuencia, que ayuda a Stellar a verificar el orden de las transacciones. El número de secuencia de una transacción debe coincidir con el número de secuencia de la cuenta, así que necesitas obtener el número de secuencia actual de la cuenta de la red.
- JavaScript
- Java
- Go
- Python
.then(function() {
return server.loadAccount(sourceKeys.publicKey());
})
AccountResponse sourceAccount = server.accounts().account(source.getAccountId());
sourceKP := keypair.MustParseFull(source)
sourceAccountRequest := horizonclient.AccountRequest{AccountID: sourceKP.Address()}
sourceAccount, err := client.AccountDetail(sourceAccountRequest)
if err != nil {
panic(err)
}
source_account = server.load_account(source_key.public_key)
El SDK incrementará automáticamente el número de secuencia de la cuenta cuando construyas una transacción, así que no necesitarás recuperar esta información nuevamente si deseas realizar una segunda transacción.
- Empieza a construir una transacción. Esto requiere un objeto de cuenta, no solo una ID de cuenta, porque incrementará el número de secuencia de la cuenta.
- JavaScript
- Java
- Go
- Python
var transaction = new StellarSdk.TransactionBuilder(sourceAccount);
Transaction transaction = new Transaction.Builder(sourceAccount, Network.TESTNET)
tx, err := txnbuild.NewTransaction(
txnbuild.TransactionParams{
SourceAccount: &sourceAccount,
IncrementSequenceNum: true,
BaseFee: MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production!
},
...
},
)
if err != nil {
panic(err)
}
transaction = TransactionBuilder(
source_account=source_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=base_fee
)
- Agrega la operación de pago a la cuenta. Ten en cuenta que necesitas especificar el tipo de activo que estás enviando: la moneda de la red Stellar es el lumen, pero puedes enviar cualquier activo emitido en la red. Cubriré el envío de activos no lumen abajo. Por ahora, sin embargo, nos mantendremos en lumens, que se llaman activos “nativos” en el SDK:
- JavaScript
- Java
- Go
- Python
.addOperation(StellarSdk.Operation.payment({
destination: destinationId,
asset: StellarSdk.Asset.native(),
amount: "10"
}))
.addOperation(new PaymentOperation.Builder(destination.getAccountId(), new AssetTypeNative(), "10").build())
Operations: []txnbuild.Operation{
&txnbuild.Payment{
Destination: destination,
Amount: "10",
Asset: txnbuild.NativeAsset{},
},
},
.append_payment_op(destination=destination_id, asset=Asset.native(), amount="10")
También debes notar que la cantidad es una cadena en lugar de un número. Al trabajar con fracciones extremadamente pequeñas o grandes valores, la matemática de punto flotante puede introducir pequeñas inexactitudes. Dado que no todos los sistemas tienen una forma nativa de representar con precisión decimales extremadamente pequeños o grandes, Stellar utiliza cadenas como una forma confiable de representar la cantidad exacta en cualquier sistema.
- Opcionalmente, puedes agregar tus propios metadatos, llamados memo, a una transacción. Stellar no hace nada con estos datos, pero puedes usarlos para cualquier propósito que desees. Muchos exchanges requieren memos para transacciones entrantes porque utilizan una sola cuenta Stellar para todos sus usuarios y dependen del memo para diferenciar entre cuentas internas de usuarios.
- JavaScript
- Java
- Go
- Python
.addMemo(StellarSdk.Memo.text('Test Transaction'))
.addMemo(Memo.text("Test Transaction"));
Memo: txnbuild.MemoText("Test Transaction")
.add_text_memo("Test Transaction")
- Ahora que la transacción tiene todos los datos que necesita, debes firmarla criptográficamente utilizando tu clave secreta. Esto demuestra que los datos realmente provinieron de ti y no de alguien que te imita.
- JavaScript
- Java
- Go
- Python
transaction.sign(sourceKeys);
transaction.sign(source);
tx, err = tx.Sign(network.TestNetworkPassphrase, sourceKP)
if err != nil {
panic(err)
}
transaction.sign(source_key)
- Y finalmente, ¡envíala a la red Stellar!
- JavaScript
- Java
- Go
- Python
server.submitTransaction(transaction);
server.submitTransaction(transaction);
resp, err := horizonclient.DefaultTestNetClient.SubmitTransaction(tx)
if err != nil {
panic(err)
}
server.submit_transaction(transaction)
En este ejemplo, estamos enviando la transacción a la instancia pública del testnet de Horizon, la API de Stellar mantenida por la SDF. Al enviar transacciones a un servidor Horizon — que es lo que la mayoría de la gente hace — es posible que no recibas una respuesta del servidor debido a un error, condiciones de red, etc. En tal situación, es imposible determinar el estado de tu transacción. Por eso deberías siempre guardar una transacción construida (o una transacción codificada en formato XDR) en una variable o base de datos y reenviarla si no conoces su estado. Si la transacción ya se ha aplicado con éxito al ledger, Horizon simplemente devolverá el resultado guardado y no intentará enviar la transacción nuevamente. Solo en casos donde el estado de una transacción es desconocido (y por lo tanto tendrá una oportunidad de ser incluida en un ledger) se producirá un reenvío a la red.
Recibir un Pago
En realidad, no necesitas hacer nada para recibir pagos en una cuenta Stellar: si un pagador realiza una transacción exitosa para enviarte activos, esos activos se agregarán automáticamente a tu cuenta.
Sin embargo, es posible que desees estar atento a los pagos entrantes. Un programa simple que vigila la red en busca de pagos e imprime cada uno podría verse así:
- JavaScript
- Java
- Go
- Python
var StellarSdk = require("stellar-sdk");
var server = new StellarSdk.Horizon.Server(
"https://horizon-testnet.stellar.org",
);
var accountId = "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF";
// Create an API call to query payments involving the account.
var payments = server.payments().forAccount(accountId);
// If some payments have already been handled, start the results from the
// last seen payment. (See below in `handlePayment` where it gets saved.)
var lastToken = loadLastPagingToken();
if (lastToken) {
payments.cursor(lastToken);
}
// `stream` will send each recorded payment, one by one, then keep the
// connection open and continue to send you new payments as they occur.
payments.stream({
onmessage: function (payment) {
// Record the paging token so we can start from here next time.
savePagingToken(payment.paging_token);
// The payments stream includes both sent and received payments. We only
// want to process received payments here.
if (payment.to !== accountId) {
return;
}
// In Stellar’s API, Lumens are referred to as the “native” type. Other
// asset types have more detailed information.
var asset;
if (payment.asset_type === "native") {
asset = "lumens";
} else {
asset = payment.asset_code + ":" + payment.asset_issuer;
}
console.log(payment.amount + " " + asset + " from " + payment.from);
},
onerror: function (error) {
console.error("Error in payment stream");
},
});
function savePagingToken(token) {
// In most cases, you should save this to a local database or file so that
// you can load it next time you stream new payments.
}
function loadLastPagingToken() {
// Get the last paging token from a local database or file
}
Server server = new Server("https://horizon-testnet.stellar.org");
KeyPair account = KeyPair.fromAccountId("GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF");
// Create an API call to query payments involving the account.
PaymentsRequestBuilder paymentsRequest = server.payments().forAccount(account.getAccountId());
// If some payments have already been handled, start the results from the
// last seen payment. (See below in `handlePayment` where it gets saved.)
String lastToken = loadLastPagingToken();
if (lastToken != null) {
paymentsRequest.cursor(lastToken);
}
// `stream` will send each recorded payment, one by one, then keep the
// connection open and continue to send you new payments as they occur.
paymentsRequest.stream(new EventListener<OperationResponse>() {
@Override
public void onEvent(OperationResponse payment) {
// Record the paging token so we can start from here next time.
savePagingToken(payment.getPagingToken());
// The payments stream includes both sent and received payments. We only
// want to process received payments here.
if (payment instanceof PaymentOperationResponse) {
if (!((PaymentOperationResponse) payment).getTo().equals(account.getAccountId()) {
return;
}
String amount = ((PaymentOperationResponse) payment).getAmount();
Asset asset = ((PaymentOperationResponse) payment).getAsset();
String assetName;
if (asset.equals(new AssetTypeNative())) {
assetName = "lumens";
} else {
StringBuilder assetNameBuilder = new StringBuilder();
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getCode());
assetNameBuilder.append(":");
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getIssuer());
assetName = assetNameBuilder.toString();
}
StringBuilder output = new StringBuilder();
output.append(amount);
output.append(" ");
output.append(assetName);
output.append(" from ");
output.append(((PaymentOperationResponse) payment).getFrom());
System.out.println(output.toString());
}
}
@Override
public void onFailure(Optional<Throwable> optional, Optional<Integer> optional1) {
}
});
package main
import (
"context"
"fmt"
"time"
"github.com/stellar/go/clients/horizonclient"
"github.com/stellar/go/protocols/horizon/operations"
)
func main() {
client := horizonclient.DefaultTestNetClient
opRequest := horizonclient.OperationRequest{ForAccount: "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF", Cursor: "now"}
ctx, cancel := context.WithCancel(context.Background())
go func() {
// Stop streaming after 60 seconds.
time.Sleep(60 * time.Second)
cancel()
}()
printHandler := func(op operations.Operation) {
fmt.Println(op)
}
err := client.StreamPayments(ctx, opRequest, printHandler)
if err != nil {
fmt.Println(err)
}
}
from stellar_sdk import Server
def load_last_paging_token():
# Get the last paging token from a local database or file
return "now"
def save_paging_token(paging_token):
# In most cases, you should save this to a local database or file so that
# you can load it next time you stream new payments.
pass
server = Server("https://horizon-testnet.stellar.org")
account_id = "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF"
# Create an API call to query payments involving the account.
payments = server.payments().for_account(account_id)
# If some payments have already been handled, start the results from the
# last seen payment. (See below in `handle_payment` where it gets saved.)
last_token = load_last_paging_token()
if last_token:
payments.cursor(last_token)
# `stream` will send each recorded payment, one by one, then keep the
# connection open and continue to send you new payments as they occur.
for payment in payments.stream():
# Record the paging token so we can start from here next time.
save_paging_token(payment["paging_token"])
# We only process `payment`, ignore `create_account` and `account_merge`.
if payment["type"] != "payment":
continue
# The payments stream includes both sent and received payments. We
# only want to process received payments here.
if payment['to'] != account_id:
continue
# In Stellar’s API, Lumens are referred to as the “native” type. Other
# asset types have more detailed information.
if payment["asset_type"] == "native":
asset = "Lumens"
else:
asset = f"{payment['asset_code']}:{payment['asset_issuer']}"
print(f"{payment['amount']} {asset} from {payment['from']}")
Hay dos partes principales en este programa. Primero, creas una consulta para pagos que involucran una cuenta dada. Como la mayoría de las consultas en Stellar, esto podría devolver un gran número de elementos, así que la API devuelve tokens de paginación, que puedes usar más tarde para comenzar tu consulta desde el mismo punto donde la dejaste anteriormente. En el ejemplo anterior, las funciones para guardar y cargar tokens de paginación se dejaron en blanco, pero en una aplicación real, querrías guardar los tokens de paginación en un archivo o base de datos para poder continuar donde te quedaste en caso de que el programa se bloquee o el usuario lo cierre.
- JavaScript
- Java
- Go
- Python
var payments = server.payments().forAccount(accountId);
var lastToken = loadLastPagingToken();
if (lastToken) {
payments.cursor(lastToken);
}
PaymentsRequestBuilder paymentsRequest = server.payments().forAccount(account.getAccountId());
String lastToken = loadLastPagingToken();
if (lastToken != null) {
paymentsRequest.cursor(lastToken);
}
client := horizonclient.DefaultTestNetClient
opRequest := horizonclient.OperationRequest{ForAccount: "GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF", Cursor: "now"}
payments = server.payments().for_account(account_id)
last_token = load_last_paging_token()
if last_token:
payments.cursor(last_token)
En segundo lugar, los resultados de la consulta se transmiten. Esta es la forma más fácil de vigilar los pagos u otras transacciones. Cada pago existente se envía a través de la transmisión, uno por uno. Una vez que se han enviado todos los pagos existentes, la transmisión se mantiene abierta y se envían nuevos pagos a medida que se realizan.
Pruébalo: Ejecuta este programa y luego, en otra ventana, crea y envía un pago. Deberías ver que este programa registra el pago.
- JavaScript
- Java
- Go
- Python
payments.stream({
onmessage: function (payment) {
// handle a payment
},
});
paymentsRequest.stream(new EventListener<OperationResponse>() {
@Override
public void onEvent(OperationResponse payment) {
// Handle a payment
}
});
ctx, cancel := context.WithCancel(context.Background())
go func() {
// Stop streaming after 60 seconds.
time.Sleep(60 * time.Second)
cancel()
}()
printHandler := func(op operations.Operation) {
fmt.Println(op)
}
err := client.StreamPayments(ctx, opRequest, printHandler)
if err != nil {
fmt.Println(err)
}
for payment in payments.stream():
# handle a payment
También puedes solicitar pagos en grupos o páginas. Una vez que hayas procesado cada página de pagos, necesitarás solicitar la siguiente hasta que no quede ninguna.
- JavaScript
- Java
- Python
payments.call().then(function handlePage(paymentsPage) {
paymentsPage.records.forEach(function (payment) {
// handle a payment
});
return paymentsPage.next().then(handlePage);
});
Page<OperationResponse> page = payments.execute();
for (OperationResponse operation : page.getRecords()) {
// handle a payment
}
page = page.getNextPage();
payments_current = payments.call()
payments_next = payments.next()
Transaccionar en Otras Monedas
Una de las cosas sorprendentes de la red Stellar es que puedes crear, mantener, enviar, recibir e intercambiar cualquier tipo de activo. Muchas organizaciones emiten activos en Stellar que representan monedas del mundo real, como dólares estadounidenses o nairas nigerianas, o criptomonedas como bitcoin o ether.
Cada uno de estos activos redimibles — anclado en la jerga Stellar — es esencialmente un crédito emitido por una cuenta particular que representa las reservas que esas cuentas tienen fuera de la red. Por eso los activos en el ejemplo anterior tenían tanto un código
como un emisor
: el emisor
es la clave pública de la cuenta que creó el activo, una cuenta propiedad de la organización que finalmente honra el crédito que representa ese activo.
Guías en esta categoría:
📄️ Crear una cuenta
Crear y financiar una cuenta Stellar
📄️ Enviar y recibir pagos
Aprender a enviar pagos y vigilar los pagos recibidos en la red Stellar
📄️ Seguir pagos recibidos
Observa los pagos entrantes utilizando Horizon
📄️ Automatizar los datos de restablecimiento de Testnet y Futurenet
Aprende a automatizar los datos de restablecimiento de Testnet y Futurenet en Stellar