Saltearse al contenido

Transacciones Patrocinadas

Normalmente, la cuenta que ejecuta una transacción paga las comisiones de gas. Puedes permitir que otra cuenta cubra esos cargos patrocinando una transacción.

Esto puede usarse para ayudar a gestionar comisiones desde una cuenta central al trabajar con contratos inteligentes complicados.

  1. Construye la transacción con el parámetro withFeePayer: true.

    const transaction = await aptos.transaction.build.simple({
    sender: sender.accountAddress,
    withFeePayer: true,
    data: {
    // Todas las transacciones en Aptos se implementan vía contratos inteligentes.
    function: "0x1::aptos_account::transfer",
    functionArguments: [destination.accountAddress, 100],
    },
    });
  2. Firma la transacción con AMBOS, el remitente y el feePayer.

    1. Firma con la cuenta remitente usando .sign.
    2. Firma con la cuenta patrocinadora usando .signAsFeePayer.
    const senderAuthenticator = aptos.transaction.sign({
    signer: sender,
    transaction,
    });
    const feePayerAuthenticator = aptos.transaction.signAsFeePayer({
    signer: feePayer,
    transaction
    })
  3. (Opcional) Simula la transacción patrocinada

    Puedes simular la transacción patrocinada para previsualizar el resultado antes de enviarla de la siguiente manera:

    const [userTransactionResponse] = await aptos.transaction.simulate.simple({
    signerPublicKey: sender.publicKey,
    transaction,
    });

    Por defecto, el feePayerAddress de la transaction se establece en 0x0, lo que hace que la simulación de la transacción omita el pago de la comisión de gas. Esto te permite simular la transacción sin especificar un fee payer. Ten en cuenta que signerPublicKey es opcional y puede omitirse si deseas omitir la verificación de la clave de autenticación del remitente.

    También puedes simular la transacción con un fee payer específico estableciendo el feePayerAddress en el objeto transaction así:

    transaction.feePayerAddress = feePayer.accountAddress;
    const [userTransactionResponse] = await aptos.transaction.simulate.simple({
    signerPublicKey: sender.publicKey,
    feePayerPublicKey: feePayer.publicKey,
    transaction,
    });

    Esta configuración verificará que feePayer tenga saldo suficiente para cubrir la comisión de gas de la transacción. De manera similar, feePayerPublicKey es opcional y puede omitirse si deseas omitir la verificación de la clave de autenticación del fee payer.

  4. Envía la transacción combinando ambas firmas.

    // 4. Enviar
    const committedTransaction = await aptos.transaction.submit.simple({
    transaction,
    senderAuthenticator: senderAuthenticator,
    feePayerAuthenticator: feePayerAuthenticator,
    });
  5. Espera a que la transacción se ejecute.

    // 5. Esperar resultados
    const executedTransaction = await aptos.waitForTransaction({ transactionHash: committedTransaction.hash });

Ejemplo de Código de Transacción Patrocinada en TypeScript

Sección titulada «Ejemplo de Código de Transacción Patrocinada en TypeScript»
/**
* Este ejemplo muestra cómo usar el SDK de Aptos para enviar una transacción con patrocinador.
*/
import {
Account,
Aptos,
AptosConfig,
Network,
} from "@aptos-labs/ts-sdk";
async function example() {
console.log("Este ejemplo enviará una transacción patrocinada de Alice a Carol.");
// 0. Configura el cliente y las cuentas de prueba
const config = new AptosConfig({ network: Network.DEVNET });
const aptos = new Aptos(config);
let alice = Account.generate();
let bob = Account.generate();
let carol = Account.generate();
console.log("=== Direcciones ===\n");
console.log(`La dirección de Alice es: ${alice.accountAddress}`);
console.log(`La dirección de Bob es: ${bob.accountAddress}`);
console.log(`La dirección de Carol es: ${carol.accountAddress}`);
console.log("\n=== Financiando cuentas ===\n");
await aptos.fundAccount({
accountAddress: alice.accountAddress,
amount: 500_000_000,
});
await aptos.fundAccount({
accountAddress: bob.accountAddress,
amount: 500_000_000,
});
await aptos.fundAccount({
accountAddress: carol.accountAddress,
amount: 100,
});
console.log("¡Cuentas financiadas!")
// 1. Construir
console.log("\n=== 1. Construyendo la transacción ===\n");
const transaction = await aptos.transaction.build.simple({
sender: alice.accountAddress,
withFeePayer: true,
data: {
// Todas las transacciones en Aptos se implementan vía contratos inteligentes.
function: "0x1::aptos_account::transfer",
functionArguments: [carol.accountAddress, 100],
},
});
console.log("¡Transacción construida!")
// 2. Firmar
console.log("\n=== 2. Firmando transacción ===\n");
const aliceSenderAuthenticator = aptos.transaction.sign({
signer: alice,
transaction,
});
const bobSenderAuthenticator = aptos.transaction.signAsFeePayer({
signer: bob,
transaction
})
console.log("¡Transacción firmada!")
// 3. Simular (Opcional)
console.log("\n === 3. Simulando Respuesta (Opcional) === \n")
const [userTransactionResponse] = await aptos.transaction.simulate.simple({
signerPublicKey: alice.publicKey,
feePayerPublicKey: bob.publicKey,
transaction,
});
console.log(userTransactionResponse)
// 4. Enviar
console.log("\n=== 4. Enviando transacción ===\n");
const committedTransaction = await aptos.transaction.submit.simple({
transaction,
senderAuthenticator: aliceSenderAuthenticator,
feePayerAuthenticator: bobSenderAuthenticator,
});
console.log("Hash de la transacción enviada:", committedTransaction.hash);
// 5. Esperar resultados
console.log("\n=== 5. Esperando resultado de la transacción ===\n");
const executedTransaction = await aptos.waitForTransaction({ transactionHash: committedTransaction.hash });
console.log(executedTransaction)
};
example();

INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEE :

  1. Esto puede ser causado por usar accidentalmente .sign en vez de .signAsFeePayer al firmar la transacción antes de enviarla en la cadena.
  2. Patrocinar una transacción requiere que la cuenta patrocinadora tenga suficientes fondos para cubrir la comisión máxima de gas posible. Esto suele ser órdenes de magnitud mayor que las comisiones de gas esperadas o reales requeridas para que una transacción se ejecute. En este caso, aumenta los fondos en la cuenta por encima de max_gas_amount multiplicado por el gas_unit_price en la transacción simulada. Estos deben multiplicarse porque el gas no tiene unidades, por lo que debe multiplicarse por la tasa de conversión de gas a octas. Puedes aprender más sobre gas aquí.