Convirtiendo el anuncio de transacción asincrónica en sincrónica

Fragmento útil para anunciar una transacción y esperar hasta que se confirme.

Casos de uso

Bitxor funciona de manera diferente: cuando se anuncia una transacción, el servidor de la API REST siempre devolverá un “OK”. Como resultado, el desarrollador no tiene que esperar hasta que el servidor devuelva una respuesta, lo que le permite crear aplicaciones más receptivas. Sin embargo, ahora es responsabilidad del desarrollador verificar el estado de la transacción y asegurarse de que esté confirmada.

El aspecto negativo de anunciar transacciones de forma asíncrona es que agrega una complejidad innecesaria a proyectos pequeños. El Bitxor SDK TransactionService tiene como objetivo resolver este problema al proporcionar una función que espera la confirmación o el rechazo de la transacción.

Requisitos previos

Enviando una transacción sincrónica

Alice está desarrollando una aplicación para enviar 10 currencytoken a Bob y quiere saber si la transacción ha llegado a la red antes de enviar un correo electrónico a Bob.

  1. Crea un nuevo archivo .ts. Luego, define y firma una TransferTransaction.

// replace with recipient address
const rawRecipientAddress = 'BXRQ5E-YACWBP-CXKGIL-I6XWCH-DRFLTB-KUK34I-YJQ';
const recipientAddress = Address.createFromRawAddress(rawRecipientAddress);
// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with bitxor id
const networkCurrencyTokenId = new TokenId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;

const transferTransaction = TransferTransaction.create(
  Deadline.create(epochAdjustment),
  recipientAddress,
  [
    new Token(
      networkCurrencyTokenId,
      UInt64.fromUint(10 * Math.pow(10, networkCurrencyDivisibility)),
    ),
  ],
  EmptyMessage,
  networkType,
  UInt64.fromUint(2000000),
);

// replace with sender private key
const privateKey =
  '1111111111111111111111111111111111111111111111111111111111111111';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
  '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
  transferTransaction,
  networkGenerationHash,
);
// replace with recipient address
const rawRecipientAddress = 'BXRQ5E-YACWBP-CXKGIL-I6XWCH-DRFLTB-KUK34I-YJQ';
const recipientAddress = bitxor_sdk_1.Address.createFromRawAddress(
    rawRecipientAddress,
);
// replace with network type
const networkType = bitxor_sdk_1.NetworkType.TEST_NET;
// replace with bitxor id
const networkCurrencyTokenId = new bitxor_sdk_1.TokenId('5E62990DCAC5BE8A');
// replace with network currency divisibility
const networkCurrencyDivisibility = 6;
const transferTransaction = bitxor_sdk_1.TransferTransaction.create(
    bitxor_sdk_1.Deadline.create(epochAdjustment),
    recipientAddress, [
        new bitxor_sdk_1.Token(
            networkCurrencyTokenId,
            bitxor_sdk_1.UInt64.fromUint(
                10 * Math.pow(10, networkCurrencyDivisibility),
            ),
        ),
    ],
    bitxor_sdk_1.EmptyMessage,
    networkType,
    bitxor_sdk_1.UInt64.fromUint(2000000),
);
// replace with sender private key
const privateKey =
    '1111111111111111111111111111111111111111111111111111111111111111';
const account = bitxor_sdk_1.Account.createFromPrivateKey(
    privateKey,
    networkType,
);
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash =
    '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = account.sign(
    transferTransaction,
    networkGenerationHash,
);
  1. Una vez firmada, anuncia la transacción utilizando TransactionService.announce en lugar de TransactionHttp.announce.

const nodeUrl = 'NODE_URL';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
const transactionService = new TransactionService(transactionHttp, receiptHttp);

listener.open().then(() => {
  merge(
    transactionService.announce(signedTransaction, listener),
    listener.status(account.address).pipe(
      filter((error) => error.hash === signedTransaction.hash),
      tap((error) => {
        throw new Error(error.code);
      }),
    ),
  ).subscribe(
    (transaction) => {
      console.log(transaction);
      // TODO: send email to recipient
      listener.close();
    },
    (err) => console.error(err),
  );
});
const nodeUrl = 'NODE_URL';
const repositoryFactory = new bitxor_sdk_1.RepositoryFactoryHttp(nodeUrl);
const receiptHttp = repositoryFactory.createReceiptRepository();
const transactionHttp = repositoryFactory.createTransactionRepository();
const listener = repositoryFactory.createListener();
const transactionService = new bitxor_sdk_1.TransactionService(
    transactionHttp,
    receiptHttp,
);
listener.open().then(() => {
    rxjs_1
        .merge(
            transactionService.announce(signedTransaction, listener),
            listener.status(account.address).pipe(
                operators_1.filter((error) => error.hash === signedTransaction.hash),
                operators_1.tap((error) => {
                    throw new Error(error.code);
                }),
            ),
        )
        .subscribe(
            (transaction) => {
                console.log(transaction);
                // TODO: send email to recipient
                listener.close();
            },
            (err) => console.error(err),
        );
});

Note

La función TransactionService.announce() responderá exitosamente si la transacción llega a la red y no tiene errores de validación. Es posible que aún necesites esperar varias confirmaciones antes de ejecutar acciones adicionales.