Skip to main content
In about five minutes you will deploy a smart account on Soneium Minato and send a sponsored UserOperation to a counter contract using nothing but Node.js and the Startale AA SDK.
The full SDK source is at StartaleGroup/scs-aa-sdk. Every symbol referenced below comes from @startale-scs/aa-sdk or viem.

Prerequisites

1

Node.js 18 or newer

Verify with node -v. The SDK targets modern ES2022 output.
2

An EOA private key for development

Any local key works. The signer is only used to sign UserOperations; the smart account is a separate address.
3

An SCS Portal API key and paymaster

Follow Portal setup to issue an API key, create a managed or self-funded paymaster, and copy the resulting bundlerUrl, paymasterUrl, and paymasterId.
4

A target contract on Soneium Minato

Any deployed contract with a public method works. The example uses a count() method on a Counter contract; substitute your own ABI and selector.

1. Initialize the project

These are the only runtime dependencies you need for the script in this guide. @startale-scs/aa-sdk carries the smart account and clients; viem provides chain definitions, transports, and ABI helpers; dotenv loads your bundler and paymaster URLs from .env.
Create a .env file alongside package.json:
.env

2. Wire up the script

Create index.ts:
index.ts

What every import does

smartAccountClient.account.address returns the counterfactual address of the smart account. The contract is not deployed until the first UserOperation lands; the bundler will deploy it for you on the first call. With sponsored gas you do not need to fund this address yourself, but if you ever skip the paymaster you must send some ETH there first.

3. Send a sponsored UserOperation

Append the following to index.ts. Replace the ABI fragment with the ABI of the function you want to call.
index.ts (continued)

What is happening here

  1. encodeFunctionData turns the count() selector into ABI-encoded calldata, exactly as if you were calling publicClient.writeContract.
  2. sendUserOperation packs the call into a UserOperation, asks the paymaster to co-sign it, signs it with your signer, and submits it to the SCS Bundler.
  3. waitForUserOperationReceipt polls the bundler until the UserOperation is mined and returns the inclusion receipt with the resolved transaction hash.
Run it:
You should see the smart account address, the UserOperation hash, and the receipt with success: true.

Common adjustments

Push more entries onto the calls array. They run atomically in the order you pass them; if any reverts, the whole UserOperation reverts.
Swap paymasterId for a token address from the supported tokens table.
See the ERC-20 paymaster tutorial for the full quote-and-execute flow.
Drop the paymaster and paymasterContext keys from createSmartAccountClient. You then need to fund the smart account address with ETH on Soneium Minato so that the EntryPoint can debit gas from the account itself.
toStartaleSmartAccount accepts any of LocalAccount, viem WalletClient, EthersWallet, or an EthereumProvider (EIP-1193). See Installation and setup for the full signer matrix.

Next steps

Tutorials path

Move from a script to a real React app: signer setup, provider context, contract interactions, sessions, and recovery.

Smart account setup

Wire toStartaleSmartAccount into a React provider so the account survives component remounts.

Sponsored paymaster

Build a real sponsored flow with a managed or self-funded paymaster and gas policies.

EIP-7702 delegation

Reuse the same script against an existing EOA address by delegating it to the Startale account implementation.