uvd-x402-sdk 2.72.0 → 2.74.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/dist/backend/index.d.mts +94 -3
- package/dist/backend/index.d.ts +94 -3
- package/dist/backend/index.js +76 -2
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/index.mjs +76 -2
- package/dist/backend/index.mjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/backend/index.ts +134 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uvd-x402-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.74.0",
|
|
4
4
|
"description": "x402 Payment SDK - Gasless crypto payments across 25 blockchains via Ultravioleta facilitator. Supports EVM (including Scroll, SKALE Base, Robinhood Chain), Solana, Fogo, Stellar, NEAR, Algorand, Sui, and XRP Ledger. Features: ERC-8004 Trustless Agents, Escrow/Refunds, multi-stablecoin (USDC, EURC, AUSD, PYUSD, USDT, USDG).",
|
|
5
5
|
"author": "Ultravioleta DAO <ultravioletadao@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
package/src/backend/index.ts
CHANGED
|
@@ -3186,6 +3186,22 @@ export interface PrepareRelayFeedbackResponse {
|
|
|
3186
3186
|
* nobody.
|
|
3187
3187
|
*/
|
|
3188
3188
|
signingPayload?: string;
|
|
3189
|
+
/**
|
|
3190
|
+
* The full `eth_signTypedData_v4` payload. **v4 delegates only.**
|
|
3191
|
+
*
|
|
3192
|
+
* Present exactly when the delegate deployed on that chain is v4, which the
|
|
3193
|
+
* facilitator reads from the chain per request rather than assuming from a
|
|
3194
|
+
* release. **When it is present, sign IT** — the wallet renders the agent, the
|
|
3195
|
+
* score, the tags and the deadline as named fields, so the rater sees what
|
|
3196
|
+
* they authorise instead of a hex blob.
|
|
3197
|
+
*
|
|
3198
|
+
* v4 carries no {@link signingPayload} and needs none: `signTypedData` has no
|
|
3199
|
+
* envelope to apply twice, which is the entire class of bug that kept the v3
|
|
3200
|
+
* rail at zero signatures for days.
|
|
3201
|
+
*
|
|
3202
|
+
* Requires facilitator v1.96.0+.
|
|
3203
|
+
*/
|
|
3204
|
+
typedData?: Record<string, unknown>;
|
|
3189
3205
|
/**
|
|
3190
3206
|
* Unix seconds after which the authorisation is void. Short on purpose:
|
|
3191
3207
|
* relaying is permissionless, so a signed authorisation is live in the wild
|
|
@@ -3231,6 +3247,41 @@ export interface SubmitRelayFeedbackRequest {
|
|
|
3231
3247
|
authorization?: RelayAuthorizationParams;
|
|
3232
3248
|
}
|
|
3233
3249
|
|
|
3250
|
+
/**
|
|
3251
|
+
* Request body for `POST /feedback/response/evm/prepare`.
|
|
3252
|
+
*
|
|
3253
|
+
* `responder` is the address the chain will record as the author.
|
|
3254
|
+
*/
|
|
3255
|
+
export interface PrepareRelayResponseRequest {
|
|
3256
|
+
x402Version: 1 | 2;
|
|
3257
|
+
network: Erc8004Network;
|
|
3258
|
+
responder: string;
|
|
3259
|
+
agentId: number | string;
|
|
3260
|
+
/** WHOSE feedback is being answered — inside the signed struct. */
|
|
3261
|
+
clientAddress: string;
|
|
3262
|
+
/** Which feedback (1-indexed) — also inside the struct. */
|
|
3263
|
+
feedbackIndex: number;
|
|
3264
|
+
responseUri: string;
|
|
3265
|
+
responseHash?: string;
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
/** Request body for `POST /feedback/response/evm/submit`. */
|
|
3269
|
+
export interface SubmitRelayResponseRequest {
|
|
3270
|
+
x402Version: 1 | 2;
|
|
3271
|
+
network: Erc8004Network;
|
|
3272
|
+
responder: string;
|
|
3273
|
+
agentId: number | string;
|
|
3274
|
+
clientAddress: string;
|
|
3275
|
+
feedbackIndex: number;
|
|
3276
|
+
responseUri: string;
|
|
3277
|
+
responseHash?: string;
|
|
3278
|
+
deadline: number;
|
|
3279
|
+
nonce: string;
|
|
3280
|
+
/** The responder's signature over the typed data. */
|
|
3281
|
+
signature: string;
|
|
3282
|
+
authorization?: RelayAuthorizationParams;
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3234
3285
|
/**
|
|
3235
3286
|
* Proof of payment returned when settling with ERC-8004 extension
|
|
3236
3287
|
*/
|
|
@@ -4017,6 +4068,9 @@ export class Erc8004Client {
|
|
|
4017
4068
|
* - wallet: `personal_sign` over `signingPayload`. `personal_sign` adds the
|
|
4018
4069
|
* envelope itself, so signing `digest` with it wraps the value TWICE and
|
|
4019
4070
|
* recovers a stranger — the only symptom is `relay_bad_signature`.
|
|
4071
|
+
* - **unless `typedData` came back** — that chain runs a v4 delegate. Then
|
|
4072
|
+
* sign THAT with `eth_signTypedData_v4` and ignore the other two: it is
|
|
4073
|
+
* the only form the rater can read, and it has no envelope ambiguity.
|
|
4020
4074
|
* 2. If `delegated` is `false`, also produce an EIP-7702 authorization over
|
|
4021
4075
|
* `(chainId, delegate, accountNonce)`.
|
|
4022
4076
|
* 3. Hand both to {@link submitRelayedFeedback} with the SAME feedback
|
|
@@ -4265,11 +4319,89 @@ export class Erc8004Client {
|
|
|
4265
4319
|
}
|
|
4266
4320
|
}
|
|
4267
4321
|
|
|
4322
|
+
/**
|
|
4323
|
+
* Ask what the RESPONDER must sign to author a response on-chain.
|
|
4324
|
+
*
|
|
4325
|
+
* The mirror of {@link prepareRelayedFeedback}, for the other write the
|
|
4326
|
+
* registry accepts from anybody. `appendResponse` is not agent-only — the
|
|
4327
|
+
* registry takes it from any address — so on the plain {@link appendResponse}
|
|
4328
|
+
* route the `responder` recorded on-chain is the FACILITATOR. That does not
|
|
4329
|
+
* destroy anyone's reputation the way a revoke would; it ties the
|
|
4330
|
+
* facilitator's on-chain identity to a third party's content, which is its own
|
|
4331
|
+
* kind of wrong.
|
|
4332
|
+
*
|
|
4333
|
+
* **v4 delegates only.** The v3 delegate accepts exactly two selectors and
|
|
4334
|
+
* `appendResponse` is not one of them, so a v3 network answers 400
|
|
4335
|
+
* `relay_response_needs_v4` rather than silently falling back to the route
|
|
4336
|
+
* this replaces.
|
|
4337
|
+
*
|
|
4338
|
+
* `clientAddress` and `feedbackIndex` are inside the signed struct: without
|
|
4339
|
+
* them one signature would answer any client's rating, or any rating at that
|
|
4340
|
+
* index.
|
|
4341
|
+
*/
|
|
4342
|
+
async prepareRelayedResponse(
|
|
4343
|
+
request: PrepareRelayResponseRequest
|
|
4344
|
+
): Promise<PrepareRelayFeedbackResponse> {
|
|
4345
|
+
return this.postRelay('/feedback/response/evm/prepare', request, {
|
|
4346
|
+
success: false,
|
|
4347
|
+
delegated: false,
|
|
4348
|
+
chainId: 0,
|
|
4349
|
+
network: request.network,
|
|
4350
|
+
});
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
/**
|
|
4354
|
+
* Relay a responder-authored response; the facilitator pays the gas.
|
|
4355
|
+
*
|
|
4356
|
+
* Pass back the same parameters, `deadline` and `nonce` that
|
|
4357
|
+
* {@link prepareRelayedResponse} returned: the facilitator rebuilds the struct
|
|
4358
|
+
* from them and refuses to relay anything the signature does not cover.
|
|
4359
|
+
*/
|
|
4360
|
+
async submitRelayedResponse(
|
|
4361
|
+
request: SubmitRelayResponseRequest
|
|
4362
|
+
): Promise<FeedbackResponse> {
|
|
4363
|
+
return this.postRelay('/feedback/response/evm/submit', request, {
|
|
4364
|
+
success: false,
|
|
4365
|
+
network: request.network,
|
|
4366
|
+
});
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
/** Shared POST for the relay routes: a refusal is data, never a throw. */
|
|
4370
|
+
private async postRelay<T>(path: string, request: { network: Erc8004Network }, onError: T): Promise<T> {
|
|
4371
|
+
const controller = new AbortController();
|
|
4372
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
4373
|
+
try {
|
|
4374
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
4375
|
+
method: 'POST',
|
|
4376
|
+
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
|
|
4377
|
+
body: JSON.stringify({ ...request, network: wireNetwork(request.network) }),
|
|
4378
|
+
signal: controller.signal,
|
|
4379
|
+
});
|
|
4380
|
+
clearTimeout(timeoutId);
|
|
4381
|
+
if (!response.ok) {
|
|
4382
|
+
const errorText = await response.text();
|
|
4383
|
+
return { ...onError, error: `Facilitator error: ${response.status} - ${errorText}` };
|
|
4384
|
+
}
|
|
4385
|
+
return await response.json();
|
|
4386
|
+
} catch (error) {
|
|
4387
|
+
clearTimeout(timeoutId);
|
|
4388
|
+
return { ...onError, error: error instanceof Error ? error.message : 'Unknown error' };
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4391
|
+
|
|
4268
4392
|
/**
|
|
4269
4393
|
* Append a response to existing feedback
|
|
4270
4394
|
*
|
|
4271
|
-
*
|
|
4272
|
-
*
|
|
4395
|
+
* @deprecated On this route the facilitator is the AUTHOR: the registry
|
|
4396
|
+
* records `msg.sender` as the `responder`, and that is the facilitator's
|
|
4397
|
+
* wallet. Where the delegate is **v4**, use {@link prepareRelayedResponse} +
|
|
4398
|
+
* {@link submitRelayedResponse} instead. This route still works and is the
|
|
4399
|
+
* only one available where the delegate is still v3.
|
|
4400
|
+
*
|
|
4401
|
+
* **This is NOT agent-only**, despite what this comment claimed until
|
|
4402
|
+
* 2026-08-25. Verified on-chain on 2026-08-18: the registry accepts
|
|
4403
|
+
* `appendResponse` from ANY address. There is no identity-owner check, here or
|
|
4404
|
+
* in the contract.
|
|
4273
4405
|
*
|
|
4274
4406
|
* @param network - Network where feedback was submitted
|
|
4275
4407
|
* @param agentId - Agent ID
|