@veridex/agentic-payments 0.1.1-beta.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/CHANGELOG.md +108 -0
- package/MIGRATION.md +307 -0
- package/README.md +395 -0
- package/dist/index.d.mts +2327 -0
- package/dist/index.d.ts +2327 -0
- package/dist/index.js +5815 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5759 -0
- package/dist/index.mjs.map +1 -0
- package/examples/basic-agent.ts +126 -0
- package/examples/mcp-claude.ts +75 -0
- package/examples/ucp-checkout.ts +92 -0
- package/examples/x402-integration.ts +75 -0
- package/package.json +36 -0
- package/src/AgentWallet.ts +432 -0
- package/src/chains/AptosChainClient.ts +29 -0
- package/src/chains/ChainClient.ts +73 -0
- package/src/chains/ChainClientFactory.ts +113 -0
- package/src/chains/EVMChainClient.ts +39 -0
- package/src/chains/SolanaChainClient.ts +37 -0
- package/src/chains/StarknetChainClient.ts +36 -0
- package/src/chains/SuiChainClient.ts +28 -0
- package/src/index.ts +83 -0
- package/src/mcp/MCPServer.ts +73 -0
- package/src/mcp/schemas.ts +60 -0
- package/src/monitoring/AlertManager.ts +258 -0
- package/src/monitoring/AuditLogger.ts +86 -0
- package/src/monitoring/BalanceCache.ts +44 -0
- package/src/monitoring/ComplianceExporter.ts +52 -0
- package/src/oracle/PythFeeds.ts +60 -0
- package/src/oracle/PythOracle.ts +121 -0
- package/src/performance/ConnectionPool.ts +217 -0
- package/src/performance/NonceManager.ts +91 -0
- package/src/performance/ParallelRouteFinder.ts +438 -0
- package/src/performance/TransactionPoller.ts +201 -0
- package/src/performance/TransactionQueue.ts +565 -0
- package/src/performance/index.ts +46 -0
- package/src/react/hooks.ts +298 -0
- package/src/routing/BridgeOrchestrator.ts +18 -0
- package/src/routing/CrossChainRouter.ts +501 -0
- package/src/routing/DEXAggregator.ts +448 -0
- package/src/routing/FeeEstimator.ts +43 -0
- package/src/session/SessionKeyManager.ts +312 -0
- package/src/session/SessionStorage.ts +80 -0
- package/src/session/SpendingTracker.ts +71 -0
- package/src/types/agent.ts +105 -0
- package/src/types/errors.ts +115 -0
- package/src/types/mcp.ts +22 -0
- package/src/types/ucp.ts +47 -0
- package/src/types/x402.ts +170 -0
- package/src/ucp/CapabilityNegotiator.ts +44 -0
- package/src/ucp/CredentialProvider.ts +73 -0
- package/src/ucp/PaymentTokenizer.ts +169 -0
- package/src/ucp/TransportAdapter.ts +18 -0
- package/src/ucp/UCPClient.ts +143 -0
- package/src/x402/NonceManager.ts +26 -0
- package/src/x402/PaymentParser.ts +225 -0
- package/src/x402/PaymentSigner.ts +305 -0
- package/src/x402/X402Client.ts +364 -0
- package/src/x402/adapters/CronosFacilitatorAdapter.ts +109 -0
- package/tests/alerts.test.ts +208 -0
- package/tests/chains.test.ts +242 -0
- package/tests/integration.test.ts +315 -0
- package/tests/monitoring.test.ts +435 -0
- package/tests/performance.test.ts +303 -0
- package/tests/property.test.ts +186 -0
- package/tests/react-hooks.test.ts +262 -0
- package/tests/session.test.ts +376 -0
- package/tests/ucp.test.ts +253 -0
- package/tests/x402.test.ts +385 -0
- package/tsconfig.json +26 -0
- package/tsup.config.ts +10 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @module ReactHooks
|
|
4
|
+
* @description
|
|
5
|
+
* React Hooks for integrating Agent functionality into web apps.
|
|
6
|
+
*
|
|
7
|
+
* Provides a set of convenient hooks (e.g., `useAgentWallet`, `usePayment`) that wrap
|
|
8
|
+
* the imperative SDK methods into reactive primitives.
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const { pay, isPaying } = usePayment(wallet);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { useState, useEffect, useCallback, createContext, useContext } from 'react';
|
|
17
|
+
import { AgentWallet } from '../AgentWallet';
|
|
18
|
+
import { AgentWalletConfig, SessionStatus, PaymentReceipt, SpendingAlert, HistoryOptions } from '../types/agent';
|
|
19
|
+
|
|
20
|
+
// Re-export HistoryOptions with different name to avoid conflict
|
|
21
|
+
export type { HistoryOptions as HookHistoryOptions } from '../types/agent';
|
|
22
|
+
|
|
23
|
+
// Context for sharing wallet instance
|
|
24
|
+
const AgentWalletContext = createContext<AgentWallet | null>(null);
|
|
25
|
+
|
|
26
|
+
export interface AgentWalletProviderProps {
|
|
27
|
+
config: AgentWalletConfig;
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Provider component for AgentWallet context.
|
|
33
|
+
*/
|
|
34
|
+
export function AgentWalletProvider(props: AgentWalletProviderProps): React.ReactElement {
|
|
35
|
+
const { wallet } = useAgentWallet(props.config);
|
|
36
|
+
|
|
37
|
+
// Use createElement to avoid JSX transpilation issues in .ts files
|
|
38
|
+
const { createElement } = require('react');
|
|
39
|
+
return createElement(
|
|
40
|
+
AgentWalletContext.Provider,
|
|
41
|
+
{ value: wallet },
|
|
42
|
+
props.children
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Hook to access the AgentWallet from context.
|
|
48
|
+
*/
|
|
49
|
+
export function useAgentWalletContext(): AgentWallet | null {
|
|
50
|
+
return useContext(AgentWalletContext);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Hook to create and manage an AgentWallet instance.
|
|
55
|
+
*/
|
|
56
|
+
export function useAgentWallet(config?: AgentWalletConfig) {
|
|
57
|
+
const [wallet, setWallet] = useState<AgentWallet | null>(null);
|
|
58
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
59
|
+
const [error, setError] = useState<Error | null>(null);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (config) {
|
|
63
|
+
setIsLoading(true);
|
|
64
|
+
setError(null);
|
|
65
|
+
const w = new AgentWallet(config);
|
|
66
|
+
w.init()
|
|
67
|
+
.then(() => {
|
|
68
|
+
setWallet(w);
|
|
69
|
+
setIsLoading(false);
|
|
70
|
+
})
|
|
71
|
+
.catch((err) => {
|
|
72
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
73
|
+
setIsLoading(false);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}, [config]);
|
|
77
|
+
|
|
78
|
+
return { wallet, isLoading, error };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Hook to get and refresh session status.
|
|
83
|
+
*/
|
|
84
|
+
export function useSessionStatus(wallet: AgentWallet | null) {
|
|
85
|
+
const [status, setStatus] = useState<SessionStatus | null>(null);
|
|
86
|
+
const [isExpired, setIsExpired] = useState(false);
|
|
87
|
+
|
|
88
|
+
const refreshStatus = useCallback(() => {
|
|
89
|
+
if (wallet) {
|
|
90
|
+
const newStatus = wallet.getSessionStatus();
|
|
91
|
+
setStatus(newStatus);
|
|
92
|
+
setIsExpired(newStatus ? newStatus.expiry < Date.now() : false);
|
|
93
|
+
} else {
|
|
94
|
+
setStatus(null);
|
|
95
|
+
setIsExpired(false);
|
|
96
|
+
}
|
|
97
|
+
}, [wallet]);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
refreshStatus();
|
|
101
|
+
const interval = setInterval(refreshStatus, 30000); // Refresh every 30s
|
|
102
|
+
return () => clearInterval(interval);
|
|
103
|
+
}, [refreshStatus]);
|
|
104
|
+
|
|
105
|
+
return { status, isExpired, refreshStatus };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Hook to fetch and manage payment history.
|
|
110
|
+
*/
|
|
111
|
+
export function usePaymentHistory(
|
|
112
|
+
wallet: AgentWallet | null,
|
|
113
|
+
options?: HistoryOptions
|
|
114
|
+
) {
|
|
115
|
+
const [history, setHistory] = useState<PaymentReceipt[]>([]);
|
|
116
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
117
|
+
const [error, setError] = useState<Error | null>(null);
|
|
118
|
+
|
|
119
|
+
const fetchHistory = useCallback(async () => {
|
|
120
|
+
if (!wallet) {
|
|
121
|
+
setHistory([]);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setIsLoading(true);
|
|
126
|
+
setError(null);
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
const result = await wallet.getPaymentHistory(options || {});
|
|
130
|
+
setHistory(result);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
133
|
+
} finally {
|
|
134
|
+
setIsLoading(false);
|
|
135
|
+
}
|
|
136
|
+
}, [wallet, options]);
|
|
137
|
+
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
fetchHistory();
|
|
140
|
+
}, [fetchHistory]);
|
|
141
|
+
|
|
142
|
+
return { history, isLoading, error, refreshHistory: fetchHistory };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Hook to subscribe to spending alerts.
|
|
147
|
+
*/
|
|
148
|
+
export function useSpendingAlerts(wallet: AgentWallet | null) {
|
|
149
|
+
const [alerts, setAlerts] = useState<SpendingAlert[]>([]);
|
|
150
|
+
const [latestAlert, setLatestAlert] = useState<SpendingAlert | null>(null);
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (!wallet) return;
|
|
154
|
+
|
|
155
|
+
// Subscribe to alerts - wallet.onSpendingAlert registers a callback
|
|
156
|
+
wallet.onSpendingAlert((alert: SpendingAlert) => {
|
|
157
|
+
setLatestAlert(alert);
|
|
158
|
+
setAlerts((prev) => [...prev, alert]);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Note: Current implementation doesn't return unsubscribe function
|
|
162
|
+
// Future improvement: add unsubscribe support to AlertManager
|
|
163
|
+
}, [wallet]);
|
|
164
|
+
|
|
165
|
+
const clearAlerts = useCallback(() => {
|
|
166
|
+
setAlerts([]);
|
|
167
|
+
setLatestAlert(null);
|
|
168
|
+
}, []);
|
|
169
|
+
|
|
170
|
+
return { alerts, latestAlert, clearAlerts };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ChainBalanceInfo {
|
|
174
|
+
chain: number;
|
|
175
|
+
chainName?: string;
|
|
176
|
+
token: string;
|
|
177
|
+
balance: bigint;
|
|
178
|
+
balanceUSD: number;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Hook to fetch balances across multiple chains.
|
|
183
|
+
*/
|
|
184
|
+
export function useMultiChainBalance(wallet: AgentWallet | null) {
|
|
185
|
+
const [balances, setBalances] = useState<ChainBalanceInfo[]>([]);
|
|
186
|
+
const [totalUSD, setTotalUSD] = useState(0);
|
|
187
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
188
|
+
const [error, setError] = useState<Error | null>(null);
|
|
189
|
+
|
|
190
|
+
const fetchBalances = useCallback(async () => {
|
|
191
|
+
if (!wallet) {
|
|
192
|
+
setBalances([]);
|
|
193
|
+
setTotalUSD(0);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
setIsLoading(true);
|
|
198
|
+
setError(null);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const result = await wallet.getMultiChainBalance();
|
|
202
|
+
// Convert PortfolioBalance to ChainBalanceInfo array
|
|
203
|
+
const balanceArray: ChainBalanceInfo[] = [];
|
|
204
|
+
if (result && typeof result === 'object') {
|
|
205
|
+
for (const [chainKey, chainBalances] of Object.entries(result)) {
|
|
206
|
+
if (Array.isArray(chainBalances)) {
|
|
207
|
+
for (const bal of chainBalances) {
|
|
208
|
+
balanceArray.push({
|
|
209
|
+
chain: parseInt(chainKey) || 0,
|
|
210
|
+
token: bal.token || 'native',
|
|
211
|
+
balance: BigInt(bal.balance || 0),
|
|
212
|
+
balanceUSD: bal.balanceUSD || 0,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
setBalances(balanceArray);
|
|
219
|
+
setTotalUSD(balanceArray.reduce((sum, b) => sum + b.balanceUSD, 0));
|
|
220
|
+
} catch (err) {
|
|
221
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
222
|
+
} finally {
|
|
223
|
+
setIsLoading(false);
|
|
224
|
+
}
|
|
225
|
+
}, [wallet]);
|
|
226
|
+
|
|
227
|
+
useEffect(() => {
|
|
228
|
+
fetchBalances();
|
|
229
|
+
}, [fetchBalances]);
|
|
230
|
+
|
|
231
|
+
return { balances, totalUSD, isLoading, error, refreshBalances: fetchBalances };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Hook for making payments with state management.
|
|
236
|
+
*/
|
|
237
|
+
export function usePayment(wallet: AgentWallet | null) {
|
|
238
|
+
const [isPaying, setIsPaying] = useState(false);
|
|
239
|
+
const [lastReceipt, setLastReceipt] = useState<PaymentReceipt | null>(null);
|
|
240
|
+
const [error, setError] = useState<Error | null>(null);
|
|
241
|
+
|
|
242
|
+
const pay = useCallback(
|
|
243
|
+
async (params: {
|
|
244
|
+
amount: string;
|
|
245
|
+
token: string;
|
|
246
|
+
recipient: string;
|
|
247
|
+
chain: number;
|
|
248
|
+
memo?: string;
|
|
249
|
+
}) => {
|
|
250
|
+
if (!wallet) {
|
|
251
|
+
throw new Error('Wallet not initialized');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
setIsPaying(true);
|
|
255
|
+
setError(null);
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
const receipt = await wallet.pay(params);
|
|
259
|
+
setLastReceipt(receipt);
|
|
260
|
+
return receipt;
|
|
261
|
+
} catch (err) {
|
|
262
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
263
|
+
setError(error);
|
|
264
|
+
throw error;
|
|
265
|
+
} finally {
|
|
266
|
+
setIsPaying(false);
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
[wallet]
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
return { pay, isPaying, lastReceipt, error };
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Hook for checking if wallet can make a payment.
|
|
277
|
+
*/
|
|
278
|
+
export function useCanPay(wallet: AgentWallet | null, amountUSD: number) {
|
|
279
|
+
const { status } = useSessionStatus(wallet);
|
|
280
|
+
|
|
281
|
+
const canPay = status
|
|
282
|
+
? status.isValid &&
|
|
283
|
+
amountUSD <= status.remainingDailyLimitUSD &&
|
|
284
|
+
status.expiry > Date.now()
|
|
285
|
+
: false;
|
|
286
|
+
|
|
287
|
+
const reason = !status
|
|
288
|
+
? 'No active session'
|
|
289
|
+
: !status.isValid
|
|
290
|
+
? 'Session not valid'
|
|
291
|
+
: amountUSD > status.remainingDailyLimitUSD
|
|
292
|
+
? 'Exceeds daily limit'
|
|
293
|
+
: status.expiry <= Date.now()
|
|
294
|
+
? 'Session expired'
|
|
295
|
+
: null;
|
|
296
|
+
|
|
297
|
+
return { canPay, reason };
|
|
298
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @module BridgeOrchestrator
|
|
4
|
+
* @description
|
|
5
|
+
* High-level orchestration for executing cross-chain bridges.
|
|
6
|
+
*
|
|
7
|
+
* Provides a unified interface to trigger Wormhole token transfers between any supported chains.
|
|
8
|
+
* It handles the complexities of:
|
|
9
|
+
* - Token approvals.
|
|
10
|
+
* - Bridge contract interactions.
|
|
11
|
+
* - Sequence tracking.
|
|
12
|
+
*/
|
|
13
|
+
export class BridgeOrchestrator {
|
|
14
|
+
async executeBridge(sourceChain: number, targetChain: number, amount: bigint): Promise<void> {
|
|
15
|
+
console.log(`Bridging ${amount} from ${sourceChain} to ${targetChain} via Wormhole...`);
|
|
16
|
+
// Implement bridge logic using @veridex/sdk and Wormhole
|
|
17
|
+
}
|
|
18
|
+
}
|