@wishknish/knishio-client-ts 0.8.2 → 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.
Files changed (38) hide show
  1. package/dist/index.cjs +425 -263
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +44 -17
  4. package/dist/index.d.ts +44 -17
  5. package/dist/index.iife.js +425 -265
  6. package/dist/index.iife.js.map +1 -1
  7. package/dist/index.js +447 -285
  8. package/dist/index.js.map +1 -1
  9. package/package.json +6 -9
  10. package/src/KnishIOClient.ts +180 -57
  11. package/src/constants.ts +1 -2
  12. package/src/core/Molecule.ts +53 -0
  13. package/src/core/Wallet.ts +84 -3
  14. package/src/libraries/Decimal.ts +1 -1
  15. package/src/libraries/GraphQLClient.ts +83 -0
  16. package/src/libraries/Hex.ts +4 -3
  17. package/src/libraries/UrqlClientWrapper.ts +13 -13
  18. package/src/libraries/crypto.ts +4 -4
  19. package/src/mutation/MutationClaimShadowWallet.ts +3 -1
  20. package/src/mutation/MutationTransferTokens.ts +18 -0
  21. package/src/query/QueryActiveSession.ts +0 -1
  22. package/src/query/QueryPolicy.ts +0 -1
  23. package/src/response/ResponseAuthorizationGuest.ts +2 -2
  24. package/src/response/ResponseBalance.ts +9 -6
  25. package/src/response/ResponseLinkIdentifier.ts +1 -1
  26. package/src/response/ResponseRequestAuthorizationGuest.ts +2 -2
  27. package/src/schemas/index.ts +2 -1
  28. package/src/subscribe/Subscribe.ts +3 -2
  29. package/src/types/assertions.ts +1 -6
  30. package/src/types/client.ts +12 -19
  31. package/src/types/guards.ts +2 -3
  32. package/src/types/index.ts +6 -0
  33. package/src/validation/UNIVERSAL_CONFIGURATION_INTERFACES.ts +3 -5
  34. package/src/validation/ValidationService.ts +6 -15
  35. package/src/validation/schemas.ts +5 -1
  36. package/src/versions/HashAtom.ts +11 -9
  37. package/src/query/QueryUserActivity.ts +0 -153
  38. package/src/response/ResponseQueryUserActivity.ts +0 -89
@@ -5053,9 +5053,19 @@ var KnishIO = (function (exports) {
5053
5053
  });
5054
5054
 
5055
5055
  // src/exception/StackableUnitDecimalsException.ts
5056
+ var StackableUnitDecimalsException, StackableUnitDecimalsException_default;
5056
5057
  var init_StackableUnitDecimalsException = __esm({
5057
5058
  "src/exception/StackableUnitDecimalsException.ts"() {
5058
5059
  init_BaseException();
5060
+ StackableUnitDecimalsException = class extends exports.BaseException {
5061
+ /**
5062
+ * Constructor using proper error type
5063
+ */
5064
+ constructor(message = "Stackable tokens with unit IDs cannot have decimal places!") {
5065
+ super("STACKABLE_UNIT_DECIMALS_ERROR", message);
5066
+ }
5067
+ };
5068
+ StackableUnitDecimalsException_default = StackableUnitDecimalsException;
5059
5069
  }
5060
5070
  });
5061
5071
 
@@ -21334,9 +21344,6 @@ ${operationTypes.join("\n")}
21334
21344
  }
21335
21345
  }
21336
21346
  function generateBundleHash(secret, _source = null) {
21337
- if (!secret || secret.length === 0) {
21338
- throw new Error("Secret is required for bundle hash generation");
21339
- }
21340
21347
  const hash = shake256(secret, CRYPTO_CONSTANTS.BUNDLE_HASH_LENGTH * 4);
21341
21348
  return hash;
21342
21349
  }
@@ -22749,8 +22756,7 @@ ${operationTypes.join("\n")}
22749
22756
  "Batch",
22750
22757
  "ActiveSession",
22751
22758
  "Policy",
22752
- "Token",
22753
- "UserActivity"
22759
+ "Token"
22754
22760
  ];
22755
22761
  function createLookup(values) {
22756
22762
  return values.reduce((acc, value2) => {
@@ -23832,6 +23838,29 @@ ${operationTypes.join("\n")}
23832
23838
  }
23833
23839
  remainderWallet.tokenUnits = remainderTokenUnits;
23834
23840
  }
23841
+ /**
23842
+ * Split token units across MULTIPLE recipients (N-way sibling of splitUnits).
23843
+ *
23844
+ * The source retains the SENT union (all units leaving), each recipient gets its own
23845
+ * subset, and the remainder keeps the KEPT units (those not assigned to any recipient).
23846
+ * recipientUnitLists is parallel to recipientWallets. No-op when no units are sent.
23847
+ *
23848
+ * @param recipientUnitLists - per-recipient arrays of token unit IDs (parallel to recipientWallets)
23849
+ * @param recipientWallets - destination wallets
23850
+ * @param remainderWallet - wallet to receive the KEPT units
23851
+ */
23852
+ splitUnitsMulti(recipientUnitLists, recipientWallets, remainderWallet) {
23853
+ const sentIds = new Set(recipientUnitLists.flat());
23854
+ if (sentIds.size === 0) {
23855
+ return;
23856
+ }
23857
+ recipientWallets.forEach((recipientWallet, i4) => {
23858
+ const ids = recipientUnitLists[i4] ?? [];
23859
+ recipientWallet.tokenUnits = this.tokenUnits.filter((tokenUnit) => ids.includes(tokenUnit.id));
23860
+ });
23861
+ remainderWallet.tokenUnits = this.tokenUnits.filter((tokenUnit) => !sentIds.has(tokenUnit.id));
23862
+ this.tokenUnits = this.tokenUnits.filter((tokenUnit) => sentIds.has(tokenUnit.id));
23863
+ }
23835
23864
  /**
23836
23865
  * Get token units data
23837
23866
  * Stub for compatibility
@@ -23878,6 +23907,15 @@ ${operationTypes.join("\n")}
23878
23907
  };
23879
23908
  }
23880
23909
  async decryptMessage(encryptedData) {
23910
+ const decryptedString = await this._mlkemDecryptToString(encryptedData);
23911
+ return decryptedString === null ? null : JSON.parse(decryptedString);
23912
+ }
23913
+ /**
23914
+ * ML-KEM768 decapsulate + AES-256-GCM decrypt → the RAW decrypted UTF-8 string (no JSON.parse).
23915
+ * Shared by {@link decryptMessage} (which JSON.parses the result) and the PQ CipherHash transport
23916
+ * ({@link decryptMyMessageML768}, which needs the raw response JSON text). PQ-transport Phase E.
23917
+ */
23918
+ async _mlkemDecryptToString(encryptedData) {
23881
23919
  const { cipherText, encryptedMessage } = encryptedData;
23882
23920
  let sharedSecret;
23883
23921
  try {
@@ -23906,9 +23944,8 @@ ${operationTypes.join("\n")}
23906
23944
  console.info("Wallet::decryptMessage() - deserialized encrypted message", deserializedEncryptedMessage);
23907
23945
  return null;
23908
23946
  }
23909
- let decryptedString;
23910
23947
  try {
23911
- decryptedString = new TextDecoder().decode(decryptedUint8);
23948
+ return new TextDecoder().decode(decryptedUint8);
23912
23949
  } catch (e4) {
23913
23950
  console.warn("Wallet::decryptMessage() - Decoding failed", e4);
23914
23951
  console.info("Wallet::decryptMessage() - my public key", this.pubkey);
@@ -23917,7 +23954,40 @@ ${operationTypes.join("\n")}
23917
23954
  console.info("Wallet::decryptMessage() - decrypted Uint8Array", decryptedUint8);
23918
23955
  return null;
23919
23956
  }
23920
- return JSON.parse(decryptedString);
23957
+ }
23958
+ /**
23959
+ * Canonical cross-SDK hashShare for a public key: standard base64 of SHAKE256(pubkey_utf8, 8 bytes)
23960
+ * — byte-matches the validator's hash_share and the JS/Kotlin/PHP hashShare. `shake256(pubkey, 64)`
23961
+ * = 64 bits = 8 bytes (hex) → hex-decode → standard base64 via serializeKey. PQ-transport Phase E.
23962
+ */
23963
+ hashShare(pubkey) {
23964
+ const hex = shake256(pubkey, 64);
23965
+ const bytes = new Uint8Array(hex.length / 2);
23966
+ for (let i4 = 0; i4 < bytes.length; i4++) {
23967
+ bytes[i4] = parseInt(hex.substr(i4 * 2, 2), 16);
23968
+ }
23969
+ return this.serializeKey(bytes);
23970
+ }
23971
+ /**
23972
+ * Post-quantum (ML-KEM768) CipherHash request envelope: a stringified single-recipient map
23973
+ * `{ "<hashShare(recipientPubkey)>": {cipherText, encryptedMessage} }` (object-valued, via
23974
+ * {@link encryptMessage}). Matches the Rust validator's CipherHash handler. PQ-transport Phase E.
23975
+ */
23976
+ async encryptStringML768(message, recipientPubkey) {
23977
+ const envelope = await this.encryptMessage(message, recipientPubkey);
23978
+ return JSON.stringify({ [this.hashShare(recipientPubkey)]: envelope });
23979
+ }
23980
+ /**
23981
+ * Decrypt a CipherHash response map addressed to THIS wallet's ML-KEM pubkey
23982
+ * (`hashShare(this.pubkey)`) → the RAW decrypted GraphQL response JSON text (NOT JSON.parsed;
23983
+ * it replaces the HTTP response body for the normal parser). `null` if no entry / decrypt fails.
23984
+ */
23985
+ async decryptMyMessageML768(map2) {
23986
+ const envelope = map2[this.hashShare(this.pubkey)];
23987
+ if (!envelope) {
23988
+ return null;
23989
+ }
23990
+ return this._mlkemDecryptToString(envelope);
23921
23991
  }
23922
23992
  // =============================================================================
23923
23993
  // SYMMETRIC ENCRYPTION HELPERS (AES-GCM with shared secret)
@@ -24045,7 +24115,8 @@ ${operationTypes.join("\n")}
24045
24115
  client: external_exports.unknown().optional(),
24046
24116
  socket: external_exports.unknown().optional(),
24047
24117
  serverSdkVersion: external_exports.number().int().min(1).optional(),
24048
- logging: external_exports.boolean().optional()
24118
+ logging: external_exports.boolean().optional(),
24119
+ defaultRequestPolicy: external_exports.enum(["cache-first", "cache-only", "network-only", "cache-and-network"]).nullable().optional()
24049
24120
  }).strict();
24050
24121
  external_exports.object({
24051
24122
  token: external_exports.string().min(1, "Auth token cannot be empty"),
@@ -25219,6 +25290,46 @@ ${operationTypes.join("\n")}
25219
25290
  }));
25220
25291
  return this;
25221
25292
  }
25293
+ /**
25294
+ * Initialize a MULTI-recipient V-type molecule: one source debits its FULL balance to fund
25295
+ * N recipients (each its own amount + stackable units) plus a remainder back to the sender.
25296
+ * Multi-recipient sibling of initValue (WP line 544: fund multiple recipients with one
25297
+ * transaction). recipientWallets is parallel to amounts.
25298
+ */
25299
+ initValues({
25300
+ recipientWallets,
25301
+ amounts
25302
+ }) {
25303
+ if (!this.sourceWallet) {
25304
+ throw new Error("Source wallet required for value transfer");
25305
+ }
25306
+ const total = amounts.reduce((sum, amount) => sum + amount, 0);
25307
+ if (Number(this.sourceWallet.balance) - total < 0) {
25308
+ throw new BalanceInsufficientException();
25309
+ }
25310
+ this.addAtom(Atom.create({
25311
+ isotope: "V",
25312
+ wallet: this.sourceWallet,
25313
+ value: -Number(this.sourceWallet.balance)
25314
+ }));
25315
+ recipientWallets.forEach((recipientWallet, i4) => {
25316
+ this.addAtom(Atom.create({
25317
+ isotope: "V",
25318
+ wallet: recipientWallet,
25319
+ value: amounts[i4],
25320
+ metaType: "walletBundle",
25321
+ metaId: recipientWallet.bundle
25322
+ }));
25323
+ });
25324
+ this.addAtom(Atom.create({
25325
+ isotope: "V",
25326
+ wallet: this.remainderWallet,
25327
+ value: Number(this.sourceWallet.balance) - total,
25328
+ metaType: "walletBundle",
25329
+ metaId: this.remainderWallet.bundle
25330
+ }));
25331
+ return this;
25332
+ }
25222
25333
  /**
25223
25334
  * Sign the molecule with one-time signature
25224
25335
  * Matches JavaScript SDK sign method
@@ -25976,7 +26087,7 @@ ${operationTypes.join("\n")}
25976
26087
  * @param debug Enable debug logging
25977
26088
  * @returns 0 if equal, 1 if value1 > value2, -1 if value1 < value2
25978
26089
  */
25979
- static cmp(value1, value2, debug = false) {
26090
+ static cmp(value1, value2, _debug = false) {
25980
26091
  const val1 = _Decimal.val(value1) * MULTIPLIER;
25981
26092
  const val2 = _Decimal.val(value2) * MULTIPLIER;
25982
26093
  if (Math.abs(val1 - val2) < 1) {
@@ -28417,6 +28528,14 @@ ${operationTypes.join("\n")}
28417
28528
 
28418
28529
  // src/libraries/GraphQLClient.ts
28419
28530
  var import_graphql_ws = __toESM(require_dist());
28531
+ var CIPHER_HASH_QUERY = "query ( $Hash: String! ) { CipherHash ( Hash: $Hash ) { hash } }";
28532
+ function parseOperation(query) {
28533
+ const typeMatch = (query || "").match(/\b(query|mutation|subscription)\b/i);
28534
+ const type2 = typeMatch?.[1]?.toLowerCase() ?? "query";
28535
+ const braceIdx = (query || "").indexOf("{");
28536
+ const nameMatch = braceIdx >= 0 ? query.slice(braceIdx + 1).match(/[A-Za-z_][A-Za-z0-9_]*/) : null;
28537
+ return { type: type2, name: nameMatch?.[0] ?? "" };
28538
+ }
28420
28539
  var GraphQLClient = class {
28421
28540
  $__client;
28422
28541
  $__authToken = "";
@@ -28462,6 +28581,10 @@ ${operationTypes.join("\n")}
28462
28581
  return Q3({
28463
28582
  url: serverUri,
28464
28583
  exchanges,
28584
+ // PQ-transport Phase E: when encryption is on, route fetch through the CipherHash wrapper
28585
+ // (encrypt the request body to the validator's ML-KEM pubkey, decrypt the response).
28586
+ // Omitted → urql uses the global fetch (plaintext).
28587
+ ...this.cipherLink ? { fetch: ((input, init) => this.cipherFetch(input, init)) } : {},
28465
28588
  fetchOptions: () => ({
28466
28589
  headers: {
28467
28590
  "X-Auth-Token": this.$__authToken
@@ -28471,6 +28594,62 @@ ${operationTypes.join("\n")}
28471
28594
  })
28472
28595
  });
28473
28596
  }
28597
+ /**
28598
+ * Whether an outgoing GraphQL request body should be wrapped in CipherHash. Bypass (plaintext):
28599
+ * introspection `__schema`, `ContinuId`, the `AccessToken` mutation, and the U-isotope
28600
+ * `ProposeMolecule` (auth bootstrap — the key exchange itself can't be encrypted). Mirrors the
28601
+ * Kotlin/PHP/validator bypass set.
28602
+ */
28603
+ shouldEncrypt(body) {
28604
+ let parsed;
28605
+ try {
28606
+ parsed = JSON.parse(body);
28607
+ } catch (e4) {
28608
+ return false;
28609
+ }
28610
+ const { type: type2, name: name2 } = parseOperation(parsed.query);
28611
+ if (type2 === "query" && (name2 === "__schema" || name2 === "ContinuId")) return false;
28612
+ if (type2 === "mutation" && name2 === "AccessToken") return false;
28613
+ if (type2 === "mutation" && name2 === "ProposeMolecule") {
28614
+ const isotope = parsed.variables?.molecule?.atoms?.[0]?.isotope;
28615
+ if (isotope === "U") return false;
28616
+ }
28617
+ return true;
28618
+ }
28619
+ /**
28620
+ * Custom `fetch` that wraps a GraphQL request in the ML-KEM CipherHash envelope and decrypts the
28621
+ * response (PQ-transport Phase E). Operates on the raw POST body (mirrors the JS/Kotlin transform).
28622
+ * Reads the CURRENT client wallet + validator pubkey from auth.
28623
+ */
28624
+ async cipherFetch(input, init) {
28625
+ const wallet = this.$__wallet;
28626
+ const serverPubkey = this.$__pubkey;
28627
+ let encryptedRequest = false;
28628
+ let requestInit = init;
28629
+ if (wallet && serverPubkey && init && typeof init.body === "string" && this.shouldEncrypt(init.body)) {
28630
+ const hashVar = await wallet.encryptStringML768(init.body, serverPubkey);
28631
+ requestInit = { ...init, body: JSON.stringify({ query: CIPHER_HASH_QUERY, variables: { Hash: hashVar } }) };
28632
+ encryptedRequest = true;
28633
+ }
28634
+ const response = await fetch(input, requestInit);
28635
+ if (!encryptedRequest) {
28636
+ return response;
28637
+ }
28638
+ const text = await response.text();
28639
+ const init2 = { status: response.status, statusText: response.statusText, headers: response.headers };
28640
+ let parsed;
28641
+ try {
28642
+ parsed = JSON.parse(text);
28643
+ } catch (e4) {
28644
+ return new Response(text, init2);
28645
+ }
28646
+ const hash = parsed?.data?.CipherHash?.hash;
28647
+ if (typeof hash !== "string") {
28648
+ return new Response(text, init2);
28649
+ }
28650
+ const decrypted = await wallet.decryptMyMessageML768(JSON.parse(hash));
28651
+ return new Response(decrypted != null ? decrypted : text, init2);
28652
+ }
28474
28653
  setAuthData({
28475
28654
  token,
28476
28655
  pubkey,
@@ -28765,8 +28944,8 @@ ${operationTypes.join("\n")}
28765
28944
  * Returns a Response object
28766
28945
  */
28767
28946
  createResponse(json) {
28768
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
28769
- return new Response2({
28947
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
28948
+ return new Response3({
28770
28949
  query: this,
28771
28950
  json
28772
28951
  });
@@ -28836,8 +29015,8 @@ ${operationTypes.join("\n")}
28836
29015
  } catch (error2) {
28837
29016
  if (error2.name === "AbortError") {
28838
29017
  this.knishIOClient.log("warn", "Query was cancelled");
28839
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
28840
- return new Response2({
29018
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
29019
+ return new Response3({
28841
29020
  query: this,
28842
29021
  json: { data: null, errors: [{ message: "Query was cancelled" }] }
28843
29022
  });
@@ -28881,8 +29060,8 @@ ${operationTypes.join("\n")}
28881
29060
  } catch (error2) {
28882
29061
  if (error2.name === "AbortError") {
28883
29062
  this.knishIOClient.log("warn", "Mutation was cancelled");
28884
- const Response2 = (init_Response(), __toCommonJS(Response_exports)).default;
28885
- return new Response2({
29063
+ const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
29064
+ return new Response3({
28886
29065
  query: this,
28887
29066
  json: { data: null, errors: [{ message: "Mutation was cancelled" }] }
28888
29067
  });
@@ -29005,7 +29184,11 @@ ${operationTypes.join("\n")}
29005
29184
  client: external_exports.unknown().optional(),
29006
29185
  socket: external_exports.unknown().optional(),
29007
29186
  serverSdkVersion: external_exports.number().int().min(1).max(10).default(4),
29008
- logging: external_exports.boolean().default(false)
29187
+ logging: external_exports.boolean().default(false),
29188
+ // Optional default urql request policy for reads (server/sync clients pass
29189
+ // 'network-only'). Permitted by the strict schema so the constructor option
29190
+ // isn't rejected.
29191
+ defaultRequestPolicy: external_exports.enum(["cache-first", "cache-only", "network-only", "cache-and-network"]).nullable().optional()
29009
29192
  }).strict();
29010
29193
  var EnvironmentConfigSchema = external_exports.object({
29011
29194
  NODE_ENV: external_exports.enum(["development", "production", "test"]).default("development"),
@@ -29817,6 +30000,89 @@ ${operationTypes.join("\n")}
29817
30000
 
29818
30001
  // src/response/ResponseBalance.ts
29819
30002
  init_Response();
30003
+
30004
+ // src/core/TokenUnit.ts
30005
+ var TokenUnit = class _TokenUnit {
30006
+ id;
30007
+ name;
30008
+ metas;
30009
+ /**
30010
+ * Create new TokenUnit instance
30011
+ * Matches JavaScript SDK constructor signature exactly
30012
+ */
30013
+ constructor(id, name2, metas) {
30014
+ this.id = id;
30015
+ this.name = name2;
30016
+ this.metas = metas || {};
30017
+ }
30018
+ /**
30019
+ * Create TokenUnit from GraphQL response data
30020
+ * Matches JavaScript SDK createFromGraphQL method exactly
30021
+ */
30022
+ static createFromGraphQL(data) {
30023
+ let metas = data.metas || {};
30024
+ if (Array.isArray(metas) && metas.length) {
30025
+ try {
30026
+ metas = JSON.parse(metas);
30027
+ if (!metas) {
30028
+ metas = {};
30029
+ }
30030
+ } catch (error2) {
30031
+ metas = {};
30032
+ }
30033
+ }
30034
+ return new _TokenUnit(
30035
+ data.id,
30036
+ data.name,
30037
+ metas
30038
+ );
30039
+ }
30040
+ /**
30041
+ * Create TokenUnit from database array data
30042
+ * Matches JavaScript SDK createFromDB method exactly
30043
+ */
30044
+ static createFromDB(data) {
30045
+ return new _TokenUnit(
30046
+ data[0],
30047
+ data[1],
30048
+ data.length > 2 ? data[2] : {}
30049
+ );
30050
+ }
30051
+ /**
30052
+ * Get fragment zone from metadata
30053
+ * Matches JavaScript SDK getFragmentZone method exactly
30054
+ */
30055
+ getFragmentZone() {
30056
+ return this.metas.fragmentZone || null;
30057
+ }
30058
+ /**
30059
+ * Get fused token units from metadata
30060
+ * Matches JavaScript SDK getFusedTokenUnits method exactly
30061
+ */
30062
+ getFusedTokenUnits() {
30063
+ return this.metas.fusedTokenUnits || null;
30064
+ }
30065
+ /**
30066
+ * Convert to data array format
30067
+ * Matches JavaScript SDK toData method exactly
30068
+ */
30069
+ toData() {
30070
+ return [this.id, this.name, this.metas];
30071
+ }
30072
+ /**
30073
+ * Convert to GraphQL response format
30074
+ * Matches JavaScript SDK toGraphQLResponse method exactly
30075
+ */
30076
+ toGraphQLResponse() {
30077
+ return {
30078
+ id: this.id,
30079
+ name: this.name,
30080
+ metas: JSON.stringify(this.metas)
30081
+ };
30082
+ }
30083
+ };
30084
+
30085
+ // src/response/ResponseBalance.ts
29820
30086
  var ResponseBalance = class _ResponseBalance extends exports.Response {
29821
30087
  /**
29822
30088
  * Class constructor
@@ -29879,6 +30145,11 @@ ${operationTypes.join("\n")}
29879
30145
  wallet.tokenSupply = data.token.supply;
29880
30146
  wallet.tokenFungibility = data.token.fungibility;
29881
30147
  }
30148
+ if (data.tokenUnits && data.tokenUnits.length) {
30149
+ for (const tokenUnitData of data.tokenUnits) {
30150
+ wallet.tokenUnits.push(TokenUnit.createFromGraphQL(tokenUnitData));
30151
+ }
30152
+ }
29882
30153
  if (data.tradeRates && data.tradeRates.length) {
29883
30154
  for (const tradeRate of data.tradeRates) {
29884
30155
  wallet.tradeRates[tradeRate.tokenSlug] = tradeRate.amount;
@@ -29938,89 +30209,6 @@ ${operationTypes.join("\n")}
29938
30209
 
29939
30210
  // src/response/ResponseWalletList.ts
29940
30211
  init_Response();
29941
-
29942
- // src/core/TokenUnit.ts
29943
- var TokenUnit = class _TokenUnit {
29944
- id;
29945
- name;
29946
- metas;
29947
- /**
29948
- * Create new TokenUnit instance
29949
- * Matches JavaScript SDK constructor signature exactly
29950
- */
29951
- constructor(id, name2, metas) {
29952
- this.id = id;
29953
- this.name = name2;
29954
- this.metas = metas || {};
29955
- }
29956
- /**
29957
- * Create TokenUnit from GraphQL response data
29958
- * Matches JavaScript SDK createFromGraphQL method exactly
29959
- */
29960
- static createFromGraphQL(data) {
29961
- let metas = data.metas || {};
29962
- if (Array.isArray(metas) && metas.length) {
29963
- try {
29964
- metas = JSON.parse(metas);
29965
- if (!metas) {
29966
- metas = {};
29967
- }
29968
- } catch (error2) {
29969
- metas = {};
29970
- }
29971
- }
29972
- return new _TokenUnit(
29973
- data.id,
29974
- data.name,
29975
- metas
29976
- );
29977
- }
29978
- /**
29979
- * Create TokenUnit from database array data
29980
- * Matches JavaScript SDK createFromDB method exactly
29981
- */
29982
- static createFromDB(data) {
29983
- return new _TokenUnit(
29984
- data[0],
29985
- data[1],
29986
- data.length > 2 ? data[2] : {}
29987
- );
29988
- }
29989
- /**
29990
- * Get fragment zone from metadata
29991
- * Matches JavaScript SDK getFragmentZone method exactly
29992
- */
29993
- getFragmentZone() {
29994
- return this.metas.fragmentZone || null;
29995
- }
29996
- /**
29997
- * Get fused token units from metadata
29998
- * Matches JavaScript SDK getFusedTokenUnits method exactly
29999
- */
30000
- getFusedTokenUnits() {
30001
- return this.metas.fusedTokenUnits || null;
30002
- }
30003
- /**
30004
- * Convert to data array format
30005
- * Matches JavaScript SDK toData method exactly
30006
- */
30007
- toData() {
30008
- return [this.id, this.name, this.metas];
30009
- }
30010
- /**
30011
- * Convert to GraphQL response format
30012
- * Matches JavaScript SDK toGraphQLResponse method exactly
30013
- */
30014
- toGraphQLResponse() {
30015
- return {
30016
- id: this.id,
30017
- name: this.name,
30018
- metas: JSON.stringify(this.metas)
30019
- };
30020
- }
30021
- };
30022
-
30023
- // src/response/ResponseWalletList.ts
30024
30212
  var ResponseWalletList = class _ResponseWalletList extends exports.Response {
30025
30213
  /**
30026
30214
  * Class constructor
@@ -30958,133 +31146,6 @@ ${operationTypes.join("\n")}
30958
31146
  }
30959
31147
  };
30960
31148
 
30961
- // src/response/ResponseQueryUserActivity.ts
30962
- init_Response();
30963
- var ResponseQueryUserActivity = class extends exports.Response {
30964
- /**
30965
- * Constructor
30966
- */
30967
- constructor({
30968
- query,
30969
- json
30970
- }) {
30971
- super({
30972
- query,
30973
- json,
30974
- dataKey: "data.UserActivity"
30975
- });
30976
- }
30977
- /**
30978
- * Returns processed user activity data
30979
- */
30980
- payload() {
30981
- const data = JSON.parse(JSON.stringify(this.data()));
30982
- if (data.instances) {
30983
- for (const datum of data.instances) {
30984
- if (datum.jsonData) {
30985
- datum.jsonData = JSON.parse(datum.jsonData);
30986
- }
30987
- }
30988
- }
30989
- return data;
30990
- }
30991
- };
30992
-
30993
- // src/query/QueryUserActivity.ts
30994
- var QueryUserActivity = class extends Query {
30995
- /**
30996
- * Constructor
30997
- */
30998
- constructor(graphQLClient, knishIOClient) {
30999
- super(graphQLClient, knishIOClient);
31000
- this.$__query = gql`
31001
- query UserActivity(
31002
- $bundleHash: String
31003
- $metaType: String
31004
- $metaId: String
31005
- $ipAddress: String
31006
- $browser: String
31007
- $osCpu: String
31008
- $resolution: String
31009
- $timeZone: String
31010
- $countBy: [CountByUserActivity]
31011
- $interval: span
31012
- ) {
31013
- UserActivity(
31014
- bundleHash: $bundleHash
31015
- metaType: $metaType
31016
- metaId: $metaId
31017
- ipAddress: $ipAddress
31018
- browser: $browser
31019
- osCpu: $osCpu
31020
- resolution: $resolution
31021
- timeZone: $timeZone
31022
- countBy: $countBy
31023
- interval: $interval
31024
- ) {
31025
- createdAt
31026
- bundleHash
31027
- metaType
31028
- metaId
31029
- instances {
31030
- bundleHash
31031
- metaType
31032
- metaId
31033
- jsonData
31034
- createdAt
31035
- updatedAt
31036
- }
31037
- instanceCount {
31038
- ...SubFields
31039
- ...Recursive
31040
- }
31041
- }
31042
- }
31043
-
31044
- fragment SubFields on InstanceCountType {
31045
- id
31046
- count
31047
- }
31048
-
31049
- fragment Recursive on InstanceCountType {
31050
- instances {
31051
- ...SubFields
31052
- instances {
31053
- ...SubFields
31054
- instances {
31055
- ...SubFields
31056
- instances {
31057
- ...SubFields
31058
- instances {
31059
- ...SubFields
31060
- instances {
31061
- ...SubFields
31062
- instances {
31063
- ...SubFields
31064
- instances {
31065
- ...SubFields
31066
- }
31067
- }
31068
- }
31069
- }
31070
- }
31071
- }
31072
- }
31073
- }
31074
- }
31075
- `;
31076
- }
31077
- /**
31078
- * Returns a Response object
31079
- */
31080
- createResponse(json) {
31081
- return new ResponseQueryUserActivity({
31082
- query: this,
31083
- json
31084
- });
31085
- }
31086
- };
31087
-
31088
31149
  // src/query/QueryToken.ts
31089
31150
  init_Response();
31090
31151
  var QueryToken = class extends Query {
@@ -31926,6 +31987,20 @@ ${operationTypes.join("\n")}
31926
31987
  this.$__molecule.sign({});
31927
31988
  this.$__molecule.check(this.$__molecule.sourceWallet);
31928
31989
  }
31990
+ /**
31991
+ * Fills the Molecule for a MULTI-recipient transfer (one source funds N recipients)
31992
+ */
31993
+ fillMoleculeMulti({
31994
+ recipientWallets,
31995
+ amounts
31996
+ }) {
31997
+ this.$__molecule.initValues({
31998
+ recipientWallets,
31999
+ amounts
32000
+ });
32001
+ this.$__molecule.sign({});
32002
+ this.$__molecule.check(this.$__molecule.sourceWallet);
32003
+ }
31929
32004
  /**
31930
32005
  * Builds a Response object out of a JSON object
31931
32006
  * Matches JavaScript SDK createResponse method signature exactly
@@ -31986,7 +32061,8 @@ ${operationTypes.join("\n")}
31986
32061
  bundle: this.$__molecule.bundle,
31987
32062
  token,
31988
32063
  batchId
31989
- })(this.$__molecule).initShadowWalletClaim(wallet);
32064
+ });
32065
+ this.$__molecule.initShadowWalletClaim(wallet);
31990
32066
  this.$__molecule.sign({});
31991
32067
  this.$__molecule.check();
31992
32068
  }
@@ -32773,6 +32849,10 @@ ${operationTypes.join("\n")}
32773
32849
  $__client;
32774
32850
  $__serverSdkVersion = 3;
32775
32851
  $__logging = false;
32852
+ // Default urql request policy applied to reads when the caller doesn't pass
32853
+ // one. null = urql's default (cache-first). Server/sync clients set this to
32854
+ // 'network-only' so a long-lived client never serves a stale cached read.
32855
+ $__defaultRequestPolicy = null;
32776
32856
  $__authTokenObjects = {};
32777
32857
  $__authToken = null;
32778
32858
  $__authInProcess = false;
@@ -32812,13 +32892,15 @@ ${operationTypes.join("\n")}
32812
32892
  serverSdkVersion = 3,
32813
32893
  logging = false
32814
32894
  } = validatedConfig;
32895
+ const defaultRequestPolicy = config.defaultRequestPolicy ?? null;
32815
32896
  this.initialize({
32816
32897
  uri,
32817
32898
  cellSlug,
32818
32899
  socket,
32819
32900
  client,
32820
32901
  serverSdkVersion,
32821
- logging
32902
+ logging,
32903
+ defaultRequestPolicy
32822
32904
  });
32823
32905
  }
32824
32906
  /**
@@ -32830,7 +32912,8 @@ ${operationTypes.join("\n")}
32830
32912
  socket = null,
32831
32913
  client = null,
32832
32914
  serverSdkVersion = 3,
32833
- logging = false
32915
+ logging = false,
32916
+ defaultRequestPolicy = null
32834
32917
  }) {
32835
32918
  this.reset();
32836
32919
  this.$__logging = logging;
@@ -32852,6 +32935,7 @@ ${operationTypes.join("\n")}
32852
32935
  encrypt: this.$__encrypt
32853
32936
  });
32854
32937
  this.$__serverSdkVersion = serverSdkVersion;
32938
+ this.$__defaultRequestPolicy = defaultRequestPolicy;
32855
32939
  }
32856
32940
  /**
32857
32941
  * Get random uri from specified this.$__uris
@@ -32899,6 +32983,20 @@ ${operationTypes.join("\n")}
32899
32983
  getServerSdkVersion() {
32900
32984
  return this.$__serverSdkVersion;
32901
32985
  }
32986
+ /**
32987
+ * Gets the client's default urql request policy (null = urql default).
32988
+ */
32989
+ getDefaultRequestPolicy() {
32990
+ return this.$__defaultRequestPolicy;
32991
+ }
32992
+ /**
32993
+ * Sets the default urql request policy applied to reads that don't specify
32994
+ * one. Pass 'network-only' on a long-lived server/sync client so it never
32995
+ * serves a stale cached read; null restores urql's default (cache-first).
32996
+ */
32997
+ setDefaultRequestPolicy(policy) {
32998
+ this.$__defaultRequestPolicy = policy;
32999
+ }
32902
33000
  /**
32903
33001
  * Reset common properties
32904
33002
  */
@@ -33103,7 +33201,8 @@ ${operationTypes.join("\n")}
33103
33201
  return response;
33104
33202
  });
33105
33203
  }
33106
- return await query.execute({ variables: variables || {}, context });
33204
+ const effectiveContext = this.$__defaultRequestPolicy && !context.requestPolicy ? { requestPolicy: this.$__defaultRequestPolicy, ...context } : context;
33205
+ return await query.execute({ variables: variables || {}, context: effectiveContext });
33107
33206
  }
33108
33207
  /**
33109
33208
  * When a ProposeMolecule submission is rejected for a position-related
@@ -33223,6 +33322,75 @@ ${operationTypes.join("\n")}
33223
33322
  });
33224
33323
  return await this.executeQuery(query);
33225
33324
  }
33325
+ /**
33326
+ * Fund N recipients from a single source in ONE molecule (multi-recipient sibling of
33327
+ * transferToken). Each recipient gets its own subset of stackable units (or a fungible
33328
+ * amount); a remainder returns the rest to the sender. Conserves:
33329
+ * -balance + Σamounts + (balance - Σ) === 0.
33330
+ *
33331
+ * @param token - token slug
33332
+ * @param recipients - destinations (bundleHash + units OR amount + optional batchId)
33333
+ * @param sourceWallet - optional pre-resolved source (defaults to the client's own wallet)
33334
+ */
33335
+ async transferTokens({
33336
+ token,
33337
+ recipients,
33338
+ sourceWallet = null
33339
+ }) {
33340
+ const amounts = recipients.map((recipient) => {
33341
+ const unitCount = recipient.units ? recipient.units.length : 0;
33342
+ if (unitCount > 0) {
33343
+ if (recipient.amount !== null && recipient.amount !== void 0 && recipient.amount > 0) {
33344
+ throw new StackableUnitAmountException_default();
33345
+ }
33346
+ return unitCount;
33347
+ }
33348
+ return recipient.amount ?? 0;
33349
+ });
33350
+ const total = amounts.reduce((sum, amount) => sum + amount, 0);
33351
+ if (sourceWallet === null) {
33352
+ sourceWallet = await this.querySourceWallet({
33353
+ token,
33354
+ amount: total
33355
+ });
33356
+ }
33357
+ if (sourceWallet === null || Decimal.cmp(Number(sourceWallet.balance), total) < 0) {
33358
+ throw new exports.TransferBalanceException();
33359
+ }
33360
+ const recipientWallets = recipients.map((recipient) => {
33361
+ const recipientWallet = Wallet.create({
33362
+ bundle: recipient.bundleHash,
33363
+ token
33364
+ });
33365
+ if (recipient.batchId !== null && recipient.batchId !== void 0) {
33366
+ recipientWallet.batchId = recipient.batchId;
33367
+ } else {
33368
+ recipientWallet.initBatchId({ sourceWallet });
33369
+ }
33370
+ return recipientWallet;
33371
+ });
33372
+ const remainderWallet = sourceWallet.createRemainder(this.getSecret());
33373
+ if (recipients.some((recipient) => recipient.units && recipient.units.length > 0)) {
33374
+ sourceWallet.splitUnitsMulti(
33375
+ recipients.map((recipient) => recipient.units ?? []),
33376
+ recipientWallets,
33377
+ remainderWallet
33378
+ );
33379
+ }
33380
+ const molecule = await this.createMolecule({
33381
+ sourceWallet,
33382
+ remainderWallet
33383
+ });
33384
+ const query = await this.createMoleculeMutation({
33385
+ mutationClass: MutationTransferTokens,
33386
+ molecule
33387
+ });
33388
+ query.fillMoleculeMulti({
33389
+ recipientWallets,
33390
+ amounts
33391
+ });
33392
+ return await this.executeQuery(query);
33393
+ }
33226
33394
  /**
33227
33395
  * Request authorization token (guest or profile)
33228
33396
  *
@@ -33679,36 +33847,6 @@ ${operationTypes.join("\n")}
33679
33847
  metaId
33680
33848
  });
33681
33849
  }
33682
- /**
33683
- * Query user activity
33684
- */
33685
- async queryUserActivity({
33686
- bundleHash,
33687
- metaType,
33688
- metaId,
33689
- ipAddress = null,
33690
- browser = null,
33691
- osCpu = null,
33692
- resolution = null,
33693
- timeZone = null,
33694
- countBy = null,
33695
- interval = null
33696
- }) {
33697
- const query = this.createQuery(QueryUserActivity);
33698
- const variables = {
33699
- bundleHash,
33700
- metaType,
33701
- metaId
33702
- };
33703
- if (ipAddress !== null) variables.ipAddress = ipAddress;
33704
- if (browser !== null) variables.browser = browser;
33705
- if (osCpu !== null) variables.osCpu = osCpu;
33706
- if (resolution !== null) variables.resolution = resolution;
33707
- if (timeZone !== null) variables.timeZone = timeZone;
33708
- if (countBy !== null) variables.countBy = countBy;
33709
- if (interval !== null) variables.interval = interval;
33710
- return this.executeQuery(query, variables);
33711
- }
33712
33850
  /**
33713
33851
  * Query token information
33714
33852
  */
@@ -33817,9 +33955,27 @@ ${operationTypes.join("\n")}
33817
33955
  amount = null,
33818
33956
  meta = null,
33819
33957
  batchId = null,
33820
- units: _units = null
33958
+ units = null
33821
33959
  }) {
33822
33960
  this.log("info", `KnishIOClient::createToken() - Creating token ${token}...`);
33961
+ const tokenMeta = meta || {};
33962
+ const fungibility = tokenMeta.fungibility;
33963
+ let resolvedAmount = amount ?? 0;
33964
+ if (fungibility === "stackable") {
33965
+ tokenMeta.batchId = batchId || generateBatchId({});
33966
+ }
33967
+ if ((fungibility === "stackable" || fungibility === "nonfungible" || fungibility === "non-fungible") && units && units.length > 0) {
33968
+ if (Number(tokenMeta.decimals ?? 0) > 0) {
33969
+ throw new StackableUnitDecimalsException_default();
33970
+ }
33971
+ if (Number(amount ?? 0) > 0) {
33972
+ throw new StackableUnitAmountException_default();
33973
+ }
33974
+ resolvedAmount = units.length;
33975
+ tokenMeta.splittable = "1";
33976
+ tokenMeta.decimals = "0";
33977
+ tokenMeta.tokenUnits = JSON.stringify(units);
33978
+ }
33823
33979
  const mutation = await this.createMoleculeMutation({ mutationClass: MutationCreateToken });
33824
33980
  const recipientWallet = new Wallet({
33825
33981
  secret: this.getSecret(),
@@ -33829,8 +33985,8 @@ ${operationTypes.join("\n")}
33829
33985
  });
33830
33986
  await mutation.fillMolecule({
33831
33987
  recipientWallet,
33832
- amount: amount ?? 0,
33833
- meta
33988
+ amount: resolvedAmount,
33989
+ meta: tokenMeta
33834
33990
  });
33835
33991
  const response = await this.executeQuery(mutation);
33836
33992
  if (!response) {
@@ -34271,8 +34427,12 @@ ${operationTypes.join("\n")}
34271
34427
  mutationClass: MutationRequestAuthorization,
34272
34428
  molecule
34273
34429
  });
34430
+ const authMeta = { encrypt: encrypt ? "true" : "false" };
34431
+ if (wallet.pubkey) {
34432
+ authMeta.walletPubkey = wallet.pubkey;
34433
+ }
34274
34434
  mutation.fillMolecule({
34275
- meta: { encrypt: encrypt ? "true" : "false" }
34435
+ meta: authMeta
34276
34436
  });
34277
34437
  const response = await this.executeQuery(mutation);
34278
34438
  if (!response) {