Appearance
Integrating OneBalance
OneBalance is a framework for setting up Credible Accounts for users, that allow them to use their balance on any EVM chain for transactions on any other EVM chain. This allows your app to abstract away the concept of "chains" for end users, and makes it significantly simpler to use balances across multiple EVM chains without the UX friction of explicitly bridging between them.
You can easily integrate OneBalance with Privy to abstract users' embedded wallet balances across the various chains that your app might support.
Get started with the steps below, or check out the sample app for a full walkthrough!
INFO
This guide assumes that you have already integrated Privy into your application for authenticating users and creating EVM embedded wallets for them. If not, please follow the Quickstart before continuing with this guide.
1. Set up OneBalance accounts for users
To start, create OneBalance accounts for your users and deposit any user assets to the account to set it up for executing transactions.
Follow the guide here to create your OneBalance API key and instantiate your users' accounts and deposit their assets to it.
You can also use your OneBalance API key to fetch an aggregated balance across all the chains your app supports.
2. Fetch a quote for a transaction
When executing a transaction, first fetch a quote from the OneBalance API for the transaction per this guide.
OneBalance supports swaps, transfers, and arbitrary calldata execution, supporting any transaction use case that your app might have.
3. Sign the transaction with the embedded wallet
Lastly, after fetching a quote for the transaction, sign the transaction using the user's embedded wallet by requesting an EIP-712 typed data signature, like so:
tsx
// below interface corresponds to ChainOperationSwaggerDto on OneBalance Swagger documentation
import {ChainOperation} from '<your path to OneBalance interfaces>';
// below interface corresponds to QuoteSwaggerDto on OneBalance Swagger documentation
import {Quote} from '<your path to OneBalance interfaces>';
import {Address, createWalletClient, custom, Hash} from 'viem';
import {ConnectedWallet} from '@privy-io/react-auth';
const signTypedDataWithPrivy =
(embeddedWallet: ConnectedWallet) =>
async (typedData: any): Promise<Hash> => {
const provider = await embeddedWallet.getEthereumProvider();
const walletClient = createWalletClient({
transport: custom(provider),
account: embeddedWallet.address as Address,
});
return walletClient.signTypedData(typedData);
};
const signOperation =
(embeddedWallet: ConnectedWallet) =>
async (operation: ChainOperation): Promise<ChainOperation> => {
const signature = await signTypedDataWithPrivy(embeddedWallet)(operation.typedDataToSign);
return {
...operation,
userOp: {...operation.userOp, signature},
};
};
export const signQuote = async (quote: Quote, embeddedWallet: ConnectedWallet) => {
const signWithEmbeddedWallet = signOperation(embeddedWallet);
const signedQuote = {
...quote,
};
signedQuote.originChainsOperations = await Promise.all(
quote.originChainsOperations.map(signWithEmbeddedWallet),
);
if (quote.destinationChainOperation) {
signedQuote.destinationChainOperation = await signWithEmbeddedWallet(
quote.destinationChainOperation,
);
}
return signedQuote;
};
Once you have successfully signed the transaction, you can execute the transaction with the OneBalance API and track its execution status.
That's it! Your users can now transact on any chain with a unified balance! 🎉