Before you can execute chain-abstracted operations with OneBalance, you need to set up a smart contract account (SCA). This smart contract account will hold your assets and enable gas abstraction across chains.

Key Concept: OneBalance uses smart contract accounts (SCAs) to enable chain and gas abstraction. Your SCA is your actual deposit address where funds are stored, and your Privy wallet acts as a signer for this account.

Predicting Your Account Address

Now that we’ve set up our project with proper CORS handling, let’s use the OneBalance API to predict a smart contract account (SCA) address based on Privy’s embedded wallet addresses:

First, create a component that will handle the account setup:

AccountSetup.tsx
// src/components/AccountSetup.tsx
'use client';

// Example usage in a component
import { useEffect, useState } from 'react';
import { useWallets } from '@privy-io/react-auth';
import { predictAccountAddress } from '@/lib/onebalance';

export function AccountSetup() {
  const { wallets } = useWallets();
  const [accountAddress, setAccountAddress] = useState<string | null>(null);

  // Find the Privy-managed embedded wallet
  const embeddedWallet = wallets.find(wallet => wallet.walletClientType === 'privy');

  useEffect(() => {
    async function setupAccount() {
      if (embeddedWallet && embeddedWallet.address) {
        try {
          // Using the same address as both session and admin for simplicity
          const predictedAddress = await predictAccountAddress(
            embeddedWallet.address,
            embeddedWallet.address
          );
          setAccountAddress(predictedAddress);
          console.log(`Smart Contract Account Address: ${predictedAddress}`);
        } catch (err) {
          console.error('Error setting up account:', err);
        }
      }
    }

    setupAccount();
  }, [embeddedWallet]);

  return (
    <div>
      {accountAddress ? (
        <p>Your OneBalance Smart Account: {accountAddress}</p>
      ) : (
        <p>Loading account address...</p>
      )}
    </div>
  );
}

This component uses the Predict Address endpoint to determine your smart contract account address before it’s deployed.

Next, create a dashboard page that will use this component:

page.tsx
// src/app/dashboard/page.tsx
import { AccountSetup } from '@/components/AccountSetup';

export default function Dashboard() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      <div className="max-w-md w-full bg-white p-8 rounded-xl shadow-md text-black">
        <h1 className="text-2xl font-bold mb-6">OneBalance Dashboard</h1>
        <AccountSetup />
      </div>
    </main>
  );
}

When a user logs in with Privy on the homepage, they’ll be redirected to this dashboard page where their predicted smart contract account address will be displayed. This is your first successful API call to OneBalance!

The predictAccountAddress function makes an API call to OneBalance’s /account/predict-address endpoint with the Privy wallet address as both the session and admin address. This deterministically calculates the smart contract account address that will be used for all your OneBalance operations.

When a user logs in with Privy via email (as shown in the previous section), they receive a verification code to complete the authentication process. Once verified, Privy creates an embedded wallet for them automatically, which becomes available through the useWallets() hook shown above.

Understanding Smart Contract Accounts (SCAs)

OneBalance uses smart contract accounts to enable key features like:

  1. Gas Abstraction: Pay for transactions using any token in your balance, not just the chain’s native gas token
  2. Resource Locks: Secure validation of transaction intents without requiring on-chain confirmations for every step
  3. Fast Path: Near-instant transactions without waiting for block confirmations

Important Account Relationship: - The SCA address (predicted by /account/predict-address) is your deposit address where funds are stored - The Privy-managed EOA wallet acts as a signer for your SCA, authorizing transactions - Always send funds to the SCA address, not to the Privy wallet address

Smart contract accounts are counterfactual, meaning they don’t need to be deployed until they’re actually used in a transaction. This saves gas costs and simplifies the user experience.

The account setup in this quickstart uses a common configuration for ease of use. OneBalance offers more advanced modular account options for specialized use cases, which you can explore in our Core Concepts: Account Models section.

Checking Account Balances

Before performing operations, you’ll want to check if your account has sufficient funds. The OneBalance API allows you to fetch aggregated balances across all chains:

balanceChecker.ts
// Example of checking for USDC and ETH balances
import { getAggregatedBalance } from '@/lib/onebalance';
import { formatUnits } from 'viem';

async function checkBalances(accountAddress: string) {
  try {
    const balanceData = await getAggregatedBalance(accountAddress);

    // Find USDC in the balance data
    const usdcAsset = balanceData.balanceByAggregatedAsset.find(
      (asset: any) => asset.aggregatedAssetId === 'ds:usdc'
    );

    // Find ETH in the balance data
    const ethAsset = balanceData.balanceByAggregatedAsset.find(
      (asset: any) => asset.aggregatedAssetId === 'ds:eth'
    );

    if (usdcAsset) {
      // Format the balance (USDC has 6 decimals)
      const formattedBalance = parseFloat(formatUnits(BigInt(usdcAsset.balance), 6)).toFixed(2);
      console.log(`USDC Balance: ${formattedBalance} USDC`);
    }

    if (ethAsset) {
      // Format the balance (ETH has 18 decimals)
      const formattedBalance = parseFloat(formatUnits(BigInt(ethAsset.balance), 18)).toFixed(6);
      console.log(`ETH Balance: ${formattedBalance} ETH`);
    }
  } catch (err) {
    console.error('Error fetching balances:', err);
  }
}

Asset ID Format: OneBalance uses the “ds:” prefix for aggregated asset identifiers (e.g., ds:usdc, ds:eth). This prefix indicates that these are aggregated assets that represent the same token across multiple chains. For example, ds:usdc represents USDC from Ethereum, Polygon, Arbitrum, and other supported networks as a single unified asset.

Learn more about how aggregated assets work in Aggregated Assets.

This example uses the Get Aggregated Balance endpoint to fetch your token balances across all supported chains with a single API call.

This function fetches the aggregated balance for an account and formats the values correctly:

  • USDC has 6 decimals, so we divide by 10^6
  • ETH has 18 decimals, so we divide by 10^18

The balances shown represent the total amount available across all supported chains, providing users with a unified view of their assets.

Your dashboard will show aggregated balances across multiple chains as a single, unified total. For example, if you have 10 USDC on Ethereum, 5 USDC on Polygon, and 5 USDC on Arbitrum, your dashboard will display a total of 20 USDC. This multichain aggregation is a key benefit of using OneBalance, as it eliminates the need to track assets separately across different networks.

Understanding Aggregated Assets

Learn how OneBalance unifies tokens across multiple chains into single aggregated assets

In the full implementation (next section), we’ll enhance the dashboard to display both the aggregated balance and a breakdown of assets per chain. Users can toggle to see exactly how their funds are distributed across networks like Ethereum, Arbitrum, Optimism, and others.

Cross-Chain Visibility: OneBalance automatically tracks your assets across all supported chains, so you don’t need to switch networks or use separate wallets to view your complete holdings. All tokens of the same type (e.g., USDC) are presented as a single aggregated balance, even if they’re distributed across multiple networks.

Funding Your Account

Before you can perform any operations with your smart contract account, you’ll need to fund it. Send tokens to the predictedAddress returned from the API. This is your SCA’s deposit address.

Remember to send funds to the SCA address (predictedAddress), not to your Privy wallet addresses. The predictedAddress is where your funds will be stored and managed across all chains.

Next Steps

Now that you’ve learned how to set up a smart contract account and check balances, you’re ready to execute chain-abstracted operations. In the next section, we’ll use the predicted account address to create a quote for swapping tokens across chains, with no bridging required.

Continue to Chain-Abstracted Transactions

Learn how to execute seamless chain-abstracted swaps using your new smart contract account