@reap-protocol/sdk 0.1.1 โ†’ 0.1.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 ADDED
@@ -0,0 +1,103 @@
1
+ # @reap-protocol/sdk
2
+
3
+ **The official TypeScript/Node.js SDK for the Reap Protocol: The Agentic Commerce Grid.**
4
+
5
+ The Reap Protocol enables AI Agents to search for products, register them on-chain, and execute atomic purchases without needing to understand smart contract ABIs. It acts as the bridge between Web2 products data and Web3 commerce settlement.
6
+
7
+ ## ๐Ÿ“ฆ Installation
8
+ ```bash
9
+ npm install @reap-protocol/sdk ethers axios
10
+ ```
11
+
12
+ ## ๐Ÿš€ Quick Start
13
+
14
+ This example demonstrates the full Agentic Commerce Loop: Identity -> Discovery -> Settlement.
15
+
16
+ ### 1. Setup
17
+
18
+ If using TypeScript, ensure your tsconfig.json targets ES2020 or higher.
19
+
20
+ ### 2. The Agent Code (agent.ts)
21
+ ```typescript
22
+ import { ReapClient } from "@reap-protocol/sdk";
23
+
24
+ // Load your private key securely
25
+ const PRIVATE_KEY = process.env.MY_WALLET_KEY || "";
26
+
27
+ async function main() {
28
+ // 1. Initialize the Agent
29
+ // (Points to official middleware by default)
30
+ const client = new ReapClient(PRIVATE_KEY);
31
+ console.log("๐Ÿค– Agent Online");
32
+
33
+ try {
34
+ // 2. Identity (One-time setup)
35
+ // Registers your wallet as an authorized Agent on the Protocol
36
+ console.log("๐Ÿ†” Checking Identity...");
37
+ await client.registerIdentity();
38
+
39
+ // 3. JIT Stocking (Discovery)
40
+ // Searches Web2 (Reap Deals), registers items on-chain, and returns inventory
41
+ console.log("๐Ÿ“ฆ Stocking Shelf with 'Gaming Laptop'...");
42
+ const result = await client.stockShelf("Gaming Laptop");
43
+
44
+ const inventory = result.items;
45
+ console.log(` ๐Ÿ” Found ${inventory.length} items on-chain.`);
46
+
47
+ if (inventory.length > 0) {
48
+ // 4. Decision Logic
49
+ // Example: Pick the first available item
50
+ const target = inventory[0];
51
+ console.log(` ๐ŸŽฏ Selected: ${target.name} ($${target.price})`);
52
+ console.log(` ID: ${target.id}`);
53
+
54
+ // 5. Agentic Cart (Settlement)
55
+ // Automatically approves USDC and executes the atomic purchase
56
+ console.log("๐Ÿ’ธ Buying Item...");
57
+ const receipt = await client.buyProduct(target.id);
58
+
59
+ if (receipt) {
60
+ console.log(`๐ŸŽ‰ SUCCESS! Transaction Hash: ${receipt.hash}`);
61
+ }
62
+ } else {
63
+ console.log("โŒ No items found.");
64
+ }
65
+
66
+ } catch (e: any) {
67
+ console.error("โŒ Error:", e.message);
68
+ }
69
+ }
70
+
71
+ main();
72
+ ```
73
+
74
+ ### 3. Run It
75
+ ```bash
76
+ # Install execution tools if you haven't already
77
+ npm install --save-dev ts-node typescript @types/node
78
+
79
+ # Run
80
+ npx ts-node agent.ts
81
+ ```
82
+
83
+ ## ๐Ÿ”ง Configuration
84
+
85
+ You can override defaults for custom RPCs or self-hosted middleware.
86
+ ```typescript
87
+ const client = new ReapClient(
88
+ "YOUR_PRIVATE_KEY",
89
+ "https://base-sepolia.g.alchemy.com/v2/YOUR_KEY", // Custom RPC
90
+ "https://api.reap.deals" // Middleware URL
91
+ );
92
+ ```
93
+
94
+ ## โœจ Features
95
+
96
+ * **JIT Stocking**: "Just-In-Time" inventory system. If an agent searches for an item not yet on the blockchain, the Protocol indexes it in real-time.
97
+ * **Agentic Cart**: Automatically routes purchases through the Protocol's batch processor.
98
+ * **Protocol Negotiation**: Built-in support for HTTP 402 Payment Negotiation loops.
99
+ * **Gas Optimized**: Checks on-chain state before sending registration transactions.
100
+
101
+ ## License
102
+
103
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reap-protocol/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/README.md CHANGED
@@ -11,7 +11,8 @@ npm install @reap-protocol/sdk ethers axios
11
11
 
12
12
  ## ๐Ÿš€ Quick Start
13
13
 
14
- This example demonstrates the full Agentic Commerce Loop: Identity -> Discovery -> Settlement.
14
+ This example demonstrates the full Agentic Commerce Loop: Identity -> Discovery -> Smart Sync -> Settlement.
15
+
15
16
 
16
17
  ### 1. Setup
17
18
 
@@ -23,11 +24,14 @@ import { ReapClient } from "@reap-protocol/sdk";
23
24
 
24
25
  // Load your private key securely
25
26
  const PRIVATE_KEY = process.env.MY_WALLET_KEY || "";
27
+ const CHAIN_RPC = "https://api.avax-test.network/ext/bc/C/rpc";
26
28
 
27
29
  async function main() {
28
30
  // 1. Initialize the Agent
29
- // (Points to official middleware by default)
30
- const client = new ReapClient(PRIVATE_KEY);
31
+ const client = new ReapClient(PRIVATE_KEY, CHAIN_RPC);
32
+
33
+ // Wait for Chain ID initialization
34
+ await new Promise(r => setTimeout(r, 1000));
31
35
  console.log("๐Ÿค– Agent Online");
32
36
 
33
37
  try {
@@ -36,25 +40,36 @@ async function main() {
36
40
  console.log("๐Ÿ†” Checking Identity...");
37
41
  await client.registerIdentity();
38
42
 
39
- // 3. JIT Stocking (Discovery)
40
- // Searches Web2 (Reap Deals), registers items on-chain, and returns inventory
41
- console.log("๐Ÿ“ฆ Stocking Shelf with 'Gaming Laptop'...");
42
- const result = await client.stockShelf("Gaming Laptop");
43
+ // 3. Discovery (Dry Run Mode)
44
+ // Pass 'true' to get the items AND the transactions without executing them yet.
45
+ console.log("๐Ÿ“ฆ Browsing for 'Gaming Laptop'...");
46
+
47
+ // dryRun = true
48
+ const result = await client.stockShelf("Gaming Laptop", true);
43
49
 
44
- const inventory = result.items;
45
- console.log(` ๐Ÿ” Found ${inventory.length} items on-chain.`);
50
+ const inventory = result.items || [];
51
+ const transactions = result.transactions || [];
52
+
53
+ console.log(` ๐Ÿ” Found ${inventory.length} items.`);
46
54
 
47
55
  if (inventory.length > 0) {
48
56
  // 4. Decision Logic
49
- // Example: Pick the first available item
50
- const target = inventory[0];
51
- console.log(` ๐ŸŽฏ Selected: ${target.name} ($${target.price})`);
52
- console.log(` ID: ${target.id}`);
57
+ // Pick the first item and its corresponding registration transaction
58
+ const targetItem = inventory[0];
59
+ const targetTx = transactions[0];
60
+
61
+ console.log(` ๐ŸŽฏ Selected: ${targetItem.name} ($${targetItem.price})`);
53
62
 
54
- // 5. Agentic Cart (Settlement)
63
+ // 5. Smart Sync (The "Gas Saver")
64
+ // Checks the Holocron (Index) first.
65
+ // If the item exists, it skips registration.
66
+ // If not, it executes the targetTx and indexes it.
67
+ await client.smartSync(targetItem, targetTx);
68
+
69
+ // 6. Agentic Cart (Settlement)
55
70
  // Automatically approves USDC and executes the atomic purchase
56
71
  console.log("๐Ÿ’ธ Buying Item...");
57
- const receipt = await client.buyProduct(target.id);
72
+ const receipt = await client.buyProduct(targetItem.id);
58
73
 
59
74
  if (receipt) {
60
75
  console.log(`๐ŸŽ‰ SUCCESS! Transaction Hash: ${receipt.hash}`);
@@ -80,23 +95,40 @@ npm install --save-dev ts-node typescript @types/node
80
95
  npx ts-node agent.ts
81
96
  ```
82
97
 
98
+ ## ๐Ÿ•ต๏ธ Agent Discovery (New)
99
+
100
+ You can now search for other AI Agents (MCP, x402, A2A).
101
+
102
+ ```typescript
103
+ // 1. Search for Agents
104
+ // Registries: 'mcp' (AI Models), 'x402' (Payment Agents), 'a2a' (Autonomous)
105
+ const agents = await client.searchAgents("ecommerce", "x402");
106
+
107
+ if (agents.length > 0) {
108
+ const targetAgent = agents[0];
109
+ console.log(`Found: ${targetAgent.name}`);
110
+ }
111
+ ```
112
+
83
113
  ## ๐Ÿ”ง Configuration
84
114
 
85
115
  You can override defaults for custom RPCs or self-hosted middleware.
86
116
  ```typescript
87
117
  const client = new ReapClient(
88
118
  "YOUR_PRIVATE_KEY",
89
- "https://base-sepolia.g.alchemy.com/v2/YOUR_KEY", // Custom RPC
90
- "https://api.reap.deals" // Middleware URL
119
+ "https://avax-fuji.g.alchemy.com/v2/YOUR_KEY", // Custom RPC
120
+ "https://avax2.api.reap.deals" // Middleware URL
91
121
  );
92
122
  ```
93
123
 
94
124
  ## โœจ Features
95
125
 
126
+ * **Agent Discovery**: Search thousands of AI Agents from MCP, x402, and A2A registries.
96
127
  * **JIT Stocking**: "Just-In-Time" inventory system. If an agent searches for an item not yet on the blockchain, the Protocol indexes it in real-time.
97
128
  * **Agentic Cart**: Automatically routes purchases through the Protocol's batch processor.
98
129
  * **Protocol Negotiation**: Built-in support for HTTP 402 Payment Negotiation loops.
99
- * **Gas Optimized**: Checks on-chain state before sending registration transactions.
130
+
131
+
100
132
 
101
133
  ## License
102
134
 
package/src/index.ts CHANGED
@@ -1,31 +1,90 @@
1
1
  import { ethers } from "ethers";
2
- import axios, { AxiosRequestConfig } from "axios";
2
+ import axios from "axios";
3
+
4
+ // ==========================================
5
+ // CONSTANTS & CONFIGURATION
6
+ // ==========================================
7
+
8
+ const HOLOCRON_ROUTER_ADDRESS = "0x2cEC5Bf3a0D3fEe4E13e8f2267176BdD579F4fd8";
9
+
10
+ const NETWORKS: Record<string, string> = {
11
+ "BASE": "https://sepolia.base.org",
12
+ "AVAX": "https://api.avax-test.network/ext/bc/C/rpc",
13
+ "CELO": "https://forno.celo-sepolia.celo-testnet.org"
14
+ };
15
+
16
+ const HOLOCRON_ABI = [
17
+ "function checkExistence(uint256 _c) view returns (bool)",
18
+ "function stock(uint256 _c) external"
19
+ ];
20
+
21
+ // --- Agent Registry Configuration ---
22
+ export type AgentRegistry = 'mcp' | 'x402' | 'a2a';
23
+
24
+ const REGISTRY_MAP: Record<AgentRegistry, string> = {
25
+ "mcp": "pulsemcp",
26
+ "x402": "coinbase-x402-bazaar",
27
+ "a2a": "a2a-registry"
28
+ };
29
+
30
+ const SEARCH_API_URL = "https://www.reap.deals/api/search-agents";
31
+
32
+ // ==========================================
33
+ // REAP CLIENT CLASS
34
+ // ==========================================
3
35
 
4
36
  export class ReapClient {
5
37
  private wallet: ethers.Wallet;
6
38
  private builderUrl: string;
7
39
  private provider: ethers.JsonRpcProvider;
40
+ private holocron: ethers.Contract;
41
+ private chainId: number = 43113;
8
42
 
9
43
  constructor(
10
44
  privateKey: string,
11
45
  chainRpc: string = "https://avalanche-fuji.drpc.org",
12
- builderUrl: string = "https://api.reap.deals"
46
+ builderUrl: string = "https://avax2.api.reap.deals"
13
47
  ) {
14
48
  this.provider = new ethers.JsonRpcProvider(chainRpc);
15
49
  this.wallet = new ethers.Wallet(privateKey, this.provider);
16
- this.builderUrl = builderUrl.replace(/\/$/, ""); // Remove trailing slash
17
- console.log(`๐Ÿค– Reap Agent Online: ${this.wallet.address}`);
50
+ this.builderUrl = builderUrl.replace(/\/$/, "");
51
+
52
+ // Initialize Holocron Contract
53
+ this.holocron = new ethers.Contract(HOLOCRON_ROUTER_ADDRESS, HOLOCRON_ABI, this.wallet);
54
+
55
+ this.init();
18
56
  }
19
57
 
20
58
  /**
21
- * Core Logic: Signs and Broadcasts transactions sequentially.
22
- * Uses manual nonce management to prevent RPC lag errors.
59
+ * Async initialization to fetch Chain ID
60
+ */
61
+ private async init() {
62
+ try {
63
+ const net = await this.provider.getNetwork();
64
+ this.chainId = Number(net.chainId);
65
+ console.log(`๐Ÿค– Reap Agent Online: ${this.wallet.address} (Chain: ${this.chainId})`);
66
+ } catch (e) {
67
+ console.error("โš ๏ธ Failed to fetch chain ID. Defaulting to 43113.");
68
+ }
69
+ }
70
+
71
+ // ==========================================
72
+ // CORE TRANSACTION LOGIC
73
+ // ==========================================
74
+
75
+ /**
76
+ * Execute Transactions with Nonce & Gas Fixes.
77
+ * Handles sequential nonce increments locally to prevent RPC lag.
23
78
  */
24
79
  private async executeTransactions(txList: any[]) {
25
80
  let lastReceipt;
26
81
 
27
82
  // 1. Fetch Nonce ONCE
28
83
  let currentNonce = await this.provider.getTransactionCount(this.wallet.address, "pending");
84
+
85
+ // 2. Gas Price Buffer (1.1x) for fast propagation
86
+ const feeData = await this.provider.getFeeData();
87
+ const gasPrice = feeData.gasPrice ? (feeData.gasPrice * 110n) / 100n : undefined;
29
88
 
30
89
  for (const txData of txList) {
31
90
  const label = txData.label || "Transaction";
@@ -35,33 +94,29 @@ export class ReapClient {
35
94
  to: txData.to,
36
95
  data: txData.data,
37
96
  value: BigInt(txData.value),
38
- gasLimit: 500000, // Safety limit
97
+ gasLimit: 500000, // Safe default limit
39
98
  nonce: currentNonce,
40
- chainId: (await this.provider.getNetwork()).chainId
99
+ chainId: this.chainId,
100
+ gasPrice: gasPrice
41
101
  };
42
102
 
43
103
  try {
44
- // 2. Sign & Send
45
104
  const response = await this.wallet.sendTransaction(tx);
46
105
  console.log(` ๐Ÿš€ Broadcasting: ${response.hash}`);
47
106
 
48
- // 3. Wait
49
107
  const receipt = await response.wait();
50
108
 
51
- // 4. Check Status (1 = Success, 0 = Revert)
52
109
  if (receipt && receipt.status === 0) {
53
110
  throw new Error(`Transaction Reverted! Hash: ${receipt.hash}`);
54
111
  }
55
112
 
56
113
  console.log(` โœ… Settled on-chain.`);
57
114
  lastReceipt = receipt;
58
-
59
- // 5. Increment Nonce
60
115
  currentNonce++;
61
116
 
62
117
  } catch (e: any) {
63
118
  console.error(` โŒ Tx Failed: ${e.message}`);
64
-
119
+ // Stop execution if payment or approval fails. Continue for others if needed.
65
120
  if (label.includes("Approve") || label.includes("Payment")) throw e;
66
121
  }
67
122
  }
@@ -70,23 +125,125 @@ export class ReapClient {
70
125
 
71
126
  private async callBuilder(endpoint: string, payload: any) {
72
127
  try {
73
- const { data } = await axios.post(`${this.builderUrl}${endpoint}`, payload);
74
- return data;
128
+ // Inject Chain ID for Middleware routing
129
+ payload.chain_id = this.chainId;
130
+ const { data } = await axios.post(`${this.builderUrl}${endpoint}`, payload);
131
+ return data;
75
132
  } catch (error: any) {
76
133
  const msg = error.response?.data?.detail || error.message;
77
134
  throw new Error(`Reap Protocol Error: ${msg}`);
78
135
  }
79
136
  }
80
137
 
81
- // --- PUBLIC API ---
138
+ // ==========================================
139
+ // HOLOCRON & SMART SYNC
140
+ // ==========================================
141
+
142
+ /**
143
+ * Check if a coordinate exists in the Holocron Registry.
144
+ */
145
+ async checkHolocron(coordinate: string) {
146
+ console.log(`๐Ÿ”Ž Scanning Holocron for ${coordinate}...`);
147
+
148
+ let exists = false;
149
+ try {
150
+ exists = await this.holocron.checkExistence(BigInt(coordinate));
151
+ } catch (e) { exists = false; }
152
+
153
+ console.log(` โ€ข Holocron Index: ${exists ? 'โœ… FOUND' : 'โŒ EMPTY'}`);
154
+ return exists;
155
+ }
156
+
157
+ /**
158
+ * Internal method to execute the 'stock' function on the Holocron.
159
+ */
160
+ private async indexToHolocron(coordinate: string) {
161
+ console.log(` ๐Ÿ“ Indexing Coordinate ${coordinate} to Holocron...`);
162
+
163
+ const nonce = await this.provider.getTransactionCount(this.wallet.address, "pending");
164
+ const feeData = await this.provider.getFeeData();
165
+ const gasPrice = feeData.gasPrice ? (feeData.gasPrice * 110n) / 100n : undefined;
82
166
 
83
- async getProduct(productId: string) {
84
- const safeId = encodeURIComponent(productId);
85
- const { data } = await axios.get(`${this.builderUrl}/read/product/${safeId}`);
86
- return data;
167
+ const tx = await this.holocron.stock(BigInt(coordinate), {
168
+ gasLimit: 150000,
169
+ nonce,
170
+ gasPrice
171
+ });
172
+
173
+ console.log(` ๐Ÿš€ Broadcast Holocron TX: ${tx.hash}`);
174
+ await tx.wait();
175
+ console.log(" โœ… Index Updated.");
176
+
177
+ // Small sleep to let RPC sync
178
+ await new Promise(r => setTimeout(r, 2000));
87
179
  }
88
180
 
89
- // ... inside ReapClient class ...
181
+ /**
182
+ * Smart Sync: Checks Holocron first.
183
+ * If item exists -> Skip registration (Save Gas).
184
+ * If missing -> Execute registration TX -> Index to Holocron.
185
+ */
186
+ async smartSync(item: any, transaction: any) {
187
+ const coordinate = item.id;
188
+
189
+ // 1. Check Status
190
+ const onHolocron = await this.checkHolocron(coordinate);
191
+
192
+ if (onHolocron) {
193
+ console.log("โšก๏ธ Fast Path: Item is indexed. Skipping registration.");
194
+ return;
195
+ }
196
+
197
+ console.log("\n๐Ÿข Syncing to Chain (Full Path)...");
198
+
199
+ // 2. Register Data (if transaction exists)
200
+ if (transaction) {
201
+ console.log(" ๐Ÿ”ธ Registering Data on-chain...");
202
+ // Wrap single transaction in array
203
+ await this.executeTransactions([transaction]);
204
+ } else {
205
+ console.log(" โš ๏ธ No registration transaction provided. Skipping to index.");
206
+ }
207
+
208
+ // 3. Index on Holocron
209
+ await this.indexToHolocron(coordinate);
210
+ }
211
+
212
+ // ==========================================
213
+ // AGENT DISCOVERY (NEW)
214
+ // ==========================================
215
+
216
+ /**
217
+ * Search for AI Agents across different registries (MCP, x402, A2A).
218
+ * @param query Keywords to search for (e.g. "customer support", "ecommerce")
219
+ * @param registry 'mcp' | 'x402' | 'a2a'
220
+ * @param limit Max results (default 40)
221
+ */
222
+ async searchAgents(query: string, registry: AgentRegistry = 'mcp', limit: number = 40) {
223
+ console.log(`๐Ÿ”Ž Searching Registry [${REGISTRY_MAP[registry]}] for: "${query}"...`);
224
+
225
+ try {
226
+ const payload = {
227
+ limit: limit,
228
+ query: query,
229
+ registry: REGISTRY_MAP[registry] // Maps 'mcp' -> 'pulsemcp', etc.
230
+ };
231
+
232
+ const response = await axios.post(SEARCH_API_URL, payload);
233
+ const hits = response.data.hits || [];
234
+
235
+ console.log(` โœ… Found ${hits.length} agents.`);
236
+ return hits;
237
+
238
+ } catch (error: any) {
239
+ console.error(" โŒ Search Failed:", error.message);
240
+ return [];
241
+ }
242
+ }
243
+
244
+ // ==========================================
245
+ // PUBLIC API (Commerce & Identity)
246
+ // ==========================================
90
247
 
91
248
  async registerIdentity(profileUri: string = "ipfs://default") {
92
249
  console.log("๐Ÿ†” Registering Protocol Identity...");
@@ -96,40 +253,45 @@ export class ReapClient {
96
253
  });
97
254
 
98
255
  if (res.status === "already_registered") {
99
- console.log(` โœ… Already Registered (Agent #${res.agent_id}). Skipping transaction.`);
256
+ console.log(` โœ… Already Registered (Agent #${res.agent_id}). Skipping.`);
100
257
  return null;
101
258
  }
102
-
103
259
  return this.executeTransactions(res.transactions);
104
260
  }
105
261
 
106
- async stockShelf(productQuery: string) {
107
- console.log(`๐Ÿ“ฆ Stocking Shelf: '${productQuery}'`);
262
+ /**
263
+ * Search for Products/Inventory.
264
+ * Use dryRun=true to get items without executing on-chain registration immediately.
265
+ */
266
+ async stockShelf(productQuery: string, dryRun: boolean = false) {
267
+ console.log(`๐Ÿ“ฆ Stocking Shelf: '${productQuery}' (Dry Run: ${dryRun})`);
268
+
108
269
  const res = await this.callBuilder("/build/inventory/stock", {
109
270
  product_query: productQuery,
110
271
  provider_address: this.wallet.address
111
272
  });
112
273
 
274
+ const items = res.meta?.items || [];
275
+ const transactions = res.transactions || [];
276
+
113
277
  if (res.status === "payment_required") {
114
- console.log("๐Ÿ›‘ 402 Payment Required via JSON Spec.");
115
- console.log(` ๐Ÿงพ Invoice: ${res.meta.description}`);
116
- } else {
117
- console.log(` ๐Ÿ” Found ${res.meta.count || 0} items.`);
278
+ console.log("๐Ÿ›‘ 402 Payment Required.");
279
+ if (dryRun) return { receipt: null, items: [] };
280
+ const receipt = await this.executeTransactions(transactions);
281
+ return { receipt, items: [] };
118
282
  }
119
283
 
120
- const receipt = await this.executeTransactions(res.transactions);
284
+ if (dryRun) {
285
+ console.log(` ๐Ÿ‘€ Preview: Found ${items.length} items. Cached ${transactions.length} TXs.`);
286
+ return { receipt: null, items, transactions };
287
+ }
121
288
 
122
- // --- THE FIX: Return both Receipt AND Items ---
123
- return {
124
- receipt,
125
- items: res.meta?.items || []
126
- };
127
- // ----------------------------------------------
289
+ const receipt = await this.executeTransactions(transactions);
290
+ return { receipt, items };
128
291
  }
129
292
 
130
293
  async buyProduct(productId: string) {
131
294
  console.log(`๐Ÿ’ธ Initiating Agentic Cart (Single Item): ${productId}`);
132
- // Route to batch endpoint
133
295
  const res = await this.callBuilder("/build/commerce/batch", {
134
296
  product_ids: [productId]
135
297
  });
@@ -143,36 +305,4 @@ async stockShelf(productQuery: string) {
143
305
  });
144
306
  return this.executeTransactions(res.transactions);
145
307
  }
146
-
147
- async fetch(url: string, config: AxiosRequestConfig = {}) {
148
- console.log(`๐ŸŒ Accessing ${url}...`);
149
- try {
150
- return await axios.get(url, config);
151
- } catch (error: any) {
152
- if (error.response && error.response.status === 402) {
153
- console.log("๐Ÿ›‘ x402 Payment Required. Engaging Protocol...");
154
- const header = error.response.headers["www-authenticate"];
155
-
156
- if (header && header.includes("X402")) {
157
- const match = header.match(/resource_id="([^"]+)"/);
158
- if (match && match[1]) {
159
- const rid = match[1];
160
-
161
- // Pay Protocol
162
- const receipt = await this.buyProduct(rid);
163
-
164
- if (!receipt) throw new Error("Payment Transaction failed");
165
- const proof = receipt.hash;
166
-
167
- console.log(` ๐Ÿ”„ Submitting Proof for Reactive Release: ${proof}`);
168
-
169
- // Release Data
170
- const newConfig = { ...config, headers: { ...config.headers, "Authorization": `X402-Proof ${proof}` } };
171
- return await axios.get(url, newConfig);
172
- }
173
- }
174
- }
175
- throw error;
176
- }
177
- }
178
308
  }