@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.cjs +392 -258
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -16
- package/dist/index.d.ts +37 -16
- package/dist/index.iife.js +392 -260
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +414 -280
- package/dist/index.js.map +1 -1
- package/package.json +6 -9
- package/src/KnishIOClient.ts +135 -53
- package/src/constants.ts +1 -2
- package/src/core/Molecule.ts +53 -0
- package/src/core/Wallet.ts +84 -3
- package/src/libraries/Decimal.ts +1 -1
- package/src/libraries/GraphQLClient.ts +83 -0
- package/src/libraries/Hex.ts +4 -3
- package/src/libraries/UrqlClientWrapper.ts +13 -13
- package/src/libraries/crypto.ts +4 -4
- package/src/mutation/MutationClaimShadowWallet.ts +3 -1
- package/src/mutation/MutationTransferTokens.ts +18 -0
- package/src/query/QueryActiveSession.ts +0 -1
- package/src/query/QueryPolicy.ts +0 -1
- package/src/response/ResponseAuthorizationGuest.ts +2 -2
- package/src/response/ResponseBalance.ts +9 -6
- package/src/response/ResponseLinkIdentifier.ts +1 -1
- package/src/response/ResponseRequestAuthorizationGuest.ts +2 -2
- package/src/subscribe/Subscribe.ts +3 -2
- package/src/types/assertions.ts +1 -6
- package/src/types/client.ts +12 -19
- package/src/types/guards.ts +2 -3
- package/src/validation/UNIVERSAL_CONFIGURATION_INTERFACES.ts +3 -5
- package/src/validation/ValidationService.ts +6 -15
- package/src/versions/HashAtom.ts +11 -9
- package/src/query/QueryUserActivity.ts +0 -153
- package/src/response/ResponseQueryUserActivity.ts +0 -89
package/dist/index.iife.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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)
|
|
@@ -25220,6 +25290,46 @@ ${operationTypes.join("\n")}
|
|
|
25220
25290
|
}));
|
|
25221
25291
|
return this;
|
|
25222
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
|
+
}
|
|
25223
25333
|
/**
|
|
25224
25334
|
* Sign the molecule with one-time signature
|
|
25225
25335
|
* Matches JavaScript SDK sign method
|
|
@@ -25977,7 +26087,7 @@ ${operationTypes.join("\n")}
|
|
|
25977
26087
|
* @param debug Enable debug logging
|
|
25978
26088
|
* @returns 0 if equal, 1 if value1 > value2, -1 if value1 < value2
|
|
25979
26089
|
*/
|
|
25980
|
-
static cmp(value1, value2,
|
|
26090
|
+
static cmp(value1, value2, _debug = false) {
|
|
25981
26091
|
const val1 = _Decimal.val(value1) * MULTIPLIER;
|
|
25982
26092
|
const val2 = _Decimal.val(value2) * MULTIPLIER;
|
|
25983
26093
|
if (Math.abs(val1 - val2) < 1) {
|
|
@@ -28418,6 +28528,14 @@ ${operationTypes.join("\n")}
|
|
|
28418
28528
|
|
|
28419
28529
|
// src/libraries/GraphQLClient.ts
|
|
28420
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
|
+
}
|
|
28421
28539
|
var GraphQLClient = class {
|
|
28422
28540
|
$__client;
|
|
28423
28541
|
$__authToken = "";
|
|
@@ -28463,6 +28581,10 @@ ${operationTypes.join("\n")}
|
|
|
28463
28581
|
return Q3({
|
|
28464
28582
|
url: serverUri,
|
|
28465
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)) } : {},
|
|
28466
28588
|
fetchOptions: () => ({
|
|
28467
28589
|
headers: {
|
|
28468
28590
|
"X-Auth-Token": this.$__authToken
|
|
@@ -28472,6 +28594,62 @@ ${operationTypes.join("\n")}
|
|
|
28472
28594
|
})
|
|
28473
28595
|
});
|
|
28474
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
|
+
}
|
|
28475
28653
|
setAuthData({
|
|
28476
28654
|
token,
|
|
28477
28655
|
pubkey,
|
|
@@ -28766,8 +28944,8 @@ ${operationTypes.join("\n")}
|
|
|
28766
28944
|
* Returns a Response object
|
|
28767
28945
|
*/
|
|
28768
28946
|
createResponse(json) {
|
|
28769
|
-
const
|
|
28770
|
-
return new
|
|
28947
|
+
const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
|
|
28948
|
+
return new Response3({
|
|
28771
28949
|
query: this,
|
|
28772
28950
|
json
|
|
28773
28951
|
});
|
|
@@ -28837,8 +29015,8 @@ ${operationTypes.join("\n")}
|
|
|
28837
29015
|
} catch (error2) {
|
|
28838
29016
|
if (error2.name === "AbortError") {
|
|
28839
29017
|
this.knishIOClient.log("warn", "Query was cancelled");
|
|
28840
|
-
const
|
|
28841
|
-
return new
|
|
29018
|
+
const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
|
|
29019
|
+
return new Response3({
|
|
28842
29020
|
query: this,
|
|
28843
29021
|
json: { data: null, errors: [{ message: "Query was cancelled" }] }
|
|
28844
29022
|
});
|
|
@@ -28882,8 +29060,8 @@ ${operationTypes.join("\n")}
|
|
|
28882
29060
|
} catch (error2) {
|
|
28883
29061
|
if (error2.name === "AbortError") {
|
|
28884
29062
|
this.knishIOClient.log("warn", "Mutation was cancelled");
|
|
28885
|
-
const
|
|
28886
|
-
return new
|
|
29063
|
+
const Response3 = (init_Response(), __toCommonJS(Response_exports)).default;
|
|
29064
|
+
return new Response3({
|
|
28887
29065
|
query: this,
|
|
28888
29066
|
json: { data: null, errors: [{ message: "Mutation was cancelled" }] }
|
|
28889
29067
|
});
|
|
@@ -29822,6 +30000,89 @@ ${operationTypes.join("\n")}
|
|
|
29822
30000
|
|
|
29823
30001
|
// src/response/ResponseBalance.ts
|
|
29824
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
|
|
29825
30086
|
var ResponseBalance = class _ResponseBalance extends exports.Response {
|
|
29826
30087
|
/**
|
|
29827
30088
|
* Class constructor
|
|
@@ -29884,6 +30145,11 @@ ${operationTypes.join("\n")}
|
|
|
29884
30145
|
wallet.tokenSupply = data.token.supply;
|
|
29885
30146
|
wallet.tokenFungibility = data.token.fungibility;
|
|
29886
30147
|
}
|
|
30148
|
+
if (data.tokenUnits && data.tokenUnits.length) {
|
|
30149
|
+
for (const tokenUnitData of data.tokenUnits) {
|
|
30150
|
+
wallet.tokenUnits.push(TokenUnit.createFromGraphQL(tokenUnitData));
|
|
30151
|
+
}
|
|
30152
|
+
}
|
|
29887
30153
|
if (data.tradeRates && data.tradeRates.length) {
|
|
29888
30154
|
for (const tradeRate of data.tradeRates) {
|
|
29889
30155
|
wallet.tradeRates[tradeRate.tokenSlug] = tradeRate.amount;
|
|
@@ -29943,89 +30209,6 @@ ${operationTypes.join("\n")}
|
|
|
29943
30209
|
|
|
29944
30210
|
// src/response/ResponseWalletList.ts
|
|
29945
30211
|
init_Response();
|
|
29946
|
-
|
|
29947
|
-
// src/core/TokenUnit.ts
|
|
29948
|
-
var TokenUnit = class _TokenUnit {
|
|
29949
|
-
id;
|
|
29950
|
-
name;
|
|
29951
|
-
metas;
|
|
29952
|
-
/**
|
|
29953
|
-
* Create new TokenUnit instance
|
|
29954
|
-
* Matches JavaScript SDK constructor signature exactly
|
|
29955
|
-
*/
|
|
29956
|
-
constructor(id, name2, metas) {
|
|
29957
|
-
this.id = id;
|
|
29958
|
-
this.name = name2;
|
|
29959
|
-
this.metas = metas || {};
|
|
29960
|
-
}
|
|
29961
|
-
/**
|
|
29962
|
-
* Create TokenUnit from GraphQL response data
|
|
29963
|
-
* Matches JavaScript SDK createFromGraphQL method exactly
|
|
29964
|
-
*/
|
|
29965
|
-
static createFromGraphQL(data) {
|
|
29966
|
-
let metas = data.metas || {};
|
|
29967
|
-
if (Array.isArray(metas) && metas.length) {
|
|
29968
|
-
try {
|
|
29969
|
-
metas = JSON.parse(metas);
|
|
29970
|
-
if (!metas) {
|
|
29971
|
-
metas = {};
|
|
29972
|
-
}
|
|
29973
|
-
} catch (error2) {
|
|
29974
|
-
metas = {};
|
|
29975
|
-
}
|
|
29976
|
-
}
|
|
29977
|
-
return new _TokenUnit(
|
|
29978
|
-
data.id,
|
|
29979
|
-
data.name,
|
|
29980
|
-
metas
|
|
29981
|
-
);
|
|
29982
|
-
}
|
|
29983
|
-
/**
|
|
29984
|
-
* Create TokenUnit from database array data
|
|
29985
|
-
* Matches JavaScript SDK createFromDB method exactly
|
|
29986
|
-
*/
|
|
29987
|
-
static createFromDB(data) {
|
|
29988
|
-
return new _TokenUnit(
|
|
29989
|
-
data[0],
|
|
29990
|
-
data[1],
|
|
29991
|
-
data.length > 2 ? data[2] : {}
|
|
29992
|
-
);
|
|
29993
|
-
}
|
|
29994
|
-
/**
|
|
29995
|
-
* Get fragment zone from metadata
|
|
29996
|
-
* Matches JavaScript SDK getFragmentZone method exactly
|
|
29997
|
-
*/
|
|
29998
|
-
getFragmentZone() {
|
|
29999
|
-
return this.metas.fragmentZone || null;
|
|
30000
|
-
}
|
|
30001
|
-
/**
|
|
30002
|
-
* Get fused token units from metadata
|
|
30003
|
-
* Matches JavaScript SDK getFusedTokenUnits method exactly
|
|
30004
|
-
*/
|
|
30005
|
-
getFusedTokenUnits() {
|
|
30006
|
-
return this.metas.fusedTokenUnits || null;
|
|
30007
|
-
}
|
|
30008
|
-
/**
|
|
30009
|
-
* Convert to data array format
|
|
30010
|
-
* Matches JavaScript SDK toData method exactly
|
|
30011
|
-
*/
|
|
30012
|
-
toData() {
|
|
30013
|
-
return [this.id, this.name, this.metas];
|
|
30014
|
-
}
|
|
30015
|
-
/**
|
|
30016
|
-
* Convert to GraphQL response format
|
|
30017
|
-
* Matches JavaScript SDK toGraphQLResponse method exactly
|
|
30018
|
-
*/
|
|
30019
|
-
toGraphQLResponse() {
|
|
30020
|
-
return {
|
|
30021
|
-
id: this.id,
|
|
30022
|
-
name: this.name,
|
|
30023
|
-
metas: JSON.stringify(this.metas)
|
|
30024
|
-
};
|
|
30025
|
-
}
|
|
30026
|
-
};
|
|
30027
|
-
|
|
30028
|
-
// src/response/ResponseWalletList.ts
|
|
30029
30212
|
var ResponseWalletList = class _ResponseWalletList extends exports.Response {
|
|
30030
30213
|
/**
|
|
30031
30214
|
* Class constructor
|
|
@@ -30963,133 +31146,6 @@ ${operationTypes.join("\n")}
|
|
|
30963
31146
|
}
|
|
30964
31147
|
};
|
|
30965
31148
|
|
|
30966
|
-
// src/response/ResponseQueryUserActivity.ts
|
|
30967
|
-
init_Response();
|
|
30968
|
-
var ResponseQueryUserActivity = class extends exports.Response {
|
|
30969
|
-
/**
|
|
30970
|
-
* Constructor
|
|
30971
|
-
*/
|
|
30972
|
-
constructor({
|
|
30973
|
-
query,
|
|
30974
|
-
json
|
|
30975
|
-
}) {
|
|
30976
|
-
super({
|
|
30977
|
-
query,
|
|
30978
|
-
json,
|
|
30979
|
-
dataKey: "data.UserActivity"
|
|
30980
|
-
});
|
|
30981
|
-
}
|
|
30982
|
-
/**
|
|
30983
|
-
* Returns processed user activity data
|
|
30984
|
-
*/
|
|
30985
|
-
payload() {
|
|
30986
|
-
const data = JSON.parse(JSON.stringify(this.data()));
|
|
30987
|
-
if (data.instances) {
|
|
30988
|
-
for (const datum of data.instances) {
|
|
30989
|
-
if (datum.jsonData) {
|
|
30990
|
-
datum.jsonData = JSON.parse(datum.jsonData);
|
|
30991
|
-
}
|
|
30992
|
-
}
|
|
30993
|
-
}
|
|
30994
|
-
return data;
|
|
30995
|
-
}
|
|
30996
|
-
};
|
|
30997
|
-
|
|
30998
|
-
// src/query/QueryUserActivity.ts
|
|
30999
|
-
var QueryUserActivity = class extends Query {
|
|
31000
|
-
/**
|
|
31001
|
-
* Constructor
|
|
31002
|
-
*/
|
|
31003
|
-
constructor(graphQLClient, knishIOClient) {
|
|
31004
|
-
super(graphQLClient, knishIOClient);
|
|
31005
|
-
this.$__query = gql`
|
|
31006
|
-
query UserActivity(
|
|
31007
|
-
$bundleHash: String
|
|
31008
|
-
$metaType: String
|
|
31009
|
-
$metaId: String
|
|
31010
|
-
$ipAddress: String
|
|
31011
|
-
$browser: String
|
|
31012
|
-
$osCpu: String
|
|
31013
|
-
$resolution: String
|
|
31014
|
-
$timeZone: String
|
|
31015
|
-
$countBy: [CountByUserActivity]
|
|
31016
|
-
$interval: span
|
|
31017
|
-
) {
|
|
31018
|
-
UserActivity(
|
|
31019
|
-
bundleHash: $bundleHash
|
|
31020
|
-
metaType: $metaType
|
|
31021
|
-
metaId: $metaId
|
|
31022
|
-
ipAddress: $ipAddress
|
|
31023
|
-
browser: $browser
|
|
31024
|
-
osCpu: $osCpu
|
|
31025
|
-
resolution: $resolution
|
|
31026
|
-
timeZone: $timeZone
|
|
31027
|
-
countBy: $countBy
|
|
31028
|
-
interval: $interval
|
|
31029
|
-
) {
|
|
31030
|
-
createdAt
|
|
31031
|
-
bundleHash
|
|
31032
|
-
metaType
|
|
31033
|
-
metaId
|
|
31034
|
-
instances {
|
|
31035
|
-
bundleHash
|
|
31036
|
-
metaType
|
|
31037
|
-
metaId
|
|
31038
|
-
jsonData
|
|
31039
|
-
createdAt
|
|
31040
|
-
updatedAt
|
|
31041
|
-
}
|
|
31042
|
-
instanceCount {
|
|
31043
|
-
...SubFields
|
|
31044
|
-
...Recursive
|
|
31045
|
-
}
|
|
31046
|
-
}
|
|
31047
|
-
}
|
|
31048
|
-
|
|
31049
|
-
fragment SubFields on InstanceCountType {
|
|
31050
|
-
id
|
|
31051
|
-
count
|
|
31052
|
-
}
|
|
31053
|
-
|
|
31054
|
-
fragment Recursive on InstanceCountType {
|
|
31055
|
-
instances {
|
|
31056
|
-
...SubFields
|
|
31057
|
-
instances {
|
|
31058
|
-
...SubFields
|
|
31059
|
-
instances {
|
|
31060
|
-
...SubFields
|
|
31061
|
-
instances {
|
|
31062
|
-
...SubFields
|
|
31063
|
-
instances {
|
|
31064
|
-
...SubFields
|
|
31065
|
-
instances {
|
|
31066
|
-
...SubFields
|
|
31067
|
-
instances {
|
|
31068
|
-
...SubFields
|
|
31069
|
-
instances {
|
|
31070
|
-
...SubFields
|
|
31071
|
-
}
|
|
31072
|
-
}
|
|
31073
|
-
}
|
|
31074
|
-
}
|
|
31075
|
-
}
|
|
31076
|
-
}
|
|
31077
|
-
}
|
|
31078
|
-
}
|
|
31079
|
-
}
|
|
31080
|
-
`;
|
|
31081
|
-
}
|
|
31082
|
-
/**
|
|
31083
|
-
* Returns a Response object
|
|
31084
|
-
*/
|
|
31085
|
-
createResponse(json) {
|
|
31086
|
-
return new ResponseQueryUserActivity({
|
|
31087
|
-
query: this,
|
|
31088
|
-
json
|
|
31089
|
-
});
|
|
31090
|
-
}
|
|
31091
|
-
};
|
|
31092
|
-
|
|
31093
31149
|
// src/query/QueryToken.ts
|
|
31094
31150
|
init_Response();
|
|
31095
31151
|
var QueryToken = class extends Query {
|
|
@@ -31931,6 +31987,20 @@ ${operationTypes.join("\n")}
|
|
|
31931
31987
|
this.$__molecule.sign({});
|
|
31932
31988
|
this.$__molecule.check(this.$__molecule.sourceWallet);
|
|
31933
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
|
+
}
|
|
31934
32004
|
/**
|
|
31935
32005
|
* Builds a Response object out of a JSON object
|
|
31936
32006
|
* Matches JavaScript SDK createResponse method signature exactly
|
|
@@ -31991,7 +32061,8 @@ ${operationTypes.join("\n")}
|
|
|
31991
32061
|
bundle: this.$__molecule.bundle,
|
|
31992
32062
|
token,
|
|
31993
32063
|
batchId
|
|
31994
|
-
})
|
|
32064
|
+
});
|
|
32065
|
+
this.$__molecule.initShadowWalletClaim(wallet);
|
|
31995
32066
|
this.$__molecule.sign({});
|
|
31996
32067
|
this.$__molecule.check();
|
|
31997
32068
|
}
|
|
@@ -33251,6 +33322,75 @@ ${operationTypes.join("\n")}
|
|
|
33251
33322
|
});
|
|
33252
33323
|
return await this.executeQuery(query);
|
|
33253
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
|
+
}
|
|
33254
33394
|
/**
|
|
33255
33395
|
* Request authorization token (guest or profile)
|
|
33256
33396
|
*
|
|
@@ -33707,36 +33847,6 @@ ${operationTypes.join("\n")}
|
|
|
33707
33847
|
metaId
|
|
33708
33848
|
});
|
|
33709
33849
|
}
|
|
33710
|
-
/**
|
|
33711
|
-
* Query user activity
|
|
33712
|
-
*/
|
|
33713
|
-
async queryUserActivity({
|
|
33714
|
-
bundleHash,
|
|
33715
|
-
metaType,
|
|
33716
|
-
metaId,
|
|
33717
|
-
ipAddress = null,
|
|
33718
|
-
browser = null,
|
|
33719
|
-
osCpu = null,
|
|
33720
|
-
resolution = null,
|
|
33721
|
-
timeZone = null,
|
|
33722
|
-
countBy = null,
|
|
33723
|
-
interval = null
|
|
33724
|
-
}) {
|
|
33725
|
-
const query = this.createQuery(QueryUserActivity);
|
|
33726
|
-
const variables = {
|
|
33727
|
-
bundleHash,
|
|
33728
|
-
metaType,
|
|
33729
|
-
metaId
|
|
33730
|
-
};
|
|
33731
|
-
if (ipAddress !== null) variables.ipAddress = ipAddress;
|
|
33732
|
-
if (browser !== null) variables.browser = browser;
|
|
33733
|
-
if (osCpu !== null) variables.osCpu = osCpu;
|
|
33734
|
-
if (resolution !== null) variables.resolution = resolution;
|
|
33735
|
-
if (timeZone !== null) variables.timeZone = timeZone;
|
|
33736
|
-
if (countBy !== null) variables.countBy = countBy;
|
|
33737
|
-
if (interval !== null) variables.interval = interval;
|
|
33738
|
-
return this.executeQuery(query, variables);
|
|
33739
|
-
}
|
|
33740
33850
|
/**
|
|
33741
33851
|
* Query token information
|
|
33742
33852
|
*/
|
|
@@ -33845,9 +33955,27 @@ ${operationTypes.join("\n")}
|
|
|
33845
33955
|
amount = null,
|
|
33846
33956
|
meta = null,
|
|
33847
33957
|
batchId = null,
|
|
33848
|
-
units
|
|
33958
|
+
units = null
|
|
33849
33959
|
}) {
|
|
33850
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
|
+
}
|
|
33851
33979
|
const mutation = await this.createMoleculeMutation({ mutationClass: MutationCreateToken });
|
|
33852
33980
|
const recipientWallet = new Wallet({
|
|
33853
33981
|
secret: this.getSecret(),
|
|
@@ -33857,8 +33985,8 @@ ${operationTypes.join("\n")}
|
|
|
33857
33985
|
});
|
|
33858
33986
|
await mutation.fillMolecule({
|
|
33859
33987
|
recipientWallet,
|
|
33860
|
-
amount:
|
|
33861
|
-
meta
|
|
33988
|
+
amount: resolvedAmount,
|
|
33989
|
+
meta: tokenMeta
|
|
33862
33990
|
});
|
|
33863
33991
|
const response = await this.executeQuery(mutation);
|
|
33864
33992
|
if (!response) {
|
|
@@ -34299,8 +34427,12 @@ ${operationTypes.join("\n")}
|
|
|
34299
34427
|
mutationClass: MutationRequestAuthorization,
|
|
34300
34428
|
molecule
|
|
34301
34429
|
});
|
|
34430
|
+
const authMeta = { encrypt: encrypt ? "true" : "false" };
|
|
34431
|
+
if (wallet.pubkey) {
|
|
34432
|
+
authMeta.walletPubkey = wallet.pubkey;
|
|
34433
|
+
}
|
|
34302
34434
|
mutation.fillMolecule({
|
|
34303
|
-
meta:
|
|
34435
|
+
meta: authMeta
|
|
34304
34436
|
});
|
|
34305
34437
|
const response = await this.executeQuery(mutation);
|
|
34306
34438
|
if (!response) {
|