Skip to content

Commit 8f47122

Browse files
committed
Add scheme_exact_atto.md
1 parent d52ef99 commit 8f47122

File tree

1 file changed

+268
-0
lines changed

1 file changed

+268
-0
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
# Scheme: `exact` on `Atto`
2+
3+
## Summary
4+
5+
The `exact` scheme on Atto uses a single native Atto `SEND` transaction to transfer a specific amount of the Atto asset from the payer to the resource server.
6+
7+
Atto is a feeless, account‑chain–style network optimized for high‑frequency micropayments. Instead of gas fees, senders perform a small proof‑of‑work (PoW) locally to prevent spam. This makes Atto a good fit for machine‑to‑machine use cases (AI agents, IoT devices) that need fast, cheap, and frequent payments.
8+
9+
This document describes how to:
10+
11+
* Express payment requirements for the `exact` scheme on Atto using the standard x402 `PaymentRequirements` structure.
12+
* Encode a signed Atto `SEND` transaction in an x402 `PaymentPayload`.
13+
* Verify and settle the payment on the Atto network.
14+
15+
16+
## PaymentRequirements
17+
18+
The `exact` scheme on Atto uses the **standard** x402 `PaymentRequirements` shape defined in the core specification. No additional top‑level fields are introduced; any scheme‑specific metadata must go inside the `extra` object.
19+
20+
For Atto, a `paymentRequirements` object inside the `accepts` array has the following semantics:
21+
22+
* `scheme` — MUST be `"exact"`.
23+
* `network` — Atto network identifier, for example:
24+
25+
* `"atto-live"` for mainnet.
26+
* `"atto-beta"` for testnet.
27+
* `"atto-dev"` for devnet.
28+
* `maxAmountRequired` — String representation of the required amount in **raw Atto units** (the smallest unit).
29+
* `asset` — Identifies the asset being paid. It SHOULD be the literal string `"atto"`.
30+
* `payTo` — Atto destination address for the payment. For example:
31+
* `"atto://abzekkyvhsos74rfeibubjifbjdzy3bi7habx5o3kt4ot2vcl5uhb2rcrn7hu"`.
32+
* `resource` — URL or identifier of the protected resource.
33+
* `description` — Human‑readable description of what is being purchased.
34+
* `mimeType` — MIME type of the resource response (e.g. `"application/json"`).
35+
* `outputSchema` (optional) — JSON schema describing the response body.
36+
* `maxTimeoutSeconds` — Maximum time the resource server is willing to wait for verification/settlement before considering the payment expired.
37+
38+
### Example PaymentRequirements Response
39+
40+
```json
41+
{
42+
"x402Version": 1,
43+
"accepts": [
44+
{
45+
"scheme": "exact",
46+
"network": "atto-live",
47+
"maxAmountRequired": "500000000",
48+
"asset": "atto",
49+
"payTo": "atto://abzekkyvhsos74rfeibubjifbjdzy3bi7habx5o3kt4ot2vcl5uhb2rcrn7hu",
50+
"resource": "https://api.example.com/premium-article",
51+
"description": "Access Premium Article (0.5 Atto)",
52+
"mimeType": "application/json",
53+
"outputSchema": null,
54+
"maxTimeoutSeconds": 60
55+
}
56+
]
57+
}
58+
```
59+
60+
In this example, the client must pay **exactly** `500000000` raw units of Atto to the `payTo` address on the `atto-live` network to access the resource.
61+
62+
## `X-PAYMENT` header payload
63+
64+
The `X-PAYMENT` header is a Base64‑encoded JSON `PaymentPayload` as defined in the x402 spec. For Atto, the `payload` field wraps a serialized Atto `SEND` transaction.
65+
66+
At a high level:
67+
68+
1. The client reads the `paymentRequirements` and determines the amount:
69+
70+
* `requiredAmount = paymentRequirements.maxAmountRequired`.
71+
2. The client constructs and signs an Atto `SEND` transaction that:
72+
73+
* Sends `requiredAmount` to `paymentRequirements.payTo`.
74+
* Uses the correct Atto network and protocol version.
75+
3. The client serializes the transaction to a 206‑byte binary form and encodes it as Base64.
76+
4. The client builds the x402 `PaymentPayload` JSON and Base64‑encodes that JSON to form the `X-PAYMENT` header.
77+
78+
### 1. Atto transaction payload
79+
80+
The inner Atto payment is a standard `SEND` transaction serialized into a 206‑byte structure:
81+
82+
| Segment | Field | Size (bytes) | Description |
83+
| ------- | --------------- | ------------ | ------------------------------------------------ |
84+
| Block | Type | 1 | Transaction type (`2` for `SEND`). |
85+
| | Network | 1 | Atto network identifier. |
86+
| | Version | 2 | Atto protocol version. |
87+
| | Algorithm | 1 | Signature algorithm identifier (e.g. `V1`). |
88+
| | Public Key | 32 | Sender’s public key. |
89+
| | Height | 8 | Account height / sequence number. |
90+
| | Balance | 8 | New balance after the transfer. |
91+
| | Timestamp | 8 | Transaction timestamp. |
92+
| | Previous | 32 | Hash of the previous block in the account chain. |
93+
| | Receiver Algo | 1 | Receiver’s algorithm identifier. |
94+
| | Receiver PubKey | 32 | Receiver’s public key (derived from `payTo`). |
95+
| | Amount | 8 | Amount being sent in raw Atto units. |
96+
| Auth | Signature | 64 | Ed25519 signature over the block contents. |
97+
| PoW | Work | 8 | Proof‑of‑work nonce. |
98+
| Total | | **206** | Full serialized Atto `SEND` transaction. |
99+
100+
The client serializes this structure and encodes it as a Base64 string:
101+
102+
```text
103+
base64Transaction = base64(206-byte-atto-send-transaction)
104+
```
105+
106+
### 2. PaymentPayload JSON
107+
108+
The decoded `X-PAYMENT` header MUST be a JSON object with this shape:
109+
110+
```json
111+
{
112+
"x402Version": 1,
113+
"scheme": "exact",
114+
"network": "atto-live",
115+
"payload": {
116+
"transaction": "<Base64-encoded 206-byte Atto SEND transaction>"
117+
}
118+
}
119+
```
120+
121+
* `scheme` must be `"exact"`.
122+
* `network` must match the selected `paymentRequirements.network`.
123+
* `payload.transaction` is the Base64 string produced in the previous step.
124+
125+
### 3. HTTP header encoding
126+
127+
On the wire, the client sends:
128+
129+
```http
130+
X-PAYMENT: <base64-encoded-PaymentPayload-JSON>
131+
```
132+
133+
Where `<base64-encoded-PaymentPayload-JSON>` is the Base64 encoding of the JSON object above. Header name is case‑insensitive, but `X-PAYMENT` is RECOMMENDED.
134+
135+
136+
## Verification
137+
138+
A facilitator or resource server verifying an Atto `exact` payment SHOULD perform at least the following steps:
139+
140+
1. **Decode `X-PAYMENT` header**
141+
142+
* Base64‑decode the header value to obtain the `PaymentPayload` JSON.
143+
* Validate:
144+
145+
* `x402Version === 1`
146+
* `scheme === "exact"`
147+
* `network` matches the `paymentRequirements.network`.
148+
149+
2. **Validate PaymentRequirements**
150+
151+
* Ensure `paymentRequirements.scheme === "exact"`.
152+
* Ensure `paymentRequirements.network` is an Atto network the verifier supports (e.g. `"atto-live"`).
153+
* Confirm `maxAmountRequired`, `asset`, and `payTo` are present and well‑formed.
154+
155+
3. **Decode Atto transaction**
156+
157+
* Read `payload.transaction` from the `PaymentPayload`.
158+
* Base64‑decode it to a 206‑byte buffer.
159+
* Parse fields according to the Atto `SEND` layout above and reject if:
160+
161+
* Length ≠ 206 bytes.
162+
* The `Type` field is not `SEND`.
163+
* Network / version fields are not recognized.
164+
165+
4. **Signature verification**
166+
167+
* Recompute the block hash per Atto’s rules.
168+
* Verify the Ed25519 signature using the `Public Key` field.
169+
* Reject if signature verification fails.
170+
171+
5. **Proof‑of‑Work verification**
172+
173+
* Derive the PoW target/difficulty from network configuration.
174+
* Verify the `Work` field meets the required difficulty.
175+
* Reject if PoW is insufficient.
176+
177+
6. **Replay protection**
178+
179+
* Check that:
180+
* `Height` is strictly greater than the last confirmed height for the account.
181+
* `Timestamp` is within an acceptable window (to prevent very old or far‑future transactions).
182+
* `Hash` does NOT exist in a persistent store (e.g., database).
183+
* These checks MUST take place, node transaction publishing is idempotent!
184+
185+
7. **Recipient & asset checks**
186+
187+
* Derive the expected receiver public key from `paymentRequirements.payTo` using Atto address rules.
188+
* Confirm the transaction’s `Receiver PubKey` matches this derived key.
189+
* Confirm `asset` in `paymentRequirements` is `"atto"` (or another Atto asset the verifier explicitly supports).
190+
191+
8. **Amount validation**
192+
193+
* Interpret the transaction’s `Amount` field as an unsigned long in raw Atto units (`txAmount`).
194+
* Interpret `paymentRequirements.maxAmountRequired` as `requiredAmount`.
195+
* Check that `txAmount == requiredAmount`.
196+
197+
If all checks pass, the payment is valid for the selected `paymentRequirements`.
198+
199+
## Settlement
200+
201+
Once a payment has been verified:
202+
203+
1. **Broadcast**
204+
205+
* The facilitator or resource server submits the validated `SEND` transaction to an Atto node.
206+
207+
2. **Consensus**
208+
209+
* The transaction is incorporated into Atto’s consensus (e.g., via Open Representative Voting).
210+
211+
3. **Finality**
212+
213+
* After confirmation, the `SEND` is final and cannot be reversed. Atto is designed for sub‑second deterministic finality.
214+
215+
4. **Receiving wallet handling (optional)**
216+
217+
* Atto requires a corresponding `RECEIVE` block to update the receiver’s balance.
218+
* From the perspective of x402 and this scheme, the payment is considered **settled** once the `SEND` block is confirmed on-chain; a later `RECEIVE` block is required to make the amount spendable, but is optional from the payment perspective.
219+
220+
## Appendix: Example
221+
222+
Below is a complete example showing a client paying for a JSON API response with Atto using the `exact` scheme.
223+
224+
### Example PaymentRequirementsResponse
225+
226+
```json
227+
{
228+
"x402Version": 1,
229+
"error": "X-PAYMENT header is required",
230+
"accepts": [
231+
{
232+
"scheme": "exact",
233+
"network": "atto-live",
234+
"maxAmountRequired": "500000000",
235+
"asset": "atto",
236+
"payTo": "atto://aabaeaqcaibaeaqcaibaeaqcaibaeaqcaibaeaqcaibaeaqcaibaevjhdj47s",
237+
"resource": "https://api.example.com/premium-article",
238+
"description": "Access Premium Article (0.5 Atto)",
239+
"mimeType": "application/json",
240+
"outputSchema": null,
241+
"maxTimeoutSeconds": 60,
242+
"extra": null
243+
}
244+
]
245+
}
246+
```
247+
248+
### Example PaymentPayload (decoded `X-PAYMENT`)
249+
250+
```json
251+
{
252+
"x402Version": 1,
253+
"scheme": "exact",
254+
"network": "atto-live",
255+
"payload": {
256+
"transaction": "BASE64_ENCODED_ATTO_SEND_TX=="
257+
}
258+
}
259+
```
260+
261+
The client sends:
262+
263+
```http
264+
X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYXR0by1saXZlIiwicGF5bG9hZCI6eyJ0cmFuc2FjdGlvbiI6IkJBU0U2NF9FTkNPREVERF9BVFRPX1NFTkRfVFhfLi4uPSJ9fQ==
265+
```
266+
267+
Where the header value is the Base64 encoding of the `PaymentPayload` JSON above.
268+

0 commit comments

Comments
 (0)