Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions docs/base-account/improve-ux/spend-permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,15 @@ await provider.request({
- [requestRevoke](/base-account/reference/spend-permission-utilities/requestRevoke)
- [prepareRevokeCallData](/base-account/reference/spend-permission-utilities/prepareRevokeCallData)
- [fetchPermissions](/base-account/reference/spend-permission-utilities/fetchPermissions)
- [fetchPermission](/base-account/reference/spend-permission-utilities/fetchPermission)
- [getPermissionStatus](/base-account/reference/spend-permission-utilities/getPermissionStatus)

## Complete Integration Example

```typescript
import {
fetchPermissions,
fetchPermission,
getPermissionStatus,
prepareSpendCallData,
requestSpendPermission,
Expand All @@ -205,22 +207,30 @@ const sdk = createBaseAccountSDK({

const spender = "0xAppSpenderAddress";

// 1) Fetch available permissions
const permissions = await fetchPermissions({
account: "0xUserBaseAccountAddress",
chainId: 84532,
spender,
// 1) Fetch a specific permission by its hash
// Use fetchPermission when you already know the permission hash
// (e.g., stored from a previous session or passed as a parameter)
const permission = await fetchPermission({
permissionHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
provider: sdk.getProvider(),
});

// Alternative: Fetch all permissions for a spender
// Use fetchPermissions when you need to see all available permissions
// and want to choose which one to use
// const permissions = await fetchPermissions({
// account: "0xUserBaseAccountAddress",
// chainId: 84532,
// spender,
// provider: sdk.getProvider(),
// });
// const permission = permissions.at(0);

// ========================================
// 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
// 2. check the status of permission
try {
const { isActive, remainingSpend } = await getPermissionStatus(permission);
const amount = 1000n;
Expand All @@ -232,13 +242,13 @@ try {
throw new Error("No spend permission available");
}

// 4. prepare the calls
// 3. prepare the calls
const [approveCall, spendCall] = await prepareSpendCallData({
permission,
amount,
});

// 5. execute the calls using your app's spender account
// 4. 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",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: "coinbase_fetchPermissions"
description: "Retrieve permissions associated with a specific account, chain, and spender"
description: "Retrieve permissions associated with a specific account and chain, optionally filtered by spender"
---

Coinbase-specific RPC method

<Info>
Retrieves permissions associated with a specific account, chain, and spender. This method excludes permissions that have expired or been revoked, returning only active spend permissions.
Retrieves permissions associated with a specific account and chain. If a spender is provided, returns only permissions for that spender. Otherwise, returns all permissions for the account. This method excludes permissions that have expired or been revoked, returning only active spend permissions.
</Info>

## Parameters
Expand All @@ -19,8 +19,8 @@ The address of the account whose permissions are being queried.
The ID of the blockchain, in hexadecimal format.
</ParamField>

<ParamField body="spender" type="string" required>
The entity granted with the permission to spend the account's funds.
<ParamField body="spender" type="string">
Optional. The entity granted with the permission to spend the account's funds. If not provided, returns all permissions for the account.
</ParamField>

<ParamField body="pageOptions" type="object">
Expand Down Expand Up @@ -54,7 +54,7 @@ Pagination information for the response.
</ResponseField>

<RequestExample>
```json Request
```json Request with spender
{
"id": 1,
"jsonrpc": "2.0",
Expand All @@ -66,6 +66,18 @@ Pagination information for the response.
}]
}
```

```json Request without spender (all permissions)
{
"id": 1,
"jsonrpc": "2.0",
"method": "coinbase_fetchPermissions",
"params": [{
"account": "0xfB2adc8629FC9F54e243377ffcECEb437a42934C",
"chainId": "0x14A34"
}]
}
```
</RequestExample>

<ResponseExample>
Expand Down Expand Up @@ -110,5 +122,5 @@ Pagination information for the response.
| -32602 | Invalid params | Invalid account, chainId, or spender parameters |

<Warning>
Ensure the `chainId`, `account`, and `spender` parameters are correctly formatted and valid for the blockchain you are querying.
Ensure the `chainId` and `account` parameters are correctly formatted and valid for the blockchain you are querying. If provided, the `spender` parameter must also be a valid address.
</Warning>
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
title: "fetchPermission"
description: "Retrieve a single Spend Permission by its hash"
---

Defined in the [Base Account SDK](https://github.com/base/account-sdk)

<Info>
Returns a single spend permission by its unique hash identifier. This is useful when you have a permission hash from a previous operation and need to retrieve its current details.
</Info>

## Parameters

<ParamField body="permissionHash" type="string" required>
The unique hash identifier of the permission to retrieve.
</ParamField>

<ParamField body="provider" type="EIP1193Provider">
Optional. EIP-1193 compliant Ethereum provider instance. Get this from `sdk.getProvider()`. If not provided, uses the default SDK provider.
</ParamField>

## Returns

<ResponseField name="permission" type="SpendPermission | null">
The spend permission matching the hash, or null if not found.

<Expandable title="SpendPermission properties">
<ResponseField name="permissionHash" type="string">
Deterministic EIP-712 hash of the permission.
</ResponseField>

<ResponseField name="signature" type="string">
Signature for the EIP-712 payload.
</ResponseField>

<ResponseField name="chainId" type="number">
Target chain ID.
</ResponseField>

<ResponseField name="permission" type="object">
Underlying permission fields.

<Expandable title="permission fields">
<ResponseField name="account" type="address" />
<ResponseField name="spender" type="address" />
<ResponseField name="token" type="address" />
<ResponseField name="allowance" type="bigint" />
<ResponseField name="period" type="number">Duration in seconds.</ResponseField>
<ResponseField name="start" type="number">Unix timestamp (seconds).</ResponseField>
<ResponseField name="end" type="number">Unix timestamp (seconds).</ResponseField>
<ResponseField name="salt" type="string" />
<ResponseField name="extraData" type="string" />
</Expandable>
</ResponseField>
</Expandable>
</ResponseField>

<RequestExample>
```typescript Fetch single permission
import { fetchPermission } from "@base-org/account/spend-permission";
import { createBaseAccountSDK } from "@base-org/account";

const sdk = createBaseAccountSDK({
appName: 'My App',
appLogoUrl: 'https://example.com/logo.png',
appChainIds: [84532],
});

// Fetch a specific permission by its hash
const permission = await fetchPermission({
permissionHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
provider: sdk.getProvider(),
});

if (permission) {
console.log('Permission found:', permission);
} else {
console.log('Permission not found');
}

// Using without explicit provider (uses default SDK provider)
const permission2 = await fetchPermission({
permissionHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
});
```
</RequestExample>

## Error Handling

The function returns `null` if the permission is not found rather than throwing an error. Always check for null values:

```typescript
const permission = await fetchPermission({
permissionHash: hash,
});

if (!permission) {
// Handle permission not found
console.error('Permission not found');
return;
}

// Safe to use permission here
console.log('Permission details:', permission);
```

## Usage Notes

<Note>
This function is particularly useful when:
- You have a permission hash from a previous operation (e.g., from `requestSpendPermission`)
- You want to verify the current state of a specific permission
- You need to look up permission details without knowing the account or spender information
- You're tracking specific permissions across sessions
</Note>

Unlike `fetchPermissions`, this function:
- Returns a single permission instead of an array
- Does not require account, chain, or spender parameters
- Provides direct access via the permission's unique identifier
- Returns `null` instead of an empty array when no permission is found

import PolicyBanner from "/snippets/PolicyBanner.mdx";

<PolicyBanner />
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
---
title: "fetchPermissions"
description: "Retrieve available Spend Permissions for an account, chain, and spender"
description: "Retrieve available Spend Permissions for an account and chain, optionally filtered by spender"
---

Defined in the [Base Account SDK](https://github.com/base/account-sdk)

<Info>
Returns all permissions available to a given `spender` for a user's Base
Account on a specific chain.
Returns permissions for a user's Base Account on a specific chain. If a `spender` is provided, returns only permissions for that spender. Otherwise, returns all permissions for the account.
</Info>

## Parameters
Expand All @@ -20,12 +19,12 @@ Defined in the [Base Account SDK](https://github.com/base/account-sdk)
Target chain ID.
</ParamField>

<ParamField body="spender" type="address" required>
Spender address you intend to use for spending.
<ParamField body="spender" type="address">
Optional. Spender address you intend to use for spending. If not provided, returns all permissions for the account.
</ParamField>

<ParamField body="provider" type="EIP1193Provider" required>
EIP-1193 compliant Ethereum provider instance. Get this from `sdk.getProvider()`.
<ParamField body="provider" type="EIP1193Provider">
Optional. EIP-1193 compliant Ethereum provider instance. Get this from `sdk.getProvider()`. If not provided, uses the default SDK provider.
</ParamField>

## Returns
Expand Down Expand Up @@ -65,7 +64,7 @@ Underlying permission fields.
</ResponseField>

<RequestExample>
```typescript Fetch permissions
```typescript Fetch permissions for specific spender
import { fetchPermissions } from "@base-org/account/spend-permission";
import { createBaseAccountSDK } from "@base-org/account";

Expand All @@ -75,12 +74,19 @@ const sdk = createBaseAccountSDK({
appChainIds: [84532],
});

// Fetch permissions for a specific spender
const permissions = await fetchPermissions({
account: "0xUserBaseAccountAddress",
chainId: 84532,
spender: "0xAppSpenderAddress",
provider: sdk.getProvider(),
});

// Fetch all permissions for the account (omitting spender)
const allPermissions = await fetchPermissions({
account: "0xUserBaseAccountAddress",
chainId: 84532,
});
```
</RequestExample>

Expand Down
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
"base-account/reference/spend-permission-utilities/requestSpendPermission",
"base-account/reference/spend-permission-utilities/prepareSpendCallData",
"base-account/reference/spend-permission-utilities/fetchPermissions",
"base-account/reference/spend-permission-utilities/fetchPermission",
"base-account/reference/spend-permission-utilities/getPermissionStatus",
"base-account/reference/spend-permission-utilities/requestRevoke",
"base-account/reference/spend-permission-utilities/prepareRevokeCallData",
Expand Down