@vesant-sdk/fraud 0.1.1-next.c8fef46 → 0.1.1-next.d538ee4

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 CHANGED
@@ -13,7 +13,7 @@ Requires `@vesant-sdk/core` (installed automatically as a dependency).
13
13
  ## Quick start
14
14
 
15
15
  ```typescript
16
- import { FraudClient, TransactionType } from '@vesant-sdk/fraud';
16
+ import { FraudClient, TransactionType, TransactionStatus } from '@vesant-sdk/fraud';
17
17
 
18
18
  const fraud = new FraudClient({
19
19
  baseURL: process.env.VESANT_API_URL!,
@@ -22,13 +22,20 @@ const fraud = new FraudClient({
22
22
  });
23
23
 
24
24
  const result = await fraud.scoreEvent({
25
- customer_id: 'customer-uuid',
26
- sift_user_id: 'stable-sift-user-id',
25
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
26
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
27
27
  event_type: '$transaction',
28
- transaction_id: 'TX-001',
29
- amount: 99.99,
28
+ transaction_id: '674a1b2c3d4e5f6789012345',
29
+ transaction_type: TransactionType.Deposit,
30
+ amount: 50.0,
30
31
  currency: 'USD',
31
- transaction_type: TransactionType.Sale,
32
+ session_id: 'sess_deposit_001',
33
+ ip_address: '192.168.1.10',
34
+ device_id: 'device_abcd1234',
35
+ payment_method: '$credit_card',
36
+ is_first_deposit: true,
37
+ deposit_count: 4,
38
+ transaction_status: TransactionStatus.Success,
32
39
  });
33
40
  ```
34
41
 
@@ -41,17 +48,192 @@ const result = await fraud.scoreEvent({
41
48
 
42
49
  Types such as `$verification` appear in the Vesant dashboard but are **not** accepted by `scoreEvent` (SDK rejects them before HTTP).
43
50
 
44
- ## Migration from 0.1.x
51
+ ## Request fields
45
52
 
46
- 1. **Transactions** — add required `amount` (> 0) and `currency`.
47
- 2. **Wagers** — add `wager_type`, `wager_status`, `amount`, `currency`; `transaction_id` is the wager id.
48
- 3. **Password updates** — add `password_reason` and `password_status` (use `PasswordUpdateReason` / `PasswordUpdateStatus` constants).
49
- 4. **Chargebacks** — use `event_type: '$chargeback'` with `transaction_id` or `order_id`.
50
- 5. **Metadata** — do not put `$`-prefixed Sift keys in `metadata`; use typed request fields.
53
+ ### Base (all events)
51
54
 
52
- ## API normalization
55
+ | Field | Wire | Notes |
56
+ |-------|------|-------|
57
+ | `customer_id` | top-level | Required |
58
+ | `sift_user_id` | top-level | Required, stable and case-sensitive |
59
+ | `session_id` | `metadata.$session_id` | Strongly recommended on every event |
60
+ | `user_email` | `metadata.$user_email` | Account/login/transaction flows |
61
+ | `name` | `metadata.$name` | Account create/update baseline |
62
+ | `phone` | `metadata.$phone` | Account create/update baseline |
63
+ | `payment_methods` | `metadata.$payment_methods` | Account baseline (array); nested keys prefixed with `$` on the wire |
64
+ | `sift_payment_method` | `metadata.$payment_method` | Sift payment object on transactions |
65
+ | `billing_address` | `metadata.$billing_address` | Nested keys prefixed with `$` on the wire |
66
+ | `app` | `metadata.$app` | Mobile clients |
67
+ | `ip_address`, `device_id`, `user_agent` | top-level | Optional |
68
+ | `metadata` | `metadata` | Plain Vesant rule signals and optional `$…` Sift pass-through |
53
69
 
54
- Until the fraud-service maps all Sift fields at the top level, the client copies some typed fields into `metadata` on the wire (e.g. `password_reason` → `metadata.$reason`). Use `buildScoreRequestPreview(request)` to inspect the JSON body sent to the API.
70
+ Prefer typed fields for common Sift keys. Typed fields win if the same key appears in `metadata`.
71
+
72
+ ### Rule signals (SDK-supplied)
73
+
74
+ | Event | Fields |
75
+ |-------|--------|
76
+ | `$login` | `ip_country_mismatch` (device/session signals are server-side — send `device_id` + `session_id`) |
77
+ | `$update_account` | `two_fa_enabled`, `two_fa_disabled`, `two_fa_method_changed`; send current `user_email`, `name`, `phone`, `billing_address`, `payment_methods` for server-side diff |
78
+ | `$transaction` | `payment_method`, deposit/withdrawal counters, timing fields — see `TransactionRuleSignals` |
79
+
80
+ Do **not** send `new_device_added`, `email_changed`, `customer_age_years`, or `kyc_status` — Vesant derives or ignores these server-side.
81
+
82
+ ### Event-specific Sift fields
83
+
84
+ Typed on the request and normalized into `metadata.$*` on the wire:
85
+
86
+ - `$login` — `login_status`, `login_failure_reason`
87
+ - `$update_password` — `password_reason`, `password_status` (optional; default `$user_update` / `$success`)
88
+ - `$transaction` — `transaction_status`, `decline_category`, `transfer_recipient_user_id`
89
+ - `$wager` — `wager_type`, `wager_status`, `wager_event_type`, `wager_event_name`, `wager_event_id`
90
+
91
+ Inspect the wire body with `buildScoreRequestPreview(request)`.
92
+
93
+ ## Examples by event
94
+
95
+ ### `$create_account`
96
+
97
+ ```typescript
98
+ await fraud.scoreEvent({
99
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
100
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
101
+ event_type: '$create_account',
102
+ ip_address: '198.51.100.101',
103
+ user_agent:
104
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
105
+ device_id: 'device_abcd1234',
106
+ session_id: 'sess_signup_001',
107
+ user_email: 'new@example.com',
108
+ name: 'Jane Doe',
109
+ phone: '+14155550123',
110
+ billing_address: {
111
+ name: 'Jane Doe',
112
+ address_1: '1 Main St',
113
+ city: 'SF',
114
+ region: 'CA',
115
+ country: 'US',
116
+ zipcode: '94105',
117
+ },
118
+ payment_methods: [{ payment_type: '$credit_card', card_bin: '424242' }],
119
+ metadata: {
120
+ country: 'US',
121
+ channel: 'web',
122
+ $referrer_user_id: '2a85f4c7-9b1e-4e2d-a6f0-8c7d5e4b3a21',
123
+ },
124
+ });
125
+ ```
126
+
127
+ ### `$login`
128
+
129
+ ```typescript
130
+ await fraud.scoreEvent({
131
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
132
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
133
+ event_type: '$login',
134
+ ip_address: '192.168.1.10',
135
+ device_id: 'device_abcd1234',
136
+ user_agent:
137
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
138
+ session_id: 'sess_login_001',
139
+ ip_country_mismatch: false,
140
+ metadata: {
141
+ channel: 'web',
142
+ country: 'US',
143
+ },
144
+ });
145
+ ```
146
+
147
+ ### `$update_account`
148
+
149
+ ```typescript
150
+ await fraud.scoreEvent({
151
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
152
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
153
+ event_type: '$update_account',
154
+ session_id: 'sess_update_001',
155
+ user_email: 'changed@example.com',
156
+ name: 'Jane Doe',
157
+ phone: '+14155550123',
158
+ two_fa_disabled: false,
159
+ });
160
+ ```
161
+
162
+ ### `$transaction` (deposit)
163
+
164
+ ```typescript
165
+ await fraud.scoreEvent({
166
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
167
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
168
+ event_type: '$transaction',
169
+ transaction_id: '674a1b2c3d4e5f6789012345',
170
+ transaction_type: TransactionType.Deposit,
171
+ amount: 50.0,
172
+ currency: 'USD',
173
+ session_id: 'sess_deposit_001',
174
+ ip_address: '192.168.1.10',
175
+ device_id: 'device_abcd1234',
176
+ payment_method: '$credit_card',
177
+ is_first_deposit: true,
178
+ cumulative_deposit_amount: 12000,
179
+ deposit_count: 4,
180
+ transaction_status: TransactionStatus.Success,
181
+ metadata: {
182
+ channel: 'web',
183
+ country: 'US',
184
+ },
185
+ });
186
+ ```
187
+
188
+ ### `$wager`
189
+
190
+ ```typescript
191
+ import { WagerStatus } from '@vesant-sdk/fraud';
192
+
193
+ await fraud.scoreEvent({
194
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
195
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
196
+ event_type: '$wager',
197
+ transaction_id: '674a1b2c3d4e5f6789012346',
198
+ wager_type: 'spread',
199
+ wager_status: WagerStatus.Accept,
200
+ amount: 50,
201
+ currency: 'USD',
202
+ wager_event_type: 'Sportsbook',
203
+ session_id: 'sess_wager_001',
204
+ ip_address: '192.168.1.10',
205
+ device_id: 'device_abcd1234',
206
+ });
207
+ ```
208
+
209
+ ### `$chargeback`
210
+
211
+ Feedback-only event for ACH returns and card chargebacks. Returns a reference; `score` and `decision` are not meaningful for tenant policy.
212
+
213
+ ```typescript
214
+ import { ChargebackReason, ChargebackState } from '@vesant-sdk/fraud';
215
+
216
+ await fraud.scoreEvent({
217
+ customer_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
218
+ sift_user_id: '0b54b190-1dc7-232d-b80e-0d2eb573ff47',
219
+ event_type: '$chargeback',
220
+ transaction_id: '674a1b2c3d4e5f6789012345',
221
+ order_id: 'LM-ORD-20240519-88421',
222
+ chargeback_state: ChargebackState.Received,
223
+ chargeback_reason: ChargebackReason.AchReturn,
224
+ ach_return_code: 'R01',
225
+ ip_address: '192.168.1.10',
226
+ device_id: 'device_abcd1234',
227
+ user_agent:
228
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
229
+ metadata: {
230
+ channel: 'web',
231
+ country: 'US',
232
+ },
233
+ });
234
+ ```
235
+
236
+ Use `buildScoreRequestPreview(request)` to inspect the normalized wire body before sending.
55
237
 
56
238
  ## Validation
57
239
 
package/dist/index.d.mts CHANGED
@@ -107,10 +107,104 @@ declare const TransactionStatus: {
107
107
  type FraudRiskLevel = 'low' | 'medium' | 'high' | 'critical';
108
108
 
109
109
  /**
110
- * Custom metadata for fraud score requests (non-Sift reserved keys).
110
+ * Metadata for fraud score requests.
111
+ * Plain keys are Vesant rule signals; $-prefixed keys are Sift pass-through (or set via typed fields).
111
112
  */
112
- type FraudCustomMetadata = Record<string, unknown>;
113
- declare function hasReservedMetadataKey(metadata: FraudCustomMetadata): string | undefined;
113
+ interface FraudRuleSignalMetadata {
114
+ /** Rule signal payment method (e.g. "$credit_card"), not Sift $payment_method object */
115
+ payment_method?: string;
116
+ country?: string;
117
+ two_fa_enabled?: boolean;
118
+ two_fa_disabled?: boolean;
119
+ two_fa_method_changed?: boolean;
120
+ ip_country_mismatch?: boolean;
121
+ is_first_deposit?: boolean;
122
+ cumulative_deposit_amount?: number;
123
+ deposit_count?: number;
124
+ failed_deposit_count?: number;
125
+ is_first_withdrawal?: boolean;
126
+ withdrawal_method_differs?: boolean;
127
+ cumulative_withdrawal_amount?: number;
128
+ withdrawal_count?: number;
129
+ hours_since_last_deposit?: number;
130
+ days_since_last_activity?: number;
131
+ hours_since_account_creation?: number;
132
+ }
133
+ /** Extra Sift fields forwarded verbatim in metadata (e.g. $referrer_user_id, $promotions). */
134
+ type SiftPassThroughMetadata = Record<`$${string}`, unknown>;
135
+ type FraudCustomMetadata = FraudRuleSignalMetadata & SiftPassThroughMetadata & Record<string, unknown>;
136
+ /** Maps typed request fields to metadata keys they populate (typed values win on normalize). */
137
+ declare const TYPED_SIFT_METADATA_KEYS: Readonly<Record<string, string>>;
138
+ declare function findMetadataConflictWithTypedFields(metadata: FraudCustomMetadata, request: Record<string, unknown>): string | undefined;
139
+
140
+ /**
141
+ * Optional top-level rule-signal fields copied into plain metadata on the wire.
142
+ */
143
+ interface LoginRuleSignals {
144
+ ip_country_mismatch?: boolean;
145
+ }
146
+ interface UpdateAccountRuleSignals {
147
+ two_fa_enabled?: boolean;
148
+ two_fa_disabled?: boolean;
149
+ two_fa_method_changed?: boolean;
150
+ }
151
+ interface TransactionRuleSignals {
152
+ payment_method?: string;
153
+ is_first_deposit?: boolean;
154
+ cumulative_deposit_amount?: number;
155
+ deposit_count?: number;
156
+ failed_deposit_count?: number;
157
+ is_first_withdrawal?: boolean;
158
+ withdrawal_method_differs?: boolean;
159
+ cumulative_withdrawal_amount?: number;
160
+ withdrawal_count?: number;
161
+ hours_since_last_deposit?: number;
162
+ days_since_last_activity?: number;
163
+ hours_since_account_creation?: number;
164
+ }
165
+ declare const LOGIN_RULE_SIGNAL_KEYS: readonly ["ip_country_mismatch"];
166
+ declare const UPDATE_ACCOUNT_RULE_SIGNAL_KEYS: readonly ["two_fa_enabled", "two_fa_disabled", "two_fa_method_changed"];
167
+ declare const TRANSACTION_RULE_SIGNAL_KEYS: readonly ["payment_method", "is_first_deposit", "cumulative_deposit_amount", "deposit_count", "failed_deposit_count", "is_first_withdrawal", "withdrawal_method_differs", "cumulative_withdrawal_amount", "withdrawal_count", "hours_since_last_deposit", "days_since_last_activity", "hours_since_account_creation"];
168
+
169
+ /**
170
+ * Sift-aligned structured fields normalized into metadata.$* on the wire.
171
+ */
172
+ interface SiftBillingAddress {
173
+ name?: string;
174
+ phone?: string;
175
+ address_1?: string;
176
+ address_2?: string;
177
+ city?: string;
178
+ region?: string;
179
+ country?: string;
180
+ zipcode?: string;
181
+ [key: string]: unknown;
182
+ }
183
+ interface SiftPaymentMethod {
184
+ payment_type?: string;
185
+ payment_gateway?: string;
186
+ card_bin?: string;
187
+ card_last4?: string;
188
+ avs_result_code?: string;
189
+ cvv_result_code?: string;
190
+ verification_status?: string;
191
+ routing_number?: string;
192
+ account_holder_name?: string;
193
+ bank_name?: string;
194
+ bank_country?: string;
195
+ [key: string]: unknown;
196
+ }
197
+ interface SiftApp {
198
+ os?: string;
199
+ os_version?: string;
200
+ device_manufacturer?: string;
201
+ device_model?: string;
202
+ device_unique_id?: string;
203
+ app_name?: string;
204
+ app_version?: string;
205
+ client_language?: string;
206
+ [key: string]: unknown;
207
+ }
114
208
 
115
209
  /**
116
210
  * Discriminated fraud score request types keyed on event_type.
@@ -124,16 +218,32 @@ interface FraudScoreRequestBase {
124
218
  ip_address?: string;
125
219
  device_id?: string;
126
220
  user_agent?: string;
221
+ /** Maps to metadata.$session_id */
222
+ session_id?: string;
223
+ /** Maps to metadata.$user_email */
224
+ user_email?: string;
225
+ /** Maps to metadata.$name */
226
+ name?: string;
227
+ /** Maps to metadata.$phone */
228
+ phone?: string;
229
+ /** Maps to metadata.$payment_method (Sift object) — typically on transactions */
230
+ sift_payment_method?: SiftPaymentMethod;
231
+ /** Maps to metadata.$payment_methods (Sift array) — account create/update baseline */
232
+ payment_methods?: SiftPaymentMethod[];
233
+ /** Maps to metadata.$billing_address */
234
+ billing_address?: SiftBillingAddress;
235
+ /** Maps to metadata.$app */
236
+ app?: SiftApp;
127
237
  /**
128
- * Custom fields only — keys must NOT start with '$'.
129
- * Sift reserved fields belong on typed request fields.
238
+ * Plain Vesant rule signals and optional $-prefixed Sift pass-through keys.
239
+ * Prefer typed fields for common Sift keys ($session_id, $user_email, etc.).
130
240
  */
131
241
  metadata?: FraudCustomMetadata;
132
242
  }
133
243
  interface CreateAccountScoreRequest extends FraudScoreRequestBase {
134
244
  event_type: '$create_account';
135
245
  }
136
- interface LoginScoreRequest extends FraudScoreRequestBase {
246
+ interface LoginScoreRequest extends FraudScoreRequestBase, LoginRuleSignals {
137
247
  event_type: '$login';
138
248
  login_status?: SiftLoginStatus;
139
249
  login_failure_reason?: SiftLoginFailureReason;
@@ -141,15 +251,17 @@ interface LoginScoreRequest extends FraudScoreRequestBase {
141
251
  interface LogoutScoreRequest extends FraudScoreRequestBase {
142
252
  event_type: '$logout';
143
253
  }
144
- interface UpdateAccountScoreRequest extends FraudScoreRequestBase {
254
+ interface UpdateAccountScoreRequest extends FraudScoreRequestBase, UpdateAccountRuleSignals {
145
255
  event_type: '$update_account';
146
256
  }
147
257
  interface UpdatePasswordScoreRequest extends FraudScoreRequestBase {
148
258
  event_type: '$update_password';
149
- password_reason: SiftPasswordUpdateReason;
150
- password_status: SiftPasswordUpdateStatus;
259
+ /** Defaults to $user_update on the wire when omitted */
260
+ password_reason?: SiftPasswordUpdateReason;
261
+ /** Defaults to $success on the wire when omitted */
262
+ password_status?: SiftPasswordUpdateStatus;
151
263
  }
152
- interface TransactionScoreRequest extends FraudScoreRequestBase {
264
+ interface TransactionScoreRequest extends FraudScoreRequestBase, TransactionRuleSignals {
153
265
  event_type: '$transaction';
154
266
  amount: number;
155
267
  currency: string;
@@ -246,4 +358,4 @@ declare function normalizeScoreRequestForApi(request: FraudScoreRequest): Record
246
358
  */
247
359
  declare function buildScoreRequestPreview(request: FraudScoreRequest): Record<string, unknown>;
248
360
 
249
- export { CHARGEBACK_FRAUD_EVENT_TYPE, type ChargebackFraudEventType, ChargebackReason, type ChargebackScoreRequest, type ChargebackScoreResponseData, ChargebackState, type CreateAccountScoreRequest, FraudClient, type FraudCustomMetadata, type FraudDecision, type FraudEventType, type FraudReactionType, type FraudRiskLevel, type FraudScoreRequest, type FraudScoreRequestBase, type FraudScoreResponseData, type FraudScoreResponseEnvelope, type FraudScoreResponseMetadata, type LoginScoreRequest, LoginStatus, type LogoutScoreRequest, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, type PlannedFraudEventType, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, type ScoredFraudEventType, type ScoredFraudScoreRequest, type SiftChargebackReason, SiftChargebackReasonValues, type SiftChargebackState, SiftChargebackStateValues, type SiftLoginFailureReason, SiftLoginFailureReasonValues, type SiftLoginStatus, SiftLoginStatusValues, type SiftPasswordUpdateReason, SiftPasswordUpdateReasonValues, type SiftPasswordUpdateStatus, SiftPasswordUpdateStatusValues, type SiftTransactionStatus, SiftTransactionStatusValues, type SiftTransactionType, SiftTransactionTypeValues, type SiftWagerStatus, SiftWagerStatusValues, type SupportedFraudEventType, type TenantAction, type TransactionScoreRequest, TransactionStatus, TransactionType, type UpdateAccountScoreRequest, type UpdatePasswordScoreRequest, type WagerScoreRequest, WagerStatus, buildScoreRequestPreview, hasReservedMetadataKey, isPlannedFraudEventType, isSupportedFraudEventType, normalizeScoreRequestForApi, validateScoreRequest };
361
+ export { CHARGEBACK_FRAUD_EVENT_TYPE, type ChargebackFraudEventType, ChargebackReason, type ChargebackScoreRequest, type ChargebackScoreResponseData, ChargebackState, type CreateAccountScoreRequest, FraudClient, type FraudCustomMetadata, type FraudDecision, type FraudEventType, type FraudReactionType, type FraudRiskLevel, type FraudRuleSignalMetadata, type FraudScoreRequest, type FraudScoreRequestBase, type FraudScoreResponseData, type FraudScoreResponseEnvelope, type FraudScoreResponseMetadata, LOGIN_RULE_SIGNAL_KEYS, type LoginRuleSignals, type LoginScoreRequest, LoginStatus, type LogoutScoreRequest, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, type PlannedFraudEventType, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, type ScoredFraudEventType, type ScoredFraudScoreRequest, type SiftApp, type SiftBillingAddress, type SiftChargebackReason, SiftChargebackReasonValues, type SiftChargebackState, SiftChargebackStateValues, type SiftLoginFailureReason, SiftLoginFailureReasonValues, type SiftLoginStatus, SiftLoginStatusValues, type SiftPassThroughMetadata, type SiftPasswordUpdateReason, SiftPasswordUpdateReasonValues, type SiftPasswordUpdateStatus, SiftPasswordUpdateStatusValues, type SiftPaymentMethod, type SiftTransactionStatus, SiftTransactionStatusValues, type SiftTransactionType, SiftTransactionTypeValues, type SiftWagerStatus, SiftWagerStatusValues, type SupportedFraudEventType, TRANSACTION_RULE_SIGNAL_KEYS, TYPED_SIFT_METADATA_KEYS, type TenantAction, type TransactionRuleSignals, type TransactionScoreRequest, TransactionStatus, TransactionType, UPDATE_ACCOUNT_RULE_SIGNAL_KEYS, type UpdateAccountRuleSignals, type UpdateAccountScoreRequest, type UpdatePasswordScoreRequest, type WagerScoreRequest, WagerStatus, buildScoreRequestPreview, findMetadataConflictWithTypedFields, isPlannedFraudEventType, isSupportedFraudEventType, normalizeScoreRequestForApi, validateScoreRequest };
package/dist/index.d.ts CHANGED
@@ -107,10 +107,104 @@ declare const TransactionStatus: {
107
107
  type FraudRiskLevel = 'low' | 'medium' | 'high' | 'critical';
108
108
 
109
109
  /**
110
- * Custom metadata for fraud score requests (non-Sift reserved keys).
110
+ * Metadata for fraud score requests.
111
+ * Plain keys are Vesant rule signals; $-prefixed keys are Sift pass-through (or set via typed fields).
111
112
  */
112
- type FraudCustomMetadata = Record<string, unknown>;
113
- declare function hasReservedMetadataKey(metadata: FraudCustomMetadata): string | undefined;
113
+ interface FraudRuleSignalMetadata {
114
+ /** Rule signal payment method (e.g. "$credit_card"), not Sift $payment_method object */
115
+ payment_method?: string;
116
+ country?: string;
117
+ two_fa_enabled?: boolean;
118
+ two_fa_disabled?: boolean;
119
+ two_fa_method_changed?: boolean;
120
+ ip_country_mismatch?: boolean;
121
+ is_first_deposit?: boolean;
122
+ cumulative_deposit_amount?: number;
123
+ deposit_count?: number;
124
+ failed_deposit_count?: number;
125
+ is_first_withdrawal?: boolean;
126
+ withdrawal_method_differs?: boolean;
127
+ cumulative_withdrawal_amount?: number;
128
+ withdrawal_count?: number;
129
+ hours_since_last_deposit?: number;
130
+ days_since_last_activity?: number;
131
+ hours_since_account_creation?: number;
132
+ }
133
+ /** Extra Sift fields forwarded verbatim in metadata (e.g. $referrer_user_id, $promotions). */
134
+ type SiftPassThroughMetadata = Record<`$${string}`, unknown>;
135
+ type FraudCustomMetadata = FraudRuleSignalMetadata & SiftPassThroughMetadata & Record<string, unknown>;
136
+ /** Maps typed request fields to metadata keys they populate (typed values win on normalize). */
137
+ declare const TYPED_SIFT_METADATA_KEYS: Readonly<Record<string, string>>;
138
+ declare function findMetadataConflictWithTypedFields(metadata: FraudCustomMetadata, request: Record<string, unknown>): string | undefined;
139
+
140
+ /**
141
+ * Optional top-level rule-signal fields copied into plain metadata on the wire.
142
+ */
143
+ interface LoginRuleSignals {
144
+ ip_country_mismatch?: boolean;
145
+ }
146
+ interface UpdateAccountRuleSignals {
147
+ two_fa_enabled?: boolean;
148
+ two_fa_disabled?: boolean;
149
+ two_fa_method_changed?: boolean;
150
+ }
151
+ interface TransactionRuleSignals {
152
+ payment_method?: string;
153
+ is_first_deposit?: boolean;
154
+ cumulative_deposit_amount?: number;
155
+ deposit_count?: number;
156
+ failed_deposit_count?: number;
157
+ is_first_withdrawal?: boolean;
158
+ withdrawal_method_differs?: boolean;
159
+ cumulative_withdrawal_amount?: number;
160
+ withdrawal_count?: number;
161
+ hours_since_last_deposit?: number;
162
+ days_since_last_activity?: number;
163
+ hours_since_account_creation?: number;
164
+ }
165
+ declare const LOGIN_RULE_SIGNAL_KEYS: readonly ["ip_country_mismatch"];
166
+ declare const UPDATE_ACCOUNT_RULE_SIGNAL_KEYS: readonly ["two_fa_enabled", "two_fa_disabled", "two_fa_method_changed"];
167
+ declare const TRANSACTION_RULE_SIGNAL_KEYS: readonly ["payment_method", "is_first_deposit", "cumulative_deposit_amount", "deposit_count", "failed_deposit_count", "is_first_withdrawal", "withdrawal_method_differs", "cumulative_withdrawal_amount", "withdrawal_count", "hours_since_last_deposit", "days_since_last_activity", "hours_since_account_creation"];
168
+
169
+ /**
170
+ * Sift-aligned structured fields normalized into metadata.$* on the wire.
171
+ */
172
+ interface SiftBillingAddress {
173
+ name?: string;
174
+ phone?: string;
175
+ address_1?: string;
176
+ address_2?: string;
177
+ city?: string;
178
+ region?: string;
179
+ country?: string;
180
+ zipcode?: string;
181
+ [key: string]: unknown;
182
+ }
183
+ interface SiftPaymentMethod {
184
+ payment_type?: string;
185
+ payment_gateway?: string;
186
+ card_bin?: string;
187
+ card_last4?: string;
188
+ avs_result_code?: string;
189
+ cvv_result_code?: string;
190
+ verification_status?: string;
191
+ routing_number?: string;
192
+ account_holder_name?: string;
193
+ bank_name?: string;
194
+ bank_country?: string;
195
+ [key: string]: unknown;
196
+ }
197
+ interface SiftApp {
198
+ os?: string;
199
+ os_version?: string;
200
+ device_manufacturer?: string;
201
+ device_model?: string;
202
+ device_unique_id?: string;
203
+ app_name?: string;
204
+ app_version?: string;
205
+ client_language?: string;
206
+ [key: string]: unknown;
207
+ }
114
208
 
115
209
  /**
116
210
  * Discriminated fraud score request types keyed on event_type.
@@ -124,16 +218,32 @@ interface FraudScoreRequestBase {
124
218
  ip_address?: string;
125
219
  device_id?: string;
126
220
  user_agent?: string;
221
+ /** Maps to metadata.$session_id */
222
+ session_id?: string;
223
+ /** Maps to metadata.$user_email */
224
+ user_email?: string;
225
+ /** Maps to metadata.$name */
226
+ name?: string;
227
+ /** Maps to metadata.$phone */
228
+ phone?: string;
229
+ /** Maps to metadata.$payment_method (Sift object) — typically on transactions */
230
+ sift_payment_method?: SiftPaymentMethod;
231
+ /** Maps to metadata.$payment_methods (Sift array) — account create/update baseline */
232
+ payment_methods?: SiftPaymentMethod[];
233
+ /** Maps to metadata.$billing_address */
234
+ billing_address?: SiftBillingAddress;
235
+ /** Maps to metadata.$app */
236
+ app?: SiftApp;
127
237
  /**
128
- * Custom fields only — keys must NOT start with '$'.
129
- * Sift reserved fields belong on typed request fields.
238
+ * Plain Vesant rule signals and optional $-prefixed Sift pass-through keys.
239
+ * Prefer typed fields for common Sift keys ($session_id, $user_email, etc.).
130
240
  */
131
241
  metadata?: FraudCustomMetadata;
132
242
  }
133
243
  interface CreateAccountScoreRequest extends FraudScoreRequestBase {
134
244
  event_type: '$create_account';
135
245
  }
136
- interface LoginScoreRequest extends FraudScoreRequestBase {
246
+ interface LoginScoreRequest extends FraudScoreRequestBase, LoginRuleSignals {
137
247
  event_type: '$login';
138
248
  login_status?: SiftLoginStatus;
139
249
  login_failure_reason?: SiftLoginFailureReason;
@@ -141,15 +251,17 @@ interface LoginScoreRequest extends FraudScoreRequestBase {
141
251
  interface LogoutScoreRequest extends FraudScoreRequestBase {
142
252
  event_type: '$logout';
143
253
  }
144
- interface UpdateAccountScoreRequest extends FraudScoreRequestBase {
254
+ interface UpdateAccountScoreRequest extends FraudScoreRequestBase, UpdateAccountRuleSignals {
145
255
  event_type: '$update_account';
146
256
  }
147
257
  interface UpdatePasswordScoreRequest extends FraudScoreRequestBase {
148
258
  event_type: '$update_password';
149
- password_reason: SiftPasswordUpdateReason;
150
- password_status: SiftPasswordUpdateStatus;
259
+ /** Defaults to $user_update on the wire when omitted */
260
+ password_reason?: SiftPasswordUpdateReason;
261
+ /** Defaults to $success on the wire when omitted */
262
+ password_status?: SiftPasswordUpdateStatus;
151
263
  }
152
- interface TransactionScoreRequest extends FraudScoreRequestBase {
264
+ interface TransactionScoreRequest extends FraudScoreRequestBase, TransactionRuleSignals {
153
265
  event_type: '$transaction';
154
266
  amount: number;
155
267
  currency: string;
@@ -246,4 +358,4 @@ declare function normalizeScoreRequestForApi(request: FraudScoreRequest): Record
246
358
  */
247
359
  declare function buildScoreRequestPreview(request: FraudScoreRequest): Record<string, unknown>;
248
360
 
249
- export { CHARGEBACK_FRAUD_EVENT_TYPE, type ChargebackFraudEventType, ChargebackReason, type ChargebackScoreRequest, type ChargebackScoreResponseData, ChargebackState, type CreateAccountScoreRequest, FraudClient, type FraudCustomMetadata, type FraudDecision, type FraudEventType, type FraudReactionType, type FraudRiskLevel, type FraudScoreRequest, type FraudScoreRequestBase, type FraudScoreResponseData, type FraudScoreResponseEnvelope, type FraudScoreResponseMetadata, type LoginScoreRequest, LoginStatus, type LogoutScoreRequest, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, type PlannedFraudEventType, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, type ScoredFraudEventType, type ScoredFraudScoreRequest, type SiftChargebackReason, SiftChargebackReasonValues, type SiftChargebackState, SiftChargebackStateValues, type SiftLoginFailureReason, SiftLoginFailureReasonValues, type SiftLoginStatus, SiftLoginStatusValues, type SiftPasswordUpdateReason, SiftPasswordUpdateReasonValues, type SiftPasswordUpdateStatus, SiftPasswordUpdateStatusValues, type SiftTransactionStatus, SiftTransactionStatusValues, type SiftTransactionType, SiftTransactionTypeValues, type SiftWagerStatus, SiftWagerStatusValues, type SupportedFraudEventType, type TenantAction, type TransactionScoreRequest, TransactionStatus, TransactionType, type UpdateAccountScoreRequest, type UpdatePasswordScoreRequest, type WagerScoreRequest, WagerStatus, buildScoreRequestPreview, hasReservedMetadataKey, isPlannedFraudEventType, isSupportedFraudEventType, normalizeScoreRequestForApi, validateScoreRequest };
361
+ export { CHARGEBACK_FRAUD_EVENT_TYPE, type ChargebackFraudEventType, ChargebackReason, type ChargebackScoreRequest, type ChargebackScoreResponseData, ChargebackState, type CreateAccountScoreRequest, FraudClient, type FraudCustomMetadata, type FraudDecision, type FraudEventType, type FraudReactionType, type FraudRiskLevel, type FraudRuleSignalMetadata, type FraudScoreRequest, type FraudScoreRequestBase, type FraudScoreResponseData, type FraudScoreResponseEnvelope, type FraudScoreResponseMetadata, LOGIN_RULE_SIGNAL_KEYS, type LoginRuleSignals, type LoginScoreRequest, LoginStatus, type LogoutScoreRequest, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, type PlannedFraudEventType, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, type ScoredFraudEventType, type ScoredFraudScoreRequest, type SiftApp, type SiftBillingAddress, type SiftChargebackReason, SiftChargebackReasonValues, type SiftChargebackState, SiftChargebackStateValues, type SiftLoginFailureReason, SiftLoginFailureReasonValues, type SiftLoginStatus, SiftLoginStatusValues, type SiftPassThroughMetadata, type SiftPasswordUpdateReason, SiftPasswordUpdateReasonValues, type SiftPasswordUpdateStatus, SiftPasswordUpdateStatusValues, type SiftPaymentMethod, type SiftTransactionStatus, SiftTransactionStatusValues, type SiftTransactionType, SiftTransactionTypeValues, type SiftWagerStatus, SiftWagerStatusValues, type SupportedFraudEventType, TRANSACTION_RULE_SIGNAL_KEYS, TYPED_SIFT_METADATA_KEYS, type TenantAction, type TransactionRuleSignals, type TransactionScoreRequest, TransactionStatus, TransactionType, UPDATE_ACCOUNT_RULE_SIGNAL_KEYS, type UpdateAccountRuleSignals, type UpdateAccountScoreRequest, type UpdatePasswordScoreRequest, type WagerScoreRequest, WagerStatus, buildScoreRequestPreview, findMetadataConflictWithTypedFields, isPlannedFraudEventType, isSupportedFraudEventType, normalizeScoreRequestForApi, validateScoreRequest };