# Your First Gasless Smart Account Transaction

**Create a Smart Account and send gasless batched transactions in under 10 minutes.**

This guide walks you through creating your first smart account and sending multiple gasless transactions in a single UserOperation. Learn the core concepts of account abstraction while building a practical example that requires no ETH for gas fees.

#### What You'll Build[​](#what-youll-build "Direct link to What You'll Build")

By the end of this tutorial, you'll have:

* Created a smart contract wallet (smart account)
* Batched two NFT minting transactions into one operation
* Sent your first gasless UserOperation using a paymaster

#### What is a UserOperation?[​](#what-is-a-useroperation "Direct link to What is a UserOperation?")

A UserOperation is the mechanism smart accounts use to interact with Ethereum. Unlike regular transactions sent directly to the network, UserOperations offer:

* **Batching**: Group multiple transactions into a single atomic operation
* **Gas Flexibility**: Sponsor transactions or pay with any ERC-20 token
* **Programmability**: Include custom validation and execution logic

## Quickstart[​](#quickstart "Direct link to Quickstart")

[YouTube video player](https://www.youtube-nocookie.com/embed/t1ycwhN-Lvw?si=OMAiB7lK50XMkF68)

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

Before starting, make sure you have:

* **Node.js 18+** and npm/yarn
* **Basic TypeScript knowledge** - We'll explain the smart account concepts

Complete Example

You can also [fork the complete code](https://github.com/candidelabs/abstractionkit-examples/blob/main/sponsor-gas/sponsor-gas.ts) and follow along.

## Step 1: Project Setup[​](#step-1-project-setup "Direct link to Step 1: Project Setup")

#### Create Project Directory[​](#create-project-directory "Direct link to Create Project Directory")

```
mkdir candide-smart-account

cd candide-smart-account

npx tsc --init
```

#### Install Dependencies[​](#install-dependencies "Direct link to Install Dependencies")

```
npm install typescript --save-dev

npm install abstractionkit dotenv
```

**What each package does:**

* `abstractionkit` - Candide's SDK for smart account operations
* `dotenv` - Loads environment variables from .env file

#### Configure Environment Variables[​](#configure-environment-variables "Direct link to Configure Environment Variables")

Create a `.env` file in your project root:

.env

```
CHAIN_ID=11155111

BUNDLER_URL=https://api.candide.dev/public/v3/11155111

JSON_RPC_NODE_PROVIDER=https://ethereum-sepolia-rpc.publicnode.com

PAYMASTER_URL=https://api.candide.dev/public/v3/11155111

SPONSORSHIP_POLICY_ID= # optional



PRIVATE_KEY=YOUR_PRIVATE_KEY_HERE

PUBLIC_ADDRESS=YOUR_PUBLIC_ADDRESS_HERE
```

#### Create Main Script[​](#create-main-script "Direct link to Create Main Script")

Create an `index.ts` file:

index.ts

```
async function main(): Promise<void> {

  // We'll build our smart account logic here

}



main().catch(console.error);
```

## Step 2: Create Your Smart Account[​](#step-2-create-your-smart-account "Direct link to Step 2: Create Your Smart Account")

#### Understanding Smart Accounts[​](#understanding-smart-accounts "Direct link to Understanding Smart Accounts")

Smart accounts are smart contracts. Unlike regular wallets (EOAs), they can:

* Execute multiple transactions atomically
* Implement custom validation logic
* Support multiple signers or alternative signature schemes

This guide uses the Safe Unified Account (`SafeMultiChainSigAccountV1`), which works for single-chain transactions and multichain flows with the same account class. See [Safe Account](https://docs.candide.dev/wallet/abstractionkit/safe-account.md) for the account versions and how the `SafeAccount` alias maps to the real class.

#### Generate Account Address[​](#generate-account-address "Direct link to Generate Account Address")

index.ts

```
import * as dotenv from "dotenv";

// SafeMultiChainSigAccountV1 is the Safe Unified Account, aliased to SafeAccount for brevity.

import { SafeMultiChainSigAccountV1 as SafeAccount } from "abstractionkit";

  

async function main(): Promise<void> {

  // Load environment variables

  dotenv.config();



  const ownerPublicAddress = process.env.PUBLIC_ADDRESS as string;

  

  // Create a new smart account controlled by your EOA

  const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);

  

  console.log("Smart Account Address:", smartAccount.accountAddress);

}



main().catch(console.error);
```

#### Test Your Setup[​](#test-your-setup "Direct link to Test Your Setup")

Run the code to generate your smart account address:

```
npx ts-node index.ts
```

**Expected output:**

```
Smart Account Address: 0x32afdcfa1e3bfe70d03ecb55b5c8045c26515c9d
```

How It Works

The `initializeNewAccount()` method deterministically computes your smart account address locally using only the provided inputs—no network calls required. The account contract is not deployed at this stage; deployment occurs automatically when you send your first transaction.

## Step 3: Prepare Your Transactions[​](#step-3-prepare-your-transactions "Direct link to Step 3: Prepare Your Transactions")

#### What We're Building[​](#what-were-building "Direct link to What We're Building")

We'll create two NFT minting transactions and batch them together, demonstrating smart accounts' ability to execute multiple operations atomically.

#### Understanding Transaction Data[​](#understanding-transaction-data "Direct link to Understanding Transaction Data")

Every transaction needs three things:

* `to`: The contract address to interact with
* `value`: ETH amount to send (0 for most contract calls)
* `data`: Encoded function call data

#### Build the Transactions[​](#build-the-transactions "Direct link to Build the Transactions")

Add this to your `index.ts` (after the account creation code):

index.ts

```
import {

  SafeMultiChainSigAccountV1 as SafeAccount,

  MetaTransaction,

  getFunctionSelector,

  createCallData,

} from "abstractionkit";



// Inside your main() function, after creating smartAccount:



// NFT contract we'll interact with (a test contract on Sepolia)

const nftContractAddress = "0x9a7af758aE5d7B6aAE84fe4C5Ba67c041dFE5336";



// Prepare the function call data

const mintFunctionSignature = 'mint(address)';

const mintFunctionSelector = getFunctionSelector(mintFunctionSignature);

const mintTransactionCallData = createCallData(

  mintFunctionSelector, 

  ["address"], 

  [smartAccount.accountAddress] // Mint NFT to our smart account

);



// Create two identical transactions (we'll mint 2 NFTs)

const transaction1: MetaTransaction = {

  to: nftContractAddress,

  value: 0n, // No ETH needed for minting

  data: mintTransactionCallData, 

};



const transaction2: MetaTransaction = {

  to: nftContractAddress, 

  value: 0n,

  data: mintTransactionCallData,

};



console.log("Prepared 2 NFT minting transactions");
```

Why Batch Transactions?

Instead of sending two separate transactions, batch them into one UserOperation for a seamless one-click user experience.

## Step 4: Create UserOperation[​](#step-4-create-useroperation "Direct link to Step 4: Create UserOperation")

index.ts

```
const jsonRpcNodeProvider = process.env.JSON_RPC_NODE_PROVIDER as string;

const bundlerUrl = process.env.BUNDLER_URL as string;



// Create the UserOperation (batching both transactions)

let userOperation = await smartAccount.createUserOperation(

  [transaction1, transaction2], // Batch both NFT mints together

  jsonRpcNodeProvider, // Used for nonce and gas price data

  bundlerUrl // Used for gas limit estimation

);
```

## Step 5: Get Paymaster Data[​](#step-5-get-paymaster-data "Direct link to Step 5: Get Paymaster Data")

We'll use a paymaster to sponsor the gas fees, making this transaction completely gasless for the user.

index.ts

```
import {

  SafeMultiChainSigAccountV1 as SafeAccount,

  MetaTransaction,

  getFunctionSelector,

  createCallData,

  Erc7677Paymaster,

} from "abstractionkit";



const paymasterUrl = process.env.PAYMASTER_URL as string;

const paymaster = new Erc7677Paymaster(paymasterUrl);

const sponsorshipPolicyId = process.env.SPONSORSHIP_POLICY_ID;

const context = sponsorshipPolicyId

  ? { sponsorshipPolicyId, policyId: sponsorshipPolicyId }

  : {};



const { userOperation: paymasterUserOperation } = await paymaster.createPaymasterUserOperation(

    smartAccount,

    userOperation,

    bundlerUrl,

    context

  )



userOperation = paymasterUserOperation;
```

## Step 6: Sign and Submit[​](#step-6-sign-and-submit "Direct link to Step 6: Sign and Submit")

#### Sign the UserOperation[​](#sign-the-useroperation "Direct link to Sign the UserOperation")

Your smart account needs to be authorized by your EOA. Add this signing code:

index.ts

```
const chainId = BigInt(process.env.CHAIN_ID as string);

const privateKey = process.env.PRIVATE_KEY as string;



// Sign the UserOperation with your private key

userOperation.signature = smartAccount.signUserOperation(

  userOperation,

  [privateKey], // Array because Safe supports multiple signers

  chainId,

);



console.log("UserOperation signed successfully");
```

#### Submit to Network[​](#submit-to-network "Direct link to Submit to Network")

Now send your UserOperation to the bundler:

index.ts

```
// Submit the UserOperation

const sendUserOperationResponse = await smartAccount.sendUserOperation(

  userOperation, 

  bundlerUrl

);



console.log("UserOperation submitted! Waiting for confirmation...");
```

#### Wait for Confirmation[​](#wait-for-confirmation "Direct link to Wait for Confirmation")

Track your UserOperation until it's included in a block:

index.ts

```
let userOperationReceiptResult = await sendUserOperationResponse.included()



console.log("UserOperation receipt received.")

console.log(userOperationReceiptResult)



if (userOperationReceiptResult.success) {

    console.log("Two NFTs were minted. The transaction hash is : " + userOperationReceiptResult.receipt.transactionHash)

} else {

    console.log("UserOperation execution failed")

}
```

#### Run Your Complete Code[​](#run-your-complete-code "Direct link to Run Your Complete Code")

Execute your smart account transaction:

```
npx ts-node index.ts
```

**Expected output:**

Example Receipt Result

```
Useroperation sent. Waiting to be included ......

Useroperation receipt received.

{

  userOpHash: '0x1acede61123ab7116eb29c797aeaec3c03615c37732ba66428524aebdb4b4514',

  entryPoint: '0x433709009B8330FDa32311DF1C2AFA402eD8D009',

  sender: '0xb8741a449d50ed0dcfe395287f85be152884c8d9',

  nonce: 0n,

  paymaster: '0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020',

  actualGasCost: 8078496n,

  actualGasUsed: 504906n,

  success: true,

  logs: '[{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000007b44a0000000000000000000000000000000000000000000000000000000000007b44a","logIndex":"0x9a","removed":false,"topics":["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f","0x1acede61123ab7116eb29c797aeaec3c03615c37732ba66428524aebdb4b4514","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9","0x0000000000000000000000003fe285dcd76bcce4ac92d38a6f2f8e964041e020"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"}]',

  receipt: {

    blockHash: '0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c',

    blockNumber: 10419807n,

    from: '0x3cfdc212769c890907bce93d3d8c2c53de6a7a89',

    cumulativeGasUsed: 6978990n,

    gasUsed: 507053n,

    logs: '[{"address":"0xb8741a449d50ed0dcfe395287f85be152884c8d9","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x","logIndex":"0x90","removed":false,"topics":["0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440","0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0xb8741a449d50ed0dcfe395287f85be152884c8d9","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008ecd4ec46d4d2a6b64fe960b3d64e8b94b2234eb000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b40370000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bdbc5fbc9ca8c3f514d073ec3de840ac84fc6d31","logIndex":"0x91","removed":false,"topics":["0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8","0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x00000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c762","logIndex":"0x92","removed":false,"topics":["0x4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec670000000000000000000000003fe285dcd76bcce4ac92d38a6f2f8e964041e020","logIndex":"0x93","removed":false,"topics":["0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d","0x1acede61123ab7116eb29c797aeaec3c03615c37732ba66428524aebdb4b4514","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x","logIndex":"0x94","removed":false,"topics":["0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0xb8741a449d50ed0dcfe395287f85be152884c8d9","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b403700000000000000000000000038869bf66a61cf6bdb996a6ae40d5853fd43b526000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001048d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000b200d9de104e3386d9a45a61bce269c43e48b534e4e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041249c58b00d9de104e3386d9a45a61bce269c43e48b534e4e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041249c58b000000000000000000000000000000000000000000000000000000000000000000000000000000000000","logIndex":"0x95","removed":false,"topics":["0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0xd9de104e3386d9a45a61bce269c43e48b534e4e7","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x","logIndex":"0x96","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9","0x0000000000000000000000000000000000000000000000000000000000000056"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0xd9de104e3386d9a45a61bce269c43e48b534e4e7","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x","logIndex":"0x97","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9","0x0000000000000000000000000000000000000000000000000000000000000057"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0xb8741a449d50ed0dcfe395287f85be152884c8d9","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x","logIndex":"0x98","removed":false,"topics":["0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8","0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0x3fe285dcd76bcce4ac92d38a6f2f8e964041e020","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x0000000000000000000000000000000000000000000000000000000000000000","logIndex":"0x99","removed":false,"topics":["0xa050a122b4c0e369e3385eb6b7cccd8019638b2764de67bec0af99130ddf8471","0x1acede61123ab7116eb29c797aeaec3c03615c37732ba66428524aebdb4b4514","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9","0x0000000000000000000000000000000000000000000000000000000000000000"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"},{"address":"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789","blockHash":"0xe19e52b4c222c1cdbc765f1a4e196ff4bf40c5550926e02974570e1845e88e2c","blockNumber":"0x9efe5f","data":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000007b44a0000000000000000000000000000000000000000000000000000000000007b44a","logIndex":"0x9a","removed":false,"topics":["0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f","0x1acede61123ab7116eb29c797aeaec3c03615c37732ba66428524aebdb4b4514","0x000000000000000000000000b8741a449d50ed0dcfe395287f85be152884c8d9","0x0000000000000000000000003fe285dcd76bcce4ac92d38a6f2f8e964041e020"],"transactionHash":"0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa","transactionIndex":"0x1d"}]',

    logsBloom: '0x0000040000009000000000000000010080000000000000000000000000000000000800000000000000020001000004040010000000000000800002000000000000001000000000000000000c0002000000000000010000080040000000000000020000000a0000000500002000000800008000000100000000000014000000000800010020000200008000000040000000000200000400000000000000000000000004000000000000500000000004000210000000000000000002001000000020200082000000000001000008000000000000002060000000100000000026000000082000010000000000000008100220000000000000000000000010000200',

    transactionHash: '0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa',

    transactionIndex: 29n,

    effectiveGasPrice: 16n

  }

}

Two Nfts were minted. The transaction hash is : 0xf43576a07f39660737a342c99a187eb70ac59d89bc0df92ff3c1bb8a8da370aa
```

🎉 **Congratulations!** You've successfully sent your first batched gasless smart account transaction.

## Full Example[​](#full-example "Direct link to Full Example")

Below is the complete example code that you can copy directly to implement the functionality described in the tutorial.

index.js

```
import * as dotenv from 'dotenv'



import { 

    SafeMultiChainSigAccountV1 as SafeAccount,

    MetaTransaction,

    Erc7677Paymaster,

    getFunctionSelector,

    createCallData,

} from "abstractionkit";



async function main(): Promise<void> {

    //get values from .env

    dotenv.config()

    const chainId = BigInt(process.env.CHAIN_ID as string)

    const bundlerUrl = process.env.BUNDLER_URL as string

    const jsonRpcNodeProvider = process.env.JSON_RPC_NODE_PROVIDER as string

    const paymasterURL = process.env.PAYMASTER_URL as string

    const ownerPublicAddress = process.env.PUBLIC_ADDRESS as string

    const ownerPrivateKey = process.env.PRIVATE_KEY as string



    //initializeNewAccount only needed when the smart account

    //have not been deployed yet for its first useroperation.

    //You can store the accountAddress to use it to initialize 

    //the SafeAccount object for the following useroperations

    let smartAccount = SafeAccount.initializeNewAccount(

        [ownerPublicAddress],

    )



    //After the account contract is deployed, no need to call initializeNewAccount

    //let smartAccount = new SafeAccount(accountAddress)



    console.log("Account address(sender) : " + smartAccount.accountAddress)



    //create two meta transaction to mint two NFTs

    //you can use favorite method (like ethers.js) to construct the call data 

    const nftContractAddress = "0x9a7af758aE5d7B6aAE84fe4C5Ba67c041dFE5336";

    const mintFunctionSignature =  'mint(address)';

    const mintFunctionSelector =  getFunctionSelector(mintFunctionSignature);

    const mintTransactionCallData = createCallData(

        mintFunctionSelector, 

        ["address"],

        [smartAccount.accountAddress]

    );

    const transaction1 :MetaTransaction ={

        to: nftContractAddress,

        value: 0n,

        data: mintTransactionCallData,

    }



    const transaction2 :MetaTransaction ={

        to: nftContractAddress,

        value: 0n,

        data: mintTransactionCallData,

    }



    //createUserOperation will determine the nonce, fetch the gas prices,

    //estimate gas limits and return a useroperation to be signed.

    //you can override all these values using the overrides parameter.

    let userOperation = await smartAccount.createUserOperation(

		[

            //You can batch multiple transactions to be executed in one useroperation.

            transaction1, transaction2,

        ],

        jsonRpcNodeProvider, //the node rpc is used to fetch the current nonce and fetch gas prices.

        bundlerUrl, //the bundler rpc is used to estimate the gas limits.

	)



    // Get paymaster data to sponsor the transaction

    const paymasterUrl = process.env.PAYMASTER_URL as string;

    const paymaster = new Erc7677Paymaster(paymasterUrl);

    const sponsorshipPolicyId = process.env.SPONSORSHIP_POLICY_ID;

    const context = sponsorshipPolicyId

        ? { sponsorshipPolicyId, policyId: sponsorshipPolicyId }

        : {};



    const { userOperation: paymasterUserOperation } = await paymaster.createPaymasterUserOperation(

        smartAccount,

        userOperation,

        bundlerUrl,

        context

    )

    userOperation = paymasterUserOperation;

    

    console.log("Transaction will be sponsored - no ETH required!");

 

    //Safe is a multisig that can have multiple owners/signers

    //signUserOperation will create a signature for the provided

    //privateKeys

    userOperation.signature = smartAccount.signUserOperation(

		userOperation,

        [ownerPrivateKey],

        chainId

	)

    console.log(userOperation)



    //use the bundler rpc to send a userOperation

    //sendUserOperation will return a SendUseroperationResponse object

    //that can be awaited for the useroperation to be included onchain

    const sendUserOperationResponse = await smartAccount.sendUserOperation(

        userOperation, bundlerUrl

    )



    console.log("Useroperation sent. Waiting to be included ......")

    //included will return a UserOperationReceiptResult when 

    //useroperation is included onchain

    let userOperationReceiptResult = await sendUserOperationResponse.included()



    console.log("Useroperation receipt received.")

    console.log(userOperationReceiptResult)

    if(userOperationReceiptResult.success){

        console.log("Two Nfts were minted. The transaction hash is : " + userOperationReceiptResult.receipt.transactionHash)

    }else{

        console.log("Useroperation execution failed")

    }

}



main()
```

## Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting")

**"Insufficient funds" error**

* Make sure your smart account address has enough Sepolia ETH, or are using a paymaster to sponsor gas fees

**"Invalid signature" error**

* Verify your `PRIVATE_KEY` matches your `PUBLIC_ADDRESS`
* Ensure you're using the correct chain ID

**Network/timeout errors**

* Try a different node endpoint if the current one is down
* Check your internet connection

For runnable examples that classify and recover from common failures (underfunded paymaster, insufficient token balance, sponsor denial, on-chain reverts, and gas-too-low retries), see the [error-handling examples](https://github.com/candidelabs/abstractionkit-examples/tree/main/error-handling).

#### Getting Help[​](#getting-help "Direct link to Getting Help")

If you're still stuck:

* Ask questions in abstractionkit's [GitHub Discussions](https://github.com/candidelabs/abstractionkit/discussions)
* Join our [Discord](https://discord.gg/7R4g9XcxDQ)
* Check the [complete example code](https://github.com/candidelabs/abstractionkit-examples/blob/main/batch-transactions/batch-transactions.ts)

You can view your transaction on block explorers that support UserOperations like [Blockscout](https://www.blockscout.com/).

## What's Next?[​](#whats-next "Direct link to What's Next?")

Now that you've mastered the basics, explore more advanced smart account features:

#### Recommended Next Steps[​](#recommended-next-steps "Direct link to Recommended Next Steps")

1. **[Pay Gas in ERC-20](https://docs.candide.dev/wallet/guides/pay-gas-in-erc20.md)** - Let users pay fees with USDC or other tokens
2. **[Passkeys](https://docs.candide.dev/wallet/plugins/passkeys.md)** - Let users secure their account with biometrics login
3. **[Enable Account Recovery](https://docs.candide.dev/wallet/plugins/recovery-with-guardians.md)** - Let users add recovery methods through guardians or traditional sms/email
