warpmetal 0.7.1 → 0.7.3
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 +2 -2
- package/package.json +1 -1
- package/skills/warpmetal/SKILL.md +1 -1
- package/skills/warpmetal/references/cli-reference.md +5 -1
- package/skills/warpmetal/references/payments.md +15 -3
- package/skills/warpmetal/references/safety.md +5 -0
- package/src/payment.js +4 -1
- package/src/state.js +31 -10
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ published wallet CLI with the exact version WarpMetal reports:
|
|
|
34
34
|
npm install --global warpmetal
|
|
35
35
|
warpmetal --help
|
|
36
36
|
|
|
37
|
-
npm install --global @x402api/agent-wallet-cli@0.2.
|
|
37
|
+
npm install --global @x402api/agent-wallet-cli@0.2.4
|
|
38
38
|
x402api help --json
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -58,7 +58,7 @@ integration.
|
|
|
58
58
|
|
|
59
59
|
The repository also contains a skills-only WarpMetal plugin for the public
|
|
60
60
|
Plugins Directory shared by Codex and ChatGPT. The plugin remains a separate
|
|
61
|
-
artifact from the npm CLI and requires `warpmetal` CLI version 0.7.
|
|
61
|
+
artifact from the npm CLI and requires `warpmetal` CLI version 0.7.3 or newer.
|
|
62
62
|
|
|
63
63
|
To test the repository marketplace after the plugin lands on `main`:
|
|
64
64
|
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ with ad hoc HTTP commands.
|
|
|
11
11
|
|
|
12
12
|
## Start safely
|
|
13
13
|
|
|
14
|
-
1. Run `warpmetal --version` and require version `0.7.
|
|
14
|
+
1. Run `warpmetal --version` and require version `0.7.3` or newer for this
|
|
15
15
|
plugin. If it is missing or older, explain the compatibility requirement,
|
|
16
16
|
ask before installing or upgrading software, and use only the official npm
|
|
17
17
|
package from `https://www.npmjs.com/package/warpmetal`.
|
|
@@ -61,8 +61,12 @@ arrays. The default envelope and suggested artifact paths live under the
|
|
|
61
61
|
private WarpMetal state directory. An explicit output path must not already
|
|
62
62
|
contain different content. `challengeHandle` is intentionally absent from the
|
|
63
63
|
wallet envelope: it is neither a buyer payment identifier nor signing input.
|
|
64
|
+
If a previously issued unsigned sponsorship reservation expired, WarpMetal may
|
|
65
|
+
retire that attempt and return a new `paymentAttemptId`. The CLI replaces the
|
|
66
|
+
saved challenge and stale wallet-attempt metadata; use only the newly returned
|
|
67
|
+
workflow.
|
|
64
68
|
|
|
65
|
-
The current integration targets `@x402api/agent-wallet-cli@0.2.
|
|
69
|
+
The current integration targets `@x402api/agent-wallet-cli@0.2.4`. A compatible
|
|
66
70
|
live term is marked `agentWalletSupported: true` and must use the sponsored
|
|
67
71
|
Base USDC or Solana USDC/USDT launch profile with buyer native fees disabled.
|
|
68
72
|
For the current declaration, x402api pays actual gas from its platform treasury
|
|
@@ -16,10 +16,16 @@ The separate x402api Agent Wallet owns encrypted network keys, balance checks,
|
|
|
16
16
|
payment authorization, and durable payment attempts. Never merge their state
|
|
17
17
|
files or pass a WarpMetal credential to `x402api`.
|
|
18
18
|
|
|
19
|
+
The CLI includes the matching `@x402api/agent-wallet-core` SDK. That SDK is the
|
|
20
|
+
authoritative buyer-side parser and signer contract. WarpMetal retains its own
|
|
21
|
+
merchant-side validation because the backend is Python and additionally binds
|
|
22
|
+
the challenge to WarpMetal's exact resource, amount, recipient, and receipt
|
|
23
|
+
contract.
|
|
24
|
+
|
|
19
25
|
WarpMetal runs on Node.js 20 or 22. The x402api Agent Wallet currently requires
|
|
20
26
|
Node.js 22. Use the exact published package reported by
|
|
21
27
|
`paymentWorkflow.signerPackage.spec`; the current contract is
|
|
22
|
-
`@x402api/agent-wallet-cli@0.2.
|
|
28
|
+
`@x402api/agent-wallet-cli@0.2.4`. Do not add it as a WarpMetal dependency,
|
|
23
29
|
install executable wallet code from an unpinned repository URL, or substitute
|
|
24
30
|
a similarly named package.
|
|
25
31
|
|
|
@@ -130,7 +136,7 @@ reservation or any buyer-funded, unsupported, or unbound alternative.
|
|
|
130
136
|
|
|
131
137
|
x402api pays actual gas from its platform treasury. The merchant tenant's
|
|
132
138
|
active sponsorship allowance controls admission, but actual gas is not a
|
|
133
|
-
tenant debit. During the coordinated rollout, accept only the exact 0.2.
|
|
139
|
+
tenant debit. During the coordinated rollout, accept only the exact 0.2.4
|
|
134
140
|
platform-treasury declaration or the matched legacy tenant-credit declaration;
|
|
135
141
|
never accept a mixed billing and final-charge policy.
|
|
136
142
|
|
|
@@ -165,6 +171,12 @@ current `termEndsAt` generation are different.
|
|
|
165
171
|
|
|
166
172
|
## Retries and recovery
|
|
167
173
|
|
|
174
|
+
- Expired unsigned gas sponsorship: run the WarpMetal challenge flow again.
|
|
175
|
+
WarpMetal retires the expired merchant attempt and requests fresh instructions
|
|
176
|
+
under a new payment-attempt ID and idempotency key. The CLI replaces stale
|
|
177
|
+
wallet-attempt metadata when it saves the new challenge. Inspect the new
|
|
178
|
+
terms and authorize only the new workflow; never reuse an expired envelope or
|
|
179
|
+
artifact.
|
|
168
180
|
- `payment_pending` or `payment_finalizing`: keep the same checkout bytes and
|
|
169
181
|
artifact. `--wait` performs bounded retries with that exact authorization.
|
|
170
182
|
- Timeout or process restart after authorization: use the saved x402api attempt
|
|
@@ -182,6 +194,6 @@ current `termEndsAt` generation are different.
|
|
|
182
194
|
a fresh challenge; never retry the artifact or fall back to buyer-funded gas.
|
|
183
195
|
- `manual_review`: payment or fulfillment may be final. Stop all payment and
|
|
184
196
|
mutation retries.
|
|
185
|
-
- Expired or corrupt artifact, changed request digest, unexpected recipient,
|
|
197
|
+
- Expired or corrupt signed artifact, changed request digest, unexpected recipient,
|
|
186
198
|
unsupported network, asset, profile, sponsorship error, or request-binding
|
|
187
199
|
mismatch: stop instead of falling back or asking the buyer to fund ETH/SOL.
|
|
@@ -105,6 +105,11 @@ Confirm the plan, hostname, OS, and public key before preparing it.
|
|
|
105
105
|
## Retry and terminal-state rules
|
|
106
106
|
|
|
107
107
|
- Reuse the same idempotency key only for the exact same logical request.
|
|
108
|
+
- If an unsigned gas-sponsorship reservation expires, run `warpmetal checkout
|
|
109
|
+
challenge` again. WarpMetal retires the old merchant attempt, requests fresh
|
|
110
|
+
instructions with a new payment-attempt ID and idempotency key, and the CLI
|
|
111
|
+
replaces its saved challenge metadata. Re-evaluate the new terms before
|
|
112
|
+
authorization; never sign or submit the expired challenge.
|
|
108
113
|
- For `payment_pending`, retry the exact checkout body and the exact same
|
|
109
114
|
payment artifact. Do not create a replacement payment.
|
|
110
115
|
- A signed HTTP 402 rejects that signature. Use the new live challenge for one
|
package/src/payment.js
CHANGED
|
@@ -15,7 +15,7 @@ const MAX_ARTIFACT_BYTES = 1024 * 1024;
|
|
|
15
15
|
const MAX_SIGNATURE_BYTES = 512 * 1024;
|
|
16
16
|
|
|
17
17
|
export const AGENT_WALLET_PACKAGE = "@x402api/agent-wallet-cli";
|
|
18
|
-
export const AGENT_WALLET_VERSION = "0.2.
|
|
18
|
+
export const AGENT_WALLET_VERSION = "0.2.4";
|
|
19
19
|
const AGENT_WALLET_SPEC = `${AGENT_WALLET_PACKAGE}@${AGENT_WALLET_VERSION}`;
|
|
20
20
|
const GAS_SPONSORSHIP_EXTENSION = "com.x402api.gas-sponsorship";
|
|
21
21
|
const BASE_NETWORK = "eip155:8453";
|
|
@@ -183,6 +183,9 @@ function paymentResource(value, label) {
|
|
|
183
183
|
function validateGasSponsorship(declaration) {
|
|
184
184
|
const info = declaration.info;
|
|
185
185
|
const schema = declaration.schema;
|
|
186
|
+
// Mirror @x402api/agent-wallet-core: platform treasury is canonical, the
|
|
187
|
+
// matched tenant-credit pair remains rollout-compatible, and mixed pairs
|
|
188
|
+
// must fail closed.
|
|
186
189
|
const platformTreasuryPolicy =
|
|
187
190
|
isObject(info) &&
|
|
188
191
|
info.billingParty === "platform_treasury" &&
|
package/src/state.js
CHANGED
|
@@ -6,6 +6,26 @@ import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
|
6
6
|
import { CliError } from "./errors.js";
|
|
7
7
|
|
|
8
8
|
const STATE_VERSION = 3;
|
|
9
|
+
const WALLET_PAYMENT_STATE_FIELDS = [
|
|
10
|
+
"walletPaymentAttemptId",
|
|
11
|
+
"walletBuyerPaymentIdentifier",
|
|
12
|
+
"walletName",
|
|
13
|
+
"walletPayerAddress",
|
|
14
|
+
"paymentArtifactExpiresAt",
|
|
15
|
+
"paymentArtifactSavedAt",
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function replaceChallenge(record, challenge) {
|
|
19
|
+
const changed =
|
|
20
|
+
(record.paymentAttemptId &&
|
|
21
|
+
record.paymentAttemptId !== challenge.paymentAttemptId) ||
|
|
22
|
+
(record.paymentChallengeDigest &&
|
|
23
|
+
record.paymentChallengeDigest !== challenge.paymentChallengeDigest);
|
|
24
|
+
if (changed) {
|
|
25
|
+
for (const name of WALLET_PAYMENT_STATE_FIELDS) delete record[name];
|
|
26
|
+
}
|
|
27
|
+
Object.assign(record, challenge);
|
|
28
|
+
}
|
|
9
29
|
|
|
10
30
|
function emptyState() {
|
|
11
31
|
return {
|
|
@@ -235,9 +255,8 @@ export class StateStore {
|
|
|
235
255
|
async saveRenewalChallenge(serverId, challenge) {
|
|
236
256
|
await this.update((state) => {
|
|
237
257
|
const renewal = state.renewals[serverId] || { serverId };
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
});
|
|
258
|
+
replaceChallenge(renewal, challenge);
|
|
259
|
+
renewal.challengeSavedAt = new Date().toISOString();
|
|
241
260
|
state.renewals[serverId] = renewal;
|
|
242
261
|
});
|
|
243
262
|
}
|
|
@@ -292,13 +311,15 @@ export class StateStore {
|
|
|
292
311
|
throw new CliError(`No local order state exists for ${taskId}.`, {
|
|
293
312
|
exitCode: 2,
|
|
294
313
|
});
|
|
295
|
-
order
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
314
|
+
replaceChallenge(order, {
|
|
315
|
+
paymentRequired,
|
|
316
|
+
paymentAttemptId,
|
|
317
|
+
challengeHandle,
|
|
318
|
+
paymentRequestDigest,
|
|
319
|
+
paymentChallengeDigest,
|
|
320
|
+
paymentRequestEnvelopePath: paymentWorkflow?.requestEnvelopePath,
|
|
321
|
+
paymentArtifactPath: paymentWorkflow?.paymentArtifactPath,
|
|
322
|
+
});
|
|
302
323
|
order.paymentChallengeSavedAt = new Date().toISOString();
|
|
303
324
|
});
|
|
304
325
|
}
|