@t402/a2a 2.4.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/README.md +182 -0
- package/dist/cjs/client.cjs +147 -0
- package/dist/cjs/client.d.cts +102 -0
- package/dist/cjs/index.cjs +388 -0
- package/dist/cjs/index.d.cts +4 -0
- package/dist/cjs/server.cjs +239 -0
- package/dist/cjs/server.d.cts +177 -0
- package/dist/esm/chunk-6TJQKXTN.mjs +219 -0
- package/dist/esm/chunk-IPWV3JOP.mjs +127 -0
- package/dist/esm/client.d.ts +102 -0
- package/dist/esm/client.mjs +6 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.mjs +38 -0
- package/dist/esm/server.d.ts +177 -0
- package/dist/esm/server.mjs +6 -0
- package/package.json +86 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { PaymentPayload, PaymentRequired, SettleResponse, A2AMessage, A2ATaskStatus, A2ATask } from '@t402/core/types';
|
|
2
|
+
import { FacilitatorClient } from '@t402/core/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A2A Payment Server
|
|
6
|
+
*
|
|
7
|
+
* Handles server-side payment processing for A2A agent endpoints,
|
|
8
|
+
* including generating payment requirements and processing payment submissions.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Result of payment processing
|
|
13
|
+
*/
|
|
14
|
+
interface A2APaymentResult {
|
|
15
|
+
/** Whether payment was successful */
|
|
16
|
+
success: boolean;
|
|
17
|
+
/** Settlement receipts (if settled) */
|
|
18
|
+
receipts?: SettleResponse[];
|
|
19
|
+
/** Error message (if failed) */
|
|
20
|
+
error?: string;
|
|
21
|
+
/** A2A message to include in response */
|
|
22
|
+
message: A2AMessage;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Payment handler function type
|
|
26
|
+
*/
|
|
27
|
+
type A2APaymentHandler = (payload: PaymentPayload, requirements: PaymentRequired) => Promise<A2APaymentResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Options for A2APaymentServer
|
|
30
|
+
*/
|
|
31
|
+
interface A2APaymentServerOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Facilitator client for verification and settlement
|
|
34
|
+
*/
|
|
35
|
+
facilitator?: FacilitatorClient;
|
|
36
|
+
/**
|
|
37
|
+
* Custom payment handler (alternative to facilitator)
|
|
38
|
+
*/
|
|
39
|
+
paymentHandler?: A2APaymentHandler;
|
|
40
|
+
/**
|
|
41
|
+
* Default payment requirements template
|
|
42
|
+
*/
|
|
43
|
+
defaultRequirements?: Partial<PaymentRequired>;
|
|
44
|
+
/**
|
|
45
|
+
* Optional callback when payment is received
|
|
46
|
+
*/
|
|
47
|
+
onPaymentReceived?: (payload: PaymentPayload) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Optional callback when payment is verified
|
|
50
|
+
*/
|
|
51
|
+
onPaymentVerified?: (payload: PaymentPayload) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Optional callback when payment is settled
|
|
54
|
+
*/
|
|
55
|
+
onPaymentSettled?: (receipts: SettleResponse[]) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Optional callback when payment fails
|
|
58
|
+
*/
|
|
59
|
+
onPaymentFailed?: (error: string, payload?: PaymentPayload) => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A2A Payment Server
|
|
63
|
+
*
|
|
64
|
+
* Provides server-side payment handling for A2A agent endpoints.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const server = new A2APaymentServer({
|
|
69
|
+
* facilitator: facilitatorClient,
|
|
70
|
+
* defaultRequirements: {
|
|
71
|
+
* t402Version: 2,
|
|
72
|
+
* resource: 'agent://my-agent/skill',
|
|
73
|
+
* },
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* // Create payment-required response
|
|
77
|
+
* const requirements = server.createRequirements({
|
|
78
|
+
* accepts: [{ scheme: 'exact', network: 'eip155:8453', amount: '1000000', ... }],
|
|
79
|
+
* });
|
|
80
|
+
* const task = server.createPaymentRequiredTask(taskId, requirements);
|
|
81
|
+
*
|
|
82
|
+
* // Process payment submission
|
|
83
|
+
* const result = await server.processPayment(message, requirements);
|
|
84
|
+
* if (result.success) {
|
|
85
|
+
* // Continue with task execution
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare class A2APaymentServer {
|
|
90
|
+
private options;
|
|
91
|
+
constructor(options?: A2APaymentServerOptions);
|
|
92
|
+
/**
|
|
93
|
+
* Create payment requirements with defaults
|
|
94
|
+
*
|
|
95
|
+
* @param requirements - Partial requirements to merge with defaults
|
|
96
|
+
* @returns Complete payment requirements
|
|
97
|
+
*/
|
|
98
|
+
createRequirements(requirements: Partial<PaymentRequired>): PaymentRequired;
|
|
99
|
+
/**
|
|
100
|
+
* Create a payment-required task status
|
|
101
|
+
*
|
|
102
|
+
* @param requirements - Payment requirements
|
|
103
|
+
* @param text - Optional text message
|
|
104
|
+
* @returns A2A task status
|
|
105
|
+
*/
|
|
106
|
+
createPaymentRequiredStatus(requirements: PaymentRequired, text?: string): A2ATaskStatus;
|
|
107
|
+
/**
|
|
108
|
+
* Create a payment-required task
|
|
109
|
+
*
|
|
110
|
+
* @param taskId - Task identifier
|
|
111
|
+
* @param requirements - Payment requirements
|
|
112
|
+
* @param text - Optional text message
|
|
113
|
+
* @returns A2A task in input-required state
|
|
114
|
+
*/
|
|
115
|
+
createPaymentRequiredTask(taskId: string, requirements: PaymentRequired, text?: string): A2ATask;
|
|
116
|
+
/**
|
|
117
|
+
* Extract payment payload from an A2A message
|
|
118
|
+
*
|
|
119
|
+
* @param message - A2A message that may contain payment
|
|
120
|
+
* @returns Payment payload or undefined
|
|
121
|
+
*/
|
|
122
|
+
extractPaymentPayload(message: A2AMessage): PaymentPayload | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Check if a message contains a payment submission
|
|
125
|
+
*
|
|
126
|
+
* @param message - A2A message to check
|
|
127
|
+
* @returns Whether the message contains a payment
|
|
128
|
+
*/
|
|
129
|
+
hasPaymentPayload(message: A2AMessage): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Process a payment submission
|
|
132
|
+
*
|
|
133
|
+
* @param message - A2A message containing payment payload
|
|
134
|
+
* @param requirements - Original payment requirements
|
|
135
|
+
* @returns Payment processing result
|
|
136
|
+
*/
|
|
137
|
+
processPayment(message: A2AMessage, requirements: PaymentRequired): Promise<A2APaymentResult>;
|
|
138
|
+
/**
|
|
139
|
+
* Create a completed task status with payment receipts
|
|
140
|
+
*
|
|
141
|
+
* @param receipts - Settlement receipts
|
|
142
|
+
* @param text - Optional text message
|
|
143
|
+
* @returns A2A task status
|
|
144
|
+
*/
|
|
145
|
+
createPaymentCompletedStatus(receipts: SettleResponse[], text?: string): A2ATaskStatus;
|
|
146
|
+
/**
|
|
147
|
+
* Create a failed task status with payment error
|
|
148
|
+
*
|
|
149
|
+
* @param error - Error message
|
|
150
|
+
* @param receipts - Optional settlement receipts
|
|
151
|
+
* @param errorCode - Optional error code
|
|
152
|
+
* @returns A2A task status
|
|
153
|
+
*/
|
|
154
|
+
createPaymentFailedStatus(error: string, receipts?: SettleResponse[], errorCode?: string): A2ATaskStatus;
|
|
155
|
+
/**
|
|
156
|
+
* Update a task with payment completion
|
|
157
|
+
*
|
|
158
|
+
* @param task - Original task
|
|
159
|
+
* @param result - Payment processing result
|
|
160
|
+
* @returns Updated task
|
|
161
|
+
*/
|
|
162
|
+
updateTaskWithPaymentResult(task: A2ATask, result: A2APaymentResult): A2ATask;
|
|
163
|
+
/**
|
|
164
|
+
* Handle a complete payment flow for a task
|
|
165
|
+
*
|
|
166
|
+
* This is a convenience method that processes a payment submission
|
|
167
|
+
* and returns an updated task.
|
|
168
|
+
*
|
|
169
|
+
* @param task - The current A2A task
|
|
170
|
+
* @param message - The message containing payment payload
|
|
171
|
+
* @param requirements - Payment requirements
|
|
172
|
+
* @returns Updated task with payment result
|
|
173
|
+
*/
|
|
174
|
+
handlePayment(task: A2ATask, message: A2AMessage, requirements: PaymentRequired): Promise<A2ATask>;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export { type A2APaymentHandler, type A2APaymentResult, A2APaymentServer, type A2APaymentServerOptions };
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import {
|
|
3
|
+
createPaymentRequiredMessage,
|
|
4
|
+
createPaymentCompletedMessage,
|
|
5
|
+
createPaymentFailedMessage
|
|
6
|
+
} from "@t402/core/types";
|
|
7
|
+
var A2APaymentServer = class {
|
|
8
|
+
options;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create payment requirements with defaults
|
|
14
|
+
*
|
|
15
|
+
* @param requirements - Partial requirements to merge with defaults
|
|
16
|
+
* @returns Complete payment requirements
|
|
17
|
+
*/
|
|
18
|
+
createRequirements(requirements) {
|
|
19
|
+
return {
|
|
20
|
+
t402Version: 2,
|
|
21
|
+
...this.options.defaultRequirements,
|
|
22
|
+
...requirements
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a payment-required task status
|
|
27
|
+
*
|
|
28
|
+
* @param requirements - Payment requirements
|
|
29
|
+
* @param text - Optional text message
|
|
30
|
+
* @returns A2A task status
|
|
31
|
+
*/
|
|
32
|
+
createPaymentRequiredStatus(requirements, text) {
|
|
33
|
+
return {
|
|
34
|
+
state: "input-required",
|
|
35
|
+
message: createPaymentRequiredMessage(requirements, text),
|
|
36
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a payment-required task
|
|
41
|
+
*
|
|
42
|
+
* @param taskId - Task identifier
|
|
43
|
+
* @param requirements - Payment requirements
|
|
44
|
+
* @param text - Optional text message
|
|
45
|
+
* @returns A2A task in input-required state
|
|
46
|
+
*/
|
|
47
|
+
createPaymentRequiredTask(taskId, requirements, text) {
|
|
48
|
+
return {
|
|
49
|
+
kind: "task",
|
|
50
|
+
id: taskId,
|
|
51
|
+
status: this.createPaymentRequiredStatus(requirements, text)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract payment payload from an A2A message
|
|
56
|
+
*
|
|
57
|
+
* @param message - A2A message that may contain payment
|
|
58
|
+
* @returns Payment payload or undefined
|
|
59
|
+
*/
|
|
60
|
+
extractPaymentPayload(message) {
|
|
61
|
+
return message.metadata?.["t402.payment.payload"];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if a message contains a payment submission
|
|
65
|
+
*
|
|
66
|
+
* @param message - A2A message to check
|
|
67
|
+
* @returns Whether the message contains a payment
|
|
68
|
+
*/
|
|
69
|
+
hasPaymentPayload(message) {
|
|
70
|
+
return message.metadata?.["t402.payment.status"] === "payment-submitted" && message.metadata?.["t402.payment.payload"] !== void 0;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Process a payment submission
|
|
74
|
+
*
|
|
75
|
+
* @param message - A2A message containing payment payload
|
|
76
|
+
* @param requirements - Original payment requirements
|
|
77
|
+
* @returns Payment processing result
|
|
78
|
+
*/
|
|
79
|
+
async processPayment(message, requirements) {
|
|
80
|
+
const payload = this.extractPaymentPayload(message);
|
|
81
|
+
if (!payload) {
|
|
82
|
+
const error = "No payment payload in message";
|
|
83
|
+
this.options.onPaymentFailed?.(error);
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
error,
|
|
87
|
+
message: createPaymentFailedMessage([], "T402-1001", error)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
this.options.onPaymentReceived?.(payload);
|
|
91
|
+
if (this.options.paymentHandler) {
|
|
92
|
+
return this.options.paymentHandler(payload, requirements);
|
|
93
|
+
}
|
|
94
|
+
if (!this.options.facilitator) {
|
|
95
|
+
const error = "No facilitator or payment handler configured";
|
|
96
|
+
this.options.onPaymentFailed?.(error, payload);
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error,
|
|
100
|
+
message: createPaymentFailedMessage([], "T402-5001", error)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const paymentRequirements = payload.accepted;
|
|
105
|
+
const verifyResponse = await this.options.facilitator.verify(
|
|
106
|
+
payload,
|
|
107
|
+
paymentRequirements
|
|
108
|
+
);
|
|
109
|
+
if (!verifyResponse.isValid) {
|
|
110
|
+
const error = verifyResponse.invalidReason || "Payment verification failed";
|
|
111
|
+
this.options.onPaymentFailed?.(error, payload);
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error,
|
|
115
|
+
message: createPaymentFailedMessage([], "T402-2001", error)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
this.options.onPaymentVerified?.(payload);
|
|
119
|
+
const settleResponse = await this.options.facilitator.settle(
|
|
120
|
+
payload,
|
|
121
|
+
paymentRequirements
|
|
122
|
+
);
|
|
123
|
+
const receipts = [settleResponse];
|
|
124
|
+
if (!settleResponse.success) {
|
|
125
|
+
const error = settleResponse.errorReason || "Payment settlement failed";
|
|
126
|
+
this.options.onPaymentFailed?.(error, payload);
|
|
127
|
+
return {
|
|
128
|
+
success: false,
|
|
129
|
+
receipts,
|
|
130
|
+
error,
|
|
131
|
+
message: createPaymentFailedMessage(receipts, "T402-3001", error)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
this.options.onPaymentSettled?.(receipts);
|
|
135
|
+
return {
|
|
136
|
+
success: true,
|
|
137
|
+
receipts,
|
|
138
|
+
message: createPaymentCompletedMessage(receipts)
|
|
139
|
+
};
|
|
140
|
+
} catch (err) {
|
|
141
|
+
const error = err instanceof Error ? err.message : "Payment processing error";
|
|
142
|
+
this.options.onPaymentFailed?.(error, payload);
|
|
143
|
+
return {
|
|
144
|
+
success: false,
|
|
145
|
+
error,
|
|
146
|
+
message: createPaymentFailedMessage([], "T402-5002", error)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a completed task status with payment receipts
|
|
152
|
+
*
|
|
153
|
+
* @param receipts - Settlement receipts
|
|
154
|
+
* @param text - Optional text message
|
|
155
|
+
* @returns A2A task status
|
|
156
|
+
*/
|
|
157
|
+
createPaymentCompletedStatus(receipts, text) {
|
|
158
|
+
return {
|
|
159
|
+
state: "completed",
|
|
160
|
+
message: createPaymentCompletedMessage(receipts, text),
|
|
161
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Create a failed task status with payment error
|
|
166
|
+
*
|
|
167
|
+
* @param error - Error message
|
|
168
|
+
* @param receipts - Optional settlement receipts
|
|
169
|
+
* @param errorCode - Optional error code
|
|
170
|
+
* @returns A2A task status
|
|
171
|
+
*/
|
|
172
|
+
createPaymentFailedStatus(error, receipts = [], errorCode = "T402-5000") {
|
|
173
|
+
return {
|
|
174
|
+
state: "failed",
|
|
175
|
+
message: createPaymentFailedMessage(receipts, errorCode, error),
|
|
176
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Update a task with payment completion
|
|
181
|
+
*
|
|
182
|
+
* @param task - Original task
|
|
183
|
+
* @param result - Payment processing result
|
|
184
|
+
* @returns Updated task
|
|
185
|
+
*/
|
|
186
|
+
updateTaskWithPaymentResult(task, result) {
|
|
187
|
+
if (result.success) {
|
|
188
|
+
return {
|
|
189
|
+
...task,
|
|
190
|
+
status: this.createPaymentCompletedStatus(result.receipts || []),
|
|
191
|
+
history: [...task.history || [], result.message]
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...task,
|
|
196
|
+
status: this.createPaymentFailedStatus(result.error || "Payment failed", result.receipts),
|
|
197
|
+
history: [...task.history || [], result.message]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Handle a complete payment flow for a task
|
|
202
|
+
*
|
|
203
|
+
* This is a convenience method that processes a payment submission
|
|
204
|
+
* and returns an updated task.
|
|
205
|
+
*
|
|
206
|
+
* @param task - The current A2A task
|
|
207
|
+
* @param message - The message containing payment payload
|
|
208
|
+
* @param requirements - Payment requirements
|
|
209
|
+
* @returns Updated task with payment result
|
|
210
|
+
*/
|
|
211
|
+
async handlePayment(task, message, requirements) {
|
|
212
|
+
const result = await this.processPayment(message, requirements);
|
|
213
|
+
return this.updateTaskWithPaymentResult(task, result);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export {
|
|
218
|
+
A2APaymentServer
|
|
219
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import {
|
|
3
|
+
isPaymentRequired,
|
|
4
|
+
getPaymentRequired,
|
|
5
|
+
createPaymentSubmissionMessage
|
|
6
|
+
} from "@t402/core/types";
|
|
7
|
+
var A2APaymentClient = class {
|
|
8
|
+
options;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if a task requires payment
|
|
14
|
+
*/
|
|
15
|
+
requiresPayment(task) {
|
|
16
|
+
const requires = isPaymentRequired(task);
|
|
17
|
+
if (requires) {
|
|
18
|
+
const requirements = getPaymentRequired(task);
|
|
19
|
+
if (requirements && this.options.onPaymentRequired) {
|
|
20
|
+
this.options.onPaymentRequired(requirements);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return requires;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get payment requirements from a task
|
|
27
|
+
*/
|
|
28
|
+
getRequirements(task) {
|
|
29
|
+
return getPaymentRequired(task);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Select the best payment option from requirements
|
|
33
|
+
*
|
|
34
|
+
* @param requirements - Payment requirements with accepts array
|
|
35
|
+
* @param preferredNetwork - Preferred network (CAIP-2 format)
|
|
36
|
+
* @param preferredScheme - Preferred scheme (e.g., 'exact', 'upto')
|
|
37
|
+
* @returns The best matching payment option or undefined
|
|
38
|
+
*/
|
|
39
|
+
selectPaymentOption(requirements, preferredNetwork, preferredScheme) {
|
|
40
|
+
const accepts = requirements.accepts;
|
|
41
|
+
if (!accepts || accepts.length === 0) {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
if (preferredNetwork && preferredScheme) {
|
|
45
|
+
const exact = accepts.find(
|
|
46
|
+
(a) => a.network === preferredNetwork && a.scheme === preferredScheme
|
|
47
|
+
);
|
|
48
|
+
if (exact) return exact;
|
|
49
|
+
}
|
|
50
|
+
if (preferredNetwork) {
|
|
51
|
+
const byNetwork = accepts.find((a) => a.network === preferredNetwork);
|
|
52
|
+
if (byNetwork) return byNetwork;
|
|
53
|
+
}
|
|
54
|
+
if (preferredScheme) {
|
|
55
|
+
const byScheme = accepts.find((a) => a.scheme === preferredScheme);
|
|
56
|
+
if (byScheme) return byScheme;
|
|
57
|
+
}
|
|
58
|
+
return accepts[0];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create a payment payload using a mechanism client
|
|
62
|
+
*
|
|
63
|
+
* @param mechanism - The scheme/network client to use
|
|
64
|
+
* @param requirements - Payment requirements to fulfill
|
|
65
|
+
* @returns Promise resolving to the payment payload
|
|
66
|
+
*/
|
|
67
|
+
async createPayload(mechanism, requirements) {
|
|
68
|
+
const selected = this.selectPaymentOption(requirements);
|
|
69
|
+
if (!selected) {
|
|
70
|
+
throw new Error("No payment options available");
|
|
71
|
+
}
|
|
72
|
+
const basePayload = await mechanism.createPaymentPayload(
|
|
73
|
+
requirements.t402Version,
|
|
74
|
+
selected
|
|
75
|
+
);
|
|
76
|
+
const payload = {
|
|
77
|
+
...basePayload,
|
|
78
|
+
resource: requirements.resource,
|
|
79
|
+
accepted: selected
|
|
80
|
+
};
|
|
81
|
+
if (this.options.onPaymentSubmitted) {
|
|
82
|
+
this.options.onPaymentSubmitted(payload);
|
|
83
|
+
}
|
|
84
|
+
return payload;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Create a payment submission message
|
|
88
|
+
*
|
|
89
|
+
* @param payload - The payment payload to submit
|
|
90
|
+
* @param text - Optional text message
|
|
91
|
+
* @returns A2A message with payment metadata
|
|
92
|
+
*/
|
|
93
|
+
createPaymentMessage(payload, text = "Here is the payment authorization.") {
|
|
94
|
+
return createPaymentSubmissionMessage(payload, text);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Handle a complete payment flow for a task
|
|
98
|
+
*
|
|
99
|
+
* This is a convenience method that checks for payment requirements,
|
|
100
|
+
* creates a payload, and returns a payment message.
|
|
101
|
+
*
|
|
102
|
+
* @param task - The A2A task that may require payment
|
|
103
|
+
* @param mechanism - The mechanism client to use for signing
|
|
104
|
+
* @param preferredNetwork - Optional preferred network
|
|
105
|
+
* @param preferredScheme - Optional preferred scheme
|
|
106
|
+
* @returns A2A message with payment, or undefined if no payment needed
|
|
107
|
+
*/
|
|
108
|
+
async handlePayment(task, mechanism, preferredNetwork, preferredScheme) {
|
|
109
|
+
if (!this.requiresPayment(task)) {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
const requirements = this.getRequirements(task);
|
|
113
|
+
if (!requirements) {
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
const selected = this.selectPaymentOption(requirements, preferredNetwork, preferredScheme);
|
|
117
|
+
if (!selected) {
|
|
118
|
+
throw new Error("No compatible payment option found");
|
|
119
|
+
}
|
|
120
|
+
const payload = await this.createPayload(mechanism, requirements);
|
|
121
|
+
return this.createPaymentMessage(payload);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
A2APaymentClient
|
|
127
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { PaymentRequired, PaymentPayload, A2ATask, SchemeNetworkClient, A2AMessage } from '@t402/core/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A2A Payment Client
|
|
5
|
+
*
|
|
6
|
+
* Handles payment flows for A2A client agents, including detecting
|
|
7
|
+
* payment-required states and submitting payment payloads.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Options for A2APaymentClient
|
|
12
|
+
*/
|
|
13
|
+
interface A2APaymentClientOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Optional callback when payment is required
|
|
16
|
+
*/
|
|
17
|
+
onPaymentRequired?: (requirements: PaymentRequired) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Optional callback when payment is submitted
|
|
20
|
+
*/
|
|
21
|
+
onPaymentSubmitted?: (payload: PaymentPayload) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Optional callback when payment is completed
|
|
24
|
+
*/
|
|
25
|
+
onPaymentCompleted?: (task: A2ATask) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Optional callback when payment fails
|
|
28
|
+
*/
|
|
29
|
+
onPaymentFailed?: (error: string, task: A2ATask) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A2A Payment Client
|
|
33
|
+
*
|
|
34
|
+
* Provides methods for handling t402 payments in A2A client agents.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const client = new A2APaymentClient({
|
|
39
|
+
* onPaymentRequired: (req) => console.log('Payment required:', req),
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Check if task requires payment
|
|
43
|
+
* if (client.requiresPayment(task)) {
|
|
44
|
+
* const requirements = client.getRequirements(task);
|
|
45
|
+
* const payload = await mechanism.createPaymentPayload(requirements);
|
|
46
|
+
* const message = client.createPaymentMessage(payload);
|
|
47
|
+
* // Send message via A2A
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare class A2APaymentClient {
|
|
52
|
+
private options;
|
|
53
|
+
constructor(options?: A2APaymentClientOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Check if a task requires payment
|
|
56
|
+
*/
|
|
57
|
+
requiresPayment(task: A2ATask): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Get payment requirements from a task
|
|
60
|
+
*/
|
|
61
|
+
getRequirements(task: A2ATask): PaymentRequired | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Select the best payment option from requirements
|
|
64
|
+
*
|
|
65
|
+
* @param requirements - Payment requirements with accepts array
|
|
66
|
+
* @param preferredNetwork - Preferred network (CAIP-2 format)
|
|
67
|
+
* @param preferredScheme - Preferred scheme (e.g., 'exact', 'upto')
|
|
68
|
+
* @returns The best matching payment option or undefined
|
|
69
|
+
*/
|
|
70
|
+
selectPaymentOption(requirements: PaymentRequired, preferredNetwork?: string, preferredScheme?: string): PaymentRequired["accepts"][0] | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Create a payment payload using a mechanism client
|
|
73
|
+
*
|
|
74
|
+
* @param mechanism - The scheme/network client to use
|
|
75
|
+
* @param requirements - Payment requirements to fulfill
|
|
76
|
+
* @returns Promise resolving to the payment payload
|
|
77
|
+
*/
|
|
78
|
+
createPayload(mechanism: SchemeNetworkClient, requirements: PaymentRequired): Promise<PaymentPayload>;
|
|
79
|
+
/**
|
|
80
|
+
* Create a payment submission message
|
|
81
|
+
*
|
|
82
|
+
* @param payload - The payment payload to submit
|
|
83
|
+
* @param text - Optional text message
|
|
84
|
+
* @returns A2A message with payment metadata
|
|
85
|
+
*/
|
|
86
|
+
createPaymentMessage(payload: PaymentPayload, text?: string): A2AMessage;
|
|
87
|
+
/**
|
|
88
|
+
* Handle a complete payment flow for a task
|
|
89
|
+
*
|
|
90
|
+
* This is a convenience method that checks for payment requirements,
|
|
91
|
+
* creates a payload, and returns a payment message.
|
|
92
|
+
*
|
|
93
|
+
* @param task - The A2A task that may require payment
|
|
94
|
+
* @param mechanism - The mechanism client to use for signing
|
|
95
|
+
* @param preferredNetwork - Optional preferred network
|
|
96
|
+
* @param preferredScheme - Optional preferred scheme
|
|
97
|
+
* @returns A2A message with payment, or undefined if no payment needed
|
|
98
|
+
*/
|
|
99
|
+
handlePayment(task: A2ATask, mechanism: SchemeNetworkClient, preferredNetwork?: string, preferredScheme?: string): Promise<A2AMessage | undefined>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { A2APaymentClient, type A2APaymentClientOptions };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { A2AAgentCard, A2AArtifact, A2ACapabilities, A2ADataPart, A2AError, A2AExtension, A2AFilePart, A2AMessage, A2AMessagePart, A2APaymentMetadata, A2APaymentStatus, A2ARequest, A2AResponse, A2ASkill, A2ATask, A2ATaskState, A2ATaskStatus, A2ATextPart, A2A_EXTENSIONS_HEADER, T402_A2A_EXTENSION_URI, createPaymentCompletedMessage, createPaymentFailedMessage, createPaymentRequiredMessage, createPaymentSubmissionMessage, createT402Extension, getPaymentReceipts, getPaymentRequired, isPaymentCompleted, isPaymentFailed, isPaymentRequired } from '@t402/core/types';
|
|
2
|
+
export { A2APaymentClient, A2APaymentClientOptions } from './client.js';
|
|
3
|
+
export { A2APaymentHandler, A2APaymentResult, A2APaymentServer, A2APaymentServerOptions } from './server.js';
|
|
4
|
+
import '@t402/core/server';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
A2APaymentClient
|
|
3
|
+
} from "./chunk-IPWV3JOP.mjs";
|
|
4
|
+
import {
|
|
5
|
+
A2APaymentServer
|
|
6
|
+
} from "./chunk-6TJQKXTN.mjs";
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
import {
|
|
10
|
+
T402_A2A_EXTENSION_URI,
|
|
11
|
+
A2A_EXTENSIONS_HEADER,
|
|
12
|
+
isPaymentRequired,
|
|
13
|
+
isPaymentCompleted,
|
|
14
|
+
isPaymentFailed,
|
|
15
|
+
getPaymentRequired,
|
|
16
|
+
getPaymentReceipts,
|
|
17
|
+
createPaymentRequiredMessage,
|
|
18
|
+
createPaymentSubmissionMessage,
|
|
19
|
+
createPaymentCompletedMessage,
|
|
20
|
+
createPaymentFailedMessage,
|
|
21
|
+
createT402Extension
|
|
22
|
+
} from "@t402/core/types";
|
|
23
|
+
export {
|
|
24
|
+
A2APaymentClient,
|
|
25
|
+
A2APaymentServer,
|
|
26
|
+
A2A_EXTENSIONS_HEADER,
|
|
27
|
+
T402_A2A_EXTENSION_URI,
|
|
28
|
+
createPaymentCompletedMessage,
|
|
29
|
+
createPaymentFailedMessage,
|
|
30
|
+
createPaymentRequiredMessage,
|
|
31
|
+
createPaymentSubmissionMessage,
|
|
32
|
+
createT402Extension,
|
|
33
|
+
getPaymentReceipts,
|
|
34
|
+
getPaymentRequired,
|
|
35
|
+
isPaymentCompleted,
|
|
36
|
+
isPaymentFailed,
|
|
37
|
+
isPaymentRequired
|
|
38
|
+
};
|