@wishknish/knishio-client-ts 0.7.4 → 0.7.7

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 (43) hide show
  1. package/dist/index.cjs +2702 -1033
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +339 -106
  4. package/dist/index.d.ts +339 -106
  5. package/dist/index.iife.js +22052 -19964
  6. package/dist/index.iife.js.map +1 -1
  7. package/dist/index.js +2699 -1034
  8. package/dist/index.js.map +1 -1
  9. package/package.json +10 -4
  10. package/src/AuthToken.ts +8 -2
  11. package/src/KnishIOClient.ts +346 -51
  12. package/src/constants.ts +5 -3
  13. package/src/core/Atom.ts +167 -100
  14. package/src/core/AtomMeta.ts +11 -28
  15. package/src/core/Meta.ts +18 -15
  16. package/src/core/Molecule.ts +607 -141
  17. package/src/core/Wallet.ts +19 -24
  18. package/src/index.ts +8 -0
  19. package/src/instance/rules/Rule.ts +128 -19
  20. package/src/libraries/CheckMolecule.ts +88 -1
  21. package/src/libraries/crypto.ts +14 -30
  22. package/src/libraries/strings.ts +26 -25
  23. package/src/mutation/MutationAppendRequest.ts +52 -0
  24. package/src/mutation/MutationCreateRule.ts +2 -2
  25. package/src/mutation/MutationPeering.ts +37 -0
  26. package/src/mutation/MutationRequestAuthorization.ts +3 -3
  27. package/src/query/QueryActiveSession.ts +0 -1
  28. package/src/query/QueryContinuId.ts +8 -0
  29. package/src/query/QueryMetaTypeViaMolecule.ts +221 -0
  30. package/src/query/QueryWalletList.ts +2 -2
  31. package/src/response/ResponseAppendRequest.ts +17 -0
  32. package/src/response/ResponseBalance.ts +8 -3
  33. package/src/response/ResponseContinuId.ts +1 -1
  34. package/src/response/ResponseMetaType.ts +32 -19
  35. package/src/response/ResponseMetaTypeViaMolecule.ts +224 -0
  36. package/src/response/ResponsePeering.ts +17 -0
  37. package/src/response/ResponsePolicy.ts +2 -3
  38. package/src/response/ResponseProposeMolecule.ts +0 -1
  39. package/src/response/ResponseRequestAuthorization.ts +32 -2
  40. package/src/response/ResponseRequestAuthorizationGuest.ts +25 -1
  41. package/src/response/ResponseWalletList.ts +1 -1
  42. package/src/types/guards.ts +18 -5
  43. package/src/types/index.ts +3 -3
@@ -47,10 +47,10 @@ License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
47
47
  */
48
48
 
49
49
  import JsSHA from 'jssha'
50
- import { randomString, chunkSubstr } from '@/libraries/strings'
50
+ import { randomString, chunkSubstr, isHex } from '@/libraries/strings'
51
51
  import { generateBundleHash, generateSecret, shake256, generateBatchId } from '@/libraries/crypto'
52
52
  import WalletCredentialException from '@/exception/WalletCredentialException'
53
- import { isWalletAddress, isBundleHash, isPosition } from '@/types'
53
+ import { isBundleHash } from '@/types'
54
54
  // Post-quantum cryptography for ML-KEM768 key encapsulation
55
55
  import { ml_kem768 } from '@noble/post-quantum/ml-kem.js'
56
56
 
@@ -60,7 +60,7 @@ import { ml_kem768 } from '@noble/post-quantum/ml-kem.js'
60
60
  */
61
61
  export default class Wallet {
62
62
  public token: string
63
- public balance: number
63
+ public balance: string
64
64
  public address: string | null
65
65
  public position: string | null
66
66
  public bundle: string | null
@@ -97,18 +97,8 @@ export default class Wallet {
97
97
  batchId?: string | null
98
98
  characters?: string | null
99
99
  } = {}) {
100
- // TypeScript 2025: Exhaustive validation with type guards
101
- if (address !== null && !isWalletAddress(address)) {
102
- throw new WalletCredentialException('Invalid wallet address format')
103
- }
104
- if (bundle !== null && !isBundleHash(bundle)) {
105
- throw new WalletCredentialException('Invalid bundle hash format')
106
- }
107
- if (position !== null && !isPosition(position)) {
108
- throw new WalletCredentialException('Invalid position format')
109
- }
110
100
  this.token = token
111
- this.balance = 0
101
+ this.balance = '0'
112
102
  this.molecules = {}
113
103
 
114
104
  // Empty values
@@ -164,20 +154,21 @@ export default class Wallet {
164
154
  batchId?: string | null
165
155
  characters?: string | null
166
156
  }): Wallet {
167
- let position = null
168
-
157
+ let position: string | null = null
158
+
169
159
  // No credentials parameters provided?
170
160
  if (!secret && !bundle) {
171
161
  throw new WalletCredentialException()
172
162
  }
173
-
163
+
174
164
  // Secret, but no bundle?
175
165
  if (secret && !bundle) {
176
166
  position = Wallet.generatePosition()
177
167
  bundle = generateBundleHash(secret, 'Wallet::create')
178
168
  }
179
-
180
- // Wallet initialization
169
+
170
+ // Wallet initialization (matching JS SDK exactly)
171
+ // Bundle-only wallets (shadow) get no position/address generation
181
172
  return new Wallet({
182
173
  secret,
183
174
  bundle,
@@ -202,11 +193,15 @@ export default class Wallet {
202
193
  token: string
203
194
  position: string
204
195
  }): string {
196
+ // Normalize non-hex secret/position via SHAKE256 (matching JS/Rust SDKs)
197
+ const secretHex = isHex(secret) ? secret : shake256(secret, 1024)
198
+ const positionHex = isHex(position) ? position : shake256(position, 256)
199
+
205
200
  // Converting secret to bigInt
206
- const bigIntSecret = BigInt(`0x${secret}`)
207
-
201
+ const bigIntSecret = BigInt(`0x${secretHex}`)
202
+
208
203
  // Adding new position to the user secret to produce the indexed key
209
- const indexedKey = bigIntSecret + BigInt(`0x${position}`)
204
+ const indexedKey = bigIntSecret + BigInt(`0x${positionHex}`)
210
205
 
211
206
  // Hashing the indexed key to produce the intermediate key
212
207
  // CRITICAL FIX: Use sponge pattern exactly like JavaScript SDK
@@ -383,8 +378,8 @@ export default class Wallet {
383
378
  */
384
379
  initializeMLKEM(): void {
385
380
  // Generate a 64-byte (512-bit) seed from the Knish.IO private key
386
- // Use deterministic approach: generateSecret(key, 64) → matches JS SDK exactly
387
- const seedHex = generateSecret(this.key!, 64) // Matches JS SDK for cross-platform compatibility
381
+ // Use deterministic approach: generateSecret(key, 128) → 128 hex chars = 64 bytes
382
+ const seedHex = generateSecret(this.key!, 128) // 128 hex chars = 64 bytes, matches JS SDK
388
383
 
389
384
  // Convert the hex string to a Uint8Array
390
385
  const seed = new Uint8Array(64)
package/src/index.ts CHANGED
@@ -113,6 +113,10 @@ export { default as MutationCreateMeta } from './mutation/MutationCreateMeta'
113
113
  export { default as MutationCreateToken } from './mutation/MutationCreateToken'
114
114
  export { default as MutationRequestTokens } from './mutation/MutationRequestTokens'
115
115
 
116
+ // P-isotope and A-isotope Mutation classes
117
+ export { default as MutationPeering } from './mutation/MutationPeering'
118
+ export { default as MutationAppendRequest } from './mutation/MutationAppendRequest'
119
+
116
120
  // Essential Response classes (Phase 1)
117
121
  export { default as ResponseBalance } from './response/ResponseBalance'
118
122
  export { default as ResponseWalletBundle } from './response/ResponseWalletBundle'
@@ -134,6 +138,10 @@ export { default as ResponseMetaTypeViaAtom } from './response/ResponseMetaTypeV
134
138
  export { default as ResponseCreateToken } from './response/ResponseCreateToken'
135
139
  export { default as ResponseRequestTokens } from './response/ResponseRequestTokens'
136
140
 
141
+ // P-isotope and A-isotope Response classes
142
+ export { default as ResponsePeering } from './response/ResponsePeering'
143
+ export { default as ResponseAppendRequest } from './response/ResponseAppendRequest'
144
+
137
145
  // Phase 2 Tier 2 Priority 3: Essential Query Operations
138
146
  export { default as ResponseContinuId } from './response/ResponseContinuId'
139
147
  // QueryBatch uses base Response class directly
@@ -1,29 +1,138 @@
1
- /**
2
- * Rule class - Policy and rule management for KnishIO DLT
3
- * STUB IMPLEMENTATION - Full implementation pending
4
- */
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 Callback from './Callback'
50
+ import Condition from './Condition'
51
+ import RuleArgumentException from './exception/RuleArgumentException'
52
+ import { MetaMissingException } from '@/exception'
53
+
54
+ interface RuleParams {
55
+ condition?: Condition[]
56
+ callback?: Callback[]
57
+ }
58
+
59
+ interface RuleJSON {
60
+ condition: Condition[]
61
+ callback: Callback[]
62
+ }
63
+
5
64
  export default class Rule {
6
- public name: string
7
- public conditions: any[]
8
- public actions: any[]
9
-
10
- constructor(data: any = {}) {
11
- this.name = data.name || ''
12
- this.conditions = data.conditions || []
13
- this.actions = data.actions || []
65
+ private __condition: Condition[]
66
+ private __callback: Callback[]
67
+
68
+ constructor({ condition = [], callback = [] }: RuleParams) {
69
+ for (const element of condition) {
70
+ if (!(element instanceof Condition)) {
71
+ throw new RuleArgumentException()
72
+ }
73
+ }
74
+
75
+ for (const element of callback) {
76
+ if (!(element instanceof Callback)) {
77
+ throw new RuleArgumentException()
78
+ }
79
+ }
80
+
81
+ this.__condition = condition
82
+ this.__callback = callback
83
+ }
84
+
85
+ /**
86
+ * Adds a condition to this rule
87
+ */
88
+ set comparison(condition: Condition | Record<string, any>) {
89
+ this.__condition.push(
90
+ condition instanceof Condition ? condition : Condition.toObject(condition as any)
91
+ )
92
+ }
93
+
94
+ /**
95
+ * Adds a callback to this rule
96
+ */
97
+ set callback(callback: Callback | Record<string, any>) {
98
+ this.__callback.push(
99
+ callback instanceof Callback ? callback : Callback.toObject(callback as any)
100
+ )
14
101
  }
15
102
 
16
103
  /**
17
104
  * Convert rule data to Rule object
18
- * @param data - Rule data to convert
105
+ * @param object - Rule data to convert
19
106
  * @return Rule instance
20
107
  */
21
- static toObject(data: any): Rule {
22
- if (data instanceof Rule) {
23
- return data
108
+ static toObject(object: any): Rule {
109
+ if (!object.condition) {
110
+ throw new MetaMissingException('Rule::toObject() - Incorrect rule format! There is no condition field.')
111
+ }
112
+ if (!object.callback) {
113
+ throw new MetaMissingException('Rule::toObject() - Incorrect rule format! There is no callback field.')
114
+ }
115
+
116
+ const rule = new Rule({})
117
+
118
+ for (const condition of object.condition) {
119
+ rule.comparison = condition
24
120
  }
25
- return new Rule(data)
121
+
122
+ for (const callback of object.callback) {
123
+ rule.callback = callback
124
+ }
125
+
126
+ return rule
26
127
  }
27
128
 
28
- // TODO: Implement remaining Rule methods
29
- }
129
+ /**
130
+ * Converts to JSON representation
131
+ */
132
+ toJSON(): RuleJSON {
133
+ return {
134
+ condition: this.__condition,
135
+ callback: this.__callback
136
+ }
137
+ }
138
+ }
@@ -71,6 +71,7 @@ import Rule from '@/instance/rules/Rule'
71
71
  import { base64ToHex, chunkSubstr } from '@/libraries/strings'
72
72
  import { shake256 } from '@/libraries/crypto'
73
73
  import Dot from '@/libraries/Dot'
74
+ import Molecule from '@/core/Molecule'
74
75
 
75
76
  // Type definitions for Molecule structure
76
77
  interface MoleculeStructure {
@@ -461,7 +462,7 @@ export default class CheckMolecule {
461
462
  throw new TypeError('Invalid isotope "V" values')
462
463
  }
463
464
 
464
- const remainder = senderWallet.balance + firstValue
465
+ const remainder = Number(senderWallet.balance) + firstValue
465
466
 
466
467
  // Is there enough balance to send?
467
468
  if (remainder < 0) {
@@ -578,4 +579,90 @@ export default class CheckMolecule {
578
579
  // Looks like we passed all the tests!
579
580
  return true
580
581
  }
582
+
583
+ /**
584
+ * Reconstructs a Molecule instance from server-side GraphQL data.
585
+ * Maps server atom field names to SDK-expected format and parses metasJson.
586
+ */
587
+ static fromServerData({
588
+ molecularHash,
589
+ bundleHash,
590
+ cellSlug = null,
591
+ status = null,
592
+ createdAt = null,
593
+ atoms = []
594
+ }: {
595
+ molecularHash: string
596
+ bundleHash: string
597
+ cellSlug?: string | null
598
+ status?: string | null
599
+ createdAt?: string | null
600
+ atoms?: any[]
601
+ }): Molecule {
602
+ const mappedAtoms = atoms.map((serverAtom: any) => {
603
+ let meta: Array<{ key: string; value: string }> = []
604
+ if (serverAtom.metasJson) {
605
+ try {
606
+ const parsed = JSON.parse(serverAtom.metasJson)
607
+ if (Array.isArray(parsed)) {
608
+ meta = parsed
609
+ } else if (parsed && typeof parsed === 'object') {
610
+ meta = Object.entries(parsed).map(([key, value]) => ({ key, value: String(value) }))
611
+ }
612
+ } catch (e) {
613
+ meta = []
614
+ }
615
+ }
616
+
617
+ return {
618
+ position: serverAtom.position || null,
619
+ walletAddress: serverAtom.walletAddress || null,
620
+ isotope: serverAtom.isotope || null,
621
+ token: serverAtom.tokenSlug || serverAtom.token || null,
622
+ value: serverAtom.value != null ? String(serverAtom.value) : null,
623
+ batchId: serverAtom.batchId || null,
624
+ metaType: serverAtom.metaType || null,
625
+ metaId: serverAtom.metaId || null,
626
+ meta,
627
+ index: serverAtom.index != null ? serverAtom.index : null,
628
+ otsFragment: serverAtom.otsFragment || null,
629
+ createdAt: serverAtom.createdAt || null
630
+ }
631
+ })
632
+
633
+ return Molecule.fromJSON({
634
+ molecularHash,
635
+ bundle: bundleHash,
636
+ cellSlug,
637
+ status,
638
+ createdAt,
639
+ atoms: mappedAtoms
640
+ })
641
+ }
642
+
643
+ /**
644
+ * Verifies a molecule reconstructed from server-side GraphQL data.
645
+ * Returns an object with verification result and any error details.
646
+ */
647
+ static verifyFromServerData(moleculeData: any): {
648
+ molecularHash: string | null
649
+ verified: boolean
650
+ error: string | null
651
+ } {
652
+ try {
653
+ const molecule = CheckMolecule.fromServerData(moleculeData)
654
+ new CheckMolecule(molecule as unknown as MoleculeStructure).verify()
655
+ return {
656
+ molecularHash: moleculeData.molecularHash,
657
+ verified: true,
658
+ error: null
659
+ }
660
+ } catch (error) {
661
+ return {
662
+ molecularHash: moleculeData.molecularHash || null,
663
+ verified: false,
664
+ error: (error as Error).message || String(error)
665
+ }
666
+ }
667
+ }
581
668
  }
@@ -176,19 +176,15 @@ export function generateSecretEnhanced(options: SecretGenerationOptions): string
176
176
  * Generate bundle hash from secret - MUST produce identical results to JS SDK
177
177
  * Uses SHAKE256 with 256-bit output (64 hex characters)
178
178
  */
179
- export function generateBundleHash(secret: string, source: string | null = null): BundleHash {
179
+ export function generateBundleHash(secret: string, _source: string | null = null): BundleHash {
180
180
  if (!secret || secret.length === 0) {
181
181
  throw new Error('Secret is required for bundle hash generation')
182
182
  }
183
183
 
184
- let input = secret
185
- if (source) {
186
- input = secret + source
187
- }
188
-
189
- // Fix: BUNDLE_HASH_LENGTH is 64 (hex chars), but shake256 expects bits
190
- // So we multiply by 4: 64 hex chars * 4 = 256 bits (matching JS SDK)
191
- const hash = shake256(input, CRYPTO_CONSTANTS.BUNDLE_HASH_LENGTH * 4)
184
+ // CRITICAL: source parameter must be IGNORED to match JS SDK behavior.
185
+ // JS SDK's generateBundleHash() accepts source but never uses it.
186
+ // The bundle hash is an identity anchor and must be deterministic from secret alone.
187
+ const hash = shake256(secret, CRYPTO_CONSTANTS.BUNDLE_HASH_LENGTH * 4)
192
188
  return hash as BundleHash
193
189
  }
194
190
 
@@ -251,30 +247,18 @@ export function generatePositionEnhanced(options: PositionGenerationOptions = {}
251
247
  * Generate batch ID from molecular hash and index
252
248
  * Uses SHAKE256 to create deterministic batch identifiers
253
249
  */
254
- export function generateBatchId({
255
- molecularHash = null,
256
- index = null
257
- }: {
250
+ export function generateBatchId({
251
+ molecularHash = null,
252
+ index = null
253
+ }: {
258
254
  molecularHash?: string | null
259
- index?: number | null
255
+ index?: number | null
260
256
  } = {}): string {
261
- let input = ''
262
-
263
- if (molecularHash) {
264
- input += molecularHash
257
+ // Match JS SDK: require BOTH molecularHash AND index for deterministic batch ID
258
+ if (molecularHash && index !== null) {
259
+ return shake256(molecularHash + index, 256) // 256 bits = 64 hex chars
265
260
  }
266
-
267
- if (index !== null) {
268
- input += index.toString()
269
- }
270
-
271
- // If no input provided, generate random batch ID
272
- if (input === '') {
273
- input = randomString(32)
274
- }
275
-
276
- // Use SHAKE256 to generate 64-character batch ID
277
- return shake256(input, 64)
261
+ return randomString(64)
278
262
  }
279
263
 
280
264
  // =============================================================================
@@ -78,7 +78,7 @@ export function chunkSubstr(str: string, size: number): string[] {
78
78
  */
79
79
  export function randomString(
80
80
  length = 32,
81
- alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
81
+ alphabet = 'abcdef0123456789'
82
82
  ): string {
83
83
  if (length <= 0) return ''
84
84
 
@@ -108,7 +108,8 @@ export function randomString(
108
108
 
109
109
  /**
110
110
  * Convert between different character sets/bases
111
- * Ported from JavaScript SDK for cross-platform compatibility
111
+ * Uses BigInt for arbitrary-precision arithmetic to handle 256-bit hashes
112
+ * MUST match JavaScript SDK charsetBaseConvert exactly
112
113
  */
113
114
  export function charsetBaseConvert(
114
115
  src: string,
@@ -120,37 +121,37 @@ export function charsetBaseConvert(
120
121
  if (!src || fromBase < 2 || toBase < 2 || fromBase > srcSymbolTable.length || toBase > destSymbolTable.length) {
121
122
  return false
122
123
  }
123
-
124
+
124
125
  try {
125
- // Convert from source base to decimal
126
- let decimalValue = 0
127
- const srcLength = src.length
128
-
129
- for (let i = 0; i < srcLength; i++) {
130
- const char = src.charAt(srcLength - 1 - i)
131
- const charIndex = srcSymbolTable.indexOf(char)
132
-
133
- if (charIndex === -1) {
126
+ // Convert from source base to BigInt (arbitrary precision)
127
+ let val = BigInt(0)
128
+ const bigFromBase = BigInt(fromBase)
129
+
130
+ for (let charIndex = 0; charIndex < src.length; charIndex++) {
131
+ const symbolIndex = srcSymbolTable.indexOf(src.charAt(charIndex))
132
+
133
+ if (symbolIndex === -1) {
134
134
  return false // Invalid character for source base
135
135
  }
136
-
137
- decimalValue += charIndex * Math.pow(fromBase, i)
136
+
137
+ val = val * bigFromBase + BigInt(symbolIndex)
138
138
  }
139
-
140
- // Convert from decimal to destination base
141
- if (decimalValue === 0) {
139
+
140
+ // Convert from BigInt to destination base
141
+ if (val === BigInt(0)) {
142
142
  return destSymbolTable.charAt(0)
143
143
  }
144
-
144
+
145
+ const bigToBase = BigInt(toBase)
145
146
  let result = ''
146
- while (decimalValue > 0) {
147
- const remainder = decimalValue % toBase
148
- result = destSymbolTable.charAt(remainder) + result
149
- decimalValue = Math.floor(decimalValue / toBase)
147
+ while (val > BigInt(0)) {
148
+ const remainder = val % bigToBase
149
+ result = destSymbolTable.charAt(Number(remainder)) + result
150
+ val = val / bigToBase
150
151
  }
151
-
152
- return result
153
-
152
+
153
+ return result || '0'
154
+
154
155
  } catch (error) {
155
156
  return false
156
157
  }
@@ -0,0 +1,52 @@
1
+ /*
2
+ Powered by Knish.IO: Connecting a Decentralized World
3
+
4
+ Please visit https://github.com/WishKnish/KnishIO-Client-TS for information.
5
+
6
+ License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
7
+ */
8
+
9
+ import MutationProposeMolecule from './MutationProposeMolecule'
10
+ import ResponseAppendRequest from '../response/ResponseAppendRequest'
11
+
12
+ /**
13
+ * Mutation for submitting an append request via the A-isotope
14
+ * Matches JavaScript SDK MutationAppendRequest implementation exactly
15
+ */
16
+ export default class MutationAppendRequest extends MutationProposeMolecule {
17
+ /**
18
+ * Fills a molecule with an A-isotope append request atom
19
+ * Matches JavaScript SDK fillMolecule method exactly
20
+ */
21
+ override fillMolecule({
22
+ metaType,
23
+ metaId,
24
+ action,
25
+ meta = {}
26
+ }: {
27
+ metaType: string
28
+ metaId: string
29
+ action: string
30
+ meta?: Record<string, any>
31
+ }): void {
32
+ (this.$__molecule as any).initAppendRequest({
33
+ metaType,
34
+ metaId,
35
+ action,
36
+ meta
37
+ });
38
+ (this.$__molecule as any).sign({});
39
+ (this.$__molecule as any).check()
40
+ }
41
+
42
+ /**
43
+ * Builds a Response object out of a JSON object
44
+ * Matches JavaScript SDK createResponse method exactly
45
+ */
46
+ override createResponse(json: any): ResponseAppendRequest {
47
+ return new ResponseAppendRequest({
48
+ query: this,
49
+ json
50
+ })
51
+ }
52
+ }
@@ -65,8 +65,8 @@ export default class MutationCreateRule extends MutationProposeMolecule {
65
65
  }: {
66
66
  metaType: MetaType
67
67
  metaId: MetaId
68
- rule: Record<string, any>[]
69
- policy: Record<string, any>
68
+ rule: any[] | any // Accept single object or array
69
+ policy?: Record<string, any> | null
70
70
  }): void {
71
71
  (this.$__molecule as any).createRule({
72
72
  metaType,
@@ -0,0 +1,37 @@
1
+ /*
2
+ Powered by Knish.IO: Connecting a Decentralized World
3
+
4
+ Please visit https://github.com/WishKnish/KnishIO-Client-TS for information.
5
+
6
+ License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
7
+ */
8
+
9
+ import MutationProposeMolecule from './MutationProposeMolecule'
10
+ import ResponsePeering from '../response/ResponsePeering'
11
+
12
+ /**
13
+ * Mutation for registering a peer node via the P-isotope
14
+ * Matches JavaScript SDK MutationPeering implementation exactly
15
+ */
16
+ export default class MutationPeering extends MutationProposeMolecule {
17
+ /**
18
+ * Fills a molecule with a P-isotope peering atom
19
+ * Matches JavaScript SDK fillMolecule method exactly
20
+ */
21
+ override fillMolecule({ host }: { host: string }): void {
22
+ (this.$__molecule as any).initPeering({ host });
23
+ (this.$__molecule as any).sign({});
24
+ (this.$__molecule as any).check()
25
+ }
26
+
27
+ /**
28
+ * Builds a Response object out of a JSON object
29
+ * Matches JavaScript SDK createResponse method exactly
30
+ */
31
+ override createResponse(json: any): ResponsePeering {
32
+ return new ResponsePeering({
33
+ query: this,
34
+ json
35
+ })
36
+ }
37
+ }
@@ -59,9 +59,9 @@ export default class MutationRequestAuthorization extends MutationProposeMolecul
59
59
  * Matches JavaScript SDK fillMolecule method exactly
60
60
  */
61
61
  override fillMolecule({ meta }: { meta: any }): void {
62
- (this.$__molecule as any).initAuthorization({ meta });
63
- (this.$__molecule as any).sign({});
64
- (this.$__molecule as any).check()
62
+ this.$__molecule.initAuthorization({ meta })
63
+ this.$__molecule.sign({})
64
+ this.$__molecule.check()
65
65
  }
66
66
 
67
67
  /**
@@ -71,7 +71,6 @@ export default class QueryActiveSession extends Query {
71
71
  metaId
72
72
  jsonData
73
73
  createdAt
74
- updatedAt
75
74
  }
76
75
  }
77
76
  `
@@ -79,6 +79,14 @@ export default class QueryContinuId extends Query {
79
79
  }`
80
80
  }
81
81
 
82
+ /**
83
+ * Force network-only for ContinuID queries to prevent URQL cache from
84
+ * returning stale wallet positions after mutations advance the ContinuID chain
85
+ */
86
+ override createQueryContext(): Record<string, any> {
87
+ return { requestPolicy: 'network-only' }
88
+ }
89
+
82
90
  /**
83
91
  * Returns a Response object
84
92
  * Matches JavaScript SDK createResponse method exactly