@springmint/x402-payment 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/SKILL.md +159 -0
- package/dist/cli/254.index.js +222 -0
- package/dist/cli/743.index.js +102795 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/client.d.ts +62 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/config.d.ts +13 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/package.json +3 -0
- package/dist/cli/x402_invoke.js +643 -0
- package/dist/lib/client.d.ts +63 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +108 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +110 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Springmint
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# @springmint/x402-payment
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.npmjs.com/package/@springmint/x402-payment)
|
|
5
|
+
|
|
6
|
+
Add **pay-per-use** capability to your AI agent skills and Node.js applications with the [x402 protocol](https://x402.org).
|
|
7
|
+
|
|
8
|
+
## What is x402?
|
|
9
|
+
|
|
10
|
+
x402 is a payment protocol built on HTTP status code **402 Payment Required**. When you call an x402-enabled API without paying, the server returns a `402` response with payment requirements. This SDK handles the entire payment flow automatically:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Your App Paid API Server
|
|
14
|
+
│ │
|
|
15
|
+
│──── GET /api/data ─────────────────>│
|
|
16
|
+
│<─── 402 Payment Required ───────────│ (includes: price, token, chain, payTo)
|
|
17
|
+
│ │
|
|
18
|
+
│ [SDK auto-signs & pays on-chain] │
|
|
19
|
+
│ │
|
|
20
|
+
│──── GET /api/data + payment proof ─>│
|
|
21
|
+
│<─── 200 OK + data ─────────────────│
|
|
22
|
+
└─────────────────────────────────────┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**You don't need to handle any of this yourself.** Just use `createX402FetchClient()` and call your API like normal — the SDK intercepts 402 responses, pays on-chain, and retries automatically.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @springmint/x402-payment
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Wallet Configuration
|
|
34
|
+
|
|
35
|
+
The SDK needs a private key to sign on-chain payments. It searches in this order:
|
|
36
|
+
|
|
37
|
+
| Priority | Source | Keys |
|
|
38
|
+
|----------|--------|------|
|
|
39
|
+
| 1 | Environment variables | `TRON_PRIVATE_KEY`, `EVM_PRIVATE_KEY`, `ETH_PRIVATE_KEY`, `PRIVATE_KEY` |
|
|
40
|
+
| 2 | Project config | `./x402-config.json` |
|
|
41
|
+
| 3 | User config | `~/.x402-config.json` |
|
|
42
|
+
| 4 | mcporter config | `~/.mcporter/mcporter.json` |
|
|
43
|
+
|
|
44
|
+
Quickest way:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# For EVM chains (BSC, Ethereum, Base, etc.)
|
|
48
|
+
export EVM_PRIVATE_KEY=your_private_key_hex
|
|
49
|
+
|
|
50
|
+
# For TRON
|
|
51
|
+
export TRON_PRIVATE_KEY=your_private_key_hex
|
|
52
|
+
|
|
53
|
+
# Verify
|
|
54
|
+
npx @springmint/x402-payment --check
|
|
55
|
+
# [OK] EVM Wallet: 0x1234...abcd
|
|
56
|
+
# [OK] TRON Wallet: TXyz...
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or use a config file:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
// x402-config.json
|
|
63
|
+
{
|
|
64
|
+
"evm_private_key": "your_evm_key",
|
|
65
|
+
"tron_private_key": "your_tron_key",
|
|
66
|
+
"tron_grid_api_key": "your_trongrid_key"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
### As a Library
|
|
73
|
+
|
|
74
|
+
Import the SDK in your skill or Node.js application to call paid APIs:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { createX402FetchClient } from "@springmint/x402-payment";
|
|
78
|
+
|
|
79
|
+
// Create a client — keys are auto-discovered
|
|
80
|
+
const client = await createX402FetchClient();
|
|
81
|
+
|
|
82
|
+
// Use it like a normal fetch — 402 payments are handled automatically
|
|
83
|
+
const response = await client.request(
|
|
84
|
+
"https://www.cpbox.io/api/rpc/x402/batch-balance",
|
|
85
|
+
{
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: { "Content-Type": "application/json" },
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
chain: "ethereum",
|
|
90
|
+
token: "",
|
|
91
|
+
addresses: ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"],
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const data = await response.json();
|
|
97
|
+
console.log(data);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
For the common pattern of calling an x402 agent's entrypoint, use the high-level helper:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { invokeEndpoint } from "@springmint/x402-payment";
|
|
104
|
+
|
|
105
|
+
// Entrypoint mode — automatically calls POST {url}/entrypoints/{name}/invoke
|
|
106
|
+
const result = await invokeEndpoint("https://api.example.com", {
|
|
107
|
+
entrypoint: "chat",
|
|
108
|
+
input: { prompt: "hello" },
|
|
109
|
+
});
|
|
110
|
+
console.log(result.status); // 200
|
|
111
|
+
console.log(result.body); // { response: "..." }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
You can also pass keys explicitly instead of relying on auto-discovery:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const client = await createX402FetchClient({
|
|
118
|
+
evmPrivateKey: "0x...",
|
|
119
|
+
tronPrivateKey: "...",
|
|
120
|
+
silent: true, // suppress [x402] log output
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### As a CLI
|
|
125
|
+
|
|
126
|
+
AI agents and command-line users can invoke paid APIs directly:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Call an agent's entrypoint
|
|
130
|
+
npx @springmint/x402-payment \
|
|
131
|
+
--url https://api.example.com \
|
|
132
|
+
--entrypoint chat \
|
|
133
|
+
--input '{"prompt": "hello"}'
|
|
134
|
+
|
|
135
|
+
# Call a URL directly
|
|
136
|
+
npx @springmint/x402-payment \
|
|
137
|
+
--url https://www.cpbox.io/api/rpc/x402/batch-balance \
|
|
138
|
+
--method POST \
|
|
139
|
+
--input '{"chain":"ethereum","token":"","addresses":["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"]}'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### CLI Options
|
|
143
|
+
|
|
144
|
+
| Option | Required | Description |
|
|
145
|
+
|--------|----------|-------------|
|
|
146
|
+
| `--url` | Yes | Target API endpoint URL |
|
|
147
|
+
| `--entrypoint` | No | Entrypoint name (constructs `/entrypoints/{name}/invoke` URL, forces POST) |
|
|
148
|
+
| `--input` | No | JSON request body |
|
|
149
|
+
| `--method` | No | HTTP method (default: GET for direct, POST for entrypoint) |
|
|
150
|
+
| `--check` | No | Verify wallet configuration and exit |
|
|
151
|
+
|
|
152
|
+
Output goes to **stdout** as JSON. Logs go to **stderr**.
|
|
153
|
+
|
|
154
|
+
## API Reference
|
|
155
|
+
|
|
156
|
+
### `createX402FetchClient(options?)`
|
|
157
|
+
|
|
158
|
+
Create a fetch client that automatically handles 402 payment flows.
|
|
159
|
+
|
|
160
|
+
Returns an `X402FetchClient` instance. Use `client.request(url, init)` to make requests — the same interface as `fetch()`.
|
|
161
|
+
|
|
162
|
+
### `createX402Client(options?)`
|
|
163
|
+
|
|
164
|
+
Create the underlying `X402Client` with all payment mechanisms registered. Use this when you need lower-level control over payment mechanisms and policies.
|
|
165
|
+
|
|
166
|
+
### `invokeEndpoint(url, options?)`
|
|
167
|
+
|
|
168
|
+
High-level helper that creates a client, sends the request, and returns the parsed response.
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
const result = await invokeEndpoint(url, {
|
|
172
|
+
entrypoint?: string, // entrypoint name (switches to invoke mode)
|
|
173
|
+
input?: any, // request body (auto-serialized to JSON)
|
|
174
|
+
method?: string, // HTTP method
|
|
175
|
+
clientOptions?: { // passed to createX402FetchClient
|
|
176
|
+
tronPrivateKey?: string,
|
|
177
|
+
evmPrivateKey?: string,
|
|
178
|
+
tronGridApiKey?: string,
|
|
179
|
+
silent?: boolean,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
// result: { status: number, headers: Record<string, string>, body: any }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `findPrivateKey(type: "tron" | "evm")`
|
|
186
|
+
|
|
187
|
+
Search for a private key following the lookup order described in [Wallet Configuration](#wallet-configuration).
|
|
188
|
+
|
|
189
|
+
### `findApiKey()`
|
|
190
|
+
|
|
191
|
+
Search for TronGrid API key using the same lookup order.
|
|
192
|
+
|
|
193
|
+
## Supported Networks & Tokens
|
|
194
|
+
|
|
195
|
+
| Chain | Network | Tokens | Example USDT Contract |
|
|
196
|
+
|----------|---------------|------------------|-----------------------|
|
|
197
|
+
| **TRON** | `mainnet` | USDT, USDD | `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` |
|
|
198
|
+
| **TRON** | `nile` | USDT, USDD | `TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf` |
|
|
199
|
+
| **BSC** | `bsc` | USDT, USDC | `0x55d398326f99059fF775485246999027B3197955` |
|
|
200
|
+
| **BSC** | `bsc-testnet` | USDT, USDC, DHLU | `0x337610d27c682E347C9cD60BD4b3b107C9d34dDd` |
|
|
201
|
+
|
|
202
|
+
Both **direct transfer** and **permit-based** payment mechanisms are supported on all chains.
|
|
203
|
+
|
|
204
|
+
## For AI Agent Skill Developers
|
|
205
|
+
|
|
206
|
+
If you're building a skill that calls a paid API, add this package as a dependency:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm install @springmint/x402-payment
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Then in your skill's code:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import { createX402FetchClient } from "@springmint/x402-payment";
|
|
216
|
+
|
|
217
|
+
const client = await createX402FetchClient();
|
|
218
|
+
const res = await client.request("https://your-paid-api.com/endpoint", {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: { "Content-Type": "application/json" },
|
|
221
|
+
body: JSON.stringify({ /* your request */ }),
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
And in your skill's `SKILL.md`, declare the dependency:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
dependencies:
|
|
229
|
+
- x402-payment
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
See [cpbox-skills/batch-balance](https://github.com/springmint/cpbox-skills) for a real-world example.
|
|
233
|
+
|
|
234
|
+
## Security
|
|
235
|
+
|
|
236
|
+
- Private keys are **never** output to stdout or logs
|
|
237
|
+
- Error messages are automatically sanitized to redact any leaked key material
|
|
238
|
+
- `console.log` is redirected to `stderr` in CLI mode to prevent library output from polluting your data pipeline
|
|
239
|
+
- Always use testnet (`nile`, `bsc-testnet`) for development
|
|
240
|
+
|
|
241
|
+
## Project Structure
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
x402-payment/
|
|
245
|
+
├── README.md
|
|
246
|
+
├── LICENSE
|
|
247
|
+
├── package.json # @springmint/x402-payment
|
|
248
|
+
├── SKILL.md # AI Agent instruction file
|
|
249
|
+
├── src/
|
|
250
|
+
│ ├── index.ts # Library exports
|
|
251
|
+
│ ├── config.ts # Key discovery
|
|
252
|
+
│ ├── client.ts # Client factory & invokeEndpoint
|
|
253
|
+
│ └── cli.ts # CLI entry point
|
|
254
|
+
└── dist/
|
|
255
|
+
├── lib/ # Library build (import)
|
|
256
|
+
└── cli/ # CLI build (npx / bin)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
[MIT](LICENSE)
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: x402-payment
|
|
3
|
+
description: "Pay for x402-enabled Agent endpoints using ERC20 tokens (USDT/USDC) on EVM or TRC20 tokens (USDT/USDD) on TRON."
|
|
4
|
+
user-invokable: true
|
|
5
|
+
argument-hint: "url(required): Base URL of the agent (v2) or full URL (v1/Discovery); entrypoint(optional): Entrypoint name to invoke (e.g., 'chat', 'search'); input(optional): Input object to send to the entrypoint; method(optional): HTTP method (GET/POST), default POST(v2)/GET(Direct)"
|
|
6
|
+
compatibility:
|
|
7
|
+
tools:
|
|
8
|
+
- x402_invoke
|
|
9
|
+
metadata:
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
author: cppay.finance
|
|
12
|
+
homepage: https://x402.org
|
|
13
|
+
tags: [crypto, payments, x402, agents, api, usdt, usdd, usdc, tron, ethereum, evm, erc20, trc20, sdk]
|
|
14
|
+
requires_tools: [x402_invoke]
|
|
15
|
+
tool_implementation_mapping:
|
|
16
|
+
x402_invoke: dist/cli/x402_invoke.js
|
|
17
|
+
dependencies:
|
|
18
|
+
- mcp-server-tron
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# x402 Payment Skill
|
|
22
|
+
|
|
23
|
+
Invoke x402-enabled AI agent endpoints with automatic token payments on both TRON (TRC20) and EVM-compatible (ERC20) chains.
|
|
24
|
+
|
|
25
|
+
## Overview
|
|
26
|
+
|
|
27
|
+
The `x402-payment` package provides two ways to handle x402 payments:
|
|
28
|
+
|
|
29
|
+
1. **As a library** — other skills and Node.js apps `import` it to gain x402 payment capability
|
|
30
|
+
2. **As a CLI tool** — AI agents invoke `x402_invoke` directly from the command line
|
|
31
|
+
|
|
32
|
+
When an HTTP `402 Payment Required` response is received, the package automatically handles negotiation, signing, and execution of the on-chain payment.
|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
|
|
36
|
+
- **Wallet Configuration**:
|
|
37
|
+
- **TRON**: Set `TRON_PRIVATE_KEY` for TRC20 payments (USDT/USDD).
|
|
38
|
+
- **EVM**: Set `EVM_PRIVATE_KEY` or `ETH_PRIVATE_KEY` for ERC20 payments (USDT/USDC).
|
|
39
|
+
- The skill also searches for keys in `x402-config.json` and `~/.mcporter/mcporter.json`.
|
|
40
|
+
- **TronGrid API Key**: Required for **Mainnet** to avoid rate limits (`TRON_GRID_API_KEY`).
|
|
41
|
+
|
|
42
|
+
## Usage as a Library
|
|
43
|
+
|
|
44
|
+
Other skills can add x402 payment capability by importing this package:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @springmint/x402-payment
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createX402FetchClient, invokeEndpoint } from "@springmint/x402-payment";
|
|
52
|
+
|
|
53
|
+
// Option 1: Fetch client with automatic 402 handling
|
|
54
|
+
const client = await createX402FetchClient();
|
|
55
|
+
const response = await client.request("https://paid-api.com/endpoint", {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
|
+
body: JSON.stringify({ query: "hello" }),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Option 2: High-level invoke helper
|
|
62
|
+
const result = await invokeEndpoint("https://api.example.com", {
|
|
63
|
+
entrypoint: "chat",
|
|
64
|
+
input: { prompt: "hello" },
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Library API
|
|
69
|
+
|
|
70
|
+
| Function | Description |
|
|
71
|
+
|----------|-------------|
|
|
72
|
+
| `createX402FetchClient(options?)` | Create a fetch client with automatic 402 payment handling |
|
|
73
|
+
| `createX402Client(options?)` | Create the underlying X402Client with payment mechanisms |
|
|
74
|
+
| `invokeEndpoint(url, options?)` | High-level: create client, request, return parsed response |
|
|
75
|
+
| `findPrivateKey(type)` | Discover private key from env/config files |
|
|
76
|
+
| `findApiKey()` | Discover TronGrid API key |
|
|
77
|
+
|
|
78
|
+
## Usage as CLI (AI Agent)
|
|
79
|
+
|
|
80
|
+
### 1. Verification
|
|
81
|
+
|
|
82
|
+
Before making payments, verify your wallet status:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx @springmint/x402-payment --check
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 2. Invoking an Agent (v2)
|
|
89
|
+
|
|
90
|
+
Most modern x402 agents use the v2 "invoke" pattern:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx @springmint/x402-payment \
|
|
94
|
+
--url https://api.example.com \
|
|
95
|
+
--entrypoint chat \
|
|
96
|
+
--input '{"prompt": "Your query here"}'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Agent Discovery (Direct)
|
|
100
|
+
|
|
101
|
+
- **Manifest**: Fetch agent metadata.
|
|
102
|
+
```bash
|
|
103
|
+
npx @springmint/x402-payment --url https://api.example.com/.well-known/agent.json
|
|
104
|
+
```
|
|
105
|
+
- **List Entrypoints**: List available functions.
|
|
106
|
+
```bash
|
|
107
|
+
npx @springmint/x402-payment --url https://api.example.com/entrypoints
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 4. Cross-Chain Support
|
|
111
|
+
|
|
112
|
+
The SDK automatically detects the required chain from the server's 402 response. No need to specify the network manually — it matches the payment requirements with registered mechanisms.
|
|
113
|
+
|
|
114
|
+
- **TRON (TRC20)**: Requires `TRON_PRIVATE_KEY`
|
|
115
|
+
- **EVM (ERC20)**: Requires `EVM_PRIVATE_KEY` or `ETH_PRIVATE_KEY`
|
|
116
|
+
|
|
117
|
+
## Supported Networks & Tokens
|
|
118
|
+
|
|
119
|
+
| Chain | Network Name | Common Tokens | USDT Contract |
|
|
120
|
+
| -------- | ------------- | ---------------- | -------------------------------------------- |
|
|
121
|
+
| **TRON** | `mainnet` | USDT, USDD | `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` |
|
|
122
|
+
| **TRON** | `nile` | USDT, USDD | `TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf` |
|
|
123
|
+
| **BSC** | `bsc` | USDT, USDC | `0x55d398326f99059fF775485246999027B3197955` |
|
|
124
|
+
| **BSC** | `bsc-testnet` | USDT, USDC, DHLU | `0x337610d27c682E347C9cD60BD4b3b107C9d34dDd` |
|
|
125
|
+
|
|
126
|
+
## Security Considerations & Rules
|
|
127
|
+
|
|
128
|
+
> [!CAUTION]
|
|
129
|
+
> **Private Key Safety**: NEVER output your private keys to the logs or console. The package loads keys from environment variables internally.
|
|
130
|
+
|
|
131
|
+
### Agent Security Rules:
|
|
132
|
+
|
|
133
|
+
- **No Private Key Output**: The Agent MUST NOT print, echo, or output any private key to the dialogue context.
|
|
134
|
+
- **Internal Loading Only**: Rely on the tool to load keys internally.
|
|
135
|
+
- **No Export Commands**: DO NOT execute shell commands containing the private key as a literal string.
|
|
136
|
+
- **Silent Environment Checks**: Use `[[ -n $TRON_PRIVATE_KEY ]] && echo "Configured" || echo "Missing"` to verify configuration without leaking secrets.
|
|
137
|
+
- **Use the Check Tool**: Use `x402-payment --check` to safely verify addresses.
|
|
138
|
+
|
|
139
|
+
## Binary and Image Handling
|
|
140
|
+
|
|
141
|
+
If the endpoint returns an image or binary data (CLI mode only):
|
|
142
|
+
|
|
143
|
+
1. The data is saved to a temporary file (e.g., `/tmp/x402_image_...`).
|
|
144
|
+
2. The tool returns JSON with `file_path`, `content_type`, and `bytes`.
|
|
145
|
+
3. **Important**: The Agent is responsible for deleting the temporary file after use.
|
|
146
|
+
|
|
147
|
+
## Error Handling
|
|
148
|
+
|
|
149
|
+
### Insufficient Allowance
|
|
150
|
+
|
|
151
|
+
If allowance is insufficient, the tool will automatically attempt an "infinite approval" transaction. Ensure you have native tokens (TRX or BNB/ETH) for gas.
|
|
152
|
+
|
|
153
|
+
### Insufficient Balance
|
|
154
|
+
|
|
155
|
+
Ensure you have enough USDT/USDC/USDD in your wallet on the specified network.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
_Last Updated: 2026-03-17_
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
export const id = 254;
|
|
2
|
+
export const ids = [254];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 7254:
|
|
6
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// EXPORTS
|
|
10
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
11
|
+
offchainLookup: () => (/* binding */ offchainLookup),
|
|
12
|
+
offchainLookupSignature: () => (/* binding */ offchainLookupSignature)
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// UNUSED EXPORTS: ccipRequest, offchainLookupAbiItem
|
|
16
|
+
|
|
17
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/actions/public/call.js + 1 modules
|
|
18
|
+
var call = __webpack_require__(8454);
|
|
19
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/stringify.js
|
|
20
|
+
var stringify = __webpack_require__(2162);
|
|
21
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/errors/base.js + 1 modules
|
|
22
|
+
var base = __webpack_require__(9298);
|
|
23
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/errors/utils.js
|
|
24
|
+
var utils = __webpack_require__(8400);
|
|
25
|
+
;// CONCATENATED MODULE: ./node_modules/viem/_esm/errors/ccip.js
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OffchainLookupError extends base/* BaseError */.C {
|
|
30
|
+
constructor({ callbackSelector, cause, data, extraData, sender, urls, }) {
|
|
31
|
+
super(cause.shortMessage ||
|
|
32
|
+
'An error occurred while fetching for an offchain result.', {
|
|
33
|
+
cause,
|
|
34
|
+
metaMessages: [
|
|
35
|
+
...(cause.metaMessages || []),
|
|
36
|
+
cause.metaMessages?.length ? '' : [],
|
|
37
|
+
'Offchain Gateway Call:',
|
|
38
|
+
urls && [
|
|
39
|
+
' Gateway URL(s):',
|
|
40
|
+
...urls.map((url) => ` ${(0,utils/* getUrl */.I)(url)}`),
|
|
41
|
+
],
|
|
42
|
+
` Sender: ${sender}`,
|
|
43
|
+
` Data: ${data}`,
|
|
44
|
+
` Callback selector: ${callbackSelector}`,
|
|
45
|
+
` Extra data: ${extraData}`,
|
|
46
|
+
].flat(),
|
|
47
|
+
name: 'OffchainLookupError',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class OffchainLookupResponseMalformedError extends base/* BaseError */.C {
|
|
52
|
+
constructor({ result, url }) {
|
|
53
|
+
super('Offchain gateway response is malformed. Response data must be a hex value.', {
|
|
54
|
+
metaMessages: [
|
|
55
|
+
`Gateway URL: ${(0,utils/* getUrl */.I)(url)}`,
|
|
56
|
+
`Response: ${(0,stringify/* stringify */.A)(result)}`,
|
|
57
|
+
],
|
|
58
|
+
name: 'OffchainLookupResponseMalformedError',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
class OffchainLookupSenderMismatchError extends base/* BaseError */.C {
|
|
63
|
+
constructor({ sender, to }) {
|
|
64
|
+
super('Reverted sender address does not match target contract address (`to`).', {
|
|
65
|
+
metaMessages: [
|
|
66
|
+
`Contract address: ${to}`,
|
|
67
|
+
`OffchainLookup sender address: ${sender}`,
|
|
68
|
+
],
|
|
69
|
+
name: 'OffchainLookupSenderMismatchError',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=ccip.js.map
|
|
74
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/errors/request.js
|
|
75
|
+
var request = __webpack_require__(1168);
|
|
76
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/abi/decodeErrorResult.js
|
|
77
|
+
var decodeErrorResult = __webpack_require__(2615);
|
|
78
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/abi/encodeAbiParameters.js
|
|
79
|
+
var encodeAbiParameters = __webpack_require__(3570);
|
|
80
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/address/isAddressEqual.js
|
|
81
|
+
var isAddressEqual = __webpack_require__(2538);
|
|
82
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/data/concat.js
|
|
83
|
+
var concat = __webpack_require__(5878);
|
|
84
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/data/isHex.js
|
|
85
|
+
var isHex = __webpack_require__(4381);
|
|
86
|
+
// EXTERNAL MODULE: ./node_modules/viem/_esm/utils/ens/localBatchGatewayRequest.js + 3 modules
|
|
87
|
+
var localBatchGatewayRequest = __webpack_require__(3547);
|
|
88
|
+
;// CONCATENATED MODULE: ./node_modules/viem/_esm/utils/ccip.js
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
const offchainLookupSignature = '0x556f1830';
|
|
100
|
+
const offchainLookupAbiItem = {
|
|
101
|
+
name: 'OffchainLookup',
|
|
102
|
+
type: 'error',
|
|
103
|
+
inputs: [
|
|
104
|
+
{
|
|
105
|
+
name: 'sender',
|
|
106
|
+
type: 'address',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'urls',
|
|
110
|
+
type: 'string[]',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'callData',
|
|
114
|
+
type: 'bytes',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'callbackFunction',
|
|
118
|
+
type: 'bytes4',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'extraData',
|
|
122
|
+
type: 'bytes',
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
async function offchainLookup(client, { blockNumber, blockTag, data, to, }) {
|
|
127
|
+
const { args } = (0,decodeErrorResult/* decodeErrorResult */.W)({
|
|
128
|
+
data,
|
|
129
|
+
abi: [offchainLookupAbiItem],
|
|
130
|
+
});
|
|
131
|
+
const [sender, urls, callData, callbackSelector, extraData] = args;
|
|
132
|
+
const { ccipRead } = client;
|
|
133
|
+
const ccipRequest_ = ccipRead && typeof ccipRead?.request === 'function'
|
|
134
|
+
? ccipRead.request
|
|
135
|
+
: ccipRequest;
|
|
136
|
+
try {
|
|
137
|
+
if (!(0,isAddressEqual/* isAddressEqual */.h)(to, sender))
|
|
138
|
+
throw new OffchainLookupSenderMismatchError({ sender, to });
|
|
139
|
+
const result = urls.includes(localBatchGatewayRequest/* localBatchGatewayUrl */.J)
|
|
140
|
+
? await (0,localBatchGatewayRequest/* localBatchGatewayRequest */.X)({
|
|
141
|
+
data: callData,
|
|
142
|
+
ccipRequest: ccipRequest_,
|
|
143
|
+
})
|
|
144
|
+
: await ccipRequest_({ data: callData, sender, urls });
|
|
145
|
+
const { data: data_ } = await (0,call/* call */.T)(client, {
|
|
146
|
+
blockNumber,
|
|
147
|
+
blockTag,
|
|
148
|
+
data: (0,concat/* concat */.xW)([
|
|
149
|
+
callbackSelector,
|
|
150
|
+
(0,encodeAbiParameters/* encodeAbiParameters */.h)([{ type: 'bytes' }, { type: 'bytes' }], [result, extraData]),
|
|
151
|
+
]),
|
|
152
|
+
to,
|
|
153
|
+
});
|
|
154
|
+
return data_;
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
throw new OffchainLookupError({
|
|
158
|
+
callbackSelector,
|
|
159
|
+
cause: err,
|
|
160
|
+
data,
|
|
161
|
+
extraData,
|
|
162
|
+
sender,
|
|
163
|
+
urls,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function ccipRequest({ data, sender, urls, }) {
|
|
168
|
+
let error = new Error('An unknown error occurred.');
|
|
169
|
+
for (let i = 0; i < urls.length; i++) {
|
|
170
|
+
const url = urls[i];
|
|
171
|
+
const method = url.includes('{data}') ? 'GET' : 'POST';
|
|
172
|
+
const body = method === 'POST' ? { data, sender } : undefined;
|
|
173
|
+
const headers = method === 'POST' ? { 'Content-Type': 'application/json' } : {};
|
|
174
|
+
try {
|
|
175
|
+
const response = await fetch(url.replace('{sender}', sender.toLowerCase()).replace('{data}', data), {
|
|
176
|
+
body: JSON.stringify(body),
|
|
177
|
+
headers,
|
|
178
|
+
method,
|
|
179
|
+
});
|
|
180
|
+
let result;
|
|
181
|
+
if (response.headers.get('Content-Type')?.startsWith('application/json')) {
|
|
182
|
+
result = (await response.json()).data;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
result = (await response.text());
|
|
186
|
+
}
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
error = new request/* HttpRequestError */.Ci({
|
|
189
|
+
body,
|
|
190
|
+
details: result?.error
|
|
191
|
+
? (0,stringify/* stringify */.A)(result.error)
|
|
192
|
+
: response.statusText,
|
|
193
|
+
headers: response.headers,
|
|
194
|
+
status: response.status,
|
|
195
|
+
url,
|
|
196
|
+
});
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (!(0,isHex/* isHex */.q)(result)) {
|
|
200
|
+
error = new OffchainLookupResponseMalformedError({
|
|
201
|
+
result,
|
|
202
|
+
url,
|
|
203
|
+
});
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
error = new request/* HttpRequestError */.Ci({
|
|
210
|
+
body,
|
|
211
|
+
details: err.message,
|
|
212
|
+
url,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=ccip.js.map
|
|
219
|
+
|
|
220
|
+
/***/ })
|
|
221
|
+
|
|
222
|
+
};
|