@agentcash/router 1.10.7 → 1.12.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/AGENTS.md +2 -0
- package/dist/index.cjs +39 -3
- package/dist/index.d.cts +20 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +39 -3
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -39,6 +39,8 @@ src/
|
|
|
39
39
|
|
|
40
40
|
`auth check -> body parse -> validate -> 402 challenge -> payment verify -> handler -> settle -> finalize`
|
|
41
41
|
|
|
42
|
+
Paid `.paid()` routes may set `mpp: { settleBeforeHandler: true }` (or chain `.mpp({ settleBeforeHandler: true })` on auto-priced routes) to broadcast MPP transaction (pull) credentials at verify instead of after the handler. x402 on the same route is unaffected. MPP hash (push) credentials already settle at verify. Use `.settlement({ onSettledHandlerError })` when eager MPP settle can charge before an upstream failure.
|
|
43
|
+
|
|
42
44
|
## Naming
|
|
43
45
|
|
|
44
46
|
Constructor-style functions use `build<Noun>` — one verb, one domain noun. Name them after the domain concept, never after an HTTP status code or transport detail (the function that builds a payment challenge is `buildChallengeResponse`, not `build402`). The challenge family shares the `Challenge` backbone: `buildChallengeResponse`, `buildChallengeExtensions`, `buildSiwxChallenge`, `buildSessionChallenge`, `buildX402Challenge`.
|
package/dist/index.cjs
CHANGED
|
@@ -1784,7 +1784,8 @@ var mppStrategy = {
|
|
|
1784
1784
|
return verifySessionMode(args, info);
|
|
1785
1785
|
}
|
|
1786
1786
|
if (info.sessionAction) return { ok: false, kind: "invalid" };
|
|
1787
|
-
|
|
1787
|
+
const deferTransactionSettlement = info.payloadType === "transaction" && args.deps.tempoClient && !args.routeEntry.mppInfo?.settleBeforeHandler;
|
|
1788
|
+
if (deferTransactionSettlement) {
|
|
1788
1789
|
return verifyTxMode(args, info);
|
|
1789
1790
|
}
|
|
1790
1791
|
return verifyHashMode(args, info);
|
|
@@ -3856,7 +3857,9 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
3856
3857
|
if (maxPrice) next.#s.maxPrice = maxPrice;
|
|
3857
3858
|
if (resolvedOptions.minPrice) next.#s.minPrice = resolvedOptions.minPrice;
|
|
3858
3859
|
if (resolvedOptions.payTo) next.#s.payTo = resolvedOptions.payTo;
|
|
3859
|
-
if (resolvedOptions.mpp)
|
|
3860
|
+
if (resolvedOptions.mpp) {
|
|
3861
|
+
next.#s.mppInfo = { ...next.#s.mppInfo, ...resolvedOptions.mpp };
|
|
3862
|
+
}
|
|
3860
3863
|
if (resolvedOptions.checkout || resolvedOptions.checkoutSession) next.#s.hasCheckout = true;
|
|
3861
3864
|
if (resolvedOptions.checkoutSession) next.#s.checkoutSession = resolvedOptions.checkoutSession;
|
|
3862
3865
|
next.#s.billing = billing;
|
|
@@ -4151,6 +4154,24 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4151
4154
|
next.#s.validateFn = fn;
|
|
4152
4155
|
return next;
|
|
4153
4156
|
}
|
|
4157
|
+
/**
|
|
4158
|
+
* Override MPP protocol metadata and per-route MPP settlement options.
|
|
4159
|
+
* Merges with any `mpp` options passed to `.paid()`. Use on auto-priced routes
|
|
4160
|
+
* (from `RouterConfig.prices`) when you cannot call `.paid()` again.
|
|
4161
|
+
*
|
|
4162
|
+
* @example
|
|
4163
|
+
* ```ts
|
|
4164
|
+
* router.route('exa/answer')
|
|
4165
|
+
* .mpp({ settleBeforeHandler: true })
|
|
4166
|
+
* .body(schema)
|
|
4167
|
+
* .handler(handler);
|
|
4168
|
+
* ```
|
|
4169
|
+
*/
|
|
4170
|
+
mpp(info) {
|
|
4171
|
+
const next = this.fork();
|
|
4172
|
+
next.#s.mppInfo = { ...this.#s.mppInfo, ...info };
|
|
4173
|
+
return next;
|
|
4174
|
+
}
|
|
4154
4175
|
/**
|
|
4155
4176
|
* Hook into the settlement lifecycle. `beforeSettle` runs after the handler
|
|
4156
4177
|
* succeeds but before on-chain settlement and can cancel the charge;
|
|
@@ -4166,7 +4187,7 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4166
4187
|
*/
|
|
4167
4188
|
settlement(lifecycle) {
|
|
4168
4189
|
const next = this.fork();
|
|
4169
|
-
next.#s.settlement = lifecycle;
|
|
4190
|
+
next.#s.settlement = { ...this.#s.settlement, ...lifecycle };
|
|
4170
4191
|
return next;
|
|
4171
4192
|
}
|
|
4172
4193
|
/**
|
|
@@ -4222,6 +4243,21 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4222
4243
|
if (this.#s.settlement && !this.#s.pricing) {
|
|
4223
4244
|
throw new Error(`route '${this.#s.key}': .settlement() requires a paid route`);
|
|
4224
4245
|
}
|
|
4246
|
+
if (this.#s.mppInfo?.settleBeforeHandler) {
|
|
4247
|
+
if (!this.#s.pricing) {
|
|
4248
|
+
throw new Error(`route '${this.#s.key}': mpp.settleBeforeHandler requires a paid route`);
|
|
4249
|
+
}
|
|
4250
|
+
if (this.#s.billing !== "exact") {
|
|
4251
|
+
throw new Error(
|
|
4252
|
+
`route '${this.#s.key}': mpp.settleBeforeHandler is only supported on .paid() routes`
|
|
4253
|
+
);
|
|
4254
|
+
}
|
|
4255
|
+
if (this.#s.settlement?.beforeSettle) {
|
|
4256
|
+
throw new Error(
|
|
4257
|
+
`route '${this.#s.key}': mpp.settleBeforeHandler is incompatible with .settlement({ beforeSettle }) \u2014 MPP payment is already broadcast before the handler runs`
|
|
4258
|
+
);
|
|
4259
|
+
}
|
|
4260
|
+
}
|
|
4225
4261
|
if (this.#s.billing === "upto") {
|
|
4226
4262
|
const hasUpto = this.#s.deps.x402Accepts.some((accept) => accept.scheme === "upto");
|
|
4227
4263
|
if (!hasUpto) {
|
package/dist/index.d.cts
CHANGED
|
@@ -221,6 +221,7 @@ interface MppProtocolInfo {
|
|
|
221
221
|
method?: string;
|
|
222
222
|
intent?: string;
|
|
223
223
|
currency?: string;
|
|
224
|
+
settleBeforeHandler?: boolean;
|
|
224
225
|
}
|
|
225
226
|
type CheckoutSessionResponse = Record<string, unknown>;
|
|
226
227
|
interface CheckoutSessionContext<TBody = unknown> {
|
|
@@ -409,6 +410,7 @@ interface DiscoveryConfig {
|
|
|
409
410
|
contact?: {
|
|
410
411
|
name?: string;
|
|
411
412
|
url?: string;
|
|
413
|
+
email?: string;
|
|
412
414
|
};
|
|
413
415
|
ownershipProofs?: string[];
|
|
414
416
|
methodHints?: 'off' | 'non-default' | 'always';
|
|
@@ -582,8 +584,9 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
582
584
|
* - `{ field, tiers, default? }` — pick a tier from `body[field]`.
|
|
583
585
|
*
|
|
584
586
|
* Common knobs (`protocols`, `maxPrice`, `minPrice`, `payTo`, `mpp`, `checkout`,
|
|
585
|
-
* `checkoutSession`) live alongside the pricing shape.
|
|
586
|
-
*
|
|
587
|
+
* `checkoutSession`) live alongside the pricing shape. Set `mpp.settleBeforeHandler`
|
|
588
|
+
* on slow upstream routes so MPP transaction (pull) credentials broadcast at verify.
|
|
589
|
+
* For auto-priced routes from `RouterConfig.prices`, chain `.mpp({ settleBeforeHandler: true })`.
|
|
587
590
|
*
|
|
588
591
|
* @example
|
|
589
592
|
* ```ts
|
|
@@ -779,6 +782,20 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
779
782
|
* ```
|
|
780
783
|
*/
|
|
781
784
|
validate(fn: (body: TBody) => void | Promise<void>): RouteBuilder<TBody, TQuery, TOutput, HasAuth, NeedsBody, HasBody, Bill>;
|
|
785
|
+
/**
|
|
786
|
+
* Override MPP protocol metadata and per-route MPP settlement options.
|
|
787
|
+
* Merges with any `mpp` options passed to `.paid()`. Use on auto-priced routes
|
|
788
|
+
* (from `RouterConfig.prices`) when you cannot call `.paid()` again.
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* ```ts
|
|
792
|
+
* router.route('exa/answer')
|
|
793
|
+
* .mpp({ settleBeforeHandler: true })
|
|
794
|
+
* .body(schema)
|
|
795
|
+
* .handler(handler);
|
|
796
|
+
* ```
|
|
797
|
+
*/
|
|
798
|
+
mpp(info: MppProtocolInfo): RouteBuilder<TBody, TQuery, TOutput, HasAuth, NeedsBody, HasBody, Bill>;
|
|
782
799
|
/**
|
|
783
800
|
* Hook into the settlement lifecycle. `beforeSettle` runs after the handler
|
|
784
801
|
* succeeds but before on-chain settlement and can cancel the charge;
|
|
@@ -953,4 +970,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
|
|
|
953
970
|
*/
|
|
954
971
|
declare function createRouterFromEnv<const P extends Record<string, string> = Record<never, string>>(options: CreateRouterFromEnvOptions<P>): ServiceRouter<Extract<keyof P, string>>;
|
|
955
972
|
|
|
956
|
-
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CheckoutSessionContext, type CheckoutSessionFn, type CheckoutSessionResponse, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
|
973
|
+
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CheckoutSessionContext, type CheckoutSessionFn, type CheckoutSessionResponse, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type MppProtocolInfo, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -221,6 +221,7 @@ interface MppProtocolInfo {
|
|
|
221
221
|
method?: string;
|
|
222
222
|
intent?: string;
|
|
223
223
|
currency?: string;
|
|
224
|
+
settleBeforeHandler?: boolean;
|
|
224
225
|
}
|
|
225
226
|
type CheckoutSessionResponse = Record<string, unknown>;
|
|
226
227
|
interface CheckoutSessionContext<TBody = unknown> {
|
|
@@ -409,6 +410,7 @@ interface DiscoveryConfig {
|
|
|
409
410
|
contact?: {
|
|
410
411
|
name?: string;
|
|
411
412
|
url?: string;
|
|
413
|
+
email?: string;
|
|
412
414
|
};
|
|
413
415
|
ownershipProofs?: string[];
|
|
414
416
|
methodHints?: 'off' | 'non-default' | 'always';
|
|
@@ -582,8 +584,9 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
582
584
|
* - `{ field, tiers, default? }` — pick a tier from `body[field]`.
|
|
583
585
|
*
|
|
584
586
|
* Common knobs (`protocols`, `maxPrice`, `minPrice`, `payTo`, `mpp`, `checkout`,
|
|
585
|
-
* `checkoutSession`) live alongside the pricing shape.
|
|
586
|
-
*
|
|
587
|
+
* `checkoutSession`) live alongside the pricing shape. Set `mpp.settleBeforeHandler`
|
|
588
|
+
* on slow upstream routes so MPP transaction (pull) credentials broadcast at verify.
|
|
589
|
+
* For auto-priced routes from `RouterConfig.prices`, chain `.mpp({ settleBeforeHandler: true })`.
|
|
587
590
|
*
|
|
588
591
|
* @example
|
|
589
592
|
* ```ts
|
|
@@ -779,6 +782,20 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
779
782
|
* ```
|
|
780
783
|
*/
|
|
781
784
|
validate(fn: (body: TBody) => void | Promise<void>): RouteBuilder<TBody, TQuery, TOutput, HasAuth, NeedsBody, HasBody, Bill>;
|
|
785
|
+
/**
|
|
786
|
+
* Override MPP protocol metadata and per-route MPP settlement options.
|
|
787
|
+
* Merges with any `mpp` options passed to `.paid()`. Use on auto-priced routes
|
|
788
|
+
* (from `RouterConfig.prices`) when you cannot call `.paid()` again.
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* ```ts
|
|
792
|
+
* router.route('exa/answer')
|
|
793
|
+
* .mpp({ settleBeforeHandler: true })
|
|
794
|
+
* .body(schema)
|
|
795
|
+
* .handler(handler);
|
|
796
|
+
* ```
|
|
797
|
+
*/
|
|
798
|
+
mpp(info: MppProtocolInfo): RouteBuilder<TBody, TQuery, TOutput, HasAuth, NeedsBody, HasBody, Bill>;
|
|
782
799
|
/**
|
|
783
800
|
* Hook into the settlement lifecycle. `beforeSettle` runs after the handler
|
|
784
801
|
* succeeds but before on-chain settlement and can cancel the charge;
|
|
@@ -953,4 +970,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
|
|
|
953
970
|
*/
|
|
954
971
|
declare function createRouterFromEnv<const P extends Record<string, string> = Record<never, string>>(options: CreateRouterFromEnvOptions<P>): ServiceRouter<Extract<keyof P, string>>;
|
|
955
972
|
|
|
956
|
-
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CheckoutSessionContext, type CheckoutSessionFn, type CheckoutSessionResponse, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
|
973
|
+
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CheckoutSessionContext, type CheckoutSessionFn, type CheckoutSessionResponse, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type MppProtocolInfo, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
package/dist/index.js
CHANGED
|
@@ -1746,7 +1746,8 @@ var mppStrategy = {
|
|
|
1746
1746
|
return verifySessionMode(args, info);
|
|
1747
1747
|
}
|
|
1748
1748
|
if (info.sessionAction) return { ok: false, kind: "invalid" };
|
|
1749
|
-
|
|
1749
|
+
const deferTransactionSettlement = info.payloadType === "transaction" && args.deps.tempoClient && !args.routeEntry.mppInfo?.settleBeforeHandler;
|
|
1750
|
+
if (deferTransactionSettlement) {
|
|
1750
1751
|
return verifyTxMode(args, info);
|
|
1751
1752
|
}
|
|
1752
1753
|
return verifyHashMode(args, info);
|
|
@@ -3818,7 +3819,9 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
3818
3819
|
if (maxPrice) next.#s.maxPrice = maxPrice;
|
|
3819
3820
|
if (resolvedOptions.minPrice) next.#s.minPrice = resolvedOptions.minPrice;
|
|
3820
3821
|
if (resolvedOptions.payTo) next.#s.payTo = resolvedOptions.payTo;
|
|
3821
|
-
if (resolvedOptions.mpp)
|
|
3822
|
+
if (resolvedOptions.mpp) {
|
|
3823
|
+
next.#s.mppInfo = { ...next.#s.mppInfo, ...resolvedOptions.mpp };
|
|
3824
|
+
}
|
|
3822
3825
|
if (resolvedOptions.checkout || resolvedOptions.checkoutSession) next.#s.hasCheckout = true;
|
|
3823
3826
|
if (resolvedOptions.checkoutSession) next.#s.checkoutSession = resolvedOptions.checkoutSession;
|
|
3824
3827
|
next.#s.billing = billing;
|
|
@@ -4113,6 +4116,24 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4113
4116
|
next.#s.validateFn = fn;
|
|
4114
4117
|
return next;
|
|
4115
4118
|
}
|
|
4119
|
+
/**
|
|
4120
|
+
* Override MPP protocol metadata and per-route MPP settlement options.
|
|
4121
|
+
* Merges with any `mpp` options passed to `.paid()`. Use on auto-priced routes
|
|
4122
|
+
* (from `RouterConfig.prices`) when you cannot call `.paid()` again.
|
|
4123
|
+
*
|
|
4124
|
+
* @example
|
|
4125
|
+
* ```ts
|
|
4126
|
+
* router.route('exa/answer')
|
|
4127
|
+
* .mpp({ settleBeforeHandler: true })
|
|
4128
|
+
* .body(schema)
|
|
4129
|
+
* .handler(handler);
|
|
4130
|
+
* ```
|
|
4131
|
+
*/
|
|
4132
|
+
mpp(info) {
|
|
4133
|
+
const next = this.fork();
|
|
4134
|
+
next.#s.mppInfo = { ...this.#s.mppInfo, ...info };
|
|
4135
|
+
return next;
|
|
4136
|
+
}
|
|
4116
4137
|
/**
|
|
4117
4138
|
* Hook into the settlement lifecycle. `beforeSettle` runs after the handler
|
|
4118
4139
|
* succeeds but before on-chain settlement and can cancel the charge;
|
|
@@ -4128,7 +4149,7 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4128
4149
|
*/
|
|
4129
4150
|
settlement(lifecycle) {
|
|
4130
4151
|
const next = this.fork();
|
|
4131
|
-
next.#s.settlement = lifecycle;
|
|
4152
|
+
next.#s.settlement = { ...this.#s.settlement, ...lifecycle };
|
|
4132
4153
|
return next;
|
|
4133
4154
|
}
|
|
4134
4155
|
/**
|
|
@@ -4184,6 +4205,21 @@ var RouteBuilder = class _RouteBuilder {
|
|
|
4184
4205
|
if (this.#s.settlement && !this.#s.pricing) {
|
|
4185
4206
|
throw new Error(`route '${this.#s.key}': .settlement() requires a paid route`);
|
|
4186
4207
|
}
|
|
4208
|
+
if (this.#s.mppInfo?.settleBeforeHandler) {
|
|
4209
|
+
if (!this.#s.pricing) {
|
|
4210
|
+
throw new Error(`route '${this.#s.key}': mpp.settleBeforeHandler requires a paid route`);
|
|
4211
|
+
}
|
|
4212
|
+
if (this.#s.billing !== "exact") {
|
|
4213
|
+
throw new Error(
|
|
4214
|
+
`route '${this.#s.key}': mpp.settleBeforeHandler is only supported on .paid() routes`
|
|
4215
|
+
);
|
|
4216
|
+
}
|
|
4217
|
+
if (this.#s.settlement?.beforeSettle) {
|
|
4218
|
+
throw new Error(
|
|
4219
|
+
`route '${this.#s.key}': mpp.settleBeforeHandler is incompatible with .settlement({ beforeSettle }) \u2014 MPP payment is already broadcast before the handler runs`
|
|
4220
|
+
);
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4187
4223
|
if (this.#s.billing === "upto") {
|
|
4188
4224
|
const hasUpto = this.#s.deps.x402Accepts.some((accept) => accept.scheme === "upto");
|
|
4189
4225
|
if (!hasUpto) {
|