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
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ export function AccountAbstractionSettingsPage(
you build your own rules.{" "}
<UnderlineLink
className="text-primary-500"
href="https://portal.thirdweb.com/wallets/smart-wallet/sponsorship-rules#setting-up-a-server-verifier"
href="https://portal.thirdweb.com/transactions/policies#server-verifier"
rel="noopener noreferrer"
target="_blank"
>
Expand Down
2 changes: 1 addition & 1 deletion apps/portal/src/app/payments/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const sidebar: SideBar = {
},
{
href: `${paymentsSlug}/x402/facilitator`,
name: "Facilitator API",
name: "Facilitator",
},
],
name: "x402",
Expand Down
40 changes: 6 additions & 34 deletions apps/portal/src/app/payments/x402/client/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,46 +68,18 @@ The client library wraps the native `fetch` API and handles:
<TabsContent value="http">
## Prepare Payment

Create a signed payment header from the authenticated user to include in your API request:
Fetch any x402-compatible API and automatically handle payment flows when APIs return a `402 Payment Required` response using the authenticated wallet.

### Making the Paid Request

After preparing the payment, include it in your API request:
Only requires passing a 'url' and 'from' query parameters with the authenticated wallet address (server or user wallet) to complete the payment.

```bash
# First, make the initial request to get payment requirements
curl -X GET https://api.example.com/paid-endpoint

# Response will be 402 Payment Required with payment details
# {
# "x402Version": 1,
# "accepts": [...payment requirements...],
# "error": "Payment required"
# }

# Select one of the payment methods, and sign the payment authorization using the API
curl -X POST https://api.thirdweb.com/v1/payments/x402/prepare \
curl -X POST https://api.thirdweb.com/v1/payments/x402/fetch?url=https://api.example.com/premium&from=0x1234... \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <user-access-token>" \
-d '{
"from": "0x1234...",
"paymentRequirements": { ... }
}'

# Response will contain the signed payment header
# {
# "paymentPayload": { ... },
# "paymentHeader": "..." // base64 encoded payment header
# }

# Finally, make the request with the payment header
curl -X GET https://api.example.com/paid-endpoint \
-H "X-PAYMENT: <base64-encoded-payment>"
-H "Authorization: Bearer <user-wallet-token>" \
-d '{ ... }' # request body passed through to the url called.
```

## API Reference

<OpenApiEndpoint path="/v1/payments/x402/prepare" method="POST" />
<OpenApiEndpoint path="/v1/payments/x402/fetch" method="POST" />

</TabsContent>
</Tabs>
9 changes: 8 additions & 1 deletion apps/portal/src/app/payments/x402/facilitator/page.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Tabs, TabsList, TabsTrigger, TabsContent, OpenApiEndpoint, Callout } from "@doc";
import { TypeScriptIcon, EngineIcon } from "@/icons";

# Facilitator API
# Facilitator

The facilitator is a service that handles verifying and submitting x402 payments. It uses your own [server wallet](/wallets/server) and leverages EIP-7702 to submit transactions gaslessly.

Expand All @@ -16,6 +16,13 @@ The thirdweb facilitator is compatible with any x402 backend and middleware libr

You can view all transactions processed by your facilitator in your project dashboard.

## Chain and token support

Our facilitator supports payments on any EVM chain, as long as the payment token supports either:

- ERC-2612 permit (most ERC20 tokens)
- ERC-3009 sign with authorization (USDC on all chains)

<Tabs defaultValue="typescript">
<TabsList>
<TabsTrigger value="typescript" className="flex items-center [&>p]:mb-0">
Expand Down
4 changes: 4 additions & 0 deletions apps/portal/src/app/payments/x402/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const fetchWithPay = wrapFetchWithPayment(fetch, client, wallet);
const response = await fetchWithPay('https://api.example.com/paid-endpoint');
```

You can also use the thirdweb API to fetch any x402 compatible endpoint and pay for it with the authenticated wallet. See the [client side docs](/payments/x402/client) for more details.

## Server Side

To make your API calls payable, use the `settlePayment` function in a middleware or endpoint:
Expand Down Expand Up @@ -77,6 +79,8 @@ export async function GET(request: Request) {
}
```

You can also create middlewares to handle payment for multiple endpoints, see the [server side docs](/payments/x402/server) for more details. The [facilitator](/payments/x402/facilitator) handles settling the payment onchain using your own server wallet.

## Going Further

<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
Expand Down
63 changes: 63 additions & 0 deletions apps/portal/src/app/transactions/policies/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Gas Sponsorship Policies

Sponsorship policies are a way to control the execution of sponsored transactions on your account.

You can use them to:

- Set global spend limits.
- Restrict sponsorship to a particular chain.
- Restrict sponsorship to a particular contract.
- Allow/Disallow specific wallets
- Setup your own server verifier.

These policies can be set from your project dashboard, under project > account abstraction > settings.

## Server Verifier

The most flexible and powerful way to control the execution of sponsored transactions is to setup your own server verifier.

In the project dashboard, under project > account abstraction > settings, setup your backend URL and any additional headers you need to pass to the verifier.

On every user transaction, your backend will be called with the transaction data and the user's wallet address, your endpoint should return a boolean indicating whether the transaction should be sponsored.

### Backend endpoint specification:

Your backend will be called with the following request:

```http
POST https://your-backend-url/verify-transaction
Content-Type: application/json
Referer: "https://api.thirdweb.com",
# additional custom headers

# request body
{
"clientId": string;
"chainId": number;
"userOp": {
sender: string;
targets: string[];
gasLimit: string;
gasPrice: string;
data?: {
targets: string[];
callDatas: string[];
values: string[];
};
}
}
```

Your backend should process the request, apply your own policy logic based on the request data and return the following JSON response:

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
"isAllowed": boolean;
"reason"?: string;
}
```

The `isAllowed` field indicates whether the transaction should be sponsored or not. `reason` is an optional field that can be used to provide a reason for the decision.
4 changes: 4 additions & 0 deletions apps/portal/src/app/transactions/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export const sidebar: SideBar = {
href: `${transactionsSlug}/session-keys`,
name: "Session Keys",
},
{
href: `${transactionsSlug}/policies`,
name: "Sponsorship Policies",
},
],
},
{ separator: true },
Expand Down
Loading