import {
fetchPermissions,
getPermissionStatus,
prepareSpendCallData,
requestSpendPermission,
requestRevoke,
prepareRevokeCallData,
} from "@base-org/account/spend-permission";
const spender = "0xAppSpenderAddress";
// 1) Fetch available permissions
const permissions = await fetchPermissions({
account: "0xUserBaseAccountAddress",
chainId: 84532,
spender,
});
// ========================================
// When there IS an existing permission
// ========================================
// 2. find the permission to use, potentially filtering by token
const permission = permissions.at(0);
// 3. check the status of permission
try {
const { isActive, remainingSpend } = await getPermissionStatus(permission);
const amount = 1000n;
if (!isActive || remainingSpend < amount) {
throw new Error("No spend permission available");
}
} catch {
throw new Error("No spend permission available");
}
// 4. prepare the calls
const [approveCall, spendCall] = await prepareSpendCallData({
permission,
amount,
});
// 5. execute the calls using your app's spender account
// this is an example using wallet_sendCalls, in production it could be using eth_sendTransaction.
await provider.request({
method: "wallet_sendCalls",
params: [
{
version: "2.0",
atomicRequired: true,
from: spender,
calls: [approveCall, spendCall],
},
],
});
// ========================================
// When there is NOT an existing permission
// ========================================
// 2. request a spend permission to use
const newPermission = await requestSpendPermission({
account: "0xUserBaseAccountAddress",
spender,
token: "0xTokenContractAddress",
chainId: 84532,
allowance: 1_000_000n,
periodInDays: 30,
});
// 3. prepare the calls
const spendCalls = await prepareSpendCallData({
permission: newPermission,
amount: 1_000n,
});
// 4. execute the calls using your app's spender account
// this is an example using eth_sendTransaction. If your app account supports wallet_sendCalls, use wallet_sendCalls to batch the calls instead.
await Promise.all(
spendCalls.map((call) =>
provider.request({
method: "eth_sendTransaction",
params: [
{
...call,
from: spender,
},
],
})
)
);
// ========================================
// Request user to revoke spend permission
// ========================================
try {
const hash = await requestRevoke(permission);
console.log("Revoke succeeded", hash);
} catch {
throw new Error("Revoke failed");
}
// ========================================
// Revoke spend permission in the background
// ========================================
const revokeCall = await prepareRevokeCallData(permission);
await provider.request({
method: "wallet_sendCalls",
params: [
{
version: "2.0",
atomicRequired: true,
from: spender,
calls: [revokeCall],
},
],
});