@relaycore/sdk 1.0.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/PUBLISHING.md +37 -0
- package/README.md +434 -0
- package/agent-sdk.ts +392 -0
- package/consumer-sdk.ts +434 -0
- package/dist/index.js +14116 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +14057 -0
- package/dist/index.mjs.map +1 -0
- package/hooks.ts +250 -0
- package/index.ts +153 -0
- package/lib/erc8004.ts +51 -0
- package/lib/facilitator.ts +65 -0
- package/lib/ipfs.ts +71 -0
- package/lib/supabase.ts +5 -0
- package/lib/x402.ts +220 -0
- package/package.json +38 -0
- package/provider-sdk.ts +311 -0
- package/relay-agent.ts +1414 -0
- package/relay-rwa.ts +128 -0
- package/relay-service.ts +886 -0
- package/tsconfig.json +23 -0
- package/tsup.config.ts +19 -0
- package/types/chat.types.ts +146 -0
- package/types/x402.types.ts +114 -0
package/hooks.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { useAccount, useWalletClient } from 'wagmi';
|
|
3
|
+
import { BrowserProvider } from 'ethers';
|
|
4
|
+
import {
|
|
5
|
+
createConsumerSDK,
|
|
6
|
+
type ServiceQuery,
|
|
7
|
+
type DiscoveredService,
|
|
8
|
+
type ServiceCallResult,
|
|
9
|
+
} from './consumer-sdk';
|
|
10
|
+
import {
|
|
11
|
+
createProviderSDK,
|
|
12
|
+
type ServiceRegistration,
|
|
13
|
+
type RegisteredService,
|
|
14
|
+
type ProviderReputation,
|
|
15
|
+
} from './provider-sdk';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* React hook for Service Consumer SDK
|
|
19
|
+
*
|
|
20
|
+
* Provides easy access to service discovery and calling functionality
|
|
21
|
+
* with automatic wallet integration via wagmi.
|
|
22
|
+
*/
|
|
23
|
+
export function useConsumerSDK(config?: { apiUrl?: string }) {
|
|
24
|
+
const { address } = useAccount();
|
|
25
|
+
const { data: walletClient } = useWalletClient();
|
|
26
|
+
|
|
27
|
+
const sdk = useMemo(() => {
|
|
28
|
+
const instance = createConsumerSDK({
|
|
29
|
+
apiUrl: config?.apiUrl,
|
|
30
|
+
network: 'mainnet',
|
|
31
|
+
});
|
|
32
|
+
return instance;
|
|
33
|
+
}, [config?.apiUrl]);
|
|
34
|
+
|
|
35
|
+
// Connect signer when wallet is available
|
|
36
|
+
const connectSigner = useCallback(async () => {
|
|
37
|
+
if (walletClient) {
|
|
38
|
+
const provider = new BrowserProvider(walletClient.transport);
|
|
39
|
+
const signer = await provider.getSigner();
|
|
40
|
+
sdk.connectSigner(signer);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}, [walletClient, sdk]);
|
|
45
|
+
|
|
46
|
+
const [loading, setLoading] = useState(false);
|
|
47
|
+
const [error, setError] = useState<string | null>(null);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Discover services matching criteria
|
|
51
|
+
*/
|
|
52
|
+
const discoverServices = useCallback(async (
|
|
53
|
+
query: ServiceQuery
|
|
54
|
+
): Promise<DiscoveredService[]> => {
|
|
55
|
+
setLoading(true);
|
|
56
|
+
setError(null);
|
|
57
|
+
try {
|
|
58
|
+
return await sdk.discoverServices(query);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
setError((err as Error).message);
|
|
61
|
+
return [];
|
|
62
|
+
} finally {
|
|
63
|
+
setLoading(false);
|
|
64
|
+
}
|
|
65
|
+
}, [sdk]);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get a single service
|
|
69
|
+
*/
|
|
70
|
+
const getService = useCallback(async (
|
|
71
|
+
serviceId: string
|
|
72
|
+
): Promise<DiscoveredService | null> => {
|
|
73
|
+
setLoading(true);
|
|
74
|
+
setError(null);
|
|
75
|
+
try {
|
|
76
|
+
return await sdk.getService(serviceId);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
setError((err as Error).message);
|
|
79
|
+
return null;
|
|
80
|
+
} finally {
|
|
81
|
+
setLoading(false);
|
|
82
|
+
}
|
|
83
|
+
}, [sdk]);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Call a service with automatic payment
|
|
87
|
+
*/
|
|
88
|
+
const callService = useCallback(async <T = unknown>(params: {
|
|
89
|
+
serviceId: string;
|
|
90
|
+
endpoint?: string;
|
|
91
|
+
method?: 'GET' | 'POST';
|
|
92
|
+
body?: unknown;
|
|
93
|
+
}): Promise<ServiceCallResult<T>> => {
|
|
94
|
+
setLoading(true);
|
|
95
|
+
setError(null);
|
|
96
|
+
try {
|
|
97
|
+
await connectSigner();
|
|
98
|
+
return await sdk.callService<T>(params);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
setError((err as Error).message);
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: (err as Error).message,
|
|
104
|
+
latencyMs: 0,
|
|
105
|
+
};
|
|
106
|
+
} finally {
|
|
107
|
+
setLoading(false);
|
|
108
|
+
}
|
|
109
|
+
}, [sdk, connectSigner]);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Find compatible services by type
|
|
113
|
+
*/
|
|
114
|
+
const findCompatible = useCallback(async (params: {
|
|
115
|
+
inputType?: string;
|
|
116
|
+
outputType?: string;
|
|
117
|
+
tags?: string[];
|
|
118
|
+
}): Promise<DiscoveredService[]> => {
|
|
119
|
+
setLoading(true);
|
|
120
|
+
setError(null);
|
|
121
|
+
try {
|
|
122
|
+
return await sdk.findCompatibleServices(params);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
setError((err as Error).message);
|
|
125
|
+
return [];
|
|
126
|
+
} finally {
|
|
127
|
+
setLoading(false);
|
|
128
|
+
}
|
|
129
|
+
}, [sdk]);
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
sdk,
|
|
133
|
+
address,
|
|
134
|
+
loading,
|
|
135
|
+
error,
|
|
136
|
+
discoverServices,
|
|
137
|
+
getService,
|
|
138
|
+
callService,
|
|
139
|
+
findCompatible,
|
|
140
|
+
connectSigner,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* React hook for Service Provider SDK
|
|
146
|
+
*
|
|
147
|
+
* Provides easy access to service registration and management
|
|
148
|
+
* with automatic wallet integration via wagmi.
|
|
149
|
+
*/
|
|
150
|
+
export function useProviderSDK(config?: { apiUrl?: string }) {
|
|
151
|
+
const { address } = useAccount();
|
|
152
|
+
const { data: walletClient } = useWalletClient();
|
|
153
|
+
|
|
154
|
+
const sdk = useMemo(() => {
|
|
155
|
+
if (!address) return null;
|
|
156
|
+
return createProviderSDK(address, {
|
|
157
|
+
apiUrl: config?.apiUrl,
|
|
158
|
+
});
|
|
159
|
+
}, [address, config?.apiUrl]);
|
|
160
|
+
|
|
161
|
+
// Connect signer when wallet is available
|
|
162
|
+
const connectSigner = useCallback(async () => {
|
|
163
|
+
if (walletClient && sdk) {
|
|
164
|
+
const provider = new BrowserProvider(walletClient.transport);
|
|
165
|
+
const signer = await provider.getSigner();
|
|
166
|
+
sdk.connectSigner(signer);
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
}, [walletClient, sdk]);
|
|
171
|
+
|
|
172
|
+
const [loading, setLoading] = useState(false);
|
|
173
|
+
const [error, setError] = useState<string | null>(null);
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Register a new service
|
|
177
|
+
*/
|
|
178
|
+
const registerService = useCallback(async (
|
|
179
|
+
service: ServiceRegistration
|
|
180
|
+
): Promise<RegisteredService | null> => {
|
|
181
|
+
if (!sdk) {
|
|
182
|
+
setError('Wallet not connected');
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
setLoading(true);
|
|
187
|
+
setError(null);
|
|
188
|
+
try {
|
|
189
|
+
return await sdk.registerService(service);
|
|
190
|
+
} catch (err) {
|
|
191
|
+
setError((err as Error).message);
|
|
192
|
+
return null;
|
|
193
|
+
} finally {
|
|
194
|
+
setLoading(false);
|
|
195
|
+
}
|
|
196
|
+
}, [sdk]);
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get provider reputation
|
|
200
|
+
*/
|
|
201
|
+
const getReputation = useCallback(async (): Promise<ProviderReputation | null> => {
|
|
202
|
+
if (!sdk) {
|
|
203
|
+
setError('Wallet not connected');
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
setLoading(true);
|
|
208
|
+
setError(null);
|
|
209
|
+
try {
|
|
210
|
+
return await sdk.getReputation();
|
|
211
|
+
} catch (err) {
|
|
212
|
+
setError((err as Error).message);
|
|
213
|
+
return null;
|
|
214
|
+
} finally {
|
|
215
|
+
setLoading(false);
|
|
216
|
+
}
|
|
217
|
+
}, [sdk]);
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get all services for this provider
|
|
221
|
+
*/
|
|
222
|
+
const getMyServices = useCallback(async (): Promise<RegisteredService[]> => {
|
|
223
|
+
if (!sdk) {
|
|
224
|
+
setError('Wallet not connected');
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
setLoading(true);
|
|
229
|
+
setError(null);
|
|
230
|
+
try {
|
|
231
|
+
return await sdk.getMyServices();
|
|
232
|
+
} catch (err) {
|
|
233
|
+
setError((err as Error).message);
|
|
234
|
+
return [];
|
|
235
|
+
} finally {
|
|
236
|
+
setLoading(false);
|
|
237
|
+
}
|
|
238
|
+
}, [sdk]);
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
sdk,
|
|
242
|
+
address,
|
|
243
|
+
loading,
|
|
244
|
+
error,
|
|
245
|
+
registerService,
|
|
246
|
+
getReputation,
|
|
247
|
+
getMyServices,
|
|
248
|
+
connectSigner,
|
|
249
|
+
};
|
|
250
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relay Core SDK
|
|
3
|
+
*
|
|
4
|
+
* Complete SDK for interacting with the Relay Core platform.
|
|
5
|
+
*
|
|
6
|
+
* NEW (Recommended):
|
|
7
|
+
* - RelayAgent - For AI agents to discover, decide, and execute
|
|
8
|
+
* - RelayService - For service providers to expose, deliver, and earn
|
|
9
|
+
*
|
|
10
|
+
* LEGACY (Still supported):
|
|
11
|
+
* - ServiceProviderSDK
|
|
12
|
+
* - ServiceConsumerSDK
|
|
13
|
+
* - AgentSDK
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// NEW IMPROVED SDKs (Recommended)
|
|
18
|
+
// =============================================================================
|
|
19
|
+
|
|
20
|
+
// RelayAgent - For AI agents
|
|
21
|
+
export {
|
|
22
|
+
RelayAgent,
|
|
23
|
+
createAgent,
|
|
24
|
+
type AgentConfig,
|
|
25
|
+
type TrustPolicy,
|
|
26
|
+
type ServiceCriteria,
|
|
27
|
+
type SelectedService,
|
|
28
|
+
type ExecutionResult,
|
|
29
|
+
type ExecutionError,
|
|
30
|
+
type ErrorCode,
|
|
31
|
+
type WorkflowStep as AgentWorkflowStep,
|
|
32
|
+
type WorkflowResult,
|
|
33
|
+
type OutcomeRecord as AgentOutcome,
|
|
34
|
+
type AgentMemory,
|
|
35
|
+
type AgentCard,
|
|
36
|
+
type AgentCardResource,
|
|
37
|
+
type TaskArtifact,
|
|
38
|
+
type TaskState,
|
|
39
|
+
type TaskStats,
|
|
40
|
+
} from './relay-agent';
|
|
41
|
+
|
|
42
|
+
// RelayService - For service providers
|
|
43
|
+
export {
|
|
44
|
+
RelayService,
|
|
45
|
+
createService,
|
|
46
|
+
defineService,
|
|
47
|
+
hashProof,
|
|
48
|
+
createPaymentMiddleware,
|
|
49
|
+
type ServiceConfig,
|
|
50
|
+
type ServiceDefinition,
|
|
51
|
+
type RegisteredService as ServiceRegistered,
|
|
52
|
+
type PaymentContext,
|
|
53
|
+
type DeliveryProof,
|
|
54
|
+
type PaymentStatus,
|
|
55
|
+
type PaymentEvent,
|
|
56
|
+
type OutcomeType,
|
|
57
|
+
type OutcomeRecord as ServiceOutcome,
|
|
58
|
+
type ServiceMetrics as ServiceMetricsData,
|
|
59
|
+
type ProviderReputation as ServiceReputation,
|
|
60
|
+
type PaymentRequirements as ServicePaymentRequirements,
|
|
61
|
+
type ServiceLogger,
|
|
62
|
+
type JsonSchema,
|
|
63
|
+
} from './relay-service';
|
|
64
|
+
|
|
65
|
+
// =============================================================================
|
|
66
|
+
// LEGACY SDKs (Backwards compatible)
|
|
67
|
+
// =============================================================================
|
|
68
|
+
|
|
69
|
+
// Provider SDK - For registering and managing services
|
|
70
|
+
export {
|
|
71
|
+
ServiceProviderSDK,
|
|
72
|
+
createProviderSDK,
|
|
73
|
+
type ProviderSDKConfig,
|
|
74
|
+
type ServiceRegistration,
|
|
75
|
+
type RegisteredService,
|
|
76
|
+
type ProviderReputation,
|
|
77
|
+
type PaymentReceived,
|
|
78
|
+
type ServiceMetrics,
|
|
79
|
+
} from './provider-sdk';
|
|
80
|
+
|
|
81
|
+
// Consumer SDK - For discovering and calling services
|
|
82
|
+
export {
|
|
83
|
+
ServiceConsumerSDK,
|
|
84
|
+
createConsumerSDK,
|
|
85
|
+
type ConsumerSDKConfig,
|
|
86
|
+
type ServiceQuery,
|
|
87
|
+
type DiscoveredService,
|
|
88
|
+
type PaymentResult,
|
|
89
|
+
type ServiceCallResult,
|
|
90
|
+
type WorkflowStep,
|
|
91
|
+
} from './consumer-sdk';
|
|
92
|
+
|
|
93
|
+
// Legacy Agent SDK (for backwards compatibility)
|
|
94
|
+
export {
|
|
95
|
+
AgentSDK,
|
|
96
|
+
createAgentSDK,
|
|
97
|
+
type AgentService,
|
|
98
|
+
type AgentProfile,
|
|
99
|
+
} from './agent-sdk';
|
|
100
|
+
|
|
101
|
+
// Re-export types for convenience
|
|
102
|
+
export type { PaymentRequirements } from '@crypto.com/facilitator-client';
|
|
103
|
+
|
|
104
|
+
// =============================================================================
|
|
105
|
+
// X402 PROTOCOL (Cronos Standard)
|
|
106
|
+
// =============================================================================
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
requireX402,
|
|
110
|
+
handleX402Settlement,
|
|
111
|
+
generatePaymentId,
|
|
112
|
+
isEntitled,
|
|
113
|
+
getEntitlement,
|
|
114
|
+
recordEntitlement,
|
|
115
|
+
createPaymentRequirements,
|
|
116
|
+
} from './lib/x402';
|
|
117
|
+
|
|
118
|
+
export type {
|
|
119
|
+
X402Accepts,
|
|
120
|
+
X402Response,
|
|
121
|
+
X402PaidRecord,
|
|
122
|
+
X402PayResult,
|
|
123
|
+
X402ProtectionOptions,
|
|
124
|
+
X402PayParams,
|
|
125
|
+
} from './types/x402.types';
|
|
126
|
+
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// CHAT TYPES (Control Plane Architecture)
|
|
129
|
+
// =============================================================================
|
|
130
|
+
|
|
131
|
+
export type {
|
|
132
|
+
ChatMode,
|
|
133
|
+
ChatResponseType,
|
|
134
|
+
ChatRequest,
|
|
135
|
+
ChatResponse,
|
|
136
|
+
ChatAction,
|
|
137
|
+
SimulationResult,
|
|
138
|
+
} from './types/chat.types';
|
|
139
|
+
|
|
140
|
+
export { CHAT_CAPABILITIES, PROHIBITED_OPERATIONS } from './types/chat.types';
|
|
141
|
+
|
|
142
|
+
// =============================================================================
|
|
143
|
+
// RWA SDK (State Machine & Asset Management)
|
|
144
|
+
// =============================================================================
|
|
145
|
+
|
|
146
|
+
export {
|
|
147
|
+
RelayRWASDK,
|
|
148
|
+
createRWASDK,
|
|
149
|
+
type RWAConfig,
|
|
150
|
+
type RWAStateMachine,
|
|
151
|
+
type TransitionParams,
|
|
152
|
+
type TransitionResult
|
|
153
|
+
} from './relay-rwa';
|
package/lib/erc8004.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
|
|
3
|
+
const IDENTITY_REGISTRY_ABI = [
|
|
4
|
+
'function registerAgent(string memory agentURI, address walletAddress) external returns (uint256)',
|
|
5
|
+
'event AgentRegistered(uint256 indexed agentId, address indexed owner, string agentURI, address walletAddress)',
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
export async function registerAgent(
|
|
9
|
+
agentURI: string,
|
|
10
|
+
walletAddress: string,
|
|
11
|
+
signer: ethers.Signer,
|
|
12
|
+
contractAddress: string
|
|
13
|
+
): Promise<{ agentId: number; txHash: string }> {
|
|
14
|
+
try {
|
|
15
|
+
if (!contractAddress) {
|
|
16
|
+
throw new Error('Identity Registry address not configured');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const identityRegistry = new ethers.Contract(
|
|
20
|
+
contractAddress,
|
|
21
|
+
IDENTITY_REGISTRY_ABI,
|
|
22
|
+
signer
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const tx = await identityRegistry.registerAgent(agentURI, walletAddress);
|
|
26
|
+
const receipt = await tx.wait();
|
|
27
|
+
|
|
28
|
+
// Extract agentId from event
|
|
29
|
+
const event = receipt.logs.find((log: any) => {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = identityRegistry.interface.parseLog(log);
|
|
32
|
+
return parsed?.name === 'AgentRegistered';
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (event) {
|
|
39
|
+
const parsed = identityRegistry.interface.parseLog(event);
|
|
40
|
+
return {
|
|
41
|
+
agentId: Number(parsed?.args.agentId),
|
|
42
|
+
txHash: receipt.hash,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw new Error('AgentRegistered event not found');
|
|
47
|
+
} catch (error: any) {
|
|
48
|
+
console.error('Failed to register agent:', error);
|
|
49
|
+
throw new Error(`Agent registration failed: ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Facilitator, type PaymentRequirements, CronosNetwork } from '@crypto.com/facilitator-client';
|
|
2
|
+
|
|
3
|
+
export class FacilitatorClient {
|
|
4
|
+
private facilitator: Facilitator;
|
|
5
|
+
|
|
6
|
+
constructor(network: CronosNetwork = 'cronos-testnet', privateKey?: string) {
|
|
7
|
+
// If privateKey is provided, set it in process.env for the Facilitator SDK to pick up
|
|
8
|
+
// Note: The Facilitator SDK currently relies on process.env.WALLET_PRIVATE_KEY
|
|
9
|
+
if (privateKey) {
|
|
10
|
+
process.env.WALLET_PRIVATE_KEY = privateKey;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.facilitator = new Facilitator({ network });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async settlePayment(params: {
|
|
17
|
+
paymentHeader: string;
|
|
18
|
+
paymentRequirements: PaymentRequirements;
|
|
19
|
+
}) {
|
|
20
|
+
try {
|
|
21
|
+
// Build the verify request
|
|
22
|
+
const verifyRequest = this.facilitator.buildVerifyRequest(
|
|
23
|
+
params.paymentHeader,
|
|
24
|
+
params.paymentRequirements
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Step 1: Verify the EIP-3009 authorization
|
|
28
|
+
const verifyResult = await this.facilitator.verifyPayment(verifyRequest);
|
|
29
|
+
|
|
30
|
+
if (!verifyResult.isValid) {
|
|
31
|
+
throw new Error('Payment verification failed: Invalid signature or parameters');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Step 2: Settle the payment on-chain
|
|
35
|
+
const settleResult = await this.facilitator.settlePayment(verifyRequest);
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
success: true,
|
|
39
|
+
txHash: settleResult.txHash,
|
|
40
|
+
timestamp: Date.now(),
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error('Payment settlement error', error);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
generatePaymentRequirements(params: {
|
|
49
|
+
merchantAddress: string;
|
|
50
|
+
amount: string;
|
|
51
|
+
resourceUrl: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
}): PaymentRequirements {
|
|
54
|
+
return this.facilitator.generatePaymentRequirements({
|
|
55
|
+
payTo: params.merchantAddress,
|
|
56
|
+
maxAmountRequired: params.amount,
|
|
57
|
+
resource: params.resourceUrl,
|
|
58
|
+
description: params.description || 'Protected resource access',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getFacilitator(): Facilitator {
|
|
63
|
+
return this.facilitator;
|
|
64
|
+
}
|
|
65
|
+
}
|
package/lib/ipfs.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPFS Metadata Service (SDK Version)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface AgentMetadata {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
image?: string;
|
|
9
|
+
external_url?: string;
|
|
10
|
+
attributes: {
|
|
11
|
+
trait_type: string;
|
|
12
|
+
value: string | number;
|
|
13
|
+
}[];
|
|
14
|
+
service_type: string;
|
|
15
|
+
endpoint: string;
|
|
16
|
+
price_per_request: string;
|
|
17
|
+
version: string;
|
|
18
|
+
created_at: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function uploadAgentMetadataToIPFS(
|
|
22
|
+
metadata: AgentMetadata,
|
|
23
|
+
apiBaseUrl: string
|
|
24
|
+
): Promise<string> {
|
|
25
|
+
try {
|
|
26
|
+
const response = await fetch(`${apiBaseUrl}/api/ipfs/upload-metadata`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(metadata),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const error = await response.json();
|
|
36
|
+
throw new Error(error.error || 'IPFS upload failed');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result = await response.json();
|
|
40
|
+
return result.ipfsUri;
|
|
41
|
+
} catch (error: unknown) {
|
|
42
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
43
|
+
throw new Error(`Failed to upload to IPFS: ${message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildAgentMetadata(params: {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
serviceType: string;
|
|
51
|
+
endpoint: string;
|
|
52
|
+
pricePerRequest: string;
|
|
53
|
+
imageUri?: string;
|
|
54
|
+
}): AgentMetadata {
|
|
55
|
+
return {
|
|
56
|
+
name: params.name,
|
|
57
|
+
description: params.description,
|
|
58
|
+
image: params.imageUri,
|
|
59
|
+
external_url: 'https://relaycore.xyz',
|
|
60
|
+
attributes: [
|
|
61
|
+
{ trait_type: 'Service Type', value: params.serviceType },
|
|
62
|
+
{ trait_type: 'Network', value: 'Cronos Testnet' },
|
|
63
|
+
{ trait_type: 'Protocol', value: 'x402' },
|
|
64
|
+
],
|
|
65
|
+
service_type: params.serviceType,
|
|
66
|
+
endpoint: params.endpoint,
|
|
67
|
+
price_per_request: params.pricePerRequest,
|
|
68
|
+
version: '1.0.0',
|
|
69
|
+
created_at: new Date().toISOString(),
|
|
70
|
+
};
|
|
71
|
+
}
|