@wishknish/knishio-client-ts 0.9.7 → 1.0.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.
- package/dist/index.cjs +237 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -36
- package/dist/index.d.ts +42 -36
- package/dist/index.iife.js +238 -52
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +238 -53
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/AuthToken.ts +47 -25
- package/src/KnishIOClient.ts +62 -17
- package/src/core/Molecule.ts +17 -7
- package/src/core/Wallet.ts +161 -32
- package/src/index.ts +2 -2
- package/src/libraries/GraphQLClient.ts +2 -2
- package/src/mutation/MutationProposeMolecule.ts +7 -4
- package/src/schemas/index.ts +2 -1
- package/src/types/crypto.ts +9 -4
- package/src/validation/schemas.ts +2 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import JsSHA from 'jssha';
|
|
3
|
-
import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';
|
|
3
|
+
import { ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem.js';
|
|
4
4
|
import { cacheExchange, fetchExchange, subscriptionExchange, createClient as createClient$1, gql } from '@urql/core';
|
|
5
5
|
import { createClient } from 'graphql-ws';
|
|
6
6
|
import { pipe, subscribe } from 'wonka';
|
|
@@ -3655,6 +3655,11 @@ var TokenUnit = class _TokenUnit {
|
|
|
3655
3655
|
};
|
|
3656
3656
|
}
|
|
3657
3657
|
};
|
|
3658
|
+
var ML_KEM_PARAMS = {
|
|
3659
|
+
1024: { kem: ml_kem1024, pkBytes: 1568, skBytes: 3168, ctBytes: 1568 },
|
|
3660
|
+
768: { kem: ml_kem768, pkBytes: 1184, skBytes: 2400, ctBytes: 1088 }
|
|
3661
|
+
};
|
|
3662
|
+
var DEFAULT_ML_KEM_PARAMETER_SET = 1024;
|
|
3658
3663
|
var Wallet = class _Wallet {
|
|
3659
3664
|
token;
|
|
3660
3665
|
balance;
|
|
@@ -3669,6 +3674,7 @@ var Wallet = class _Wallet {
|
|
|
3669
3674
|
tokenUnits;
|
|
3670
3675
|
tradeRates;
|
|
3671
3676
|
molecules;
|
|
3677
|
+
mlKemParameterSet;
|
|
3672
3678
|
// Token metadata (populated from query responses)
|
|
3673
3679
|
tokenName;
|
|
3674
3680
|
tokenAmount;
|
|
@@ -3682,8 +3688,14 @@ var Wallet = class _Wallet {
|
|
|
3682
3688
|
address = null,
|
|
3683
3689
|
position = null,
|
|
3684
3690
|
batchId = null,
|
|
3685
|
-
characters = null
|
|
3691
|
+
characters = null,
|
|
3692
|
+
mlKemParameterSet = DEFAULT_ML_KEM_PARAMETER_SET
|
|
3686
3693
|
} = {}) {
|
|
3694
|
+
const paramSetNum = Number(mlKemParameterSet);
|
|
3695
|
+
if (!ML_KEM_PARAMS[paramSetNum]) {
|
|
3696
|
+
throw new Error(`KnishIO: unsupported ML-KEM parameter set ${mlKemParameterSet}; expected 1024 or 768.`);
|
|
3697
|
+
}
|
|
3698
|
+
this.mlKemParameterSet = paramSetNum;
|
|
3687
3699
|
this.token = token;
|
|
3688
3700
|
this.balance = "0";
|
|
3689
3701
|
this.molecules = {};
|
|
@@ -3719,7 +3731,8 @@ var Wallet = class _Wallet {
|
|
|
3719
3731
|
bundle = null,
|
|
3720
3732
|
token = "USER",
|
|
3721
3733
|
batchId = null,
|
|
3722
|
-
characters = null
|
|
3734
|
+
characters = null,
|
|
3735
|
+
mlKemParameterSet = DEFAULT_ML_KEM_PARAMETER_SET
|
|
3723
3736
|
}) {
|
|
3724
3737
|
let position = null;
|
|
3725
3738
|
if (!secret && !bundle) {
|
|
@@ -3735,7 +3748,8 @@ var Wallet = class _Wallet {
|
|
|
3735
3748
|
token,
|
|
3736
3749
|
position,
|
|
3737
3750
|
batchId,
|
|
3738
|
-
characters
|
|
3751
|
+
characters,
|
|
3752
|
+
mlKemParameterSet
|
|
3739
3753
|
});
|
|
3740
3754
|
}
|
|
3741
3755
|
/**
|
|
@@ -3894,20 +3908,80 @@ var Wallet = class _Wallet {
|
|
|
3894
3908
|
return (typeof this.position === "undefined" || this.position === null) && (typeof this.address === "undefined" || this.address === null);
|
|
3895
3909
|
}
|
|
3896
3910
|
// =============================================================================
|
|
3897
|
-
// POST-QUANTUM CRYPTOGRAPHY - ML-
|
|
3911
|
+
// POST-QUANTUM CRYPTOGRAPHY - ML-KEM INTEGRATION
|
|
3898
3912
|
// =============================================================================
|
|
3899
3913
|
/**
|
|
3900
|
-
*
|
|
3914
|
+
* Derive an ML-KEM keypair for an arbitrary parameter set from the wallet's key seed,
|
|
3915
|
+
* without mutating the wallet. The 64-byte `d‖z` seed takes no parameter-set input — only
|
|
3916
|
+
* the final `keygen` call differs — so one KnishIO wallet owns both an ML-KEM-768 and an
|
|
3917
|
+
* ML-KEM-1024 identity and either can be reconstructed on demand.
|
|
3918
|
+
*
|
|
3919
|
+
* Returns `null` when the wallet holds no key — a secret-less wallet, which is what a molecule
|
|
3920
|
+
* deserializer builds for validation context. `generateSecret(null, …)` does NOT throw, so
|
|
3921
|
+
* without this the wallet would derive a plausible-looking identity from a bogus seed and fail
|
|
3922
|
+
* three layers down at AES-GCM instead of at the missing key. The guard lives here rather than
|
|
3923
|
+
* at each call site so a new caller cannot miss it.
|
|
3924
|
+
*
|
|
3925
|
+
* @param parameterSet - 1024 or 768
|
|
3901
3926
|
*/
|
|
3902
|
-
|
|
3927
|
+
deriveMlKemKeypair(parameterSet) {
|
|
3928
|
+
const params = ML_KEM_PARAMS[parameterSet];
|
|
3929
|
+
if (!params) {
|
|
3930
|
+
throw new Error(`KnishIO: unsupported ML-KEM parameter set ${parameterSet}; expected 1024 or 768.`);
|
|
3931
|
+
}
|
|
3932
|
+
if (!this.key) {
|
|
3933
|
+
return null;
|
|
3934
|
+
}
|
|
3903
3935
|
const seedHex = generateSecret(this.key, 128);
|
|
3904
3936
|
const seed = new Uint8Array(64);
|
|
3905
3937
|
for (let i = 0; i < 64; i++) {
|
|
3906
3938
|
seed[i] = parseInt(seedHex.substr(i * 2, 2), 16);
|
|
3907
3939
|
}
|
|
3908
|
-
const { publicKey, secretKey } =
|
|
3909
|
-
|
|
3910
|
-
|
|
3940
|
+
const { publicKey, secretKey } = params.kem.keygen(seed);
|
|
3941
|
+
return {
|
|
3942
|
+
pubkey: this.serializeKey(publicKey),
|
|
3943
|
+
privkey: secretKey,
|
|
3944
|
+
params
|
|
3945
|
+
};
|
|
3946
|
+
}
|
|
3947
|
+
/**
|
|
3948
|
+
* ML-KEM parameter set implied by a serialized public key's raw byte length. FIPS 203's key
|
|
3949
|
+
* lengths are disjoint (1568 bytes → ML-KEM-1024, 1184 bytes → ML-KEM-768), so a stored peer
|
|
3950
|
+
* key recovers the parameter set of the session it belongs to without a wire-format change.
|
|
3951
|
+
* Used by AuthToken.restore to resolve a snapshot that predates the field.
|
|
3952
|
+
*
|
|
3953
|
+
* @param pubkey - Base64-serialized ML-KEM public key
|
|
3954
|
+
* @return 1024, 768, or null when the length matches neither
|
|
3955
|
+
*/
|
|
3956
|
+
static mlKemParameterSetFromPubkey(pubkey) {
|
|
3957
|
+
if (!pubkey) {
|
|
3958
|
+
return null;
|
|
3959
|
+
}
|
|
3960
|
+
let byteLength;
|
|
3961
|
+
try {
|
|
3962
|
+
byteLength = typeof Buffer !== "undefined" ? Buffer.from(pubkey, "base64").length : atob(pubkey).length;
|
|
3963
|
+
} catch {
|
|
3964
|
+
return null;
|
|
3965
|
+
}
|
|
3966
|
+
if (byteLength === ML_KEM_PARAMS[1024].pkBytes) {
|
|
3967
|
+
return 1024;
|
|
3968
|
+
}
|
|
3969
|
+
if (byteLength === ML_KEM_PARAMS[768].pkBytes) {
|
|
3970
|
+
return 768;
|
|
3971
|
+
}
|
|
3972
|
+
return null;
|
|
3973
|
+
}
|
|
3974
|
+
/**
|
|
3975
|
+
* Initializes the ML-KEM key pair (matches JavaScript SDK exactly). Only ever reached from the
|
|
3976
|
+
* constructor's `secret` branch, so the derivation cannot come back empty here.
|
|
3977
|
+
*/
|
|
3978
|
+
initializeMLKEM() {
|
|
3979
|
+
const derived = this.deriveMlKemKeypair(this.mlKemParameterSet);
|
|
3980
|
+
if (!derived) {
|
|
3981
|
+
return;
|
|
3982
|
+
}
|
|
3983
|
+
this.pubkey = derived.pubkey;
|
|
3984
|
+
this.privkey = derived.privkey;
|
|
3911
3985
|
}
|
|
3912
3986
|
// =============================================================================
|
|
3913
3987
|
// HIGH-LEVEL MESSAGE ENCRYPTION (JavaScript SDK Compatibility)
|
|
@@ -3916,13 +3990,13 @@ var Wallet = class _Wallet {
|
|
|
3916
3990
|
const messageString = JSON.stringify(message);
|
|
3917
3991
|
const messageUint8 = new TextEncoder().encode(messageString);
|
|
3918
3992
|
const deserializedPubkey = this.deserializeKey(recipientPubkey);
|
|
3919
|
-
const
|
|
3920
|
-
if (deserializedPubkey.length !==
|
|
3993
|
+
const params = ML_KEM_PARAMS[this.mlKemParameterSet];
|
|
3994
|
+
if (deserializedPubkey.length !== params.pkBytes) {
|
|
3921
3995
|
throw new Error(
|
|
3922
|
-
`KnishIO: cannot ML-KEM-encrypt \u2014 recipient public key is ${deserializedPubkey.length} bytes, expected ${
|
|
3996
|
+
`KnishIO: cannot ML-KEM-encrypt \u2014 recipient public key is ${deserializedPubkey.length} bytes, expected ${params.pkBytes} (ML-KEM-${this.mlKemParameterSet}). The peer is not running ML-KEM-${this.mlKemParameterSet}; upgrade the peer, or step this client back to the other parameter set.`
|
|
3923
3997
|
);
|
|
3924
3998
|
}
|
|
3925
|
-
const { cipherText, sharedSecret } =
|
|
3999
|
+
const { cipherText, sharedSecret } = params.kem.encapsulate(deserializedPubkey);
|
|
3926
4000
|
const encryptedMessage = await this.encryptWithSharedSecret(messageUint8, sharedSecret);
|
|
3927
4001
|
return {
|
|
3928
4002
|
cipherText: this.serializeKey(cipherText),
|
|
@@ -3934,15 +4008,37 @@ var Wallet = class _Wallet {
|
|
|
3934
4008
|
return decryptedString === null ? null : JSON.parse(decryptedString);
|
|
3935
4009
|
}
|
|
3936
4010
|
/**
|
|
3937
|
-
* ML-
|
|
4011
|
+
* ML-KEM decapsulate + AES-256-GCM decrypt → the RAW decrypted UTF-8 string (no JSON.parse).
|
|
3938
4012
|
* Shared by {@link decryptMessage} (which JSON.parses the result) and the PQ CipherHash transport
|
|
3939
|
-
* ({@link
|
|
4013
|
+
* ({@link decryptMyMessageML}, which needs the raw response JSON text). PQ-transport Phase E.
|
|
3940
4014
|
*/
|
|
3941
4015
|
async _mlkemDecryptToString(encryptedData) {
|
|
3942
4016
|
const { cipherText, encryptedMessage } = encryptedData;
|
|
4017
|
+
const configuredParams = ML_KEM_PARAMS[this.mlKemParameterSet];
|
|
4018
|
+
const otherSet = this.mlKemParameterSet === 1024 ? 768 : 1024;
|
|
4019
|
+
const deserializedCipherText = this.deserializeKey(cipherText);
|
|
4020
|
+
let params = configuredParams;
|
|
4021
|
+
let decapsPrivkey = this.privkey;
|
|
4022
|
+
if (deserializedCipherText.length !== configuredParams.ctBytes) {
|
|
4023
|
+
if (deserializedCipherText.length !== ML_KEM_PARAMS[otherSet].ctBytes) {
|
|
4024
|
+
console.error(
|
|
4025
|
+
`Wallet::decryptMessage() - Ciphertext length mismatch: got ${deserializedCipherText.length}, expected ${configuredParams.ctBytes}`
|
|
4026
|
+
);
|
|
4027
|
+
return null;
|
|
4028
|
+
}
|
|
4029
|
+
const derived = this.deriveMlKemKeypair(otherSet);
|
|
4030
|
+
if (!derived) {
|
|
4031
|
+
console.error(
|
|
4032
|
+
`Wallet::decryptMessage() - cannot derive the ML-KEM-${otherSet} identity: wallet has no key`
|
|
4033
|
+
);
|
|
4034
|
+
return null;
|
|
4035
|
+
}
|
|
4036
|
+
params = derived.params;
|
|
4037
|
+
decapsPrivkey = derived.privkey;
|
|
4038
|
+
}
|
|
3943
4039
|
let sharedSecret;
|
|
3944
4040
|
try {
|
|
3945
|
-
sharedSecret =
|
|
4041
|
+
sharedSecret = params.kem.decapsulate(deserializedCipherText, decapsPrivkey);
|
|
3946
4042
|
} catch (e) {
|
|
3947
4043
|
console.error("Wallet::decryptMessage() - Decapsulation failed", e);
|
|
3948
4044
|
console.info("Wallet::decryptMessage() - my public key", this.pubkey);
|
|
@@ -3992,11 +4088,11 @@ var Wallet = class _Wallet {
|
|
|
3992
4088
|
return this.serializeKey(bytes);
|
|
3993
4089
|
}
|
|
3994
4090
|
/**
|
|
3995
|
-
* Post-quantum (ML-
|
|
4091
|
+
* Post-quantum (ML-KEM) CipherHash request envelope: a stringified single-recipient map
|
|
3996
4092
|
* `{ "<hashShare(recipientPubkey)>": {cipherText, encryptedMessage} }` (object-valued, via
|
|
3997
4093
|
* {@link encryptMessage}). Matches the Rust validator's CipherHash handler. PQ-transport Phase E.
|
|
3998
4094
|
*/
|
|
3999
|
-
async
|
|
4095
|
+
async encryptStringML(message, recipientPubkey) {
|
|
4000
4096
|
const envelope = await this.encryptMessage(message, recipientPubkey);
|
|
4001
4097
|
return JSON.stringify({ [this.hashShare(recipientPubkey)]: envelope });
|
|
4002
4098
|
}
|
|
@@ -4004,9 +4100,21 @@ var Wallet = class _Wallet {
|
|
|
4004
4100
|
* Decrypt a CipherHash response map addressed to THIS wallet's ML-KEM pubkey
|
|
4005
4101
|
* (`hashShare(this.pubkey)`) → the RAW decrypted GraphQL response JSON text (NOT JSON.parsed;
|
|
4006
4102
|
* it replaces the HTTP response body for the normal parser). `null` if no entry / decrypt fails.
|
|
4103
|
+
*
|
|
4104
|
+
* A pre-bump peer addressed its envelope to `hashShare(our_768_pubkey)`, which a wallet
|
|
4105
|
+
* configured at ML-KEM-1024 would never find — so the other identity's share is tried too.
|
|
4106
|
+
* Without this, the permissive length dispatch in {@link _mlkemDecryptToString} is
|
|
4107
|
+
* unreachable on the transport path.
|
|
4007
4108
|
*/
|
|
4008
|
-
async
|
|
4009
|
-
|
|
4109
|
+
async decryptMyMessageML(map) {
|
|
4110
|
+
let envelope = map[this.hashShare(this.pubkey)];
|
|
4111
|
+
if (!envelope) {
|
|
4112
|
+
const otherSet = this.mlKemParameterSet === 1024 ? 768 : 1024;
|
|
4113
|
+
const other = this.deriveMlKemKeypair(otherSet);
|
|
4114
|
+
if (other) {
|
|
4115
|
+
envelope = map[this.hashShare(other.pubkey)];
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4010
4118
|
if (!envelope) {
|
|
4011
4119
|
return null;
|
|
4012
4120
|
}
|
|
@@ -4160,7 +4268,8 @@ z.object({
|
|
|
4160
4268
|
serverSdkVersion: z.number().int().min(1).optional(),
|
|
4161
4269
|
logging: z.boolean().optional(),
|
|
4162
4270
|
defaultRequestPolicy: z.enum(["cache-first", "cache-only", "network-only", "cache-and-network"]).nullable().optional(),
|
|
4163
|
-
secretStorage: z.unknown().optional()
|
|
4271
|
+
secretStorage: z.unknown().optional(),
|
|
4272
|
+
mlKemParameterSet: z.union([z.literal(1024), z.literal(768)]).optional()
|
|
4164
4273
|
}).strict();
|
|
4165
4274
|
z.object({
|
|
4166
4275
|
token: z.string().min(1, "Auth token cannot be empty"),
|
|
@@ -5249,6 +5358,7 @@ var Molecule = class _Molecule {
|
|
|
5249
5358
|
continuIdPosition;
|
|
5250
5359
|
parentHashes;
|
|
5251
5360
|
local;
|
|
5361
|
+
mlKemParameterSet = 1024;
|
|
5252
5362
|
/**
|
|
5253
5363
|
* Create new Molecule instance
|
|
5254
5364
|
* Matches JavaScript SDK constructor signature
|
|
@@ -5260,7 +5370,8 @@ var Molecule = class _Molecule {
|
|
|
5260
5370
|
remainderWallet = null,
|
|
5261
5371
|
cellSlug = null,
|
|
5262
5372
|
version = null,
|
|
5263
|
-
continuIdPosition = null
|
|
5373
|
+
continuIdPosition = null,
|
|
5374
|
+
mlKemParameterSet = null
|
|
5264
5375
|
} = {}) {
|
|
5265
5376
|
this.status = null;
|
|
5266
5377
|
this.molecularHash = null;
|
|
@@ -5272,6 +5383,7 @@ var Molecule = class _Molecule {
|
|
|
5272
5383
|
this.continuIdPosition = continuIdPosition;
|
|
5273
5384
|
this.atoms = [];
|
|
5274
5385
|
this.parentHashes = [];
|
|
5386
|
+
this.mlKemParameterSet = mlKemParameterSet || sourceWallet?.mlKemParameterSet || 1024;
|
|
5275
5387
|
const versionRegistry = versions_default;
|
|
5276
5388
|
if (version !== null && Object.prototype.hasOwnProperty.call(versionRegistry, version)) {
|
|
5277
5389
|
this.version = String(version);
|
|
@@ -5282,7 +5394,8 @@ var Molecule = class _Molecule {
|
|
|
5282
5394
|
bundle,
|
|
5283
5395
|
token: sourceWallet.token,
|
|
5284
5396
|
batchId: sourceWallet.batchId,
|
|
5285
|
-
characters: sourceWallet.characters
|
|
5397
|
+
characters: sourceWallet.characters,
|
|
5398
|
+
mlKemParameterSet: this.mlKemParameterSet
|
|
5286
5399
|
});
|
|
5287
5400
|
} else {
|
|
5288
5401
|
this.remainderWallet = null;
|
|
@@ -5343,7 +5456,8 @@ var Molecule = class _Molecule {
|
|
|
5343
5456
|
if (!this.remainderWallet || this.remainderWallet.token !== "USER") {
|
|
5344
5457
|
this.remainderWallet = Wallet.create({
|
|
5345
5458
|
secret: this.secret,
|
|
5346
|
-
bundle: this.bundle
|
|
5459
|
+
bundle: this.bundle,
|
|
5460
|
+
mlKemParameterSet: this.mlKemParameterSet
|
|
5347
5461
|
});
|
|
5348
5462
|
}
|
|
5349
5463
|
const continuIdMeta = {};
|
|
@@ -5730,7 +5844,8 @@ var Molecule = class _Molecule {
|
|
|
5730
5844
|
}
|
|
5731
5845
|
const burnWallet = new Wallet({
|
|
5732
5846
|
bundle: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
5733
|
-
token: this.sourceWallet.token
|
|
5847
|
+
token: this.sourceWallet.token,
|
|
5848
|
+
mlKemParameterSet: this.mlKemParameterSet
|
|
5734
5849
|
});
|
|
5735
5850
|
this.addAtom(Atom.create({
|
|
5736
5851
|
isotope: "V",
|
|
@@ -6002,7 +6117,8 @@ var Molecule = class _Molecule {
|
|
|
6002
6117
|
position: data.sourceWallet.position,
|
|
6003
6118
|
bundle: data.sourceWallet.bundle,
|
|
6004
6119
|
batchId: data.sourceWallet.batchId,
|
|
6005
|
-
characters: data.sourceWallet.characters
|
|
6120
|
+
characters: data.sourceWallet.characters,
|
|
6121
|
+
mlKemParameterSet: molecule.mlKemParameterSet
|
|
6006
6122
|
});
|
|
6007
6123
|
molecule.sourceWallet.balance = String(data.sourceWallet.balance != null ? data.sourceWallet.balance : 0);
|
|
6008
6124
|
molecule.sourceWallet.address = data.sourceWallet.address;
|
|
@@ -6020,7 +6136,8 @@ var Molecule = class _Molecule {
|
|
|
6020
6136
|
position: data.remainderWallet.position,
|
|
6021
6137
|
bundle: data.remainderWallet.bundle,
|
|
6022
6138
|
batchId: data.remainderWallet.batchId,
|
|
6023
|
-
characters: data.remainderWallet.characters
|
|
6139
|
+
characters: data.remainderWallet.characters,
|
|
6140
|
+
mlKemParameterSet: molecule.mlKemParameterSet
|
|
6024
6141
|
});
|
|
6025
6142
|
molecule.remainderWallet.balance = String(data.remainderWallet.balance != null ? data.remainderWallet.balance : 0);
|
|
6026
6143
|
molecule.remainderWallet.address = data.remainderWallet.address;
|
|
@@ -6118,7 +6235,8 @@ var Molecule = class _Molecule {
|
|
|
6118
6235
|
secret: this.secret,
|
|
6119
6236
|
bundle: this.bundle,
|
|
6120
6237
|
token: this.sourceWallet.token,
|
|
6121
|
-
batchId: this.sourceWallet.batchId
|
|
6238
|
+
batchId: this.sourceWallet.batchId,
|
|
6239
|
+
mlKemParameterSet: this.mlKemParameterSet
|
|
6122
6240
|
});
|
|
6123
6241
|
if (tradeRates) {
|
|
6124
6242
|
bufferWallet.tradeRates = tradeRates;
|
|
@@ -6389,7 +6507,7 @@ var GraphQLClient = class {
|
|
|
6389
6507
|
let encryptedRequest = false;
|
|
6390
6508
|
let requestInit = init;
|
|
6391
6509
|
if (wallet && serverPubkey && init && typeof init.body === "string" && this.shouldEncrypt(init.body)) {
|
|
6392
|
-
const hashVar = await wallet.
|
|
6510
|
+
const hashVar = await wallet.encryptStringML(init.body, serverPubkey);
|
|
6393
6511
|
requestInit = { ...init, body: JSON.stringify({ query: CIPHER_HASH_QUERY, variables: { Hash: hashVar } }) };
|
|
6394
6512
|
encryptedRequest = true;
|
|
6395
6513
|
}
|
|
@@ -6409,7 +6527,7 @@ var GraphQLClient = class {
|
|
|
6409
6527
|
if (typeof hash !== "string") {
|
|
6410
6528
|
return new Response(text, init2);
|
|
6411
6529
|
}
|
|
6412
|
-
const decrypted = await wallet.
|
|
6530
|
+
const decrypted = await wallet.decryptMyMessageML(JSON.parse(hash));
|
|
6413
6531
|
return new Response(decrypted != null ? decrypted : text, init2);
|
|
6414
6532
|
}
|
|
6415
6533
|
setAuthData({
|
|
@@ -6578,6 +6696,22 @@ var AuthToken = class _AuthToken {
|
|
|
6578
6696
|
authToken.setWallet(wallet);
|
|
6579
6697
|
return authToken;
|
|
6580
6698
|
}
|
|
6699
|
+
/**
|
|
6700
|
+
* ML-KEM parameter set a restored session must use, resolved in three tiers:
|
|
6701
|
+
* an explicit snapshot field, then the stored validator key's length, then ML-KEM-768.
|
|
6702
|
+
*
|
|
6703
|
+
* The final tier is deliberately NOT the constructor default. A snapshot with neither an
|
|
6704
|
+
* explicit field nor a recognisable key can only have come from a pre-bump build, and every
|
|
6705
|
+
* pre-bump build was 768-only — defaulting to 1024 would make the restored wallet advertise
|
|
6706
|
+
* a public key the validator never recorded for that token.
|
|
6707
|
+
*/
|
|
6708
|
+
static resolveMlKemParameterSet(snapshot) {
|
|
6709
|
+
const explicit = snapshot.wallet?.mlKemParameterSet;
|
|
6710
|
+
if (explicit) {
|
|
6711
|
+
return Number(explicit) === 768 ? 768 : 1024;
|
|
6712
|
+
}
|
|
6713
|
+
return Wallet.mlKemParameterSetFromPubkey(snapshot.pubkey) ?? 768;
|
|
6714
|
+
}
|
|
6581
6715
|
/**
|
|
6582
6716
|
* Restore AuthToken from snapshot
|
|
6583
6717
|
*/
|
|
@@ -6585,8 +6719,9 @@ var AuthToken = class _AuthToken {
|
|
|
6585
6719
|
const wallet = new Wallet({
|
|
6586
6720
|
secret,
|
|
6587
6721
|
token: "AUTH",
|
|
6588
|
-
position: snapshot.wallet
|
|
6589
|
-
characters: snapshot.wallet
|
|
6722
|
+
position: snapshot.wallet?.position ?? null,
|
|
6723
|
+
characters: snapshot.wallet?.characters ?? null,
|
|
6724
|
+
mlKemParameterSet: _AuthToken.resolveMlKemParameterSet(snapshot)
|
|
6590
6725
|
});
|
|
6591
6726
|
return _AuthToken.create({
|
|
6592
6727
|
token: snapshot.token,
|
|
@@ -6654,7 +6789,9 @@ var AuthToken = class _AuthToken {
|
|
|
6654
6789
|
};
|
|
6655
6790
|
}
|
|
6656
6791
|
/**
|
|
6657
|
-
* Create snapshot for persistence
|
|
6792
|
+
* Create snapshot for persistence. The wallet's ML-KEM parameter set is recorded beside its
|
|
6793
|
+
* position and characters so a stepped-back ML-KEM-768 session restores as 768 rather than
|
|
6794
|
+
* silently taking the constructor default.
|
|
6658
6795
|
*/
|
|
6659
6796
|
toSnapshot() {
|
|
6660
6797
|
return {
|
|
@@ -6665,7 +6802,8 @@ var AuthToken = class _AuthToken {
|
|
|
6665
6802
|
...this.$__wallet ? {
|
|
6666
6803
|
wallet: {
|
|
6667
6804
|
position: this.$__wallet.position,
|
|
6668
|
-
characters: this.$__wallet.characters
|
|
6805
|
+
characters: this.$__wallet.characters,
|
|
6806
|
+
mlKemParameterSet: this.$__wallet.mlKemParameterSet
|
|
6669
6807
|
}
|
|
6670
6808
|
} : {}
|
|
6671
6809
|
};
|
|
@@ -6962,7 +7100,8 @@ var KnishIOClientConfigSchema2 = z.object({
|
|
|
6962
7100
|
// isn't rejected.
|
|
6963
7101
|
defaultRequestPolicy: z.enum(["cache-first", "cache-only", "network-only", "cache-and-network"]).nullable().optional(),
|
|
6964
7102
|
// Pluggable hardware envelope encryption secret storage provider
|
|
6965
|
-
secretStorage: z.unknown().optional()
|
|
7103
|
+
secretStorage: z.unknown().optional(),
|
|
7104
|
+
mlKemParameterSet: z.union([z.literal(1024), z.literal(768)]).optional()
|
|
6966
7105
|
}).strict();
|
|
6967
7106
|
var EnvironmentConfigSchema = z.object({
|
|
6968
7107
|
NODE_ENV: z.enum(["development", "production", "test"]).optional(),
|
|
@@ -9536,6 +9675,13 @@ var MutationProposeMolecule = class extends Mutation {
|
|
|
9536
9675
|
molecule() {
|
|
9537
9676
|
return this.$__molecule.toJSON ? this.$__molecule.toJSON() : this.$__molecule;
|
|
9538
9677
|
}
|
|
9678
|
+
/**
|
|
9679
|
+
* Fills the molecule with specific mutation data.
|
|
9680
|
+
* Subclasses override to build domain-specific atoms.
|
|
9681
|
+
* Default implementation is a no-op for pre-assembled molecules.
|
|
9682
|
+
*/
|
|
9683
|
+
fillMolecule(_params) {
|
|
9684
|
+
}
|
|
9539
9685
|
};
|
|
9540
9686
|
|
|
9541
9687
|
// src/response/ResponseCreateToken.ts
|
|
@@ -10641,6 +10787,7 @@ var KnishIOClient = class {
|
|
|
10641
10787
|
$__authTokenObjects = {};
|
|
10642
10788
|
$__authToken = null;
|
|
10643
10789
|
$__authInProcess = false;
|
|
10790
|
+
$__mlKemParameterSet = 1024;
|
|
10644
10791
|
$__remainderWallet = null;
|
|
10645
10792
|
lastMoleculeQuery = null;
|
|
10646
10793
|
abortControllers = /* @__PURE__ */ new Map();
|
|
@@ -10685,7 +10832,8 @@ var KnishIOClient = class {
|
|
|
10685
10832
|
client,
|
|
10686
10833
|
serverSdkVersion,
|
|
10687
10834
|
logging,
|
|
10688
|
-
defaultRequestPolicy
|
|
10835
|
+
defaultRequestPolicy,
|
|
10836
|
+
mlKemParameterSet: config.mlKemParameterSet ?? 1024
|
|
10689
10837
|
});
|
|
10690
10838
|
if (config.secretStorage) {
|
|
10691
10839
|
this.$__secretStorage = config.secretStorage;
|
|
@@ -10701,10 +10849,12 @@ var KnishIOClient = class {
|
|
|
10701
10849
|
client = null,
|
|
10702
10850
|
serverSdkVersion = 3,
|
|
10703
10851
|
logging = false,
|
|
10704
|
-
defaultRequestPolicy = null
|
|
10852
|
+
defaultRequestPolicy = null,
|
|
10853
|
+
mlKemParameterSet = 1024
|
|
10705
10854
|
}) {
|
|
10706
10855
|
this.reset();
|
|
10707
10856
|
this.$__logging = logging;
|
|
10857
|
+
this.setMlKemParameterSet(mlKemParameterSet);
|
|
10708
10858
|
this.$__authTokenObjects = {};
|
|
10709
10859
|
this.setUri(uri);
|
|
10710
10860
|
if (cellSlug) {
|
|
@@ -10725,6 +10875,17 @@ var KnishIOClient = class {
|
|
|
10725
10875
|
this.$__serverSdkVersion = serverSdkVersion;
|
|
10726
10876
|
this.$__defaultRequestPolicy = defaultRequestPolicy;
|
|
10727
10877
|
}
|
|
10878
|
+
getMlKemParameterSet() {
|
|
10879
|
+
return this.$__mlKemParameterSet || 1024;
|
|
10880
|
+
}
|
|
10881
|
+
setMlKemParameterSet(parameterSet) {
|
|
10882
|
+
const paramNum = Number(parameterSet);
|
|
10883
|
+
if (![1024, 768].includes(paramNum)) {
|
|
10884
|
+
throw new Error(`KnishIO: unsupported ML-KEM parameter set ${parameterSet}; expected 1024 or 768.`);
|
|
10885
|
+
}
|
|
10886
|
+
this.$__mlKemParameterSet = paramNum;
|
|
10887
|
+
return this;
|
|
10888
|
+
}
|
|
10728
10889
|
/**
|
|
10729
10890
|
* Get random uri from specified this.$__uris
|
|
10730
10891
|
*/
|
|
@@ -10961,7 +11122,8 @@ var KnishIOClient = class {
|
|
|
10961
11122
|
bundle,
|
|
10962
11123
|
token: "USER",
|
|
10963
11124
|
batchId: sourceWallet.batchId,
|
|
10964
|
-
characters: sourceWallet.characters
|
|
11125
|
+
characters: sourceWallet.characters,
|
|
11126
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
10965
11127
|
}));
|
|
10966
11128
|
return new Molecule({
|
|
10967
11129
|
secret,
|
|
@@ -10970,7 +11132,8 @@ var KnishIOClient = class {
|
|
|
10970
11132
|
remainderWallet: this.getRemainderWallet(),
|
|
10971
11133
|
cellSlug: this.getCellSlug(),
|
|
10972
11134
|
version: this.getServerSdkVersion(),
|
|
10973
|
-
continuIdPosition
|
|
11135
|
+
continuIdPosition,
|
|
11136
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
10974
11137
|
});
|
|
10975
11138
|
}
|
|
10976
11139
|
/**
|
|
@@ -11082,7 +11245,8 @@ var KnishIOClient = class {
|
|
|
11082
11245
|
}))?.payload();
|
|
11083
11246
|
if (!sourceWallet) {
|
|
11084
11247
|
sourceWallet = new Wallet({
|
|
11085
|
-
secret: this.getSecret()
|
|
11248
|
+
secret: this.getSecret(),
|
|
11249
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11086
11250
|
});
|
|
11087
11251
|
} else {
|
|
11088
11252
|
sourceWallet.key = Wallet.generateKey({
|
|
@@ -11125,7 +11289,8 @@ var KnishIOClient = class {
|
|
|
11125
11289
|
}
|
|
11126
11290
|
const recipientWallet = Wallet.create({
|
|
11127
11291
|
bundle: bundleHash,
|
|
11128
|
-
token
|
|
11292
|
+
token,
|
|
11293
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11129
11294
|
});
|
|
11130
11295
|
if (batchId !== null) {
|
|
11131
11296
|
recipientWallet.batchId = batchId;
|
|
@@ -11192,7 +11357,8 @@ var KnishIOClient = class {
|
|
|
11192
11357
|
const recipientWallets = recipients.map((recipient) => {
|
|
11193
11358
|
const recipientWallet = Wallet.create({
|
|
11194
11359
|
bundle: recipient.bundleHash,
|
|
11195
|
-
token
|
|
11360
|
+
token,
|
|
11361
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11196
11362
|
});
|
|
11197
11363
|
if (recipient.batchId !== null && recipient.batchId !== void 0) {
|
|
11198
11364
|
recipientWallet.batchId = recipient.batchId;
|
|
@@ -11816,7 +11982,8 @@ var KnishIOClient = class {
|
|
|
11816
11982
|
secret: this.getSecret(),
|
|
11817
11983
|
bundle: this.getBundle(),
|
|
11818
11984
|
token,
|
|
11819
|
-
batchId
|
|
11985
|
+
batchId,
|
|
11986
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11820
11987
|
});
|
|
11821
11988
|
await mutation.fillMolecule({
|
|
11822
11989
|
recipientWallet,
|
|
@@ -11884,7 +12051,8 @@ var KnishIOClient = class {
|
|
|
11884
12051
|
const recipientWallet = new Wallet({
|
|
11885
12052
|
secret: this.getSecret(),
|
|
11886
12053
|
bundle: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11887
|
-
token
|
|
12054
|
+
token,
|
|
12055
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11888
12056
|
});
|
|
11889
12057
|
await mutation.fillMolecule({
|
|
11890
12058
|
recipientWallet,
|
|
@@ -11961,7 +12129,8 @@ var KnishIOClient = class {
|
|
|
11961
12129
|
const newWallet = new Wallet({
|
|
11962
12130
|
secret: this.getSecret(),
|
|
11963
12131
|
bundle: this.getBundle(),
|
|
11964
|
-
token
|
|
12132
|
+
token,
|
|
12133
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
11965
12134
|
});
|
|
11966
12135
|
await mutation.fillMolecule(newWallet);
|
|
11967
12136
|
const response = await this.executeQuery(mutation);
|
|
@@ -12092,15 +12261,30 @@ var KnishIOClient = class {
|
|
|
12092
12261
|
async createPolicy({
|
|
12093
12262
|
metaType,
|
|
12094
12263
|
metaId,
|
|
12095
|
-
policy =
|
|
12264
|
+
policy = {}
|
|
12096
12265
|
}) {
|
|
12097
12266
|
this.log("info", `KnishIOClient::createPolicy() - Creating policy for ${metaType}:${metaId}...`);
|
|
12098
|
-
|
|
12267
|
+
const molecule = await this.createMolecule({});
|
|
12268
|
+
molecule.addPolicyAtom({
|
|
12099
12269
|
metaType,
|
|
12100
12270
|
metaId,
|
|
12101
|
-
meta:
|
|
12102
|
-
policy
|
|
12271
|
+
meta: {},
|
|
12272
|
+
policy: policy || {}
|
|
12103
12273
|
});
|
|
12274
|
+
molecule.addContinuIdAtom();
|
|
12275
|
+
molecule.sign({
|
|
12276
|
+
bundle: this.getBundle()
|
|
12277
|
+
});
|
|
12278
|
+
molecule.check();
|
|
12279
|
+
const query = await this.createMoleculeMutation({
|
|
12280
|
+
mutationClass: MutationProposeMolecule,
|
|
12281
|
+
molecule
|
|
12282
|
+
});
|
|
12283
|
+
const response = await this.executeQuery(query);
|
|
12284
|
+
if (!response) {
|
|
12285
|
+
throw new CodeException("Policy creation failed");
|
|
12286
|
+
}
|
|
12287
|
+
return response;
|
|
12104
12288
|
}
|
|
12105
12289
|
/**
|
|
12106
12290
|
* Create an identifier
|
|
@@ -12274,7 +12458,8 @@ var KnishIOClient = class {
|
|
|
12274
12458
|
this.setSecret(secret);
|
|
12275
12459
|
const wallet = new Wallet({
|
|
12276
12460
|
secret,
|
|
12277
|
-
token: "AUTH"
|
|
12461
|
+
token: "AUTH",
|
|
12462
|
+
mlKemParameterSet: this.getMlKemParameterSet()
|
|
12278
12463
|
});
|
|
12279
12464
|
const molecule = await this.createMolecule({
|
|
12280
12465
|
secret,
|
|
@@ -12674,7 +12859,7 @@ function createDefaultSecretStorage(options = {}) {
|
|
|
12674
12859
|
}
|
|
12675
12860
|
|
|
12676
12861
|
// src/index.ts
|
|
12677
|
-
var SDK_VERSION = "0.
|
|
12862
|
+
var SDK_VERSION = "1.0.0";
|
|
12678
12863
|
var SDK_NAME = "KnishIO-Client-TS";
|
|
12679
12864
|
var COMPATIBLE_SERVER_VERSIONS = [4, 5];
|
|
12680
12865
|
var SDK_INFO = {
|
|
@@ -12683,7 +12868,7 @@ var SDK_INFO = {
|
|
|
12683
12868
|
description: "TypeScript SDK for Knish.IO post-blockchain distributed ledger",
|
|
12684
12869
|
compatibleServerVersions: COMPATIBLE_SERVER_VERSIONS,
|
|
12685
12870
|
features: [
|
|
12686
|
-
"Post-quantum cryptography (XMSS, ML-
|
|
12871
|
+
"Post-quantum cryptography (XMSS, ML-KEM-1024)",
|
|
12687
12872
|
"Cross-platform compatibility",
|
|
12688
12873
|
"Type-safe APIs",
|
|
12689
12874
|
"DAG-based transaction processing",
|