Quickstart: Send Your First UserOperation
This guide helps you send a UserOperation (UserOp) using ERC-4337 Account Abstraction with the Startale SCS AA SDK.
You'll interact with a Counter
smart contract and submit a sponsored UserOp via a Bundler and Paymaster.
Prerequisites
Ensure the following:
- Node.js v18+
.env
file with configuration values- A Bundler URL from SCS Portal
- (Optional) Paymaster URL
- Your EOA Private Key
- A deployed Counter smart contract on Soneium Minato
Project Setup
- Initialize a Node.js project
mkdir aa-quickstart && cd aa-quickstart
npm init -y
- Install dependencies
npm install dotenv ora viem @startale-scs/aa-sdk cli-table3 chalk
- Install TypeScript + CLI runner
npm install -D typescript ts-node @types/node
- Create a tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"resolveJsonModule": true,
"outDir": "dist"
},
"include": ["*.ts"]
}
- Create a .env file
MINATO_BUNDLER_URL="https://soneium-minato.bundler.scs.startale.com?apikey=YOUR_API_KEY"
PAYMASTER_SERVICE_URL="https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY"
OWNER_PRIVATE_KEY="0xYourPrivateKey"
COUNTER_CONTRACT_ADDRESS="0xCounterContractAddress"
# Counter deployed on Minato: 0x6bcf154A6B80fDE9bd1556d39C9bCbB19B539Bd8
Write Your Script
Create a file called quickstart.ts
with the following code:
1. Initialize Smart Account
Create Paymaster Client
Before creating the smart account client, initialize the SCS Paymaster Client:
// create API key here to obtain URLs: https://portal.scs.startale.com/api-keys
const scsPaymasterClient = createSCSPaymasterClient({
transport: http("<YOUR_PAYMASTER_URL_FROM_PORTAL>") as any,
});
const smartAccountClient = createSmartAccountClient({
account: await toStartaleSmartAccount({
signer: signer,
chain: chain,
transport: http(),
index: BigInt(2132) // Account index (salt)
}),
// create API key here to obtain URLs: https://portal.scs.startale.com/api-keys
transport: http("<YOUR_BUNDLER_URL_FROM_PORTAL>"), // from .env
client: publicClient,
paymaster: scsPaymasterClient,
paymasterContext: { calculateGasLimits: true, paymasterId: "<YOUR_PAYMASTER_ID_FROM_PORTAL>" }
});
If you do not wish to use a paymaster right now, you can simply comment out the paymaster
and paymasterContext
fields in the createSmartAccountClient
arguments.
However, make sure your smart account has enough ETH to cover gas fees.
You can get the counterfactual address (before deployment) with:
const address = smartAccountClient.account.address;
console.log("address", address);
Send some ETH to this address before submitting the UserOperation.
You can check the tutorial on how to create a Paymaster, set up policies, and obtain a Paymaster ID in the Portal Setup Guide.
2. Prepare Contract Interaction
Let’s assume you’ve already deployed a Counter contract that has a count() method. Encode the call:
const callData = encodeFunctionData({
abi: CounterAbi,
functionName: "count",
});
3. Send a UserOperation
You can now submit a UserOperation to the bundler. Note: If the smart account hasn't been deployed yet, this step will deploy it automatically.
const hash = await smartAccountClient.sendUserOperation({
calls: [{
to: counterContract as Address,
value: BigInt(0),
data: callData,
}],
});
const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash });
console.log("receipt", receipt);
-
calls
: Specifies the target contract and the function to execute. -
waitForUserOperationReceipt
: Waits until the UserOp is confirmed on-chain.
Key Features
- Gasless Transactions — Optional Paymaster support covers gas fees
- Smart Account — No direct private key use for end-users
- Bundler Integration — Handles mempool, simulation, and submission to
EntryPoint
Run the Script
Make sure you have the necessary .env
variables and dependencies set up:
1. Install Dependencies
npm install dotenv ora viem @startale-scs/aa-sdk cli-table3 chalk
2. Execute the Quickstart Script
Use ts-node to run your script:
npx ts-node quickstart.ts
Make sure your .env file includes:
MINATO_BUNDLER_URL="https://bundler.example.com"
PAYMASTER_SERVICE_URL="https://paymaster.example.com"
OWNER_PRIVATE_KEY="0xYourPrivateKey"
COUNTER_CONTRACT_ADDRESS="0xCounterContractAddress"