@portel/photon-core 1.4.0 → 2.1.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 +123 -0
- package/dist/auto-ui.d.ts +103 -0
- package/dist/auto-ui.d.ts.map +1 -0
- package/dist/auto-ui.js +275 -0
- package/dist/auto-ui.js.map +1 -0
- package/dist/base.d.ts +9 -2
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +23 -10
- package/dist/base.js.map +1 -1
- package/dist/cli-ui-renderer.d.ts +31 -0
- package/dist/cli-ui-renderer.d.ts.map +1 -0
- package/dist/cli-ui-renderer.js +224 -0
- package/dist/cli-ui-renderer.js.map +1 -0
- package/dist/dependency-manager.d.ts.map +1 -1
- package/dist/dependency-manager.js +0 -1
- package/dist/dependency-manager.js.map +1 -1
- package/dist/design-system/index.d.ts +21 -0
- package/dist/design-system/index.d.ts.map +1 -0
- package/dist/design-system/index.js +27 -0
- package/dist/design-system/index.js.map +1 -0
- package/dist/design-system/tokens.d.ts +149 -0
- package/dist/design-system/tokens.d.ts.map +1 -0
- package/dist/design-system/tokens.js +413 -0
- package/dist/design-system/tokens.js.map +1 -0
- package/dist/design-system/transaction-ui.d.ts +70 -0
- package/dist/design-system/transaction-ui.d.ts.map +1 -0
- package/dist/design-system/transaction-ui.js +982 -0
- package/dist/design-system/transaction-ui.js.map +1 -0
- package/dist/generator.d.ts +58 -8
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +9 -4
- package/dist/generator.js.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -44
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +395 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +304 -0
- package/dist/io.js.map +1 -0
- package/dist/path-resolver.d.ts.map +1 -1
- package/dist/path-resolver.js +2 -1
- package/dist/path-resolver.js.map +1 -1
- package/dist/rendering/components.d.ts +29 -0
- package/dist/rendering/components.d.ts.map +1 -0
- package/dist/rendering/components.js +773 -0
- package/dist/rendering/components.js.map +1 -0
- package/dist/rendering/field-analyzer.d.ts +48 -0
- package/dist/rendering/field-analyzer.d.ts.map +1 -0
- package/dist/rendering/field-analyzer.js +270 -0
- package/dist/rendering/field-analyzer.js.map +1 -0
- package/dist/rendering/field-renderers.d.ts +64 -0
- package/dist/rendering/field-renderers.d.ts.map +1 -0
- package/dist/rendering/field-renderers.js +317 -0
- package/dist/rendering/field-renderers.js.map +1 -0
- package/dist/rendering/index.d.ts +28 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/rendering/index.js +60 -0
- package/dist/rendering/index.js.map +1 -0
- package/dist/rendering/layout-selector.d.ts +48 -0
- package/dist/rendering/layout-selector.d.ts.map +1 -0
- package/dist/rendering/layout-selector.js +347 -0
- package/dist/rendering/layout-selector.js.map +1 -0
- package/dist/rendering/template-engine.d.ts +41 -0
- package/dist/rendering/template-engine.d.ts.map +1 -0
- package/dist/rendering/template-engine.js +236 -0
- package/dist/rendering/template-engine.js.map +1 -0
- package/dist/schema-extractor.d.ts +30 -0
- package/dist/schema-extractor.d.ts.map +1 -1
- package/dist/schema-extractor.js +205 -12
- package/dist/schema-extractor.js.map +1 -1
- package/dist/stateful.d.ts +63 -0
- package/dist/stateful.d.ts.map +1 -1
- package/dist/stateful.js +222 -0
- package/dist/stateful.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ucp/ap2/handlers.d.ts +242 -0
- package/dist/ucp/ap2/handlers.d.ts.map +1 -0
- package/dist/ucp/ap2/handlers.js +482 -0
- package/dist/ucp/ap2/handlers.js.map +1 -0
- package/dist/ucp/ap2/mandates.d.ts +95 -0
- package/dist/ucp/ap2/mandates.d.ts.map +1 -0
- package/dist/ucp/ap2/mandates.js +234 -0
- package/dist/ucp/ap2/mandates.js.map +1 -0
- package/dist/ucp/ap2/types.d.ts +305 -0
- package/dist/ucp/ap2/types.d.ts.map +1 -0
- package/dist/ucp/ap2/types.js +8 -0
- package/dist/ucp/ap2/types.js.map +1 -0
- package/dist/ucp/capabilities/checkout.d.ts +118 -0
- package/dist/ucp/capabilities/checkout.d.ts.map +1 -0
- package/dist/ucp/capabilities/checkout.js +344 -0
- package/dist/ucp/capabilities/checkout.js.map +1 -0
- package/dist/ucp/capabilities/identity.d.ts +130 -0
- package/dist/ucp/capabilities/identity.d.ts.map +1 -0
- package/dist/ucp/capabilities/identity.js +290 -0
- package/dist/ucp/capabilities/identity.js.map +1 -0
- package/dist/ucp/capabilities/order.d.ts +142 -0
- package/dist/ucp/capabilities/order.d.ts.map +1 -0
- package/dist/ucp/capabilities/order.js +383 -0
- package/dist/ucp/capabilities/order.js.map +1 -0
- package/dist/ucp/index.d.ts +18 -0
- package/dist/ucp/index.d.ts.map +1 -0
- package/dist/ucp/index.js +19 -0
- package/dist/ucp/index.js.map +1 -0
- package/dist/ucp/manifest.d.ts +62 -0
- package/dist/ucp/manifest.d.ts.map +1 -0
- package/dist/ucp/manifest.js +180 -0
- package/dist/ucp/manifest.js.map +1 -0
- package/dist/ucp/types.d.ts +327 -0
- package/dist/ucp/types.d.ts.map +1 -0
- package/dist/ucp/types.js +8 -0
- package/dist/ucp/types.js.map +1 -0
- package/package.json +3 -4
- package/src/auto-ui.ts +413 -0
- package/src/base.ts +22 -9
- package/src/cli-ui-renderer.ts +264 -0
- package/src/dependency-manager.ts +0 -1
- package/src/design-system/index.ts +30 -0
- package/src/design-system/tokens.ts +451 -0
- package/src/design-system/transaction-ui.ts +1038 -0
- package/src/generator.ts +68 -8
- package/src/index.ts +159 -101
- package/src/io.ts +493 -0
- package/src/path-resolver.ts +2 -1
- package/src/rendering/components.ts +785 -0
- package/src/rendering/field-analyzer.ts +299 -0
- package/src/rendering/field-renderers.ts +356 -0
- package/src/rendering/index.ts +63 -0
- package/src/rendering/layout-selector.ts +390 -0
- package/src/rendering/template-engine.ts +254 -0
- package/src/schema-extractor.ts +225 -12
- package/src/stateful.ts +301 -0
- package/src/types.ts +10 -1
- package/src/ucp/ap2/handlers.ts +779 -0
- package/src/ucp/ap2/mandates.ts +354 -0
- package/src/ucp/ap2/types.ts +441 -0
- package/src/ucp/capabilities/checkout.ts +497 -0
- package/src/ucp/capabilities/identity.ts +425 -0
- package/src/ucp/capabilities/order.ts +549 -0
- package/src/ucp/index.ts +27 -0
- package/src/ucp/manifest.ts +257 -0
- package/src/ucp/types.ts +454 -0
- package/dist/cli-formatter.d.ts +0 -92
- package/dist/cli-formatter.d.ts.map +0 -1
- package/dist/cli-formatter.js +0 -486
- package/dist/cli-formatter.js.map +0 -1
- package/dist/elicit.d.ts +0 -93
- package/dist/elicit.d.ts.map +0 -1
- package/dist/elicit.js +0 -373
- package/dist/elicit.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -218
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js +0 -424
- package/dist/mcp-client.js.map +0 -1
- package/dist/mcp-sdk-transport.d.ts +0 -88
- package/dist/mcp-sdk-transport.d.ts.map +0 -1
- package/dist/mcp-sdk-transport.js +0 -360
- package/dist/mcp-sdk-transport.js.map +0 -1
- package/dist/photon-config.d.ts +0 -86
- package/dist/photon-config.d.ts.map +0 -1
- package/dist/photon-config.js +0 -156
- package/dist/photon-config.js.map +0 -1
- package/src/cli-formatter.ts +0 -579
- package/src/elicit.ts +0 -438
- package/src/mcp-client.ts +0 -561
- package/src/mcp-sdk-transport.ts +0 -449
- package/src/photon-config.ts +0 -201
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AP2 Mandate Creation and Validation Helpers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as crypto from 'crypto';
|
|
6
|
+
import {
|
|
7
|
+
CartMandate,
|
|
8
|
+
CartMandateContents,
|
|
9
|
+
IntentMandate,
|
|
10
|
+
IntentMandateContents,
|
|
11
|
+
PaymentMandate,
|
|
12
|
+
PaymentMandateContents,
|
|
13
|
+
PaymentResponse,
|
|
14
|
+
PaymentMethodType,
|
|
15
|
+
TransactionContext,
|
|
16
|
+
RiskPayload
|
|
17
|
+
} from './types.js';
|
|
18
|
+
import { Money, Address, LineItem } from '../types.js';
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Cart Mandate Helpers
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
export interface CreateCartMandateParams {
|
|
25
|
+
items: LineItem[];
|
|
26
|
+
total: Money;
|
|
27
|
+
merchant: {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
url?: string;
|
|
31
|
+
};
|
|
32
|
+
paymentMethods: PaymentMethodType[];
|
|
33
|
+
fulfillment?: {
|
|
34
|
+
method: string;
|
|
35
|
+
destination: Address;
|
|
36
|
+
estimatedDelivery?: string;
|
|
37
|
+
};
|
|
38
|
+
refundPeriodDays?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create a new Cart Mandate for human-present transactions
|
|
43
|
+
*/
|
|
44
|
+
export function createCartMandate(
|
|
45
|
+
params: CreateCartMandateParams,
|
|
46
|
+
merchantPrivateKey?: string
|
|
47
|
+
): CartMandate {
|
|
48
|
+
const contents: CartMandateContents = {
|
|
49
|
+
id: `cart_${crypto.randomUUID()}`,
|
|
50
|
+
userSignatureRequired: true,
|
|
51
|
+
paymentRequest: {
|
|
52
|
+
methodData: params.paymentMethods.map(method => ({
|
|
53
|
+
supportedMethods: method,
|
|
54
|
+
data: {}
|
|
55
|
+
})),
|
|
56
|
+
details: {
|
|
57
|
+
id: `order_${crypto.randomUUID()}`,
|
|
58
|
+
displayItems: params.items.map(item => ({
|
|
59
|
+
label: item.label,
|
|
60
|
+
amount: item.totalPrice
|
|
61
|
+
})),
|
|
62
|
+
total: {
|
|
63
|
+
label: 'Total',
|
|
64
|
+
amount: params.total
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
merchant: params.merchant,
|
|
69
|
+
fulfillment: params.fulfillment,
|
|
70
|
+
refundConditions: params.refundPeriodDays ? {
|
|
71
|
+
period: params.refundPeriodDays,
|
|
72
|
+
policy: `Full refund within ${params.refundPeriodDays} days of delivery`
|
|
73
|
+
} : undefined
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const timestamp = new Date().toISOString();
|
|
77
|
+
const merchantSignature = merchantPrivateKey
|
|
78
|
+
? signMandate(contents, merchantPrivateKey)
|
|
79
|
+
: `sig_merchant_${crypto.randomBytes(16).toString('hex')}`;
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
contents,
|
|
83
|
+
merchantSignature,
|
|
84
|
+
timestamp
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Add user signature to Cart Mandate
|
|
90
|
+
*/
|
|
91
|
+
export function signCartMandate(
|
|
92
|
+
mandate: CartMandate,
|
|
93
|
+
userPrivateKey?: string
|
|
94
|
+
): CartMandate {
|
|
95
|
+
const userSignature = userPrivateKey
|
|
96
|
+
? signMandate(mandate.contents, userPrivateKey)
|
|
97
|
+
: `sig_user_${crypto.randomBytes(16).toString('hex')}`;
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
...mandate,
|
|
101
|
+
userSignature,
|
|
102
|
+
userSignatureTimestamp: new Date().toISOString()
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Intent Mandate Helpers
|
|
108
|
+
// ============================================================================
|
|
109
|
+
|
|
110
|
+
export interface CreateIntentMandateParams {
|
|
111
|
+
description: string;
|
|
112
|
+
productCategories?: string[];
|
|
113
|
+
specificSkus?: string[];
|
|
114
|
+
keywords?: string[];
|
|
115
|
+
maxPrice: Money;
|
|
116
|
+
minPrice?: Money;
|
|
117
|
+
quantity?: { min?: number; max?: number };
|
|
118
|
+
allowedMerchants?: string[];
|
|
119
|
+
validForHours?: number;
|
|
120
|
+
executeWhen?: 'immediately' | 'price_drop' | 'in_stock' | 'scheduled';
|
|
121
|
+
paymentMethods: PaymentMethodType[];
|
|
122
|
+
promptPlayback?: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Create a new Intent Mandate for autonomous agent purchases
|
|
127
|
+
*/
|
|
128
|
+
export function createIntentMandate(
|
|
129
|
+
params: CreateIntentMandateParams,
|
|
130
|
+
userPrivateKey?: string
|
|
131
|
+
): IntentMandate {
|
|
132
|
+
const now = new Date();
|
|
133
|
+
const validUntil = new Date(now.getTime() + (params.validForHours || 24) * 60 * 60 * 1000);
|
|
134
|
+
|
|
135
|
+
const contents: IntentMandateContents = {
|
|
136
|
+
id: `intent_${crypto.randomUUID()}`,
|
|
137
|
+
intent: {
|
|
138
|
+
description: params.description,
|
|
139
|
+
productCategories: params.productCategories,
|
|
140
|
+
specificSkus: params.specificSkus,
|
|
141
|
+
keywords: params.keywords
|
|
142
|
+
},
|
|
143
|
+
constraints: {
|
|
144
|
+
maxPrice: params.maxPrice,
|
|
145
|
+
minPrice: params.minPrice,
|
|
146
|
+
quantity: params.quantity,
|
|
147
|
+
merchants: params.allowedMerchants
|
|
148
|
+
},
|
|
149
|
+
timing: {
|
|
150
|
+
validFrom: now.toISOString(),
|
|
151
|
+
validUntil: validUntil.toISOString(),
|
|
152
|
+
executeWhen: params.executeWhen || 'immediately'
|
|
153
|
+
},
|
|
154
|
+
paymentAuthorization: {
|
|
155
|
+
methodCategories: params.paymentMethods,
|
|
156
|
+
preAuthorizedAmount: params.maxPrice
|
|
157
|
+
},
|
|
158
|
+
promptPlayback: params.promptPlayback
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const userSignature = userPrivateKey
|
|
162
|
+
? signMandate(contents, userPrivateKey)
|
|
163
|
+
: `sig_user_${crypto.randomBytes(16).toString('hex')}`;
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
contents,
|
|
167
|
+
userSignature,
|
|
168
|
+
userSignatureTimestamp: now.toISOString()
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Check if Intent Mandate is still valid
|
|
174
|
+
*/
|
|
175
|
+
export function isIntentMandateValid(mandate: IntentMandate): boolean {
|
|
176
|
+
const now = new Date();
|
|
177
|
+
const validFrom = new Date(mandate.contents.timing.validFrom);
|
|
178
|
+
const validUntil = new Date(mandate.contents.timing.validUntil);
|
|
179
|
+
|
|
180
|
+
return now >= validFrom && now <= validUntil;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Check if a price satisfies Intent Mandate constraints
|
|
185
|
+
*/
|
|
186
|
+
export function checkPriceConstraints(
|
|
187
|
+
mandate: IntentMandate,
|
|
188
|
+
price: Money
|
|
189
|
+
): { valid: boolean; reason?: string } {
|
|
190
|
+
const { constraints } = mandate.contents;
|
|
191
|
+
|
|
192
|
+
if (price.currency !== constraints.maxPrice.currency) {
|
|
193
|
+
return { valid: false, reason: 'Currency mismatch' };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (price.amount > constraints.maxPrice.amount) {
|
|
197
|
+
return { valid: false, reason: `Price ${price.amount} exceeds max ${constraints.maxPrice.amount}` };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (constraints.minPrice && price.amount < constraints.minPrice.amount) {
|
|
201
|
+
return { valid: false, reason: `Price ${price.amount} below min ${constraints.minPrice.amount}` };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return { valid: true };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ============================================================================
|
|
208
|
+
// Payment Mandate Helpers
|
|
209
|
+
// ============================================================================
|
|
210
|
+
|
|
211
|
+
export interface CreatePaymentMandateParams {
|
|
212
|
+
sourceMandate: CartMandate | IntentMandate;
|
|
213
|
+
paymentResponse: PaymentResponse;
|
|
214
|
+
agentName?: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Create a Payment Mandate from Cart or Intent Mandate
|
|
219
|
+
*/
|
|
220
|
+
export function createPaymentMandate(
|
|
221
|
+
params: CreatePaymentMandateParams,
|
|
222
|
+
userPrivateKey?: string
|
|
223
|
+
): PaymentMandate {
|
|
224
|
+
const { sourceMandate, paymentResponse, agentName } = params;
|
|
225
|
+
|
|
226
|
+
const isCartMandate = 'merchantSignature' in sourceMandate;
|
|
227
|
+
const sourceMandateType = isCartMandate ? 'cart' : 'intent';
|
|
228
|
+
const sourceMandateId = sourceMandate.contents.id;
|
|
229
|
+
|
|
230
|
+
// Get total from source mandate
|
|
231
|
+
let total: Money;
|
|
232
|
+
if (isCartMandate) {
|
|
233
|
+
total = (sourceMandate as CartMandate).contents.paymentRequest.details.total.amount;
|
|
234
|
+
} else {
|
|
235
|
+
total = (sourceMandate as IntentMandate).contents.constraints.maxPrice;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const contents: PaymentMandateContents = {
|
|
239
|
+
paymentMandateId: `pm_${crypto.randomUUID()}`,
|
|
240
|
+
paymentDetailsId: paymentResponse.requestId,
|
|
241
|
+
paymentDetailsTotal: {
|
|
242
|
+
label: 'Total',
|
|
243
|
+
amount: total,
|
|
244
|
+
refundPeriod: isCartMandate
|
|
245
|
+
? (sourceMandate as CartMandate).contents.refundConditions?.period
|
|
246
|
+
: 30
|
|
247
|
+
},
|
|
248
|
+
paymentResponse,
|
|
249
|
+
merchantAgent: agentName || 'MerchantAgent',
|
|
250
|
+
sourceMandateType,
|
|
251
|
+
sourceMandateId,
|
|
252
|
+
timestamp: new Date().toISOString()
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const userAuthorization = userPrivateKey
|
|
256
|
+
? signMandate(contents, userPrivateKey)
|
|
257
|
+
: `auth_${crypto.randomBytes(32).toString('base64url')}`;
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
paymentMandateContents: contents,
|
|
261
|
+
userAuthorization
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// Signature Helpers
|
|
267
|
+
// ============================================================================
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Sign mandate contents (simplified - production should use proper PKI)
|
|
271
|
+
*/
|
|
272
|
+
function signMandate(contents: any, privateKey: string): string {
|
|
273
|
+
const payload = JSON.stringify(contents);
|
|
274
|
+
const hmac = crypto.createHmac('sha256', privateKey);
|
|
275
|
+
hmac.update(payload);
|
|
276
|
+
return `sig_${hmac.digest('base64url')}`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Verify mandate signature
|
|
281
|
+
*/
|
|
282
|
+
export function verifyMandateSignature(
|
|
283
|
+
contents: any,
|
|
284
|
+
signature: string,
|
|
285
|
+
publicKey: string
|
|
286
|
+
): boolean {
|
|
287
|
+
// Simplified verification - production should use proper PKI
|
|
288
|
+
const expectedSig = signMandate(contents, publicKey);
|
|
289
|
+
return signature === expectedSig;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ============================================================================
|
|
293
|
+
// Transaction Context
|
|
294
|
+
// ============================================================================
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Create transaction context for audit trail
|
|
298
|
+
*/
|
|
299
|
+
export function createTransactionContext(params: {
|
|
300
|
+
modality: 'human_present' | 'human_not_present';
|
|
301
|
+
initiatedBy: 'user' | 'agent';
|
|
302
|
+
mandates: (CartMandate | IntentMandate | PaymentMandate)[];
|
|
303
|
+
}): TransactionContext {
|
|
304
|
+
return {
|
|
305
|
+
modality: params.modality,
|
|
306
|
+
agentPresent: true,
|
|
307
|
+
initiatedBy: params.initiatedBy,
|
|
308
|
+
sessionId: `session_${crypto.randomUUID()}`,
|
|
309
|
+
startTime: new Date().toISOString(),
|
|
310
|
+
mandateChain: params.mandates.map(mandate => {
|
|
311
|
+
if ('merchantSignature' in mandate) {
|
|
312
|
+
return {
|
|
313
|
+
type: 'cart' as const,
|
|
314
|
+
id: mandate.contents.id,
|
|
315
|
+
timestamp: mandate.timestamp
|
|
316
|
+
};
|
|
317
|
+
} else if ('paymentMandateContents' in mandate) {
|
|
318
|
+
return {
|
|
319
|
+
type: 'payment' as const,
|
|
320
|
+
id: mandate.paymentMandateContents.paymentMandateId,
|
|
321
|
+
timestamp: mandate.paymentMandateContents.timestamp
|
|
322
|
+
};
|
|
323
|
+
} else {
|
|
324
|
+
return {
|
|
325
|
+
type: 'intent' as const,
|
|
326
|
+
id: mandate.contents.id,
|
|
327
|
+
timestamp: mandate.userSignatureTimestamp
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
})
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// ============================================================================
|
|
335
|
+
// Risk Assessment
|
|
336
|
+
// ============================================================================
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Create risk payload for payment authorization
|
|
340
|
+
*/
|
|
341
|
+
export function createRiskPayload(params: {
|
|
342
|
+
deviceFingerprint?: string;
|
|
343
|
+
ipAddress?: string;
|
|
344
|
+
userAgent?: string;
|
|
345
|
+
authLevel: 'none' | 'basic' | 'mfa' | 'biometric';
|
|
346
|
+
sessionDuration?: number;
|
|
347
|
+
previousPurchases?: number;
|
|
348
|
+
agentVerified?: boolean;
|
|
349
|
+
}): RiskPayload {
|
|
350
|
+
return {
|
|
351
|
+
...params,
|
|
352
|
+
authTimestamp: new Date().toISOString()
|
|
353
|
+
};
|
|
354
|
+
}
|