@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,2020 @@
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
+ import Decimal from '@/libraries/Decimal'
50
+ import GraphQLClient from '@/libraries/GraphQLClient'
51
+ import {
52
+ generateBundleHash
53
+ } from '@/libraries/crypto'
54
+ import Molecule from '@/core/Molecule'
55
+ import Wallet from '@/core/Wallet'
56
+ import AuthToken from '@/AuthToken'
57
+ import Query from '@/query/Query'
58
+ import Mutation from '@/mutation/Mutation'
59
+ import Response from '@/response/Response'
60
+
61
+ // 2025 TypeScript: Zod validation integration
62
+ import {
63
+ validateClientConfig,
64
+ validateTransferParams,
65
+ type ValidationResult
66
+ } from '@/validation/ValidationService'
67
+
68
+ // Enhanced configuration validation (Phase 2)
69
+ import { ConfigValidator } from '@/validation/UNIVERSAL_CONFIGURATION_INTERFACES'
70
+
71
+ // Query imports
72
+ import QueryBalance from '@/query/QueryBalance'
73
+ import QueryWalletList from '@/query/QueryWalletList'
74
+ import QueryWalletBundle from '@/query/QueryWalletBundle'
75
+ import QueryContinuId from '@/query/QueryContinuId'
76
+ // QueryMeta is not needed - using QueryMetaType instead
77
+ import QueryMetaType from '@/query/QueryMetaType'
78
+ import QueryBatch from '@/query/QueryBatch'
79
+ import QueryBatchHistory from '@/query/QueryBatchHistory'
80
+ import QueryAtom from '@/query/QueryAtom'
81
+ import QueryPolicy from '@/query/QueryPolicy'
82
+ import QueryActiveSession from '@/query/QueryActiveSession'
83
+ import QueryUserActivity from '@/query/QueryUserActivity'
84
+ import QueryToken from '@/query/QueryToken'
85
+ import QueryMetaTypeViaAtom from '@/query/QueryMetaTypeViaAtom'
86
+
87
+ // Mutation imports
88
+ import MutationCreateToken from '@/mutation/MutationCreateToken'
89
+ import MutationRequestTokens from '@/mutation/MutationRequestTokens'
90
+ import MutationTransferTokens from '@/mutation/MutationTransferTokens'
91
+ import MutationCreateWallet from '@/mutation/MutationCreateWallet'
92
+ import MutationClaimShadowWallet from '@/mutation/MutationClaimShadowWallet'
93
+ import MutationCreateMeta from '@/mutation/MutationCreateMeta'
94
+ import MutationCreateRule from '@/mutation/MutationCreateRule'
95
+ import MutationCreateIdentifier from '@/mutation/MutationCreateIdentifier'
96
+ import MutationActiveSession from '@/mutation/MutationActiveSession'
97
+ import MutationDepositBufferToken from '@/mutation/MutationDepositBufferToken'
98
+ import MutationWithdrawBufferToken from '@/mutation/MutationWithdrawBufferToken'
99
+ import MutationRequestAuthorization from '@/mutation/MutationRequestAuthorization'
100
+ import MutationRequestAuthorizationGuest from '@/mutation/MutationRequestAuthorizationGuest'
101
+ import MutationLinkIdentifier from '@/mutation/MutationLinkIdentifier'
102
+
103
+ // Subscribe imports
104
+ import CreateMoleculeSubscribe from '@/subscribe/CreateMoleculeSubscribe'
105
+ import WalletStatusSubscribe from '@/subscribe/WalletStatusSubscribe'
106
+ import ActiveWalletSubscribe from '@/subscribe/ActiveWalletSubscribe'
107
+ import ActiveSessionSubscribe from '@/subscribe/ActiveSessionSubscribe'
108
+
109
+ // Exception imports
110
+ import {
111
+ CodeException,
112
+ UnauthenticatedException,
113
+ TransferBalanceException,
114
+ WalletShadowException
115
+ } from '@/exception'
116
+
117
+ // Type imports
118
+ import type {
119
+ WalletAddress,
120
+ BundleHash,
121
+ TokenSlug,
122
+ CellSlug,
123
+ MetaType,
124
+ MetaId,
125
+ BatchId
126
+ } from '@/types'
127
+
128
+ /**
129
+ * Base client class providing a powerful but user-friendly wrapper
130
+ * around complex Knish.IO ledger transactions.
131
+ */
132
+ export default class KnishIOClient {
133
+ private $__secret: string = ''
134
+ private $__bundle: string = ''
135
+ private $__cellSlug: string | null = null
136
+ private $__encrypt: boolean = false
137
+ private $__uris: string[] = []
138
+ private $__client: GraphQLClient
139
+ private $__serverSdkVersion: number = 3
140
+ private $__logging: boolean = false
141
+ private $__authTokenObjects: Record<string, AuthToken | null> = {}
142
+ private $__authToken: AuthToken | null = null
143
+ private $__remainderWallet: Wallet | null = null
144
+ private lastMoleculeQuery: Mutation | null = null
145
+ private abortControllers: Map<string, AbortController> = new Map()
146
+
147
+ /**
148
+ * Enhanced constructor with standardized configuration validation (Phase 2 Enhancement)
149
+ */
150
+ constructor(config: {
151
+ uri: string | string[]
152
+ cellSlug?: string | null
153
+ client?: GraphQLClient | null
154
+ socket?: { socketUri: string | null; appKey?: string } | null
155
+ serverSdkVersion?: number
156
+ logging?: boolean
157
+ }) {
158
+ // Phase 2 Enhancement: Use standardized configuration validation
159
+ const standardValidationResult = ConfigValidator.validateClientConfig(config)
160
+
161
+ if (!standardValidationResult.isValid) {
162
+ const errorDetails = standardValidationResult.errors.join(', ')
163
+ throw new Error(`Invalid KnishIOClient configuration: ${errorDetails}`)
164
+ }
165
+
166
+ // Enhanced validation with warnings (Phase 2 improvement)
167
+ if (standardValidationResult.warnings.length > 0 && config.logging) {
168
+ console.warn('KnishIOClient Configuration Warnings:', standardValidationResult.warnings)
169
+ }
170
+
171
+ // Legacy validation for backward compatibility
172
+ const legacyValidationResult = validateClientConfig(config)
173
+
174
+ if (!legacyValidationResult.success) {
175
+ const errorDetails = legacyValidationResult.error.details
176
+ ?.map(issue => `${issue.path.join('.')}: ${issue.message}`)
177
+ .join(', ') || legacyValidationResult.error.message
178
+
179
+ throw new Error(`KnishIOClient configuration validation failed: ${errorDetails}`)
180
+ }
181
+
182
+ // Use enhanced configuration with backward compatibility
183
+ const validatedConfig = legacyValidationResult.data
184
+
185
+ // Extract validated values (maintaining existing pattern)
186
+ const {
187
+ uri,
188
+ cellSlug = null,
189
+ client = null,
190
+ socket = null,
191
+ serverSdkVersion = 3,
192
+ logging = false
193
+ } = validatedConfig
194
+
195
+ this.initialize({
196
+ uri,
197
+ cellSlug,
198
+ socket,
199
+ client,
200
+ serverSdkVersion,
201
+ logging
202
+ })
203
+ }
204
+
205
+ /**
206
+ * Initializes a new Knish.IO client session
207
+ */
208
+ initialize({
209
+ uri,
210
+ cellSlug = null,
211
+ socket = null,
212
+ client = null,
213
+ serverSdkVersion = 3,
214
+ logging = false
215
+ }: {
216
+ uri: string | string[]
217
+ cellSlug?: string | null
218
+ socket?: { socketUri: string | null; appKey?: string } | null
219
+ client?: GraphQLClient | null
220
+ serverSdkVersion?: number
221
+ logging?: boolean
222
+ }): void {
223
+ this.reset()
224
+
225
+ this.$__logging = logging
226
+ this.$__authTokenObjects = {}
227
+
228
+ this.setUri(uri)
229
+
230
+ if (cellSlug) {
231
+ this.setCellSlug(cellSlug)
232
+ }
233
+
234
+ for (const url of this.$__uris) {
235
+ this.$__authTokenObjects[url] = null
236
+ }
237
+
238
+ this.log('info', `KnishIOClient::initialize() - Initializing new Knish.IO client session for SDK version ${serverSdkVersion}...`)
239
+
240
+ this.$__client = client || new GraphQLClient({
241
+ socket: {
242
+ socketUri: socket?.socketUri || null,
243
+ appKey: socket?.appKey || 'knishio'
244
+ },
245
+ serverUri: this.getRandomUri(),
246
+ encrypt: this.$__encrypt
247
+ })
248
+
249
+ this.$__serverSdkVersion = serverSdkVersion
250
+ }
251
+
252
+ /**
253
+ * Get random uri from specified this.$__uris
254
+ */
255
+ getRandomUri(): string {
256
+ const rand = Math.floor(Math.random() * this.$__uris.length)
257
+ return this.$__uris[rand]
258
+ }
259
+
260
+ /**
261
+ * Switch encryption on/off
262
+ */
263
+ switchEncryption(encrypt: boolean): boolean {
264
+ if (this.$__encrypt === encrypt) {
265
+ return false
266
+ }
267
+ this.log('info', `KnishIOClient::switchEncryption() - Forcing encryption ${encrypt ? 'on' : 'off'} to match node...`)
268
+
269
+ // Set encryption
270
+ this.$__encrypt = encrypt
271
+ if ('setEncryption' in this.$__client) {
272
+ (this.$__client as any).setEncryption(encrypt)
273
+ }
274
+ return true
275
+ }
276
+
277
+ /**
278
+ * De-initializes the Knish.IO client session so that a new session can replace it
279
+ */
280
+ deinitialize(): void {
281
+ this.log('info', 'KnishIOClient::deinitialize() - Clearing the Knish.IO client session...')
282
+ this.reset()
283
+ }
284
+
285
+ /**
286
+ * Subscribes the client to the node's broadcast socket
287
+ */
288
+ subscribe(): GraphQLClient {
289
+ if (!('getSocketUri' in this.$__client) || !(this.$__client as any).getSocketUri()) {
290
+ throw new CodeException('KnishIOClient::subscribe() - Socket client not initialized!')
291
+ }
292
+ return this.client()
293
+ }
294
+
295
+ /**
296
+ * Gets the client's SDK version
297
+ */
298
+ getServerSdkVersion(): number {
299
+ return this.$__serverSdkVersion
300
+ }
301
+
302
+ /**
303
+ * Reset common properties
304
+ */
305
+ reset(): void {
306
+ this.$__secret = ''
307
+ this.$__bundle = ''
308
+ this.$__encrypt = false
309
+ this.$__cellSlug = null
310
+ this.$__authToken = null
311
+ this.$__remainderWallet = null
312
+ this.lastMoleculeQuery = null
313
+ }
314
+
315
+ /**
316
+ * Get the GraphQL client
317
+ */
318
+ client(): GraphQLClient {
319
+ return this.$__client
320
+ }
321
+
322
+ /**
323
+ * Sets the Knish.IO server URIs
324
+ */
325
+ setUri(uri: string | string[]): void {
326
+ if (typeof uri === 'string') {
327
+ this.$__uris = [uri]
328
+ } else {
329
+ this.$__uris = uri
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Gets the Knish.IO server URIs
335
+ */
336
+ getUri(): string[] {
337
+ return this.$__uris
338
+ }
339
+
340
+ /**
341
+ * Sets the Cell slug
342
+ */
343
+ setCellSlug(cellSlug: string | null): void {
344
+ this.$__cellSlug = cellSlug
345
+ }
346
+
347
+ /**
348
+ * Gets the Cell slug
349
+ */
350
+ getCellSlug(): string | null {
351
+ return this.$__cellSlug
352
+ }
353
+
354
+ /**
355
+ * Returns whether a secret is stored for this session
356
+ */
357
+ hasSecret(): boolean {
358
+ return !!this.$__secret && this.$__secret.length > 0
359
+ }
360
+
361
+ /**
362
+ * Returns the stored secret
363
+ */
364
+ getSecret(): string {
365
+ if (!this.hasSecret()) {
366
+ throw new UnauthenticatedException('KnishIOClient::getSecret() - Unable to find a stored secret! Have you set a secret?')
367
+ }
368
+ return this.$__secret
369
+ }
370
+
371
+ /**
372
+ * Returns whether a bundle hash is being stored for this session
373
+ */
374
+ hasBundle(): boolean {
375
+ return !!this.$__bundle && this.$__bundle.length > 0
376
+ }
377
+
378
+ /**
379
+ * Returns the stored bundle hash
380
+ */
381
+ getBundle(): string {
382
+ if (!this.hasBundle()) {
383
+ throw new UnauthenticatedException('KnishIOClient::getBundle() - Unable to find a stored bundle! Have you set a secret?')
384
+ }
385
+ return this.$__bundle
386
+ }
387
+
388
+ /**
389
+ * Sets the remainder wallet for this session
390
+ */
391
+ setRemainderWallet(remainderWallet: Wallet): void {
392
+ this.$__remainderWallet = remainderWallet
393
+ }
394
+
395
+ /**
396
+ * Gets the remainder wallet for this session
397
+ */
398
+ getRemainderWallet(): Wallet | null {
399
+ return this.$__remainderWallet
400
+ }
401
+
402
+ /**
403
+ * Creates a new molecule for a transaction
404
+ */
405
+ async createMolecule({
406
+ secret = null,
407
+ bundle = null,
408
+ sourceWallet = null,
409
+ remainderWallet = null
410
+ }: {
411
+ secret?: string | null
412
+ bundle?: string | null
413
+ sourceWallet?: Wallet | null
414
+ remainderWallet?: Wallet | null
415
+ } = {}): Promise<Molecule> {
416
+ this.log('info', 'KnishIOClient::createMolecule() - Creating a new molecule...')
417
+
418
+ secret = secret || this.getSecret()
419
+ bundle = bundle || this.getBundle()
420
+
421
+ // Sets the source wallet as the last remainder wallet (to maintain ContinuID)
422
+ if (!sourceWallet &&
423
+ this.lastMoleculeQuery &&
424
+ this.getRemainderWallet()?.token === 'USER' &&
425
+ this.lastMoleculeQuery.response() &&
426
+ this.lastMoleculeQuery.response()?.success()
427
+ ) {
428
+ sourceWallet = this.getRemainderWallet()
429
+ }
430
+
431
+ // Unable to use last remainder wallet; Figure out what wallet to use:
432
+ if (!sourceWallet) {
433
+ // Get source wallet
434
+ sourceWallet = await this.getSourceWallet()
435
+ }
436
+
437
+ return new Molecule({
438
+ secret,
439
+ bundle,
440
+ sourceWallet,
441
+ remainderWallet
442
+ })
443
+ }
444
+
445
+ /**
446
+ * Creates a new molecule mutation
447
+ */
448
+ async createMoleculeMutation({
449
+ mutationClass,
450
+ molecule = null
451
+ }: {
452
+ mutationClass: typeof Mutation
453
+ molecule?: Molecule | null
454
+ }): Promise<Mutation> {
455
+ this.log('info', `KnishIOClient::createMoleculeMutation() - Creating a new ${mutationClass.name} query...`)
456
+
457
+ // If you don't supply the molecule, we'll generate one for you
458
+ const _molecule = molecule || await this.createMolecule({})
459
+
460
+ const mutation = new mutationClass(this.client(), this) as Mutation
461
+
462
+ if (!(mutation instanceof Mutation)) {
463
+ throw new CodeException(`${this.constructor.name}::createMoleculeMutation() - This method only accepts Mutation subclasses!`)
464
+ }
465
+
466
+ this.lastMoleculeQuery = mutation
467
+
468
+ return mutation
469
+ }
470
+
471
+ /**
472
+ * Executes a query or mutation
473
+ */
474
+ async executeQuery(query: Query | Mutation, variables: Record<string, any> | null = null): Promise<Response | null> {
475
+ // Check and refresh authorization token if needed
476
+ if (this.$__authToken && this.$__authToken.isExpired()) {
477
+ this.log('info', 'KnishIOClient::executeQuery() - Access token is expired. Getting new one...')
478
+ await this.requestAuthToken({
479
+ secret: this.$__secret,
480
+ cellSlug: this.$__cellSlug,
481
+ encrypt: this.$__encrypt
482
+ })
483
+ }
484
+
485
+ // Execute the query
486
+ return await query.execute({ variables: variables || {} })
487
+ }
488
+
489
+ /**
490
+ * Sets the secret for this session
491
+ */
492
+ setSecret(secret: string): void {
493
+ this.$__secret = secret
494
+ this.$__bundle = generateBundleHash(secret)
495
+ }
496
+
497
+ /**
498
+ * Sets the auth token for this session
499
+ */
500
+ setAuthToken(authToken: AuthToken): void {
501
+ this.$__authToken = authToken
502
+
503
+ // Set auth data on the client
504
+ if ('setAuthData' in this.$__client) {
505
+ (this.$__client as any).setAuthData(authToken.getAuthData())
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Gets source wallet - basic implementation
511
+ */
512
+ async getSourceWallet(): Promise<Wallet> {
513
+ // For now, create a new wallet with the current secret
514
+ // In full implementation, this would query the ledger
515
+ return Wallet.create({
516
+ secret: this.getSecret(),
517
+ bundle: this.getBundle(),
518
+ token: 'USER'
519
+ })
520
+ }
521
+
522
+ /**
523
+ * Transfer tokens between wallets
524
+ * Enhanced with 2025 TypeScript validation patterns
525
+ */
526
+ async transferToken(params: {
527
+ bundleHash: string
528
+ token: string
529
+ amount?: number | null
530
+ units?: string[]
531
+ batchId?: string | null
532
+ sourceWallet?: Wallet | null
533
+ }): Promise<ValidationResult<Response | null>> {
534
+ // 2025 Pattern: Validate parameters with Zod
535
+ const transferParams = {
536
+ recipient: params.bundleHash,
537
+ amount: params.amount || 0,
538
+ token: params.token
539
+ }
540
+
541
+ const validationResult = validateTransferParams(transferParams)
542
+
543
+ if (!validationResult.success) {
544
+ return {
545
+ success: false,
546
+ error: {
547
+ code: 'VALIDATION_ERROR',
548
+ message: 'Invalid transfer parameters',
549
+ details: validationResult.error.details,
550
+ context: 'transferToken'
551
+ }
552
+ }
553
+ }
554
+
555
+ // Use validated parameters
556
+ const validatedParams = validationResult.data
557
+ let {
558
+ bundleHash,
559
+ token,
560
+ amount = null,
561
+ units = [],
562
+ batchId = null,
563
+ sourceWallet = null
564
+ } = params
565
+ // Calculate amount & set meta key
566
+ if (units.length > 0) {
567
+ // Can't move stackable units AND provide amount
568
+ if (amount && amount > 0) {
569
+ throw new CodeException('Cannot specify both amount and units')
570
+ }
571
+ amount = units.length
572
+ }
573
+
574
+ // Build recipient wallet
575
+ const recipientWallet = Wallet.create({
576
+ bundle: bundleHash,
577
+ token,
578
+ batchId
579
+ })
580
+
581
+ // Get source wallet
582
+ if (!sourceWallet) {
583
+ sourceWallet = await this.getSourceWallet()
584
+ }
585
+
586
+ // Check balance
587
+ if (!sourceWallet.balance || sourceWallet.balance < (amount || 0)) {
588
+ throw new TransferBalanceException()
589
+ }
590
+
591
+ // Create remainder wallet
592
+ const remainderWallet = sourceWallet.createRemainder(this.getSecret())
593
+
594
+ // Build the molecule itself
595
+ const molecule = await this.createMolecule({
596
+ sourceWallet,
597
+ remainderWallet
598
+ })
599
+
600
+ // For now, return a basic implementation
601
+ // Full implementation would create and execute MutationTransferTokens
602
+ return null
603
+ }
604
+
605
+ /**
606
+ * Request authorization token
607
+ */
608
+ async requestAuthToken({
609
+ secret = null,
610
+ seed = null,
611
+ cellSlug = null,
612
+ encrypt = false
613
+ }: {
614
+ secret?: string | null
615
+ seed?: string | null
616
+ cellSlug?: string | null
617
+ encrypt?: boolean
618
+ }): Promise<Response | null> {
619
+ // SDK versions 2 and below do not utilize an authorization token
620
+ if (this.$__serverSdkVersion < 3) {
621
+ this.log('warn', 'KnishIOClient::authorize() - Server SDK version does not require an authorization...')
622
+ return null
623
+ }
624
+
625
+ // For now, return null - full implementation would handle authorization
626
+ return null
627
+ }
628
+
629
+ /**
630
+ * Logging utility
631
+ */
632
+ log(level: 'info' | 'warn' | 'error', message: string): void {
633
+ if (this.$__logging) {
634
+ switch (level) {
635
+ case 'info':
636
+ console.log(`[INFO] ${message}`)
637
+ break
638
+ case 'warn':
639
+ console.warn(`[WARN] ${message}`)
640
+ break
641
+ case 'error':
642
+ console.error(`[ERROR] ${message}`)
643
+ break
644
+ }
645
+ }
646
+ }
647
+
648
+ /**
649
+ * Creates a Query instance
650
+ */
651
+ createQuery<T extends Query>(QueryClass: new (client: GraphQLClient, knishIOClient: KnishIOClient) => T): T {
652
+ return new QueryClass(this.client(), this)
653
+ }
654
+
655
+ /**
656
+ * Creates a Subscribe instance
657
+ */
658
+ createSubscribe<T>(SubscribeClass: new (client: GraphQLClient) => T): T {
659
+ return new SubscribeClass(this.client())
660
+ }
661
+
662
+ /**
663
+ * Helper to hash secret into bundle hash
664
+ */
665
+ hashSecret(secret: string, source: string | null = null): string {
666
+ const bundleHash = generateBundleHash(secret, source)
667
+ this.$__bundle = bundleHash
668
+ return bundleHash
669
+ }
670
+
671
+ /**
672
+ * Get current auth token
673
+ */
674
+ getAuthToken(): AuthToken | null {
675
+ return this.$__authToken
676
+ }
677
+
678
+ /**
679
+ * Cancel a specific query
680
+ */
681
+ cancelQuery(query: Query | Mutation, variables: Record<string, any> | null = null): void {
682
+ const queryKey = `${query.constructor.name}_${JSON.stringify(variables || {})}`
683
+ const controller = this.abortControllers.get(queryKey)
684
+
685
+ if (controller) {
686
+ controller.abort()
687
+ this.abortControllers.delete(queryKey)
688
+ }
689
+ }
690
+
691
+ /**
692
+ * Cancel all pending queries
693
+ */
694
+ cancelAllQueries(): void {
695
+ for (const controller of this.abortControllers.values()) {
696
+ controller.abort()
697
+ }
698
+ this.abortControllers.clear()
699
+ }
700
+
701
+ // =============================================================================
702
+ // QUERY METHODS
703
+ // =============================================================================
704
+
705
+ /**
706
+ * Query wallet balance for a specific token
707
+ */
708
+ async queryBalance({
709
+ token,
710
+ bundle = null,
711
+ type = 'regular'
712
+ }: {
713
+ token: TokenSlug | string
714
+ bundle?: BundleHash | string | null
715
+ type?: 'regular' | 'stackable'
716
+ }): Promise<Response> {
717
+ const query = this.createQuery(QueryBalance)
718
+
719
+ return this.executeQuery(query, {
720
+ bundleHash: bundle || this.getBundle(),
721
+ token,
722
+ type
723
+ }) as Promise<Response>
724
+ }
725
+
726
+ /**
727
+ * Get source wallet with sufficient balance for a transaction
728
+ */
729
+ async querySourceWallet({
730
+ token,
731
+ amount,
732
+ type = 'regular'
733
+ }: {
734
+ token: TokenSlug | string
735
+ amount: number | string
736
+ type?: 'regular' | 'stackable'
737
+ }): Promise<Wallet> {
738
+ const response = await this.queryBalance({
739
+ token,
740
+ type
741
+ })
742
+
743
+ const sourceWallet = response.payload() as Wallet | null
744
+
745
+ // Do you have enough tokens?
746
+ if (sourceWallet === null || Decimal.cmp(sourceWallet.balance || 0, amount) < 0) {
747
+ throw new TransferBalanceException()
748
+ }
749
+
750
+ // Check shadow wallet
751
+ if (!sourceWallet.position || !sourceWallet.address) {
752
+ throw new TransferBalanceException('Source wallet cannot be a shadow wallet.')
753
+ }
754
+
755
+ return sourceWallet
756
+ }
757
+
758
+ /**
759
+ * Query wallet list
760
+ */
761
+ async queryWallets({
762
+ bundle = null,
763
+ token = null,
764
+ unspent = true
765
+ }: {
766
+ bundle?: BundleHash | string | null
767
+ token?: TokenSlug | string | null
768
+ unspent?: boolean
769
+ } = {}): Promise<Wallet[]> {
770
+ this.log('info', `KnishIOClient::queryWallets() - Querying wallets${bundle ? ` for ${bundle}` : ''}...`)
771
+
772
+ const walletQuery = this.createQuery(QueryWalletList)
773
+
774
+ const response = await this.executeQuery(walletQuery, {
775
+ bundleHash: bundle || this.getBundle(),
776
+ tokenSlug: token,
777
+ unspent
778
+ })
779
+
780
+ return response?.payload() || []
781
+ }
782
+
783
+ /**
784
+ * Query wallet bundle metadata
785
+ */
786
+ async queryBundle({
787
+ bundle = null,
788
+ fields = null,
789
+ raw = false
790
+ }: {
791
+ bundle?: BundleHash | string | string[] | null
792
+ fields?: string[] | null
793
+ raw?: boolean
794
+ } = {}): Promise<any> {
795
+ this.log('info', `KnishIOClient::queryBundle() - Querying wallet bundle metadata${bundle ? ` for ${bundle}` : ''}...`)
796
+
797
+ // Bundle default init & to array conversion
798
+ if (!bundle) {
799
+ bundle = this.getBundle()
800
+ }
801
+ if (typeof bundle === 'string') {
802
+ bundle = [bundle]
803
+ }
804
+
805
+ const query = this.createQuery(QueryWalletBundle)
806
+ const response = await this.executeQuery(query, { bundleHashes: bundle })
807
+
808
+ return raw ? response : response?.payload()
809
+ }
810
+
811
+ /**
812
+ * Query next ContinuId wallet
813
+ */
814
+ async queryContinuId({
815
+ bundle
816
+ }: {
817
+ bundle: BundleHash | string
818
+ }): Promise<Response> {
819
+ const query = this.createQuery(QueryContinuId)
820
+
821
+ return this.executeQuery(query, {
822
+ bundle
823
+ }) as Promise<Response>
824
+ }
825
+
826
+ /**
827
+ * Query metadata
828
+ */
829
+ async queryMeta({
830
+ metaType,
831
+ metaId = null,
832
+ key = null,
833
+ value = null,
834
+ latest = null,
835
+ fields = null,
836
+ filter = null,
837
+ queryArgs = null,
838
+ count = null,
839
+ countBy = null,
840
+ throughAtom = null,
841
+ values = null,
842
+ keys = null,
843
+ atomValues = null
844
+ }: {
845
+ metaType: MetaType | string
846
+ metaId?: MetaId | string | null
847
+ key?: string | null
848
+ value?: string | null
849
+ latest?: boolean | null
850
+ fields?: string[] | null
851
+ filter?: string | null
852
+ queryArgs?: Record<string, any> | null
853
+ count?: number | null
854
+ countBy?: string | null
855
+ throughAtom?: boolean | null
856
+ values?: any[] | null
857
+ keys?: string[] | null
858
+ atomValues?: any[] | null
859
+ }): Promise<Response> {
860
+ this.log('info', `KnishIOClient::queryMeta() - Querying metaType: ${metaType}, metaId: ${metaId}...`)
861
+
862
+ let query: Query
863
+
864
+ if (throughAtom === true) {
865
+ query = this.createQuery(QueryMetaTypeViaAtom)
866
+ } else {
867
+ query = this.createQuery(QueryMetaType)
868
+ }
869
+
870
+ const variables: Record<string, any> = {
871
+ metaType: metaType.toUpperCase(),
872
+ metaId
873
+ }
874
+
875
+ if (filter !== null) {
876
+ variables.filter = filter
877
+ }
878
+ if (latest !== null) {
879
+ variables.latest = latest
880
+ }
881
+ if (key !== null) {
882
+ variables.key = key
883
+ }
884
+ if (value !== null) {
885
+ variables.value = value
886
+ }
887
+ if (queryArgs !== null) {
888
+ variables.queryArgs = queryArgs
889
+ }
890
+ if (count !== null) {
891
+ variables.count = count
892
+ }
893
+ if (countBy !== null) {
894
+ variables.countBy = countBy
895
+ }
896
+ if (values !== null) {
897
+ variables.values = values
898
+ }
899
+ if (keys !== null) {
900
+ variables.keys = keys
901
+ }
902
+ if (atomValues !== null) {
903
+ variables.atomValues = atomValues
904
+ }
905
+
906
+ return this.executeQuery(query, variables) as Promise<Response>
907
+ }
908
+
909
+ /**
910
+ * Query cascading meta instances for batchId
911
+ */
912
+ async queryBatch({
913
+ batchId
914
+ }: {
915
+ batchId: BatchId | string
916
+ }): Promise<Response> {
917
+ this.log('info', `KnishIOClient::queryBatch() - Querying cascading meta instances for batchId: ${batchId}...`)
918
+
919
+ const query = this.createQuery(QueryBatch)
920
+
921
+ return this.executeQuery(query, {
922
+ batchId
923
+ }) as Promise<Response>
924
+ }
925
+
926
+ /**
927
+ * Query batch history
928
+ */
929
+ async queryBatchHistory({
930
+ batchId
931
+ }: {
932
+ batchId: BatchId | string
933
+ }): Promise<Response> {
934
+ this.log('info', `KnishIOClient::queryBatchHistory() - Querying cascading meta instances for batchId: ${batchId}...`)
935
+
936
+ const query = this.createQuery(QueryBatchHistory)
937
+
938
+ return this.executeQuery(query, {
939
+ batchId
940
+ }) as Promise<Response>
941
+ }
942
+
943
+ /**
944
+ * Query atoms with comprehensive filters
945
+ */
946
+ async queryAtom({
947
+ molecularHashes = null,
948
+ molecularHash = null,
949
+ bundleHashes = null,
950
+ bundleHash = null,
951
+ positions = null,
952
+ position = null,
953
+ walletAddresses = null,
954
+ walletAddress = null,
955
+ isotopes = null,
956
+ isotope = null,
957
+ tokenSlugs = null,
958
+ tokenSlug = null,
959
+ cellSlugs = null,
960
+ cellSlug = null,
961
+ batchIds = null,
962
+ batchId = null,
963
+ values = null,
964
+ value = null,
965
+ metaTypes = null,
966
+ metaType = null,
967
+ metaIds = null,
968
+ metaId = null,
969
+ indexes = null,
970
+ index = null,
971
+ filter = null,
972
+ latest = null,
973
+ queryArgs = null
974
+ }: {
975
+ molecularHashes?: string[] | null
976
+ molecularHash?: string | null
977
+ bundleHashes?: string[] | null
978
+ bundleHash?: string | null
979
+ positions?: string[] | null
980
+ position?: string | null
981
+ walletAddresses?: string[] | null
982
+ walletAddress?: string | null
983
+ isotopes?: string[] | null
984
+ isotope?: string | null
985
+ tokenSlugs?: string[] | null
986
+ tokenSlug?: string | null
987
+ cellSlugs?: string[] | null
988
+ cellSlug?: string | null
989
+ batchIds?: string[] | null
990
+ batchId?: string | null
991
+ values?: any[] | null
992
+ value?: any | null
993
+ metaTypes?: string[] | null
994
+ metaType?: string | null
995
+ metaIds?: string[] | null
996
+ metaId?: string | null
997
+ indexes?: number[] | null
998
+ index?: number | null
999
+ filter?: string | null
1000
+ latest?: boolean | null
1001
+ queryArgs?: Record<string, any> | null
1002
+ } = {}): Promise<Response> {
1003
+ const query = this.createQuery(QueryAtom)
1004
+
1005
+ const variables: Record<string, any> = {}
1006
+
1007
+ // Add all non-null parameters to variables
1008
+ if (molecularHashes !== null) variables.molecularHashes = molecularHashes
1009
+ if (molecularHash !== null) variables.molecularHash = molecularHash
1010
+ if (bundleHashes !== null) variables.bundleHashes = bundleHashes
1011
+ if (bundleHash !== null) variables.bundleHash = bundleHash
1012
+ if (positions !== null) variables.positions = positions
1013
+ if (position !== null) variables.position = position
1014
+ if (walletAddresses !== null) variables.walletAddresses = walletAddresses
1015
+ if (walletAddress !== null) variables.walletAddress = walletAddress
1016
+ if (isotopes !== null) variables.isotopes = isotopes
1017
+ if (isotope !== null) variables.isotope = isotope
1018
+ if (tokenSlugs !== null) variables.tokenSlugs = tokenSlugs
1019
+ if (tokenSlug !== null) variables.tokenSlug = tokenSlug
1020
+ if (cellSlugs !== null) variables.cellSlugs = cellSlugs
1021
+ if (cellSlug !== null) variables.cellSlug = cellSlug
1022
+ if (batchIds !== null) variables.batchIds = batchIds
1023
+ if (batchId !== null) variables.batchId = batchId
1024
+ if (values !== null) variables.values = values
1025
+ if (value !== null) variables.value = value
1026
+ if (metaTypes !== null) variables.metaTypes = metaTypes
1027
+ if (metaType !== null) variables.metaType = metaType
1028
+ if (metaIds !== null) variables.metaIds = metaIds
1029
+ if (metaId !== null) variables.metaId = metaId
1030
+ if (indexes !== null) variables.indexes = indexes
1031
+ if (index !== null) variables.index = index
1032
+ if (filter !== null) variables.filter = filter
1033
+ if (latest !== null) variables.latest = latest
1034
+ if (queryArgs !== null) variables.queryArgs = queryArgs
1035
+
1036
+ return this.executeQuery(query, variables) as Promise<Response>
1037
+ }
1038
+
1039
+ /**
1040
+ * Query policy
1041
+ */
1042
+ async queryPolicy({
1043
+ metaType,
1044
+ metaId
1045
+ }: {
1046
+ metaType: MetaType | string
1047
+ metaId: MetaId | string
1048
+ }): Promise<Response> {
1049
+ const query = this.createQuery(QueryPolicy)
1050
+
1051
+ return this.executeQuery(query, {
1052
+ metaType,
1053
+ metaId
1054
+ }) as Promise<Response>
1055
+ }
1056
+
1057
+ /**
1058
+ * Query active sessions
1059
+ */
1060
+ async queryActiveSession({
1061
+ bundleHash,
1062
+ metaType,
1063
+ metaId
1064
+ }: {
1065
+ bundleHash: BundleHash | string
1066
+ metaType: MetaType | string
1067
+ metaId: MetaId | string
1068
+ }): Promise<Response> {
1069
+ const query = this.createQuery(QueryActiveSession)
1070
+
1071
+ return this.executeQuery(query, {
1072
+ bundleHash,
1073
+ metaType,
1074
+ metaId
1075
+ }) as Promise<Response>
1076
+ }
1077
+
1078
+ /**
1079
+ * Query user activity
1080
+ */
1081
+ async queryUserActivity({
1082
+ bundleHash,
1083
+ metaType,
1084
+ metaId,
1085
+ ipAddress = null,
1086
+ browser = null,
1087
+ osCpu = null,
1088
+ resolution = null,
1089
+ timeZone = null,
1090
+ countBy = null,
1091
+ interval = null
1092
+ }: {
1093
+ bundleHash: BundleHash | string
1094
+ metaType: MetaType | string
1095
+ metaId: MetaId | string
1096
+ ipAddress?: string | null
1097
+ browser?: string | null
1098
+ osCpu?: string | null
1099
+ resolution?: string | null
1100
+ timeZone?: string | null
1101
+ countBy?: string | null
1102
+ interval?: string | null
1103
+ }): Promise<Response> {
1104
+ const query = this.createQuery(QueryUserActivity)
1105
+
1106
+ const variables: Record<string, any> = {
1107
+ bundleHash,
1108
+ metaType,
1109
+ metaId
1110
+ }
1111
+
1112
+ if (ipAddress !== null) variables.ipAddress = ipAddress
1113
+ if (browser !== null) variables.browser = browser
1114
+ if (osCpu !== null) variables.osCpu = osCpu
1115
+ if (resolution !== null) variables.resolution = resolution
1116
+ if (timeZone !== null) variables.timeZone = timeZone
1117
+ if (countBy !== null) variables.countBy = countBy
1118
+ if (interval !== null) variables.interval = interval
1119
+
1120
+ return this.executeQuery(query, variables) as Promise<Response>
1121
+ }
1122
+
1123
+ /**
1124
+ * Query token information
1125
+ */
1126
+ async queryToken({
1127
+ token
1128
+ }: {
1129
+ token: TokenSlug | string
1130
+ }): Promise<Response> {
1131
+ const query = this.createQuery(QueryToken)
1132
+
1133
+ return this.executeQuery(query, {
1134
+ token
1135
+ }) as Promise<Response>
1136
+ }
1137
+
1138
+ // =============================================================================
1139
+ // SUBSCRIPTION METHODS
1140
+ // =============================================================================
1141
+
1142
+ /**
1143
+ * Subscribe to molecule creation events
1144
+ */
1145
+ async subscribeCreateMolecule({
1146
+ bundle,
1147
+ closure
1148
+ }: {
1149
+ bundle: BundleHash | string | null
1150
+ closure: (result: any) => void
1151
+ }): Promise<string> {
1152
+ const subscribe = this.createSubscribe(CreateMoleculeSubscribe)
1153
+
1154
+ return await subscribe.execute({
1155
+ variables: {
1156
+ bundle: bundle || this.getBundle()
1157
+ },
1158
+ closure
1159
+ })
1160
+ }
1161
+
1162
+ /**
1163
+ * Subscribe to wallet status updates
1164
+ */
1165
+ async subscribeWalletStatus({
1166
+ bundle,
1167
+ token,
1168
+ closure
1169
+ }: {
1170
+ bundle: BundleHash | string | null
1171
+ token: TokenSlug | string
1172
+ closure: (result: any) => void
1173
+ }): Promise<string> {
1174
+ if (!token) {
1175
+ throw new CodeException(`${this.constructor.name}::subscribeWalletStatus() - Token parameter is required!`)
1176
+ }
1177
+
1178
+ const subscribe = this.createSubscribe(WalletStatusSubscribe)
1179
+
1180
+ return await subscribe.execute({
1181
+ variables: {
1182
+ bundle: bundle || this.getBundle(),
1183
+ token
1184
+ },
1185
+ closure
1186
+ })
1187
+ }
1188
+
1189
+ /**
1190
+ * Subscribe to active wallet updates
1191
+ */
1192
+ async subscribeActiveWallet({
1193
+ bundle,
1194
+ closure
1195
+ }: {
1196
+ bundle: BundleHash | string | null
1197
+ closure: (result: any) => void
1198
+ }): Promise<string> {
1199
+ const subscribe = this.createSubscribe(ActiveWalletSubscribe)
1200
+
1201
+ return await subscribe.execute({
1202
+ variables: {
1203
+ bundle: bundle || this.getBundle()
1204
+ },
1205
+ closure
1206
+ })
1207
+ }
1208
+
1209
+ /**
1210
+ * Subscribe to active session updates
1211
+ */
1212
+ async subscribeActiveSession({
1213
+ metaType,
1214
+ metaId,
1215
+ closure
1216
+ }: {
1217
+ metaType: MetaType | string
1218
+ metaId: MetaId | string
1219
+ closure: (result: any) => void
1220
+ }): Promise<string> {
1221
+ const subscribe = this.createSubscribe(ActiveSessionSubscribe)
1222
+
1223
+ return await subscribe.execute({
1224
+ variables: {
1225
+ metaType,
1226
+ metaId
1227
+ },
1228
+ closure
1229
+ })
1230
+ }
1231
+
1232
+ /**
1233
+ * Unsubscribe from a specific subscription
1234
+ */
1235
+ unsubscribe(operationName: string): void {
1236
+ if ('unsubscribe' in this.$__client) {
1237
+ (this.$__client as any).unsubscribe(operationName)
1238
+ }
1239
+ }
1240
+
1241
+ /**
1242
+ * Unsubscribe from all subscriptions
1243
+ */
1244
+ unsubscribeAll(): void {
1245
+ if ('unsubscribeAll' in this.$__client) {
1246
+ (this.$__client as any).unsubscribeAll()
1247
+ }
1248
+ }
1249
+
1250
+ // =============================================================================
1251
+ // MUTATION METHODS - TOKEN OPERATIONS
1252
+ // =============================================================================
1253
+
1254
+ /**
1255
+ * Create a new token
1256
+ */
1257
+ async createToken({
1258
+ token,
1259
+ amount = null,
1260
+ meta = null,
1261
+ batchId = null,
1262
+ units = null
1263
+ }: {
1264
+ token: TokenSlug | string
1265
+ amount?: number | string | null
1266
+ meta?: Record<string, any> | null
1267
+ batchId?: BatchId | string | null
1268
+ units?: string[] | null
1269
+ }): Promise<Response> {
1270
+ this.log('info', `KnishIOClient::createToken() - Creating token ${token}...`)
1271
+
1272
+ const mutation = this.createQuery(MutationCreateToken) as MutationCreateToken
1273
+
1274
+ // Get source wallet
1275
+ const sourceWallet = await this.getSourceWallet()
1276
+
1277
+ // Initialize the create token mutation
1278
+ await mutation.fillMolecule({
1279
+ sourceWallet,
1280
+ token: token.toUpperCase(),
1281
+ amount,
1282
+ meta,
1283
+ batchId,
1284
+ units
1285
+ })
1286
+
1287
+ // Create the molecule mutation
1288
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1289
+
1290
+ // Execute the mutation
1291
+ const response = await this.executeQuery(moleculeMutation)
1292
+
1293
+ if (!response) {
1294
+ throw new CodeException('Token creation failed')
1295
+ }
1296
+
1297
+ return response
1298
+ }
1299
+
1300
+ /**
1301
+ * Request tokens for recipient
1302
+ */
1303
+ async requestTokens({
1304
+ token,
1305
+ to = null,
1306
+ amount = null,
1307
+ units = null,
1308
+ meta = null,
1309
+ batchId = null
1310
+ }: {
1311
+ token: TokenSlug | string
1312
+ to?: WalletAddress | string | null
1313
+ amount?: number | string | null
1314
+ units?: string[] | null
1315
+ meta?: Record<string, any> | null
1316
+ batchId?: BatchId | string | null
1317
+ }): Promise<Response> {
1318
+ this.log('info', `KnishIOClient::requestTokens() - Requesting ${amount || 'units'} of ${token}...`)
1319
+
1320
+ const mutation = this.createQuery(MutationRequestTokens) as MutationRequestTokens
1321
+
1322
+ // Get source wallet if needed
1323
+ const sourceWallet = await this.getSourceWallet()
1324
+
1325
+ // Initialize the request tokens mutation
1326
+ await mutation.fillMolecule({
1327
+ sourceWallet,
1328
+ token: token.toUpperCase(),
1329
+ to,
1330
+ amount,
1331
+ units,
1332
+ meta,
1333
+ batchId
1334
+ })
1335
+
1336
+ // Create the molecule mutation
1337
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1338
+
1339
+ // Execute the mutation
1340
+ const response = await this.executeQuery(moleculeMutation)
1341
+
1342
+ if (!response) {
1343
+ throw new CodeException('Token request failed')
1344
+ }
1345
+
1346
+ return response
1347
+ }
1348
+
1349
+ /**
1350
+ * Burn/destroy tokens
1351
+ */
1352
+ async burnTokens({
1353
+ token,
1354
+ amount = null,
1355
+ units = null,
1356
+ sourceWallet = null
1357
+ }: {
1358
+ token: TokenSlug | string
1359
+ amount?: number | string | null
1360
+ units?: string[] | null
1361
+ sourceWallet?: Wallet | null
1362
+ }): Promise<Response> {
1363
+ this.log('info', `KnishIOClient::burnTokens() - Burning ${amount || 'units'} of ${token}...`)
1364
+
1365
+ // Get source wallet if not provided
1366
+ if (!sourceWallet) {
1367
+ sourceWallet = await this.querySourceWallet({
1368
+ token,
1369
+ amount: amount || 0
1370
+ })
1371
+ }
1372
+
1373
+ // Create a transfer to null address (burn)
1374
+ const mutation = this.createQuery(MutationTransferTokens) as MutationTransferTokens
1375
+
1376
+ await mutation.fillMolecule({
1377
+ sourceWallet,
1378
+ recipient: '0000000000000000000000000000000000000000000000000000000000000000', // Burn address
1379
+ token: token.toUpperCase(),
1380
+ amount,
1381
+ units
1382
+ })
1383
+
1384
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1385
+ const response = await this.executeQuery(moleculeMutation)
1386
+
1387
+ if (!response) {
1388
+ throw new CodeException('Token burn failed')
1389
+ }
1390
+
1391
+ return response
1392
+ }
1393
+
1394
+ /**
1395
+ * Replenish tokens
1396
+ */
1397
+ async replenishToken({
1398
+ token,
1399
+ amount = null,
1400
+ units = null,
1401
+ sourceWallet = null
1402
+ }: {
1403
+ token: TokenSlug | string
1404
+ amount?: number | string | null
1405
+ units?: string[] | null
1406
+ sourceWallet?: Wallet | null
1407
+ }): Promise<Response> {
1408
+ this.log('info', `KnishIOClient::replenishToken() - Replenishing ${amount || 'units'} of ${token}...`)
1409
+
1410
+ // Similar to requestTokens but with specific replenishment logic
1411
+ return this.requestTokens({
1412
+ token,
1413
+ amount,
1414
+ units
1415
+ })
1416
+ }
1417
+
1418
+ /**
1419
+ * Fuse token units
1420
+ */
1421
+ async fuseToken({
1422
+ bundleHash,
1423
+ tokenSlug,
1424
+ newTokenUnit,
1425
+ fusedTokenUnitIds,
1426
+ sourceWallet = null
1427
+ }: {
1428
+ bundleHash: BundleHash | string
1429
+ tokenSlug: TokenSlug | string
1430
+ newTokenUnit: string
1431
+ fusedTokenUnitIds: string[]
1432
+ sourceWallet?: Wallet | null
1433
+ }): Promise<Response> {
1434
+ this.log('info', `KnishIOClient::fuseToken() - Fusing token units for ${tokenSlug}...`)
1435
+
1436
+ // This would require a specific mutation for token fusion
1437
+ // For now, return a placeholder
1438
+ throw new CodeException('Token fusion not yet implemented')
1439
+ }
1440
+
1441
+ // =============================================================================
1442
+ // MUTATION METHODS - WALLET OPERATIONS
1443
+ // =============================================================================
1444
+
1445
+ /**
1446
+ * Create a new wallet for a token
1447
+ */
1448
+ async createWallet({
1449
+ token
1450
+ }: {
1451
+ token: TokenSlug | string
1452
+ }): Promise<Response> {
1453
+ this.log('info', `KnishIOClient::createWallet() - Creating wallet for token ${token}...`)
1454
+
1455
+ const mutation = this.createQuery(MutationCreateWallet) as MutationCreateWallet
1456
+
1457
+ // Get source wallet
1458
+ const sourceWallet = await this.getSourceWallet()
1459
+
1460
+ // Initialize the create wallet mutation
1461
+ await mutation.fillMolecule({
1462
+ sourceWallet,
1463
+ token: token.toUpperCase()
1464
+ })
1465
+
1466
+ // Create the molecule mutation
1467
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1468
+
1469
+ // Execute the mutation
1470
+ const response = await this.executeQuery(moleculeMutation)
1471
+
1472
+ if (!response) {
1473
+ throw new CodeException('Wallet creation failed')
1474
+ }
1475
+
1476
+ return response
1477
+ }
1478
+
1479
+ /**
1480
+ * Claim a single shadow wallet
1481
+ */
1482
+ async claimShadowWallet({
1483
+ token,
1484
+ batchId = null,
1485
+ molecule = null
1486
+ }: {
1487
+ token: TokenSlug | string
1488
+ batchId?: BatchId | string | null
1489
+ molecule?: Molecule | null
1490
+ }): Promise<Response> {
1491
+ this.log('info', `KnishIOClient::claimShadowWallet() - Claiming shadow wallet for token ${token}...`)
1492
+
1493
+ // Get shadow wallets
1494
+ const shadowWallets = await this.queryWallets({ token })
1495
+
1496
+ if (!shadowWallets || shadowWallets.length === 0) {
1497
+ throw new WalletShadowException('No shadow wallets found')
1498
+ }
1499
+
1500
+ // Find the shadow wallet with matching batchId
1501
+ const shadowWallet = batchId
1502
+ ? shadowWallets.find(w => w.batchId === batchId)
1503
+ : shadowWallets[0]
1504
+
1505
+ if (!shadowWallet) {
1506
+ throw new WalletShadowException('Shadow wallet not found')
1507
+ }
1508
+
1509
+ if (!shadowWallet.isShadow()) {
1510
+ throw new WalletShadowException('Wallet is not a shadow wallet')
1511
+ }
1512
+
1513
+ const mutation = this.createQuery(MutationClaimShadowWallet) as MutationClaimShadowWallet
1514
+
1515
+ // Get source wallet
1516
+ const sourceWallet = await this.getSourceWallet()
1517
+
1518
+ // Initialize the claim shadow wallet mutation
1519
+ await mutation.fillMolecule({
1520
+ sourceWallet,
1521
+ token: token.toUpperCase(),
1522
+ batchId: shadowWallet.batchId
1523
+ })
1524
+
1525
+ // Create the molecule mutation
1526
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1527
+
1528
+ // Execute the mutation
1529
+ const response = await this.executeQuery(moleculeMutation)
1530
+
1531
+ if (!response) {
1532
+ throw new CodeException('Shadow wallet claim failed')
1533
+ }
1534
+
1535
+ return response
1536
+ }
1537
+
1538
+ /**
1539
+ * Claim all shadow wallets for a token
1540
+ */
1541
+ async claimShadowWallets({
1542
+ token
1543
+ }: {
1544
+ token: TokenSlug | string
1545
+ }): Promise<Response[]> {
1546
+ this.log('info', `KnishIOClient::claimShadowWallets() - Claiming all shadow wallets for token ${token}...`)
1547
+
1548
+ // Get all shadow wallets
1549
+ const shadowWallets = await this.queryWallets({ token })
1550
+
1551
+ if (!shadowWallets || !Array.isArray(shadowWallets)) {
1552
+ throw new WalletShadowException()
1553
+ }
1554
+
1555
+ // Verify they are all shadow wallets
1556
+ shadowWallets.forEach(shadowWallet => {
1557
+ if (!shadowWallet.isShadow()) {
1558
+ throw new WalletShadowException('Found non-shadow wallet in list')
1559
+ }
1560
+ })
1561
+
1562
+ // Claim each shadow wallet
1563
+ const responses: Response[] = []
1564
+ for (const shadowWallet of shadowWallets) {
1565
+ const response = await this.claimShadowWallet({
1566
+ token,
1567
+ batchId: shadowWallet.batchId
1568
+ })
1569
+ responses.push(response)
1570
+ }
1571
+
1572
+ return responses
1573
+ }
1574
+
1575
+ // =============================================================================
1576
+ // MUTATION METHODS - METADATA OPERATIONS
1577
+ // =============================================================================
1578
+
1579
+ /**
1580
+ * Create metadata entry
1581
+ */
1582
+ async createMeta({
1583
+ metaType,
1584
+ metaId,
1585
+ meta = null,
1586
+ policy = null
1587
+ }: {
1588
+ metaType: MetaType | string
1589
+ metaId: MetaId | string
1590
+ meta?: Record<string, any> | null
1591
+ policy?: any | null
1592
+ }): Promise<Response> {
1593
+ this.log('info', `KnishIOClient::createMeta() - Creating metadata for ${metaType}:${metaId}...`)
1594
+
1595
+ const mutation = this.createQuery(MutationCreateMeta) as MutationCreateMeta
1596
+
1597
+ // Get source wallet
1598
+ const sourceWallet = await this.getSourceWallet()
1599
+
1600
+ // Initialize the create meta mutation
1601
+ await mutation.fillMolecule({
1602
+ sourceWallet,
1603
+ metaType: metaType.toUpperCase(),
1604
+ metaId,
1605
+ meta,
1606
+ policy
1607
+ })
1608
+
1609
+ // Create the molecule mutation
1610
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1611
+
1612
+ // Execute the mutation
1613
+ const response = await this.executeQuery(moleculeMutation)
1614
+
1615
+ if (!response) {
1616
+ throw new CodeException('Metadata creation failed')
1617
+ }
1618
+
1619
+ return response
1620
+ }
1621
+
1622
+ /**
1623
+ * Create a new rule
1624
+ */
1625
+ async createRule({
1626
+ metaType,
1627
+ metaId,
1628
+ rule,
1629
+ policy = null
1630
+ }: {
1631
+ metaType: MetaType | string
1632
+ metaId: MetaId | string
1633
+ rule: any
1634
+ policy?: any | null
1635
+ }): Promise<Response> {
1636
+ this.log('info', `KnishIOClient::createRule() - Creating rule for ${metaType}:${metaId}...`)
1637
+
1638
+ const mutation = this.createQuery(MutationCreateRule) as MutationCreateRule
1639
+
1640
+ // Get source wallet
1641
+ const sourceWallet = await this.getSourceWallet()
1642
+
1643
+ // Initialize the create rule mutation
1644
+ await mutation.fillMolecule({
1645
+ sourceWallet,
1646
+ metaType: metaType.toUpperCase(),
1647
+ metaId,
1648
+ rule,
1649
+ policy
1650
+ })
1651
+
1652
+ // Create the molecule mutation
1653
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1654
+
1655
+ // Execute the mutation
1656
+ const response = await this.executeQuery(moleculeMutation)
1657
+
1658
+ if (!response) {
1659
+ throw new CodeException('Rule creation failed')
1660
+ }
1661
+
1662
+ return response
1663
+ }
1664
+
1665
+ /**
1666
+ * Create a policy
1667
+ */
1668
+ async createPolicy({
1669
+ metaType,
1670
+ metaId,
1671
+ policy = null
1672
+ }: {
1673
+ metaType: MetaType | string
1674
+ metaId: MetaId | string
1675
+ policy?: any | null
1676
+ }): Promise<Response> {
1677
+ this.log('info', `KnishIOClient::createPolicy() - Creating policy for ${metaType}:${metaId}...`)
1678
+
1679
+ // Policies are created via createMeta with policy parameter
1680
+ return this.createMeta({
1681
+ metaType,
1682
+ metaId,
1683
+ meta: null,
1684
+ policy
1685
+ })
1686
+ }
1687
+
1688
+ /**
1689
+ * Create an identifier
1690
+ */
1691
+ async createIdentifier({
1692
+ type,
1693
+ contact,
1694
+ code
1695
+ }: {
1696
+ type: string
1697
+ contact: string
1698
+ code: string
1699
+ }): Promise<Response> {
1700
+ this.log('info', `KnishIOClient::createIdentifier() - Creating identifier of type ${type}...`)
1701
+
1702
+ const mutation = this.createQuery(MutationCreateIdentifier) as MutationCreateIdentifier
1703
+
1704
+ // Get source wallet
1705
+ const sourceWallet = await this.getSourceWallet()
1706
+
1707
+ // Initialize the create identifier mutation
1708
+ await mutation.fillMolecule({
1709
+ sourceWallet,
1710
+ type,
1711
+ contact,
1712
+ code
1713
+ })
1714
+
1715
+ // Create the molecule mutation
1716
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1717
+
1718
+ // Execute the mutation
1719
+ const response = await this.executeQuery(moleculeMutation)
1720
+
1721
+ if (!response) {
1722
+ throw new CodeException('Identifier creation failed')
1723
+ }
1724
+
1725
+ return response
1726
+ }
1727
+
1728
+ /**
1729
+ * Link an identifier
1730
+ */
1731
+ async linkIdentifier({
1732
+ type,
1733
+ contact
1734
+ }: {
1735
+ type: string
1736
+ contact: string
1737
+ }): Promise<Response> {
1738
+ this.log('info', `KnishIOClient::linkIdentifier() - Linking identifier of type ${type}...`)
1739
+
1740
+ const mutation = this.createQuery(MutationLinkIdentifier) as MutationLinkIdentifier
1741
+
1742
+ // Get source wallet
1743
+ const sourceWallet = await this.getSourceWallet()
1744
+
1745
+ // Initialize the link identifier mutation
1746
+ await mutation.fillMolecule({
1747
+ sourceWallet,
1748
+ type,
1749
+ contact
1750
+ })
1751
+
1752
+ // Create the molecule mutation
1753
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1754
+
1755
+ // Execute the mutation
1756
+ const response = await this.executeQuery(moleculeMutation)
1757
+
1758
+ if (!response) {
1759
+ throw new CodeException('Identifier linking failed')
1760
+ }
1761
+
1762
+ return response
1763
+ }
1764
+
1765
+ // =============================================================================
1766
+ // MUTATION METHODS - SESSION & BUFFER OPERATIONS
1767
+ // =============================================================================
1768
+
1769
+ /**
1770
+ * Declare an active session
1771
+ */
1772
+ async activeSession({
1773
+ bundle,
1774
+ metaType,
1775
+ metaId,
1776
+ ipAddress,
1777
+ browser,
1778
+ osCpu,
1779
+ resolution,
1780
+ timeZone,
1781
+ json = null
1782
+ }: {
1783
+ bundle: BundleHash | string
1784
+ metaType: MetaType | string
1785
+ metaId: MetaId | string
1786
+ ipAddress: string
1787
+ browser: string
1788
+ osCpu: string
1789
+ resolution: string
1790
+ timeZone: string
1791
+ json?: any | null
1792
+ }): Promise<Response> {
1793
+ this.log('info', `KnishIOClient::activeSession() - Declaring active session for ${metaType}:${metaId}...`)
1794
+
1795
+ const mutation = this.createQuery(MutationActiveSession) as MutationActiveSession
1796
+
1797
+ // Get source wallet
1798
+ const sourceWallet = await this.getSourceWallet()
1799
+
1800
+ // Initialize the active session mutation
1801
+ await mutation.fillMolecule({
1802
+ sourceWallet,
1803
+ bundle,
1804
+ metaType: metaType.toUpperCase(),
1805
+ metaId,
1806
+ ipAddress,
1807
+ browser,
1808
+ osCpu,
1809
+ resolution,
1810
+ timeZone,
1811
+ json
1812
+ })
1813
+
1814
+ // Create the molecule mutation
1815
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1816
+
1817
+ // Execute the mutation
1818
+ const response = await this.executeQuery(moleculeMutation)
1819
+
1820
+ if (!response) {
1821
+ throw new CodeException('Active session declaration failed')
1822
+ }
1823
+
1824
+ return response
1825
+ }
1826
+
1827
+ /**
1828
+ * Deposit buffer tokens
1829
+ */
1830
+ async depositBufferToken({
1831
+ tokenSlug,
1832
+ amount,
1833
+ tradeRates,
1834
+ sourceWallet = null
1835
+ }: {
1836
+ tokenSlug: TokenSlug | string
1837
+ amount: number | string
1838
+ tradeRates: Record<string, number>
1839
+ sourceWallet?: Wallet | null
1840
+ }): Promise<Response> {
1841
+ this.log('info', `KnishIOClient::depositBufferToken() - Depositing ${amount} of ${tokenSlug} to buffer...`)
1842
+
1843
+ // Get source wallet if not provided
1844
+ if (!sourceWallet) {
1845
+ sourceWallet = await this.querySourceWallet({
1846
+ token: tokenSlug,
1847
+ amount
1848
+ })
1849
+ }
1850
+
1851
+ const mutation = this.createQuery(MutationDepositBufferToken) as MutationDepositBufferToken
1852
+
1853
+ // Initialize the deposit buffer token mutation
1854
+ await mutation.fillMolecule({
1855
+ sourceWallet,
1856
+ tokenSlug: tokenSlug.toUpperCase(),
1857
+ amount,
1858
+ tradeRates
1859
+ })
1860
+
1861
+ // Create the molecule mutation
1862
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1863
+
1864
+ // Execute the mutation
1865
+ const response = await this.executeQuery(moleculeMutation)
1866
+
1867
+ if (!response) {
1868
+ throw new CodeException('Buffer token deposit failed')
1869
+ }
1870
+
1871
+ return response
1872
+ }
1873
+
1874
+ /**
1875
+ * Withdraw buffer tokens
1876
+ */
1877
+ async withdrawBufferToken({
1878
+ tokenSlug,
1879
+ amount,
1880
+ sourceWallet = null,
1881
+ signingWallet = null
1882
+ }: {
1883
+ tokenSlug: TokenSlug | string
1884
+ amount: number | string
1885
+ sourceWallet?: Wallet | null
1886
+ signingWallet?: Wallet | null
1887
+ }): Promise<Response> {
1888
+ this.log('info', `KnishIOClient::withdrawBufferToken() - Withdrawing ${amount} of ${tokenSlug} from buffer...`)
1889
+
1890
+ // Get source wallet if not provided
1891
+ if (!sourceWallet) {
1892
+ sourceWallet = await this.getSourceWallet()
1893
+ }
1894
+
1895
+ const mutation = this.createQuery(MutationWithdrawBufferToken) as MutationWithdrawBufferToken
1896
+
1897
+ // Initialize the withdraw buffer token mutation
1898
+ await mutation.fillMolecule({
1899
+ sourceWallet,
1900
+ tokenSlug: tokenSlug.toUpperCase(),
1901
+ amount,
1902
+ signingWallet
1903
+ })
1904
+
1905
+ // Create the molecule mutation
1906
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1907
+
1908
+ // Execute the mutation
1909
+ const response = await this.executeQuery(moleculeMutation)
1910
+
1911
+ if (!response) {
1912
+ throw new CodeException('Buffer token withdrawal failed')
1913
+ }
1914
+
1915
+ return response
1916
+ }
1917
+
1918
+ // =============================================================================
1919
+ // AUTHENTICATION METHODS
1920
+ // =============================================================================
1921
+
1922
+ /**
1923
+ * Request guest authentication token
1924
+ */
1925
+ async requestGuestAuthToken({
1926
+ cellSlug = null,
1927
+ encrypt = false
1928
+ }: {
1929
+ cellSlug?: CellSlug | string | null
1930
+ encrypt?: boolean
1931
+ } = {}): Promise<Response> {
1932
+ this.log('info', 'KnishIOClient::requestGuestAuthToken() - Requesting guest auth token...')
1933
+
1934
+ const mutation = this.createQuery(MutationRequestAuthorizationGuest) as MutationRequestAuthorizationGuest
1935
+
1936
+ // Initialize the guest auth mutation
1937
+ await mutation.fillMolecule({
1938
+ cellSlug: cellSlug || this.getCellSlug()
1939
+ })
1940
+
1941
+ // Create the molecule mutation
1942
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1943
+
1944
+ // Execute the mutation
1945
+ const response = await this.executeQuery(moleculeMutation)
1946
+
1947
+ if (!response) {
1948
+ throw new CodeException('Guest auth token request failed')
1949
+ }
1950
+
1951
+ // Handle encryption if needed
1952
+ if (encrypt) {
1953
+ this.switchEncryption(true)
1954
+ }
1955
+
1956
+ return response
1957
+ }
1958
+
1959
+ /**
1960
+ * Request profile authentication token
1961
+ */
1962
+ async requestProfileAuthToken({
1963
+ secret,
1964
+ encrypt = false
1965
+ }: {
1966
+ secret: string
1967
+ encrypt?: boolean
1968
+ }): Promise<Response> {
1969
+ this.log('info', 'KnishIOClient::requestProfileAuthToken() - Requesting profile auth token...')
1970
+
1971
+ // Set the secret
1972
+ this.setSecret(secret)
1973
+
1974
+ const mutation = this.createQuery(MutationRequestAuthorization) as MutationRequestAuthorization
1975
+
1976
+ // Get source wallet
1977
+ const sourceWallet = await this.getSourceWallet()
1978
+
1979
+ // Initialize the profile auth mutation
1980
+ await mutation.fillMolecule({
1981
+ sourceWallet,
1982
+ cellSlug: this.getCellSlug()
1983
+ })
1984
+
1985
+ // Create the molecule mutation
1986
+ const moleculeMutation = await this.createMoleculeMutation({ mutationClass: mutation })
1987
+
1988
+ // Execute the mutation
1989
+ const response = await this.executeQuery(moleculeMutation)
1990
+
1991
+ if (!response) {
1992
+ throw new CodeException('Profile auth token request failed')
1993
+ }
1994
+
1995
+ // Handle encryption if needed
1996
+ if (encrypt) {
1997
+ this.switchEncryption(true)
1998
+ }
1999
+
2000
+ return response
2001
+ }
2002
+
2003
+ // =============================================================================
2004
+ // LEGACY/DEPRECATED METHODS
2005
+ // =============================================================================
2006
+
2007
+ /**
2008
+ * @deprecated Use getCellSlug() instead
2009
+ */
2010
+ cellSlug(): string | null {
2011
+ return this.getCellSlug()
2012
+ }
2013
+
2014
+ /**
2015
+ * @deprecated Use getUri() instead
2016
+ */
2017
+ uri(): string[] {
2018
+ return this.getUri()
2019
+ }
2020
+ }