@teneo-protocol/sdk 2.2.2 → 3.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/.github/ISSUE_TEMPLATE/config.yml +1 -1
- package/CHANGELOG.md +366 -15
- package/CONCEPTS.md +182 -44
- package/README.md +524 -94
- package/dist/constants.d.ts +3 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -3
- package/dist/constants.js.map +1 -1
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +9 -5
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/formatters/response-formatter.d.ts +6 -6
- package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +756 -756
- package/dist/handlers/message-handlers/agent-details-response-handler.js +2 -2
- package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/agent-error-handler.d.ts +91 -0
- package/dist/handlers/message-handlers/agent-error-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-error-handler.js +44 -0
- package/dist/handlers/message-handlers/agent-error-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +756 -756
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.js +2 -7
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -1
- package/dist/handlers/message-handlers/all-agents-response-handler.js +2 -2
- package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +6 -1
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +6 -1
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/base-handler.d.ts +2 -1
- package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/base-handler.js +24 -4
- package/dist/handlers/message-handlers/base-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +4 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +23 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +792 -756
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.js +23 -10
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -1
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +756 -756
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-room-agents-handler.js +2 -6
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -1
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/list-rooms-response-handler.js +2 -5
- package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +52 -4
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.js +23 -4
- package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
- package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js +3 -2
- package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +12 -6
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/success-handler.d.ts +82 -0
- package/dist/handlers/message-handlers/success-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/success-handler.js +24 -0
- package/dist/handlers/message-handlers/success-handler.js.map +1 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.d.ts +110 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.js +46 -0
- package/dist/handlers/message-handlers/task-confirmed-handler.js.map +1 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts +244 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js +58 -0
- package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js.map +1 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +12 -6
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/user-authenticated-handler.js +2 -2
- package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -1
- package/dist/handlers/message-handlers/user-count-handler.js +2 -2
- package/dist/handlers/message-handlers/user-count-handler.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/managers/admin-manager.d.ts +2 -0
- package/dist/managers/admin-manager.d.ts.map +1 -1
- package/dist/managers/admin-manager.js +3 -2
- package/dist/managers/admin-manager.js.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +89 -11
- package/dist/managers/agent-room-manager.d.ts.map +1 -1
- package/dist/managers/agent-room-manager.js +99 -35
- package/dist/managers/agent-room-manager.js.map +1 -1
- package/dist/managers/index.d.ts +1 -1
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/message-router.d.ts +45 -5
- package/dist/managers/message-router.d.ts.map +1 -1
- package/dist/managers/message-router.js +96 -24
- package/dist/managers/message-router.js.map +1 -1
- package/dist/managers/room-manager.d.ts +29 -7
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js +37 -11
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/payments/index.d.ts +3 -1
- package/dist/payments/index.d.ts.map +1 -1
- package/dist/payments/index.js +17 -3
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/networks.d.ts +59 -0
- package/dist/payments/networks.d.ts.map +1 -0
- package/dist/payments/networks.js +192 -0
- package/dist/payments/networks.js.map +1 -0
- package/dist/payments/payment-client.d.ts +55 -10
- package/dist/payments/payment-client.d.ts.map +1 -1
- package/dist/payments/payment-client.js +172 -51
- package/dist/payments/payment-client.js.map +1 -1
- package/dist/teneo-sdk.d.ts +214 -40
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +360 -83
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +334 -25
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +114 -22
- package/dist/types/config.js.map +1 -1
- package/dist/types/events.d.ts +60 -14
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +11 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +9801 -7222
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +180 -40
- package/dist/types/messages.js.map +1 -1
- package/dist/utils/pricing-resolver.d.ts +1 -1
- package/dist/utils/pricing-resolver.d.ts.map +1 -1
- package/dist/utils/pricing-resolver.js +9 -1
- package/dist/utils/pricing-resolver.js.map +1 -1
- package/examples/agent-room-management-example.ts +5 -5
- package/examples/basic-usage.ts +26 -6
- package/examples/claude-agent-x-follower/index.ts +1 -1
- package/examples/minimal-chat.ts +4 -3
- package/examples/n8n-teneo/index.ts +2 -2
- package/examples/nestjs-dashboard/README.md +1 -1
- package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +3 -3
- package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +5 -5
- package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +8 -8
- package/examples/openai-teneo/index.ts +1 -1
- package/examples/payment-flow.ts +143 -0
- package/examples/production-dashboard/README.md +6 -8
- package/examples/production-dashboard/server.ts +22 -10
- package/examples/room-management-example.ts +2 -2
- package/examples/usage/01-connect.ts +0 -3
- package/examples/usage/02-list-agents.ts +0 -2
- package/examples/usage/03-pick-agent.ts +3 -4
- package/examples/usage/04-find-by-capability.ts +10 -12
- package/examples/usage/05-webhook-example.ts +2 -4
- package/examples/usage/06-simple-api-server.ts +13 -9
- package/examples/usage/07-event-listener.ts +1 -13
- package/examples/usage/README.md +33 -7
- package/examples/webhook-integration.ts +9 -9
- package/examples/x-influencer-battle-server.ts +1 -1
- package/package.json +1 -1
- package/scripts/diagnose-connection.ts +86 -0
- package/scripts/investigate-payload.ts +163 -0
- package/scripts/list-agents.ts +58 -0
- package/scripts/live-multi-network-test.ts +230 -0
- package/src/constants.ts +5 -3
- package/src/core/websocket-client.ts +10 -9
- package/src/handlers/message-handlers/agent-details-response-handler.ts +2 -2
- package/src/handlers/message-handlers/agent-error-handler.ts +47 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +2 -7
- package/src/handlers/message-handlers/all-agents-response-handler.ts +2 -2
- package/src/handlers/message-handlers/auth-message-handler.ts +7 -1
- package/src/handlers/message-handlers/auth-success-handler.ts +7 -1
- package/src/handlers/message-handlers/base-handler.ts +24 -4
- package/src/handlers/message-handlers/index.ts +24 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +24 -11
- package/src/handlers/message-handlers/list-room-agents-handler.ts +2 -6
- package/src/handlers/message-handlers/list-rooms-response-handler.ts +2 -5
- package/src/handlers/message-handlers/ping-pong-handler.ts +29 -4
- package/src/handlers/message-handlers/rate-limit-notification-handler.ts +3 -2
- package/src/handlers/message-handlers/success-handler.ts +26 -0
- package/src/handlers/message-handlers/task-confirmed-handler.ts +49 -0
- package/src/handlers/message-handlers/trigger-wallet-tx-handler.ts +62 -0
- package/src/handlers/message-handlers/user-authenticated-handler.ts +2 -2
- package/src/handlers/message-handlers/user-count-handler.ts +2 -2
- package/src/index.ts +12 -4
- package/src/managers/admin-manager.ts +5 -2
- package/src/managers/agent-room-manager.ts +155 -26
- package/src/managers/index.ts +6 -1
- package/src/managers/message-router.ts +122 -27
- package/src/managers/room-manager.ts +39 -11
- package/src/payments/index.ts +20 -5
- package/src/payments/networks.ts +208 -0
- package/src/payments/payment-client.ts +211 -56
- package/src/teneo-sdk.ts +401 -70
- package/src/types/config.test.ts +24 -4
- package/src/types/config.ts +123 -25
- package/src/types/events.ts +36 -2
- package/src/types/index.ts +16 -3
- package/src/types/messages.ts +221 -57
- package/src/utils/pricing-resolver.ts +10 -2
- package/tests/direct-agent-test.ts +1 -1
- package/tests/integration/real-server.test.ts +1 -1
- package/tests/integration/websocket.test.ts +3 -3
- package/tests/multi-network-payment.test.ts +309 -0
- package/tests/multi-network.test.ts +296 -0
- package/tests/payment-flow-test.ts +6 -4
- package/tests/unit/handlers/agent-error-handler.test.ts +388 -0
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +9 -6
- package/tests/unit/handlers/agent-status-update-handler.test.ts +11 -16
- package/tests/unit/handlers/list-available-agents-handler.test.ts +11 -14
- package/tests/unit/handlers/list-room-agents-handler.test.ts +11 -15
- package/tests/unit/handlers/room-operation-response-handler.test.ts +9 -6
- package/tests/unit/handlers/trigger-wallet-tx-handler.test.ts +431 -0
- package/tests/unit/managers/admin-manager.test.ts +183 -0
- package/tests/unit/managers/agent-room-manager.test.ts +189 -33
- package/tests/unit/sdk-new-methods.test.ts +221 -0
|
@@ -1,37 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PaymentClient - Handles x402 payment header generation for quote-approve flow
|
|
3
3
|
*
|
|
4
|
-
* Creates x402 V2 payment headers for USDC payments on
|
|
4
|
+
* Creates x402 V2 payment headers for USDC payments on multiple networks.
|
|
5
5
|
* Implements ERC-3009 TransferWithAuthorization signing using viem's EIP-712.
|
|
6
|
+
*
|
|
7
|
+
* v2.3.0: Multi-network support with dynamic chain configuration
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
|
-
import {
|
|
10
|
+
import { type Hex, toHex, keccak256, encodePacked } from "viem";
|
|
9
11
|
import { privateKeyToAccount, signTypedData } from "viem/accounts";
|
|
10
12
|
import type { SecurePrivateKey } from "../utils/secure-private-key";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
nativeCurrency: {
|
|
18
|
-
decimals: 18,
|
|
19
|
-
name: "PEAQ",
|
|
20
|
-
symbol: "PEAQ"
|
|
21
|
-
},
|
|
22
|
-
rpcUrls: {
|
|
23
|
-
default: {
|
|
24
|
-
http: ["https://peaq.api.onfinality.io/public"]
|
|
25
|
-
},
|
|
26
|
-
public: {
|
|
27
|
-
http: ["https://peaq.api.onfinality.io/public"]
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// USDC contract on PEAQ
|
|
33
|
-
const USDC_CONTRACT = "0xbbA60da06c2c5424f03f7434542280FCAd453d10";
|
|
34
|
-
const PEAQ_NETWORK_CAIP2 = "eip155:3338";
|
|
13
|
+
import {
|
|
14
|
+
getNetwork,
|
|
15
|
+
getDefaultNetwork,
|
|
16
|
+
createChainDefinition,
|
|
17
|
+
type NetworkConfig
|
|
18
|
+
} from "./networks";
|
|
35
19
|
|
|
36
20
|
// ERC-3009 TransferWithAuthorization EIP-712 types
|
|
37
21
|
const ERC3009_TYPES = {
|
|
@@ -46,8 +30,9 @@ const ERC3009_TYPES = {
|
|
|
46
30
|
} as const;
|
|
47
31
|
|
|
48
32
|
export interface PaymentClientConfig {
|
|
49
|
-
network?: string; // CAIP-2 format
|
|
50
|
-
|
|
33
|
+
network?: string; // Network name (peaq, base, avalanche) or CAIP-2 format
|
|
34
|
+
networkChainId?: number; // Or chain ID directly
|
|
35
|
+
asset?: string; // Optional override for asset contract
|
|
51
36
|
resourceUrl?: string; // x402 resource URL
|
|
52
37
|
}
|
|
53
38
|
|
|
@@ -56,11 +41,10 @@ export const USDC_DECIMALS = 6;
|
|
|
56
41
|
export const X402_VERSION = 2;
|
|
57
42
|
export const DEFAULT_PAYMENT_TIMEOUT_SECONDS = 60;
|
|
58
43
|
export const DEFAULT_PAY_TO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
59
|
-
export const DEFAULT_RPC_URL = "https://peaq.api.onfinality.io/public";
|
|
60
|
-
export type SupportedChain = "peaq";
|
|
61
44
|
|
|
62
|
-
// Re-export
|
|
63
|
-
export
|
|
45
|
+
// Re-export for backwards compatibility
|
|
46
|
+
export const USDC_CONTRACT = "0xbbA60da06c2c5424f03f7434542280FCAd453d10"; // PEAQ USDC
|
|
47
|
+
export const PEAQ_CHAIN_ID = "eip155:3338";
|
|
64
48
|
|
|
65
49
|
/**
|
|
66
50
|
* Converts a WebSocket URL to an HTTP(S) URL for x402 resource specification.
|
|
@@ -108,15 +92,71 @@ function generateNonce(): Hex {
|
|
|
108
92
|
return toHex(randomBytes);
|
|
109
93
|
}
|
|
110
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Settlement data provided by backend in task_quote response.
|
|
97
|
+
* Used for x402x-router-settlement extension.
|
|
98
|
+
*/
|
|
99
|
+
export interface SettlementData {
|
|
100
|
+
settlementRouter: string;
|
|
101
|
+
salt: string;
|
|
102
|
+
facilitatorFee: string;
|
|
103
|
+
hook: string;
|
|
104
|
+
hookData: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Validates that a string is a valid Ethereum address
|
|
109
|
+
* @param address - String to validate
|
|
110
|
+
* @returns True if valid Ethereum address format
|
|
111
|
+
*/
|
|
112
|
+
function isValidEthereumAddress(address: string): boolean {
|
|
113
|
+
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Resolve network configuration from various input formats
|
|
118
|
+
*
|
|
119
|
+
* @param config - PaymentClientConfig with network options
|
|
120
|
+
* @returns Resolved NetworkConfig
|
|
121
|
+
*/
|
|
122
|
+
function resolveNetworkConfig(config: PaymentClientConfig): NetworkConfig {
|
|
123
|
+
// Priority: chainId > network name > default
|
|
124
|
+
if (config.networkChainId) {
|
|
125
|
+
return getNetwork(config.networkChainId);
|
|
126
|
+
}
|
|
127
|
+
if (config.network) {
|
|
128
|
+
return getNetwork(config.network);
|
|
129
|
+
}
|
|
130
|
+
return getDefaultNetwork();
|
|
131
|
+
}
|
|
132
|
+
|
|
111
133
|
/**
|
|
112
134
|
* PaymentClient handles creation of x402 V2 payment headers
|
|
113
135
|
* for the quote-approve payment flow.
|
|
136
|
+
*
|
|
137
|
+
* Supports multiple networks with dynamic configuration.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* // Default network (PEAQ or TENEO_NETWORK env var)
|
|
142
|
+
* const client = new PaymentClient(secureKey, walletAddress);
|
|
143
|
+
*
|
|
144
|
+
* // Specific network by name
|
|
145
|
+
* const baseClient = new PaymentClient(secureKey, walletAddress, {
|
|
146
|
+
* network: "base"
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* // Specific network by chain ID
|
|
150
|
+
* const avaxClient = new PaymentClient(secureKey, walletAddress, {
|
|
151
|
+
* networkChainId: 43114
|
|
152
|
+
* });
|
|
153
|
+
* ```
|
|
114
154
|
*/
|
|
115
155
|
export class PaymentClient {
|
|
116
156
|
private readonly secureKey: SecurePrivateKey;
|
|
117
157
|
private readonly walletAddress: string;
|
|
118
|
-
private readonly
|
|
119
|
-
private readonly
|
|
158
|
+
private readonly networkConfig: NetworkConfig;
|
|
159
|
+
private readonly assetOverride?: string;
|
|
120
160
|
private readonly resourceUrl: string;
|
|
121
161
|
|
|
122
162
|
constructor(
|
|
@@ -124,29 +164,67 @@ export class PaymentClient {
|
|
|
124
164
|
walletAddress: string,
|
|
125
165
|
config: PaymentClientConfig = {}
|
|
126
166
|
) {
|
|
167
|
+
if (!isValidEthereumAddress(walletAddress)) {
|
|
168
|
+
throw new Error(`Invalid wallet address: ${walletAddress}`);
|
|
169
|
+
}
|
|
127
170
|
this.secureKey = secureKey;
|
|
128
171
|
this.walletAddress = walletAddress;
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
172
|
+
this.networkConfig = resolveNetworkConfig(config);
|
|
173
|
+
this.assetOverride = config.asset;
|
|
131
174
|
this.resourceUrl = config.resourceUrl ?? "";
|
|
132
175
|
}
|
|
133
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Get the current network configuration
|
|
179
|
+
*/
|
|
180
|
+
get network(): NetworkConfig {
|
|
181
|
+
return this.networkConfig;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the USDC contract address for the current network
|
|
186
|
+
*/
|
|
187
|
+
get asset(): string {
|
|
188
|
+
return this.assetOverride ?? this.networkConfig.usdcContract;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get the CAIP-2 network identifier
|
|
193
|
+
*/
|
|
194
|
+
get caip2(): string {
|
|
195
|
+
return this.networkConfig.caip2;
|
|
196
|
+
}
|
|
197
|
+
|
|
134
198
|
/**
|
|
135
199
|
* Creates an x402 V2 payment header for a specific amount and recipient.
|
|
136
200
|
*
|
|
137
201
|
* @param amountMicroUnits - Amount in micro-units (e.g., 1000 = 0.001 USDC)
|
|
138
202
|
* @param recipientAddress - Wallet address of the payment recipient (agent)
|
|
139
203
|
* @param resourceUrl - Optional override for x402 resource URL
|
|
204
|
+
* @param networkOverride - Optional network override for this specific payment
|
|
205
|
+
* @param settlementData - Backend-provided settlement data for x402x-router-settlement
|
|
140
206
|
* @returns Base64 encoded x402 V2 payment header
|
|
141
207
|
*/
|
|
142
208
|
async createPaymentHeader(
|
|
143
209
|
amountMicroUnits: number,
|
|
144
210
|
recipientAddress: string,
|
|
145
|
-
resourceUrl?: string
|
|
211
|
+
resourceUrl?: string,
|
|
212
|
+
networkOverride?: string | number,
|
|
213
|
+
settlementData?: SettlementData
|
|
146
214
|
): Promise<string> {
|
|
215
|
+
if (!isValidEthereumAddress(recipientAddress)) {
|
|
216
|
+
throw new Error(`Invalid recipient address: ${recipientAddress}`);
|
|
217
|
+
}
|
|
147
218
|
const resource = resourceUrl || this.resourceUrl || this.getDefaultResourceUrl();
|
|
148
219
|
const amountStr = Math.round(amountMicroUnits).toString();
|
|
149
220
|
|
|
221
|
+
// Resolve network for this payment (allows per-request override)
|
|
222
|
+
const network = networkOverride ? getNetwork(networkOverride) : this.networkConfig;
|
|
223
|
+
|
|
224
|
+
// When using a per-request network override, always use that network's asset contract
|
|
225
|
+
const asset = networkOverride ? network.usdcContract : (this.assetOverride ?? network.usdcContract);
|
|
226
|
+
const chain = createChainDefinition(network);
|
|
227
|
+
|
|
150
228
|
// Create payment header using the secure key
|
|
151
229
|
const header = await this.secureKey.use(async (privateKey) => {
|
|
152
230
|
const account = privateKeyToAccount(privateKey as `0x${string}`);
|
|
@@ -155,24 +233,70 @@ export class PaymentClient {
|
|
|
155
233
|
const now = Math.floor(Date.now() / 1000);
|
|
156
234
|
const validAfter = now - 60; // Valid from 60 seconds ago
|
|
157
235
|
const validBefore = now + 60; // Valid until 60 seconds from now
|
|
158
|
-
const nonce = generateNonce();
|
|
159
236
|
|
|
160
|
-
//
|
|
237
|
+
// Use backend-provided settlement data or fall back to defaults
|
|
238
|
+
// CRITICAL: For x402x-router-settlement to work, we MUST use the values
|
|
239
|
+
// provided by the backend in the task_quote response
|
|
240
|
+
const salt = settlementData?.salt as Hex ?? generateNonce();
|
|
241
|
+
const facilitatorFee = settlementData?.facilitatorFee ?? "1000";
|
|
242
|
+
const hookData = (settlementData?.hookData ?? "0x") as Hex;
|
|
243
|
+
const settlementRouter = settlementData?.settlementRouter ?? network.settlementRouter;
|
|
244
|
+
const hook = settlementData?.hook ?? network.transferHook;
|
|
245
|
+
|
|
246
|
+
// Calculate commitment hash (becomes the EIP-3009 nonce)
|
|
247
|
+
// This cryptographically binds all settlement parameters to the signature
|
|
248
|
+
const commitment = keccak256(
|
|
249
|
+
encodePacked(
|
|
250
|
+
[
|
|
251
|
+
"string", // Protocol identifier
|
|
252
|
+
"uint256", // Chain ID
|
|
253
|
+
"address", // Hub (settlementRouter)
|
|
254
|
+
"address", // Token (USDC)
|
|
255
|
+
"address", // From (payer)
|
|
256
|
+
"uint256", // Value
|
|
257
|
+
"uint256", // Valid after
|
|
258
|
+
"uint256", // Valid before
|
|
259
|
+
"bytes32", // Salt
|
|
260
|
+
"address", // Pay to (final recipient)
|
|
261
|
+
"uint256", // Facilitator fee
|
|
262
|
+
"address", // Hook
|
|
263
|
+
"bytes32" // keccak256(hookData)
|
|
264
|
+
],
|
|
265
|
+
[
|
|
266
|
+
"X402/settle/v1",
|
|
267
|
+
BigInt(chain.id),
|
|
268
|
+
settlementRouter as Hex,
|
|
269
|
+
asset as Hex,
|
|
270
|
+
account.address,
|
|
271
|
+
BigInt(amountStr),
|
|
272
|
+
BigInt(validAfter),
|
|
273
|
+
BigInt(validBefore),
|
|
274
|
+
salt as Hex,
|
|
275
|
+
recipientAddress as Hex,
|
|
276
|
+
BigInt(facilitatorFee),
|
|
277
|
+
hook as Hex,
|
|
278
|
+
keccak256(hookData)
|
|
279
|
+
]
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
// EIP-712 domain using network-specific parameters
|
|
161
284
|
const domain = {
|
|
162
|
-
name:
|
|
163
|
-
version:
|
|
164
|
-
chainId: BigInt(
|
|
165
|
-
verifyingContract:
|
|
285
|
+
name: network.eip712.name,
|
|
286
|
+
version: network.eip712.version,
|
|
287
|
+
chainId: BigInt(chain.id),
|
|
288
|
+
verifyingContract: asset as `0x${string}`
|
|
166
289
|
};
|
|
167
290
|
|
|
168
291
|
// ERC-3009 TransferWithAuthorization message
|
|
292
|
+
// x402x: "to" is settlementRouter, nonce is commitment hash
|
|
169
293
|
const message = {
|
|
170
294
|
from: account.address,
|
|
171
|
-
to:
|
|
295
|
+
to: settlementRouter as `0x${string}`, // Router receives funds first
|
|
172
296
|
value: BigInt(amountStr),
|
|
173
297
|
validAfter: BigInt(validAfter),
|
|
174
298
|
validBefore: BigInt(validBefore),
|
|
175
|
-
nonce: nonce
|
|
299
|
+
nonce: commitment // Commitment hash as nonce
|
|
176
300
|
};
|
|
177
301
|
|
|
178
302
|
// Sign the EIP-712 typed data
|
|
@@ -188,16 +312,19 @@ export class PaymentClient {
|
|
|
188
312
|
const v1Payload = {
|
|
189
313
|
authorization: {
|
|
190
314
|
from: account.address,
|
|
191
|
-
to:
|
|
315
|
+
to: settlementRouter, // Router address
|
|
192
316
|
value: amountStr,
|
|
193
317
|
validAfter: validAfter.toString(),
|
|
194
318
|
validBefore: validBefore.toString(),
|
|
195
|
-
nonce:
|
|
319
|
+
nonce: commitment // Commitment hash
|
|
196
320
|
},
|
|
197
321
|
signature: signature
|
|
198
322
|
};
|
|
199
323
|
|
|
200
|
-
//
|
|
324
|
+
// Convert facilitator fee to hex format (required by facilitator)
|
|
325
|
+
const facilitatorFeeHex = `0x${BigInt(facilitatorFee).toString(16)}`;
|
|
326
|
+
|
|
327
|
+
// Build V2 payload with x402x-router-settlement extension
|
|
201
328
|
const v2Payload = {
|
|
202
329
|
x402Version: 2,
|
|
203
330
|
resource: {
|
|
@@ -207,14 +334,37 @@ export class PaymentClient {
|
|
|
207
334
|
},
|
|
208
335
|
accepted: {
|
|
209
336
|
scheme: "exact",
|
|
210
|
-
network:
|
|
337
|
+
network: network.caip2,
|
|
211
338
|
amount: amountStr,
|
|
212
|
-
asset:
|
|
213
|
-
payTo: recipientAddress,
|
|
339
|
+
asset: asset,
|
|
340
|
+
payTo: recipientAddress, // Final recipient (for display)
|
|
214
341
|
maxTimeoutSeconds: 60,
|
|
215
|
-
extra: {
|
|
342
|
+
extra: {
|
|
343
|
+
name: network.eip712.name,
|
|
344
|
+
version: network.eip712.version,
|
|
345
|
+
// Settlement router info - MUST include all fields for facilitator
|
|
346
|
+
settlementRouter: settlementRouter,
|
|
347
|
+
salt: salt,
|
|
348
|
+
payTo: recipientAddress, // finalPayTo
|
|
349
|
+
facilitatorFee: facilitatorFeeHex, // Must be hex format
|
|
350
|
+
hook: hook,
|
|
351
|
+
hookData: hookData
|
|
352
|
+
}
|
|
216
353
|
},
|
|
217
|
-
payload: v1Payload
|
|
354
|
+
payload: v1Payload,
|
|
355
|
+
// x402x router settlement extension (v2 format)
|
|
356
|
+
extensions: {
|
|
357
|
+
"x402x-router-settlement": {
|
|
358
|
+
info: {
|
|
359
|
+
settlementRouter: settlementRouter,
|
|
360
|
+
hook: hook,
|
|
361
|
+
hookData: hookData,
|
|
362
|
+
facilitatorFee: facilitatorFeeHex, // Must be hex format
|
|
363
|
+
salt: salt,
|
|
364
|
+
finalPayTo: recipientAddress // Final recipient of the payment
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
218
368
|
};
|
|
219
369
|
|
|
220
370
|
return Buffer.from(JSON.stringify(v2Payload)).toString("base64");
|
|
@@ -224,11 +374,16 @@ export class PaymentClient {
|
|
|
224
374
|
}
|
|
225
375
|
|
|
226
376
|
/**
|
|
227
|
-
* Get
|
|
377
|
+
* Get resource URL for x402 payments.
|
|
378
|
+
* Throws if no resource URL is configured.
|
|
228
379
|
*/
|
|
229
380
|
private getDefaultResourceUrl(): string {
|
|
230
|
-
|
|
231
|
-
|
|
381
|
+
if (!this.resourceUrl) {
|
|
382
|
+
throw new Error(
|
|
383
|
+
"Resource URL not configured. Pass resourceUrl to PaymentClient or use buildX402ResourceUrl(wsUrl)."
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
return this.resourceUrl;
|
|
232
387
|
}
|
|
233
388
|
|
|
234
389
|
/**
|