@reap-protocol/sdk 0.1.2 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reap-protocol/sdk",
3
- "version": "0.1.2",
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
@@ -24,8 +24,6 @@ import { ReapClient } from "@reap-protocol/sdk";
24
24
 
25
25
  // Load your private key securely
26
26
  const PRIVATE_KEY = process.env.MY_WALLET_KEY || "";
27
-
28
- // Optional: Use a specific RPC (e.g., Celo Alfajores or Avalanche Fuji)
29
27
  const CHAIN_RPC = "https://api.avax-test.network/ext/bc/C/rpc";
30
28
 
31
29
  async function main() {
@@ -97,6 +95,21 @@ npm install --save-dev ts-node typescript @types/node
97
95
  npx ts-node agent.ts
98
96
  ```
99
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
+
100
113
  ## 🔧 Configuration
101
114
 
102
115
  You can override defaults for custom RPCs or self-hosted middleware.
@@ -110,10 +123,12 @@ const client = new ReapClient(
110
123
 
111
124
  ## ✨ Features
112
125
 
126
+ * **Agent Discovery**: Search thousands of AI Agents from MCP, x402, and A2A registries.
113
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.
114
128
  * **Agentic Cart**: Automatically routes purchases through the Protocol's batch processor.
115
129
  * **Protocol Negotiation**: Built-in support for HTTP 402 Payment Negotiation loops.
116
- * **Gas Optimized**: Checks on-chain state before sending registration transactions.
130
+
131
+
117
132
 
118
133
  ## License
119
134
 
package/src/index.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { ethers } from "ethers";
2
- import axios, { AxiosRequestConfig } from "axios";
2
+ import axios from "axios";
3
+
4
+ // ==========================================
5
+ // CONSTANTS & CONFIGURATION
6
+ // ==========================================
3
7
 
4
8
  const HOLOCRON_ROUTER_ADDRESS = "0x2cEC5Bf3a0D3fEe4E13e8f2267176BdD579F4fd8";
5
9
 
@@ -9,12 +13,26 @@ const NETWORKS: Record<string, string> = {
9
13
  "CELO": "https://forno.celo-sepolia.celo-testnet.org"
10
14
  };
11
15
 
12
-
13
16
  const HOLOCRON_ABI = [
14
17
  "function checkExistence(uint256 _c) view returns (bool)",
15
18
  "function stock(uint256 _c) external"
16
19
  ];
17
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
+ // ==========================================
35
+
18
36
  export class ReapClient {
19
37
  private wallet: ethers.Wallet;
20
38
  private builderUrl: string;
@@ -37,22 +55,34 @@ export class ReapClient {
37
55
  this.init();
38
56
  }
39
57
 
58
+ /**
59
+ * Async initialization to fetch Chain ID
60
+ */
40
61
  private async init() {
41
- const net = await this.provider.getNetwork();
42
- this.chainId = Number(net.chainId);
43
- console.log(`🤖 Reap Agent Online: ${this.wallet.address} (Chain: ${this.chainId})`);
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
+ }
44
69
  }
45
70
 
71
+ // ==========================================
72
+ // CORE TRANSACTION LOGIC
73
+ // ==========================================
74
+
46
75
  /**
47
- * Execute Transactions with Nonce & Gas Fixes
76
+ * Execute Transactions with Nonce & Gas Fixes.
77
+ * Handles sequential nonce increments locally to prevent RPC lag.
48
78
  */
49
79
  private async executeTransactions(txList: any[]) {
50
80
  let lastReceipt;
51
81
 
52
- // FIX 1: Use pending nonce
82
+ // 1. Fetch Nonce ONCE
53
83
  let currentNonce = await this.provider.getTransactionCount(this.wallet.address, "pending");
54
84
 
55
- // FIX 2: Gas Price Buffer (1.1x)
85
+ // 2. Gas Price Buffer (1.1x) for fast propagation
56
86
  const feeData = await this.provider.getFeeData();
57
87
  const gasPrice = feeData.gasPrice ? (feeData.gasPrice * 110n) / 100n : undefined;
58
88
 
@@ -64,10 +94,10 @@ export class ReapClient {
64
94
  to: txData.to,
65
95
  data: txData.data,
66
96
  value: BigInt(txData.value),
67
- gasLimit: 500000,
97
+ gasLimit: 500000, // Safe default limit
68
98
  nonce: currentNonce,
69
99
  chainId: this.chainId,
70
- gasPrice: gasPrice // Apply buffered gas price
100
+ gasPrice: gasPrice
71
101
  };
72
102
 
73
103
  try {
@@ -86,6 +116,7 @@ export class ReapClient {
86
116
 
87
117
  } catch (e: any) {
88
118
  console.error(` ❌ Tx Failed: ${e.message}`);
119
+ // Stop execution if payment or approval fails. Continue for others if needed.
89
120
  if (label.includes("Approve") || label.includes("Payment")) throw e;
90
121
  }
91
122
  }
@@ -94,7 +125,7 @@ export class ReapClient {
94
125
 
95
126
  private async callBuilder(endpoint: string, payload: any) {
96
127
  try {
97
- // Inject Chain ID
128
+ // Inject Chain ID for Middleware routing
98
129
  payload.chain_id = this.chainId;
99
130
  const { data } = await axios.post(`${this.builderUrl}${endpoint}`, payload);
100
131
  return data;
@@ -104,8 +135,13 @@ export class ReapClient {
104
135
  }
105
136
  }
106
137
 
107
- // --- SMART AVAILABILITY (Holocron Only) ---
138
+ // ==========================================
139
+ // HOLOCRON & SMART SYNC
140
+ // ==========================================
108
141
 
142
+ /**
143
+ * Check if a coordinate exists in the Holocron Registry.
144
+ */
109
145
  async checkHolocron(coordinate: string) {
110
146
  console.log(`🔎 Scanning Holocron for ${coordinate}...`);
111
147
 
@@ -118,10 +154,12 @@ export class ReapClient {
118
154
  return exists;
119
155
  }
120
156
 
157
+ /**
158
+ * Internal method to execute the 'stock' function on the Holocron.
159
+ */
121
160
  private async indexToHolocron(coordinate: string) {
122
161
  console.log(` 📝 Indexing Coordinate ${coordinate} to Holocron...`);
123
162
 
124
- // Re-fetch nonce/gas
125
163
  const nonce = await this.provider.getTransactionCount(this.wallet.address, "pending");
126
164
  const feeData = await this.provider.getFeeData();
127
165
  const gasPrice = feeData.gasPrice ? (feeData.gasPrice * 110n) / 100n : undefined;
@@ -140,8 +178,11 @@ export class ReapClient {
140
178
  await new Promise(r => setTimeout(r, 2000));
141
179
  }
142
180
 
143
- // --- src/index.ts ---
144
-
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
+ */
145
186
  async smartSync(item: any, transaction: any) {
146
187
  const coordinate = item.id;
147
188
 
@@ -158,11 +199,8 @@ export class ReapClient {
158
199
  // 2. Register Data (if transaction exists)
159
200
  if (transaction) {
160
201
  console.log(" 🔸 Registering Data on-chain...");
161
-
162
- // ⚠️ THE FIX: Wrap the single 'transaction' object in brackets [ ]
163
- // to make it a list, because executeTransactions expects a list.
202
+ // Wrap single transaction in array
164
203
  await this.executeTransactions([transaction]);
165
-
166
204
  } else {
167
205
  console.log(" ⚠️ No registration transaction provided. Skipping to index.");
168
206
  }
@@ -171,7 +209,41 @@ export class ReapClient {
171
209
  await this.indexToHolocron(coordinate);
172
210
  }
173
211
 
174
- // --- PUBLIC API ---
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
+ // ==========================================
175
247
 
176
248
  async registerIdentity(profileUri: string = "ipfs://default") {
177
249
  console.log("🆔 Registering Protocol Identity...");
@@ -187,6 +259,10 @@ export class ReapClient {
187
259
  return this.executeTransactions(res.transactions);
188
260
  }
189
261
 
262
+ /**
263
+ * Search for Products/Inventory.
264
+ * Use dryRun=true to get items without executing on-chain registration immediately.
265
+ */
190
266
  async stockShelf(productQuery: string, dryRun: boolean = false) {
191
267
  console.log(`📦 Stocking Shelf: '${productQuery}' (Dry Run: ${dryRun})`);
192
268