@coin-voyage/paykit-headless 0.0.1 → 0.0.2
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/README.md +114 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,32 +1,64 @@
|
|
|
1
1
|
# @coin-voyage/paykit-headless
|
|
2
2
|
|
|
3
|
-
Headless helpers for CoinVoyage PayKit and x402 payments.
|
|
3
|
+
Headless helpers for CoinVoyage PayKit and x402 payments in agent or server runtimes.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What This Package Does
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`@coin-voyage/paykit-headless` is intended for agents and backend services that need to pay
|
|
8
|
+
CoinVoyage x402 `PAYMENT-REQUIRED` challenges without a browser wallet UI.
|
|
9
|
+
|
|
10
|
+
For EVM and Solana payments, it wraps the default x402 EVM and SVM clients and provides a single
|
|
11
|
+
agent-oriented helper for fetching a challenge, signing the selected `accepts[]` entry, and retrying
|
|
12
|
+
the protected resource.
|
|
13
|
+
|
|
14
|
+
For Sui payments, it adds CoinVoyage-specific support that generic x402 clients do not provide yet:
|
|
15
|
+
it can select a `sui:mainnet` accept, build or sign the required Sui transaction payload, and return a
|
|
16
|
+
valid `PAYMENT-SIGNATURE` header for CoinVoyage's verifier.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
8
19
|
|
|
9
20
|
```bash
|
|
10
21
|
npm install @coin-voyage/paykit-headless
|
|
11
22
|
```
|
|
12
23
|
|
|
24
|
+
## Exports
|
|
25
|
+
|
|
26
|
+
The package exposes two public entry points:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { readResponseBody } from "@coin-voyage/paykit-headless"
|
|
30
|
+
import {
|
|
31
|
+
executeX402AgentPayment,
|
|
32
|
+
createSuiX402PaymentSignatureHeader,
|
|
33
|
+
decodeX402PaymentRequiredHeader,
|
|
34
|
+
type X402AgentPaymentRequest,
|
|
35
|
+
} from "@coin-voyage/paykit-headless/x402"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Do not import internal files such as `x402/agent` or `x402/sui`; use the `x402` barrel.
|
|
39
|
+
|
|
40
|
+
## Agent Payment Flow
|
|
41
|
+
|
|
13
42
|
Use `executeX402AgentPayment` when the agent should fetch a `PAYMENT-REQUIRED` challenge, create a
|
|
14
|
-
`PAYMENT-SIGNATURE`, and retry the protected resource
|
|
43
|
+
`PAYMENT-SIGNATURE`, and retry the protected resource.
|
|
15
44
|
|
|
16
45
|
```ts
|
|
17
46
|
import { executeX402AgentPayment } from "@coin-voyage/paykit-headless/x402"
|
|
18
47
|
|
|
48
|
+
const coinType = "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC"
|
|
49
|
+
const privateKey = process.env.AGENT_SUI_PRIVATE_KEY
|
|
50
|
+
const url = new URL("https://example.com/api/agent/payment-required")
|
|
51
|
+
url.searchParams.set("preferred_chain_type", "SUI")
|
|
52
|
+
url.searchParams.set("preferred_chain_id", "30000000000002")
|
|
53
|
+
url.searchParams.set("preferred_token_address", coinType)
|
|
54
|
+
|
|
19
55
|
const result = await executeX402AgentPayment({
|
|
20
|
-
url:
|
|
21
|
-
|
|
22
|
-
"?preferred_chain_type=SUI" +
|
|
23
|
-
"&preferred_chain_id=30000000000002" +
|
|
24
|
-
"&preferred_token_address=0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
|
|
56
|
+
url: url.toString(),
|
|
57
|
+
chainType: "SUI",
|
|
25
58
|
network: "sui:mainnet",
|
|
26
|
-
asset:
|
|
59
|
+
asset: coinType,
|
|
27
60
|
maxAmount: "20000",
|
|
28
|
-
|
|
29
|
-
privateKey: process.env.X402_AGENT_SUI_PRIVATE_KEY,
|
|
61
|
+
privateKey,
|
|
30
62
|
})
|
|
31
63
|
|
|
32
64
|
if (!result.ok) {
|
|
@@ -34,49 +66,96 @@ if (!result.ok) {
|
|
|
34
66
|
}
|
|
35
67
|
```
|
|
36
68
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
`privateKey` must match `chainType`:
|
|
70
|
+
|
|
71
|
+
| `chainType` | Expected key |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `EVM` | EVM private key for `eip155:*` accepts |
|
|
74
|
+
| `SOL` | Solana private key for `solana:*` accepts |
|
|
75
|
+
| `SUI` | Sui Ed25519 private key for `sui:*` accepts |
|
|
40
76
|
|
|
41
|
-
|
|
77
|
+
The agent filters `accepts[]` by `chainType`, then by `network`, `asset`, `paymentIdentifier`, and
|
|
78
|
+
`maxAmount` when those fields are provided.
|
|
79
|
+
|
|
80
|
+
## Payment Requirement Preferences
|
|
81
|
+
|
|
82
|
+
`X402RequirementRequest` is optional as a whole. If you send it, include both
|
|
83
|
+
`preferred_chain_type` and `preferred_token_address`.
|
|
84
|
+
|
|
85
|
+
Valid tailored request:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"preferred_chain_type": "SUI",
|
|
90
|
+
"preferred_chain_id": 30000000000002,
|
|
91
|
+
"preferred_token_address": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Do not request only `?preferred_chain_type=SUI`. If you do not need a tailored token response, omit all
|
|
96
|
+
preference fields and choose from the returned `accepts[]`.
|
|
97
|
+
|
|
98
|
+
## Existing PAYMENT-REQUIRED Header
|
|
99
|
+
|
|
100
|
+
If you already fetched a challenge, pass the header to `executeX402AgentPayment`:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const result = await executeX402AgentPayment({
|
|
104
|
+
url: "https://example.com/api/agent/payment-required",
|
|
105
|
+
paymentRequiredHeader,
|
|
106
|
+
chainType: "SUI",
|
|
107
|
+
network: "sui:mainnet",
|
|
108
|
+
asset: coinType,
|
|
109
|
+
maxAmount: "20000",
|
|
110
|
+
privateKey,
|
|
111
|
+
})
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For Sui-only integrations that only need the signature header:
|
|
42
115
|
|
|
43
116
|
```ts
|
|
44
117
|
import { createSuiX402PaymentSignatureHeader } from "@coin-voyage/paykit-headless/x402"
|
|
45
118
|
|
|
46
119
|
const { paymentSignature } = await createSuiX402PaymentSignatureHeader(paymentRequiredHeader, {
|
|
47
120
|
network: "sui:mainnet",
|
|
48
|
-
asset:
|
|
121
|
+
asset: coinType,
|
|
49
122
|
maxAmount: "20000",
|
|
50
|
-
privateKey
|
|
51
|
-
rpcUrl: process.env.
|
|
123
|
+
privateKey,
|
|
124
|
+
rpcUrl: process.env.SUI_RPC_URL,
|
|
52
125
|
})
|
|
53
126
|
```
|
|
54
127
|
|
|
55
|
-
## Sui Payload
|
|
128
|
+
## Sui PAYMENT-SIGNATURE Payload
|
|
56
129
|
|
|
57
130
|
Sui x402 support uses a CoinVoyage-specific payload carried in the standard base64
|
|
58
|
-
`PAYMENT-SIGNATURE` header. The
|
|
131
|
+
`PAYMENT-SIGNATURE` header. The SDK:
|
|
59
132
|
|
|
60
133
|
- Selects the returned `sui:mainnet` `accepts[]` entry without changing `scheme`, `network`,
|
|
61
134
|
`asset`, `amount`, `payTo`, or `paymentIdentifier`.
|
|
62
|
-
- Builds a Sui programmable transaction block
|
|
63
|
-
|
|
135
|
+
- Builds a Sui programmable transaction block when the backend does not provide transaction bytes.
|
|
136
|
+
- Transfers the exact raw `amount` of the exact Sui coin type to `payTo`.
|
|
64
137
|
- Signs the transaction with the configured Sui Ed25519 key.
|
|
65
|
-
- Encodes
|
|
138
|
+
- Encodes the signed transaction bytes, signature, payer address, selected accept, and CoinVoyage Sui
|
|
139
|
+
payload fields into `PAYMENT-SIGNATURE`.
|
|
66
140
|
|
|
67
141
|
If the server provides prepared Sui transaction bytes in `accept.transactionBytes`, `accept.txBytes`,
|
|
68
|
-
`accept.extra.sui.transactionBytes`, or `accept.extra.sui.txBytes`, the
|
|
69
|
-
|
|
142
|
+
`accept.extra.sui.transactionBytes`, or `accept.extra.sui.txBytes`, the SDK signs those bytes instead
|
|
143
|
+
of constructing a transfer transaction. It is valid for the backend `extra` object to contain only
|
|
144
|
+
`paymentIdentifier`; in that case the SDK builds the Sui PTB from the payer's owned coins.
|
|
70
145
|
|
|
71
|
-
##
|
|
146
|
+
## Current Limits
|
|
72
147
|
|
|
73
|
-
Use
|
|
148
|
+
- Native ETH and native SOL accepts are not supported by the headless agent. Use token accepts such as
|
|
149
|
+
USDC.
|
|
150
|
+
- Sui accepts require this SDK or another client that implements CoinVoyage's Sui
|
|
151
|
+
`PAYMENT-SIGNATURE` payload.
|
|
152
|
+
- The `maxAmount` value is compared against the raw token amount, not display units.
|
|
74
153
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```
|
|
154
|
+
## Key Handling
|
|
155
|
+
|
|
156
|
+
The package does not read private keys or RPC URLs from environment variables. Your application is
|
|
157
|
+
responsible for loading the correct key and passing it as `privateKey`.
|
|
80
158
|
|
|
81
|
-
|
|
82
|
-
|
|
159
|
+
For each payment attempt, pass the key that matches `chainType`. For example, pass a Sui Ed25519 key
|
|
160
|
+
when `chainType` is `"SUI"`, an EVM private key when `chainType` is `"EVM"`, and a Solana private key
|
|
161
|
+
when `chainType` is `"SOL"`.
|
package/package.json
CHANGED