@dexterai/x402 1.9.0 → 1.9.1
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 +101 -8
- package/dist/client/index.cjs +28 -0
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +25 -0
- package/dist/client/index.js.map +1 -1
- package/dist/react/index.cjs +40 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +10 -1
- package/dist/react/index.d.ts +10 -1
- package/dist/react/index.js +38 -1
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +16 -1
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +10 -1
- package/dist/server/index.d.ts +10 -1
- package/dist/server/index.js +15 -1
- package/dist/server/index.js.map +1 -1
- package/dist/{x402-client-BDaOwfgE.d.cts → sponsored-access-BCB2CxdG.d.cts} +68 -1
- package/dist/{x402-client-DIcp-PvX.d.ts → sponsored-access-H1EX6zpi.d.ts} +68 -1
- package/package.json +2 -6
package/README.md
CHANGED
|
@@ -580,20 +580,113 @@ tiktoken's default encoding works well for most transformer models. Only use a c
|
|
|
580
580
|
|
|
581
581
|
---
|
|
582
582
|
|
|
583
|
-
## Sponsored Access (
|
|
583
|
+
## Sponsored Access (Ads for Agents)
|
|
584
584
|
|
|
585
|
-
|
|
585
|
+
Sponsored Access delivers targeted resource recommendations through x402 payments. When an agent pays for an API, the facilitator can inject a recommendation for a related tool in the settlement receipt. The agent sees the recommendation and can call it immediately -- the subsequent call is tracked as a conversion with both blockchain transaction hashes as proof.
|
|
586
|
+
|
|
587
|
+
### Server — Enable Recommendation Injection
|
|
588
|
+
|
|
589
|
+
Add `sponsoredAccess: true` to your middleware config. This reads `extensions["sponsored-access"]` from the facilitator's settlement response and injects `_x402_sponsored` into the JSON response body so the agent's LLM can see the recommendations (headers are invisible to LLMs).
|
|
586
590
|
|
|
587
591
|
```typescript
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
+
import { x402Middleware } from '@dexterai/x402/server';
|
|
593
|
+
|
|
594
|
+
// Default injection: adds _x402_sponsored field to JSON response
|
|
595
|
+
app.get('/api/data',
|
|
596
|
+
x402Middleware({
|
|
597
|
+
payTo: '...', amount: '0.01',
|
|
598
|
+
sponsoredAccess: true,
|
|
599
|
+
}),
|
|
600
|
+
(req, res) => res.json({ data: 'content' })
|
|
601
|
+
);
|
|
602
|
+
// Agent receives: { _x402_sponsored: [{ resourceUrl, description, sponsor }], data: 'content' }
|
|
603
|
+
|
|
604
|
+
// Custom injection: control where recommendations appear
|
|
605
|
+
app.get('/api/data',
|
|
606
|
+
x402Middleware({
|
|
607
|
+
payTo: '...', amount: '0.01',
|
|
608
|
+
sponsoredAccess: {
|
|
609
|
+
inject: (body, recs) => ({ ...body, related_tools: recs }),
|
|
610
|
+
onMatch: (recs, settlement) => {
|
|
611
|
+
console.log(`Matched ${recs.length} recommendations for tx ${settlement.transaction}`);
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
}),
|
|
615
|
+
(req, res) => res.json({ data: 'content' })
|
|
616
|
+
);
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Client — Read Recommendations
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
import {
|
|
623
|
+
wrapFetch,
|
|
624
|
+
getSponsoredRecommendations,
|
|
625
|
+
fireImpressionBeacon,
|
|
626
|
+
} from '@dexterai/x402/client';
|
|
627
|
+
|
|
628
|
+
const x402Fetch = wrapFetch(fetch, { walletPrivateKey: key });
|
|
629
|
+
const response = await x402Fetch('https://api.example.com/data');
|
|
630
|
+
|
|
631
|
+
// Extract typed recommendations from the payment receipt
|
|
632
|
+
const recs = getSponsoredRecommendations(response);
|
|
633
|
+
if (recs) {
|
|
634
|
+
for (const rec of recs) {
|
|
635
|
+
console.log(`${rec.sponsor}: ${rec.description} -- ${rec.resourceUrl}`);
|
|
636
|
+
}
|
|
637
|
+
// Confirm delivery to the ad network
|
|
638
|
+
await fireImpressionBeacon(response);
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### React — Recommendations in Hooks
|
|
643
|
+
|
|
644
|
+
```tsx
|
|
645
|
+
import { useX402Payment } from '@dexterai/x402/react';
|
|
646
|
+
|
|
647
|
+
function PayButton() {
|
|
648
|
+
const {
|
|
649
|
+
fetch,
|
|
650
|
+
isLoading,
|
|
651
|
+
sponsoredRecommendations, // auto-populated after payment
|
|
652
|
+
} = useX402Payment({ wallets });
|
|
653
|
+
|
|
654
|
+
return (
|
|
655
|
+
<div>
|
|
656
|
+
<button onClick={() => fetch(url)} disabled={isLoading}>Pay</button>
|
|
657
|
+
{sponsoredRecommendations?.map((rec, i) => (
|
|
658
|
+
<a key={i} href={rec.resourceUrl}>{rec.sponsor}: {rec.description}</a>
|
|
659
|
+
))}
|
|
660
|
+
</div>
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### Types
|
|
666
|
+
|
|
667
|
+
All types are re-exported from `@dexterai/x402-ads-types`:
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
import type { SponsoredRecommendation, SponsoredAccessSettlementInfo } from '@dexterai/x402/client';
|
|
671
|
+
|
|
672
|
+
interface SponsoredRecommendation {
|
|
673
|
+
resourceUrl: string; // The URL to call
|
|
674
|
+
description: string; // Agent-readable description
|
|
675
|
+
sponsor: string; // Brand name
|
|
676
|
+
bazaarId?: string; // Bazaar catalog ID
|
|
677
|
+
price?: string; // Cost in atomic units
|
|
678
|
+
currency?: string; // e.g., "USDC"
|
|
679
|
+
}
|
|
592
680
|
```
|
|
593
681
|
|
|
594
|
-
|
|
682
|
+
### How It Works
|
|
595
683
|
|
|
596
|
-
|
|
684
|
+
1. Agent pays for an API via x402
|
|
685
|
+
2. Facilitator settles payment and calls the ad network's match API
|
|
686
|
+
3. If a campaign matches (by URL pattern, category, network), a recommendation is injected into `SettlementResponse.extensions["sponsored-access"]`
|
|
687
|
+
4. Publisher middleware (with `sponsoredAccess: true`) injects it into the JSON response body
|
|
688
|
+
5. Agent's LLM sees the recommendation and can call the suggested resource
|
|
689
|
+
6. If the agent calls it, the facilitator records a conversion with both tx hashes as proof
|
|
597
690
|
|
|
598
691
|
---
|
|
599
692
|
|
package/dist/client/index.cjs
CHANGED
|
@@ -195,7 +195,10 @@ __export(client_exports, {
|
|
|
195
195
|
createKeypairWallet: () => createKeypairWallet,
|
|
196
196
|
createSolanaAdapter: () => createSolanaAdapter,
|
|
197
197
|
createX402Client: () => createX402Client,
|
|
198
|
+
fireImpressionBeacon: () => fireImpressionBeacon,
|
|
198
199
|
getPaymentReceipt: () => getPaymentReceipt,
|
|
200
|
+
getSponsoredAccessInfo: () => getSponsoredAccessInfo,
|
|
201
|
+
getSponsoredRecommendations: () => getSponsoredRecommendations,
|
|
199
202
|
isEvmKeypairWallet: () => isEvmKeypairWallet,
|
|
200
203
|
isKeypairWallet: () => isKeypairWallet,
|
|
201
204
|
wrapFetch: () => wrapFetch
|
|
@@ -1151,6 +1154,28 @@ function wrapFetch(fetchImpl, options) {
|
|
|
1151
1154
|
}
|
|
1152
1155
|
return clientFetch;
|
|
1153
1156
|
}
|
|
1157
|
+
|
|
1158
|
+
// src/client/sponsored-access.ts
|
|
1159
|
+
function getSponsoredAccessInfo(response) {
|
|
1160
|
+
const receipt = getPaymentReceipt(response);
|
|
1161
|
+
if (!receipt?.extensions?.["sponsored-access"]) return void 0;
|
|
1162
|
+
return receipt.extensions["sponsored-access"];
|
|
1163
|
+
}
|
|
1164
|
+
function getSponsoredRecommendations(response) {
|
|
1165
|
+
const info = getSponsoredAccessInfo(response);
|
|
1166
|
+
if (!info?.recommendations?.length) return void 0;
|
|
1167
|
+
return info.recommendations;
|
|
1168
|
+
}
|
|
1169
|
+
async function fireImpressionBeacon(response) {
|
|
1170
|
+
const info = getSponsoredAccessInfo(response);
|
|
1171
|
+
const beaconUrl = info?.tracking?.impressionBeacon;
|
|
1172
|
+
if (!beaconUrl) return false;
|
|
1173
|
+
try {
|
|
1174
|
+
await fetch(beaconUrl, { method: "GET" });
|
|
1175
|
+
} catch {
|
|
1176
|
+
}
|
|
1177
|
+
return true;
|
|
1178
|
+
}
|
|
1154
1179
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1155
1180
|
0 && (module.exports = {
|
|
1156
1181
|
BASE_MAINNET,
|
|
@@ -1163,7 +1188,10 @@ function wrapFetch(fetchImpl, options) {
|
|
|
1163
1188
|
createKeypairWallet,
|
|
1164
1189
|
createSolanaAdapter,
|
|
1165
1190
|
createX402Client,
|
|
1191
|
+
fireImpressionBeacon,
|
|
1166
1192
|
getPaymentReceipt,
|
|
1193
|
+
getSponsoredAccessInfo,
|
|
1194
|
+
getSponsoredRecommendations,
|
|
1167
1195
|
isEvmKeypairWallet,
|
|
1168
1196
|
isKeypairWallet,
|
|
1169
1197
|
wrapFetch
|