@wishknish/knishio-client-ts 0.9.2 → 0.9.4
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/index.cjs +173 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.iife.js +3463 -339
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +173 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/Wallet.ts +21 -2
- package/src/libraries/CheckMolecule.ts +194 -4
- package/src/libraries/array.ts +6 -4
- package/src/libraries/strings.ts +12 -7
package/dist/index.js
CHANGED
|
@@ -1843,11 +1843,15 @@ function hexToBase64(hexString) {
|
|
|
1843
1843
|
try {
|
|
1844
1844
|
const cleanHex = hexString.replace(/^0x/i, "");
|
|
1845
1845
|
const bytes = hexStringToBuffer(cleanHex);
|
|
1846
|
-
if (typeof
|
|
1847
|
-
return btoa(String.fromCharCode(...bytes));
|
|
1848
|
-
} else {
|
|
1846
|
+
if (typeof Buffer !== "undefined") {
|
|
1849
1847
|
return Buffer.from(bytes).toString("base64");
|
|
1850
1848
|
}
|
|
1849
|
+
let binary = "";
|
|
1850
|
+
const CHUNK_SIZE = 32768;
|
|
1851
|
+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
1852
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK_SIZE));
|
|
1853
|
+
}
|
|
1854
|
+
return btoa(binary);
|
|
1851
1855
|
} catch (error) {
|
|
1852
1856
|
throw new Error(`Failed to convert hex to base64: ${error instanceof Error ? error.message : String(error)}`);
|
|
1853
1857
|
}
|
|
@@ -3805,11 +3809,26 @@ var Wallet = class _Wallet {
|
|
|
3805
3809
|
return new Uint8Array(decryptedContent);
|
|
3806
3810
|
}
|
|
3807
3811
|
serializeKey(key) {
|
|
3808
|
-
|
|
3812
|
+
if (typeof Buffer !== "undefined") {
|
|
3813
|
+
return Buffer.from(key).toString("base64");
|
|
3814
|
+
}
|
|
3815
|
+
let binary = "";
|
|
3816
|
+
const CHUNK_SIZE = 32768;
|
|
3817
|
+
for (let i = 0; i < key.length; i += CHUNK_SIZE) {
|
|
3818
|
+
binary += String.fromCharCode(...key.subarray(i, i + CHUNK_SIZE));
|
|
3819
|
+
}
|
|
3820
|
+
return btoa(binary);
|
|
3809
3821
|
}
|
|
3810
3822
|
deserializeKey(serializedKey) {
|
|
3823
|
+
if (typeof Buffer !== "undefined") {
|
|
3824
|
+
return new Uint8Array(Buffer.from(serializedKey, "base64"));
|
|
3825
|
+
}
|
|
3811
3826
|
const binaryString = atob(serializedKey);
|
|
3812
|
-
|
|
3827
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
3828
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
3829
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3830
|
+
}
|
|
3831
|
+
return bytes;
|
|
3813
3832
|
}
|
|
3814
3833
|
};
|
|
3815
3834
|
var hexStringRegex = /^[0-9a-fA-F]+$/;
|
|
@@ -4176,10 +4195,11 @@ function deepCloning(o, h) {
|
|
|
4176
4195
|
return r || o;
|
|
4177
4196
|
}
|
|
4178
4197
|
function chunkArray(arr, size) {
|
|
4179
|
-
|
|
4180
|
-
|
|
4198
|
+
const chunks = [];
|
|
4199
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
4200
|
+
chunks.push(arr.slice(i, i + size));
|
|
4181
4201
|
}
|
|
4182
|
-
return
|
|
4202
|
+
return chunks;
|
|
4183
4203
|
}
|
|
4184
4204
|
function diff(...arrays) {
|
|
4185
4205
|
return [].concat(...arrays.map((arr, i) => {
|
|
@@ -4467,7 +4487,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4467
4487
|
* @return True if all validations pass
|
|
4468
4488
|
*/
|
|
4469
4489
|
verify(senderWallet) {
|
|
4470
|
-
return this.molecularHash() && this.ots() && this.batchId() && this.continuId() && this.isotopeM() && this.isotopeT() && this.isotopeC() && this.isotopeU() && this.isotopeI() && this.isotopeR() && this.isotopeV(senderWallet || null);
|
|
4490
|
+
return this.molecularHash() && this.ots() && this.batchId() && this.continuId() && this.isotopeM() && this.isotopeT() && this.isotopeC() && this.isotopeU() && this.isotopeI() && this.isotopeR() && this.isotopeP() && this.isotopeA() && this.isotopeB() && this.isotopeF() && this.isotopeV(senderWallet || null);
|
|
4471
4491
|
}
|
|
4472
4492
|
/**
|
|
4473
4493
|
* Validate ContinuID requirement
|
|
@@ -4655,6 +4675,141 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4655
4675
|
}
|
|
4656
4676
|
return true;
|
|
4657
4677
|
}
|
|
4678
|
+
/**
|
|
4679
|
+
* Validate isotope P atoms (peering)
|
|
4680
|
+
* @return True if valid
|
|
4681
|
+
* @throws WrongTokenTypeException if the token slug is not USER
|
|
4682
|
+
* @throws MetaMissingException if the required peerHost meta field is absent
|
|
4683
|
+
*/
|
|
4684
|
+
isotopeP() {
|
|
4685
|
+
for (const atom of this.molecule.getIsotopes("P")) {
|
|
4686
|
+
if (atom.token !== "USER") {
|
|
4687
|
+
throw new WrongTokenTypeException(`Check::isotopeP() - "${atom.token}" is not a valid Token slug for "${atom.isotope}" isotope Atoms!`);
|
|
4688
|
+
}
|
|
4689
|
+
const metas = atom.aggregatedMeta();
|
|
4690
|
+
if (!Object.prototype.hasOwnProperty.call(metas, "peerHost") || !metas.peerHost) {
|
|
4691
|
+
throw new MetaMissingException('Check::isotopeP() - Required meta field "peerHost" is missing!');
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
return true;
|
|
4695
|
+
}
|
|
4696
|
+
/**
|
|
4697
|
+
* Validate isotope A atoms (append request)
|
|
4698
|
+
* @return True if valid
|
|
4699
|
+
* @throws WrongTokenTypeException if the token slug is not USER
|
|
4700
|
+
* @throws MetaMissingException if metaType, metaId or the action meta field is absent
|
|
4701
|
+
*/
|
|
4702
|
+
isotopeA() {
|
|
4703
|
+
for (const atom of this.molecule.getIsotopes("A")) {
|
|
4704
|
+
if (atom.token !== "USER") {
|
|
4705
|
+
throw new WrongTokenTypeException(`Check::isotopeA() - "${atom.token}" is not a valid Token slug for "${atom.isotope}" isotope Atoms!`);
|
|
4706
|
+
}
|
|
4707
|
+
if (!atom.metaType) {
|
|
4708
|
+
throw new MetaMissingException('Check::isotopeA() - Required field "metaType" is missing!');
|
|
4709
|
+
}
|
|
4710
|
+
if (!atom.metaId) {
|
|
4711
|
+
throw new MetaMissingException('Check::isotopeA() - Required field "metaId" is missing!');
|
|
4712
|
+
}
|
|
4713
|
+
const metas = atom.aggregatedMeta();
|
|
4714
|
+
if (!Object.prototype.hasOwnProperty.call(metas, "action") || !metas.action) {
|
|
4715
|
+
throw new MetaMissingException('Check::isotopeA() - Required meta field "action" is missing!');
|
|
4716
|
+
}
|
|
4717
|
+
}
|
|
4718
|
+
return true;
|
|
4719
|
+
}
|
|
4720
|
+
/**
|
|
4721
|
+
* Validate isotope B atoms (buffer/exchange)
|
|
4722
|
+
*
|
|
4723
|
+
* Buffer molecules are cross-isotope: their V atoms do not balance on their own
|
|
4724
|
+
* because a B atom absorbs the difference. isotopeV() therefore skips its V-only
|
|
4725
|
+
* conservation checks whenever B (or F) atoms are present, and conservation is
|
|
4726
|
+
* enforced here instead over the combined V+B set.
|
|
4727
|
+
*
|
|
4728
|
+
* @return True if valid
|
|
4729
|
+
* @throws MetaMissingException if metaType is not walletBundle, or metaId is absent
|
|
4730
|
+
* @throws TransferMalformedException if a B atom value is not a number
|
|
4731
|
+
* @throws TransferUnbalancedException if V+B atom values do not sum to zero
|
|
4732
|
+
*/
|
|
4733
|
+
isotopeB() {
|
|
4734
|
+
const isotopeB = this.molecule.getIsotopes("B");
|
|
4735
|
+
if (isotopeB.length === 0) {
|
|
4736
|
+
return true;
|
|
4737
|
+
}
|
|
4738
|
+
for (const atom of isotopeB) {
|
|
4739
|
+
if (!atom.metaType || atom.metaType !== "walletBundle") {
|
|
4740
|
+
throw new MetaMissingException('Check::isotopeB() - B-isotope atoms must have metaType "walletBundle"!');
|
|
4741
|
+
}
|
|
4742
|
+
if (!atom.metaId) {
|
|
4743
|
+
throw new MetaMissingException("Check::isotopeB() - B-isotope atoms must have a metaId!");
|
|
4744
|
+
}
|
|
4745
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4746
|
+
if (Number.isNaN(value)) {
|
|
4747
|
+
throw new TransferMalformedException("Check::isotopeB() - B-isotope atom value is not a valid number!");
|
|
4748
|
+
}
|
|
4749
|
+
}
|
|
4750
|
+
const vAtoms = this.molecule.getIsotopes("V");
|
|
4751
|
+
if (vAtoms.length > 0) {
|
|
4752
|
+
let sum = 0;
|
|
4753
|
+
for (const atom of [...vAtoms, ...isotopeB]) {
|
|
4754
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4755
|
+
if (!Number.isNaN(value)) {
|
|
4756
|
+
sum += value;
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
if (sum !== 0) {
|
|
4760
|
+
throw new TransferUnbalancedException("Check::isotopeB() - V+B atom values do not balance to zero!");
|
|
4761
|
+
}
|
|
4762
|
+
}
|
|
4763
|
+
return true;
|
|
4764
|
+
}
|
|
4765
|
+
/**
|
|
4766
|
+
* Validate isotope F atoms (fusion/NFT)
|
|
4767
|
+
*
|
|
4768
|
+
* Mirrors isotopeB() and additionally forbids negative values. Must stay paired
|
|
4769
|
+
* with the hasCrossIsotope gate in isotopeV(), which is keyed on B *or* F: without
|
|
4770
|
+
* this check an F-isotope molecule would skip V-only conservation with nothing
|
|
4771
|
+
* validating V+F conservation in its place.
|
|
4772
|
+
*
|
|
4773
|
+
* @return True if valid
|
|
4774
|
+
* @throws MetaMissingException if metaType is not walletBundle, or metaId is absent
|
|
4775
|
+
* @throws TransferMalformedException if an F atom value is not a number, or is negative
|
|
4776
|
+
* @throws TransferUnbalancedException if V+F atom values do not sum to zero
|
|
4777
|
+
*/
|
|
4778
|
+
isotopeF() {
|
|
4779
|
+
const isotopeF = this.molecule.getIsotopes("F");
|
|
4780
|
+
if (isotopeF.length === 0) {
|
|
4781
|
+
return true;
|
|
4782
|
+
}
|
|
4783
|
+
for (const atom of isotopeF) {
|
|
4784
|
+
if (!atom.metaType || atom.metaType !== "walletBundle") {
|
|
4785
|
+
throw new MetaMissingException('Check::isotopeF() - F-isotope atoms must have metaType "walletBundle"!');
|
|
4786
|
+
}
|
|
4787
|
+
if (!atom.metaId) {
|
|
4788
|
+
throw new MetaMissingException("Check::isotopeF() - F-isotope atoms must have a metaId!");
|
|
4789
|
+
}
|
|
4790
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4791
|
+
if (Number.isNaN(value)) {
|
|
4792
|
+
throw new TransferMalformedException("Check::isotopeF() - F-isotope atom value is not a valid number!");
|
|
4793
|
+
}
|
|
4794
|
+
if (value < 0) {
|
|
4795
|
+
throw new TransferMalformedException("Check::isotopeF() - F-isotope atom value must not be negative!");
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
const vAtoms = this.molecule.getIsotopes("V");
|
|
4799
|
+
if (vAtoms.length > 0) {
|
|
4800
|
+
let sum = 0;
|
|
4801
|
+
for (const atom of [...vAtoms, ...isotopeF]) {
|
|
4802
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4803
|
+
if (!Number.isNaN(value)) {
|
|
4804
|
+
sum += value;
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
if (sum !== 0) {
|
|
4808
|
+
throw new TransferUnbalancedException("Check::isotopeF() - V+F atom values do not balance to zero!");
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
return true;
|
|
4812
|
+
}
|
|
4658
4813
|
/**
|
|
4659
4814
|
* Validate isotope V atoms (value transfers)
|
|
4660
4815
|
* @param senderWallet - Optional wallet for balance validation
|
|
@@ -4666,11 +4821,12 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4666
4821
|
if (isotopeV.length === 0) {
|
|
4667
4822
|
return true;
|
|
4668
4823
|
}
|
|
4824
|
+
const hasCrossIsotope = this.molecule.getIsotopes("B").length > 0 || this.molecule.getIsotopes("F").length > 0;
|
|
4669
4825
|
const firstAtom = this.molecule.atoms[0];
|
|
4670
4826
|
if (!firstAtom) {
|
|
4671
4827
|
throw new AtomsMissingException("Check::isotopeV() - Missing first atom");
|
|
4672
4828
|
}
|
|
4673
|
-
if (firstAtom.isotope === "V" && isotopeV.length === 2) {
|
|
4829
|
+
if (!hasCrossIsotope && firstAtom.isotope === "V" && isotopeV.length === 2) {
|
|
4674
4830
|
const endAtom = isotopeV[isotopeV.length - 1];
|
|
4675
4831
|
if (!endAtom) {
|
|
4676
4832
|
throw new AtomsMissingException("Check::isotopeV() - Missing end atom");
|
|
@@ -4682,6 +4838,10 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4682
4838
|
if (endValue < 0) {
|
|
4683
4839
|
throw new TransferMalformedException();
|
|
4684
4840
|
}
|
|
4841
|
+
const firstValueForPair = firstAtom.value !== null ? Number(firstAtom.value) : 0;
|
|
4842
|
+
if (firstValueForPair + endValue !== 0) {
|
|
4843
|
+
throw new TransferUnbalancedException();
|
|
4844
|
+
}
|
|
4685
4845
|
return true;
|
|
4686
4846
|
}
|
|
4687
4847
|
let sum = 0;
|
|
@@ -4710,7 +4870,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4710
4870
|
sum += value;
|
|
4711
4871
|
}
|
|
4712
4872
|
}
|
|
4713
|
-
if (sum !== 0) {
|
|
4873
|
+
if (!hasCrossIsotope && sum !== 0) {
|
|
4714
4874
|
throw new TransferUnbalancedException();
|
|
4715
4875
|
}
|
|
4716
4876
|
if (senderWallet) {
|
|
@@ -4722,7 +4882,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4722
4882
|
if (remainder < 0) {
|
|
4723
4883
|
throw new TransferBalanceException();
|
|
4724
4884
|
}
|
|
4725
|
-
if (remainder !== sum) {
|
|
4885
|
+
if (!hasCrossIsotope && remainder !== sum) {
|
|
4726
4886
|
throw new TransferRemainderException();
|
|
4727
4887
|
}
|
|
4728
4888
|
} else if (sum !== 0) {
|
|
@@ -7007,6 +7167,7 @@ var ValidationChainBuilder = class {
|
|
|
7007
7167
|
constructor(service) {
|
|
7008
7168
|
this.service = service;
|
|
7009
7169
|
}
|
|
7170
|
+
service;
|
|
7010
7171
|
validators = [];
|
|
7011
7172
|
/**
|
|
7012
7173
|
* Add a schema validation step
|