@wishknish/knishio-client-ts 0.8.3 → 0.9.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.js CHANGED
@@ -939,9 +939,19 @@ var init_StackableUnitAmountException = __esm({
939
939
  });
940
940
 
941
941
  // src/exception/StackableUnitDecimalsException.ts
942
+ var StackableUnitDecimalsException, StackableUnitDecimalsException_default;
942
943
  var init_StackableUnitDecimalsException = __esm({
943
944
  "src/exception/StackableUnitDecimalsException.ts"() {
944
945
  init_BaseException();
946
+ StackableUnitDecimalsException = class extends BaseException {
947
+ /**
948
+ * Constructor using proper error type
949
+ */
950
+ constructor(message = "Stackable tokens with unit IDs cannot have decimal places!") {
951
+ super("STACKABLE_UNIT_DECIMALS_ERROR", message);
952
+ }
953
+ };
954
+ StackableUnitDecimalsException_default = StackableUnitDecimalsException;
945
955
  }
946
956
  });
947
957
 
@@ -1560,15 +1570,15 @@ var init_EnhancedResponse = __esm({
1560
1570
  // src/response/Response.ts
1561
1571
  var Response_exports = {};
1562
1572
  __export(Response_exports, {
1563
- default: () => Response
1573
+ default: () => Response2
1564
1574
  });
1565
- var Response;
1575
+ var Response2;
1566
1576
  var init_Response = __esm({
1567
1577
  "src/response/Response.ts"() {
1568
1578
  init_exception();
1569
1579
  init_Dot();
1570
1580
  init_EnhancedResponse();
1571
- Response = class {
1581
+ Response2 = class {
1572
1582
  dataKey;
1573
1583
  errorKey = "exception";
1574
1584
  $__payload = null;
@@ -1923,9 +1933,6 @@ function generateSecret(seed = null, length = CRYPTO_CONSTANTS.SECRET_LENGTH) {
1923
1933
  }
1924
1934
  }
1925
1935
  function generateBundleHash(secret, _source = null) {
1926
- if (!secret || secret.length === 0) {
1927
- throw new Error("Secret is required for bundle hash generation");
1928
- }
1929
1936
  const hash = shake256(secret, CRYPTO_CONSTANTS.BUNDLE_HASH_LENGTH * 4);
1930
1937
  return hash;
1931
1938
  }
@@ -3336,8 +3343,7 @@ var QUERY_TYPES = [
3336
3343
  "Batch",
3337
3344
  "ActiveSession",
3338
3345
  "Policy",
3339
- "Token",
3340
- "UserActivity"
3346
+ "Token"
3341
3347
  ];
3342
3348
  function createLookup(values) {
3343
3349
  return values.reduce((acc, value) => {
@@ -3596,6 +3602,29 @@ var Wallet = class _Wallet {
3596
3602
  }
3597
3603
  remainderWallet.tokenUnits = remainderTokenUnits;
3598
3604
  }
3605
+ /**
3606
+ * Split token units across MULTIPLE recipients (N-way sibling of splitUnits).
3607
+ *
3608
+ * The source retains the SENT union (all units leaving), each recipient gets its own
3609
+ * subset, and the remainder keeps the KEPT units (those not assigned to any recipient).
3610
+ * recipientUnitLists is parallel to recipientWallets. No-op when no units are sent.
3611
+ *
3612
+ * @param recipientUnitLists - per-recipient arrays of token unit IDs (parallel to recipientWallets)
3613
+ * @param recipientWallets - destination wallets
3614
+ * @param remainderWallet - wallet to receive the KEPT units
3615
+ */
3616
+ splitUnitsMulti(recipientUnitLists, recipientWallets, remainderWallet) {
3617
+ const sentIds = new Set(recipientUnitLists.flat());
3618
+ if (sentIds.size === 0) {
3619
+ return;
3620
+ }
3621
+ recipientWallets.forEach((recipientWallet, i) => {
3622
+ const ids = recipientUnitLists[i] ?? [];
3623
+ recipientWallet.tokenUnits = this.tokenUnits.filter((tokenUnit) => ids.includes(tokenUnit.id));
3624
+ });
3625
+ remainderWallet.tokenUnits = this.tokenUnits.filter((tokenUnit) => !sentIds.has(tokenUnit.id));
3626
+ this.tokenUnits = this.tokenUnits.filter((tokenUnit) => sentIds.has(tokenUnit.id));
3627
+ }
3599
3628
  /**
3600
3629
  * Get token units data
3601
3630
  * Stub for compatibility
@@ -3642,6 +3671,15 @@ var Wallet = class _Wallet {
3642
3671
  };
3643
3672
  }
3644
3673
  async decryptMessage(encryptedData) {
3674
+ const decryptedString = await this._mlkemDecryptToString(encryptedData);
3675
+ return decryptedString === null ? null : JSON.parse(decryptedString);
3676
+ }
3677
+ /**
3678
+ * ML-KEM768 decapsulate + AES-256-GCM decrypt → the RAW decrypted UTF-8 string (no JSON.parse).
3679
+ * Shared by {@link decryptMessage} (which JSON.parses the result) and the PQ CipherHash transport
3680
+ * ({@link decryptMyMessageML768}, which needs the raw response JSON text). PQ-transport Phase E.
3681
+ */
3682
+ async _mlkemDecryptToString(encryptedData) {
3645
3683
  const { cipherText, encryptedMessage } = encryptedData;
3646
3684
  let sharedSecret;
3647
3685
  try {
@@ -3670,9 +3708,8 @@ var Wallet = class _Wallet {
3670
3708
  console.info("Wallet::decryptMessage() - deserialized encrypted message", deserializedEncryptedMessage);
3671
3709
  return null;
3672
3710
  }
3673
- let decryptedString;
3674
3711
  try {
3675
- decryptedString = new TextDecoder().decode(decryptedUint8);
3712
+ return new TextDecoder().decode(decryptedUint8);
3676
3713
  } catch (e) {
3677
3714
  console.warn("Wallet::decryptMessage() - Decoding failed", e);
3678
3715
  console.info("Wallet::decryptMessage() - my public key", this.pubkey);
@@ -3681,7 +3718,40 @@ var Wallet = class _Wallet {
3681
3718
  console.info("Wallet::decryptMessage() - decrypted Uint8Array", decryptedUint8);
3682
3719
  return null;
3683
3720
  }
3684
- return JSON.parse(decryptedString);
3721
+ }
3722
+ /**
3723
+ * Canonical cross-SDK hashShare for a public key: standard base64 of SHAKE256(pubkey_utf8, 8 bytes)
3724
+ * — byte-matches the validator's hash_share and the JS/Kotlin/PHP hashShare. `shake256(pubkey, 64)`
3725
+ * = 64 bits = 8 bytes (hex) → hex-decode → standard base64 via serializeKey. PQ-transport Phase E.
3726
+ */
3727
+ hashShare(pubkey) {
3728
+ const hex = shake256(pubkey, 64);
3729
+ const bytes = new Uint8Array(hex.length / 2);
3730
+ for (let i = 0; i < bytes.length; i++) {
3731
+ bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
3732
+ }
3733
+ return this.serializeKey(bytes);
3734
+ }
3735
+ /**
3736
+ * Post-quantum (ML-KEM768) CipherHash request envelope: a stringified single-recipient map
3737
+ * `{ "<hashShare(recipientPubkey)>": {cipherText, encryptedMessage} }` (object-valued, via
3738
+ * {@link encryptMessage}). Matches the Rust validator's CipherHash handler. PQ-transport Phase E.
3739
+ */
3740
+ async encryptStringML768(message, recipientPubkey) {
3741
+ const envelope = await this.encryptMessage(message, recipientPubkey);
3742
+ return JSON.stringify({ [this.hashShare(recipientPubkey)]: envelope });
3743
+ }
3744
+ /**
3745
+ * Decrypt a CipherHash response map addressed to THIS wallet's ML-KEM pubkey
3746
+ * (`hashShare(this.pubkey)`) → the RAW decrypted GraphQL response JSON text (NOT JSON.parsed;
3747
+ * it replaces the HTTP response body for the normal parser). `null` if no entry / decrypt fails.
3748
+ */
3749
+ async decryptMyMessageML768(map) {
3750
+ const envelope = map[this.hashShare(this.pubkey)];
3751
+ if (!envelope) {
3752
+ return null;
3753
+ }
3754
+ return this._mlkemDecryptToString(envelope);
3685
3755
  }
3686
3756
  // =============================================================================
3687
3757
  // SYMMETRIC ENCRYPTION HELPERS (AES-GCM with shared secret)
@@ -4980,6 +5050,46 @@ var Molecule = class _Molecule {
4980
5050
  }));
4981
5051
  return this;
4982
5052
  }
5053
+ /**
5054
+ * Initialize a MULTI-recipient V-type molecule: one source debits its FULL balance to fund
5055
+ * N recipients (each its own amount + stackable units) plus a remainder back to the sender.
5056
+ * Multi-recipient sibling of initValue (WP line 544: fund multiple recipients with one
5057
+ * transaction). recipientWallets is parallel to amounts.
5058
+ */
5059
+ initValues({
5060
+ recipientWallets,
5061
+ amounts
5062
+ }) {
5063
+ if (!this.sourceWallet) {
5064
+ throw new Error("Source wallet required for value transfer");
5065
+ }
5066
+ const total = amounts.reduce((sum, amount) => sum + amount, 0);
5067
+ if (Number(this.sourceWallet.balance) - total < 0) {
5068
+ throw new BalanceInsufficientException();
5069
+ }
5070
+ this.addAtom(Atom.create({
5071
+ isotope: "V",
5072
+ wallet: this.sourceWallet,
5073
+ value: -Number(this.sourceWallet.balance)
5074
+ }));
5075
+ recipientWallets.forEach((recipientWallet, i) => {
5076
+ this.addAtom(Atom.create({
5077
+ isotope: "V",
5078
+ wallet: recipientWallet,
5079
+ value: amounts[i],
5080
+ metaType: "walletBundle",
5081
+ metaId: recipientWallet.bundle
5082
+ }));
5083
+ });
5084
+ this.addAtom(Atom.create({
5085
+ isotope: "V",
5086
+ wallet: this.remainderWallet,
5087
+ value: Number(this.sourceWallet.balance) - total,
5088
+ metaType: "walletBundle",
5089
+ metaId: this.remainderWallet.bundle
5090
+ }));
5091
+ return this;
5092
+ }
4983
5093
  /**
4984
5094
  * Sign the molecule with one-time signature
4985
5095
  * Matches JavaScript SDK sign method
@@ -5737,7 +5847,7 @@ var Decimal = class _Decimal {
5737
5847
  * @param debug Enable debug logging
5738
5848
  * @returns 0 if equal, 1 if value1 > value2, -1 if value1 < value2
5739
5849
  */
5740
- static cmp(value1, value2, debug = false) {
5850
+ static cmp(value1, value2, _debug = false) {
5741
5851
  const val1 = _Decimal.val(value1) * MULTIPLIER;
5742
5852
  const val2 = _Decimal.val(value2) * MULTIPLIER;
5743
5853
  if (Math.abs(val1 - val2) < 1) {
@@ -5752,6 +5862,14 @@ var Decimal = class _Decimal {
5752
5862
  return _Decimal.cmp(value1, value2) === 0;
5753
5863
  }
5754
5864
  };
5865
+ var CIPHER_HASH_QUERY = "query ( $Hash: String! ) { CipherHash ( Hash: $Hash ) { hash } }";
5866
+ function parseOperation(query) {
5867
+ const typeMatch = (query || "").match(/\b(query|mutation|subscription)\b/i);
5868
+ const type = typeMatch?.[1]?.toLowerCase() ?? "query";
5869
+ const braceIdx = (query || "").indexOf("{");
5870
+ const nameMatch = braceIdx >= 0 ? query.slice(braceIdx + 1).match(/[A-Za-z_][A-Za-z0-9_]*/) : null;
5871
+ return { type, name: nameMatch?.[0] ?? "" };
5872
+ }
5755
5873
  var GraphQLClient = class {
5756
5874
  $__client;
5757
5875
  $__authToken = "";
@@ -5797,6 +5915,10 @@ var GraphQLClient = class {
5797
5915
  return createClient$1({
5798
5916
  url: serverUri,
5799
5917
  exchanges,
5918
+ // PQ-transport Phase E: when encryption is on, route fetch through the CipherHash wrapper
5919
+ // (encrypt the request body to the validator's ML-KEM pubkey, decrypt the response).
5920
+ // Omitted → urql uses the global fetch (plaintext).
5921
+ ...this.cipherLink ? { fetch: ((input, init) => this.cipherFetch(input, init)) } : {},
5800
5922
  fetchOptions: () => ({
5801
5923
  headers: {
5802
5924
  "X-Auth-Token": this.$__authToken
@@ -5806,6 +5928,62 @@ var GraphQLClient = class {
5806
5928
  })
5807
5929
  });
5808
5930
  }
5931
+ /**
5932
+ * Whether an outgoing GraphQL request body should be wrapped in CipherHash. Bypass (plaintext):
5933
+ * introspection `__schema`, `ContinuId`, the `AccessToken` mutation, and the U-isotope
5934
+ * `ProposeMolecule` (auth bootstrap — the key exchange itself can't be encrypted). Mirrors the
5935
+ * Kotlin/PHP/validator bypass set.
5936
+ */
5937
+ shouldEncrypt(body) {
5938
+ let parsed;
5939
+ try {
5940
+ parsed = JSON.parse(body);
5941
+ } catch (e) {
5942
+ return false;
5943
+ }
5944
+ const { type, name } = parseOperation(parsed.query);
5945
+ if (type === "query" && (name === "__schema" || name === "ContinuId")) return false;
5946
+ if (type === "mutation" && name === "AccessToken") return false;
5947
+ if (type === "mutation" && name === "ProposeMolecule") {
5948
+ const isotope = parsed.variables?.molecule?.atoms?.[0]?.isotope;
5949
+ if (isotope === "U") return false;
5950
+ }
5951
+ return true;
5952
+ }
5953
+ /**
5954
+ * Custom `fetch` that wraps a GraphQL request in the ML-KEM CipherHash envelope and decrypts the
5955
+ * response (PQ-transport Phase E). Operates on the raw POST body (mirrors the JS/Kotlin transform).
5956
+ * Reads the CURRENT client wallet + validator pubkey from auth.
5957
+ */
5958
+ async cipherFetch(input, init) {
5959
+ const wallet = this.$__wallet;
5960
+ const serverPubkey = this.$__pubkey;
5961
+ let encryptedRequest = false;
5962
+ let requestInit = init;
5963
+ if (wallet && serverPubkey && init && typeof init.body === "string" && this.shouldEncrypt(init.body)) {
5964
+ const hashVar = await wallet.encryptStringML768(init.body, serverPubkey);
5965
+ requestInit = { ...init, body: JSON.stringify({ query: CIPHER_HASH_QUERY, variables: { Hash: hashVar } }) };
5966
+ encryptedRequest = true;
5967
+ }
5968
+ const response = await fetch(input, requestInit);
5969
+ if (!encryptedRequest) {
5970
+ return response;
5971
+ }
5972
+ const text = await response.text();
5973
+ const init2 = { status: response.status, statusText: response.statusText, headers: response.headers };
5974
+ let parsed;
5975
+ try {
5976
+ parsed = JSON.parse(text);
5977
+ } catch (e) {
5978
+ return new Response(text, init2);
5979
+ }
5980
+ const hash = parsed?.data?.CipherHash?.hash;
5981
+ if (typeof hash !== "string") {
5982
+ return new Response(text, init2);
5983
+ }
5984
+ const decrypted = await wallet.decryptMyMessageML768(JSON.parse(hash));
5985
+ return new Response(decrypted != null ? decrypted : text, init2);
5986
+ }
5809
5987
  setAuthData({
5810
5988
  token,
5811
5989
  pubkey,
@@ -6100,8 +6278,8 @@ var Query = class {
6100
6278
  * Returns a Response object
6101
6279
  */
6102
6280
  createResponse(json) {
6103
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
6104
- return new Response2({
6281
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
6282
+ return new Response3({
6105
6283
  query: this,
6106
6284
  json
6107
6285
  });
@@ -6171,8 +6349,8 @@ var Query = class {
6171
6349
  } catch (error) {
6172
6350
  if (error.name === "AbortError") {
6173
6351
  this.knishIOClient.log("warn", "Query was cancelled");
6174
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
6175
- return new Response2({
6352
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
6353
+ return new Response3({
6176
6354
  query: this,
6177
6355
  json: { data: null, errors: [{ message: "Query was cancelled" }] }
6178
6356
  });
@@ -6216,8 +6394,8 @@ var Mutation = class extends Query {
6216
6394
  } catch (error) {
6217
6395
  if (error.name === "AbortError") {
6218
6396
  this.knishIOClient.log("warn", "Mutation was cancelled");
6219
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
6220
- return new Response2({
6397
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
6398
+ return new Response3({
6221
6399
  query: this,
6222
6400
  json: { data: null, errors: [{ message: "Mutation was cancelled" }] }
6223
6401
  });
@@ -7153,7 +7331,90 @@ var ConfigValidator = class _ConfigValidator {
7153
7331
 
7154
7332
  // src/response/ResponseBalance.ts
7155
7333
  init_Response();
7156
- var ResponseBalance = class _ResponseBalance extends Response {
7334
+
7335
+ // src/core/TokenUnit.ts
7336
+ var TokenUnit = class _TokenUnit {
7337
+ id;
7338
+ name;
7339
+ metas;
7340
+ /**
7341
+ * Create new TokenUnit instance
7342
+ * Matches JavaScript SDK constructor signature exactly
7343
+ */
7344
+ constructor(id, name, metas) {
7345
+ this.id = id;
7346
+ this.name = name;
7347
+ this.metas = metas || {};
7348
+ }
7349
+ /**
7350
+ * Create TokenUnit from GraphQL response data
7351
+ * Matches JavaScript SDK createFromGraphQL method exactly
7352
+ */
7353
+ static createFromGraphQL(data) {
7354
+ let metas = data.metas || {};
7355
+ if (Array.isArray(metas) && metas.length) {
7356
+ try {
7357
+ metas = JSON.parse(metas);
7358
+ if (!metas) {
7359
+ metas = {};
7360
+ }
7361
+ } catch (error) {
7362
+ metas = {};
7363
+ }
7364
+ }
7365
+ return new _TokenUnit(
7366
+ data.id,
7367
+ data.name,
7368
+ metas
7369
+ );
7370
+ }
7371
+ /**
7372
+ * Create TokenUnit from database array data
7373
+ * Matches JavaScript SDK createFromDB method exactly
7374
+ */
7375
+ static createFromDB(data) {
7376
+ return new _TokenUnit(
7377
+ data[0],
7378
+ data[1],
7379
+ data.length > 2 ? data[2] : {}
7380
+ );
7381
+ }
7382
+ /**
7383
+ * Get fragment zone from metadata
7384
+ * Matches JavaScript SDK getFragmentZone method exactly
7385
+ */
7386
+ getFragmentZone() {
7387
+ return this.metas.fragmentZone || null;
7388
+ }
7389
+ /**
7390
+ * Get fused token units from metadata
7391
+ * Matches JavaScript SDK getFusedTokenUnits method exactly
7392
+ */
7393
+ getFusedTokenUnits() {
7394
+ return this.metas.fusedTokenUnits || null;
7395
+ }
7396
+ /**
7397
+ * Convert to data array format
7398
+ * Matches JavaScript SDK toData method exactly
7399
+ */
7400
+ toData() {
7401
+ return [this.id, this.name, this.metas];
7402
+ }
7403
+ /**
7404
+ * Convert to GraphQL response format
7405
+ * Matches JavaScript SDK toGraphQLResponse method exactly
7406
+ */
7407
+ toGraphQLResponse() {
7408
+ return {
7409
+ id: this.id,
7410
+ name: this.name,
7411
+ metas: JSON.stringify(this.metas)
7412
+ };
7413
+ }
7414
+ };
7415
+
7416
+ // src/response/ResponseBalance.ts
7417
+ var ResponseBalance = class _ResponseBalance extends Response2 {
7157
7418
  /**
7158
7419
  * Class constructor
7159
7420
  */
@@ -7215,6 +7476,11 @@ var ResponseBalance = class _ResponseBalance extends Response {
7215
7476
  wallet.tokenSupply = data.token.supply;
7216
7477
  wallet.tokenFungibility = data.token.fungibility;
7217
7478
  }
7479
+ if (data.tokenUnits && data.tokenUnits.length) {
7480
+ for (const tokenUnitData of data.tokenUnits) {
7481
+ wallet.tokenUnits.push(TokenUnit.createFromGraphQL(tokenUnitData));
7482
+ }
7483
+ }
7218
7484
  if (data.tradeRates && data.tradeRates.length) {
7219
7485
  for (const tradeRate of data.tradeRates) {
7220
7486
  wallet.tradeRates[tradeRate.tokenSlug] = tradeRate.amount;
@@ -7272,90 +7538,7 @@ var QueryBalance = class extends Query {
7272
7538
 
7273
7539
  // src/response/ResponseWalletList.ts
7274
7540
  init_Response();
7275
-
7276
- // src/core/TokenUnit.ts
7277
- var TokenUnit = class _TokenUnit {
7278
- id;
7279
- name;
7280
- metas;
7281
- /**
7282
- * Create new TokenUnit instance
7283
- * Matches JavaScript SDK constructor signature exactly
7284
- */
7285
- constructor(id, name, metas) {
7286
- this.id = id;
7287
- this.name = name;
7288
- this.metas = metas || {};
7289
- }
7290
- /**
7291
- * Create TokenUnit from GraphQL response data
7292
- * Matches JavaScript SDK createFromGraphQL method exactly
7293
- */
7294
- static createFromGraphQL(data) {
7295
- let metas = data.metas || {};
7296
- if (Array.isArray(metas) && metas.length) {
7297
- try {
7298
- metas = JSON.parse(metas);
7299
- if (!metas) {
7300
- metas = {};
7301
- }
7302
- } catch (error) {
7303
- metas = {};
7304
- }
7305
- }
7306
- return new _TokenUnit(
7307
- data.id,
7308
- data.name,
7309
- metas
7310
- );
7311
- }
7312
- /**
7313
- * Create TokenUnit from database array data
7314
- * Matches JavaScript SDK createFromDB method exactly
7315
- */
7316
- static createFromDB(data) {
7317
- return new _TokenUnit(
7318
- data[0],
7319
- data[1],
7320
- data.length > 2 ? data[2] : {}
7321
- );
7322
- }
7323
- /**
7324
- * Get fragment zone from metadata
7325
- * Matches JavaScript SDK getFragmentZone method exactly
7326
- */
7327
- getFragmentZone() {
7328
- return this.metas.fragmentZone || null;
7329
- }
7330
- /**
7331
- * Get fused token units from metadata
7332
- * Matches JavaScript SDK getFusedTokenUnits method exactly
7333
- */
7334
- getFusedTokenUnits() {
7335
- return this.metas.fusedTokenUnits || null;
7336
- }
7337
- /**
7338
- * Convert to data array format
7339
- * Matches JavaScript SDK toData method exactly
7340
- */
7341
- toData() {
7342
- return [this.id, this.name, this.metas];
7343
- }
7344
- /**
7345
- * Convert to GraphQL response format
7346
- * Matches JavaScript SDK toGraphQLResponse method exactly
7347
- */
7348
- toGraphQLResponse() {
7349
- return {
7350
- id: this.id,
7351
- name: this.name,
7352
- metas: JSON.stringify(this.metas)
7353
- };
7354
- }
7355
- };
7356
-
7357
- // src/response/ResponseWalletList.ts
7358
- var ResponseWalletList = class _ResponseWalletList extends Response {
7541
+ var ResponseWalletList = class _ResponseWalletList extends Response2 {
7359
7542
  /**
7360
7543
  * Class constructor
7361
7544
  * Matches JavaScript SDK constructor signature exactly
@@ -7494,7 +7677,7 @@ var QueryWalletList = class extends Query {
7494
7677
 
7495
7678
  // src/response/ResponseWalletBundle.ts
7496
7679
  init_Response();
7497
- var ResponseWalletBundle = class extends Response {
7680
+ var ResponseWalletBundle = class extends Response2 {
7498
7681
  /**
7499
7682
  * Class constructor
7500
7683
  */
@@ -7561,7 +7744,7 @@ var QueryWalletBundle = class extends Query {
7561
7744
 
7562
7745
  // src/response/ResponseContinuId.ts
7563
7746
  init_Response();
7564
- var ResponseContinuId = class extends Response {
7747
+ var ResponseContinuId = class extends Response2 {
7565
7748
  /**
7566
7749
  * Class constructor
7567
7750
  * Matches JavaScript SDK constructor signature exactly
@@ -7641,7 +7824,7 @@ var QueryContinuId = class extends Query {
7641
7824
 
7642
7825
  // src/response/ResponseMetaType.ts
7643
7826
  init_Response();
7644
- var ResponseMetaType = class extends Response {
7827
+ var ResponseMetaType = class extends Response2 {
7645
7828
  /**
7646
7829
  * Class constructor
7647
7830
  * Matches JavaScript SDK constructor signature exactly
@@ -7866,7 +8049,7 @@ var QueryBatch = class _QueryBatch extends Query {
7866
8049
  * Matches JavaScript SDK createResponse method exactly
7867
8050
  */
7868
8051
  createResponse(json) {
7869
- const responseObject = new Response({
8052
+ const responseObject = new Response2({
7870
8053
  query: this,
7871
8054
  json
7872
8055
  });
@@ -7895,7 +8078,7 @@ var QueryBatchHistory = class extends Query {
7895
8078
  * Returns a Response object
7896
8079
  */
7897
8080
  createResponse(json) {
7898
- const responseObject = new Response({
8081
+ const responseObject = new Response2({
7899
8082
  query: this,
7900
8083
  json
7901
8084
  });
@@ -7906,7 +8089,7 @@ var QueryBatchHistory = class extends Query {
7906
8089
 
7907
8090
  // src/response/ResponseAtom.ts
7908
8091
  init_Response();
7909
- var ResponseAtom = class extends Response {
8092
+ var ResponseAtom = class extends Response2 {
7910
8093
  /**
7911
8094
  * Class constructor
7912
8095
  * Matches JavaScript SDK constructor signature exactly
@@ -8147,7 +8330,7 @@ var QueryAtom = class extends Query {
8147
8330
 
8148
8331
  // src/response/ResponsePolicy.ts
8149
8332
  init_Response();
8150
- var ResponsePolicy = class extends Response {
8333
+ var ResponsePolicy = class extends Response2 {
8151
8334
  /**
8152
8335
  * Constructor
8153
8336
  */
@@ -8209,7 +8392,7 @@ var QueryPolicy = class extends Query {
8209
8392
 
8210
8393
  // src/response/ResponseQueryActiveSession.ts
8211
8394
  init_Response();
8212
- var ResponseQueryActiveSession = class extends Response {
8395
+ var ResponseQueryActiveSession = class extends Response2 {
8213
8396
  /**
8214
8397
  * Constructor
8215
8398
  */
@@ -8278,131 +8461,6 @@ var QueryActiveSession = class extends Query {
8278
8461
  }
8279
8462
  };
8280
8463
 
8281
- // src/response/ResponseQueryUserActivity.ts
8282
- init_Response();
8283
- var ResponseQueryUserActivity = class extends Response {
8284
- /**
8285
- * Constructor
8286
- */
8287
- constructor({
8288
- query,
8289
- json
8290
- }) {
8291
- super({
8292
- query,
8293
- json,
8294
- dataKey: "data.UserActivity"
8295
- });
8296
- }
8297
- /**
8298
- * Returns processed user activity data
8299
- */
8300
- payload() {
8301
- const data = JSON.parse(JSON.stringify(this.data()));
8302
- if (data.instances) {
8303
- for (const datum of data.instances) {
8304
- if (datum.jsonData) {
8305
- datum.jsonData = JSON.parse(datum.jsonData);
8306
- }
8307
- }
8308
- }
8309
- return data;
8310
- }
8311
- };
8312
- var QueryUserActivity = class extends Query {
8313
- /**
8314
- * Constructor
8315
- */
8316
- constructor(graphQLClient, knishIOClient) {
8317
- super(graphQLClient, knishIOClient);
8318
- this.$__query = gql`
8319
- query UserActivity(
8320
- $bundleHash: String
8321
- $metaType: String
8322
- $metaId: String
8323
- $ipAddress: String
8324
- $browser: String
8325
- $osCpu: String
8326
- $resolution: String
8327
- $timeZone: String
8328
- $countBy: [CountByUserActivity]
8329
- $interval: span
8330
- ) {
8331
- UserActivity(
8332
- bundleHash: $bundleHash
8333
- metaType: $metaType
8334
- metaId: $metaId
8335
- ipAddress: $ipAddress
8336
- browser: $browser
8337
- osCpu: $osCpu
8338
- resolution: $resolution
8339
- timeZone: $timeZone
8340
- countBy: $countBy
8341
- interval: $interval
8342
- ) {
8343
- createdAt
8344
- bundleHash
8345
- metaType
8346
- metaId
8347
- instances {
8348
- bundleHash
8349
- metaType
8350
- metaId
8351
- jsonData
8352
- createdAt
8353
- updatedAt
8354
- }
8355
- instanceCount {
8356
- ...SubFields
8357
- ...Recursive
8358
- }
8359
- }
8360
- }
8361
-
8362
- fragment SubFields on InstanceCountType {
8363
- id
8364
- count
8365
- }
8366
-
8367
- fragment Recursive on InstanceCountType {
8368
- instances {
8369
- ...SubFields
8370
- instances {
8371
- ...SubFields
8372
- instances {
8373
- ...SubFields
8374
- instances {
8375
- ...SubFields
8376
- instances {
8377
- ...SubFields
8378
- instances {
8379
- ...SubFields
8380
- instances {
8381
- ...SubFields
8382
- instances {
8383
- ...SubFields
8384
- }
8385
- }
8386
- }
8387
- }
8388
- }
8389
- }
8390
- }
8391
- }
8392
- }
8393
- `;
8394
- }
8395
- /**
8396
- * Returns a Response object
8397
- */
8398
- createResponse(json) {
8399
- return new ResponseQueryUserActivity({
8400
- query: this,
8401
- json
8402
- });
8403
- }
8404
- };
8405
-
8406
8464
  // src/query/QueryToken.ts
8407
8465
  init_Response();
8408
8466
  var QueryToken = class extends Query {
@@ -8429,7 +8487,7 @@ var QueryToken = class extends Query {
8429
8487
  * Creates a Response object
8430
8488
  */
8431
8489
  createResponse(json) {
8432
- return new Response({
8490
+ return new Response2({
8433
8491
  query: this,
8434
8492
  json,
8435
8493
  dataKey: "data.Token"
@@ -8439,7 +8497,7 @@ var QueryToken = class extends Query {
8439
8497
 
8440
8498
  // src/response/ResponseMetaTypeViaAtom.ts
8441
8499
  init_Response();
8442
- var ResponseMetaTypeViaAtom = class extends Response {
8500
+ var ResponseMetaTypeViaAtom = class extends Response2 {
8443
8501
  /**
8444
8502
  * Class constructor
8445
8503
  * Matches JavaScript SDK constructor signature exactly
@@ -8597,7 +8655,7 @@ var QueryMetaTypeViaAtom = class extends Query {
8597
8655
 
8598
8656
  // src/response/ResponseMetaTypeViaMolecule.ts
8599
8657
  init_Response();
8600
- var ResponseMetaTypeViaMolecule = class _ResponseMetaTypeViaMolecule extends Response {
8658
+ var ResponseMetaTypeViaMolecule = class _ResponseMetaTypeViaMolecule extends Response2 {
8601
8659
  /**
8602
8660
  * Class constructor
8603
8661
  */
@@ -8843,7 +8901,7 @@ var QueryMetaTypeViaMolecule = class extends Query {
8843
8901
 
8844
8902
  // src/response/ResponseEmbeddingStatus.ts
8845
8903
  init_Response();
8846
- var ResponseEmbeddingStatus = class extends Response {
8904
+ var ResponseEmbeddingStatus = class extends Response2 {
8847
8905
  /**
8848
8906
  * Class constructor
8849
8907
  */
@@ -8926,7 +8984,7 @@ init_Dot();
8926
8984
  init_MolecularHashMismatchException();
8927
8985
  init_SignatureMismatchException();
8928
8986
  init_AtomIndexException();
8929
- var ResponseProposeMolecule = class extends Response {
8987
+ var ResponseProposeMolecule = class extends Response2 {
8930
8988
  $__clientMolecule;
8931
8989
  /**
8932
8990
  * Class constructor
@@ -9236,6 +9294,20 @@ var MutationTransferTokens = class extends MutationProposeMolecule {
9236
9294
  this.$__molecule.sign({});
9237
9295
  this.$__molecule.check(this.$__molecule.sourceWallet);
9238
9296
  }
9297
+ /**
9298
+ * Fills the Molecule for a MULTI-recipient transfer (one source funds N recipients)
9299
+ */
9300
+ fillMoleculeMulti({
9301
+ recipientWallets,
9302
+ amounts
9303
+ }) {
9304
+ this.$__molecule.initValues({
9305
+ recipientWallets,
9306
+ amounts
9307
+ });
9308
+ this.$__molecule.sign({});
9309
+ this.$__molecule.check(this.$__molecule.sourceWallet);
9310
+ }
9239
9311
  /**
9240
9312
  * Builds a Response object out of a JSON object
9241
9313
  * Matches JavaScript SDK createResponse method signature exactly
@@ -9296,7 +9368,8 @@ var MutationClaimShadowWallet = class extends MutationProposeMolecule {
9296
9368
  bundle: this.$__molecule.bundle,
9297
9369
  token,
9298
9370
  batchId
9299
- })(this.$__molecule).initShadowWalletClaim(wallet);
9371
+ });
9372
+ this.$__molecule.initShadowWalletClaim(wallet);
9300
9373
  this.$__molecule.sign({});
9301
9374
  this.$__molecule.check();
9302
9375
  }
@@ -9422,7 +9495,7 @@ var MutationCreateIdentifier = class extends MutationProposeMolecule {
9422
9495
 
9423
9496
  // src/response/ResponseActiveSession.ts
9424
9497
  init_Response();
9425
- var ResponseActiveSession = class extends Response {
9498
+ var ResponseActiveSession = class extends Response2 {
9426
9499
  /**
9427
9500
  * Constructor
9428
9501
  */
@@ -9613,7 +9686,7 @@ var MutationRequestAuthorization = class extends MutationProposeMolecule {
9613
9686
  init_Response();
9614
9687
  init_Dot();
9615
9688
  init_exception();
9616
- var ResponseRequestAuthorizationGuest = class extends Response {
9689
+ var ResponseRequestAuthorizationGuest = class extends Response2 {
9617
9690
  /**
9618
9691
  * Constructor
9619
9692
  */
@@ -9729,7 +9802,7 @@ var MutationRequestAuthorizationGuest = class extends Mutation {
9729
9802
  // src/response/ResponseLinkIdentifier.ts
9730
9803
  init_Response();
9731
9804
  init_Dot();
9732
- var ResponseLinkIdentifier = class extends Response {
9805
+ var ResponseLinkIdentifier = class extends Response2 {
9733
9806
  /**
9734
9807
  * Constructor
9735
9808
  */
@@ -10542,6 +10615,75 @@ var KnishIOClient = class {
10542
10615
  });
10543
10616
  return await this.executeQuery(query);
10544
10617
  }
10618
+ /**
10619
+ * Fund N recipients from a single source in ONE molecule (multi-recipient sibling of
10620
+ * transferToken). Each recipient gets its own subset of stackable units (or a fungible
10621
+ * amount); a remainder returns the rest to the sender. Conserves:
10622
+ * -balance + Σamounts + (balance - Σ) === 0.
10623
+ *
10624
+ * @param token - token slug
10625
+ * @param recipients - destinations (bundleHash + units OR amount + optional batchId)
10626
+ * @param sourceWallet - optional pre-resolved source (defaults to the client's own wallet)
10627
+ */
10628
+ async transferTokens({
10629
+ token,
10630
+ recipients,
10631
+ sourceWallet = null
10632
+ }) {
10633
+ const amounts = recipients.map((recipient) => {
10634
+ const unitCount = recipient.units ? recipient.units.length : 0;
10635
+ if (unitCount > 0) {
10636
+ if (recipient.amount !== null && recipient.amount !== void 0 && recipient.amount > 0) {
10637
+ throw new StackableUnitAmountException_default();
10638
+ }
10639
+ return unitCount;
10640
+ }
10641
+ return recipient.amount ?? 0;
10642
+ });
10643
+ const total = amounts.reduce((sum, amount) => sum + amount, 0);
10644
+ if (sourceWallet === null) {
10645
+ sourceWallet = await this.querySourceWallet({
10646
+ token,
10647
+ amount: total
10648
+ });
10649
+ }
10650
+ if (sourceWallet === null || Decimal.cmp(Number(sourceWallet.balance), total) < 0) {
10651
+ throw new TransferBalanceException();
10652
+ }
10653
+ const recipientWallets = recipients.map((recipient) => {
10654
+ const recipientWallet = Wallet.create({
10655
+ bundle: recipient.bundleHash,
10656
+ token
10657
+ });
10658
+ if (recipient.batchId !== null && recipient.batchId !== void 0) {
10659
+ recipientWallet.batchId = recipient.batchId;
10660
+ } else {
10661
+ recipientWallet.initBatchId({ sourceWallet });
10662
+ }
10663
+ return recipientWallet;
10664
+ });
10665
+ const remainderWallet = sourceWallet.createRemainder(this.getSecret());
10666
+ if (recipients.some((recipient) => recipient.units && recipient.units.length > 0)) {
10667
+ sourceWallet.splitUnitsMulti(
10668
+ recipients.map((recipient) => recipient.units ?? []),
10669
+ recipientWallets,
10670
+ remainderWallet
10671
+ );
10672
+ }
10673
+ const molecule = await this.createMolecule({
10674
+ sourceWallet,
10675
+ remainderWallet
10676
+ });
10677
+ const query = await this.createMoleculeMutation({
10678
+ mutationClass: MutationTransferTokens,
10679
+ molecule
10680
+ });
10681
+ query.fillMoleculeMulti({
10682
+ recipientWallets,
10683
+ amounts
10684
+ });
10685
+ return await this.executeQuery(query);
10686
+ }
10545
10687
  /**
10546
10688
  * Request authorization token (guest or profile)
10547
10689
  *
@@ -10998,36 +11140,6 @@ var KnishIOClient = class {
10998
11140
  metaId
10999
11141
  });
11000
11142
  }
11001
- /**
11002
- * Query user activity
11003
- */
11004
- async queryUserActivity({
11005
- bundleHash,
11006
- metaType,
11007
- metaId,
11008
- ipAddress = null,
11009
- browser = null,
11010
- osCpu = null,
11011
- resolution = null,
11012
- timeZone = null,
11013
- countBy = null,
11014
- interval = null
11015
- }) {
11016
- const query = this.createQuery(QueryUserActivity);
11017
- const variables = {
11018
- bundleHash,
11019
- metaType,
11020
- metaId
11021
- };
11022
- if (ipAddress !== null) variables.ipAddress = ipAddress;
11023
- if (browser !== null) variables.browser = browser;
11024
- if (osCpu !== null) variables.osCpu = osCpu;
11025
- if (resolution !== null) variables.resolution = resolution;
11026
- if (timeZone !== null) variables.timeZone = timeZone;
11027
- if (countBy !== null) variables.countBy = countBy;
11028
- if (interval !== null) variables.interval = interval;
11029
- return this.executeQuery(query, variables);
11030
- }
11031
11143
  /**
11032
11144
  * Query token information
11033
11145
  */
@@ -11136,9 +11248,27 @@ var KnishIOClient = class {
11136
11248
  amount = null,
11137
11249
  meta = null,
11138
11250
  batchId = null,
11139
- units: _units = null
11251
+ units = null
11140
11252
  }) {
11141
11253
  this.log("info", `KnishIOClient::createToken() - Creating token ${token}...`);
11254
+ const tokenMeta = meta || {};
11255
+ const fungibility = tokenMeta.fungibility;
11256
+ let resolvedAmount = amount ?? 0;
11257
+ if (fungibility === "stackable") {
11258
+ tokenMeta.batchId = batchId || generateBatchId({});
11259
+ }
11260
+ if ((fungibility === "stackable" || fungibility === "nonfungible" || fungibility === "non-fungible") && units && units.length > 0) {
11261
+ if (Number(tokenMeta.decimals ?? 0) > 0) {
11262
+ throw new StackableUnitDecimalsException_default();
11263
+ }
11264
+ if (Number(amount ?? 0) > 0) {
11265
+ throw new StackableUnitAmountException_default();
11266
+ }
11267
+ resolvedAmount = units.length;
11268
+ tokenMeta.splittable = "1";
11269
+ tokenMeta.decimals = "0";
11270
+ tokenMeta.tokenUnits = JSON.stringify(units);
11271
+ }
11142
11272
  const mutation = await this.createMoleculeMutation({ mutationClass: MutationCreateToken });
11143
11273
  const recipientWallet = new Wallet({
11144
11274
  secret: this.getSecret(),
@@ -11148,8 +11278,8 @@ var KnishIOClient = class {
11148
11278
  });
11149
11279
  await mutation.fillMolecule({
11150
11280
  recipientWallet,
11151
- amount: amount ?? 0,
11152
- meta
11281
+ amount: resolvedAmount,
11282
+ meta: tokenMeta
11153
11283
  });
11154
11284
  const response = await this.executeQuery(mutation);
11155
11285
  if (!response) {
@@ -11590,8 +11720,12 @@ var KnishIOClient = class {
11590
11720
  mutationClass: MutationRequestAuthorization,
11591
11721
  molecule
11592
11722
  });
11723
+ const authMeta = { encrypt: encrypt ? "true" : "false" };
11724
+ if (wallet.pubkey) {
11725
+ authMeta.walletPubkey = wallet.pubkey;
11726
+ }
11593
11727
  mutation.fillMolecule({
11594
- meta: { encrypt: encrypt ? "true" : "false" }
11728
+ meta: authMeta
11595
11729
  });
11596
11730
  const response = await this.executeQuery(mutation);
11597
11731
  if (!response) {
@@ -11843,6 +11977,6 @@ var KnishIO = {
11843
11977
  SDK_INFO
11844
11978
  };
11845
11979
 
11846
- export { Atom, AtomIndexException, AtomMeta, AtomsMissingException, AuthToken, BaseException, COMPATIBLE_SERVER_VERSIONS, CRYPTO_CONSTANTS, CheckMolecule, DevUtils, Dot, EXCEPTION_CODES, EXCEPTION_TYPES, EXTENDED_COMPATIBILITY_TEST_VECTORS, ExceptionFactory, GraphQLClient, InvalidResponseException, KnishIO, KnishIOClient, Meta, MolecularHashMismatchException, Molecule, Mutation, MutationAppendRequest, MutationCreateMeta, MutationCreateToken, MutationCreateWallet, MutationPeering, MutationProposeMolecule, MutationRequestAuthorization, MutationRequestTokens, MutationTransferTokens, PolicyMeta, Query, QueryAtom, QueryBalance, QueryBatch, QueryContinuId, QueryEmbeddingStatus, QueryMetaType, QueryMetaTypeViaAtom, QueryWalletBundle, QueryWalletList, Response, ResponseAppendRequest, ResponseAtom, ResponseBalance, ResponseContinuId, ResponseCreateMeta, ResponseCreateToken, ResponseCreateWallet, ResponseEmbeddingStatus, ResponseMetaType, ResponseMetaTypeViaAtom, ResponsePeering, ResponseProposeMolecule, ResponseRequestAuthorization, ResponseRequestTokens, ResponseTransferTokens, ResponseWalletBundle, ResponseWalletList, SDK_INFO, SDK_NAME, SDK_VERSION, SignatureMismatchException, TokenUnit, TransferBalanceException, Wallet, WalletCredentialException, base64ToHex, bufferToHexString, capitalize, charsetBaseConvert, chunkArray, chunkSubstr, configureSDK, convertToBase17, createBundleHash, createMolecularHash, createPosition, createTokenSlug, createWalletAddress, deepCloning, diff, enumerateMolecularHash, generateBatchId, generateBundleHash, generateOTSSignature, generatePosition, generateSecret, generateWalletAddress, generateWalletKey, getSDKConfig, hexStringToBuffer, hexToBase64, intersect, isAtomIsotope, isBundleHash, isHex, isHexString, isMolecularHash, isNumeric, isPosition2 as isPosition, isWalletAddress2 as isWalletAddress, normalizeMolecularHash, randomString, runCompatibilityTests, runExtendedCompatibilityTests, shake256, toCamelCase, toSnakeCase, truncate, validateBundleHash, validateMolecularHashForSignature, validateOTSSignature, validatePosition, validateSecret, validateWalletAddress, verifyOTSSignature };
11980
+ export { Atom, AtomIndexException, AtomMeta, AtomsMissingException, AuthToken, BaseException, COMPATIBLE_SERVER_VERSIONS, CRYPTO_CONSTANTS, CheckMolecule, DevUtils, Dot, EXCEPTION_CODES, EXCEPTION_TYPES, EXTENDED_COMPATIBILITY_TEST_VECTORS, ExceptionFactory, GraphQLClient, InvalidResponseException, KnishIO, KnishIOClient, Meta, MolecularHashMismatchException, Molecule, Mutation, MutationAppendRequest, MutationCreateMeta, MutationCreateToken, MutationCreateWallet, MutationPeering, MutationProposeMolecule, MutationRequestAuthorization, MutationRequestTokens, MutationTransferTokens, PolicyMeta, Query, QueryAtom, QueryBalance, QueryBatch, QueryContinuId, QueryEmbeddingStatus, QueryMetaType, QueryMetaTypeViaAtom, QueryWalletBundle, QueryWalletList, Response2 as Response, ResponseAppendRequest, ResponseAtom, ResponseBalance, ResponseContinuId, ResponseCreateMeta, ResponseCreateToken, ResponseCreateWallet, ResponseEmbeddingStatus, ResponseMetaType, ResponseMetaTypeViaAtom, ResponsePeering, ResponseProposeMolecule, ResponseRequestAuthorization, ResponseRequestTokens, ResponseTransferTokens, ResponseWalletBundle, ResponseWalletList, SDK_INFO, SDK_NAME, SDK_VERSION, SignatureMismatchException, TokenUnit, TransferBalanceException, Wallet, WalletCredentialException, base64ToHex, bufferToHexString, capitalize, charsetBaseConvert, chunkArray, chunkSubstr, configureSDK, convertToBase17, createBundleHash, createMolecularHash, createPosition, createTokenSlug, createWalletAddress, deepCloning, diff, enumerateMolecularHash, generateBatchId, generateBundleHash, generateOTSSignature, generatePosition, generateSecret, generateWalletAddress, generateWalletKey, getSDKConfig, hexStringToBuffer, hexToBase64, intersect, isAtomIsotope, isBundleHash, isHex, isHexString, isMolecularHash, isNumeric, isPosition2 as isPosition, isWalletAddress2 as isWalletAddress, normalizeMolecularHash, randomString, runCompatibilityTests, runExtendedCompatibilityTests, shake256, toCamelCase, toSnakeCase, truncate, validateBundleHash, validateMolecularHashForSignature, validateOTSSignature, validatePosition, validateSecret, validateWalletAddress, verifyOTSSignature };
11847
11981
  //# sourceMappingURL=index.js.map
11848
11982
  //# sourceMappingURL=index.js.map