@wishknish/knishio-client-ts 0.7.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.
Files changed (141) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +425 -0
  3. package/dist/index.cjs +9961 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.iife.js +32241 -0
  6. package/dist/index.iife.js.map +1 -0
  7. package/dist/index.js +9853 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +113 -0
  10. package/src/AuthToken.ts +214 -0
  11. package/src/KnishIOClient.ts +2020 -0
  12. package/src/constants.ts +398 -0
  13. package/src/core/Atom.ts +646 -0
  14. package/src/core/AtomMeta.ts +278 -0
  15. package/src/core/Meta.ts +428 -0
  16. package/src/core/Molecule.ts +825 -0
  17. package/src/core/PolicyMeta.ts +130 -0
  18. package/src/core/TokenUnit.ts +148 -0
  19. package/src/core/Wallet.ts +467 -0
  20. package/src/exception/AtomIndexException.ts +97 -0
  21. package/src/exception/AtomsMissingException.ts +109 -0
  22. package/src/exception/AuthorizationRejectedException.ts +63 -0
  23. package/src/exception/BalanceInsufficientException.ts +58 -0
  24. package/src/exception/BaseException.ts +275 -0
  25. package/src/exception/BatchIdException.ts +58 -0
  26. package/src/exception/CodeException.ts +119 -0
  27. package/src/exception/DecryptionKeyException.ts +65 -0
  28. package/src/exception/InvalidResponseException.ts +112 -0
  29. package/src/exception/MetaMissingException.ts +58 -0
  30. package/src/exception/MolecularHashMismatchException.ts +115 -0
  31. package/src/exception/MolecularHashMissingException.ts +58 -0
  32. package/src/exception/NegativeAmountException.ts +58 -0
  33. package/src/exception/PolicyInvalidException.ts +58 -0
  34. package/src/exception/SignatureMalformedException.ts +58 -0
  35. package/src/exception/SignatureMismatchException.ts +98 -0
  36. package/src/exception/StackableUnitAmountException.ts +65 -0
  37. package/src/exception/StackableUnitDecimalsException.ts +65 -0
  38. package/src/exception/TransferBalanceException.ts +98 -0
  39. package/src/exception/TransferMalformedException.ts +58 -0
  40. package/src/exception/TransferMismatchedException.ts +58 -0
  41. package/src/exception/TransferRemainderException.ts +58 -0
  42. package/src/exception/TransferToSelfException.ts +58 -0
  43. package/src/exception/TransferUnbalancedException.ts +58 -0
  44. package/src/exception/UnauthenticatedException.ts +147 -0
  45. package/src/exception/WalletCredentialException.ts +108 -0
  46. package/src/exception/WalletShadowException.ts +65 -0
  47. package/src/exception/WrongTokenTypeException.ts +58 -0
  48. package/src/exception/index.ts +272 -0
  49. package/src/index.ts +512 -0
  50. package/src/instance/rules/Callback.ts +257 -0
  51. package/src/instance/rules/Condition.ts +96 -0
  52. package/src/instance/rules/Meta.ts +163 -0
  53. package/src/instance/rules/Rule.ts +29 -0
  54. package/src/instance/rules/exception/RuleArgumentException.ts +65 -0
  55. package/src/libraries/CheckMolecule.ts +581 -0
  56. package/src/libraries/Decimal.ts +94 -0
  57. package/src/libraries/Dot.ts +202 -0
  58. package/src/libraries/GraphQLClient.ts +276 -0
  59. package/src/libraries/Hex.ts +155 -0
  60. package/src/libraries/UrqlClientWrapper.ts +336 -0
  61. package/src/libraries/array.ts +91 -0
  62. package/src/libraries/crypto.ts +816 -0
  63. package/src/libraries/strings.ts +458 -0
  64. package/src/mutation/Mutation.ts +103 -0
  65. package/src/mutation/MutationActiveSession.ts +108 -0
  66. package/src/mutation/MutationClaimShadowWallet.ts +91 -0
  67. package/src/mutation/MutationCreateIdentifier.ts +86 -0
  68. package/src/mutation/MutationCreateMeta.ts +92 -0
  69. package/src/mutation/MutationCreateRule.ts +90 -0
  70. package/src/mutation/MutationCreateToken.ts +92 -0
  71. package/src/mutation/MutationCreateWallet.ts +78 -0
  72. package/src/mutation/MutationDepositBufferToken.ts +72 -0
  73. package/src/mutation/MutationLinkIdentifier.ts +87 -0
  74. package/src/mutation/MutationProposeMolecule.ts +147 -0
  75. package/src/mutation/MutationRequestAuthorization.ts +77 -0
  76. package/src/mutation/MutationRequestAuthorizationGuest.ts +85 -0
  77. package/src/mutation/MutationRequestTokens.ts +98 -0
  78. package/src/mutation/MutationTransferTokens.ts +87 -0
  79. package/src/mutation/MutationWithdrawBufferToken.ts +73 -0
  80. package/src/query/Query.ts +187 -0
  81. package/src/query/QueryActiveSession.ts +89 -0
  82. package/src/query/QueryAtom.ts +275 -0
  83. package/src/query/QueryBalance.ts +102 -0
  84. package/src/query/QueryBatch.ts +145 -0
  85. package/src/query/QueryBatchHistory.ts +86 -0
  86. package/src/query/QueryContinuId.ts +91 -0
  87. package/src/query/QueryMetaType.ts +177 -0
  88. package/src/query/QueryMetaTypeViaAtom.ts +199 -0
  89. package/src/query/QueryPolicy.ts +91 -0
  90. package/src/query/QueryToken.ts +90 -0
  91. package/src/query/QueryUserActivity.ts +153 -0
  92. package/src/query/QueryWalletBundle.ts +92 -0
  93. package/src/query/QueryWalletList.ts +106 -0
  94. package/src/response/EnhancedResponse.ts +345 -0
  95. package/src/response/Response.ts +254 -0
  96. package/src/response/ResponseActiveSession.ts +72 -0
  97. package/src/response/ResponseAtom.ts +132 -0
  98. package/src/response/ResponseAuthorizationGuest.ts +119 -0
  99. package/src/response/ResponseBalance.ts +153 -0
  100. package/src/response/ResponseClaimShadowWallet.ts +56 -0
  101. package/src/response/ResponseContinuId.ts +101 -0
  102. package/src/response/ResponseCreateIdentifier.ts +56 -0
  103. package/src/response/ResponseCreateMeta.ts +58 -0
  104. package/src/response/ResponseCreateRule.ts +56 -0
  105. package/src/response/ResponseCreateToken.ts +58 -0
  106. package/src/response/ResponseCreateWallet.ts +58 -0
  107. package/src/response/ResponseLinkIdentifier.ts +87 -0
  108. package/src/response/ResponseMetaBatch.ts +72 -0
  109. package/src/response/ResponseMetaType.ts +108 -0
  110. package/src/response/ResponseMetaTypeViaAtom.ts +108 -0
  111. package/src/response/ResponsePolicy.ts +90 -0
  112. package/src/response/ResponseProposeMolecule.ts +155 -0
  113. package/src/response/ResponseQueryActiveSession.ts +105 -0
  114. package/src/response/ResponseQueryUserActivity.ts +89 -0
  115. package/src/response/ResponseRequestAuthorization.ts +100 -0
  116. package/src/response/ResponseRequestAuthorizationGuest.ts +133 -0
  117. package/src/response/ResponseRequestTokens.ts +58 -0
  118. package/src/response/ResponseTransferTokens.ts +72 -0
  119. package/src/response/ResponseWalletBundle.ts +95 -0
  120. package/src/response/ResponseWalletList.ts +165 -0
  121. package/src/schemas/index.ts +457 -0
  122. package/src/subscribe/ActiveSessionSubscribe.ts +72 -0
  123. package/src/subscribe/ActiveWalletSubscribe.ts +99 -0
  124. package/src/subscribe/CreateMoleculeSubscribe.ts +106 -0
  125. package/src/subscribe/Subscribe.ts +182 -0
  126. package/src/subscribe/WalletStatusSubscribe.ts +70 -0
  127. package/src/subscribe/index.ts +59 -0
  128. package/src/types/assertions.ts +722 -0
  129. package/src/types/client.ts +567 -0
  130. package/src/types/crypto.ts +541 -0
  131. package/src/types/graphql.ts +630 -0
  132. package/src/types/guards.ts +659 -0
  133. package/src/types/index.ts +614 -0
  134. package/src/types/response.ts +133 -0
  135. package/src/types/template-literals.ts +382 -0
  136. package/src/validation/UNIVERSAL_CONFIGURATION_INTERFACES.ts +580 -0
  137. package/src/validation/ValidationService.ts +607 -0
  138. package/src/validation/schemas.ts +447 -0
  139. package/src/versions/HashAtom.ts +170 -0
  140. package/src/versions/Version4.ts +120 -0
  141. package/src/versions/index.ts +80 -0
@@ -0,0 +1,607 @@
1
+ /*
2
+ (
3
+ (/(
4
+ (//(
5
+ (///(
6
+ (/////(
7
+ (//////( )
8
+ (////////( (/)
9
+ (////////( (///)
10
+ (//////////( (////)
11
+ (//////////( (//////)
12
+ (////////////( (///////)
13
+ (/////////////( (/////////)
14
+ (//////////////( (///////////)
15
+ (///////////////( (/////////////)
16
+ (////////////////( (//////////////)
17
+ ((((((((((((((((((( (((((((((((((((
18
+ ((((((((((((((((((( ((((((((((((((
19
+ ((((((((((((((((((( ((((((((((((((
20
+ (((((((((((((((((((( (((((((((((((
21
+ (((((((((((((((((((( ((((((((((((
22
+ ((((((((((((((((((( ((((((((((((
23
+ ((((((((((((((((((( ((((((((((
24
+ ((((((((((((((((((/ (((((((((
25
+ (((((((((((((((((( ((((((((
26
+ ((((((((((((((((( (((((((
27
+ (((((((((((((((((( (((((
28
+ ################# ##
29
+ ################ #
30
+ ################# ##
31
+ %################ ###
32
+ ###############( ####
33
+ ############### ####
34
+ ############### ######
35
+ %#############( (#######
36
+ %############# #########
37
+ ############( ##########
38
+ ########### #############
39
+ ######### ##############
40
+ %######
41
+
42
+ Powered by Knish.IO: Connecting a Decentralized World
43
+
44
+ Please visit https://github.com/WishKnish/KnishIO-Client-TS for information.
45
+
46
+ License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
47
+ */
48
+
49
+ /**
50
+ * ValidationService - Centralized validation for KnishIO SDK
51
+ *
52
+ * Implements 2025 TypeScript patterns:
53
+ * - Zod runtime validation with compile-time types
54
+ * - Result<T, E> pattern for error handling
55
+ * - Builder pattern for validation chains
56
+ * - Branded types for domain safety
57
+ */
58
+
59
+ import { z } from 'zod'
60
+ import type {
61
+ KnishIOClientConfig,
62
+ TransferParams,
63
+ CreateTokenParams,
64
+ RequestTokensParams,
65
+ BalanceQueryParams,
66
+ MetaQueryParams,
67
+ WalletQueryParams
68
+ } from '@/types'
69
+ import {
70
+ Schemas,
71
+ safeParse,
72
+ validateStrict,
73
+ validateWithDefaults,
74
+ createTypeGuard,
75
+ type ValidatedClientConfig,
76
+ type ValidatedTransferParams,
77
+ type ValidatedGraphQLResponse
78
+ } from './schemas'
79
+
80
+ // =============================================================================
81
+ // RESULT TYPE PATTERN (2025 TYPESCRIPT)
82
+ // =============================================================================
83
+
84
+ export type ValidationResult<T, E = ValidationError> =
85
+ | { success: true; data: T; warnings?: string[] }
86
+ | { success: false; error: E }
87
+
88
+ export interface ValidationError {
89
+ code: 'VALIDATION_ERROR' | 'SCHEMA_ERROR' | 'TYPE_ERROR'
90
+ message: string
91
+ field?: string
92
+ value?: unknown
93
+ details?: z.ZodIssue[]
94
+ context?: string
95
+ }
96
+
97
+ export interface ValidationOptions {
98
+ strict?: boolean
99
+ allowUnknown?: boolean
100
+ stripUnknown?: boolean
101
+ context?: string
102
+ warnings?: boolean
103
+ }
104
+
105
+ // =============================================================================
106
+ // VALIDATION SERVICE CLASS
107
+ // =============================================================================
108
+
109
+ /**
110
+ * Centralized validation service using Zod schemas
111
+ * Provides type-safe validation with enhanced error reporting
112
+ */
113
+ export class ValidationService {
114
+ private static instance: ValidationService
115
+ private validationHistory: Array<{
116
+ timestamp: number
117
+ schema: string
118
+ success: boolean
119
+ error?: string
120
+ }> = []
121
+
122
+ private constructor() {}
123
+
124
+ static getInstance(): ValidationService {
125
+ if (!ValidationService.instance) {
126
+ ValidationService.instance = new ValidationService()
127
+ }
128
+ return ValidationService.instance
129
+ }
130
+
131
+ // =============================================================================
132
+ // CORE VALIDATION METHODS
133
+ // =============================================================================
134
+
135
+ /**
136
+ * Validate client configuration with environment overrides
137
+ */
138
+ validateClientConfig(config: unknown): ValidationResult<ValidatedClientConfig> {
139
+ try {
140
+ // First get environment-mapped client config
141
+ const envResult = this.validateEnvironmentConfig()
142
+ const envMappedConfig = envResult.success ? envResult.data : {}
143
+
144
+ // Merge environment config with provided config (provided config takes precedence)
145
+ const mergedConfig = {
146
+ ...envMappedConfig,
147
+ ...(typeof config === 'object' && config !== null ? config : {})
148
+ }
149
+
150
+ const parseResult = safeParse(Schemas.ClientConfig, mergedConfig)
151
+
152
+ if (!parseResult.success) {
153
+ return {
154
+ success: false,
155
+ error: {
156
+ code: 'VALIDATION_ERROR',
157
+ message: 'Invalid client configuration',
158
+ details: parseResult.error.issues,
159
+ context: 'ClientConfig'
160
+ }
161
+ }
162
+ }
163
+
164
+ this.logValidation('ClientConfig', true)
165
+ return {
166
+ success: true,
167
+ data: parseResult.data,
168
+ warnings: this.generateConfigWarnings(parseResult.data)
169
+ }
170
+ } catch (error) {
171
+ this.logValidation('ClientConfig', false, String(error))
172
+ return {
173
+ success: false,
174
+ error: {
175
+ code: 'SCHEMA_ERROR',
176
+ message: `Validation failed: ${error}`,
177
+ context: 'ClientConfig'
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Validate environment configuration and map to client config format
185
+ */
186
+ validateEnvironmentConfig(): ValidationResult<Record<string, any>> {
187
+ try {
188
+ const env = {
189
+ NODE_ENV: process.env.NODE_ENV,
190
+ KNISHIO_NODE_URI: process.env.KNISHIO_NODE_URI,
191
+ KNISHIO_CELL_SLUG: process.env.KNISHIO_CELL_SLUG,
192
+ KNISHIO_LOGGING: process.env.KNISHIO_LOGGING,
193
+ KNISHIO_SERVER_SDK_VERSION: process.env.KNISHIO_SERVER_SDK_VERSION
194
+ }
195
+
196
+ const parseResult = safeParse(Schemas.EnvironmentConfig, env)
197
+
198
+ if (!parseResult.success) {
199
+ return {
200
+ success: false,
201
+ error: {
202
+ code: 'VALIDATION_ERROR',
203
+ message: 'Invalid environment configuration',
204
+ details: parseResult.error.issues,
205
+ context: 'Environment'
206
+ }
207
+ }
208
+ }
209
+
210
+ // Map environment variables to client configuration properties
211
+ const validatedEnv = parseResult.data
212
+ const clientConfig: Record<string, any> = {}
213
+
214
+ // Map KNISHIO_NODE_URI to uri
215
+ if (validatedEnv.KNISHIO_NODE_URI) {
216
+ clientConfig.uri = validatedEnv.KNISHIO_NODE_URI
217
+ }
218
+
219
+ // Map KNISHIO_CELL_SLUG to cellSlug
220
+ if (validatedEnv.KNISHIO_CELL_SLUG) {
221
+ clientConfig.cellSlug = validatedEnv.KNISHIO_CELL_SLUG
222
+ }
223
+
224
+ // Map KNISHIO_LOGGING to logging
225
+ if (validatedEnv.KNISHIO_LOGGING !== undefined) {
226
+ clientConfig.logging = validatedEnv.KNISHIO_LOGGING
227
+ }
228
+
229
+ // Map KNISHIO_SERVER_SDK_VERSION to serverSdkVersion
230
+ if (validatedEnv.KNISHIO_SERVER_SDK_VERSION !== undefined) {
231
+ clientConfig.serverSdkVersion = validatedEnv.KNISHIO_SERVER_SDK_VERSION
232
+ }
233
+
234
+ return { success: true, data: clientConfig }
235
+ } catch (error) {
236
+ return {
237
+ success: false,
238
+ error: {
239
+ code: 'SCHEMA_ERROR',
240
+ message: `Environment validation failed: ${error}`,
241
+ context: 'Environment'
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Validate transfer parameters with business logic
249
+ */
250
+ validateTransferParams(params: unknown): ValidationResult<ValidatedTransferParams> {
251
+ try {
252
+ const parseResult = safeParse(Schemas.TransferParams, params)
253
+
254
+ if (!parseResult.success) {
255
+ return {
256
+ success: false,
257
+ error: {
258
+ code: 'VALIDATION_ERROR',
259
+ message: 'Invalid transfer parameters',
260
+ details: parseResult.error.issues,
261
+ context: 'TransferParams'
262
+ }
263
+ }
264
+ }
265
+
266
+ // Additional business logic validation
267
+ const businessValidation = this.validateTransferBusinessLogic(parseResult.data)
268
+ if (!businessValidation.success) {
269
+ return businessValidation
270
+ }
271
+
272
+ this.logValidation('TransferParams', true)
273
+ return {
274
+ success: true,
275
+ data: parseResult.data,
276
+ warnings: this.generateTransferWarnings(parseResult.data)
277
+ }
278
+ } catch (error) {
279
+ this.logValidation('TransferParams', false, String(error))
280
+ return {
281
+ success: false,
282
+ error: {
283
+ code: 'SCHEMA_ERROR',
284
+ message: `Transfer validation failed: ${error}`,
285
+ context: 'TransferParams'
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Validate GraphQL response structure
293
+ */
294
+ validateGraphQLResponse(response: unknown): ValidationResult<ValidatedGraphQLResponse> {
295
+ try {
296
+ const parseResult = safeParse(Schemas.GraphQLResponse, response)
297
+
298
+ if (!parseResult.success) {
299
+ return {
300
+ success: false,
301
+ error: {
302
+ code: 'VALIDATION_ERROR',
303
+ message: 'Invalid GraphQL response format',
304
+ details: parseResult.error.issues,
305
+ context: 'GraphQLResponse'
306
+ }
307
+ }
308
+ }
309
+
310
+ // Check for GraphQL errors
311
+ if (parseResult.data.errors && parseResult.data.errors.length > 0) {
312
+ return {
313
+ success: false,
314
+ error: {
315
+ code: 'VALIDATION_ERROR',
316
+ message: 'GraphQL response contains errors',
317
+ details: parseResult.data.errors.map(err => ({
318
+ code: 'invalid_type',
319
+ expected: 'success',
320
+ received: 'error',
321
+ path: [],
322
+ message: err.message
323
+ } as z.ZodIssue)),
324
+ context: 'GraphQLResponse'
325
+ }
326
+ }
327
+ }
328
+
329
+ this.logValidation('GraphQLResponse', true)
330
+ return { success: true, data: parseResult.data }
331
+ } catch (error) {
332
+ this.logValidation('GraphQLResponse', false, String(error))
333
+ return {
334
+ success: false,
335
+ error: {
336
+ code: 'SCHEMA_ERROR',
337
+ message: `GraphQL response validation failed: ${error}`,
338
+ context: 'GraphQLResponse'
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ // =============================================================================
345
+ // BUILDER PATTERN FOR VALIDATION CHAINS
346
+ // =============================================================================
347
+
348
+ /**
349
+ * Create a validation chain builder
350
+ */
351
+ createValidationChain<T>(): ValidationChainBuilder<T> {
352
+ return new ValidationChainBuilder<T>(this)
353
+ }
354
+
355
+ // =============================================================================
356
+ // TYPE GUARDS AND UTILITIES
357
+ // =============================================================================
358
+
359
+ /**
360
+ * Runtime type guards for common types
361
+ */
362
+ readonly typeGuards = {
363
+ isWalletAddress: createTypeGuard(Schemas.WalletAddress),
364
+ isBundleHash: createTypeGuard(Schemas.BundleHash),
365
+ isTokenSlug: createTypeGuard(Schemas.TokenSlug),
366
+ isClientConfig: createTypeGuard(Schemas.ClientConfig),
367
+ isTransferParams: createTypeGuard(Schemas.TransferParams),
368
+ isGraphQLResponse: createTypeGuard(Schemas.GraphQLResponse)
369
+ } as const
370
+
371
+ /**
372
+ * Validate any value against a specific schema
373
+ */
374
+ validate<T>(schema: z.ZodType<T>, value: unknown, options: ValidationOptions = {}): ValidationResult<T> {
375
+ try {
376
+ const parseResult = safeParse(schema, value)
377
+
378
+ if (!parseResult.success) {
379
+ return {
380
+ success: false,
381
+ error: {
382
+ code: 'VALIDATION_ERROR',
383
+ message: options.context ? `Validation failed in ${options.context}` : 'Validation failed',
384
+ details: parseResult.error.issues,
385
+ context: options.context
386
+ }
387
+ }
388
+ }
389
+
390
+ return { success: true, data: parseResult.data }
391
+ } catch (error) {
392
+ return {
393
+ success: false,
394
+ error: {
395
+ code: 'SCHEMA_ERROR',
396
+ message: `Schema validation failed: ${error}`,
397
+ context: options.context
398
+ }
399
+ }
400
+ }
401
+ }
402
+
403
+ // =============================================================================
404
+ // BUSINESS LOGIC VALIDATION
405
+ // =============================================================================
406
+
407
+ private validateTransferBusinessLogic(params: ValidatedTransferParams): ValidationResult<ValidatedTransferParams> {
408
+ const warnings: string[] = []
409
+
410
+ // Check for self-transfer
411
+ if (params.recipient === params.recipient) {
412
+ warnings.push('Transfer to same address detected')
413
+ }
414
+
415
+ // Validate amount ranges
416
+ const amount = Number(params.amount)
417
+ if (amount > 1000000) {
418
+ warnings.push('Large transfer amount detected - consider splitting')
419
+ }
420
+
421
+ return { success: true, data: params, warnings }
422
+ }
423
+
424
+ private generateConfigWarnings(config: ValidatedClientConfig): string[] {
425
+ const warnings: string[] = []
426
+
427
+ if (!config.uri) {
428
+ warnings.push('No URI specified - using default')
429
+ }
430
+
431
+ if (config.logging) {
432
+ warnings.push('Logging enabled - may impact performance')
433
+ }
434
+
435
+ if (config.serverSdkVersion && config.serverSdkVersion < 4) {
436
+ warnings.push('Using older server SDK version - consider upgrading')
437
+ }
438
+
439
+ return warnings
440
+ }
441
+
442
+ private generateTransferWarnings(params: ValidatedTransferParams): string[] {
443
+ const warnings: string[] = []
444
+
445
+ if (!params.token) {
446
+ warnings.push('No token specified - using default USER token')
447
+ }
448
+
449
+ if (!params.metaType && !params.metaId) {
450
+ warnings.push('No metadata specified for transfer')
451
+ }
452
+
453
+ return warnings
454
+ }
455
+
456
+ // =============================================================================
457
+ // VALIDATION LOGGING AND MONITORING
458
+ // =============================================================================
459
+
460
+ private logValidation(schema: string, success: boolean, error?: string): void {
461
+ this.validationHistory.push({
462
+ timestamp: Date.now(),
463
+ schema,
464
+ success,
465
+ error
466
+ })
467
+
468
+ // Keep only last 1000 validations
469
+ if (this.validationHistory.length > 1000) {
470
+ this.validationHistory = this.validationHistory.slice(-1000)
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Get validation statistics
476
+ */
477
+ getValidationStats(): {
478
+ total: number
479
+ successful: number
480
+ failed: number
481
+ successRate: number
482
+ schemaStats: Record<string, number>
483
+ recentFailures: Array<{
484
+ schema: string
485
+ error?: string
486
+ timestamp: number
487
+ }>
488
+ } {
489
+ const total = this.validationHistory.length
490
+ const successful = this.validationHistory.filter(v => v.success).length
491
+ const failed = total - successful
492
+
493
+ const schemaStats = this.validationHistory.reduce((acc, v) => {
494
+ acc[v.schema] = (acc[v.schema] || 0) + 1
495
+ return acc
496
+ }, {} as Record<string, number>)
497
+
498
+ return {
499
+ total,
500
+ successful,
501
+ failed,
502
+ successRate: total > 0 ? (successful / total) * 100 : 0,
503
+ schemaStats,
504
+ recentFailures: this.validationHistory
505
+ .filter(v => !v.success)
506
+ .slice(-10)
507
+ .map(v => ({ schema: v.schema, error: v.error, timestamp: v.timestamp }))
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Clear validation history
513
+ */
514
+ clearValidationHistory(): void {
515
+ this.validationHistory = []
516
+ }
517
+ }
518
+
519
+ // =============================================================================
520
+ // VALIDATION CHAIN BUILDER (FLUENT PATTERN)
521
+ // =============================================================================
522
+
523
+ export class ValidationChainBuilder<T> {
524
+ private validators: Array<(value: T) => ValidationResult<T>> = []
525
+
526
+ constructor(private service: ValidationService) {}
527
+
528
+ /**
529
+ * Add a schema validation step
530
+ */
531
+ schema<U>(schema: z.ZodType<U>): ValidationChainBuilder<T> {
532
+ this.validators.push((value) =>
533
+ this.service.validate(schema, value) as ValidationResult<T>
534
+ )
535
+ return this
536
+ }
537
+
538
+ /**
539
+ * Add a custom validation step
540
+ */
541
+ custom(validator: (value: T) => ValidationResult<T>): ValidationChainBuilder<T> {
542
+ this.validators.push(validator)
543
+ return this
544
+ }
545
+
546
+ /**
547
+ * Add a business logic validation step
548
+ */
549
+ business(validator: (value: T) => boolean, errorMessage: string): ValidationChainBuilder<T> {
550
+ this.validators.push((value) => {
551
+ if (validator(value)) {
552
+ return { success: true, data: value }
553
+ }
554
+ return {
555
+ success: false,
556
+ error: {
557
+ code: 'VALIDATION_ERROR',
558
+ message: errorMessage,
559
+ value,
560
+ context: 'BusinessLogic'
561
+ }
562
+ }
563
+ })
564
+ return this
565
+ }
566
+
567
+ /**
568
+ * Execute the validation chain
569
+ */
570
+ validate(value: unknown): ValidationResult<T> {
571
+ let currentValue = value as T
572
+
573
+ for (const validator of this.validators) {
574
+ const result = validator(currentValue)
575
+ if (!result.success) {
576
+ return result
577
+ }
578
+ currentValue = result.data
579
+ }
580
+
581
+ return { success: true, data: currentValue }
582
+ }
583
+ }
584
+
585
+ // =============================================================================
586
+ // SINGLETON INSTANCE AND UTILITIES
587
+ // =============================================================================
588
+
589
+ // Export singleton instance
590
+ export const validationService = ValidationService.getInstance()
591
+
592
+ // Convenience functions
593
+ export const validateClientConfig = (config: unknown): ValidationResult<ValidatedClientConfig> =>
594
+ validationService.validateClientConfig(config)
595
+
596
+ export const validateTransferParams = (params: unknown): ValidationResult<ValidatedTransferParams> =>
597
+ validationService.validateTransferParams(params)
598
+
599
+ export const validateGraphQLResponse = (response: unknown): ValidationResult<ValidatedGraphQLResponse> =>
600
+ validationService.validateGraphQLResponse(response)
601
+
602
+ // Type guard exports
603
+ export const { typeGuards } = validationService
604
+
605
+ // Validation chain factory
606
+ export const createValidationChain = <T>(): ValidationChainBuilder<T> =>
607
+ validationService.createValidationChain<T>()