@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.cjs
CHANGED
|
@@ -1849,11 +1849,15 @@ function hexToBase64(hexString) {
|
|
|
1849
1849
|
try {
|
|
1850
1850
|
const cleanHex = hexString.replace(/^0x/i, "");
|
|
1851
1851
|
const bytes = hexStringToBuffer(cleanHex);
|
|
1852
|
-
if (typeof
|
|
1853
|
-
return btoa(String.fromCharCode(...bytes));
|
|
1854
|
-
} else {
|
|
1852
|
+
if (typeof Buffer !== "undefined") {
|
|
1855
1853
|
return Buffer.from(bytes).toString("base64");
|
|
1856
1854
|
}
|
|
1855
|
+
let binary = "";
|
|
1856
|
+
const CHUNK_SIZE = 32768;
|
|
1857
|
+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
1858
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK_SIZE));
|
|
1859
|
+
}
|
|
1860
|
+
return btoa(binary);
|
|
1857
1861
|
} catch (error) {
|
|
1858
1862
|
throw new Error(`Failed to convert hex to base64: ${error instanceof Error ? error.message : String(error)}`);
|
|
1859
1863
|
}
|
|
@@ -3811,11 +3815,26 @@ var Wallet = class _Wallet {
|
|
|
3811
3815
|
return new Uint8Array(decryptedContent);
|
|
3812
3816
|
}
|
|
3813
3817
|
serializeKey(key) {
|
|
3814
|
-
|
|
3818
|
+
if (typeof Buffer !== "undefined") {
|
|
3819
|
+
return Buffer.from(key).toString("base64");
|
|
3820
|
+
}
|
|
3821
|
+
let binary = "";
|
|
3822
|
+
const CHUNK_SIZE = 32768;
|
|
3823
|
+
for (let i = 0; i < key.length; i += CHUNK_SIZE) {
|
|
3824
|
+
binary += String.fromCharCode(...key.subarray(i, i + CHUNK_SIZE));
|
|
3825
|
+
}
|
|
3826
|
+
return btoa(binary);
|
|
3815
3827
|
}
|
|
3816
3828
|
deserializeKey(serializedKey) {
|
|
3829
|
+
if (typeof Buffer !== "undefined") {
|
|
3830
|
+
return new Uint8Array(Buffer.from(serializedKey, "base64"));
|
|
3831
|
+
}
|
|
3817
3832
|
const binaryString = atob(serializedKey);
|
|
3818
|
-
|
|
3833
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
3834
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
3835
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3836
|
+
}
|
|
3837
|
+
return bytes;
|
|
3819
3838
|
}
|
|
3820
3839
|
};
|
|
3821
3840
|
var hexStringRegex = /^[0-9a-fA-F]+$/;
|
|
@@ -4182,10 +4201,11 @@ function deepCloning(o, h) {
|
|
|
4182
4201
|
return r || o;
|
|
4183
4202
|
}
|
|
4184
4203
|
function chunkArray(arr, size) {
|
|
4185
|
-
|
|
4186
|
-
|
|
4204
|
+
const chunks = [];
|
|
4205
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
4206
|
+
chunks.push(arr.slice(i, i + size));
|
|
4187
4207
|
}
|
|
4188
|
-
return
|
|
4208
|
+
return chunks;
|
|
4189
4209
|
}
|
|
4190
4210
|
function diff(...arrays) {
|
|
4191
4211
|
return [].concat(...arrays.map((arr, i) => {
|
|
@@ -4473,7 +4493,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4473
4493
|
* @return True if all validations pass
|
|
4474
4494
|
*/
|
|
4475
4495
|
verify(senderWallet) {
|
|
4476
|
-
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);
|
|
4496
|
+
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);
|
|
4477
4497
|
}
|
|
4478
4498
|
/**
|
|
4479
4499
|
* Validate ContinuID requirement
|
|
@@ -4661,6 +4681,141 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4661
4681
|
}
|
|
4662
4682
|
return true;
|
|
4663
4683
|
}
|
|
4684
|
+
/**
|
|
4685
|
+
* Validate isotope P atoms (peering)
|
|
4686
|
+
* @return True if valid
|
|
4687
|
+
* @throws WrongTokenTypeException if the token slug is not USER
|
|
4688
|
+
* @throws MetaMissingException if the required peerHost meta field is absent
|
|
4689
|
+
*/
|
|
4690
|
+
isotopeP() {
|
|
4691
|
+
for (const atom of this.molecule.getIsotopes("P")) {
|
|
4692
|
+
if (atom.token !== "USER") {
|
|
4693
|
+
throw new WrongTokenTypeException(`Check::isotopeP() - "${atom.token}" is not a valid Token slug for "${atom.isotope}" isotope Atoms!`);
|
|
4694
|
+
}
|
|
4695
|
+
const metas = atom.aggregatedMeta();
|
|
4696
|
+
if (!Object.prototype.hasOwnProperty.call(metas, "peerHost") || !metas.peerHost) {
|
|
4697
|
+
throw new MetaMissingException('Check::isotopeP() - Required meta field "peerHost" is missing!');
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
4700
|
+
return true;
|
|
4701
|
+
}
|
|
4702
|
+
/**
|
|
4703
|
+
* Validate isotope A atoms (append request)
|
|
4704
|
+
* @return True if valid
|
|
4705
|
+
* @throws WrongTokenTypeException if the token slug is not USER
|
|
4706
|
+
* @throws MetaMissingException if metaType, metaId or the action meta field is absent
|
|
4707
|
+
*/
|
|
4708
|
+
isotopeA() {
|
|
4709
|
+
for (const atom of this.molecule.getIsotopes("A")) {
|
|
4710
|
+
if (atom.token !== "USER") {
|
|
4711
|
+
throw new WrongTokenTypeException(`Check::isotopeA() - "${atom.token}" is not a valid Token slug for "${atom.isotope}" isotope Atoms!`);
|
|
4712
|
+
}
|
|
4713
|
+
if (!atom.metaType) {
|
|
4714
|
+
throw new MetaMissingException('Check::isotopeA() - Required field "metaType" is missing!');
|
|
4715
|
+
}
|
|
4716
|
+
if (!atom.metaId) {
|
|
4717
|
+
throw new MetaMissingException('Check::isotopeA() - Required field "metaId" is missing!');
|
|
4718
|
+
}
|
|
4719
|
+
const metas = atom.aggregatedMeta();
|
|
4720
|
+
if (!Object.prototype.hasOwnProperty.call(metas, "action") || !metas.action) {
|
|
4721
|
+
throw new MetaMissingException('Check::isotopeA() - Required meta field "action" is missing!');
|
|
4722
|
+
}
|
|
4723
|
+
}
|
|
4724
|
+
return true;
|
|
4725
|
+
}
|
|
4726
|
+
/**
|
|
4727
|
+
* Validate isotope B atoms (buffer/exchange)
|
|
4728
|
+
*
|
|
4729
|
+
* Buffer molecules are cross-isotope: their V atoms do not balance on their own
|
|
4730
|
+
* because a B atom absorbs the difference. isotopeV() therefore skips its V-only
|
|
4731
|
+
* conservation checks whenever B (or F) atoms are present, and conservation is
|
|
4732
|
+
* enforced here instead over the combined V+B set.
|
|
4733
|
+
*
|
|
4734
|
+
* @return True if valid
|
|
4735
|
+
* @throws MetaMissingException if metaType is not walletBundle, or metaId is absent
|
|
4736
|
+
* @throws TransferMalformedException if a B atom value is not a number
|
|
4737
|
+
* @throws TransferUnbalancedException if V+B atom values do not sum to zero
|
|
4738
|
+
*/
|
|
4739
|
+
isotopeB() {
|
|
4740
|
+
const isotopeB = this.molecule.getIsotopes("B");
|
|
4741
|
+
if (isotopeB.length === 0) {
|
|
4742
|
+
return true;
|
|
4743
|
+
}
|
|
4744
|
+
for (const atom of isotopeB) {
|
|
4745
|
+
if (!atom.metaType || atom.metaType !== "walletBundle") {
|
|
4746
|
+
throw new MetaMissingException('Check::isotopeB() - B-isotope atoms must have metaType "walletBundle"!');
|
|
4747
|
+
}
|
|
4748
|
+
if (!atom.metaId) {
|
|
4749
|
+
throw new MetaMissingException("Check::isotopeB() - B-isotope atoms must have a metaId!");
|
|
4750
|
+
}
|
|
4751
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4752
|
+
if (Number.isNaN(value)) {
|
|
4753
|
+
throw new TransferMalformedException("Check::isotopeB() - B-isotope atom value is not a valid number!");
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
const vAtoms = this.molecule.getIsotopes("V");
|
|
4757
|
+
if (vAtoms.length > 0) {
|
|
4758
|
+
let sum = 0;
|
|
4759
|
+
for (const atom of [...vAtoms, ...isotopeB]) {
|
|
4760
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4761
|
+
if (!Number.isNaN(value)) {
|
|
4762
|
+
sum += value;
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
if (sum !== 0) {
|
|
4766
|
+
throw new TransferUnbalancedException("Check::isotopeB() - V+B atom values do not balance to zero!");
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
return true;
|
|
4770
|
+
}
|
|
4771
|
+
/**
|
|
4772
|
+
* Validate isotope F atoms (fusion/NFT)
|
|
4773
|
+
*
|
|
4774
|
+
* Mirrors isotopeB() and additionally forbids negative values. Must stay paired
|
|
4775
|
+
* with the hasCrossIsotope gate in isotopeV(), which is keyed on B *or* F: without
|
|
4776
|
+
* this check an F-isotope molecule would skip V-only conservation with nothing
|
|
4777
|
+
* validating V+F conservation in its place.
|
|
4778
|
+
*
|
|
4779
|
+
* @return True if valid
|
|
4780
|
+
* @throws MetaMissingException if metaType is not walletBundle, or metaId is absent
|
|
4781
|
+
* @throws TransferMalformedException if an F atom value is not a number, or is negative
|
|
4782
|
+
* @throws TransferUnbalancedException if V+F atom values do not sum to zero
|
|
4783
|
+
*/
|
|
4784
|
+
isotopeF() {
|
|
4785
|
+
const isotopeF = this.molecule.getIsotopes("F");
|
|
4786
|
+
if (isotopeF.length === 0) {
|
|
4787
|
+
return true;
|
|
4788
|
+
}
|
|
4789
|
+
for (const atom of isotopeF) {
|
|
4790
|
+
if (!atom.metaType || atom.metaType !== "walletBundle") {
|
|
4791
|
+
throw new MetaMissingException('Check::isotopeF() - F-isotope atoms must have metaType "walletBundle"!');
|
|
4792
|
+
}
|
|
4793
|
+
if (!atom.metaId) {
|
|
4794
|
+
throw new MetaMissingException("Check::isotopeF() - F-isotope atoms must have a metaId!");
|
|
4795
|
+
}
|
|
4796
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4797
|
+
if (Number.isNaN(value)) {
|
|
4798
|
+
throw new TransferMalformedException("Check::isotopeF() - F-isotope atom value is not a valid number!");
|
|
4799
|
+
}
|
|
4800
|
+
if (value < 0) {
|
|
4801
|
+
throw new TransferMalformedException("Check::isotopeF() - F-isotope atom value must not be negative!");
|
|
4802
|
+
}
|
|
4803
|
+
}
|
|
4804
|
+
const vAtoms = this.molecule.getIsotopes("V");
|
|
4805
|
+
if (vAtoms.length > 0) {
|
|
4806
|
+
let sum = 0;
|
|
4807
|
+
for (const atom of [...vAtoms, ...isotopeF]) {
|
|
4808
|
+
const value = atom.value !== null ? Number(atom.value) : Number.NaN;
|
|
4809
|
+
if (!Number.isNaN(value)) {
|
|
4810
|
+
sum += value;
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4813
|
+
if (sum !== 0) {
|
|
4814
|
+
throw new TransferUnbalancedException("Check::isotopeF() - V+F atom values do not balance to zero!");
|
|
4815
|
+
}
|
|
4816
|
+
}
|
|
4817
|
+
return true;
|
|
4818
|
+
}
|
|
4664
4819
|
/**
|
|
4665
4820
|
* Validate isotope V atoms (value transfers)
|
|
4666
4821
|
* @param senderWallet - Optional wallet for balance validation
|
|
@@ -4672,11 +4827,12 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4672
4827
|
if (isotopeV.length === 0) {
|
|
4673
4828
|
return true;
|
|
4674
4829
|
}
|
|
4830
|
+
const hasCrossIsotope = this.molecule.getIsotopes("B").length > 0 || this.molecule.getIsotopes("F").length > 0;
|
|
4675
4831
|
const firstAtom = this.molecule.atoms[0];
|
|
4676
4832
|
if (!firstAtom) {
|
|
4677
4833
|
throw new exports.AtomsMissingException("Check::isotopeV() - Missing first atom");
|
|
4678
4834
|
}
|
|
4679
|
-
if (firstAtom.isotope === "V" && isotopeV.length === 2) {
|
|
4835
|
+
if (!hasCrossIsotope && firstAtom.isotope === "V" && isotopeV.length === 2) {
|
|
4680
4836
|
const endAtom = isotopeV[isotopeV.length - 1];
|
|
4681
4837
|
if (!endAtom) {
|
|
4682
4838
|
throw new exports.AtomsMissingException("Check::isotopeV() - Missing end atom");
|
|
@@ -4688,6 +4844,10 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4688
4844
|
if (endValue < 0) {
|
|
4689
4845
|
throw new TransferMalformedException();
|
|
4690
4846
|
}
|
|
4847
|
+
const firstValueForPair = firstAtom.value !== null ? Number(firstAtom.value) : 0;
|
|
4848
|
+
if (firstValueForPair + endValue !== 0) {
|
|
4849
|
+
throw new TransferUnbalancedException();
|
|
4850
|
+
}
|
|
4691
4851
|
return true;
|
|
4692
4852
|
}
|
|
4693
4853
|
let sum = 0;
|
|
@@ -4716,7 +4876,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4716
4876
|
sum += value;
|
|
4717
4877
|
}
|
|
4718
4878
|
}
|
|
4719
|
-
if (sum !== 0) {
|
|
4879
|
+
if (!hasCrossIsotope && sum !== 0) {
|
|
4720
4880
|
throw new TransferUnbalancedException();
|
|
4721
4881
|
}
|
|
4722
4882
|
if (senderWallet) {
|
|
@@ -4728,7 +4888,7 @@ var CheckMolecule = class _CheckMolecule {
|
|
|
4728
4888
|
if (remainder < 0) {
|
|
4729
4889
|
throw new exports.TransferBalanceException();
|
|
4730
4890
|
}
|
|
4731
|
-
if (remainder !== sum) {
|
|
4891
|
+
if (!hasCrossIsotope && remainder !== sum) {
|
|
4732
4892
|
throw new TransferRemainderException();
|
|
4733
4893
|
}
|
|
4734
4894
|
} else if (sum !== 0) {
|
|
@@ -7013,6 +7173,7 @@ var ValidationChainBuilder = class {
|
|
|
7013
7173
|
constructor(service) {
|
|
7014
7174
|
this.service = service;
|
|
7015
7175
|
}
|
|
7176
|
+
service;
|
|
7016
7177
|
validators = [];
|
|
7017
7178
|
/**
|
|
7018
7179
|
* Add a schema validation step
|