Skip to content

The script demonstrates how to fetch balances, generate transaction data, and execute a cross-chain transfer using the Aarc Core SDK and the Ethereum provider via `ethers.js`

Notifications You must be signed in to change notification settings

aarc-xyz/Aarc-Core-SDK-Contract-Call-Example

Repository files navigation

README: Contract Call Example - Aarc Core SDK

This README explains the flow and execution of the provided TypeScript script that interacts with the Aarc Core SDK. The script demonstrates how to fetch balances, generate transaction data, and execute a cross-chain transfer using the Aarc Core SDK and the Ethereum provider via ethers.js.

Prerequisites

Before running the script, make sure you have the following set up:

  • Node.js: Ensure you have Node.js (v16 or higher) installed.
  • TypeScript: The script is written in TypeScript, so make sure TypeScript is installed.
  • Aarc Core SDK: You must have the Aarc Core SDK installed.
  • Environment Variables: The script requires the following environment variables:
    • API_KEY: Your Aarc Core API key.
    • PRIVATE_KEY: Your Ethereum wallet private key.
    • RPC_URL: The URL of the Ethereum RPC provider (e.g., Infura, Alchemy).

Setup Instructions

  1. Clone the repository (if needed) and navigate to your project folder.

  2. Install dependencies:

    npm install
  3. Create a .env file in the root directory of the project and set the following environment variables:

    API_KEY=your_aarc_api_key
    PRIVATE_KEY=your_private_key
    RPC_URL=your_rpc_url
    
  4. Install TypeScript and ts-node (if not installed):

    npm install --save-dev ts-node typescript
  5. Run the script:

    npx ts-node contract-call-example.ts

Overview of the Flow

The script demonstrates a complete flow involving balance fetching, generating transaction data, and executing a cross-chain transaction.

Script Breakdown

1. Environment Variables Loading

The script starts by loading environment variables from a .env file using the dotenv package. These variables are essential for connecting to Aarc Core and Ethereum networks.

config();
const API_KEY = process.env.API_KEY!;
const PRIVATE_KEY = process.env.PRIVATE_KEY!;
const RPC_URL = process.env.RPC_URL!;

2. Aarc Core SDK Initialization

An instance of the Aarc Core SDK is created using the provided API key. Additionally, an Ethereum wallet is initialized using the ethers.js library and the private key.

const aarcCoreSDK = new AarcCore(API_KEY);
const walletProvider = ethers.getDefaultProvider("https://base-rpc.publicnode.com");
const wallet = new ethers.Wallet(PRIVATE_KEY, walletProvider);

3. Fetching Multichain Balances

The getMultichainBalance function fetches the wallet's balance for the specified token (in this case, USDC) on the desired chain. This function uses the Aarc Core SDK to fetch balances across multiple chains.

const balance = await getMultichainBalance(wallet.address);

4. Generate Call Data for Transaction

A helper function generateCheckoutCallData generates the calldata for the transaction. This is the data needed for the contract call that will trigger the minting or transfer of tokens.

const callData = generateCheckoutCallData(
  destinationToken.address,
  destinationWalletAddress,
  "10000"
);

5. Fetch Deposit Address

The getDepositAddress function is responsible for fetching the deposit address from the Aarc Core API. It constructs the necessary payload, including the contract call data, and sends a request to Aarc Core to obtain a deposit address.

const depositData = await getDepositAddress({
  contractPayload: callData,
  fromToken: {
    decimals: fromToken.decimals,
    chainId: destinationToken.chainId,
    address: fromToken.token_address,
  },
  fromTokenAmount: "0.01",
});

6. Execute the Transaction

Once the deposit address is retrieved, the transaction is constructed with the necessary details, including the destination address, the value, the transaction data, and gas limit. The transaction is then signed and sent using the Ethereum wallet.

const txResponse = await wallet.sendTransaction(tx);

The transaction hash is logged, and Aarc Core is notified of the successful transaction.

7. Error Handling

Throughout the script, appropriate error handling is performed. If any error occurs at any stage (e.g., missing API key, insufficient balance, or transaction execution failure), the script will log the error message and stop execution.

Script Execution Flow

  1. Fetching Balances: The script fetches the balance of the specified token (USDC) for the Ethereum wallet address.
  2. Generating Call Data: It generates the contract call data needed to mint or transfer tokens.
  3. Fetching Deposit Address: The deposit address is fetched from Aarc Core using the contract call data.
  4. Executing Transaction: The transaction is sent to the network for execution.
  5. Request Polling: Poll the request id to get the tx status.
  6. Completion: The script logs the transaction hash and polling status upon successful execution.

Transaction Execution Disabled

Note: In the script, a line disables actual transaction execution. For testing purposes, the throw new Error("Transaction execution is disabled...") is included to prevent unintended transactions. To enable the transaction, you should remove or comment out this line.

throw new Error("Transaction execution is disabled for now, Please remove this line to execute the transaction");

Error Scenarios

  • Invalid API Key: If the API key is incorrect, an error will be thrown with the message "Invalid API key".
  • Insufficient Funds: If the wallet doesn't have enough balance for the transaction, an error will occur.
  • No Route Available: If there is no available route for the requested transfer, the script will log the error and suggest increasing the amount.

Conclusion

This script demonstrates the process of performing a cross-chain token transfer using the Aarc Core SDK, including fetching balances, generating call data, and executing the transaction. The flow is flexible and can be modified to suit different token transfers or blockchain configurations.

Sample Logs:

> [email protected] start
> npx tsc && node contract-call-example

Fetching balances...
Selected token: {
  decimals: 6,
  name: 'USD Coin',
  symbol: 'USDC',
  token_address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
  logo: 'https://logos.covalenthq.com/tokens/8453/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.png',
  native_token: false,
  type: 'cryptocurrency',
  is_spam: false,
  balance: '12470196',
  usd_price: 1,
  amount_required: 0.254021821170496,
  amount_required_usd: 0.254021821170496
}
Generating call data...
Fetching deposit address...
Deposit address fetched: {
  requestId: 'eab2f03a-0aaf-4b26-9edb-05bf1c54689e',
  status: 'INITIALISED',
  depositAddress: '0x321432bc871f6F40E6Ac7977DfD2Cc57a9752a65',
  onChainID: '8453',
  depositTokenName: 'USD Coin',
  depositTokenSymbol: 'USDC',
  depositTokenAddress: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
  depositTokenDecimals: '6',
  depositTokenUsdPrice: 1,
  amount: '10150',
  executionTime: '0',
  gasFee: '0',
  txData: {
    chainId: '8453',
    from: '0xeda8dec60b6c2055b61939dda41e9173bab372b2',
    to: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
    data: '0xa9059cbb000000000000000000000000321432bc871f6f40e6ac7977dfd2cc57a9752a6500000000000000000000000000000000000000000000000000000000000027a6',
    value: '0',
    gasLimit: '75571'
  }
}
Executing transaction...
Transaction hash: 0x3d4e89e8cd148650c9f701640ba46e3c64359a89c16f0e981c4a4b4f8d86f4d4
Transaction response:  Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 200,
    timingInfo: {
      startTime: 7751.5273001194,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 7751.5273001194,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 32,
      decodedBodySize: 32,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'OK',
    headersList: HeadersList {
      cookies: null,
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ [URL] ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: null,
    [Symbol(headers map)]: Map(26) {
      'date' => [Object],
      'content-type' => [Object],
      'content-length' => [Object],
      'connection' => [Object],
      'content-security-policy' => [Object],
      'cross-origin-opener-policy' => [Object],
      'cross-origin-resource-policy' => [Object],
      'origin-agent-cluster' => [Object],
      'strict-transport-security' => [Object],
      'x-content-type-options' => [Object],
      'x-dns-prefetch-control' => [Object],
      'x-download-options' => [Object],
      'access-control-allow-origin' => [Object],
      'etag' => [Object],
      'cf-cache-status' => [Object],
      'report-to' => [Object],
      'nel' => [Object],
      'feature-policy' => [Object],
      'permissions-policy' => [Object],
      'referrer-policy' => [Object],
      'x-frame-options' => [Object],
      'x-permitted-cross-domain-policies' => [Object],
      'x-xss-protection' => [Object],
      'server' => [Object],
      'cf-ray' => [Object],
      'server-timing' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}
Transaction completed with hash: 0x3d4e89e8cd148650c9f701640ba46e3c64359a89c16f0e981c4a4b4f8d86f4d4
{
  code: 200,
  data: {
    requestId: 'eab2f03a-0aaf-4b26-9edb-05bf1c54689e',
    status: 'SCHEDULED',
    transactionSteps: []
  },
  message: 'success'
}
Polling message: Request is being processed.
{
  code: 200,
  data: {
    requestId: 'eab2f03a-0aaf-4b26-9edb-05bf1c54689e',
    status: 'CREATE_AND_FORWARD_PENDING',
    transactionSteps: []
  },
  message: 'success'
}
Polling message: Creating and forwarding your request.
{
  code: 200,
  data: {
    requestId: 'eab2f03a-0aaf-4b26-9edb-05bf1c54689e',
    status: 'DEPOSIT_COMPLETED',
    transactionSteps: [ [Object] ]
  },
  message: 'success'
}
Polling message: Funds received successfully.
{
  code: 200,
  data: {
    requestId: 'eab2f03a-0aaf-4b26-9edb-05bf1c54689e',
    status: 'CHECKOUT_COMPLETED',
    transactionSteps: [ [Object], [Object] ]
  },
  message: 'success'
}
Polling message: Checkout completed successfully.
Polling result: {
  pollStatus: 'success',
  error: null,
  hasTimedOut: false,
  pollingMessage: 'Checkout completed successfully.'
}

About

The script demonstrates how to fetch balances, generate transaction data, and execute a cross-chain transfer using the Aarc Core SDK and the Ethereum provider via `ethers.js`

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published