You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: specs/schemes/exact/scheme_exact_svm.md
+46-10Lines changed: 46 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,24 +10,23 @@ This scheme facilitates payments of a specific amount of an SPL token on the Sol
10
10
11
11
## Protocol Flow
12
12
13
-
The protocol flow for `exact` on Solana is client-driven.
13
+
The protocol flow for `exact` on Solana is client-driven.
14
14
15
15
1.**Client** makes an HTTP request to a **Resource Server**.
16
16
2.**Resource Server** responds with a `402 Payment Required` status. The response body contains the `paymentRequirements` for the `exact` scheme. Critically, the `extra` field in the requirements contains a **feePayer** which is the public address of the identity that will pay the fee for the transaction. This will typically be the facilitator.
17
-
3.**Client** creates a transaction that contains a transfer of an asset to the resource server's wallet address for a specified amount.
17
+
3.**Client** creates a transaction that contains a transfer of an asset to the resource server's wallet address for a specified amount.
18
18
4.**Client** signs the transaction with their wallet. This results in a partially signed transaction (since the signature of the facilitator that will sponsor the transaction is still missing).
19
19
5.**Client** serializes the partially signed transaction and encodes it as a Base64 string.
20
20
6.**Client** sends a new HTTP request to the resource server with the `X-PAYMENT` header containing the Base64-encoded partially-signed transaction payload.
21
21
7.**Resource Server** receives the request and forwards the `X-PAYMENT` header and `paymentRequirements` to a **Facilitator Server's**`/verify` endpoint.
22
22
8.**Facilitator** decodes and deserializes the proposed transaction.
23
23
9.**Facilitator** inspects the transaction to ensure it is valid and only contains the expected payment instruction.
24
-
10.**Facilitator** returns a response to the **Resource Server** verifying the **client** transaction.
24
+
10.**Facilitator** returns a response to the **Resource Server** verifying the **client** transaction.
25
25
11.**Resource Server**, upon successful verification, forwards the payload to the facilitator's `/settle` endpoint.
26
26
12.**Facilitator Server** provides its final signature as the `feePayer` and submits the now fully-signed transaction to the Solana network.
27
27
13. Upon successful on-chain settlement, the **Facilitator Server** responds to the **Resource Server**.
28
28
14.**Resource Server** grants the **Client** access to the resource in its response.
29
29
30
-
31
30
## `PaymentRequirements` for `exact`
32
31
33
32
In addition to the standard x402 `PaymentRequirements` fields, the `exact` scheme on Solana requires the following inside the `extra` field:
@@ -50,13 +49,12 @@ In addition to the standard x402 `PaymentRequirements` fields, the `exact` schem
50
49
}
51
50
```
52
51
53
-
-`asset`: The public key of the token mint.
54
-
-`extra.feePayer`: The public key of the account that will pay for the transaction fees. This is typically the facilitator's public key.
55
-
52
+
-`asset`: The public key of the token mint.
53
+
-`extra.feePayer`: The public key of the account that will pay for the transaction fees. This is typically the facilitator's public key.
56
54
57
55
## `X-PAYMENT` Header Payload
58
56
59
-
The `X-PAYMENT` header is base64 encoded and sent in the request from the client to the resource server when paying for a resource.
57
+
The `X-PAYMENT` header is base64 encoded and sent in the request from the client to the resource server when paying for a resource.
60
58
61
59
Once decoded, the `X-PAYMENT` header is a JSON string with the following properties:
62
60
@@ -73,7 +71,6 @@ Once decoded, the `X-PAYMENT` header is a JSON string with the following propert
73
71
74
72
The `payload` field contains the base64-encoded, serialized, **partially-signed** versioned Solana transaction.
75
73
76
-
77
74
## `X-PAYMENT-RESPONSE` Header Payload
78
75
79
76
The `X-PAYMENT-RESPONSE` header is base64 encoded and returned to the client from the resource server.
@@ -87,4 +84,43 @@ Once decoded, the `X-PAYMENT-RESPONSE` is a JSON string with the following prope
87
84
"network": "solana"| "solana-devnet",
88
85
"payer": "base58 encoded public address of the transaction fee payer"
89
86
}
90
-
```
87
+
```
88
+
89
+
## Facilitator Verification Rules (MUST)
90
+
91
+
A facilitator verifying an `exact`-scheme SVM payment MUST enforce all of the following checks before sponsoring and signing the transaction:
92
+
93
+
1. Instruction layout
94
+
95
+
- The decompiled transaction MUST contain either 3 or 4 instructions in this exact order:
96
+
1. Compute Budget: Set Compute Unit Limit
97
+
2. Compute Budget: Set Compute Unit Price
98
+
3. Optional: Associated Token Account Create (when the destination ATA does not yet exist)
99
+
4. SPL Token or Token-2022 TransferChecked
100
+
101
+
2. Fee payer (facilitator) safety
102
+
103
+
- The configured fee payer address MUST NOT appear in the `accounts` of any instruction in the transaction.
104
+
- The fee payer MUST NOT be the `authority` for the TransferChecked instruction.
105
+
- The fee payer MUST NOT be the `source` of the transferred funds.
106
+
107
+
3. Compute budget validity
108
+
109
+
- The program for instructions (1) and (2) MUST be `ComputeBudget` with the correct discriminators (2 = SetLimit, 3 = SetPrice).
110
+
- The compute unit price MUST be bounded to prevent gas abuse. The reference implementation enforces ≤ 5 lamports per compute unit.
111
+
112
+
4. Transfer intent and destination
113
+
114
+
- The TransferChecked program MUST be either `spl-token` or `token-2022`.
115
+
- Destination MUST equal the Associated Token Account PDA for `(owner = payTo, mint = asset)` under the selected token program.
116
+
117
+
5. Account existence
118
+
119
+
- The `source` ATA MUST exist.
120
+
- The destination ATA MUST exist if and only if the Create ATA instruction is NOT present in the transaction. If Create ATA is present, the destination ATA MAY be absent prior to execution.
121
+
122
+
6. Amount
123
+
124
+
- The `amount` in TransferChecked MUST equal `maxAmountRequired` exactly.
125
+
126
+
These checks are security-critical to ensure the fee payer cannot be tricked into transferring their own funds or sponsoring unintended actions. Implementations MAY introduce stricter limits (e.g., lower compute price caps) but MUST NOT relax the above constraints.
Copy file name to clipboardExpand all lines: specs/x402-specification.md
+13-1Lines changed: 13 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -218,7 +218,7 @@ Each scheme defines:
218
218
- Settlement and validation procedures
219
219
- Scheme-specific requirements in the `extra` field of `PaymentRequirements`
220
220
221
-
**6.1 Exact Scheme**
221
+
**6.1 Exact Scheme (EVM overview)**
222
222
223
223
The "exact" scheme uses EIP-3009 (Transfer with Authorization) to enable secure, gasless transfers of specific amounts of ERC-20 tokens.
224
224
@@ -254,6 +254,18 @@ The facilitator performs the following verification steps:
254
254
255
255
Settlement is performed by calling the `transferWithAuthorization` function on the ERC-20 contract with the signature and authorization parameters provided in the payment payload.
256
256
257
+
**6.2 Exact Scheme (SVM overview)**
258
+
259
+
For Solana (SVM), the `exact` scheme is implemented using `TransferChecked` for SPL tokens. Critical verification requirements include:
260
+
261
+
- Enforcing a strict instruction layout (Compute Unit Limit, Compute Unit Price, optional ATA Create, TransferChecked)
262
+
- Ensuring the facilitator fee payer does not appear in any instruction accounts and is not the transfer `authority` or `source`
263
+
- Bounding compute unit price to mitigate gas abuse
264
+
- Verifying the destination ATA matches the `payTo`/`asset` PDA and account existence rules
265
+
- Requiring the transfer `amount` to exactly equal `maxAmountRequired`
266
+
267
+
Full SVM details are specified in `specs/schemes/exact/scheme_exact_svm.md`.
268
+
257
269
**7. Facilitator Interface**
258
270
259
271
The facilitator provides HTTP REST APIs for payment verification and settlement. This allows resource servers to delegate blockchain operations to trusted third parties or host the endpoints themselves. Note that while the core x402 protocol is transport-agnostic, facilitator APIs are currently standardized as HTTP endpoints.
0 commit comments