@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,467 @@
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 JsSHA from 'jssha'
50
+ import { randomString, chunkSubstr } from '@/libraries/strings'
51
+ import { generateBundleHash, generateSecret, shake256 } from '@/libraries/crypto'
52
+ import WalletCredentialException from '@/exception/WalletCredentialException'
53
+ import { isWalletAddress, isBundleHash, isPosition } from '@/types'
54
+ // Post-quantum cryptography for ML-KEM768 key encapsulation
55
+ import { ml_kem768 } from '@noble/post-quantum/ml-kem.js'
56
+
57
+ /**
58
+ * Wallet class - Identity and key management for KnishIO DLT
59
+ * Essential implementation for transaction operations
60
+ */
61
+ export default class Wallet {
62
+ public token: string
63
+ public balance: number
64
+ public address: string | null
65
+ public position: string | null
66
+ public bundle: string | null
67
+ public batchId: string | null
68
+ public characters: string | null
69
+ public key: string | null
70
+ public privkey: any
71
+ public pubkey: any
72
+ public tokenUnits: any[]
73
+ public tradeRates: Record<string, any>
74
+ public molecules: Record<string, any>
75
+
76
+ constructor({
77
+ secret = null,
78
+ bundle = null,
79
+ token = 'USER',
80
+ address = null,
81
+ position = null,
82
+ batchId = null,
83
+ characters = null
84
+ }: {
85
+ secret?: string | null
86
+ bundle?: string | null
87
+ token?: string
88
+ address?: string | null
89
+ position?: string | null
90
+ batchId?: string | null
91
+ characters?: string | null
92
+ } = {}) {
93
+ // TypeScript 2025: Exhaustive validation with type guards
94
+ if (address !== null && !isWalletAddress(address)) {
95
+ throw new WalletCredentialException('Invalid wallet address format')
96
+ }
97
+ if (bundle !== null && !isBundleHash(bundle)) {
98
+ throw new WalletCredentialException('Invalid bundle hash format')
99
+ }
100
+ if (position !== null && !isPosition(position)) {
101
+ throw new WalletCredentialException('Invalid position format')
102
+ }
103
+ this.token = token
104
+ this.balance = 0
105
+ this.molecules = {}
106
+
107
+ // Empty values
108
+ this.key = null
109
+ this.privkey = null
110
+ this.pubkey = null
111
+ this.tokenUnits = []
112
+ this.tradeRates = {}
113
+
114
+ this.address = address
115
+ this.position = position
116
+ this.bundle = bundle
117
+ this.batchId = batchId
118
+ this.characters = characters
119
+
120
+ if (secret) {
121
+ // Set bundle from the secret
122
+ this.bundle = this.bundle || generateBundleHash(secret, 'Wallet::constructor')
123
+
124
+ // Generate a position for non-shadow wallet if not initialized
125
+ this.position = this.position || Wallet.generatePosition()
126
+
127
+ // Key & address initialization
128
+ this.key = Wallet.generateKey({
129
+ secret,
130
+ token: this.token,
131
+ position: this.position
132
+ })
133
+ this.address = this.address || Wallet.generateAddress(this.key)
134
+
135
+ // Set characters
136
+ this.characters = this.characters || 'BASE64'
137
+
138
+ // Initialize ML-KEM768 keys (matches JavaScript SDK)
139
+ this.initializeMLKEM()
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Creates a new Wallet instance
145
+ * Matches JavaScript SDK Wallet.create exactly
146
+ */
147
+ static create({
148
+ secret = null,
149
+ bundle = null,
150
+ token = 'USER',
151
+ batchId = null,
152
+ characters = null
153
+ }: {
154
+ secret?: string | null
155
+ bundle?: string | null
156
+ token?: string
157
+ batchId?: string | null
158
+ characters?: string | null
159
+ }): Wallet {
160
+ let position = null
161
+
162
+ // No credentials parameters provided?
163
+ if (!secret && !bundle) {
164
+ throw new WalletCredentialException()
165
+ }
166
+
167
+ // Secret, but no bundle?
168
+ if (secret && !bundle) {
169
+ position = Wallet.generatePosition()
170
+ bundle = generateBundleHash(secret, 'Wallet::create')
171
+ }
172
+
173
+ // Wallet initialization
174
+ return new Wallet({
175
+ secret,
176
+ bundle,
177
+ token,
178
+ position,
179
+ batchId,
180
+ characters
181
+ })
182
+ }
183
+
184
+
185
+ /**
186
+ * Generates a private key for the given parameters
187
+ * MUST match JavaScript SDK Wallet.generateKey exactly using sponge pattern
188
+ */
189
+ static generateKey({
190
+ secret,
191
+ token,
192
+ position
193
+ }: {
194
+ secret: string
195
+ token: string
196
+ position: string
197
+ }): string {
198
+ // Converting secret to bigInt
199
+ const bigIntSecret = BigInt(`0x${secret}`)
200
+
201
+ // Adding new position to the user secret to produce the indexed key
202
+ const indexedKey = bigIntSecret + BigInt(`0x${position}`)
203
+
204
+ // Hashing the indexed key to produce the intermediate key
205
+ // CRITICAL FIX: Use sponge pattern exactly like JavaScript SDK
206
+ const intermediateKeySponge = new JsSHA('SHAKE256', 'TEXT')
207
+ intermediateKeySponge.update(indexedKey.toString(16))
208
+
209
+ if (token) {
210
+ // CRITICAL FIX: Update the SAME sponge with token (no concatenation)
211
+ intermediateKeySponge.update(token)
212
+ }
213
+
214
+ // Hashing the intermediate key to produce the private key
215
+ // CRITICAL FIX: Create NEW sponge for private key (matching JS SDK)
216
+ const privateKeySponge = new JsSHA('SHAKE256', 'TEXT')
217
+ privateKeySponge.update(intermediateKeySponge.getHash('HEX', { outputLen: 8192 }))
218
+
219
+ return privateKeySponge.getHash('HEX', { outputLen: 8192 })
220
+ }
221
+
222
+ /**
223
+ * Generates a wallet address
224
+ * Matches JavaScript SDK Wallet.generateAddress exactly
225
+ */
226
+ static generateAddress(key: string): string {
227
+ // Subdivide private key into 16 fragments of 128 characters each
228
+ const keyFragments = chunkSubstr(key, 128)
229
+
230
+ // Generating wallet digest
231
+ let digestInput = ''
232
+
233
+ for (let index = 0; index < keyFragments.length; index++) {
234
+ let workingFragment = keyFragments[index]
235
+ if (!workingFragment) continue
236
+
237
+ // Hash each fragment 16 times
238
+ for (let fragmentCount = 1; fragmentCount <= 16; fragmentCount++) {
239
+ // Fix: Use 512 bits to get 128 hex chars output (matching JS SDK)
240
+ workingFragment = shake256(workingFragment, 512)
241
+ }
242
+
243
+ digestInput += workingFragment
244
+ }
245
+
246
+ // Producing wallet address
247
+ // Fix: Use 8192 bits to get 2048 hex chars for digest (matching JS SDK)
248
+ const digest = shake256(digestInput, 8192)
249
+ // Fix: Use 256 bits to get 64 hex chars for address (matching JS SDK)
250
+ return shake256(digest, 256)
251
+ }
252
+
253
+ /**
254
+ * Generate a random position for wallet
255
+ * Matches JavaScript SDK Wallet.generatePosition exactly
256
+ */
257
+ static generatePosition(saltLength = 64): string {
258
+ return randomString(saltLength, 'abcdef0123456789')
259
+ }
260
+
261
+ /**
262
+ * Determines if the provided string is a bundle hash
263
+ * Uses exhaustive type guard from types system
264
+ * @param maybeBundleHash - String to check
265
+ * @return True if valid bundle hash format
266
+ */
267
+ static isBundleHash(maybeBundleHash: unknown): maybeBundleHash is string {
268
+ return typeof maybeBundleHash === 'string' && isBundleHash(maybeBundleHash)
269
+ }
270
+
271
+ /**
272
+ * Get formatted token units from raw data
273
+ * Stub implementation for now
274
+ */
275
+ static getTokenUnits(unitsData: any[]): any[] {
276
+ // TODO: Implement TokenUnit class if needed
277
+ return unitsData
278
+ }
279
+
280
+ /**
281
+ * Create a remainder wallet for transactions
282
+ * Used by Molecule for creating remainder atoms
283
+ */
284
+ createRemainder(secret: string): Wallet {
285
+ return Wallet.create({
286
+ secret,
287
+ bundle: this.bundle,
288
+ token: this.token,
289
+ batchId: this.batchId,
290
+ characters: this.characters
291
+ })
292
+ }
293
+
294
+ /**
295
+ * Get token units data
296
+ * Stub for compatibility
297
+ */
298
+ getTokenUnitsData(): any[] {
299
+ return this.tokenUnits
300
+ }
301
+
302
+ /**
303
+ * Check if this is a shadow wallet
304
+ * Shadow wallets don't have position or address set
305
+ * @return True if this is a shadow wallet
306
+ */
307
+ isShadow(): boolean {
308
+ return (
309
+ (typeof this.position === 'undefined' || this.position === null) &&
310
+ (typeof this.address === 'undefined' || this.address === null)
311
+ )
312
+ }
313
+
314
+ // =============================================================================
315
+ // POST-QUANTUM CRYPTOGRAPHY - ML-KEM768 INTEGRATION
316
+ // =============================================================================
317
+
318
+ /**
319
+ * Initializes the ML-KEM key pair (matches JavaScript SDK exactly)
320
+ */
321
+ initializeMLKEM(): void {
322
+ // Generate a 64-byte (512-bit) seed from the Knish.IO private key
323
+ // Use deterministic approach: generateSecret(key, 128) → 128 hex chars = 64 bytes
324
+ const seedHex = generateSecret(this.key!, 128) // 128 hex chars = 64 bytes
325
+
326
+ // Convert the hex string to a Uint8Array
327
+ const seed = new Uint8Array(64)
328
+ for (let i = 0; i < 64; i++) {
329
+ seed[i] = parseInt(seedHex.substr(i * 2, 2), 16)
330
+ }
331
+
332
+ const { publicKey, secretKey } = ml_kem768.keygen(seed)
333
+ this.pubkey = this.serializeKey(publicKey)
334
+ this.privkey = secretKey // Note: We're keeping privkey as UInt8Array for security
335
+ }
336
+
337
+
338
+ // =============================================================================
339
+ // HIGH-LEVEL MESSAGE ENCRYPTION (JavaScript SDK Compatibility)
340
+ // =============================================================================
341
+
342
+ async encryptMessage(message: any, recipientPubkey: string): Promise<{ cipherText: string; encryptedMessage: string }> {
343
+ const messageString = JSON.stringify(message)
344
+ const messageUint8 = new TextEncoder().encode(messageString)
345
+ const deserializedPubkey = this.deserializeKey(recipientPubkey)
346
+ const { cipherText, sharedSecret } = ml_kem768.encapsulate(deserializedPubkey)
347
+ const encryptedMessage = await this.encryptWithSharedSecret(messageUint8, sharedSecret)
348
+ return {
349
+ cipherText: this.serializeKey(cipherText),
350
+ encryptedMessage: this.serializeKey(encryptedMessage)
351
+ }
352
+ }
353
+
354
+ async decryptMessage(encryptedData: { cipherText: string; encryptedMessage: string }): Promise<any> {
355
+ const { cipherText, encryptedMessage } = encryptedData
356
+ let sharedSecret
357
+ try {
358
+ sharedSecret = ml_kem768.decapsulate(this.deserializeKey(cipherText), this.privkey)
359
+ } catch (e) {
360
+ console.error('Wallet::decryptMessage() - Decapsulation failed', e)
361
+ console.info('Wallet::decryptMessage() - my public key', this.pubkey)
362
+ return null
363
+ }
364
+ let deserializedEncryptedMessage
365
+ try {
366
+ deserializedEncryptedMessage = this.deserializeKey(encryptedMessage)
367
+ } catch (e) {
368
+ console.warn('Wallet::decryptMessage() - Deserialization failed', e)
369
+ console.info('Wallet::decryptMessage() - my public key', this.pubkey)
370
+ console.info('Wallet::decryptMessage() - our shared secret', sharedSecret)
371
+ return null
372
+ }
373
+ let decryptedUint8
374
+ try {
375
+ decryptedUint8 = await this.decryptWithSharedSecret(deserializedEncryptedMessage, sharedSecret)
376
+ } catch (e) {
377
+ console.warn('Wallet::decryptMessage() - Decryption failed', e)
378
+ console.info('Wallet::decryptMessage() - my public key', this.pubkey)
379
+ console.info('Wallet::decryptMessage() - our shared secret', sharedSecret)
380
+ console.info('Wallet::decryptMessage() - deserialized encrypted message', deserializedEncryptedMessage)
381
+ return null
382
+ }
383
+ let decryptedString
384
+ try {
385
+ decryptedString = new TextDecoder().decode(decryptedUint8)
386
+ } catch (e) {
387
+ console.warn('Wallet::decryptMessage() - Decoding failed', e)
388
+ console.info('Wallet::decryptMessage() - my public key', this.pubkey)
389
+ console.info('Wallet::decryptMessage() - our shared secret', sharedSecret)
390
+ console.info('Wallet::decryptMessage() - deserialized encrypted message', deserializedEncryptedMessage)
391
+ console.info('Wallet::decryptMessage() - decrypted Uint8Array', decryptedUint8)
392
+ return null
393
+ }
394
+ return JSON.parse(decryptedString)
395
+ }
396
+
397
+ // =============================================================================
398
+ // SYMMETRIC ENCRYPTION HELPERS (AES-GCM with shared secret)
399
+ // =============================================================================
400
+
401
+ /**
402
+ * Encrypt data using AES-GCM with the given shared secret
403
+ */
404
+ private async encryptWithSharedSecret(message: Uint8Array, sharedSecret: Uint8Array): Promise<Uint8Array> {
405
+ // Generate random IV for AES-GCM
406
+ const iv = crypto.getRandomValues(new Uint8Array(12))
407
+
408
+ // Import shared secret as CryptoKey
409
+ const key = await crypto.subtle.importKey(
410
+ 'raw',
411
+ sharedSecret,
412
+ { name: 'AES-GCM' },
413
+ false,
414
+ ['encrypt']
415
+ )
416
+
417
+ // Encrypt the message
418
+ const encryptedContent = await crypto.subtle.encrypt(
419
+ { name: 'AES-GCM', iv },
420
+ key,
421
+ message
422
+ )
423
+
424
+ // Combine IV and encrypted content
425
+ const result = new Uint8Array(iv.length + encryptedContent.byteLength)
426
+ result.set(iv)
427
+ result.set(new Uint8Array(encryptedContent), iv.length)
428
+
429
+ return result
430
+ }
431
+
432
+ /**
433
+ * Decrypt data using AES-GCM with the given shared secret
434
+ */
435
+ private async decryptWithSharedSecret(encryptedMessage: Uint8Array, sharedSecret: Uint8Array): Promise<Uint8Array> {
436
+ // Extract IV from the encrypted message
437
+ const iv = encryptedMessage.slice(0, 12)
438
+ const ciphertext = encryptedMessage.slice(12)
439
+
440
+ // Import shared secret as CryptoKey
441
+ const key = await crypto.subtle.importKey(
442
+ 'raw',
443
+ sharedSecret,
444
+ { name: 'AES-GCM' },
445
+ false,
446
+ ['decrypt']
447
+ )
448
+
449
+ // Decrypt the message
450
+ const decryptedContent = await crypto.subtle.decrypt(
451
+ { name: 'AES-GCM', iv },
452
+ key,
453
+ ciphertext
454
+ )
455
+
456
+ return new Uint8Array(decryptedContent)
457
+ }
458
+
459
+ serializeKey(key: Uint8Array): string {
460
+ return btoa(String.fromCharCode(...key))
461
+ }
462
+
463
+ deserializeKey(serializedKey: string): Uint8Array {
464
+ const binaryString = atob(serializedKey)
465
+ return new Uint8Array([...binaryString].map(char => char.charCodeAt(0)))
466
+ }
467
+ }
@@ -0,0 +1,97 @@
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 BaseException, { type BaseExceptionOptions } from './BaseException'
50
+
51
+ /**
52
+ * Exception thrown when atom indexing is invalid or conflicts
53
+ * Used in molecular composition when atom indices are incorrect
54
+ */
55
+ export default class AtomIndexException extends BaseException {
56
+ constructor(message = 'Invalid atom index', options: BaseExceptionOptions = {}) {
57
+ super('ATOM_INDEX_ERROR', message, options)
58
+ }
59
+
60
+ /**
61
+ * Factory method for index conflicts
62
+ */
63
+ static indexConflict(index: number, existingIndex: number): AtomIndexException {
64
+ return new AtomIndexException(
65
+ `Atom index ${index} conflicts with existing index ${existingIndex}`,
66
+ {
67
+ details: { index, existingIndex },
68
+ code: 'INDEX_CONFLICT'
69
+ }
70
+ )
71
+ }
72
+
73
+ /**
74
+ * Factory method for out-of-range indices
75
+ */
76
+ static indexOutOfRange(index: number, maxIndex: number): AtomIndexException {
77
+ return new AtomIndexException(
78
+ `Atom index ${index} is out of range (max: ${maxIndex})`,
79
+ {
80
+ details: { index, maxIndex },
81
+ code: 'INDEX_OUT_OF_RANGE'
82
+ }
83
+ )
84
+ }
85
+
86
+ /**
87
+ * Factory method for missing required index
88
+ */
89
+ static missingIndex(): AtomIndexException {
90
+ return new AtomIndexException(
91
+ 'Atom index is required but not provided',
92
+ {
93
+ code: 'INDEX_MISSING'
94
+ }
95
+ )
96
+ }
97
+ }
@@ -0,0 +1,109 @@
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 BaseException, { type BaseExceptionOptions } from './BaseException'
50
+
51
+ /**
52
+ * Exception thrown when required atoms are missing from a molecule
53
+ * Used in molecular validation and composition
54
+ */
55
+ export default class AtomsMissingException extends BaseException {
56
+ constructor(message = 'Required atoms are missing', options: BaseExceptionOptions = {}) {
57
+ super('ATOMS_MISSING_ERROR', message, options)
58
+ }
59
+
60
+ /**
61
+ * Factory method for empty molecule
62
+ */
63
+ static emptyMolecule(): AtomsMissingException {
64
+ return new AtomsMissingException(
65
+ 'Molecule cannot be empty - at least one atom is required',
66
+ {
67
+ code: 'EMPTY_MOLECULE'
68
+ }
69
+ )
70
+ }
71
+
72
+ /**
73
+ * Factory method for missing isotope-specific atoms
74
+ */
75
+ static missingIsotope(isotope: string): AtomsMissingException {
76
+ return new AtomsMissingException(
77
+ `Missing required ${isotope} isotope atoms`,
78
+ {
79
+ details: { isotope },
80
+ code: 'MISSING_ISOTOPE'
81
+ }
82
+ )
83
+ }
84
+
85
+ /**
86
+ * Factory method for missing remainder atoms
87
+ */
88
+ static missingRemainder(expectedCount: number, actualCount: number): AtomsMissingException {
89
+ return new AtomsMissingException(
90
+ `Missing remainder atoms: expected ${expectedCount}, found ${actualCount}`,
91
+ {
92
+ details: { expectedCount, actualCount },
93
+ code: 'MISSING_REMAINDER'
94
+ }
95
+ )
96
+ }
97
+
98
+ /**
99
+ * Factory method for missing value atoms in transfers
100
+ */
101
+ static missingValueAtoms(): AtomsMissingException {
102
+ return new AtomsMissingException(
103
+ 'Transfer molecules must contain value (V) atoms',
104
+ {
105
+ code: 'MISSING_VALUE_ATOMS'
106
+ }
107
+ )
108
+ }
109
+ }