Chain Abstraction
💡 Chain Abstraction is currently in experimental phase.
Chain Abstraction in WalletKit enables users with stablecoins on any network to spend them on-the-fly on a different network. Our Chain Abstraction solution provides a toolkit for wallet developers to integrate this complex functionality using WalletKit.
For example, when an app requests a 100 USDC payment on Base network but the user only has USDC on Arbitrum, WalletKit offers methods to detect this mismatch, generate necessary transactions, track the cross-chain transfer, and complete the original transaction after bridging finishes.
How It Works​
Apps need to pass gas
as null, while sending a transaction to allow proper gas estimation by the wallet. Refer to this guide for more details.
When sending a transaction, you need to:
- Check if the required chain has enough funds to complete the transaction or not
- If not, use the
prepare
method to generate necessary bridging transactions - Check the status of the bridging transactions and wait for them to be completed
- Once the bridging transactions are completed, execute the initial transaction
The following sequence diagram illustrates the complete flow of a chain abstraction operation, from the initial dapp request to the final transaction confirmation
Methods​
Make sure you are using canary version of @reown/walletkit
and @walletconnect/react-native-compat
Following are the methods from WalletKit that you will use in implementing chain abstraction.
Prepare​
This method checks if a transaction requires additional bridging transactions beforehand.
public prepare(params: {
transaction: ChainAbstractionTypes.Transaction;
}): Promise<ChainAbstractionTypes.CanFulfilResponse>;
Status​
Helper method used to check the fulfilment status of a bridging operation.
public abstract status(params: {
fulfilmentId: string;
}): Promise<ChainAbstractionTypes.FulfilmentStatusResponse>;
Usage​
When your wallet receives an eth_sendTransaction
request, first check if chain abstraction is needed using the prepare
method, if it is, you need to sign all the fulfilment transactions and broadcast them in parallel.
After that, you need to call the status
method to check the status of the fulfillment operation.
If the operation is successful, you need to broadcast the initial transaction and await for the transaction hash and receipt. If the operation is not successful, you need to send the JsonRpcError to the dapp and display the error to the user.
walletkit.on("session_request", async (event) => {
const {
id,
topic,
params: { request, chainId },
} = event;
if (request.method === "eth_sendTransaction") {
const originalTransaction = request.params[0];
// Check if bridging transactions are required
const prepareResponse = await wallet.prepare({
transaction: {
...originalTransaction,
chainId,
},
});
if (prepareResponse.status === "error") {
// Display error to user and respond to dapp
await wallet.respondSessionRequest({
topic,
response: formatJsonRpcResult(id, prepareResponse.reason),
});
return;
}
if (prepareResponse.status === "available") {
const { transactions, funding, fulfilmentId, checkIn } = prepareResponse.data;
// Display bridging information to user
// Once approved, execute bridging transactions
for (const transaction of transactions) {
const signedTransaction = await wallet.signTransaction(transaction);
await wallet.sendTransaction(signedTransaction);
}
// await for the completed fulfilment status
await statusResult = await wallet.status({
fulfilmentId
});
// Proceed with original transaction
const signedTransaction = await wallet.signTransaction(originalTransaction);
const result = await wallet.sendTransaction(signedTransaction);
await wallet.respondSessionRequest({
topic,
response: formatJsonRpcResult(id, result)
});
} else {
// No bridging required, process transaction normally
const signedTransaction = await wallet.signTransaction(originalTransaction);
const result = await wallet.sendTransaction(signedTransaction);
await wallet.respondSessionRequest({
topic,
response: formatJsonRpcResult(id, result)
});
}
}
});