FeeProxy (EVM example)
Pay the gas for an ERC-20 transfer in a token other than XRP. Reference: FeeProxy precompile.
Copied from Futureverse’s
futureversecom/trn-examples, deleted with its GitHub organisation, at commit44c9e16of 2024-10-31. Apache-2.0: license. Before you run it, read Running the examples.
Offline destinations
Some places this page points to did not answer when last checked:
docs-beta.therootnetwork.com— does not resolve (checked 2026-10-18)stackblitz.com/github/futureversecom— StackBlitz loads these projects from the deleted futureversecom organisation on GitHub (checked 2026-10-18)
Run in StackBlitz (repository deleted, checked 2026-10-18) · Precompile Documentation (offline, checked 2026-10-18)
IMPORTANT
Ensure the following ENV vars are available before running the examples
CALLER_PRIVATE_KEY- Private key of an account that submits the transaction. Follow this guide to create and fund an account with some test tokens on Porcini (testnet) if you don't have one yet.
Examples
bash
# change your working directory to this example first
cd examples/evm/use-feeProxy
# export all required environments
export CALLER_PRIVATE_KEY=
# `feeProxy.callWithFeePreferences` that wraps around `ERC20.transfer`
pnpm call:callERC20TransferSource files
src/callERC20Transfer.ts
ts
import { ERC20_ABI } from "@therootnetwork/evm";
import { ALICE } from "@trne/utils/accounts";
import { filterTransactionEvents } from "@trne/utils/filterTransactionEvents";
import { getERC20Contract } from "@trne/utils/getERC20Contract";
import { getFeeProxyContract } from "@trne/utils/getFeeProxyContract";
import { getFeeProxyPricePair } from "@trne/utils/getFeeProxyPricePair";
import { ASTO_ASSET_ID, SYLO_ASSET_ID } from "@trne/utils/porcini-assets";
import { withEthersProvider } from "@trne/utils/withEthersProvider";
import { ContractReceipt, utils } from "ethers";
/**
* Use `feeProxy.callWithFeePreferences` to trigger a `transfer` call of SYLO token, and pay gas
* in ASTO token.
*
* Assumes the caller has ASTO balance to pay for gas and SYLO balance to demonstrate
* the transfer
*/
withEthersProvider("porcini", async (provider, wallet, logger) => {
// contracts creation
const feeProxy = getFeeProxyContract().connect(wallet);
const sylo = getERC20Contract(SYLO_ASSET_ID).connect(wallet);
const asto = getERC20Contract(ASTO_ASSET_ID).connect(wallet);
// transfer call
const transferAmount = utils.parseUnits("0.1", 18); // 1 SYLO
const transferInput = new utils.Interface(ERC20_ABI).encodeFunctionData("transfer", [
ALICE,
transferAmount,
]);
const transferEstimate = await sylo.estimateGas.transfer(ALICE, transferAmount);
logger.info(
{
parameters: {
destination: ALICE,
amount: transferAmount,
},
},
`create a transfer call`
);
// retrieve the maxPayment and maxFeePerGas parameters with slippage to be 0.05 (5%)
const { maxPayment, maxFeePerGas } = await getFeeProxyPricePair(
provider,
transferEstimate,
ASTO_ASSET_ID,
0.05
);
logger.info(`dispatch transaction from wallet=${wallet.address}`);
const tx = await feeProxy.callWithFeePreferences(
asto.address,
maxPayment,
sylo.address,
transferInput,
{
gasLimit: transferEstimate,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: 0,
}
);
const receipt = (await tx.wait()) as unknown as ContractReceipt;
const [transferEvent] = filterTransactionEvents(ERC20_ABI, receipt.logs, ["Transfer"]);
logger.info(
{
result: {
transactionHash: receipt.transactionHash,
blockNumber: receipt.blockNumber,
transferEvent: {
name: transferEvent.name,
args: transferEvent.args,
},
},
},
"receive result"
);
});package.json
json
{
"scripts": {
"call": "tsx --tsconfig ../../../tsconfig.json",
"call:callERC20Transfer": "pnpm call src/callERC20Transfer.ts"
}
}Source:
futureversecom/trn-examples, examples/evm/use-feeProxy (deleted) · commit 44c9e16, 2024-10-31 · Apache-2.0, license · part of Code examples