@wishknish/knishio-client-js 0.7.4 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs.js +90 -28
- package/dist/client.cjs.js.map +1 -1
- package/dist/client.es.mjs +1680 -892
- package/dist/client.es.mjs.map +1 -1
- package/dist/client.iife.js +90 -28
- package/dist/client.iife.js.map +1 -1
- package/package.json +1 -1
- package/src/KnishIOClient.js +74 -13
- package/src/Molecule.js +102 -14
- package/src/Wallet.js +48 -1
- package/src/index.js +233 -9
- package/src/libraries/CheckMolecule.js +211 -5
- package/src/query/QueryContinuId.js +8 -0
- package/src/query/QueryMetaTypeViaMolecule.js +223 -0
- package/src/query/QueryWalletList.js +2 -2
- package/src/response/ResponseContinuId.js +1 -1
- package/src/response/ResponseMetaTypeViaMolecule.js +210 -0
- package/src/response/ResponseRequestAuthorization.js +34 -1
- package/src/response/ResponseRequestAuthorizationGuest.js +32 -1
- package/src/response/ResponseWalletList.js +1 -1
package/package.json
CHANGED
package/src/KnishIOClient.js
CHANGED
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
} from './libraries/crypto.js'
|
|
55
55
|
import Molecule from './Molecule.js'
|
|
56
56
|
import Wallet from './Wallet.js'
|
|
57
|
+
import TokenUnit from './TokenUnit.js'
|
|
57
58
|
import AuthToken from './AuthToken.js'
|
|
58
59
|
import QueryContinuId from './query/QueryContinuId.js'
|
|
59
60
|
import QueryWalletBundle from './query/QueryWalletBundle.js'
|
|
@@ -72,6 +73,7 @@ import MutationClaimShadowWallet from './mutation/MutationClaimShadowWallet.js'
|
|
|
72
73
|
import MutationCreateMeta from './mutation/MutationCreateMeta.js'
|
|
73
74
|
import MutationPeering from './mutation/MutationPeering.js'
|
|
74
75
|
import MutationAppendRequest from './mutation/MutationAppendRequest.js'
|
|
76
|
+
import MutationLinkIdentifier from './mutation/MutationLinkIdentifier.js'
|
|
75
77
|
import MutationCreateWallet from './mutation/MutationCreateWallet.js'
|
|
76
78
|
import MutationRequestAuthorizationGuest from './mutation/MutationRequestAuthorizationGuest.js'
|
|
77
79
|
import TransferBalanceException from './exception/TransferBalanceException.js'
|
|
@@ -93,6 +95,7 @@ import AuthorizationRejectedException from './exception/AuthorizationRejectedExc
|
|
|
93
95
|
import QueryAtom from './query/QueryAtom.js'
|
|
94
96
|
import QueryPolicy from './query/QueryPolicy.js'
|
|
95
97
|
import QueryMetaTypeViaAtom from './query/QueryMetaTypeViaAtom.js'
|
|
98
|
+
import QueryMetaTypeViaMolecule from './query/QueryMetaTypeViaMolecule.js'
|
|
96
99
|
import MutationCreateRule from './mutation/MutationCreateRule.js'
|
|
97
100
|
import MutationDepositBufferToken from './mutation/MutationDepositBufferToken.js'
|
|
98
101
|
import MutationWithdrawBufferToken from './mutation/MutationWithdrawBufferToken.js'
|
|
@@ -777,10 +780,11 @@ export default class KnishIOClient {
|
|
|
777
780
|
* @param {string|null} count
|
|
778
781
|
* @param {string|null} countBy
|
|
779
782
|
* @param {boolean} throughAtom
|
|
783
|
+
* @param {boolean} throughMolecule
|
|
780
784
|
* @param {array|null} values
|
|
781
785
|
* @param {array|null} keys
|
|
782
786
|
* @param {array|null} atomValues
|
|
783
|
-
* @return {Promise<ResponseMetaType>}
|
|
787
|
+
* @return {Promise<ResponseMetaType|ResponseMetaTypeViaAtom|ResponseMetaTypeViaMolecule>}
|
|
784
788
|
*/
|
|
785
789
|
queryMeta ({
|
|
786
790
|
metaType,
|
|
@@ -794,6 +798,7 @@ export default class KnishIOClient {
|
|
|
794
798
|
count = null,
|
|
795
799
|
countBy = null,
|
|
796
800
|
throughAtom = true,
|
|
801
|
+
throughMolecule = false,
|
|
797
802
|
values = null,
|
|
798
803
|
keys = null,
|
|
799
804
|
atomValues = null
|
|
@@ -803,7 +808,26 @@ export default class KnishIOClient {
|
|
|
803
808
|
let query
|
|
804
809
|
let variables
|
|
805
810
|
|
|
806
|
-
if (
|
|
811
|
+
if (throughMolecule) {
|
|
812
|
+
/**
|
|
813
|
+
* @type {QueryMetaTypeViaMolecule}
|
|
814
|
+
*/
|
|
815
|
+
query = this.createQuery(QueryMetaTypeViaMolecule)
|
|
816
|
+
variables = QueryMetaTypeViaMolecule.createVariables({
|
|
817
|
+
metaType,
|
|
818
|
+
metaId,
|
|
819
|
+
key,
|
|
820
|
+
value,
|
|
821
|
+
latest,
|
|
822
|
+
filter,
|
|
823
|
+
queryArgs,
|
|
824
|
+
countBy,
|
|
825
|
+
values,
|
|
826
|
+
keys,
|
|
827
|
+
atomValues,
|
|
828
|
+
cellSlug: this.getCellSlug()
|
|
829
|
+
})
|
|
830
|
+
} else if (throughAtom) {
|
|
807
831
|
/**
|
|
808
832
|
* @type {QueryMetaTypeViaAtom}
|
|
809
833
|
*/
|
|
@@ -844,6 +868,23 @@ export default class KnishIOClient {
|
|
|
844
868
|
return this.executeQuery(query, variables)
|
|
845
869
|
}
|
|
846
870
|
|
|
871
|
+
/**
|
|
872
|
+
* Queries meta assets and verifies cryptographic integrity of associated molecules.
|
|
873
|
+
* Returns the same response as queryMeta(), with an additional `integrity` field on the payload
|
|
874
|
+
* containing verification results for each molecule.
|
|
875
|
+
*
|
|
876
|
+
* @param {object} params - Same parameters as queryMeta()
|
|
877
|
+
* @return {Promise<ResponseMetaType|ResponseMetaTypeViaAtom|ResponseMetaTypeViaMolecule>}
|
|
878
|
+
*/
|
|
879
|
+
async queryMetaVerified (params) {
|
|
880
|
+
const response = await this.queryMeta(params)
|
|
881
|
+
const payload = response.payload()
|
|
882
|
+
if (payload) {
|
|
883
|
+
payload.integrity = response.verifyIntegrity()
|
|
884
|
+
}
|
|
885
|
+
return response
|
|
886
|
+
}
|
|
887
|
+
|
|
847
888
|
/**
|
|
848
889
|
* Query batch to get cascading meta instances by batchID
|
|
849
890
|
*
|
|
@@ -1208,8 +1249,7 @@ export default class KnishIOClient {
|
|
|
1208
1249
|
const query = await this.createMoleculeMutation({
|
|
1209
1250
|
mutationClass: MutationCreateRule,
|
|
1210
1251
|
molecule: await this.createMolecule({
|
|
1211
|
-
secret: this.getSecret()
|
|
1212
|
-
sourceWallet: await this.getSourceWallet()
|
|
1252
|
+
secret: this.getSecret()
|
|
1213
1253
|
})
|
|
1214
1254
|
}
|
|
1215
1255
|
)
|
|
@@ -1245,8 +1285,7 @@ export default class KnishIOClient {
|
|
|
1245
1285
|
const query = await this.createMoleculeMutation({
|
|
1246
1286
|
mutationClass: MutationCreateMeta,
|
|
1247
1287
|
molecule: await this.createMolecule({
|
|
1248
|
-
secret: this.getSecret()
|
|
1249
|
-
sourceWallet: await this.getSourceWallet()
|
|
1288
|
+
secret: this.getSecret()
|
|
1250
1289
|
})
|
|
1251
1290
|
}
|
|
1252
1291
|
)
|
|
@@ -1278,8 +1317,7 @@ export default class KnishIOClient {
|
|
|
1278
1317
|
const query = await this.createMoleculeMutation({
|
|
1279
1318
|
mutationClass: MutationPeering,
|
|
1280
1319
|
molecule: await this.createMolecule({
|
|
1281
|
-
secret: this.getSecret()
|
|
1282
|
-
sourceWallet: await this.getSourceWallet()
|
|
1320
|
+
secret: this.getSecret()
|
|
1283
1321
|
})
|
|
1284
1322
|
})
|
|
1285
1323
|
|
|
@@ -1311,8 +1349,7 @@ export default class KnishIOClient {
|
|
|
1311
1349
|
const query = await this.createMoleculeMutation({
|
|
1312
1350
|
mutationClass: MutationAppendRequest,
|
|
1313
1351
|
molecule: await this.createMolecule({
|
|
1314
|
-
secret: this.getSecret()
|
|
1315
|
-
sourceWallet: await this.getSourceWallet()
|
|
1352
|
+
secret: this.getSecret()
|
|
1316
1353
|
})
|
|
1317
1354
|
})
|
|
1318
1355
|
|
|
@@ -1355,6 +1392,25 @@ export default class KnishIOClient {
|
|
|
1355
1392
|
return await this.executeQuery(query)
|
|
1356
1393
|
}
|
|
1357
1394
|
|
|
1395
|
+
/**
|
|
1396
|
+
* Links an identifier to the current wallet bundle
|
|
1397
|
+
*
|
|
1398
|
+
* @param {string} type - The type of the identifier.
|
|
1399
|
+
* @param {string} contact - The contact associated with the identifier.
|
|
1400
|
+
* @returns {Promise<ResponseLinkIdentifier>} - A promise that resolves to the link result.
|
|
1401
|
+
*/
|
|
1402
|
+
async linkIdentifier ({
|
|
1403
|
+
type,
|
|
1404
|
+
contact
|
|
1405
|
+
}) {
|
|
1406
|
+
const query = this.createQuery(MutationLinkIdentifier)
|
|
1407
|
+
return await this.executeQuery(query, {
|
|
1408
|
+
bundle: this.getBundle(),
|
|
1409
|
+
type,
|
|
1410
|
+
content: contact
|
|
1411
|
+
})
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1358
1414
|
/**
|
|
1359
1415
|
* Creates a policy for a given metaType and metaId.
|
|
1360
1416
|
*
|
|
@@ -1433,7 +1489,7 @@ export default class KnishIOClient {
|
|
|
1433
1489
|
|
|
1434
1490
|
return this.executeQuery(walletQuery, {
|
|
1435
1491
|
bundleHash: bundle || this.getBundle(),
|
|
1436
|
-
|
|
1492
|
+
token,
|
|
1437
1493
|
unspent
|
|
1438
1494
|
})
|
|
1439
1495
|
.then((response) => {
|
|
@@ -2022,6 +2078,11 @@ export default class KnishIOClient {
|
|
|
2022
2078
|
// Split token units (fused)
|
|
2023
2079
|
sourceWallet.splitUnits(fusedTokenUnitIds, remainderWallet)
|
|
2024
2080
|
|
|
2081
|
+
// Coerce string newTokenUnit to TokenUnit object
|
|
2082
|
+
if (typeof newTokenUnit === 'string') {
|
|
2083
|
+
newTokenUnit = new TokenUnit(newTokenUnit, newTokenUnit, {})
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2025
2086
|
// Set recipient new fused token unit
|
|
2026
2087
|
newTokenUnit.metas.fusedTokenUnits = sourceWallet.getTokenUnitsData()
|
|
2027
2088
|
recipientWallet.tokenUnits = [newTokenUnit]
|
|
@@ -2086,7 +2147,7 @@ export default class KnishIOClient {
|
|
|
2086
2147
|
// Map server payload field names (time/key) to AuthToken constructor names (expiresAt/pubkey)
|
|
2087
2148
|
const authToken = AuthToken.create({
|
|
2088
2149
|
token: response.token(),
|
|
2089
|
-
expiresAt: response.
|
|
2150
|
+
expiresAt: response.expiresAt(),
|
|
2090
2151
|
pubkey: response.pubKey(),
|
|
2091
2152
|
encrypt: response.encrypt()
|
|
2092
2153
|
}, wallet)
|
|
@@ -2143,7 +2204,7 @@ export default class KnishIOClient {
|
|
|
2143
2204
|
// Map server payload field names (time/key) to AuthToken constructor names (expiresAt/pubkey)
|
|
2144
2205
|
const authToken = AuthToken.create({
|
|
2145
2206
|
token: response.token(),
|
|
2146
|
-
expiresAt: response.
|
|
2207
|
+
expiresAt: response.expiresAt(),
|
|
2147
2208
|
pubkey: response.pubKey(),
|
|
2148
2209
|
encrypt: response.encrypt()
|
|
2149
2210
|
}, wallet)
|
package/src/Molecule.js
CHANGED
|
@@ -96,6 +96,7 @@ export default class Molecule {
|
|
|
96
96
|
this.bundle = bundle
|
|
97
97
|
this.sourceWallet = sourceWallet
|
|
98
98
|
this.atoms = []
|
|
99
|
+
this.parentHashes = []
|
|
99
100
|
if (version !== null && Object.prototype.hasOwnProperty.call(versions, version)) {
|
|
100
101
|
this.version = String(version)
|
|
101
102
|
}
|
|
@@ -112,6 +113,17 @@ export default class Molecule {
|
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Sets parent molecular hashes for DAG linkage
|
|
118
|
+
*
|
|
119
|
+
* @param {string[]} hashes - Array of parent molecular hash strings
|
|
120
|
+
* @return {Molecule} this instance for chaining
|
|
121
|
+
*/
|
|
122
|
+
withParentHashes (hashes) {
|
|
123
|
+
this.parentHashes = Array.isArray(hashes) ? [...hashes] : []
|
|
124
|
+
return this
|
|
125
|
+
}
|
|
126
|
+
|
|
115
127
|
/**
|
|
116
128
|
* Returns the cell slug delimiter
|
|
117
129
|
*
|
|
@@ -327,20 +339,21 @@ export default class Molecule {
|
|
|
327
339
|
})
|
|
328
340
|
}
|
|
329
341
|
|
|
330
|
-
//
|
|
342
|
+
// ContinuID metadata for chain integrity validation (matching Rust SDK GAP-07-002).
|
|
343
|
+
// These are atom meta fields (not core fields), so they don't affect molecular hash.
|
|
331
344
|
const continuIdMeta = {}
|
|
332
345
|
|
|
333
|
-
// previousPosition: source wallet position being consumed
|
|
346
|
+
// previousPosition: the source wallet's position being consumed
|
|
334
347
|
if (this.sourceWallet && this.sourceWallet.position) {
|
|
335
348
|
continuIdMeta.previousPosition = this.sourceWallet.position
|
|
336
349
|
}
|
|
337
350
|
|
|
338
|
-
// pubkey:
|
|
351
|
+
// pubkey: ML-KEM public key for encrypted communication
|
|
339
352
|
if (this.remainderWallet.pubkey) {
|
|
340
353
|
continuIdMeta.pubkey = this.remainderWallet.pubkey
|
|
341
354
|
}
|
|
342
355
|
|
|
343
|
-
// characters: encoding format
|
|
356
|
+
// characters: encoding format for the wallet
|
|
344
357
|
if (this.remainderWallet.characters) {
|
|
345
358
|
continuIdMeta.characters = this.remainderWallet.characters
|
|
346
359
|
}
|
|
@@ -493,28 +506,28 @@ export default class Molecule {
|
|
|
493
506
|
for (const unit of units) {
|
|
494
507
|
this.remainderWallet.tokenUnits.push(unit)
|
|
495
508
|
}
|
|
496
|
-
this.remainderWallet.balance = this.remainderWallet.tokenUnits.length
|
|
509
|
+
this.remainderWallet.balance = String(this.remainderWallet.tokenUnits.length)
|
|
497
510
|
|
|
498
511
|
// Override first atom's token units to replenish values
|
|
499
512
|
this.sourceWallet.tokenUnits = units
|
|
500
|
-
this.sourceWallet.balance = this.sourceWallet.tokenUnits.length
|
|
513
|
+
this.sourceWallet.balance = String(this.sourceWallet.tokenUnits.length)
|
|
501
514
|
} else {
|
|
502
515
|
// Update wallet's balances
|
|
503
|
-
this.remainderWallet.balance = this.sourceWallet.balance + amount
|
|
504
|
-
this.sourceWallet.balance = amount
|
|
516
|
+
this.remainderWallet.balance = String(Number(this.sourceWallet.balance) + amount)
|
|
517
|
+
this.sourceWallet.balance = String(amount)
|
|
505
518
|
}
|
|
506
519
|
|
|
507
520
|
// Initializing a new Atom to remove tokens from source
|
|
508
521
|
this.addAtom(Atom.create({
|
|
509
522
|
isotope: 'V',
|
|
510
523
|
wallet: this.sourceWallet,
|
|
511
|
-
value: this.sourceWallet.balance
|
|
524
|
+
value: Number(this.sourceWallet.balance)
|
|
512
525
|
}))
|
|
513
526
|
|
|
514
527
|
this.addAtom(Atom.create({
|
|
515
528
|
isotope: 'V',
|
|
516
529
|
wallet: this.remainderWallet,
|
|
517
|
-
value: this.remainderWallet.balance,
|
|
530
|
+
value: Number(this.remainderWallet.balance),
|
|
518
531
|
metaType: 'walletBundle',
|
|
519
532
|
metaId: this.remainderWallet.bundle
|
|
520
533
|
}))
|
|
@@ -564,6 +577,60 @@ export default class Molecule {
|
|
|
564
577
|
return this
|
|
565
578
|
}
|
|
566
579
|
|
|
580
|
+
/**
|
|
581
|
+
* Creates a stackable V-isotope transfer with 3 atoms:
|
|
582
|
+
* source debit, recipient credit, remainder.
|
|
583
|
+
* Propagates batchId from source wallet.
|
|
584
|
+
*
|
|
585
|
+
* @param {Wallet} recipientWallet - wallet receiving the tokens
|
|
586
|
+
* @param {number} amount - amount to transfer
|
|
587
|
+
* @return {Molecule}
|
|
588
|
+
*/
|
|
589
|
+
addStackableTransfer ({
|
|
590
|
+
recipientWallet,
|
|
591
|
+
amount
|
|
592
|
+
}) {
|
|
593
|
+
if (amount <= 0) {
|
|
594
|
+
throw new NegativeAmountException('Molecule::addStackableTransfer() - Amount must be positive!')
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (this.sourceWallet.balance - amount < 0) {
|
|
598
|
+
throw new BalanceInsufficientException()
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const batchId = this.sourceWallet.batchId || generateBatchId({})
|
|
602
|
+
|
|
603
|
+
// Source debit atom
|
|
604
|
+
this.addAtom(Atom.create({
|
|
605
|
+
isotope: 'V',
|
|
606
|
+
wallet: this.sourceWallet,
|
|
607
|
+
value: -amount,
|
|
608
|
+
batchId
|
|
609
|
+
}))
|
|
610
|
+
|
|
611
|
+
// Recipient credit atom
|
|
612
|
+
this.addAtom(Atom.create({
|
|
613
|
+
isotope: 'V',
|
|
614
|
+
wallet: recipientWallet,
|
|
615
|
+
value: amount,
|
|
616
|
+
metaType: 'walletBundle',
|
|
617
|
+
metaId: recipientWallet.bundle,
|
|
618
|
+
batchId: generateBatchId({})
|
|
619
|
+
}))
|
|
620
|
+
|
|
621
|
+
// Remainder atom
|
|
622
|
+
this.addAtom(Atom.create({
|
|
623
|
+
isotope: 'V',
|
|
624
|
+
wallet: this.remainderWallet,
|
|
625
|
+
value: this.sourceWallet.balance - amount,
|
|
626
|
+
metaType: 'walletBundle',
|
|
627
|
+
metaId: this.remainderWallet.bundle,
|
|
628
|
+
batchId
|
|
629
|
+
}))
|
|
630
|
+
|
|
631
|
+
return this
|
|
632
|
+
}
|
|
633
|
+
|
|
567
634
|
/**
|
|
568
635
|
*
|
|
569
636
|
* @param amount
|
|
@@ -1053,6 +1120,20 @@ export default class Molecule {
|
|
|
1053
1120
|
return lastPosition
|
|
1054
1121
|
}
|
|
1055
1122
|
|
|
1123
|
+
/**
|
|
1124
|
+
* Synchronous signing — identical to sign() since all operations are CPU-bound.
|
|
1125
|
+
* Provided for API parity with Rust SDK's sign_sync().
|
|
1126
|
+
*
|
|
1127
|
+
* @param {object} options
|
|
1128
|
+
* @param {string|null} options.bundle
|
|
1129
|
+
* @param {boolean} options.anonymous
|
|
1130
|
+
* @param {boolean} options.compressed
|
|
1131
|
+
* @return {string|null}
|
|
1132
|
+
*/
|
|
1133
|
+
signSync (options = {}) {
|
|
1134
|
+
return this.sign(options)
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1056
1137
|
/**
|
|
1057
1138
|
* Returns the base cell slug portion
|
|
1058
1139
|
*
|
|
@@ -1096,6 +1177,12 @@ export default class Molecule {
|
|
|
1096
1177
|
}))
|
|
1097
1178
|
};
|
|
1098
1179
|
|
|
1180
|
+
// Parent molecular hashes for DAG linkage (only include when non-empty
|
|
1181
|
+
// to maintain backward compatibility with servers that don't support it)
|
|
1182
|
+
if (this.parentHashes && this.parentHashes.length > 0) {
|
|
1183
|
+
serialized.parentHashes = this.parentHashes
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1099
1186
|
// Extended context for Rust validator and local validation
|
|
1100
1187
|
if (includeValidationContext) {
|
|
1101
1188
|
serialized.cellSlugOrigin = this.cellSlugOrigin
|
|
@@ -1106,7 +1193,7 @@ export default class Molecule {
|
|
|
1106
1193
|
address: this.sourceWallet.address,
|
|
1107
1194
|
position: this.sourceWallet.position,
|
|
1108
1195
|
token: this.sourceWallet.token,
|
|
1109
|
-
balance: this.sourceWallet.balance || 0,
|
|
1196
|
+
balance: this.sourceWallet.balance || '0',
|
|
1110
1197
|
bundle: this.sourceWallet.bundle,
|
|
1111
1198
|
batchId: this.sourceWallet.batchId || null,
|
|
1112
1199
|
characters: this.sourceWallet.characters || 'BASE64',
|
|
@@ -1122,7 +1209,7 @@ export default class Molecule {
|
|
|
1122
1209
|
address: this.remainderWallet.address,
|
|
1123
1210
|
position: this.remainderWallet.position,
|
|
1124
1211
|
token: this.remainderWallet.token,
|
|
1125
|
-
balance: this.remainderWallet.balance || 0,
|
|
1212
|
+
balance: this.remainderWallet.balance || '0',
|
|
1126
1213
|
bundle: this.remainderWallet.bundle,
|
|
1127
1214
|
batchId: this.remainderWallet.batchId || null,
|
|
1128
1215
|
characters: this.remainderWallet.characters || 'BASE64',
|
|
@@ -1184,6 +1271,7 @@ export default class Molecule {
|
|
|
1184
1271
|
molecule.molecularHash = data.molecularHash;
|
|
1185
1272
|
molecule.createdAt = data.createdAt || String(+new Date());
|
|
1186
1273
|
molecule.cellSlugOrigin = data.cellSlugOrigin;
|
|
1274
|
+
molecule.parentHashes = Array.isArray(data.parentHashes) ? [...data.parentHashes] : [];
|
|
1187
1275
|
|
|
1188
1276
|
// Reconstruct atoms array with proper Atom instances
|
|
1189
1277
|
if (Array.isArray(data.atoms)) {
|
|
@@ -1210,7 +1298,7 @@ export default class Molecule {
|
|
|
1210
1298
|
});
|
|
1211
1299
|
|
|
1212
1300
|
// Set additional properties for validation context
|
|
1213
|
-
molecule.sourceWallet.balance = data.sourceWallet.balance
|
|
1301
|
+
molecule.sourceWallet.balance = String(data.sourceWallet.balance != null ? data.sourceWallet.balance : 0);
|
|
1214
1302
|
molecule.sourceWallet.address = data.sourceWallet.address;
|
|
1215
1303
|
if (data.sourceWallet.pubkey) {
|
|
1216
1304
|
molecule.sourceWallet.pubkey = data.sourceWallet.pubkey;
|
|
@@ -1232,7 +1320,7 @@ export default class Molecule {
|
|
|
1232
1320
|
});
|
|
1233
1321
|
|
|
1234
1322
|
// Set additional properties for validation context
|
|
1235
|
-
molecule.remainderWallet.balance = data.remainderWallet.balance
|
|
1323
|
+
molecule.remainderWallet.balance = String(data.remainderWallet.balance != null ? data.remainderWallet.balance : 0);
|
|
1236
1324
|
molecule.remainderWallet.address = data.remainderWallet.address;
|
|
1237
1325
|
if (data.remainderWallet.pubkey) {
|
|
1238
1326
|
molecule.remainderWallet.pubkey = data.remainderWallet.pubkey;
|
package/src/Wallet.js
CHANGED
|
@@ -87,7 +87,7 @@ export default class Wallet {
|
|
|
87
87
|
characters = null
|
|
88
88
|
}) {
|
|
89
89
|
this.token = token
|
|
90
|
-
this.balance = 0
|
|
90
|
+
this.balance = '0'
|
|
91
91
|
this.molecules = {}
|
|
92
92
|
|
|
93
93
|
// Empty values
|
|
@@ -208,6 +208,13 @@ export default class Wallet {
|
|
|
208
208
|
token,
|
|
209
209
|
position
|
|
210
210
|
}) {
|
|
211
|
+
if (!secret) {
|
|
212
|
+
throw new WalletCredentialException('Wallet::generateKey() - Secret is required!')
|
|
213
|
+
}
|
|
214
|
+
if (!position) {
|
|
215
|
+
throw new WalletCredentialException('Wallet::generateKey() - Position is required!')
|
|
216
|
+
}
|
|
217
|
+
|
|
211
218
|
// Normalize non-hex secret via SHAKE256 (matching Rust/Kotlin behavior)
|
|
212
219
|
const secretHex = isHex(secret) ? secret : shake256(secret, 1024)
|
|
213
220
|
// Normalize non-hex position via SHAKE256
|
|
@@ -301,6 +308,46 @@ export default class Wallet {
|
|
|
301
308
|
return new Uint8Array(binaryString.length).map((_, i) => binaryString.charCodeAt(i))
|
|
302
309
|
}
|
|
303
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Returns balance as a Number for arithmetic operations.
|
|
313
|
+
* WARNING: Precision loss for values > 2^53.
|
|
314
|
+
*
|
|
315
|
+
* @return {number}
|
|
316
|
+
*/
|
|
317
|
+
balanceAsNumber () {
|
|
318
|
+
return Number(this.balance)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Returns balance as a BigInt for precision-safe integer arithmetic.
|
|
323
|
+
* Truncates any fractional component.
|
|
324
|
+
*
|
|
325
|
+
* @return {bigint}
|
|
326
|
+
*/
|
|
327
|
+
balanceAsBigInt () {
|
|
328
|
+
const str = String(this.balance)
|
|
329
|
+
const intPart = str.includes('.') ? str.split('.')[0] : str
|
|
330
|
+
return BigInt(intPart || '0')
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Sets balance from a BigInt value
|
|
335
|
+
*
|
|
336
|
+
* @param {bigint} value
|
|
337
|
+
*/
|
|
338
|
+
setBalanceBigInt (value) {
|
|
339
|
+
this.balance = value.toString()
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Sets balance from a Number value, storing as String
|
|
344
|
+
*
|
|
345
|
+
* @param {number} value
|
|
346
|
+
*/
|
|
347
|
+
setBalanceNumber (value) {
|
|
348
|
+
this.balance = String(value)
|
|
349
|
+
}
|
|
350
|
+
|
|
304
351
|
/**
|
|
305
352
|
*
|
|
306
353
|
* @returns {*[]}
|