From bed4f31efc131c0305b2d886492625687b399edc Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 2 Apr 2025 13:17:40 -0700
Subject: [PATCH 01/80] Add decryptdata, getidentitycontent and
z_getencryptionaddress to the native api.
---
package.json | 2 +-
routes/api.js | 2 +
routes/api/native/decryptdata.js | 62 +++++++++++++++++++++
routes/api/native/idInformation.js | 64 +++++++++++++++++++++-
routes/api/native/zgetencryptionaddress.js | 62 +++++++++++++++++++++
yarn.lock | 10 ++++
6 files changed, 200 insertions(+), 2 deletions(-)
create mode 100644 routes/api/native/decryptdata.js
create mode 100644 routes/api/native/zgetencryptionaddress.js
diff --git a/package.json b/package.json
index 754c1379..5d9978c2 100644
--- a/package.json
+++ b/package.json
@@ -80,7 +80,7 @@
"systeminformation": "5.23.8",
"tx-builder": "^0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/VerusCoin/verus-typescript-primitives.git",
+ "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
"verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client",
diff --git a/routes/api.js b/routes/api.js
index 8b79089f..aab6d911 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -137,6 +137,7 @@ api = require('./api/native/mininginfo')(api);
api = require('./api/native/getTransaction.js')(api);
api = require('./api/native/transactions')(api);
api = require('./api/native/zoperations')(api);
+api = require('./api/native/zgetencryptionaddress.js')(api);
api = require('./api/native/remove')(api);
api = require('./api/native/restart')(api);
api = require('./api/native/send.js')(api);
@@ -154,6 +155,7 @@ api = require('./api/native/estimateConversion.js')(api);
api = require('./api/native/getConversionPaths.js')(api);
api = require('./api/native/currencyGraylist.js')(api);
api = require('./api/native/idRecovery.js')(api);
+api = require('./api/native/decryptdata.js')(api);
api = require('./api/native/signdata.js')(api);
api = require('./api/native/verifydata.js')(api);
api = require('./api/native/generate.js')(api);
diff --git a/routes/api/native/decryptdata.js b/routes/api/native/decryptdata.js
new file mode 100644
index 00000000..2b37bb81
--- /dev/null
+++ b/routes/api/native/decryptdata.js
@@ -0,0 +1,62 @@
+module.exports = (api) => {
+
+ /**
+ * Decrypts data given the arguments of a data descriptor, and optionally
+ * evk, ivk, txid and/or if to retrieve the data from its reference.
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} arguments The arguments to pass to decryptdata
+ */
+ api.native.decrypt_data = (
+ coin,
+ arguments,
+ ) => {
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(
+ coin,
+ "decryptdata",
+ [
+ arguments,
+ ]
+ )
+ .then(resultObj => {
+ resolve(resultObj)
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ };
+
+ api.setPost('/native/decrypt_data', (req, res, next) => {
+ const {
+ chainTicker,
+ arguments
+ } = req.body;
+
+ api.native
+ .decrypt_data(
+ chainTicker,
+ arguments
+ )
+ .then(resultObj => {
+ const retObj = {
+ msg: "success",
+ result: resultObj
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: "error",
+ result: error.message
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
+ });
+
+ return api;
+};
\ No newline at end of file
diff --git a/routes/api/native/idInformation.js b/routes/api/native/idInformation.js
index dc4608a2..fde78298 100644
--- a/routes/api/native/idInformation.js
+++ b/routes/api/native/idInformation.js
@@ -281,6 +281,68 @@ module.exports = (api) => {
res.send(JSON.stringify(retObj));
})
});
-
+
+ api.native.get_identity_content = (coin, name) => {
+ return new Promise((resolve, reject) => {
+ api.native.callDaemon(coin, 'getidentitycontent', [name])
+ .then(async (identity) => {
+ if (
+ identity.identity.parent !==
+ "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV" &&
+ identity.identity.parent !==
+ "iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq" &&
+ // Avoid trying to get the null parent of VRSC or VRSCTEST.
+ identity.identity.parent !==
+ "i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk"
+ ) {
+ identity.identity.name = `${identity.identity.name}.${
+ (
+ await api.native.get_currency_definition(
+ coin,
+ identity.identity.parent
+ )
+ ).name
+ }`;
+ }
+
+ try {
+ identity.offers = await api.native.getoffers(
+ new GetOffersRequest(coin, identity.identity.identityaddress, false, false)
+ );
+ } catch (e) {
+ api.log(`Failed to get offers for ${identity.identity.name}`, "get_identity_content");
+ api.log(e, "get_identity_content");
+ }
+
+ resolve(identity)
+ })
+ .catch(err => {
+ reject(err)
+ })
+ });
+ };
+
+ api.setPost('/native/get_identity_content', (req, res, next) => {
+ const { chainTicker, name } = req.body
+
+ api.native.get_identity_content(chainTicker, name)
+ .then((identity) => {
+ const retObj = {
+ msg: 'success',
+ result: identity,
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ });
+
return api;
};
\ No newline at end of file
diff --git a/routes/api/native/zgetencryptionaddress.js b/routes/api/native/zgetencryptionaddress.js
new file mode 100644
index 00000000..e3d45604
--- /dev/null
+++ b/routes/api/native/zgetencryptionaddress.js
@@ -0,0 +1,62 @@
+module.exports = (api) => {
+
+ /**
+ * Generates a z-address, viewing key, and optionally an extended secret key using either
+ * a z-address in the wallet, wallet seed and hdindex, or root key (extended private key).
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} arguments The arguments to pass to z_getencryptionaddress
+ */
+ api.native.z_get_encryption_address = (
+ coin,
+ arguments,
+ ) => {
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(
+ coin,
+ "z_getencryptionaddress",
+ [
+ arguments,
+ ]
+ )
+ .then(resultObj => {
+ resolve(resultObj)
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ };
+
+ api.setPost('/native/z_get_encryption_address', (req, res, next) => {
+ const {
+ chainTicker,
+ arguments
+ } = req.body;
+
+ api.native
+ .z_get_encryption_address(
+ chainTicker,
+ arguments
+ )
+ .then(resultObj => {
+ const retObj = {
+ msg: "success",
+ result: resultObj
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: "error",
+ result: error.message
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
+ });
+
+ return api;
+ };
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index ca5d2691..97615a9b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8005,6 +8005,16 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
+"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
+ version "1.0.0"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#dd497f8efaf28e8a6e22f810da14bb45ba9e7dab"
+ dependencies:
+ base64url "3.0.1"
+ bech32 "2.0.0"
+ bn.js "5.2.1"
+ bs58check "2.0.0"
+ create-hash "1.2.0"
+
"verus-wallet-endpoints@git+https://github.com/VerusCoin/verus-wallet-endpoints.git":
version "1.0.0"
resolved "git+https://github.com/VerusCoin/verus-wallet-endpoints.git#d7c9d51138e5231ac66cbfe316fb5d7527d35e4c"
From 8bd5a243753373f674d0fb468666e3118e926881 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 3 Apr 2025 22:36:06 -0700
Subject: [PATCH 02/80] Add credential decryption from an identity and fix
formatting for the api of z_getencryptionaddress.
---
routes/api.js | 1 +
.../api/native/credentials/getCredentials.js | 161 ++++++++++++++++++
routes/api/native/zgetencryptionaddress.js | 110 ++++++------
.../api/utils/credentials/parseCredential.js | 15 ++
yarn.lock | 2 +-
5 files changed, 233 insertions(+), 56 deletions(-)
create mode 100644 routes/api/native/credentials/getCredentials.js
create mode 100644 routes/api/utils/credentials/parseCredential.js
diff --git a/routes/api.js b/routes/api.js
index aab6d911..058d8ffb 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -167,6 +167,7 @@ api = require('./api/native/verusid/login/verifyRequest.js')(api);
api = require('./api/native/verusid/login/signResponse.js')(api);
api = require('./api/native/verusid/provision/signIdProvisioningRequest.js')(api);
api = require('./api/native/verusid/provision/verifyIdProvisioningResponse.js')(api);
+api = require('./api/native/credentials/getCredentials.js')(api);
api = require('./api/native/makeoffer')(api);
api = require('./api/native/getoffers')(api);
api = require('./api/native/closeoffers')(api);
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
new file mode 100644
index 00000000..443b5cc7
--- /dev/null
+++ b/routes/api/native/credentials/getCredentials.js
@@ -0,0 +1,161 @@
+const {
+ DATA_TYPE_OBJECT_DATADESCRIPTOR,
+} = require("verus-typescript-primitives");
+const { parseCredential } = require("../../utils/credentials/parseCredential");
+
+module.exports = (api) => {
+ /**
+ * Extracts and decrypts the list of credentials in the given identity
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} address The identity or address to get the credentials from
+ */
+ api.native.get_credentials_list = async (
+ coin,
+ address
+ ) => {
+ // Get the z-address and contentmultimap from the address
+ const identity = await api.native.get_identity_content(coin, address);
+
+ if (!identity || !identity.identity) {
+ throw new Error(`Identity not found for ${address}`);
+ }
+
+ const zaddress = identity.identity.privateaddress;
+
+ if (!zaddress) {
+ throw new Error(`No z-address found for identity ${address}`);
+ }
+
+ // Generate the viewing key to decrypt the credentials.
+ const keys = await api.native.z_get_encryption_address(
+ coin,
+ {
+ address: zaddress,
+ fromid: address,
+ toid: address
+ }
+ );
+
+ if (!keys || !keys.extendedviewingkey) {
+ throw new Error(`Failed to get keys for ${address}`);
+ }
+
+ const viewingKey = keys.extendedviewingkey;
+
+ // Generate the credential key using the viewing key
+ const credentialKeyResult = await api.native.get_vdxf_id(
+ coin,
+ "vrsc::identity.credentials",
+ { vdxfkey: viewingKey }
+ );
+
+ if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
+ throw new Error("Failed to generate credential key");
+ }
+
+ const credentialKey = credentialKeyResult.vdxfid;
+
+ // Check if the identity has credentials in its content multimap.
+ if (!identity.identity.contentmultimap || !identity.identity.contentmultimap[credentialKey]) {
+ return []; // No credentials found.
+ }
+
+ const credentialEntries = identity.identity.contentmultimap[credentialKey];
+ const credentials = [];
+
+ for (const entry of credentialEntries) {
+ if (entry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid]) {
+ const dataDescriptor = entry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid];
+
+ // Decrypt the data descriptor using the viewing key.
+ try {
+ const decryptedData = await api.native.decrypt_data(
+ coin,
+ {
+ datadescriptor: dataDescriptor,
+ evk: viewingKey
+ }
+ );
+
+ // The data descriptor is in a list.
+ if (decryptedData && Array.isArray(decryptedData)) {
+ const credObj = decryptedData[0];
+ const cred = parseCredential(credObj);
+ credentials.push(cred);
+ }
+ } catch (err) {
+ console.error(`Failed to decrypt credential: ${err.message}`);
+ // Decrypt the other credentials even if one fails.
+ }
+ }
+ }
+
+ return credentials;
+ };
+
+ /**
+ * Creates a map of credentials organized by scope
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} address The identity or address to get the credentials from
+ */
+ api.native.get_credentials_map = async (
+ coin,
+ address
+ ) => {
+ // Get the list of credentials.
+ const credentialsList = await api.native.get_credentials_list(coin, address);
+
+ const credentialsMap = {};
+
+ // Track seen credential keys by scope to avoid duplicates.
+ const seenCredentials = {};
+
+ // Process each credential and organize by scope.
+ for (const credential of credentialsList) {
+
+ const scope = credential.scopes;
+ const credentialKey = credential.credentialKey;
+
+ if (!credentialsMap[scope]) {
+ credentialsMap[scope] = [];
+ }
+
+ // Using a set to track duplicates for efficient lookup.
+ if (!seenCredentials[scope]) {
+ seenCredentials[scope] = new Set();
+ }
+
+ // Skip duplicate credentials that come later since they are
+ // the previous credentials for that scope.
+ if (!seenCredentials[scope].has(credentialKey)) {
+ credentialsMap[scope].push(credential);
+ seenCredentials[scope].add(credentialKey);
+ }
+ }
+
+ return credentialsMap;
+ };
+
+ /**
+ * Creates a map of credentials organized by scope
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} address The identity or address to get the credentials from
+ * @param {String} scope The scope of the credentials to get
+ */
+
+ api.native.get_credentials_by_scope = async (
+ coin,
+ address,
+ scope
+ ) => {
+ const credentialsMap = await api.native.get_credentials_map(coin, address);
+
+ console.log(credentialsMap[scope])
+ return credentialsMap[scope];
+ }
+
+ return api;
+};
diff --git a/routes/api/native/zgetencryptionaddress.js b/routes/api/native/zgetencryptionaddress.js
index e3d45604..ef6b0fd4 100644
--- a/routes/api/native/zgetencryptionaddress.js
+++ b/routes/api/native/zgetencryptionaddress.js
@@ -1,62 +1,62 @@
module.exports = (api) => {
- /**
- * Generates a z-address, viewing key, and optionally an extended secret key using either
- * a z-address in the wallet, wallet seed and hdindex, or root key (extended private key).
- *
- * @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} arguments The arguments to pass to z_getencryptionaddress
- */
- api.native.z_get_encryption_address = (
- coin,
- arguments,
- ) => {
- return new Promise((resolve, reject) => {
- api.native
- .callDaemon(
- coin,
- "z_getencryptionaddress",
- [
- arguments,
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
+ /**
+ * Generates a z-address, viewing key, and optionally an extended secret key using either
+ * a z-address in the wallet, wallet seed and hdindex, or root key (extended private key).
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} arguments The arguments to pass to z_getencryptionaddress
+ */
+ api.native.z_get_encryption_address = (
+ coin,
+ arguments,
+ ) => {
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(
+ coin,
+ "z_getencryptionaddress",
+ [
+ arguments,
+ ]
+ )
+ .then(resultObj => {
+ resolve(resultObj)
+ })
+ .catch(err => {
+ reject(err);
});
- };
+ });
+ };
- api.setPost('/native/z_get_encryption_address', (req, res, next) => {
- const {
- chainTicker,
- arguments
- } = req.body;
+ api.setPost('/native/z_get_encryption_address', (req, res, next) => {
+ const {
+ chainTicker,
+ arguments
+ } = req.body;
- api.native
- .z_get_encryption_address(
- chainTicker,
- arguments
- )
- .then(resultObj => {
- const retObj = {
- msg: "success",
- result: resultObj
- };
+ api.native
+ .z_get_encryption_address(
+ chainTicker,
+ arguments
+ )
+ .then(resultObj => {
+ const retObj = {
+ msg: "success",
+ result: resultObj
+ };
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
- msg: "error",
- result: error.message
- };
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: "error",
+ result: error.message
+ };
- res.send(JSON.stringify(retObj));
- });
- });
-
- return api;
- };
\ No newline at end of file
+ res.send(JSON.stringify(retObj));
+ });
+ });
+
+ return api;
+};
\ No newline at end of file
diff --git a/routes/api/utils/credentials/parseCredential.js b/routes/api/utils/credentials/parseCredential.js
new file mode 100644
index 00000000..43ffeb74
--- /dev/null
+++ b/routes/api/utils/credentials/parseCredential.js
@@ -0,0 +1,15 @@
+const {
+ Credential,
+ DATA_TYPE_OBJECT_CREDENTIAL,
+} = require("verus-typescript-primitives");
+
+// parseCredential converts a credential object from a data descriptor into a credential class.
+const parseCredential = (credObj) => {
+ const credJson = credObj[DATA_TYPE_OBJECT_CREDENTIAL.vdxfid];
+
+ return Credential.fromJSON(credJson);
+};
+
+module.exports = {
+ parseCredential
+};
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 97615a9b..f2076e76 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#dd497f8efaf28e8a6e22f810da14bb45ba9e7dab"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#45002fa364bcf66fd4f0a87f37bac689a04b14bf"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From 6179a4a11bc9889e7aab8dc460b7d01deb040373 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 4 Apr 2025 12:04:14 -0700
Subject: [PATCH 03/80] Convert scopes into i-addresses when possible in order
to make credential lookup easier for login.
---
routes/api/native/credentials/getCredentials.js | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 443b5cc7..2410a12a 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -1,5 +1,6 @@
const {
DATA_TYPE_OBJECT_DATADESCRIPTOR,
+ fromBase58Check,
} = require("verus-typescript-primitives");
const { parseCredential } = require("../../utils/credentials/parseCredential");
@@ -115,7 +116,21 @@ module.exports = (api) => {
// Process each credential and organize by scope.
for (const credential of credentialsList) {
- const scope = credential.scopes;
+ // Try to convert the scope into an i-address, if it isn't one already.
+ let scope = credential.scopes;
+ try {
+ fromBase58Check(scope);
+ } catch {
+ try {
+ const scopeId = await api.native.get_identity(coin, credential.scopes);
+ if (scopeId && scopeId.identity && scopeId.identity.identityaddress) {
+ scope = scopeId.identity.identityaddress;
+ }
+ // If there is an error getting the identity, then the scope is not an identity.
+ // In that case, just leave the scope as is.
+ } catch {}
+ }
+
const credentialKey = credential.credentialKey;
if (!credentialsMap[scope]) {
From 6658120321f64bd155aac4c26f74f83d44360cec Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 4 Apr 2025 14:00:45 -0700
Subject: [PATCH 04/80] Add API POST endpoint for getting the credentials for a
specific scope and remove the console logging for debugging the credential
fetching.
---
.../api/native/credentials/getCredentials.js | 36 +++++++++++++++++--
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 2410a12a..3826585b 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -167,10 +167,40 @@ module.exports = (api) => {
scope
) => {
const credentialsMap = await api.native.get_credentials_map(coin, address);
-
- console.log(credentialsMap[scope])
+
return credentialsMap[scope];
- }
+ };
+
+ api.setPost("/native/get_credentials_by_scope", async (req, res, next) => {
+ const {
+ coin,
+ address,
+ scope
+ } = req.body;
+
+ api.native
+ .get_credentials_by_scope(
+ coin,
+ address,
+ scope
+ )
+ .then(resultObj => {
+ const retObj = {
+ msg: "success",
+ result: resultObj
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: "error",
+ result: error.message
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
+ });
return api;
};
From f3549081060715bb8afa3c744a4c032407efc6d0 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 4 Apr 2025 23:37:21 -0700
Subject: [PATCH 05/80] Update parsing of the credential list to handle older
versions of a credential.
---
routes/api/native/credentials/getCredentials.js | 6 ++++--
yarn.lock | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 3826585b..fbfb8a75 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -113,8 +113,10 @@ module.exports = (api) => {
// Track seen credential keys by scope to avoid duplicates.
const seenCredentials = {};
- // Process each credential and organize by scope.
- for (const credential of credentialsList) {
+ // Process each credential and organize by scope in reverse order so
+ // the newest credentials are first.
+ for (let i = credentialsList.length - 1; i >= 0; i--) {
+ const credential = credentialsList[i];
// Try to convert the scope into an i-address, if it isn't one already.
let scope = credential.scopes;
diff --git a/yarn.lock b/yarn.lock
index f2076e76..079d5d8f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#45002fa364bcf66fd4f0a87f37bac689a04b14bf"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#4368bf8780c00e779f83cd1c37a0412d10449aa4"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From ade9d15e2913afa32edd40ff5b0f50b4d51596eb Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 6 May 2025 17:04:01 -0700
Subject: [PATCH 06/80] Update the fetching of credentials to handle the plain
login credential and arrays of scopes.
---
main.js | 4 ++--
.../api/native/credentials/getCredentials.js | 24 +++++++++----------
yarn.lock | 2 +-
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/main.js b/main.js
index de740841..c70860cc 100644
--- a/main.js
+++ b/main.js
@@ -553,8 +553,8 @@ if (!hasLock) {
focusMain();
if (process.platform == "win32" || process.platform == "linux") {
- const argIndex = 2;
- openurlhandler(null, argv.slice(1).toString().split(",")[argIndex], api.dlhandler);
+ const argIndex = process.platform === "win32" ? 1 : 2;
+ openurlhandler(null, argv.slice(1)[argIndex], api.dlhandler);
}
}
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index fbfb8a75..55fc41a1 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -113,20 +113,20 @@ module.exports = (api) => {
// Track seen credential keys by scope to avoid duplicates.
const seenCredentials = {};
- // Process each credential and organize by scope in reverse order so
+ // Process each credential and organize by the main scope in reverse order so
// the newest credentials are first.
for (let i = credentialsList.length - 1; i >= 0; i--) {
const credential = credentialsList[i];
- // Try to convert the scope into an i-address, if it isn't one already.
- let scope = credential.scopes;
+ // Try to convert the main scope into an i-address, if it isn't one already.
+ let mainScope = credential.scopes[0];
try {
fromBase58Check(scope);
} catch {
try {
- const scopeId = await api.native.get_identity(coin, credential.scopes);
+ const scopeId = await api.native.get_identity(coin, mainScope);
if (scopeId && scopeId.identity && scopeId.identity.identityaddress) {
- scope = scopeId.identity.identityaddress;
+ mainScope = scopeId.identity.identityaddress;
}
// If there is an error getting the identity, then the scope is not an identity.
// In that case, just leave the scope as is.
@@ -135,20 +135,20 @@ module.exports = (api) => {
const credentialKey = credential.credentialKey;
- if (!credentialsMap[scope]) {
- credentialsMap[scope] = [];
+ if (!credentialsMap[mainScope]) {
+ credentialsMap[mainScope] = [];
}
// Using a set to track duplicates for efficient lookup.
- if (!seenCredentials[scope]) {
- seenCredentials[scope] = new Set();
+ if (!seenCredentials[mainScope]) {
+ seenCredentials[mainScope] = new Set();
}
// Skip duplicate credentials that come later since they are
// the previous credentials for that scope.
- if (!seenCredentials[scope].has(credentialKey)) {
- credentialsMap[scope].push(credential);
- seenCredentials[scope].add(credentialKey);
+ if (!seenCredentials[mainScope].has(credentialKey)) {
+ credentialsMap[mainScope].push(credential);
+ seenCredentials[mainScope].add(credentialKey);
}
}
diff --git a/yarn.lock b/yarn.lock
index 079d5d8f..80e21f13 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#4368bf8780c00e779f83cd1c37a0412d10449aa4"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#db0bd6cca7a3969d462e4722a0174a06b26e9bc5"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From b0c324a95de9e58e7a0388f33bca1c2b5635112b Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 8 May 2025 14:54:48 -0700
Subject: [PATCH 07/80] Update the verus-typescript-primitives version to get
changes to the login response decision's context and credentials.
---
yarn.lock | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/yarn.lock b/yarn.lock
index 80e21f13..cef16728 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#db0bd6cca7a3969d462e4722a0174a06b26e9bc5"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#0d06b404ec018be0df7a47d5551b1cf241df59fc"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From fea9860a73001901b956abc2d27d3a20409be543 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 9 May 2025 14:15:23 -0700
Subject: [PATCH 08/80] Update credential fetching to send only specific types
of credentials based on credential keys.
---
.../api/native/credentials/getCredentials.js | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 55fc41a1..30ff0e88 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -161,30 +161,41 @@ module.exports = (api) => {
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to get the credentials from
* @param {String} scope The scope of the credentials to get
+ * @param {string[]} credentialKeys - Optional list of credential keys to filter the result by
*/
api.native.get_credentials_by_scope = async (
coin,
address,
- scope
+ scope,
+ credentialKeys
) => {
const credentialsMap = await api.native.get_credentials_map(coin, address);
+ const scopeCredentials = credentialsMap[scope] || [];
- return credentialsMap[scope];
+ if (!credentialKeys || credentialKeys.length === 0) {
+ return scopeCredentials;
+ }
+
+ return scopeCredentials.filter(cred =>
+ credentialKeys.includes(cred.credentialKey)
+ );
};
api.setPost("/native/get_credentials_by_scope", async (req, res, next) => {
const {
coin,
address,
- scope
+ scope,
+ credentialKeys
} = req.body;
api.native
.get_credentials_by_scope(
coin,
address,
- scope
+ scope,
+ credentialKeys
)
.then(resultObj => {
const retObj = {
From 22d6ab5557b6a74d15f23dc0dd193eafd5ce1a36 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 1 Jul 2025 09:42:58 -0700
Subject: [PATCH 09/80] Update verus-typescript-primitives to use the
credential class version with the identity update request and change login
request handling to not require the chain ticker in the request.
---
package.json | 2 +-
routes/api/native/verusid/login/signResponse.js | 17 ++++++-----------
.../api/native/verusid/login/verifyRequest.js | 9 ++++-----
routes/api/utils/credentials/parseCredential.js | 2 +-
yarn.lock | 5 +++--
5 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/package.json b/package.json
index 5d9978c2..e7644d2c 100644
--- a/package.json
+++ b/package.json
@@ -80,7 +80,7 @@
"systeminformation": "5.23.8",
"tx-builder": "^0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class",
+ "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class-iur",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
"verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client",
diff --git a/routes/api/native/verusid/login/signResponse.js b/routes/api/native/verusid/login/signResponse.js
index 540c1b72..52e41bbd 100644
--- a/routes/api/native/verusid/login/signResponse.js
+++ b/routes/api/native/verusid/login/signResponse.js
@@ -5,14 +5,12 @@ const {
} = require("verus-typescript-primitives");
module.exports = (api) => {
- api.native.verusid.login.sign_response = async (response) => {
+ api.native.verusid.login.sign_response = async (coin, response) => {
const loginResponse = new LoginConsentResponse(response);
- const chainTicker = response.chainTicker
- // Add the chainTicker when checking the request since the verify request needs it.
- let decisionRequest = loginResponse.decision.request
- decisionRequest.chainTicker = chainTicker
+ const decisionRequest = loginResponse.decision.request
const verificatonCheck = await api.native.verusid.login.verify_request(
+ coin,
decisionRequest
);
@@ -20,7 +18,7 @@ module.exports = (api) => {
throw new Error(verificatonCheck.message);
}
- const signdataResult = await api.native.sign_data(chainTicker,
+ const signdataResult = await api.native.sign_data(coin,
{
"address": loginResponse.signing_id,
"datahash": loginResponse.decision.toSha256().toString("hex")
@@ -32,20 +30,17 @@ module.exports = (api) => {
LOGIN_CONSENT_RESPONSE_SIG_VDXF_KEY
);
- // Remove the chainTicker field since it's not normally part of the response.
- delete decisionRequest.chainTicker
-
return { response: loginResponse};
};
api.setPost("/native/verusid/login/sign_response", async (req, res, next) => {
- const { response } = req.body;
+ const { chainTicker, response } = req.body;
try {
res.send(
JSON.stringify({
msg: "success",
- result: await api.native.verusid.login.sign_response(response),
+ result: await api.native.verusid.login.sign_response(chainTicker, response),
})
);
} catch (e) {
diff --git a/routes/api/native/verusid/login/verifyRequest.js b/routes/api/native/verusid/login/verifyRequest.js
index c80c0358..097f676e 100644
--- a/routes/api/native/verusid/login/verifyRequest.js
+++ b/routes/api/native/verusid/login/verifyRequest.js
@@ -5,12 +5,11 @@ module.exports = (api) => {
* Verifies a login request
* @param {LoginConsentRequest} Request
*/
- api.native.verusid.login.verify_request = async (request) => {
+ api.native.verusid.login.verify_request = async (coin, request) => {
const loginConsentRequest = new LoginConsentRequest(request);
- const chainTicker = request.chainTicker
const verified = await api.native.verify_hash(
- chainTicker,
+ coin,
loginConsentRequest.signing_id,
loginConsentRequest.challenge.toSha256().toString('hex'),
loginConsentRequest.signature.signature
@@ -20,13 +19,13 @@ module.exports = (api) => {
};
api.setPost("/native/verusid/login/verify_request", async (req, res, next) => {
- const { request } = req.body;
+ const { chainTicker, request } = req.body;
try {
res.send(
JSON.stringify({
msg: "success",
- result: await api.native.verusid.login.verify_request(request),
+ result: await api.native.verusid.login.verify_request(chainTicker, request),
})
);
} catch (e) {
diff --git a/routes/api/utils/credentials/parseCredential.js b/routes/api/utils/credentials/parseCredential.js
index 43ffeb74..90c1552b 100644
--- a/routes/api/utils/credentials/parseCredential.js
+++ b/routes/api/utils/credentials/parseCredential.js
@@ -7,7 +7,7 @@ const {
const parseCredential = (credObj) => {
const credJson = credObj[DATA_TYPE_OBJECT_CREDENTIAL.vdxfid];
- return Credential.fromJSON(credJson);
+ return Credential.fromJson(credJson);
};
module.exports = {
diff --git a/yarn.lock b/yarn.lock
index cef16728..62fbe353 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8005,12 +8005,13 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
-"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class":
+"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class-iur":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#0d06b404ec018be0df7a47d5551b1cf241df59fc"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#02909300fb884b6274d95a01f0b3473a32e9cb4d"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
+ blake2b "https://github.com/VerusCoin/blake2b"
bn.js "5.2.1"
bs58check "2.0.0"
create-hash "1.2.0"
From 480042be533106ee7d5f641dbcf027adf57b838e Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 3 Jul 2025 16:17:28 -0700
Subject: [PATCH 10/80] Start changing the deeplink handler to accept other
types of deeplinks.
---
routes/api/dlhandler.js | 69 +++++++++++++++------
routes/api/plugin/builtin/loginconsentui.js | 8 +--
routes/api/utils/constants/supported_dls.js | 7 ++-
3 files changed, 60 insertions(+), 24 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 6a15e303..65fe4244 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -1,27 +1,60 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY, LoginConsentRequest } = require('verus-typescript-primitives');
+const { LOGIN_CONSENT_REQUEST_VDXF_KEY, LoginConsentRequest, VERUSPAY_INVOICE_VDXF_KEY, VerusPayInvoice } = require('verus-typescript-primitives');
const base64url = require("base64url");
const { ROOT_SYSTEM_NAME } = require('./utils/constants/dev_options');
+const { SUPPORTED_DLS, CALLBACK_HOST } = require('./utils/constants/supported_dls');
module.exports = (api) => {
- api.dlhandler = (url) => {
- const handlers = {
- [LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid]: (url) => {
- const value = url.searchParams.get(LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid)
- const req = new LoginConsentRequest();
- req.fromBuffer(base64url.toBuffer(value));
-
- return api.loginConsentUi.request(
- req.toJson(),
- {
- id: "VERUS_DESKTOP_MAIN",
- search_builtin: true,
- main_chain_ticker: ROOT_SYSTEM_NAME
- }
- )
+ api.dlhandler = (urlstring) => {
+ const deeplinkHandler = (urlstring) => {
+ const url = new URL(urlstring);
+
+ if (url.host !== CALLBACK_HOST) {
+ throw new Error('Unsupported deeplink host url.');
+ }
+
+ const id = url.pathname.split('/')[1];
+
+ if (!SUPPORTED_DLS.includes(id)) {
+ throw new Error('Unsupported deeplink url path.');
}
- }
- return handlers[url.pathname.replace(/\//g, "")](url)
+ let dl;
+
+ switch (id) {
+ case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
+ dl = new LoginConsentRequest();
+ dl.fromBuffer(
+ base64url.toBuffer(
+ url.searchParams.get(LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid),
+ ),
+ );
+ break;
+
+ case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
+ dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
+
+ // TODO: Handle VerusPay invoice processing here
+ throw new Error('VerusPay is unsupported');
+
+ default:
+ throw new Error(`Unsupported deeplink ID: ${id}`);
+ }
+
+
+ return api.loginConsentUi.deeplink(
+ {
+ id: id,
+ data: dl.toJson()
+ },
+ {
+ id: "VERUS_DESKTOP_MAIN",
+ search_builtin: true,
+ main_chain_ticker: ROOT_SYSTEM_NAME
+ }
+ );
+ };
+
+ return deeplinkHandler(urlstring);
}
return api;
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index aa169032..d80373d7 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -46,8 +46,8 @@ module.exports = (api) => {
return handlers[vdxfkey] == null ? null : handlers[vdxfkey]();
}
- api.loginConsentUi.request = async (
- request,
+ api.loginConsentUi.deeplink = async (
+ deeplink,
originInfo
) => {
return new Promise((resolve, reject) => {
@@ -68,7 +68,7 @@ module.exports = (api) => {
pushMessage(
pluginWindow,
{
- request: request,
+ deeplink: deeplink,
origin_app_info: originInfo,
},
"VERUS_LOGIN_CONSENT_REQUEST"
@@ -91,7 +91,7 @@ module.exports = (api) => {
try {
const retObj = {
msg: "success",
- result: await api.loginConsentUi.request(
+ result: await api.loginConsentUi.deeplink(
request,
{
id: app_id,
diff --git a/routes/api/utils/constants/supported_dls.js b/routes/api/utils/constants/supported_dls.js
index 82973bb1..c95082e2 100644
--- a/routes/api/utils/constants/supported_dls.js
+++ b/routes/api/utils/constants/supported_dls.js
@@ -1,8 +1,11 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY } = require("verus-typescript-primitives")
+const { LOGIN_CONSENT_REQUEST_VDXF_KEY, VERUSPAY_INVOICE_VDXF_KEY } = require("verus-typescript-primitives")
const CALLBACK_HOST = 'x-callback-url'
-const SUPPORTED_DLS = [LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid]
+const SUPPORTED_DLS = [
+ LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid,
+ VERUSPAY_INVOICE_VDXF_KEY.vdxfid
+]
module.exports = {
SUPPORTED_DLS,
From bb60233949b73273fc83907d69f5ec1fba349c25 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 11 Jul 2025 10:41:43 -0700
Subject: [PATCH 11/80] Update the deeplink handler to support identity update
requests, fix the double parsing of the deeplink, and enable sending of all
supported deeplink types to the plugin.
---
routes/api/dlhandler.js | 17 +++++++----------
routes/api/utils/constants/supported_dls.js | 5 +++--
routes/deeplink/openurlhandler.js | 8 +-------
3 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 65fe4244..460d35f1 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -1,4 +1,4 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY, LoginConsentRequest, VERUSPAY_INVOICE_VDXF_KEY, VerusPayInvoice } = require('verus-typescript-primitives');
+const { LOGIN_CONSENT_REQUEST_VDXF_KEY, LoginConsentRequest, VERUSPAY_INVOICE_VDXF_KEY, VerusPayInvoice, IDENTITY_UPDATE_REQUEST_VDXF_KEY, IdentityUpdateRequest } = require('verus-typescript-primitives');
const base64url = require("base64url");
const { ROOT_SYSTEM_NAME } = require('./utils/constants/dev_options');
const { SUPPORTED_DLS, CALLBACK_HOST } = require('./utils/constants/supported_dls');
@@ -22,20 +22,17 @@ module.exports = (api) => {
switch (id) {
case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
- dl = new LoginConsentRequest();
- dl.fromBuffer(
- base64url.toBuffer(
- url.searchParams.get(LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid),
- ),
- );
+ dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
break;
case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
-
- // TODO: Handle VerusPay invoice processing here
- throw new Error('VerusPay is unsupported');
+ break;
+ case IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid:
+ dl = IdentityUpdateRequest.fromWalletDeeplinkUri(urlstring);
+ break;
+
default:
throw new Error(`Unsupported deeplink ID: ${id}`);
}
diff --git a/routes/api/utils/constants/supported_dls.js b/routes/api/utils/constants/supported_dls.js
index c95082e2..864293a3 100644
--- a/routes/api/utils/constants/supported_dls.js
+++ b/routes/api/utils/constants/supported_dls.js
@@ -1,10 +1,11 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY, VERUSPAY_INVOICE_VDXF_KEY } = require("verus-typescript-primitives")
+const { LOGIN_CONSENT_REQUEST_VDXF_KEY, VERUSPAY_INVOICE_VDXF_KEY, IDENTITY_UPDATE_REQUEST_VDXF_KEY } = require("verus-typescript-primitives")
const CALLBACK_HOST = 'x-callback-url'
const SUPPORTED_DLS = [
LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid,
- VERUSPAY_INVOICE_VDXF_KEY.vdxfid
+ VERUSPAY_INVOICE_VDXF_KEY.vdxfid,
+ IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid
]
module.exports = {
diff --git a/routes/deeplink/openurlhandler.js b/routes/deeplink/openurlhandler.js
index 5828959c..25140229 100644
--- a/routes/deeplink/openurlhandler.js
+++ b/routes/deeplink/openurlhandler.js
@@ -4,13 +4,7 @@ const { SUPPORTED_DLS, CALLBACK_HOST } = require('../api/utils/constants/support
function openurlhandler(event, urlstring, apihandler) {
try {
- const url = new URL(urlstring);
-
- if (url.host !== CALLBACK_HOST) throw new Error("Unsupported host url.");
- if (!SUPPORTED_DLS.includes(url.pathname.replace(/\//g, "")))
- throw new Error("Unsupported url path.");
-
- return apihandler(url);
+ return apihandler(urlstring);
} catch (e) {
setTimeout(() => {
// This avoids crashing 20 seconds after the error box has been left open.
From 91e83e5f2dc4481c0d9a6463ccd748502edcc0a8 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 16 Jul 2025 13:37:26 -0700
Subject: [PATCH 12/80] Add verification for identity update requests and
refactor how verusid api functions are included in the api structure.
---
routes/api.js | 4 --
.../identity/verifyIdentityUpdateRequest.js | 44 +++++++++++++++++++
routes/api/native/verusid/verusid.js | 12 +++++
3 files changed, 56 insertions(+), 4 deletions(-)
create mode 100644 routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
diff --git a/routes/api.js b/routes/api.js
index 058d8ffb..9775134d 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -163,10 +163,6 @@ api = require('./api/native/coinSupply.js')(api);
api = require('./api/native/blockSubsidy.js')(api);
api = require('./api/native/shieldcoinbase.js')(api);
api = require('./api/native/verusid/verusid.js')(api);
-api = require('./api/native/verusid/login/verifyRequest.js')(api);
-api = require('./api/native/verusid/login/signResponse.js')(api);
-api = require('./api/native/verusid/provision/signIdProvisioningRequest.js')(api);
-api = require('./api/native/verusid/provision/verifyIdProvisioningResponse.js')(api);
api = require('./api/native/credentials/getCredentials.js')(api);
api = require('./api/native/makeoffer')(api);
api = require('./api/native/getoffers')(api);
diff --git a/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js b/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
new file mode 100644
index 00000000..c34b4653
--- /dev/null
+++ b/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
@@ -0,0 +1,44 @@
+const { IdentityUpdateRequest, IDENTITY_UPDATE_REQUEST_VDXF_KEY } = require("verus-typescript-primitives")
+
+module.exports = (api) => {
+ /**
+ * Verifies an identity update request
+ * @param {IdentityUpdateRequest} Request
+ */
+ api.native.verusid.identity.verify_identity_update_request = async (coin, request) => {
+ const identityUpdateRequest = IdentityUpdateRequest.fromJson(request);
+
+ const verified = await api.native.verify_hash(
+ coin,
+ identityUpdateRequest.signingid.toAddress(),
+ identityUpdateRequest.details.toSha256().toString('hex'),
+ // The nesting of the signature does not match the expected structure
+ // and is also more nested than in the login consent plugin.
+ identityUpdateRequest.signature.signature.signature.signature
+ );
+
+ return verified ? { verified } : { verified, message: "Failed to verify signature" };
+ };
+
+ api.setPost("/native/verusid/identity/verify_identity_update_request", async (req, res, next) => {
+ const { chainTicker, request } = req.body;
+
+ try {
+ res.send(
+ JSON.stringify({
+ msg: "success",
+ result: await api.native.verusid.identity.verify_identity_update_request(chainTicker, request),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: "error",
+ result: e.message,
+ })
+ );
+ }
+ });
+
+ return api;
+};
\ No newline at end of file
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index b49bab87..d04fc124 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -2,6 +2,18 @@ module.exports = (api) => {
api.native.verusid = {}
api.native.verusid.login = {}
api.native.verusid.provision = {}
+ api.native.verusid.identity = {}
+
+ // Identity
+ require('./identity/verifyIdentityUpdateRequest')(api);
+
+ // Login
+ require('./login/verifyRequest')(api);
+ require('./login/signResponse')(api);
+
+ // Provisioning
+ require('./provision/signIdProvisioningRequest')(api);
+ require('./provision/verifyIdProvisioningResponse')(api);
return api;
};
From f756e2aebc684f67174c630aab1a91aab5ea62d7 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 24 Jul 2025 13:37:36 -0700
Subject: [PATCH 13/80] Update the verification of the identity update request
to match a change made in the consent client.
---
.../native/verusid/identity/verifyIdentityUpdateRequest.js | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js b/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
index c34b4653..27e4afa1 100644
--- a/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
+++ b/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
@@ -12,9 +12,8 @@ module.exports = (api) => {
coin,
identityUpdateRequest.signingid.toAddress(),
identityUpdateRequest.details.toSha256().toString('hex'),
- // The nesting of the signature does not match the expected structure
- // and is also more nested than in the login consent plugin.
- identityUpdateRequest.signature.signature.signature.signature
+ // The nesting of the signature does not match the expected structure.
+ identityUpdateRequest.signature.signature.signature
);
return verified ? { verified } : { verified, message: "Failed to verify signature" };
From ae4816a7a5fa39238c0bd7b51c78e852e0cb82c7 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 28 Jul 2025 16:41:11 -0700
Subject: [PATCH 14/80] Add processing of the identity update request and
running update identity using its contents.
---
routes/api.js | 1 +
.../api/native/credentials/getCredentials.js | 50 +++++------
routes/api/native/updateIdentity.js | 83 +++++++++++++++++++
.../identity/executeIdentityUpdateRequest.js | 77 +++++++++++++++++
routes/api/native/verusid/verusid.js | 1 +
.../utils/credentials/encryptCredentials.js | 65 +++++++++++++++
6 files changed, 253 insertions(+), 24 deletions(-)
create mode 100644 routes/api/native/updateIdentity.js
create mode 100644 routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
create mode 100644 routes/api/utils/credentials/encryptCredentials.js
diff --git a/routes/api.js b/routes/api.js
index 9775134d..def4fb68 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -148,6 +148,7 @@ api = require('./api/native/idRegistration.js')(api);
api = require('./api/native/idRevocation.js')(api);
api = require('./api/native/idUpdate.js')(api);
api = require('./api/native/idInformation.js')(api);
+api = require('./api/native/updateIdentity.js')(api);
api = require('./api/native/getCurrencies.js')(api);
api = require('./api/native/getCurrency.js')(api);
api = require('./api/native/estimateSendcurrencyFee.js')(api);
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 30ff0e88..fc93439b 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -15,7 +15,7 @@ module.exports = (api) => {
coin,
address
) => {
- // Get the z-address and contentmultimap from the address
+ // Get the z-address and contentmultimap from the address.
const identity = await api.native.get_identity_content(coin, address);
if (!identity || !identity.identity) {
@@ -57,37 +57,40 @@ module.exports = (api) => {
const credentialKey = credentialKeyResult.vdxfid;
- // Check if the identity has credentials in its content multimap.
if (!identity.identity.contentmultimap || !identity.identity.contentmultimap[credentialKey]) {
- return []; // No credentials found.
+ return [];
}
const credentialEntries = identity.identity.contentmultimap[credentialKey];
const credentials = [];
for (const entry of credentialEntries) {
- if (entry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid]) {
- const dataDescriptor = entry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid];
-
- // Decrypt the data descriptor using the viewing key.
- try {
- const decryptedData = await api.native.decrypt_data(
- coin,
- {
- datadescriptor: dataDescriptor,
- evk: viewingKey
- }
- );
+ // Convert single univalues to an array to make the processing consistent.
+ const entriesToProcess = Array.isArray(entry) ? entry : [entry];
+
+ for (const singleEntry of entriesToProcess) {
+ if (singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid]) {
+ const dataDescriptor = singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid];
- // The data descriptor is in a list.
- if (decryptedData && Array.isArray(decryptedData)) {
- const credObj = decryptedData[0];
- const cred = parseCredential(credObj);
- credentials.push(cred);
+ try {
+ const decryptedData = await api.native.decrypt_data(
+ coin,
+ {
+ datadescriptor: dataDescriptor,
+ evk: viewingKey
+ }
+ );
+
+ // The data descriptor is in a list.
+ if (decryptedData && Array.isArray(decryptedData)) {
+ const credObj = decryptedData[0];
+ const cred = parseCredential(credObj);
+ credentials.push(cred);
+ }
+ } catch (err) {
+ console.error(`Failed to decrypt credential: ${err.message}`);
+ // Decrypt the other credentials even if one fails.
}
- } catch (err) {
- console.error(`Failed to decrypt credential: ${err.message}`);
- // Decrypt the other credentials even if one fails.
}
}
}
@@ -139,7 +142,6 @@ module.exports = (api) => {
credentialsMap[mainScope] = [];
}
- // Using a set to track duplicates for efficient lookup.
if (!seenCredentials[mainScope]) {
seenCredentials[mainScope] = new Set();
}
diff --git a/routes/api/native/updateIdentity.js b/routes/api/native/updateIdentity.js
new file mode 100644
index 00000000..078ab1bc
--- /dev/null
+++ b/routes/api/native/updateIdentity.js
@@ -0,0 +1,83 @@
+module.exports = (api) => {
+ /**
+ * Updates an identity using the `jsonidentity` and optional parameters.
+ *
+ * @param {String} coin The chainTicker of the coin to make the call on
+ * @param {String} jsonidentity The new definition of the identity
+ * @param {Boolean} [returntx] If true, the transaction is signed by this wallet and returned
+ * @param {Boolean} [tokenupdate] If true and a tokenized ID control token exists, uses the token to perform the update
+ * @param {Number} [feeoffer] The non-standard fee amount to pay for the transaction
+ * @param {Number} [sourceoffunds] The transparent or private address to source all funds for fees to preserve privacy of the identity
+ */
+ api.native.update_identity = (
+ coin,
+ jsonidentity,
+ returntx = false,
+ tokenupdate = false,
+ feeoffer = undefined,
+ sourceoffunds = undefined
+ ) => {
+
+ const params = [
+ jsonidentity,
+ returntx,
+ tokenupdate,
+ ...(feeoffer !== undefined ? [feeoffer] : []),
+ ...(sourceoffunds !== undefined ? [sourceoffunds] : [])
+ ];
+
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(
+ coin,
+ "updateidentity",
+ params
+ )
+ .then(resultObj => {
+ resolve(resultObj)
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ };
+
+ api.setPost('/native/update_identity', (req, res, next) => {
+ const {
+ coin,
+ jsonidentity,
+ returntx,
+ tokenupdate,
+ feeoffer,
+ sourceoffunds
+ } = req.body;
+
+ api.native
+ .update_identity(
+ coin,
+ jsonidentity,
+ returntx,
+ tokenupdate,
+ feeoffer,
+ sourceoffunds
+ )
+ .then(resultObj => {
+ const retObj = {
+ msg: "success",
+ result: resultObj
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: "error",
+ result: error.message
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
+ });
+
+ return api;
+};
\ No newline at end of file
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
new file mode 100644
index 00000000..90c231e2
--- /dev/null
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
@@ -0,0 +1,77 @@
+const { IdentityUpdateRequest } = require("verus-typescript-primitives")
+const { encryptCredentialsInContentMultiMap } = require("../../../utils/credentials/encryptCredentials")
+
+module.exports = (api) => {
+ api.native.verusid.identity.execute_identity_update_request = async (coin, request) => {
+ const identityUpdateRequest = IdentityUpdateRequest.fromJson(request);
+
+ // Replace any values that need to be encrypted before updating the identity.
+ if (!identityUpdateRequest.details.identity) {
+ throw new Error("IdentityUpdateRequest does not contain an identity.");
+ }
+
+ const address = identityUpdateRequest.details.identity.name;
+ const identity = await api.native.get_identity(coin, identityUpdateRequest.details.identity.name);
+ const zaddress = identity.identity.privateaddress;
+
+ if (!zaddress) {
+ throw new Error(`No z-address found for identity ${address}`);
+ }
+
+ // Generate the viewing key and encryption address to encrypt the credentials.
+ const encryptionAddressInfo = await api.native.z_get_encryption_address(
+ coin,
+ {
+ address: zaddress,
+ fromid: address,
+ toid: address
+ }
+ );
+
+ if (!encryptionAddressInfo || !encryptionAddressInfo.extendedviewingkey || !encryptionAddressInfo.address) {
+ throw new Error(`Failed to get the personal encryption address for ${address}`);
+ }
+
+ const contentmultimap = identityUpdateRequest.details.identity.content_multimap;
+
+ if (contentmultimap) {
+ await encryptCredentialsInContentMultiMap(
+ api,
+ coin,
+ address,
+ contentmultimap,
+ encryptionAddressInfo.extendedviewingkey,
+ encryptionAddressInfo.address
+ );
+ }
+
+ const txid = await api.native.update_identity(
+ coin,
+ identityUpdateRequest.details.toCLIJson()
+ );
+
+ return { txid: txid };
+ };
+
+ api.setPost("/native/verusid/identity/execute_identity_update_request", async (req, res, next) => {
+ const { chainTicker, request } = req.body;
+
+ try {
+ res.send(
+ JSON.stringify({
+ msg: "success",
+ result: await api.native.verusid.identity.execute_identity_update_request(chainTicker, request),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: "error",
+ result: e.message,
+ })
+ );
+ }
+ });
+
+ return api;
+};
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index d04fc124..68969281 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -6,6 +6,7 @@ module.exports = (api) => {
// Identity
require('./identity/verifyIdentityUpdateRequest')(api);
+ require('./identity/executeIdentityUpdateRequest')(api);
// Login
require('./login/verifyRequest')(api);
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
new file mode 100644
index 00000000..9500171d
--- /dev/null
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -0,0 +1,65 @@
+const {
+ IDENTITY_CREDENTIALS,
+ DATA_TYPE_OBJECT_CREDENTIAL,
+ DataDescriptor,
+ DATA_TYPE_OBJECT_DATADESCRIPTOR
+} = require('verus-typescript-primitives');
+
+const encryptCredentialsInContentMultiMap = async (
+ api,
+ coin,
+ address,
+ contentmultimap,
+ viewingKey,
+ encryptionAddress
+) => {
+ for (const [key, valueArray] of contentmultimap.kv_content.entries()) {
+ if (key === IDENTITY_CREDENTIALS.vdxfid) {
+ console.log("Found IDENTITY_CREDENTIALS key:", key);
+
+ for (let i = 0; i < valueArray.length; i++) {
+ const vdxfUniValue = valueArray[i];
+ for (const valueObj of vdxfUniValue.values) {
+ // Each valueObj contains exactly one key-value pair.
+ const valueKey = Object.keys(valueObj)[0];
+
+ if (valueKey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
+ // Replace the credential with the encrypted data descriptor.
+ const vdxfUniType = valueObj[valueKey];
+
+ const signdataResult = await api.native.sign_data(coin,
+ {
+ "address": address,
+ "vdxfdata": {[valueKey]: vdxfUniType.toJson()},
+ "encrypttoaddress": encryptionAddress
+ }
+ );
+
+ const dataDescriptor = DataDescriptor.fromJson(signdataResult.mmrdescriptor_encrypted.datadescriptors[0]);
+ delete valueObj[valueKey];
+ valueObj[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid] = dataDescriptor;
+ }
+ }
+ }
+ // Replace the credentials key with an obfuscated key.
+ const credentialKeyResult = await api.native.get_vdxf_id(
+ coin,
+ "vrsc::identity.credentials",
+ { vdxfkey: viewingKey }
+ );
+
+ if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
+ throw new Error("Failed to generate credential key");
+ }
+
+ const credentialKey = credentialKeyResult.vdxfid;
+
+ contentmultimap.kv_content.set(credentialKey, valueArray);
+ contentmultimap.kv_content.delete(IDENTITY_CREDENTIALS.vdxfid);
+ }
+ }
+};
+
+module.exports = {
+ encryptCredentialsInContentMultiMap
+};
From d87345dfd10f562b23a1ce94363c99499df76469 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 28 Jul 2025 21:21:12 -0700
Subject: [PATCH 15/80] Add api for signing of IdentityUpdateResponses.
---
.../identity/signIdentityUpdateResponse.js | 47 +++++++++++++++++++
routes/api/native/verusid/verusid.js | 1 +
2 files changed, 48 insertions(+)
create mode 100644 routes/api/native/verusid/identity/signIdentityUpdateResponse.js
diff --git a/routes/api/native/verusid/identity/signIdentityUpdateResponse.js b/routes/api/native/verusid/identity/signIdentityUpdateResponse.js
new file mode 100644
index 00000000..087ec004
--- /dev/null
+++ b/routes/api/native/verusid/identity/signIdentityUpdateResponse.js
@@ -0,0 +1,47 @@
+const {
+ VerusIDSignature,
+ IdentityUpdateResponse,
+ LOGIN_CONSENT_RESPONSE_SIG_VDXF_KEY,
+} = require("verus-typescript-primitives");
+
+module.exports = (api) => {
+ api.native.verusid.identity.sign_identity_update_response = async (coin, response) => {
+ const identityUpdateResponse = IdentityUpdateResponse.fromJson(response);
+
+ const signdataResult = await api.native.sign_data(coin,
+ {
+ "address": identityUpdateResponse.signingid.toAddress(),
+ "datahash": identityUpdateResponse.details.toSha256().toString("hex")
+ }
+ )
+
+ identityUpdateResponse.signature = new VerusIDSignature(
+ { signature: signdataResult.signature },
+ LOGIN_CONSENT_RESPONSE_SIG_VDXF_KEY
+ );
+
+ return { response: identityUpdateResponse.toJson()};
+ };
+
+ api.setPost("/native/verusid/identity/sign_identity_update_response", async (req, res, next) => {
+ const { chainTicker, response } = req.body;
+
+ try {
+ res.send(
+ JSON.stringify({
+ msg: "success",
+ result: await api.native.verusid.identity.sign_identity_update_response(chainTicker, response),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: "error",
+ result: e.message,
+ })
+ );
+ }
+ });
+
+ return api;
+};
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index 68969281..b893cc5b 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -7,6 +7,7 @@ module.exports = (api) => {
// Identity
require('./identity/verifyIdentityUpdateRequest')(api);
require('./identity/executeIdentityUpdateRequest')(api);
+ require('./identity/signIdentityUpdateResponse')(api);
// Login
require('./login/verifyRequest')(api);
From b5f24ba272291e3d415a06a9a97faadd0121bb61 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 30 Jul 2025 19:15:02 -0700
Subject: [PATCH 16/80] Change handling of the deeplink responses to accept the
newer way to indicate whether to redirect or send a POST request.
---
routes/api/plugin/builtin/loginconsentui.js | 93 +++++++++++++------
.../utils/credentials/encryptCredentials.js | 2 -
routes/deeplink/openurlhandler.js | 2 -
yarn.lock | 2 +-
4 files changed, 67 insertions(+), 32 deletions(-)
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index d80373d7..493f961d 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -4,6 +4,8 @@ const {
LOGIN_CONSENT_WEBHOOK_VDXF_KEY,
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
+ IDENTITY_UPDATE_RESPONSE_VDXF_KEY,
+ ResponseUri,
} = require("verus-typescript-primitives");
const { pushMessage } = require('../../../ipc/ipc');
const { ReservedPluginTypes } = require('../../utils/plugin/builtin');
@@ -14,36 +16,68 @@ const base64url = require('base64url');
module.exports = (api) => {
api.loginConsentUi = {}
- api.loginConsentUi.handle_redirect = (response, redirectinfo) => {
- const { vdxfkey, uri } = redirectinfo
+ api.loginConsentUi.handle_redirect = (responseKey, response, redirectinfo) => {
+ const { type, uri } = redirectinfo;
- const handlers = {
- [LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: async () => {
- return await axios.post(
+ let processedType = type;
+
+ // Type can either be a string vdxfkey or a BN converted into a number.
+ const usesResponseUri = responseKey === IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid;
+ if (usesResponseUri) {
+ const responseUri = ResponseUri.fromJson(redirectinfo);
+ processedType = responseUri.type;
+ }
+
+ const post = async () => {
+ return await axios.post(
uri,
response
- );
- },
- [LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: () => {
- const url = new URL(uri)
-
- // Prevent opening any urls that don't go to the browser.
- if (!['https:', 'http:'].includes(url.protocol)) {
- return null;
- }
-
- const res = new LoginConsentResponse(response)
- url.searchParams.set(
- LOGIN_CONSENT_RESPONSE_VDXF_KEY.vdxfid,
- base64url(res.toBuffer())
- );
-
- shell.openExternal(url.toString())
- return null
+ );
+ };
+
+ const redirect = async () => {
+ const url = new URL(uri);
+
+ // Prevent opening any urls that don't go to the browser for security reasons.
+ if (!['https:', 'http:'].includes(url.protocol)) {
+ return null;
}
- }
- return handlers[vdxfkey] == null ? null : handlers[vdxfkey]();
+ let res;
+
+ switch (responseKey) {
+ case LOGIN_CONSENT_RESPONSE_VDXF_KEY.vdxfid:
+ res = new LoginConsentResponse(response)
+ break;
+
+ case IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid:
+ // Always convert from JSON when handling Identity Update Responses
+ // since they need to be sent as JSON from the plugin to avoid
+ // issues with the response being malformed.
+ res = IdentityUpdateResponse.fromJson(response);
+ break;
+
+ default:
+ throw new Error(`Unsupported response key for redirecting: ${responseKey}`);
+ }
+
+ url.searchParams.set(
+ responseKey,
+ base64url(res.toBuffer())
+ );
+
+ shell.openExternal(url.toString());
+ return null;
+ };
+
+ const handlers = {
+ [LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: post,
+ [LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: redirect,
+ [ResponseUri.TYPE_POST]: post,
+ [ResponseUri.TYPE_REDIRECT]: redirect,
+ };
+
+ return handlers[processedType] == null ? null : handlers[processedType]();
}
api.loginConsentUi.deeplink = async (
@@ -57,8 +91,13 @@ module.exports = (api) => {
true,
(data) => {
try {
- if (data.redirect) api.loginConsentUi.handle_redirect(data.response, data.redirect);
-
+ if (data.redirect) {
+ api.loginConsentUi.handle_redirect(
+ data.responseKey,
+ data.response,
+ data.redirect
+ );
+ }
resolve(data.response);
} catch(e) {
reject(e)
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 9500171d..50c4863a 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -15,8 +15,6 @@ const encryptCredentialsInContentMultiMap = async (
) => {
for (const [key, valueArray] of contentmultimap.kv_content.entries()) {
if (key === IDENTITY_CREDENTIALS.vdxfid) {
- console.log("Found IDENTITY_CREDENTIALS key:", key);
-
for (let i = 0; i < valueArray.length; i++) {
const vdxfUniValue = valueArray[i];
for (const valueObj of vdxfUniValue.values) {
diff --git a/routes/deeplink/openurlhandler.js b/routes/deeplink/openurlhandler.js
index 25140229..0877022e 100644
--- a/routes/deeplink/openurlhandler.js
+++ b/routes/deeplink/openurlhandler.js
@@ -1,6 +1,4 @@
const { dialog } = require('electron')
-const { URL } = require('url');
-const { SUPPORTED_DLS, CALLBACK_HOST } = require('../api/utils/constants/supported_dls');
function openurlhandler(event, urlstring, apihandler) {
try {
diff --git a/yarn.lock b/yarn.lock
index 62fbe353..5df28dff 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class-iur":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#02909300fb884b6274d95a01f0b3473a32e9cb4d"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#9e0608267fde963e945ef6750c0583e202d4bc57"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From 4b3ab0ae9f44af14332b1cfcaf28802f59b47763 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 31 Jul 2025 09:43:07 -0700
Subject: [PATCH 17/80] Create a new work in progress version of the readme
that is tailored towards making it easier for developers to get started.
---
README.md | 116 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 86 insertions(+), 30 deletions(-)
diff --git a/README.md b/README.md
index 454375d0..b8c9f778 100644
--- a/README.md
+++ b/README.md
@@ -1,59 +1,115 @@
-### This is experimental and unfinished software. Use at your own risk! No warranty for any kind of damage!
+# Verus Desktop Wallet
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+The Verus Multicoin Wallet and Ecosystem GUI
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+## Build & Installation
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### Prerequisites
-# Verus Wallet
-The Verus Multicoin Wallet and Ecosystem GUI
+1) [Node.js](https://nodejs.org/en/download/)
+ - **Note:** Node.js 20.x is recommended. Node.js 22 and higher are **not supported**
+2) [Yarn](https://yarnpkg.com/getting-started/install)
+3) [Git](https://git-scm.com/)
-## Build & Installation
+### Getting the Code
-#### Prerequirements:
+Clone the Verus Desktop repository and the GUI submodule:
+```bash
+git clone --recursive --branch master https://github.com/VerusCoin/Verus-Desktop
+```
-1) [Install yarn](https://yarnpkg.com/)
+### Verus Desktop GUI Setup
-2) [Install git](https://git-scm.com/)
+The GUI requires the `NODE_OPTIONS=--openssl-legacy-provider` environment variable.
+**Note:** This variable is only for building the GUI, not for running Verus Desktop. It will cause an error when trying to run Verus Desktop.
-#### Build & Start Verus-Desktop-GUI (frontend)
-```shell
-git clone --recursive https://github.com/VerusCoin/Verus --branch master --single-branch
-cd Verus/gui/Verus-Desktop-GUI/react/
-yarn install
+Open a new terminal window or tab and run:
+```bash
+export NODE_OPTIONS=--openssl-legacy-provider
+cd Verus-Desktop/gui/Verus-Desktop-GUI/react/
+yarn install
+yarn build
```
-Leave the above process running and use a new terminal windows/tab when proceeding with the below steps.
-Now please create a directory called `bin` inside `assets/` and afterwards copy `komodod` and `komodo-cli` to a new subfolder named after the operating system you are building Agama for: `linux64`, `osx` or `win64`. Inside this subfolder, create another directory called `verusd`
-and copy `verusd` and `verus-cli` into it.
+This will build the GUI for later use.
+
+**Continue the next steps in a new terminal window or tab to avoid issues with the environment variable.**
+
+### Verus Desktop Setup
+
+To set up Verus Desktop, you’ll need to add the required binaries and any plugins you wish to use.
+
+#### Verus Daemon
+
+Verus Desktop needs the Verus CLI binaries. You can download them from [https://verus.io/wallet](https://verus.io/wallet).
+
+From the `Verus-Desktop` directory, create the following folder structure for your operating system:
+
+- **Linux**: `assets/bin/linux64/verusd`
+- **macOS**: `assets/bin/osx/verusd`
+- **Windows**: `assets/bin/win64/verusd`
+
+Copy both `verusd` and `verus-cli` into the appropriate folder (e.g. `assets/bin/linux64/verusd/`).
-From within `Verus/` the structure will be `assets/bin/linux64` (for example on linux).
+#### Plugins
+There are two built-in plugins:
-#### Start Verus App (electron)
+- [Verus Login Consent Client](https://github.com/VerusCoin/verus-login-consent-client)
+- [Verus PBaaS Visualizer](https://github.com/VerusCoin/verus-pbaas-visualizer)
+To add these plugins to Verus Desktop
+
+1. Clone them anywhere on your system:
+ ```bash
+ git clone https://github.com/VerusCoin/verus-login-consent-client
+ git clone https://github.com/VerusCoin/verus-pbaas-visualizer
+ ```
+
+2. Generate builds:
+ ```bash
+ yarn install
+ yarn build
+ ```
+ This will generate a `/build` directory inside each plugin project.
+
+3. Create the following folders in your Verus Desktop project:
+ - `Verus-Desktop/assets/plugins/builtin/verus-login-consent-client/`
+ - `Verus-Desktop/assets/plugins/builtin/verus-pbaas-visualizer/`
+
+ Then copy the contents of each plugin's `/build` directory into its corresponding folder.
+
+ For example, copy all the files from `verus-login-consent-client/build/` into `Verus-Desktop/assets/plugins/builtin/verus-login-consent-client/`.
+
+
+The plugins are now ready to use.
+
+### Starting Verus Desktop
+
+From the root directory, run:
```shell
-cd Verus
yarn install
yarn start
```
-To use debug/dev mode please stop the Verus App (electron) and either set `dev: true` and `debug: true` in `~/.verus/config.json` and then restart the app or replace step 3) from above with the start command below:
-
-```shell
-yarn start devmode
-```
-You are ready to dev!
+This will start the application.
+### Bundling & Packaging:
-## Bundling & packaging:
-
+To create a packaged application, run:
```shell
yarn run dist
```
-We refer to the original [electron-builder](https://www.electron.build) website for more detailed information and further documentation.
+
+The packaged application will be built and packaged based on your operating system, and located in the `/dist` directory:
+| Operating System | Output File Type |
+|------------------|------------------|
+| Linux | `.AppImage` |
+| macOS | `.dmg` |
+| Windows | `.exe` |
+
+For more detailed information about the build process, see the original [electron-builder](https://www.electron.build) website.
From 6a5604c44b1b4bbb64e07fb6b4ad4c69182f286f Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 31 Jul 2025 19:36:33 -0700
Subject: [PATCH 18/80] Restructure the readme to include information on the
different development modes and improve the general quality.
---
README.md | 182 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 126 insertions(+), 56 deletions(-)
diff --git a/README.md b/README.md
index b8c9f778..6aa56acd 100644
--- a/README.md
+++ b/README.md
@@ -1,115 +1,185 @@
-# Verus Desktop Wallet
+# Verus Desktop
-The Verus Multicoin Wallet and Ecosystem GUI
+The Verus Multicoin Wallet and Ecosystem desktop application
-## Build & Installation
+## Development Prerequisites
-### Prerequisites
+### Required Software
1) [Node.js](https://nodejs.org/en/download/)
- **Note:** Node.js 20.x is recommended. Node.js 22 and higher are **not supported**
2) [Yarn](https://yarnpkg.com/getting-started/install)
3) [Git](https://git-scm.com/)
+4) [Verus CLI](https://verus.io/wallet) (`verus` and `verusd` binaries)
-### Getting the Code
+### Cloning the Repository and Optional Plugins
Clone the Verus Desktop repository and the GUI submodule:
```bash
-git clone --recursive --branch master https://github.com/VerusCoin/Verus-Desktop
+git clone --recursive https://github.com/VerusCoin/Verus-Desktop
```
-### Verus Desktop GUI Setup
+#### Optional Plugins
-The GUI requires the `NODE_OPTIONS=--openssl-legacy-provider` environment variable.
-
-**Note:** This variable is only for building the GUI, not for running Verus Desktop. It will cause an error when trying to run Verus Desktop.
-
-
-Open a new terminal window or tab and run:
+The [Verus Login Consent Client](https://github.com/VerusCoin/verus-login-consent-client) is needed to handle deeplinks, including login.
```bash
-export NODE_OPTIONS=--openssl-legacy-provider
-cd Verus-Desktop/gui/Verus-Desktop-GUI/react/
-yarn install
-yarn build
+git clone https://github.com/VerusCoin/verus-login-consent-client.git
```
-This will build the GUI for later use.
-
-**Continue the next steps in a new terminal window or tab to avoid issues with the environment variable.**
+The [Verus PBaaS visualizer](https://github.com/VerusCoin/verus-pbaas-visualizer) provides PBaaS network Visualizations in 3d graphs.
+```bash
+git clone https://github.com/VerusCoin/verus-pbaas-visualizer.git
+```
### Verus Desktop Setup
-To set up Verus Desktop, you’ll need to add the required binaries and any plugins you wish to use.
+From the Verus Desktop directory, create the following folder structure for your operating system:
-#### Verus Daemon
+| Operating System | Path |
+|------------------|----------------------------|
+| Linux | `assets/bin/linux64/verusd`|
+| macOS | `assets/bin/osx/verusd` |
+| Windows | `assets/bin/win64/verusd` |
-Verus Desktop needs the Verus CLI binaries. You can download them from [https://verus.io/wallet](https://verus.io/wallet).
+Copy both `verus` and `verusd` binaries into the appropriate folder (e.g. `assets/bin/linux64/verusd/`).
-From the `Verus-Desktop` directory, create the following folder structure for your operating system:
+## Running
-- **Linux**: `assets/bin/linux64/verusd`
-- **macOS**: `assets/bin/osx/verusd`
-- **Windows**: `assets/bin/win64/verusd`
+Verus Desktop can be run without building to allow for easier development or with building to test for production before packaging the app.
-Copy both `verusd` and `verus-cli` into the appropriate folder (e.g. `assets/bin/linux64/verusd/`).
+**Important:** Both the GUI and the PBaaS visualizer require the `NODE_OPTIONS=--openssl-legacy-provider` environment variable. This environment variable will cause an error when trying to run Verus Desktop. Make sure to use a **separate terminal** for the GUI and PBaaS visualizer.
-#### Plugins
+### Development Mode (Without Building)
-There are two built-in plugins:
+#### GUI
-- [Verus Login Consent Client](https://github.com/VerusCoin/verus-login-consent-client)
-- [Verus PBaaS Visualizer](https://github.com/VerusCoin/verus-pbaas-visualizer)
+Open a new terminal in the Verus Desktop directory:
+```bash
+export NODE_OPTIONS=--openssl-legacy-provider
+cd gui/Verus-Desktop-GUI/react/
+yarn install
+```
-To add these plugins to Verus Desktop
+You can run the GUI in two ways.
-1. Clone them anywhere on your system:
+1. Without plugins:
```bash
- git clone https://github.com/VerusCoin/verus-login-consent-client
- git clone https://github.com/VerusCoin/verus-pbaas-visualizer
+ yarn start
```
-2. Generate builds:
+2. With plugins:
```bash
- yarn install
- yarn build
+ yarn start-no-dashboard
```
- This will generate a `/build` directory inside each plugin project.
-3. Create the following folders in your Verus Desktop project:
- - `Verus-Desktop/assets/plugins/builtin/verus-login-consent-client/`
- - `Verus-Desktop/assets/plugins/builtin/verus-pbaas-visualizer/`
+#### Optional: PBaaS visualizer
+
+Open a new terminal, navigate to the PBaaS visualizer directory:
+```bash
+export NODE_OPTIONS=--openssl-legacy-provider
+yarn install
+yarn start
+```
+
+#### Optional: Login Consent Client
+
+Open a new terminal, navigate to the Login Consent Client directory:
+```bash
+yarn install
+yarn start
+```
+
+#### Desktop
+
+With the GUI and any optional plugins running, navigate to the Verus Desktop directory:
+```bash
+yarn install
+yarn start devmode
+```
+
+#### Debugging
- Then copy the contents of each plugin's `/build` directory into its corresponding folder.
+- If you see a blank white window after starting the desktop application, check if the GUI is running.
+- If the GUI or PBaaS visualizer fails to start and you get this error:
+
+ `Error: error:0308010C:digital envelope routines::unsupported`
- For example, copy all the files from `verus-login-consent-client/build/` into `Verus-Desktop/assets/plugins/builtin/verus-login-consent-client/`.
+ This indicates that the required environment variable is not set.
+- If the GUI or PBaaS visualizer fails to start and you get this error:
+ `Error: listen EADDRINUSE: address already in use :::9838`
-The plugins are now ready to use.
+ Then run the GUI with `yarn start-no-dashboard` to avoid dashboard conflicts.
-### Starting Verus Desktop
+- If you get a blank white window after trying to open the PBaaS visualizer, check if the PBaaS visualizer is running.
+- If you get a smaller blank white window after using a deeplink, check if the Login Consent Client is running.
-From the root directory, run:
-```shell
+### Production Mode (With Building)
+
+#### GUI
+
+Open a new terminal in the Verus Desktop directory:
+```bash
+export NODE_OPTIONS=--openssl-legacy-provider
+cd gui/Verus-Desktop-GUI/react/
+yarn build
+```
+
+#### Optional: PBaaS visualizer
+
+Open a new terminal, navigate to the PBaaS visualizer directory:
+```bash
+export NODE_OPTIONS=--openssl-legacy-provider
+yarn install
+yarn build
+```
+
+After building, you will find the plugin files in the `/build` directory. Create the folder `assets/plugins/builtin/verus-pbaas-visualizer/` inside your Verus Desktop directory and copy the build files into it.
+
+#### Optional: Login Consent Client
+
+Open a new terminal, navigate to the Login Consent Client directory:
+```bash
+yarn install
+yarn build
+```
+
+After building, you will find the plugin files in the `/build` directory. Create the folder `assets/plugins/builtin/verus-login-consent-client/` inside your Verus Desktop directory and copy the build files into it.
+
+#### Desktop
+
+With the GUI and any optional plugins built, navigate to the Verus Desktop directory:
+```bash
yarn install
yarn start
```
-This will start the application.
+#### Debugging
+
+- If you see a blank white window after starting the desktop application, the GUI needs to be built.
+- If the GUI or PBaaS visualizer fails to build and you get this error:
+
+ `Error: error:0308010C:digital envelope routines::unsupported`
+
+ This indicates that the required environment variable is not set.
+- If you get a blank white window after trying to open the PBaaS visualizer, the PBaaS visualizer needs to be built.
+- If you get a smaller blank white window after using a deeplink, the Login Consent Client needs to be built.
+
+
+## Packaging
-### Bundling & Packaging:
+Build all dependencies, including the GUI and any optional plugins, before packaging the application. See [Production Mode (With Building)](#production-mode-with-building) for how to build.
-To create a packaged application, run:
+Package the application:
```shell
yarn run dist
```
-The packaged application will be built and packaged based on your operating system, and located in the `/dist` directory:
+The packaged application will be packaged based on your operating system, and located in the `/dist` directory.
| Operating System | Output File Type |
|------------------|------------------|
| Linux | `.AppImage` |
| macOS | `.dmg` |
| Windows | `.exe` |
-For more detailed information about the build process, see the original [electron-builder](https://www.electron.build) website.
-
-
+For more detailed information about the build process, see the original [electron-builder](https://www.electron.build) website.
\ No newline at end of file
From 518a990a742a78a0fc91a90fededa3f6cb373f6b Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 12 Aug 2025 08:57:21 -0700
Subject: [PATCH 19/80] Update the readme with fixes and update a comment about
fetching credentials.
---
README.md | 15 +++++++++------
routes/api/native/credentials/getCredentials.js | 2 +-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 6aa56acd..637d33b3 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ The Verus Multicoin Wallet and Ecosystem desktop application
### Required Software
1) [Node.js](https://nodejs.org/en/download/)
- - **Note:** Node.js 20.x is recommended. Node.js 22 and higher are **not supported**
+ - **Note:** Node.js 20.x is recommended. Node.js 22 and higher are **not supported**.
2) [Yarn](https://yarnpkg.com/getting-started/install)
3) [Git](https://git-scm.com/)
4) [Verus CLI](https://verus.io/wallet) (`verus` and `verusd` binaries)
@@ -21,6 +21,8 @@ git clone --recursive https://github.com/VerusCoin/Verus-Desktop
#### Optional Plugins
+Optional plugins can be cloned into the same directory level as the Verus Desktop folder.
+
The [Verus Login Consent Client](https://github.com/VerusCoin/verus-login-consent-client) is needed to handle deeplinks, including login.
```bash
git clone https://github.com/VerusCoin/verus-login-consent-client.git
@@ -35,11 +37,11 @@ git clone https://github.com/VerusCoin/verus-pbaas-visualizer.git
From the Verus Desktop directory, create the following folder structure for your operating system:
-| Operating System | Path |
-|------------------|----------------------------|
-| Linux | `assets/bin/linux64/verusd`|
-| macOS | `assets/bin/osx/verusd` |
-| Windows | `assets/bin/win64/verusd` |
+| Operating System | Path |
+|------------------|-----------------------------|
+| Linux | `assets/bin/linux64/verusd/`|
+| macOS | `assets/bin/osx/verusd/` |
+| Windows | `assets/bin/win64/verusd/` |
Copy both `verus` and `verusd` binaries into the appropriate folder (e.g. `assets/bin/linux64/verusd/`).
@@ -122,6 +124,7 @@ Open a new terminal in the Verus Desktop directory:
```bash
export NODE_OPTIONS=--openssl-legacy-provider
cd gui/Verus-Desktop-GUI/react/
+yarn install
yarn build
```
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index fc93439b..1d270045 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -44,7 +44,7 @@ module.exports = (api) => {
const viewingKey = keys.extendedviewingkey;
- // Generate the credential key using the viewing key
+ // Generate the credential key using the viewing key.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
"vrsc::identity.credentials",
From c5b2bf25490e50dbf5945828f49cb8b0843f8285 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 15 Aug 2025 19:07:30 -0700
Subject: [PATCH 20/80] Add automatic desktop integration for AppImages on
Linux that works for only the testnet version.
---
main.js | 15 +-
routes/api.js | 1 +
routes/api/utility_apis/deeplinkSetup.js | 166 +++++++++++++++++++++++
3 files changed, 181 insertions(+), 1 deletion(-)
create mode 100644 routes/api/utility_apis/deeplinkSetup.js
diff --git a/main.js b/main.js
index c70860cc..71a9f8e9 100644
--- a/main.js
+++ b/main.js
@@ -565,7 +565,20 @@ if (!hasLock) {
// Deep linking
if (!appConfig.general.main.disableDeeplink) {
- api.log("setting up deeplink", "init");
+ api.log("setting up deeplink", "init");
+ try {
+ api.installLinuxDeeplinkIntegration()
+ .then(() => {
+ api.log("deeplink integration created", "init");
+ })
+ .catch((e) => {
+ api.log("deeplink integration failed", "init");
+ api.log(e, "init");
+ });
+ } catch (e) {
+ api.log("deeplink integration failed", "init");
+ api.log(e, "init");
+ }
setuplink(app);
} else {
api.log("removing deeplink", "init");
diff --git a/routes/api.js b/routes/api.js
index def4fb68..19386659 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -205,6 +205,7 @@ api = require('./api/dlhandler.js')(api);
api = require('./api/utility_apis/csvExport.js')(api);
api = require('./api/utility_apis/pbaas')(api);
api = require('./api/utility_apis/checkUpdates')(api);
+api = require('./api/utility_apis/deeplinkSetup')(api);
api = require('./api/utility_apis/cache')(api);
// kv
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
new file mode 100644
index 00000000..762ef9c8
--- /dev/null
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -0,0 +1,166 @@
+const fs = require('fs-extra');
+const path = require('path');
+const os = require('os');
+const { execFile, exec } = require('child_process');
+const util = require('util');
+const run = util.promisify(exec);
+const runFile = util.promisify(execFile);
+
+// Increase maxBuffer to handle large outputs (e.g., AppImage extraction).
+const MAX_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
+
+function xdgDataHome() {
+ return process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');
+}
+
+async function extractAppImage(appImage, tmpDir) {
+ await runFile(appImage, ['--appimage-extract'], {
+ cwd: tmpDir,
+ maxBuffer: MAX_BUFFER_SIZE
+ });
+ const extractedPath = path.join(tmpDir, 'squashfs-root');
+ return extractedPath;
+}
+
+async function installIcons(squashRoot) {
+ const hicolorBase = path.join(xdgDataHome(), 'icons', 'hicolor');
+ const sourceHicolorBase = path.join(squashRoot, 'usr', 'share', 'icons', 'hicolor');
+
+ // Check if hicolor directory exists in AppImage.
+ if (!(await fs.pathExists(sourceHicolorBase))) {
+ return;
+ }
+
+ let iconsCopied = 0;
+
+ // Copy all available icon sizes from the hicolor structure.
+ const sizeDirs = await fs.readdir(sourceHicolorBase).catch(() => []);
+
+ for (const sizeDir of sizeDirs) {
+ const sourceSizeDir = path.join(sourceHicolorBase, sizeDir, 'apps');
+ const destSizeDir = path.join(hicolorBase, sizeDir, 'apps');
+
+ if (await fs.pathExists(sourceSizeDir)) {
+ const iconFiles = await fs.readdir(sourceSizeDir).catch(() => []);
+ const pngFiles = iconFiles.filter(f => f.toLowerCase().endsWith('.png'));
+
+ if (pngFiles.length > 0) {
+ await fs.mkdirp(destSizeDir);
+
+ for (const pngFile of pngFiles) {
+ const sourceIcon = path.join(sourceSizeDir, pngFile);
+ const destIcon = path.join(destSizeDir, pngFile);
+
+ await fs.copyFile(sourceIcon, destIcon);
+ iconsCopied++;
+ }
+ }
+ }
+ }
+
+ if (iconsCopied > 0) {
+ // Caching is not necessary for the icons to work, but would be ideal.
+ try {
+ await run(`gtk-update-icon-cache -f "${hicolorBase}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
+ }
+}
+
+async function installDesktopFile(squashRoot, appImage) {
+ const appsDir = path.join(xdgDataHome(), 'applications');
+ await fs.mkdirp(appsDir);
+ const desktopFile = path.join(appsDir, 'verus-desktop-testnet.desktop');
+
+ // Find the desktop file in the extracted AppImage.
+ const sourceDesktopFile = path.join(squashRoot, 'verus-desktop-testnet.desktop');
+
+ if (!(await fs.pathExists(sourceDesktopFile))) {
+ throw new Error(`Desktop file not found in AppImage at ${sourceDesktopFile}`);
+ }
+
+ let desktopFileContent = await fs.readFile(sourceDesktopFile, 'utf8');
+
+ // Extract X-AppImage-Version and append to Name in parentheses.
+ const versionMatch = desktopFileContent.match(/^X-AppImage-Version=(.+)$/m);
+ if (versionMatch) {
+ const version = versionMatch[1].trim();
+
+ desktopFileContent = desktopFileContent.replace(
+ /^Name=(.+)$/m,
+ (match, name) => {
+ const trimmedName = name.trim();
+ if (!trimmedName.includes(`(${version})`)) {
+ return `Name=${trimmedName} (${version})`;
+ }
+ return match;
+ }
+ );
+ }
+
+ // Replace AppRun with the actual AppImage path and append --no-sandbox %U
+ // Need to have --no-sandbox for Electron otherwise the deeplinks fail.
+ desktopFileContent = desktopFileContent.replace(
+ /^Exec=.*$/m,
+ `Exec=${appImage} --no-sandbox %U`
+ );
+
+ await fs.writeFile(desktopFile, desktopFileContent, { mode: 0o644 });
+
+ return desktopFileContent;
+}
+
+async function registerDesktopFile(desktopFileName, desktopFileContent) {
+ const appsDir = path.dirname(desktopFileName);
+
+ // Extract MimeType from the provided desktop file.
+ let mimeTypes = [];
+ const mimeTypeMatch = desktopFileContent.match(/^MimeType=(.+)$/m);
+ if (mimeTypeMatch) {
+ mimeTypes = mimeTypeMatch[1].split(';').map(m => m.trim()).filter(m => m.length > 0);
+ }
+
+ // Skip registration if no MIME types found in desktop file
+ if (mimeTypes.length === 0) {
+ return;
+ }
+
+ // Create the desktop integration.
+ await run(`update-desktop-database "${appsDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ for (const mimeType of mimeTypes) {
+ await run(`xdg-mime default "${path.basename(desktopFileName)}" "${mimeType}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ }
+}
+
+module.exports = (api) => {
+ api.installLinuxDeeplinkIntegration = async () => {
+ if (process.platform !== 'linux') return;
+
+ // Skip the integration if desktop file already exists.
+ const appsDir = path.join(xdgDataHome(), 'applications');
+ const desktopFileLocation = path.join(appsDir, 'verus-desktop-testnet.desktop');
+
+ if (await fs.pathExists(desktopFileLocation)) {
+ return;
+ }
+
+ const appImage = process.env.APPIMAGE;
+
+ // Skip it if not running from an AppImage.
+ if (!appImage || !(await fs.pathExists(appImage))) {
+ return;
+ }
+
+ const tmpBase = await fs.mkdtemp(path.join(os.tmpdir(), 'verus-appimage-'));
+
+ try {
+ const squashRoot = await extractAppImage(appImage, tmpBase);
+ await installIcons(squashRoot);
+ const desktopFileContent = await installDesktopFile(squashRoot, appImage);
+ await registerDesktopFile(desktopFileLocation, desktopFileContent);
+ } finally {
+ await fs.remove(tmpBase);
+ }
+ }
+
+ return api;
+};
From 4d0011f13218896c1b737a267c6fa60e93959881 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 15 Aug 2025 19:24:09 -0700
Subject: [PATCH 21/80] Add a note about deeplink integration to the readme.
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 637d33b3..19f9d9f8 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,10 @@ From the Verus Desktop directory, create the following folder structure for your
Copy both `verus` and `verusd` binaries into the appropriate folder (e.g. `assets/bin/linux64/verusd/`).
+#### Deeplinks
+
+Deeplinks require running a production build at least once. After that, you can run Verus Desktop in any mode and still have the deeplinks functional.
+
## Running
Verus Desktop can be run without building to allow for easier development or with building to test for production before packaging the app.
From 51f95898b329460376973f4afab54421a266e62f Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 10 Sep 2025 15:35:01 -0700
Subject: [PATCH 22/80] Generalize the processing of the desktop file to also
work for the regular version of the desktop wallet and improve when the
desktop integration is run.
---
routes/api/utility_apis/deeplinkSetup.js | 32 +++++++++++++-----------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index 762ef9c8..fac91165 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -66,13 +66,22 @@ async function installIcons(squashRoot) {
}
}
+// Moves the desktop file from the extracted AppImage, modifies the execution so
+// that it works for electron, and returns the contents and path of the file.
async function installDesktopFile(squashRoot, appImage) {
const appsDir = path.join(xdgDataHome(), 'applications');
await fs.mkdirp(appsDir);
- const desktopFile = path.join(appsDir, 'verus-desktop-testnet.desktop');
-
- // Find the desktop file in the extracted AppImage.
- const sourceDesktopFile = path.join(squashRoot, 'verus-desktop-testnet.desktop');
+
+ // Find the desktop file in the extracted AppImage dynamically.
+ const files = await fs.readdir(squashRoot);
+ const desktopFileName = files.find(file => file.endsWith('.desktop'));
+
+ if (!desktopFileName) {
+ throw new Error('No desktop file found in AppImage');
+ }
+
+ const desktopFile = path.join(appsDir, desktopFileName);
+ const sourceDesktopFile = path.join(squashRoot, desktopFileName);
if (!(await fs.pathExists(sourceDesktopFile))) {
throw new Error(`Desktop file not found in AppImage at ${sourceDesktopFile}`);
@@ -106,7 +115,7 @@ async function installDesktopFile(squashRoot, appImage) {
await fs.writeFile(desktopFile, desktopFileContent, { mode: 0o644 });
- return desktopFileContent;
+ return { content: desktopFileContent, path: desktopFile };
}
async function registerDesktopFile(desktopFileName, desktopFileContent) {
@@ -135,13 +144,8 @@ module.exports = (api) => {
api.installLinuxDeeplinkIntegration = async () => {
if (process.platform !== 'linux') return;
- // Skip the integration if desktop file already exists.
- const appsDir = path.join(xdgDataHome(), 'applications');
- const desktopFileLocation = path.join(appsDir, 'verus-desktop-testnet.desktop');
-
- if (await fs.pathExists(desktopFileLocation)) {
- return;
- }
+ // Always run the integration so that if the appimage moves or a new version is being used,
+ // the user will always have a working integration.
const appImage = process.env.APPIMAGE;
@@ -155,8 +159,8 @@ module.exports = (api) => {
try {
const squashRoot = await extractAppImage(appImage, tmpBase);
await installIcons(squashRoot);
- const desktopFileContent = await installDesktopFile(squashRoot, appImage);
- await registerDesktopFile(desktopFileLocation, desktopFileContent);
+ const desktopFileResult = await installDesktopFile(squashRoot, appImage);
+ await registerDesktopFile(desktopFileResult.path, desktopFileResult.content);
} finally {
await fs.remove(tmpBase);
}
From 0451b9b0ea3545f1e432e784b2e69303c4b695f3 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 10 Sep 2025 19:28:12 -0700
Subject: [PATCH 23/80] Add documentation on the credential encryption and
decryption process used in the wallet.
---
docs/Credentials.md | 252 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 252 insertions(+)
create mode 100644 docs/Credentials.md
diff --git a/docs/Credentials.md b/docs/Credentials.md
new file mode 100644
index 00000000..1aecf885
--- /dev/null
+++ b/docs/Credentials.md
@@ -0,0 +1,252 @@
+# Credentials
+
+Credentials contain sensitive information, so they must be encrypted at rest. The wallet handles the encryption and decryption of credentials for the user.
+
+The encryption and decryption processes are works in progress.
+
+## Notes
+
+1. For encrypting and storing data to be accessed only by a specific identity (e.g., yourself), the `fromid` and `toid` both must match that identity.
+2. For the encryption and decryption processes, an identity with a z-address is needed.
+
+## Encryption Process
+
+The steps for the encryption process are as follows.
+
+1. Run `z_getencryptionaddress` with
+ - `address`: the identity's z-address
+ - `fromid`: the identity's address (e.g., `CredentialTester@`)
+ - `toid`: the same identity's address
+
+ The result should contain the z-address that will be used to encrypt the credential and its corresponding extended viewing key.
+
+ Example:
+
+ ```json
+ z_getencryptionaddress '{
+ "address": "zs1ztll53sh8dst9utln6vl6vn7fv2zdayxhk58rd7casqhemuh5fwymv8q86g9cf670g3wsge573w",
+ "fromid": "CredentialTester@",
+ "toid": "CredentialTester@"
+ }'
+ ```
+ ```json
+ {
+ "address": "zs1x49g3lkt93udlnnc8y5k7p5n0vlvqa2r2rsmsj2629hfvwljpn39mltsxy0fktp5ue46wlw3mlc",
+ "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"
+ }
+ ```
+
+
+
+2. Encrypt the credential using `signdata` with
+ - `address`: the same identity's address
+ - `vdxfdata`: the credential
+ - `encrypttoaddress`: the z-address obtained in Step 1
+
+ From the result, get the data descriptor of the encrypted credential, which is in the `mmrdescriptor_encrypted` section of the JSON result.
+
+ Example:
+
+ ```json
+ signdata '{
+ "address":"CredentialTester@",
+ "vdxfdata": {
+ "vrsc::data.type.object.credential":{
+ "version": 1,
+ "credentialkey": "iHh1FFVvcNb2mcBudD11umfKJXHbBbH6Sj",
+ "credential": ["username", "password"],
+ "scopes": ["App1@"]
+ }
+ },
+ "encrypttoaddress": "zs1x49g3lkt93udlnnc8y5k7p5n0vlvqa2r2rsmsj2629hfvwljpn39mltsxy0fktp5ue46wlw3mlc"
+ }'
+ ```
+ ```json
+ {
+ "version": 1,
+ "flags": 5,
+ "objectdata": "fb9a69e5019a6a790b94cd7c5c1cef65126029e8709c3efcbd302fff69bf3488a4fbde512fc4117cc989dd8d3f98d3650e60e90eb02add89fb3c887d225eeee62723b4f71d192cb0ebe17bcc0680501b86201a4448fd562368d62efac7a7778e943fe93841acf091f02210b24cf988449241782962b65731e7939a9adaa8fd870100dd598ea6a4c22bbd620e07b996e53e521f38849210f9f2d916599346fe1676484e461a61ae9c7437e111",
+ "epk": "27d8a2e582b6f30bac693154d6d18a4ee333fc93ae8361813b4c6c7c6ed1f90b"
+ }
+ ```
+
+
+
+3. Hash `vrsc::identity.credentials` with the extended viewing key using `getvdxfid` with
+ - `vrsc::identity.credentials`
+ - `vdxfkey`: the extended viewing key
+
+ Get the `vdxfid` in the result for the next step.
+
+ Example:
+
+ ```json
+ getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
+ ```
+ ```json
+ {
+ "vdxfid": "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8",
+ "indexid": "xFaSmqHz5nvEaT2Ypjjf6uqohFfVGyMb1c",
+ "hash160result": "86a4deebbaecab2da5c8547b2fda278c8d40c64f",
+ "qualifiedname": {
+ "namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
+ "name": "vrsc::identity.credentials"
+ },
+ "bounddata": {
+ "vdxfkey": "iMArFRJ3bZPg65ttXJdxGub4VbPWYRqBwW"
+ }
+ }
+ ```
+
+
+4. Add the encrypted credential to the contentmultimap using `updateidentity` with
+ - `name`: the identity's address
+ - `contentmultimap`: the hashed `vrsc::identity.credentials` key with the data descriptor of the encrypted credential
+
+ Example:
+
+ ```json
+ updateidentity '{
+ "name": "CredentialTester@",
+ "contentmultimap": {
+ "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8": [
+ {
+ "vrsc::data.type.object.datadescriptor": {
+ "version": 1,
+ "flags": 5,
+ "objectdata": "fb9a69e5019a6a790b94cd7c5c1cef65126029e8709c3efcbd302fff69bf3488a4fbde512fc4117cc989dd8d3f98d3650e60e90eb02add89fb3c887d225eeee62723b4f71d192cb0ebe17bcc0680501b86201a4448fd562368d62efac7a7778e943fe93841acf091f02210b24cf988449241782962b65731e7939a9adaa8fd870100dd598ea6a4c22bbd620e07b996e53e521f38849210f9f2d916599346fe1676484e461a61ae9c7437e111",
+ "epk": "27d8a2e582b6f30bac693154d6d18a4ee333fc93ae8361813b4c6c7c6ed1f90b"
+ }
+ }
+ ]
+ }
+ }'
+ ```
+
+
+
+## Decryption Process
+
+The steps for the decryption process are as follows.
+
+1. Run `z_getencryptionaddress` with
+ - `address`: the identity's z-address
+ - `fromid`: the identity's address (e.g., `CredentialTester@`)
+ - `toid`: the same identity's address
+
+ This is the same as Step 1 from the [*Encryption Process*](#encryption-process).
+
+ The result should contain a z-address and its corresponding extended viewing key, which will be used to find and decrypt the credential.
+
+ Example:
+
+ ```json
+ z_getencryptionaddress '{
+ "address": "zs1ztll53sh8dst9utln6vl6vn7fv2zdayxhk58rd7casqhemuh5fwymv8q86g9cf670g3wsge573w",
+ "fromid": "CredentialTester@",
+ "toid": "CredentialTester@"
+ }'
+ ```
+ ```json
+ {
+ "address": "zs1x49g3lkt93udlnnc8y5k7p5n0vlvqa2r2rsmsj2629hfvwljpn39mltsxy0fktp5ue46wlw3mlc",
+ "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"
+ }
+ ```
+
+
+
+2. Hash `vrsc::identity.credentials` with the extended viewing key using `getvdxfid` with
+ - `vrsc::identity.credentials`
+ - `vdxfkey`: the extended viewing key
+
+ This is the same as Step 3 from the [*Encryption Process*](#encryption-process).
+
+ Get the `vdxfid` in the result for Step 4.
+
+ Example:
+
+ ```json
+ getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
+ ```
+ ```json
+ {
+ "vdxfid": "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8",
+ "indexid": "xFaSmqHz5nvEaT2Ypjjf6uqohFfVGyMb1c",
+ "hash160result": "86a4deebbaecab2da5c8547b2fda278c8d40c64f",
+ "qualifiedname": {
+ "namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
+ "name": "vrsc::identity.credentials"
+ },
+ "bounddata": {
+ "vdxfkey": "iMArFRJ3bZPg65ttXJdxGub4VbPWYRqBwW"
+ }
+ }
+ ```
+
+
+3. Get the `contentmultimap` of the identity using `getidentitycontent` with
+ - the identity's address
+
+ This doesn't currently use a `vdxfkey` for selective searching within the `contentmultimap`, but it should in the future.
+
+ The `contentmultimap` is within the `identity` part of the JSON result.
+
+ Example:
+
+ ```json
+ getidentitycontent CredentialTester@
+ ```
+ ```json
+ "contentmultimap": {
+ "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8": [
+ {
+ "i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQv": {
+ "version": 1,
+ "flags": 5,
+ "objectdata": "fb9a69e5019a6a790b94cd7c5c1cef65126029e8709c3efcbd302fff69bf3488a4fbde512fc4117cc989dd8d3f98d3650e60e90eb02add89fb3c887d225eeee62723b4f71d192cb0ebe17bcc0680501b86201a4448fd562368d62efac7a7778e943fe93841acf091f02210b24cf988449241782962b65731e7939a9adaa8fd870100dd598ea6a4c22bbd620e07b996e53e521f38849210f9f2d916599346fe1676484e461a61ae9c7437e111",
+ "epk": "27d8a2e582b6f30bac693154d6d18a4ee333fc93ae8361813b4c6c7c6ed1f90b"
+ }
+ }
+ ]
+ }
+ ```
+
+
+
+4. Using the hashed key created in Step 2, find the data descriptor of the encrypted credential, and decrypt it using `decryptdata` with
+ - `datadescriptor`: the data descriptor of the encrypted credential
+ - `evk`: the extended viewing key obtained in Step 1
+
+ Example:
+
+ ```json
+ decryptdata '{
+ "datadescriptor": {
+ "version": 1,
+ "flags": 5,
+ "objectdata": "fb9a69e5019a6a790b94cd7c5c1cef65126029e8709c3efcbd302fff69bf3488a4fbde512fc4117cc989dd8d3f98d3650e60e90eb02add89fb3c887d225eeee62723b4f71d192cb0ebe17bcc0680501b86201a4448fd562368d62efac7a7778e943fe93841acf091f02210b24cf988449241782962b65731e7939a9adaa8fd870100dd598ea6a4c22bbd620e07b996e53e521f38849210f9f2d916599346fe1676484e461a61ae9c7437e111",
+ "epk": "27d8a2e582b6f30bac693154d6d18a4ee333fc93ae8361813b4c6c7c6ed1f90b"
+ },
+ "evk":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"
+ }'
+ ```
+ ```json
+ [
+ {
+ "iDTG49YLqmkHMYRyuQBYgEyTByQwAzqGd6": {
+ "version": 1,
+ "flags": 0,
+ "credentialkey": "iHh1FFVvcNb2mcBudD11umfKJXHbBbH6Sj",
+ "credential": [
+ "cjkdfasjak@tlmail.com",
+ "!@23ji2390uodsf"
+ ],
+ "scopes": [
+ "App1@"
+ ]
+ }
+ }
+ ]
+ ```
+
\ No newline at end of file
From ee174d4a2816b64d5d07ae0bb20cc41a06ab7916 Mon Sep 17 00:00:00 2001
From: Mark Stoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 10 Sep 2025 19:32:02 -0700
Subject: [PATCH 24/80] Fix syntax highlighting in Credentials document.
---
docs/Credentials.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/docs/Credentials.md b/docs/Credentials.md
index 1aecf885..e4226cbd 100644
--- a/docs/Credentials.md
+++ b/docs/Credentials.md
@@ -22,7 +22,7 @@ The steps for the encryption process are as follows.
Example:
- ```json
+ ```bash
z_getencryptionaddress '{
"address": "zs1ztll53sh8dst9utln6vl6vn7fv2zdayxhk58rd7casqhemuh5fwymv8q86g9cf670g3wsge573w",
"fromid": "CredentialTester@",
@@ -47,7 +47,7 @@ The steps for the encryption process are as follows.
Example:
- ```json
+ ```bash
signdata '{
"address":"CredentialTester@",
"vdxfdata": {
@@ -80,7 +80,7 @@ The steps for the encryption process are as follows.
Example:
- ```json
+ ```bash
getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
```
```json
@@ -105,7 +105,7 @@ The steps for the encryption process are as follows.
Example:
- ```json
+ ```bash
updateidentity '{
"name": "CredentialTester@",
"contentmultimap": {
@@ -140,7 +140,7 @@ The steps for the decryption process are as follows.
Example:
- ```json
+ ```bash
z_getencryptionaddress '{
"address": "zs1ztll53sh8dst9utln6vl6vn7fv2zdayxhk58rd7casqhemuh5fwymv8q86g9cf670g3wsge573w",
"fromid": "CredentialTester@",
@@ -166,7 +166,7 @@ The steps for the decryption process are as follows.
Example:
- ```json
+ ```bash
getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
```
```json
@@ -194,7 +194,7 @@ The steps for the decryption process are as follows.
Example:
- ```json
+ ```bash
getidentitycontent CredentialTester@
```
```json
@@ -220,7 +220,7 @@ The steps for the decryption process are as follows.
Example:
- ```json
+ ```bash
decryptdata '{
"datadescriptor": {
"version": 1,
@@ -249,4 +249,4 @@ The steps for the decryption process are as follows.
}
]
```
-
\ No newline at end of file
+
From 1bd423bf1c50d4f553207e2f982580723e57a97f Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 16 Sep 2025 08:11:21 -0700
Subject: [PATCH 25/80] Update verus-typescript-primitives and associated
helper libraries to the main versions where possible.
---
package.json | 2 +-
yarn.lock | 20 ++++----------------
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/package.json b/package.json
index e7644d2c..754c1379 100644
--- a/package.json
+++ b/package.json
@@ -80,7 +80,7 @@
"systeminformation": "5.23.8",
"tx-builder": "^0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class-iur",
+ "verus-typescript-primitives": "git+https://github.com/VerusCoin/verus-typescript-primitives.git",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
"verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client",
diff --git a/yarn.lock b/yarn.lock
index 5df28dff..52fcb0cd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1326,7 +1326,7 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-axios@0.25.0, axios@1.13.5, axios@1.7.4:
+axios@0.25.0, axios@1.11.0, axios@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
@@ -7996,18 +7996,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#6103331a5e1ef229ba89cd4965c7170757eadb87"
- dependencies:
- base64url "3.0.1"
- bech32 "2.0.0"
- blake2b "https://github.com/VerusCoin/blake2b"
- bn.js "5.2.3"
- bs58check "2.0.0"
- create-hash "1.2.0"
-
-"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-class-iur":
- version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#9e0608267fde963e945ef6750c0583e202d4bc57"
+ resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#93a1fdea07e81c7d570ad0803685336d4d7ea838"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -8037,10 +8026,9 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client":
version "0.1.0"
- resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client#b558c4d14560eeaa697f84e4d53727214450423d"
+ resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client#a2519d42650e0bd014e73ab0cbc26c2cadd4a672"
dependencies:
- axios "1.13.5"
- blake2b "https://github.com/VerusCoin/blake2b"
+ axios "1.11.0"
verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
wcwidth@^1.0.0:
From 3efc23fbf8575028754de432c2b83ec31a7d4ba5 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 16 Sep 2025 16:44:12 -0700
Subject: [PATCH 26/80] Run additional commands to setup the desktop
integration.
---
routes/api/utility_apis/deeplinkSetup.js | 31 ++++++++++++++++++++----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index fac91165..81613ae4 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -59,10 +59,18 @@ async function installIcons(squashRoot) {
}
if (iconsCopied > 0) {
- // Caching is not necessary for the icons to work, but would be ideal.
- try {
- await run(`gtk-update-icon-cache -f "${hicolorBase}"`, { maxBuffer: MAX_BUFFER_SIZE });
- } catch {}
+ // Update icon caches if possible.
+ const iconCacheCommands = [
+ `gtk-update-icon-cache-3.0 -t "${hicolorBase}"`,
+ `gtk-update-icon-cache -f "${hicolorBase}"`,
+ `update-icon-caches "${path.dirname(hicolorBase)}"`
+ ];
+
+ for (const command of iconCacheCommands) {
+ try {
+ await run(command, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
+ }
}
}
@@ -136,8 +144,21 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
// Create the desktop integration.
await run(`update-desktop-database "${appsDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
for (const mimeType of mimeTypes) {
- await run(`xdg-mime default "${path.basename(desktopFileName)}" "${mimeType}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ try {
+ await run(`xdg-mime default "${path.basename(desktopFileName)}" "${mimeType}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
}
+
+ // Update MIME database.
+ try {
+ const mimeDir = path.join(xdgDataHome(), 'mime');
+ await run(`update-mime-database "${mimeDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
+
+ // Force update desktop menu.
+ try {
+ await run(`xdg-desktop-menu forceupdate`, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
}
module.exports = (api) => {
From 3bbcd938c06fe29fe21a7ee2acd34dee9ca37b56 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 23 Sep 2025 16:51:24 -0700
Subject: [PATCH 27/80] Update the encryption and decryption processes for
credentials to use the ivk, and update the associated documentation.
---
docs/Credentials.md | 52 ++++++++++---------
.../api/native/credentials/getCredentials.js | 11 ++--
.../identity/executeIdentityUpdateRequest.js | 7 ++-
routes/api/native/zgetencryptionaddress.js | 12 ++---
.../utils/credentials/encryptCredentials.js | 6 +--
5 files changed, 47 insertions(+), 41 deletions(-)
diff --git a/docs/Credentials.md b/docs/Credentials.md
index e4226cbd..44894375 100644
--- a/docs/Credentials.md
+++ b/docs/Credentials.md
@@ -6,7 +6,7 @@ The encryption and decryption processes are works in progress.
## Notes
-1. For encrypting and storing data to be accessed only by a specific identity (e.g., yourself), the `fromid` and `toid` both must match that identity.
+1. For encrypting and storing data to be accessed only by a specific identity (e.g., yourself), both the `fromid` and `toid` must match that identity.
2. For the encryption and decryption processes, an identity with a z-address is needed.
## Encryption Process
@@ -18,7 +18,7 @@ The steps for the encryption process are as follows.
- `fromid`: the identity's address (e.g., `CredentialTester@`)
- `toid`: the same identity's address
- The result should contain the z-address that will be used to encrypt the credential and its corresponding extended viewing key.
+ The result should contain the z-address that will be used to encrypt the credential and its corresponding incoming viewing key (ivk).
Example:
@@ -32,7 +32,8 @@ The steps for the encryption process are as follows.
```json
{
"address": "zs1x49g3lkt93udlnnc8y5k7p5n0vlvqa2r2rsmsj2629hfvwljpn39mltsxy0fktp5ue46wlw3mlc",
- "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"
+ "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2",
+ "ivk": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
}
```
@@ -72,28 +73,28 @@ The steps for the encryption process are as follows.
-3. Hash `vrsc::identity.credentials` with the extended viewing key using `getvdxfid` with
+3. Hash the vdxfkey corresponding to `vrsc::identity.credentials` with the ivk using `getvdxfid` with
- `vrsc::identity.credentials`
- - `vdxfkey`: the extended viewing key
+ - `uint256`: the ivk
Get the `vdxfid` in the result for the next step.
Example:
```bash
- getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
+ getvdxfid vrsc::identity.credentials '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
```
```json
{
- "vdxfid": "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8",
- "indexid": "xFaSmqHz5nvEaT2Ypjjf6uqohFfVGyMb1c",
- "hash160result": "86a4deebbaecab2da5c8547b2fda278c8d40c64f",
+ "vdxfid": "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK",
+ "indexid": "xVoHPtL8i2Mk3cvpRZ5yNMXtXP29ZL4AMN",
+ "hash160result": "c9b30b4a009f0099e414f4b40e38e9178997c5eb",
"qualifiedname": {
"namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
"name": "vrsc::identity.credentials"
},
"bounddata": {
- "vdxfkey": "iMArFRJ3bZPg65ttXJdxGub4VbPWYRqBwW"
+ "uint256": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
}
}
```
@@ -101,7 +102,7 @@ The steps for the encryption process are as follows.
4. Add the encrypted credential to the contentmultimap using `updateidentity` with
- `name`: the identity's address
- - `contentmultimap`: the hashed `vrsc::identity.credentials` key with the data descriptor of the encrypted credential
+ - `contentmultimap`: the hashed vdxfkey from Step 3 with the data descriptor of the encrypted credential
Example:
@@ -109,7 +110,7 @@ The steps for the encryption process are as follows.
updateidentity '{
"name": "CredentialTester@",
"contentmultimap": {
- "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8": [
+ "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK": [
{
"vrsc::data.type.object.datadescriptor": {
"version": 1,
@@ -136,7 +137,7 @@ The steps for the decryption process are as follows.
This is the same as Step 1 from the [*Encryption Process*](#encryption-process).
- The result should contain a z-address and its corresponding extended viewing key, which will be used to find and decrypt the credential.
+ The result should contain an ivk and extended viewing key (evk), which will be used to find and decrypt the credential.
Example:
@@ -150,15 +151,16 @@ The steps for the decryption process are as follows.
```json
{
"address": "zs1x49g3lkt93udlnnc8y5k7p5n0vlvqa2r2rsmsj2629hfvwljpn39mltsxy0fktp5ue46wlw3mlc",
- "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"
+ "extendedviewingkey": "zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2",
+ "ivk": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
}
```
-2. Hash `vrsc::identity.credentials` with the extended viewing key using `getvdxfid` with
+2. Hash the vdxfkey corresponding to `vrsc::identity.credentials` with the ivk using `getvdxfid` with
- `vrsc::identity.credentials`
- - `vdxfkey`: the extended viewing key
+ - `uint256`: the ivk
This is the same as Step 3 from the [*Encryption Process*](#encryption-process).
@@ -167,19 +169,19 @@ The steps for the decryption process are as follows.
Example:
```bash
- getvdxfid vrsc::identity.credentials '{"vdxfkey":"zxviews1qde7tnnvqqqqpqy03gsmqjumlyg0ck25hh9etcf7h4l56kunlcjtr36e4pkr32kftw650890j009cdhgm2lc23uyrrq5g7xp5cspjy6lnwf9uk96pv9yruewfrz6k8q0gy9w065cellk3pt37s0ps90rc2zwj4h46f82h35sk23kxduuewc26673fam042zfazxn5r9zwaytcdhc3r50vrutvnnw4zxdalpw2s0w40nxu7qkgh3x3duha872ckhwt9fcl5uy7ne0d3gwknyp2"}'
+ getvdxfid vrsc::identity.credentials '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
```
```json
{
- "vdxfid": "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8",
- "indexid": "xFaSmqHz5nvEaT2Ypjjf6uqohFfVGyMb1c",
- "hash160result": "86a4deebbaecab2da5c8547b2fda278c8d40c64f",
+ "vdxfid": "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK",
+ "indexid": "xVoHPtL8i2Mk3cvpRZ5yNMXtXP29ZL4AMN",
+ "hash160result": "c9b30b4a009f0099e414f4b40e38e9178997c5eb",
"qualifiedname": {
"namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
"name": "vrsc::identity.credentials"
},
"bounddata": {
- "vdxfkey": "iMArFRJ3bZPg65ttXJdxGub4VbPWYRqBwW"
+ "uint256": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
}
}
```
@@ -188,7 +190,7 @@ The steps for the decryption process are as follows.
3. Get the `contentmultimap` of the identity using `getidentitycontent` with
- the identity's address
- This doesn't currently use a `vdxfkey` for selective searching within the `contentmultimap`, but it should in the future.
+ This doesn't currently use a vdxfkey for selective searching within the `contentmultimap`, but it should in the future.
The `contentmultimap` is within the `identity` part of the JSON result.
@@ -199,7 +201,7 @@ The steps for the decryption process are as follows.
```
```json
"contentmultimap": {
- "iAkLK2ruEUhZxH9Wy45W8XKGfbeUUg5Bp8": [
+ "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK": [
{
"i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQv": {
"version": 1,
@@ -214,9 +216,9 @@ The steps for the decryption process are as follows.
-4. Using the hashed key created in Step 2, find the data descriptor of the encrypted credential, and decrypt it using `decryptdata` with
+4. Using the hashed vdxfkey created in Step 2, find the data descriptor of the encrypted credential, and decrypt it using `decryptdata` with
- `datadescriptor`: the data descriptor of the encrypted credential
- - `evk`: the extended viewing key obtained in Step 1
+ - `evk`: the evk obtained in Step 1
Example:
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 1d270045..47caf431 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -38,17 +38,18 @@ module.exports = (api) => {
}
);
- if (!keys || !keys.extendedviewingkey) {
+ if (!keys || !keys.extendedviewingkey || !keys.ivk) {
throw new Error(`Failed to get keys for ${address}`);
}
- const viewingKey = keys.extendedviewingkey;
+ const evk = keys.extendedviewingkey;
+ const ivk = keys.ivk;
- // Generate the credential key using the viewing key.
+ // Generate the credential key using the ivk.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
"vrsc::identity.credentials",
- { vdxfkey: viewingKey }
+ { uint256: ivk }
);
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
@@ -77,7 +78,7 @@ module.exports = (api) => {
coin,
{
datadescriptor: dataDescriptor,
- evk: viewingKey
+ evk: evk
}
);
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
index 90c231e2..7f7a2529 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
@@ -28,7 +28,10 @@ module.exports = (api) => {
}
);
- if (!encryptionAddressInfo || !encryptionAddressInfo.extendedviewingkey || !encryptionAddressInfo.address) {
+ if (!encryptionAddressInfo
+ || !encryptionAddressInfo.address
+ || !encryptionAddressInfo.ivk
+ ) {
throw new Error(`Failed to get the personal encryption address for ${address}`);
}
@@ -40,7 +43,7 @@ module.exports = (api) => {
coin,
address,
contentmultimap,
- encryptionAddressInfo.extendedviewingkey,
+ encryptionAddressInfo.ivk,
encryptionAddressInfo.address
);
}
diff --git a/routes/api/native/zgetencryptionaddress.js b/routes/api/native/zgetencryptionaddress.js
index ef6b0fd4..9df1e222 100644
--- a/routes/api/native/zgetencryptionaddress.js
+++ b/routes/api/native/zgetencryptionaddress.js
@@ -5,11 +5,11 @@ module.exports = (api) => {
* a z-address in the wallet, wallet seed and hdindex, or root key (extended private key).
*
* @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} arguments The arguments to pass to z_getencryptionaddress
+ * @param {String} args The arguments to pass to z_getencryptionaddress
*/
api.native.z_get_encryption_address = (
coin,
- arguments,
+ args,
) => {
return new Promise((resolve, reject) => {
api.native
@@ -17,7 +17,7 @@ module.exports = (api) => {
coin,
"z_getencryptionaddress",
[
- arguments,
+ args,
]
)
.then(resultObj => {
@@ -32,13 +32,13 @@ module.exports = (api) => {
api.setPost('/native/z_get_encryption_address', (req, res, next) => {
const {
chainTicker,
- arguments
+ args
} = req.body;
api.native
.z_get_encryption_address(
- chainTicker,
- arguments
+ chainTicker,
+ args
)
.then(resultObj => {
const retObj = {
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 50c4863a..9001f44b 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -10,7 +10,7 @@ const encryptCredentialsInContentMultiMap = async (
coin,
address,
contentmultimap,
- viewingKey,
+ ivk,
encryptionAddress
) => {
for (const [key, valueArray] of contentmultimap.kv_content.entries()) {
@@ -39,11 +39,11 @@ const encryptCredentialsInContentMultiMap = async (
}
}
}
- // Replace the credentials key with an obfuscated key.
+ // Replace the credentials key with a hashed key.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
"vrsc::identity.credentials",
- { vdxfkey: viewingKey }
+ { uint256: ivk }
);
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
From 0699373c0872640e6d109aa527139c2a04a83533 Mon Sep 17 00:00:00 2001
From: Mark Stoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 23 Sep 2025 16:52:50 -0700
Subject: [PATCH 28/80] Clarify wording regarding the ivk in Step 1 of the
encryption process
(cherry picked from commit ce4e480904bb3eda91d1f950f8aee19c48351164)
---
docs/Credentials.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/Credentials.md b/docs/Credentials.md
index 44894375..620a8a18 100644
--- a/docs/Credentials.md
+++ b/docs/Credentials.md
@@ -18,7 +18,7 @@ The steps for the encryption process are as follows.
- `fromid`: the identity's address (e.g., `CredentialTester@`)
- `toid`: the same identity's address
- The result should contain the z-address that will be used to encrypt the credential and its corresponding incoming viewing key (ivk).
+ The result should contain the z-address that will be used to encrypt the credential and the corresponding incoming viewing key (ivk).
Example:
From cb4382cb0436e40ad8dad34ba457b39c794a7a6c Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 26 Sep 2025 15:05:04 -0700
Subject: [PATCH 29/80] Add scripts to make it easier to run and build the
project. Update the README to recommend the scripts.
(cherry picked from commit 7cdcc1f875a16d7858d8935962dcb706c3d8d90a)
---
README.md | 58 +++++++++++++++++++++++++++-----
package.json | 5 +++
scripts/build-gui-and-plugins.sh | 47 ++++++++++++++++++++++++++
scripts/create-build-win.sh | 11 ++++++
scripts/create-build.sh | 11 ++++++
scripts/dev.sh | 48 ++++++++++++++++++++++++++
scripts/directories.sh | 8 +++++
scripts/prod.sh | 11 ++++++
scripts/setup-node.sh | 5 +++
scripts/setup.sh | 40 ++++++++++++++++++++++
10 files changed, 236 insertions(+), 8 deletions(-)
create mode 100644 scripts/build-gui-and-plugins.sh
create mode 100755 scripts/create-build-win.sh
create mode 100755 scripts/create-build.sh
create mode 100755 scripts/dev.sh
create mode 100644 scripts/directories.sh
create mode 100755 scripts/prod.sh
create mode 100755 scripts/setup-node.sh
create mode 100755 scripts/setup.sh
diff --git a/README.md b/README.md
index 19f9d9f8..21443183 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,14 @@ Verus Desktop can be run without building to allow for easier development or wit
### Development Mode (Without Building)
+On Linux and macOS, run Verus Desktop with plugins in development mode using a single terminal with:
+```bash
+yarn install:all
+yarn dev:all
+```
+
+On Windows, or to run each part separately, follow these steps.
+
#### GUI
Open a new terminal in the Verus Desktop directory:
@@ -122,6 +130,14 @@ yarn start devmode
### Production Mode (With Building)
+On Linux and macOS, run Verus Desktop with plugins using a single terminal with
+```bash
+yarn install:all
+yarn start:all
+```
+
+On Windows, or to manually build the components and run Verus Desktop, follow these steps.
+
#### GUI
Open a new terminal in the Verus Desktop directory:
@@ -173,20 +189,46 @@ yarn start
- If you get a smaller blank white window after using a deeplink, the Login Consent Client needs to be built.
-## Packaging
+## Creating Builds
+
+| Operating System | File Type |
+|------------------|------------|
+| Linux | `.AppImage`|
+| macOS | `.dmg` |
+| Windows | `.exe` |
+
+To create a build from Linux for Windows, you will need either Wine or a [Docker container](https://www.electron.build/multi-platform-build#to-build-app-for-windows-on-linux)
+
+### Using Linux and macOS
+
+On Linux and macOS, package Verus Desktop with plugins using a single terminal with:
+```bash
+yarn install:all
+yarn dist:all
+```
+
+The packaged application will be packaged based on your operating system, and located in the `/dist` directory.
+
+To create a build for Windows:
+```bash
+yarn install:all
+yarn dist-win:all
+```
+
+### Windows or Manual Builds
+
+To manually build the components and package Verus Desktop, follow these steps.
Build all dependencies, including the GUI and any optional plugins, before packaging the application. See [Production Mode (With Building)](#production-mode-with-building) for how to build.
Package the application:
```shell
-yarn run dist
+yarn dist-win
```
-The packaged application will be packaged based on your operating system, and located in the `/dist` directory.
-| Operating System | Output File Type |
-|------------------|------------------|
-| Linux | `.AppImage` |
-| macOS | `.dmg` |
-| Windows | `.exe` |
+For manually building on Linux or macOS:
+```shell
+yarn dist
+```
For more detailed information about the build process, see the original [electron-builder](https://www.electron.build) website.
\ No newline at end of file
diff --git a/package.json b/package.json
index 754c1379..246aa090 100644
--- a/package.json
+++ b/package.json
@@ -6,11 +6,16 @@
"main": "main.js",
"scripts": {
"start": "cross-env NODE_ENV=development electron .",
+ "start:all": "./scripts/prod.sh",
"debug": "yarn start devmode",
+ "dev:all": "./scripts/dev.sh",
"make-patch": "./make-patch.sh",
+ "install:all": "./scripts/setup.sh",
"pack": "cross-env NODE_ENV=production electron-builder --dir verus-unpacked",
"dist": "cross-env NODE_ENV=production electron-builder --publish=never ",
"dist-win": "cross-env NODE_ENV=production electron-builder --publish=never --win",
+ "dist:all": "./scripts/create-build.sh",
+ "dist-win:all": "./scripts/create-build-win.sh",
"test": "mocha",
"update-agamalib": "rm -rf node_modules/agama-wallet-lib/ && yarn install",
"postinstall": "rm -rf node_modules/bitgo-utxo-lib/node_modules/create-hash"
diff --git a/scripts/build-gui-and-plugins.sh b/scripts/build-gui-and-plugins.sh
new file mode 100644
index 00000000..a19b8222
--- /dev/null
+++ b/scripts/build-gui-and-plugins.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+FULL_PATH=$(dirname $0)
+
+source $FULL_PATH/directories.sh
+$FULL_PATH/setup-node.sh
+
+# Build the desktop GUI
+(
+ export NODE_OPTIONS=--openssl-legacy-provider
+ echo "Building Verus-Desktop-GUI..."
+ cd $GUI_DIR
+ yarn build
+)
+
+# Build and copy the login consent client if it exists
+if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+ echo "Building verus-login-consent-client..."
+ (
+ cd $LOGIN_CONSENT_CLIENT_DIR
+ yarn build
+ )
+
+ # Copy the build files over
+ echo "Copying the build of verus-login-consent-client..."
+ if [ ! -d "$LOGIN_CONSENT_CLIENT_PLUGIN_DIR" ]; then
+ mkdir -p $LOGIN_CONSENT_CLIENT_PLUGIN_DIR
+ fi
+ cp -r $LOGIN_CONSENT_CLIENT_DIR/build/* $LOGIN_CONSENT_CLIENT_PLUGIN_DIR
+fi
+
+# Build and copy the pbaas visualizer if it exists
+if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+ echo "Building verus-pbaas-visualizer..."
+ (
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd $PBAAS_VISUALIZER_DIR
+ yarn build
+ )
+
+ # Copy the build files over
+ echo "Copying the build of verus-pbaas-visualizer..."
+ if [ ! -d "$PBAAS_VISUALIZER_PLUGIN_DIR" ]; then
+ mkdir -p $PBAAS_VISUALIZER_PLUGIN_DIR
+ fi
+ cp -r $PBAAS_VISUALIZER_DIR/build/* $PBAAS_VISUALIZER_PLUGIN_DIR
+fi
\ No newline at end of file
diff --git a/scripts/create-build-win.sh b/scripts/create-build-win.sh
new file mode 100755
index 00000000..38814106
--- /dev/null
+++ b/scripts/create-build-win.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+FULL_PATH=$(dirname $0)
+
+$FULL_PATH/setup-node.sh
+
+$FULL_PATH/build-gui-and-plugins.sh
+
+# Build the the electron app
+echo "Building Verus-Desktop for Windows..."
+yarn dist-win
\ No newline at end of file
diff --git a/scripts/create-build.sh b/scripts/create-build.sh
new file mode 100755
index 00000000..19143e4c
--- /dev/null
+++ b/scripts/create-build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+FULL_PATH=$(dirname $0)
+
+$FULL_PATH/setup-node.sh
+
+$FULL_PATH/build-gui-and-plugins.sh
+
+# Build the the electron app
+echo "Building Verus-Desktop..."
+yarn dist
\ No newline at end of file
diff --git a/scripts/dev.sh b/scripts/dev.sh
new file mode 100755
index 00000000..8bad9cbf
--- /dev/null
+++ b/scripts/dev.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+FULL_PATH=$(dirname $0)
+
+source $FULL_PATH/directories.sh
+$FULL_PATH/setup-node.sh
+
+# Start desktop GUI
+(
+ echo "Starting Verus-Desktop-GUI..."
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd $GUI_DIR
+ yarn start-no-dashboard
+) &
+
+# Check if the login consent client exists and start it if possible
+if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+ (
+ echo "Starting verus-login-consent-client..."
+ cd $LOGIN_CONSENT_CLIENT_DIR
+ yarn start
+ ) &
+fi
+
+# Check if the pbass visualizer exists and start it if possible
+if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+ (
+ echo "Starting verus-pbaas-visualizer..."
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd $PBAAS_VISUALIZER_DIR
+ # Discard the webpack dashboard output to not clutter the terminal
+ yarn start > /dev/null 2>&1
+ ) &
+fi
+
+# Start the electron app in development mode
+echo "Starting Verus-Desktop..."
+yarn start devmode
+
+cleanup() {
+ echo "Cleaning up processes..."
+ jobs -p | xargs kill
+
+ # Give the login consent client time to close gracefully
+ sleep 1
+}
+
+trap cleanup EXIT
\ No newline at end of file
diff --git a/scripts/directories.sh b/scripts/directories.sh
new file mode 100644
index 00000000..93897139
--- /dev/null
+++ b/scripts/directories.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+readonly GUI_DIR="gui/Verus-Desktop-GUI/react"
+readonly PLUGIN_DIR="assets/plugins/builtin"
+readonly LOGIN_CONSENT_CLIENT_DIR="../verus-login-consent-client"
+readonly LOGIN_CONSENT_CLIENT_PLUGIN_DIR="$PLUGIN_DIR/verus-login-consent-client"
+readonly PBAAS_VISUALIZER_DIR="../verus-pbaas-visualizer"
+readonly PBAAS_VISUALIZER_PLUGIN_DIR="$PLUGIN_DIR/verus-pbaas-visualizer"
\ No newline at end of file
diff --git a/scripts/prod.sh b/scripts/prod.sh
new file mode 100755
index 00000000..b56b28d0
--- /dev/null
+++ b/scripts/prod.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+FULL_PATH=$(dirname $0)
+
+$FULL_PATH/setup-node.sh
+
+$FULL_PATH/build-gui-and-plugins.sh
+
+# Start the electron app
+echo "Starting Verus-Desktop..."
+yarn start
\ No newline at end of file
diff --git a/scripts/setup-node.sh b/scripts/setup-node.sh
new file mode 100755
index 00000000..2618b115
--- /dev/null
+++ b/scripts/setup-node.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+# Try to switch to node 20 using nvm if possible
+. ~/.nvm/nvm.sh
+nvm use 20
diff --git a/scripts/setup.sh b/scripts/setup.sh
new file mode 100755
index 00000000..e4097477
--- /dev/null
+++ b/scripts/setup.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+set -e
+set -o pipefail
+
+FULL_PATH=$(dirname $0)
+
+source $FULL_PATH/directories.sh
+$FULL_PATH/setup-node.sh
+
+# Install dependencies for the desktop GUI
+(
+ echo "Installing dependencies for Verus-Desktop-GUI..."
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd $GUI_DIR
+ yarn install
+)
+
+# Check if the login consent client exists and install dependencies if possible
+if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+ (
+ echo "Installing dependencies for verus-login-consent-client..."
+ cd $LOGIN_CONSENT_CLIENT_DIR
+ yarn install
+ )
+fi
+
+# Check if the pbass visualizer exists and install dependencies if possible
+if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+ (
+ echo "Installing dependencies for verus-pbaas-visualizer..."
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd $PBAAS_VISUALIZER_DIR
+ yarn install
+ )
+fi
+
+# Install dependencies for the electron app
+echo "Installing dependencies for Verus-Desktop..."
+yarn install
\ No newline at end of file
From ef8a7e43408df3b7350f699b55d8d389d275f781 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 26 Sep 2025 15:16:24 -0700
Subject: [PATCH 30/80] Fix the permissions on the building script.
(cherry picked from commit bb7b6c7b86a510f986985031f38ec5f1b5a51872)
---
scripts/build-gui-and-plugins.sh | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 scripts/build-gui-and-plugins.sh
diff --git a/scripts/build-gui-and-plugins.sh b/scripts/build-gui-and-plugins.sh
old mode 100644
new mode 100755
From cdf7f698577f4516b7629199f13f6e6579d505a7 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 26 Sep 2025 17:26:18 -0700
Subject: [PATCH 31/80] Improve the scripts by adding a new line when going to
the next part of the project, and also add braces around variables.
(cherry picked from commit 4633b7b17f4323a94640f729991ce82c7e65474c)
---
scripts/build-gui-and-plugins.sh | 33 ++++++++++++++++++--------------
scripts/create-build-win.sh | 6 +++---
scripts/create-build.sh | 5 +++--
scripts/dev.sh | 18 ++++++++++-------
scripts/directories.sh | 4 ++--
scripts/prod.sh | 5 +++--
scripts/setup.sh | 19 ++++++++++--------
7 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/scripts/build-gui-and-plugins.sh b/scripts/build-gui-and-plugins.sh
index a19b8222..53e2bc63 100755
--- a/scripts/build-gui-and-plugins.sh
+++ b/scripts/build-gui-and-plugins.sh
@@ -2,46 +2,51 @@
FULL_PATH=$(dirname $0)
-source $FULL_PATH/directories.sh
-$FULL_PATH/setup-node.sh
+source ${FULL_PATH}/directories.sh
+${FULL_PATH}/setup-node.sh
# Build the desktop GUI
(
- export NODE_OPTIONS=--openssl-legacy-provider
+ echo ""
echo "Building Verus-Desktop-GUI..."
- cd $GUI_DIR
+ export NODE_OPTIONS=--openssl-legacy-provider
+ cd ${GUI_DIR}
yarn build
)
# Build and copy the login consent client if it exists
-if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+if [ -d "${LOGIN_CONSENT_CLIENT_DIR}" ]; then
+ echo ""
echo "Building verus-login-consent-client..."
(
- cd $LOGIN_CONSENT_CLIENT_DIR
+ cd ${LOGIN_CONSENT_CLIENT_DIR}
yarn build
)
# Copy the build files over
+ echo ""
echo "Copying the build of verus-login-consent-client..."
- if [ ! -d "$LOGIN_CONSENT_CLIENT_PLUGIN_DIR" ]; then
- mkdir -p $LOGIN_CONSENT_CLIENT_PLUGIN_DIR
+ if [ ! -d "${LOGIN_CONSENT_CLIENT_PLUGIN_DIR}" ]; then
+ mkdir -p ${LOGIN_CONSENT_CLIENT_PLUGIN_DIR}
fi
- cp -r $LOGIN_CONSENT_CLIENT_DIR/build/* $LOGIN_CONSENT_CLIENT_PLUGIN_DIR
+ cp -r ${LOGIN_CONSENT_CLIENT_DIR}/build/* ${LOGIN_CONSENT_CLIENT_PLUGIN_DIR}
fi
# Build and copy the pbaas visualizer if it exists
-if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
+ echo ""
echo "Building verus-pbaas-visualizer..."
(
export NODE_OPTIONS=--openssl-legacy-provider
- cd $PBAAS_VISUALIZER_DIR
+ cd ${PBAAS_VISUALIZER_DIR}
yarn build
)
# Copy the build files over
+ echo ""
echo "Copying the build of verus-pbaas-visualizer..."
- if [ ! -d "$PBAAS_VISUALIZER_PLUGIN_DIR" ]; then
- mkdir -p $PBAAS_VISUALIZER_PLUGIN_DIR
+ if [ ! -d "${PBAAS_VISUALIZER_PLUGIN_DIR}" ]; then
+ mkdir -p ${PBAAS_VISUALIZER_PLUGIN_DIR}
fi
- cp -r $PBAAS_VISUALIZER_DIR/build/* $PBAAS_VISUALIZER_PLUGIN_DIR
+ cp -r ${PBAAS_VISUALIZER_DIR}/build/* ${PBAAS_VISUALIZER_PLUGIN_DIR}
fi
\ No newline at end of file
diff --git a/scripts/create-build-win.sh b/scripts/create-build-win.sh
index 38814106..51e8dff5 100755
--- a/scripts/create-build-win.sh
+++ b/scripts/create-build-win.sh
@@ -1,10 +1,10 @@
#!/bin/bash
-FULL_PATH=$(dirname $0)
+FULL_PATH=$(dirname "${0}")
-$FULL_PATH/setup-node.sh
+${FULL_PATH}/setup-node.sh
-$FULL_PATH/build-gui-and-plugins.sh
+${FULL_PATH}/build-gui-and-plugins.sh
# Build the the electron app
echo "Building Verus-Desktop for Windows..."
diff --git a/scripts/create-build.sh b/scripts/create-build.sh
index 19143e4c..3ad0d20a 100755
--- a/scripts/create-build.sh
+++ b/scripts/create-build.sh
@@ -2,10 +2,11 @@
FULL_PATH=$(dirname $0)
-$FULL_PATH/setup-node.sh
+${FULL_PATH}/setup-node.sh
-$FULL_PATH/build-gui-and-plugins.sh
+${FULL_PATH}/build-gui-and-plugins.sh
# Build the the electron app
+echo ""
echo "Building Verus-Desktop..."
yarn dist
\ No newline at end of file
diff --git a/scripts/dev.sh b/scripts/dev.sh
index 8bad9cbf..b943a50f 100755
--- a/scripts/dev.sh
+++ b/scripts/dev.sh
@@ -2,38 +2,42 @@
FULL_PATH=$(dirname $0)
-source $FULL_PATH/directories.sh
-$FULL_PATH/setup-node.sh
+source ${FULL_PATH}/directories.sh
+${FULL_PATH}/setup-node.sh
# Start desktop GUI
(
+ echo ""
echo "Starting Verus-Desktop-GUI..."
export NODE_OPTIONS=--openssl-legacy-provider
- cd $GUI_DIR
+ cd ${GUI_DIR}
yarn start-no-dashboard
) &
# Check if the login consent client exists and start it if possible
-if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+if [ -d "${LOGIN_CONSENT_CLIENT_DIR}" ]; then
(
+ echo ""
echo "Starting verus-login-consent-client..."
- cd $LOGIN_CONSENT_CLIENT_DIR
+ cd ${LOGIN_CONSENT_CLIENT_DIR}
yarn start
) &
fi
# Check if the pbass visualizer exists and start it if possible
-if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
(
+ echo ""
echo "Starting verus-pbaas-visualizer..."
export NODE_OPTIONS=--openssl-legacy-provider
- cd $PBAAS_VISUALIZER_DIR
+ cd ${PBAAS_VISUALIZER_DIR}
# Discard the webpack dashboard output to not clutter the terminal
yarn start > /dev/null 2>&1
) &
fi
# Start the electron app in development mode
+echo ""
echo "Starting Verus-Desktop..."
yarn start devmode
diff --git a/scripts/directories.sh b/scripts/directories.sh
index 93897139..98a6051c 100644
--- a/scripts/directories.sh
+++ b/scripts/directories.sh
@@ -3,6 +3,6 @@
readonly GUI_DIR="gui/Verus-Desktop-GUI/react"
readonly PLUGIN_DIR="assets/plugins/builtin"
readonly LOGIN_CONSENT_CLIENT_DIR="../verus-login-consent-client"
-readonly LOGIN_CONSENT_CLIENT_PLUGIN_DIR="$PLUGIN_DIR/verus-login-consent-client"
+readonly LOGIN_CONSENT_CLIENT_PLUGIN_DIR="${PLUGIN_DIR}/verus-login-consent-client"
readonly PBAAS_VISUALIZER_DIR="../verus-pbaas-visualizer"
-readonly PBAAS_VISUALIZER_PLUGIN_DIR="$PLUGIN_DIR/verus-pbaas-visualizer"
\ No newline at end of file
+readonly PBAAS_VISUALIZER_PLUGIN_DIR="${PLUGIN_DIR}/verus-pbaas-visualizer"
\ No newline at end of file
diff --git a/scripts/prod.sh b/scripts/prod.sh
index b56b28d0..d6e4470a 100755
--- a/scripts/prod.sh
+++ b/scripts/prod.sh
@@ -2,10 +2,11 @@
FULL_PATH=$(dirname $0)
-$FULL_PATH/setup-node.sh
+${FULL_PATH}/setup-node.sh
-$FULL_PATH/build-gui-and-plugins.sh
+${FULL_PATH}/build-gui-and-plugins.sh
# Start the electron app
+echo ""
echo "Starting Verus-Desktop..."
yarn start
\ No newline at end of file
diff --git a/scripts/setup.sh b/scripts/setup.sh
index e4097477..5333a041 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -1,40 +1,43 @@
#!/bin/bash
set -e
-set -o pipefail
FULL_PATH=$(dirname $0)
-source $FULL_PATH/directories.sh
-$FULL_PATH/setup-node.sh
+source ${FULL_PATH}/directories.sh
+${FULL_PATH}/setup-node.sh
# Install dependencies for the desktop GUI
(
+ echo ""
echo "Installing dependencies for Verus-Desktop-GUI..."
export NODE_OPTIONS=--openssl-legacy-provider
- cd $GUI_DIR
+ cd ${GUI_DIR}
yarn install
)
# Check if the login consent client exists and install dependencies if possible
-if [ -d "$LOGIN_CONSENT_CLIENT_DIR" ]; then
+if [ -d "${LOGIN_CONSENT_CLIENT_DIR}" ]; then
(
+ echo ""
echo "Installing dependencies for verus-login-consent-client..."
- cd $LOGIN_CONSENT_CLIENT_DIR
+ cd ${LOGIN_CONSENT_CLIENT_DIR}
yarn install
)
fi
# Check if the pbass visualizer exists and install dependencies if possible
-if [ -d "$PBAAS_VISUALIZER_DIR" ]; then
+if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
(
+ echo ""
echo "Installing dependencies for verus-pbaas-visualizer..."
export NODE_OPTIONS=--openssl-legacy-provider
- cd $PBAAS_VISUALIZER_DIR
+ cd ${PBAAS_VISUALIZER_DIR}
yarn install
)
fi
# Install dependencies for the electron app
+echo ""
echo "Installing dependencies for Verus-Desktop..."
yarn install
\ No newline at end of file
From 7ffa24f768355055b94306a67a812281e2e8af24 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 26 Sep 2025 18:23:51 -0700
Subject: [PATCH 32/80] Fix the script for building Windows binaries to not
have curly braces on the positional parameter.
(cherry picked from commit 76abd1eda8dc8853175652fe1ea0c387190460d4)
---
scripts/create-build-win.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/create-build-win.sh b/scripts/create-build-win.sh
index 51e8dff5..91965ad6 100755
--- a/scripts/create-build-win.sh
+++ b/scripts/create-build-win.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-FULL_PATH=$(dirname "${0}")
+FULL_PATH=$(dirname $0)
${FULL_PATH}/setup-node.sh
From 030ab415f7910f536cbcb9d1fa146ec656d38fa4 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 30 Sep 2025 10:57:08 -0700
Subject: [PATCH 33/80] Replace the constant vrsc::identity.credentials with
the variable from verus-typescript-primitives.
(cherry picked from commit bd32b6acfd3dc25006585f51b493cc04ef58b3e9)
---
routes/api/native/credentials/getCredentials.js | 3 ++-
routes/api/utils/credentials/encryptCredentials.js | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index 47caf431..ae2ee9fb 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -1,6 +1,7 @@
const {
DATA_TYPE_OBJECT_DATADESCRIPTOR,
fromBase58Check,
+ IDENTITY_CREDENTIALS,
} = require("verus-typescript-primitives");
const { parseCredential } = require("../../utils/credentials/parseCredential");
@@ -48,7 +49,7 @@ module.exports = (api) => {
// Generate the credential key using the ivk.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
- "vrsc::identity.credentials",
+ IDENTITY_CREDENTIALS.vdxfid,
{ uint256: ivk }
);
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 9001f44b..0d3111ba 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -42,7 +42,7 @@ const encryptCredentialsInContentMultiMap = async (
// Replace the credentials key with a hashed key.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
- "vrsc::identity.credentials",
+ IDENTITY_CREDENTIALS.vdxfid,
{ uint256: ivk }
);
From 0e2799743113c9f0844436a3fae3d9db485cc191 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 30 Sep 2025 15:59:00 -0700
Subject: [PATCH 34/80] Use newer version of credential vdxfkey.
(cherry picked from commit 73d620202235d6740351b7ca918bf29766b5f6e4)
---
package.json | 2 +-
routes/api/native/credentials/getCredentials.js | 4 ++--
routes/api/utils/credentials/encryptCredentials.js | 8 ++++----
yarn.lock | 11 +++++++++++
4 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index 246aa090..832165fb 100644
--- a/package.json
+++ b/package.json
@@ -85,7 +85,7 @@
"systeminformation": "5.23.8",
"tx-builder": "^0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/VerusCoin/verus-typescript-primitives.git",
+ "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
"verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client",
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.js
index ae2ee9fb..16e4b22c 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.js
@@ -1,7 +1,7 @@
const {
DATA_TYPE_OBJECT_DATADESCRIPTOR,
fromBase58Check,
- IDENTITY_CREDENTIALS,
+ IDENTITY_CREDENTIAL,
} = require("verus-typescript-primitives");
const { parseCredential } = require("../../utils/credentials/parseCredential");
@@ -49,7 +49,7 @@ module.exports = (api) => {
// Generate the credential key using the ivk.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
- IDENTITY_CREDENTIALS.vdxfid,
+ IDENTITY_CREDENTIAL.vdxfid,
{ uint256: ivk }
);
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 0d3111ba..43c5d68c 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -1,5 +1,5 @@
const {
- IDENTITY_CREDENTIALS,
+ IDENTITY_CREDENTIAL,
DATA_TYPE_OBJECT_CREDENTIAL,
DataDescriptor,
DATA_TYPE_OBJECT_DATADESCRIPTOR
@@ -14,7 +14,7 @@ const encryptCredentialsInContentMultiMap = async (
encryptionAddress
) => {
for (const [key, valueArray] of contentmultimap.kv_content.entries()) {
- if (key === IDENTITY_CREDENTIALS.vdxfid) {
+ if (key === IDENTITY_CREDENTIAL.vdxfid) {
for (let i = 0; i < valueArray.length; i++) {
const vdxfUniValue = valueArray[i];
for (const valueObj of vdxfUniValue.values) {
@@ -42,7 +42,7 @@ const encryptCredentialsInContentMultiMap = async (
// Replace the credentials key with a hashed key.
const credentialKeyResult = await api.native.get_vdxf_id(
coin,
- IDENTITY_CREDENTIALS.vdxfid,
+ IDENTITY_CREDENTIAL.vdxfid,
{ uint256: ivk }
);
@@ -53,7 +53,7 @@ const encryptCredentialsInContentMultiMap = async (
const credentialKey = credentialKeyResult.vdxfid;
contentmultimap.kv_content.set(credentialKey, valueArray);
- contentmultimap.kv_content.delete(IDENTITY_CREDENTIALS.vdxfid);
+ contentmultimap.kv_content.delete(IDENTITY_CREDENTIAL.vdxfid);
}
}
};
diff --git a/yarn.lock b/yarn.lock
index 52fcb0cd..45d30413 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8005,6 +8005,17 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
+"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
+ version "1.0.0"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#57f107a0c7a81b27b6ddcdb3cad95cb8cd6279f8"
+ dependencies:
+ base64url "3.0.1"
+ bech32 "2.0.0"
+ blake2b "https://github.com/VerusCoin/blake2b"
+ bn.js "5.2.1"
+ bs58check "2.0.0"
+ create-hash "1.2.0"
+
"verus-wallet-endpoints@git+https://github.com/VerusCoin/verus-wallet-endpoints.git":
version "1.0.0"
resolved "git+https://github.com/VerusCoin/verus-wallet-endpoints.git#d7c9d51138e5231ac66cbfe316fb5d7527d35e4c"
From 0401b0170a702a6d82a816448460641487da7d5c Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 23 Oct 2025 15:46:39 -0700
Subject: [PATCH 35/80] Minimize the GUI after POSTing to a webhook at the end
of a successful deeplink handling.
(cherry picked from commit 39b956cf7b51e667d8efc839696101bdc7114f2c)
---
main.js | 11 +++++++++++
routes/api.js | 1 +
routes/api/minimize.js | 22 +++++++++++++++++++++
routes/api/plugin/builtin/loginconsentui.js | 16 +++++++++++++--
4 files changed, 48 insertions(+), 2 deletions(-)
create mode 100644 routes/api/minimize.js
diff --git a/main.js b/main.js
index 71a9f8e9..3b168f3a 100644
--- a/main.js
+++ b/main.js
@@ -549,6 +549,16 @@ if (!hasLock) {
}
}
+ function minimizeMain() {
+ if (!mainWindow) {
+ createMainWindow();
+ } else {
+ if (!mainWindow.isMinimized()) {
+ mainWindow.minimize();
+ }
+ }
+ }
+
function handleSecondInstance(event, argv, cwd) {
focusMain();
@@ -559,6 +569,7 @@ if (!hasLock) {
}
api.setupFocusApis(focusMain);
+ api.setupMinimizeApis(minimizeMain);
app.on("activate", focusMain);
app.on("second-instance", handleSecondInstance);
diff --git a/routes/api.js b/routes/api.js
index 19386659..97689038 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -122,6 +122,7 @@ api = require('./api/plugin/builtin/loginconsentui')(api);
api = require('./api/plugin/builtin/pbaasvisualizer')(api);
api = require('./api/focus')(api);
+api = require('./api/minimize')(api);
// native
api = require('./api/native/addrBalance.js')(api);
diff --git a/routes/api/minimize.js b/routes/api/minimize.js
new file mode 100644
index 00000000..012040bf
--- /dev/null
+++ b/routes/api/minimize.js
@@ -0,0 +1,22 @@
+module.exports = (api) => {
+ api.setupMinimizeApis = (minimizeFunction) => {
+ api.minimizeApp = minimizeFunction
+
+ api.setPost('/plugin/minimize', async (req, res, next) => {
+ try {
+ api.minimizeApp()
+
+ res.send(JSON.stringify({
+ msg: 'success'
+ }))
+ } catch(e) {
+ res.send(JSON.stringify({
+ msg: 'error',
+ error: e.message
+ }))
+ }
+ });
+ }
+
+ return api;
+};
\ No newline at end of file
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index 493f961d..64ddcc9a 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -29,10 +29,22 @@ module.exports = (api) => {
}
const post = async () => {
- return await axios.post(
+ // Add a slight delay to allow the user to see the desktop GUI briefly.
+ setTimeout(() => {
+ api.minimizeApp();
+ }, 250);
+
+ let result
+ try {
+ result = await axios.post(
uri,
response
- );
+ );
+ } catch (e) {
+ console.error(`Failed to post to webhook ${e}`)
+ }
+
+ return result;
};
const redirect = async () => {
From 5ffebac4e9da0f3953894f5f4ea1f5acfc29e75c Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 3 Nov 2025 13:49:22 -0800
Subject: [PATCH 36/80] Add the version number to the desktop file in order to
help with updating the integration on version updates.
(cherry picked from commit ced5479617545ac46ea8547dfa51dd258a0b0965)
---
routes/api/utility_apis/deeplinkSetup.js | 31 ++++++++++++++++++------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index 81613ae4..1a7da207 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -87,8 +87,7 @@ async function installDesktopFile(squashRoot, appImage) {
if (!desktopFileName) {
throw new Error('No desktop file found in AppImage');
}
-
- const desktopFile = path.join(appsDir, desktopFileName);
+
const sourceDesktopFile = path.join(squashRoot, desktopFileName);
if (!(await fs.pathExists(sourceDesktopFile))) {
@@ -96,6 +95,9 @@ async function installDesktopFile(squashRoot, appImage) {
}
let desktopFileContent = await fs.readFile(sourceDesktopFile, 'utf8');
+ let adjustedDesktopFileName = desktopFileName;
+
+ const desktopFileBaseName = desktopFileName.replace(/\.desktop$/, '');
// Extract X-AppImage-Version and append to Name in parentheses.
const versionMatch = desktopFileContent.match(/^X-AppImage-Version=(.+)$/m);
@@ -112,6 +114,20 @@ async function installDesktopFile(squashRoot, appImage) {
return match;
}
);
+
+ // Add the version if possible to the desktop file name.
+ const versionSuffix = `-${version}`;
+ const desktopFileNameWithId = `${desktopFileBaseName}${versionSuffix}.desktop`;
+ adjustedDesktopFileName = desktopFileNameWithId;
+ }
+
+ const desktopFile = path.join(appsDir, adjustedDesktopFileName);
+
+ // Remove stale desktop files to clean up the cache.
+ for (const file of await fs.readdir(appsDir)) {
+ if (file.startsWith(desktopFileBaseName) && file.endsWith('.desktop')) {
+ await fs.remove(path.join(appsDir, file)).catch(() => {});
+ }
}
// Replace AppRun with the actual AppImage path and append --no-sandbox %U
@@ -143,6 +159,12 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
// Create the desktop integration.
await run(`update-desktop-database "${appsDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
+
+ // Force update desktop menu.
+ try {
+ await run(`xdg-desktop-menu forceupdate`, { maxBuffer: MAX_BUFFER_SIZE });
+ } catch {}
+
for (const mimeType of mimeTypes) {
try {
await run(`xdg-mime default "${path.basename(desktopFileName)}" "${mimeType}"`, { maxBuffer: MAX_BUFFER_SIZE });
@@ -154,11 +176,6 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
const mimeDir = path.join(xdgDataHome(), 'mime');
await run(`update-mime-database "${mimeDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
} catch {}
-
- // Force update desktop menu.
- try {
- await run(`xdg-desktop-menu forceupdate`, { maxBuffer: MAX_BUFFER_SIZE });
- } catch {}
}
module.exports = (api) => {
From 2c04ad0d7032b9858c8219856ed9c86e550f89e4 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 24 Nov 2025 15:03:24 -0800
Subject: [PATCH 37/80] Fix creating the desktop integration on mainnet
deleting the testnet integration.
(cherry picked from commit 1667eeb77df9daf01c1ff7c9793dab9603193a74)
---
routes/api/utility_apis/deeplinkSetup.js | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index 1a7da207..0e7c64f5 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -3,6 +3,7 @@ const path = require('path');
const os = require('os');
const { execFile, exec } = require('child_process');
const util = require('util');
+const { IS_TESTNET } = require('../utils/constants/dev_options');
const run = util.promisify(exec);
const runFile = util.promisify(execFile);
@@ -124,9 +125,13 @@ async function installDesktopFile(squashRoot, appImage) {
const desktopFile = path.join(appsDir, adjustedDesktopFileName);
// Remove stale desktop files to clean up the cache.
- for (const file of await fs.readdir(appsDir)) {
- if (file.startsWith(desktopFileBaseName) && file.endsWith('.desktop')) {
- await fs.remove(path.join(appsDir, file)).catch(() => {});
+ for (const filename of await fs.readdir(appsDir)) {
+ if (filename.startsWith(desktopFileBaseName) && filename.endsWith('.desktop')) {
+
+ // Don't delete testnet files if not installing testnet and vice versa.
+ if (IS_TESTNET === filename.includes('testnet')) {
+ await fs.remove(path.join(appsDir, filename)).catch(() => {});
+ }
}
}
From c8ddfdc852830b7affc6cc0ead06af8fbe512341 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 10 Dec 2025 14:42:17 -0800
Subject: [PATCH 38/80] Fix the icon and running status for the desktop
integration.
(cherry picked from commit a95f126b2ec82e87485fe370ad43e9b88909d3d8)
---
main.js | 7 ++++---
routes/api/utility_apis/deeplinkSetup.js | 9 +++++++++
routes/appBasicInfo.js | 7 +++++++
3 files changed, 20 insertions(+), 3 deletions(-)
create mode 100644 routes/appBasicInfo.js
diff --git a/main.js b/main.js
index 3b168f3a..7beaae2b 100644
--- a/main.js
+++ b/main.js
@@ -37,6 +37,7 @@ if (!hasLock) {
const { MasterSecret, BuiltinSecret } = require("./routes/preloads/keys");
const setuplink = require("./routes/deeplink/setuplink");
const removelink = require('./routes/deeplink/removelink');
+ const { APP_NAME, APP_MODE, APP_VERSION } = require('./routes/appBasicInfo');
const guiapp = express();
@@ -44,9 +45,9 @@ if (!hasLock) {
const { appConfig } = api;
const appBasicInfo = {
- name: "Verus Desktop",
- mode: "standard",
- version: version.version,
+ name: APP_NAME,
+ mode: APP_MODE,
+ version: APP_VERSION,
};
app.setName(appBasicInfo.name);
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index 0e7c64f5..fd608c50 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -6,6 +6,7 @@ const util = require('util');
const { IS_TESTNET } = require('../utils/constants/dev_options');
const run = util.promisify(exec);
const runFile = util.promisify(execFile);
+const { APP_NAME } = require('../../appBasicInfo');
// Increase maxBuffer to handle large outputs (e.g., AppImage extraction).
const MAX_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
@@ -142,6 +143,14 @@ async function installDesktopFile(squashRoot, appImage) {
`Exec=${appImage} --no-sandbox %U`
);
+ // Update the StartupWMClass to properly associate the running app with the desktop icon.
+ // The name used by electron doesn't match the one used by electron builder, so we need to set it here.
+ const wmClass = APP_NAME;
+ desktopFileContent = desktopFileContent.replace(
+ /^StartupWMClass=.*$/m,
+ `StartupWMClass=${wmClass}`
+ );
+
await fs.writeFile(desktopFile, desktopFileContent, { mode: 0o644 });
return { content: desktopFileContent, path: desktopFile };
diff --git a/routes/appBasicInfo.js b/routes/appBasicInfo.js
new file mode 100644
index 00000000..68ebf567
--- /dev/null
+++ b/routes/appBasicInfo.js
@@ -0,0 +1,7 @@
+const version = require("../version.json");
+
+module.exports = {
+ APP_NAME: "Verus Desktop Testnet",
+ APP_MODE: "standard",
+ APP_VERSION: version.version,
+};
From 5cbb3d8297be06994445960998887543638e1c8a Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 9 Jan 2026 19:59:58 -0800
Subject: [PATCH 39/80] Fix the incorrect class name for ResponseURI caused by
updating the Verus libraries.
(cherry picked from commit 14b80196d1744c71e8ca5a6ee1252c034e3d5d04)
---
routes/api/plugin/builtin/loginconsentui.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index 64ddcc9a..0949b513 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -5,7 +5,7 @@ const {
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
IDENTITY_UPDATE_RESPONSE_VDXF_KEY,
- ResponseUri,
+ ResponseURI,
} = require("verus-typescript-primitives");
const { pushMessage } = require('../../../ipc/ipc');
const { ReservedPluginTypes } = require('../../utils/plugin/builtin');
@@ -24,8 +24,8 @@ module.exports = (api) => {
// Type can either be a string vdxfkey or a BN converted into a number.
const usesResponseUri = responseKey === IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid;
if (usesResponseUri) {
- const responseUri = ResponseUri.fromJson(redirectinfo);
- processedType = responseUri.type;
+ const responseUri = ResponseURI.fromJson(redirectinfo);
+ processedType = ResponseURI.type;
}
const post = async () => {
@@ -85,8 +85,8 @@ module.exports = (api) => {
const handlers = {
[LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: post,
[LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: redirect,
- [ResponseUri.TYPE_POST]: post,
- [ResponseUri.TYPE_REDIRECT]: redirect,
+ [ResponseURI.TYPE_POST]: post,
+ [ResponseURI.TYPE_REDIRECT]: redirect,
};
return handlers[processedType] == null ? null : handlers[processedType]();
From f85d09ef07efc301e5e05eadbcf33a639459bacf Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Sat, 10 Jan 2026 10:33:27 -0800
Subject: [PATCH 40/80] Revert the verus-typescript-primitives version to keep
identity update requests working.
(cherry picked from commit 2266024e56e5a903d9b73ced1e46da900d97765f)
---
routes/api/plugin/builtin/loginconsentui.js | 10 +++++-----
yarn.lock | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index 0949b513..4ccf94e6 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -5,7 +5,7 @@ const {
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
IDENTITY_UPDATE_RESPONSE_VDXF_KEY,
- ResponseURI,
+ ResponseUri,
} = require("verus-typescript-primitives");
const { pushMessage } = require('../../../ipc/ipc');
const { ReservedPluginTypes } = require('../../utils/plugin/builtin');
@@ -24,8 +24,8 @@ module.exports = (api) => {
// Type can either be a string vdxfkey or a BN converted into a number.
const usesResponseUri = responseKey === IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid;
if (usesResponseUri) {
- const responseUri = ResponseURI.fromJson(redirectinfo);
- processedType = ResponseURI.type;
+ const responseUri = ResponseUri.fromJson(redirectinfo);
+ processedType = ResponseUri.type;
}
const post = async () => {
@@ -85,8 +85,8 @@ module.exports = (api) => {
const handlers = {
[LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: post,
[LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: redirect,
- [ResponseURI.TYPE_POST]: post,
- [ResponseURI.TYPE_REDIRECT]: redirect,
+ [ResponseUri.TYPE_POST]: post,
+ [ResponseUri.TYPE_REDIRECT]: redirect,
};
return handlers[processedType] == null ? null : handlers[processedType]();
diff --git a/yarn.lock b/yarn.lock
index 45d30413..f815f2ad 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8005,9 +8005,9 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
-"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
+"verus-typescript-primitives@https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#57f107a0c7a81b27b6ddcdb3cad95cb8cd6279f8"
+ resolved "https://github.com/mcstoer/verus-typescript-primitives.git#509ee45582a83732705369904a495daed4187288"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From 1010bd0cb70d0d02999810d67e408e536cf90ceb Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 5 Feb 2026 16:58:04 -0800
Subject: [PATCH 41/80] Update yarn.lock with a new resolution for
verus-typescript-primitives.
(cherry picked from commit 8e0f64e1c6236361da32075bd6f8539ef1c7da12)
---
yarn.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index f815f2ad..6de88111 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8005,9 +8005,9 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
-"verus-typescript-primitives@https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
+"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
version "1.0.0"
- resolved "https://github.com/mcstoer/verus-typescript-primitives.git#509ee45582a83732705369904a495daed4187288"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#509ee45582a83732705369904a495daed4187288"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
From 070666bb04cb76305b713724089f0ad80b63735b Mon Sep 17 00:00:00 2001
From: Mark Stoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 13 Feb 2026 11:24:56 -0800
Subject: [PATCH 42/80] Fix references to 'credentials' in Credential
encryption and decryption documentation
(cherry picked from commit ff791e439026a93ef2d942fcea10022106e5e6ee)
---
docs/Credentials.md | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/docs/Credentials.md b/docs/Credentials.md
index 620a8a18..abdf82b2 100644
--- a/docs/Credentials.md
+++ b/docs/Credentials.md
@@ -73,8 +73,8 @@ The steps for the encryption process are as follows.
-3. Hash the vdxfkey corresponding to `vrsc::identity.credentials` with the ivk using `getvdxfid` with
- - `vrsc::identity.credentials`
+3. Hash the vdxfkey corresponding to `vrsc::identity.credential` with the ivk using `getvdxfid` with
+ - `vrsc::identity.credential`
- `uint256`: the ivk
Get the `vdxfid` in the result for the next step.
@@ -82,16 +82,16 @@ The steps for the encryption process are as follows.
Example:
```bash
- getvdxfid vrsc::identity.credentials '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
+ getvdxfid vrsc::identity.credential '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
```
```json
{
- "vdxfid": "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK",
- "indexid": "xVoHPtL8i2Mk3cvpRZ5yNMXtXP29ZL4AMN",
- "hash160result": "c9b30b4a009f0099e414f4b40e38e9178997c5eb",
+ "vdxfid": "i4zYNxkyAsMKuL5MFV9cy5aqxCbhTnS3da",
+ "indexid": "x9peqmC42BZzXVxP7AomwU7NyrciGcZi1T",
+ "hash160result": "01dc9f8b9389d5569b6fa505185fd37e0265a510",
"qualifiedname": {
"namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
- "name": "vrsc::identity.credentials"
+ "name": "vrsc::identity.credential"
},
"bounddata": {
"uint256": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
@@ -110,7 +110,7 @@ The steps for the encryption process are as follows.
updateidentity '{
"name": "CredentialTester@",
"contentmultimap": {
- "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK": [
+ "i4zYNxkyAsMKuL5MFV9cy5aqxCbhTnS3da": [
{
"vrsc::data.type.object.datadescriptor": {
"version": 1,
@@ -158,8 +158,8 @@ The steps for the decryption process are as follows.
-2. Hash the vdxfkey corresponding to `vrsc::identity.credentials` with the ivk using `getvdxfid` with
- - `vrsc::identity.credentials`
+2. Hash the vdxfkey corresponding to `vrsc::identity.credential` with the ivk using `getvdxfid` with
+ - `vrsc::identity.credential`
- `uint256`: the ivk
This is the same as Step 3 from the [*Encryption Process*](#encryption-process).
@@ -169,16 +169,16 @@ The steps for the decryption process are as follows.
Example:
```bash
- getvdxfid vrsc::identity.credentials '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
+ getvdxfid vrsc::identity.credential '{"uint256":"f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"}'
```
```json
{
- "vdxfid": "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK",
- "indexid": "xVoHPtL8i2Mk3cvpRZ5yNMXtXP29ZL4AMN",
- "hash160result": "c9b30b4a009f0099e414f4b40e38e9178997c5eb",
+ "vdxfid": "i4zYNxkyAsMKuL5MFV9cy5aqxCbhTnS3da",
+ "indexid": "x9peqmC42BZzXVxP7AomwU7NyrciGcZi1T",
+ "hash160result": "01dc9f8b9389d5569b6fa505185fd37e0265a510",
"qualifiedname": {
"namespace": "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV",
- "name": "vrsc::identity.credentials"
+ "name": "vrsc::identity.credential"
},
"bounddata": {
"uint256": "f094f7446c88558005eebfcff532cb448bd0ada959903bc2570b1a5c74e41e07"
@@ -201,7 +201,7 @@ The steps for the decryption process are as follows.
```
```json
"contentmultimap": {
- "iQyAw5u3ri95RT3nZsRpPy1MVj18bdreHK": [
+ "i4zYNxkyAsMKuL5MFV9cy5aqxCbhTnS3da": [
{
"i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQv": {
"version": 1,
From 74af54562ad9f42b0d6d3d1ddc15b89418546056 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 17 Feb 2026 23:16:56 -0800
Subject: [PATCH 43/80] Generalize the Credential documentation to be about how
the encrypted keys are handled.
(cherry picked from commit 02633983d9638f1db726a0c4bda9d34737f02b6a)
---
docs/{Credentials.md => EncryptedKeys.md} | 30 ++++++++++++++---------
1 file changed, 18 insertions(+), 12 deletions(-)
rename docs/{Credentials.md => EncryptedKeys.md} (86%)
diff --git a/docs/Credentials.md b/docs/EncryptedKeys.md
similarity index 86%
rename from docs/Credentials.md
rename to docs/EncryptedKeys.md
index abdf82b2..3e4de342 100644
--- a/docs/Credentials.md
+++ b/docs/EncryptedKeys.md
@@ -1,17 +1,25 @@
-# Credentials
+# Encrypted Keys
-Credentials contain sensitive information, so they must be encrypted at rest. The wallet handles the encryption and decryption of credentials for the user.
+Certain vdxfkeys, also known as encrypted keys, are for sensitive data that must be encrypted at rest. The wallet handles the encryption and decryption of the sensitive data for the user.
-The encryption and decryption processes are works in progress.
+The encryption and decryption processes are still being developed.
-## Notes
+## List of Encrypted Keys
+
+The following keys are used to store sensitive data in encrypted form:
+
+- `vrsc::identity.credential`: Stores credentials (such as usernames and passwords), which can be given to applications for authentication purposes.
+
+## General Notes
1. For encrypting and storing data to be accessed only by a specific identity (e.g., yourself), both the `fromid` and `toid` must match that identity.
-2. For the encryption and decryption processes, an identity with a z-address is needed.
+2. For the encryption and decryption processes, an identity with a z-address is needed.
+3. The decryption process doesn't currently use a vdxfkey for selective searching within the `contentmultimap`, but it should in the future.
+4. Currently, the encryption process runs whenever an encrypted key is found at the top level of the `contentmultimap` keys of the Identity Update Request. For a credential, `vrsc::identity.credential` key and the plaintext credential are respectively replaced with a derived key hash (based on `vrsc::identity.credential` and the encryption ivk) and a data descriptor that contains the encrypted credential data. More detail about this replacement can be found below in [Encryption Process with a Credential](#encryption-process-with-a-credential).
-## Encryption Process
+## Encryption Process with a Credential
-The steps for the encryption process are as follows.
+The encryption process follows these steps:
1. Run `z_getencryptionaddress` with
- `address`: the identity's z-address
@@ -126,9 +134,9 @@ The steps for the encryption process are as follows.
-## Decryption Process
+## Decryption Process with a Credential
-The steps for the decryption process are as follows.
+The decryption process follows these steps:
1. Run `z_getencryptionaddress` with
- `address`: the identity's z-address
@@ -162,7 +170,7 @@ The steps for the decryption process are as follows.
- `vrsc::identity.credential`
- `uint256`: the ivk
- This is the same as Step 3 from the [*Encryption Process*](#encryption-process).
+ This is identical as Step 3 from the [*Encryption Process*](#encryption-process).
Get the `vdxfid` in the result for Step 4.
@@ -190,8 +198,6 @@ The steps for the decryption process are as follows.
3. Get the `contentmultimap` of the identity using `getidentitycontent` with
- the identity's address
- This doesn't currently use a vdxfkey for selective searching within the `contentmultimap`, but it should in the future.
-
The `contentmultimap` is within the `identity` part of the JSON result.
Example:
From 8c2dc8eeedbd46da515fb3a4ac84da1c2705e1c2 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 15 Dec 2025 11:43:00 -0800
Subject: [PATCH 44/80] Update verus-typescript-primitives to the version with
requests v2.
---
package.json | 4 ++--
yarn.lock | 14 +++++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/package.json b/package.json
index 832165fb..db0f57f1 100644
--- a/package.json
+++ b/package.json
@@ -85,10 +85,10 @@
"systeminformation": "5.23.8",
"tx-builder": "^0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update",
+ "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
- "verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client",
+ "verusd-rpc-ts-client": "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys",
"wif": "2.0.6"
},
"optionalDependencies": {
diff --git a/yarn.lock b/yarn.lock
index 6de88111..bae535b6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1326,7 +1326,7 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-axios@0.25.0, axios@1.11.0, axios@1.7.4:
+axios@0.25.0, axios@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
@@ -8005,9 +8005,9 @@ verror@^1.10.0:
bs58check "2.0.0"
create-hash "1.2.0"
-"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#credential-key-update":
+"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#509ee45582a83732705369904a495daed4187288"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#68e47b27669fadbbb3fc4de8db944b79d5b167ea"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -8035,12 +8035,12 @@ verror@^1.10.0:
react-native-cache "git+https://github.com/michaeltout/react-native-cache.git"
web3 "1.10.0"
-"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client":
+"verusd-rpc-ts-client@git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys":
version "0.1.0"
- resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client#a2519d42650e0bd014e73ab0cbc26c2cadd4a672"
+ resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#d68031949eb8b64c4919c3b2d18d8c1e63a66883"
dependencies:
- axios "1.11.0"
- verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
+ axios "1.7.4"
+ verus-typescript-primitives "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys"
wcwidth@^1.0.0:
version "1.0.1"
From e02dcde8b33bb8ccca3bff41057cab21f87f3bd4 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 16 Dec 2025 17:03:09 -0800
Subject: [PATCH 45/80] Add the verus:// protocol scheme for deeplinking.
---
package.json | 2 +-
routes/deeplink/removelink.js | 10 +++++++++-
routes/deeplink/setuplink.js | 19 ++++++++++++-------
3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/package.json b/package.json
index db0f57f1..d7896200 100644
--- a/package.json
+++ b/package.json
@@ -140,7 +140,7 @@
"icon": "assets/icons/agama_icons",
"desktop": {
"Encoding": "UTF-8",
- "MimeType": "x-scheme-handler/i5jtwbp6zymeay9llnraglgjqgdrffsau4"
+ "MimeType": "x-scheme-handler/i5jtwbp6zymeay9llnraglgjqgdrffsau4;x-scheme-handler/verus"
},
"target": [
"appimage"
diff --git a/routes/deeplink/removelink.js b/routes/deeplink/removelink.js
index 57598076..a9b56932 100644
--- a/routes/deeplink/removelink.js
+++ b/routes/deeplink/removelink.js
@@ -1,7 +1,15 @@
const { WALLET_VDXF_KEY } = require("verus-typescript-primitives")
function removelink(app) {
- return app.removeAsDefaultProtocolClient(WALLET_VDXF_KEY.vdxfid)
+ const protocols = [WALLET_VDXF_KEY.vdxfid, 'verus'];
+ const results = [];
+
+ for (const protocol of protocols) {
+ const res = app.removeAsDefaultProtocolClient(protocol);
+ results.push({ protocol, success: res });
+ }
+
+ return results;
}
module.exports = removelink
\ No newline at end of file
diff --git a/routes/deeplink/setuplink.js b/routes/deeplink/setuplink.js
index db209712..80aeb544 100644
--- a/routes/deeplink/setuplink.js
+++ b/routes/deeplink/setuplink.js
@@ -2,17 +2,22 @@ const path = require('path')
const { WALLET_VDXF_KEY } = require('verus-typescript-primitives');
function setuplink(app) {
- let res;
+ const protocols = [WALLET_VDXF_KEY.vdxfid, 'verus'];
+ const results = [];
- if (process.defaultApp) {
- if (process.argv.length >= 2) {
- res = app.setAsDefaultProtocolClient(WALLET_VDXF_KEY.vdxfid, process.execPath, [path.resolve(process.argv[1])])
+ for (const protocol of protocols) {
+ let res;
+ if (process.defaultApp) {
+ if (process.argv.length >= 2) {
+ res = app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(process.argv[1])])
+ }
+ } else {
+ res = app.setAsDefaultProtocolClient(protocol)
}
- } else {
- res = app.setAsDefaultProtocolClient(WALLET_VDXF_KEY.vdxfid)
+ results.push({ protocol, success: res });
}
- return res
+ return results;
}
module.exports = setuplink
\ No newline at end of file
From 458f7d3e2c7a017c356b94acc35b30ffd01f5c22 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 17 Dec 2025 16:32:52 -0800
Subject: [PATCH 46/80] Update the deeplink handler to support requests v2.
---
routes/api/dlhandler.js | 61 ++++++++++++++++++++++++-----------------
1 file changed, 36 insertions(+), 25 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 460d35f1..33ea0557 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -1,4 +1,13 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY, LoginConsentRequest, VERUSPAY_INVOICE_VDXF_KEY, VerusPayInvoice, IDENTITY_UPDATE_REQUEST_VDXF_KEY, IdentityUpdateRequest } = require('verus-typescript-primitives');
+const {
+ LOGIN_CONSENT_REQUEST_VDXF_KEY,
+ LoginConsentRequest,
+ VERUSPAY_INVOICE_VDXF_KEY,
+ VerusPayInvoice,
+ IDENTITY_UPDATE_REQUEST_VDXF_KEY,
+ IdentityUpdateRequest,
+ DEEPLINK_PROTOCOL_URL_CURRENT_VERSION,
+ GenericRequest
+} = require('verus-typescript-primitives');
const base64url = require("base64url");
const { ROOT_SYSTEM_NAME } = require('./utils/constants/dev_options');
const { SUPPORTED_DLS, CALLBACK_HOST } = require('./utils/constants/supported_dls');
@@ -8,35 +17,37 @@ module.exports = (api) => {
const deeplinkHandler = (urlstring) => {
const url = new URL(urlstring);
- if (url.host !== CALLBACK_HOST) {
- throw new Error('Unsupported deeplink host url.');
- }
+ let dl;
+ let id;
- const id = url.pathname.split('/')[1];
+ // Handle v1 and v2 requests separately.
+ if (url.host === CALLBACK_HOST) {
+ id = url.pathname.split('/')[1];
- if (!SUPPORTED_DLS.includes(id)) {
- throw new Error('Unsupported deeplink url path.');
- }
+ if (!SUPPORTED_DLS.includes(id)) {
+ throw new Error('Unsupported deeplink url path.');
+ }
- let dl;
+ switch (id) {
+ case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
+ dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
+ break;
- switch (id) {
- case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
- dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
- break;
-
- case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
- dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
- break;
-
- case IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid:
- dl = IdentityUpdateRequest.fromWalletDeeplinkUri(urlstring);
- break;
-
- default:
- throw new Error(`Unsupported deeplink ID: ${id}`);
- }
+ case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
+ dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
+ break;
+ case IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid:
+ dl = IdentityUpdateRequest.fromWalletDeeplinkUri(urlstring);
+ break;
+
+ default:
+ throw new Error(`Unsupported deeplink ID: ${urlstring}`);
+ }
+ } else {
+ dl = GenericRequest.fromWalletDeeplinkUri(urlstring);
+ id = DEEPLINK_PROTOCOL_URL_CURRENT_VERSION.toString();
+ }
return api.loginConsentUi.deeplink(
{
From 0a76133c5dc958ebbb7fd1c08468a97664d6d5c7 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 18 Dec 2025 16:14:41 -0800
Subject: [PATCH 47/80] Update verus-typescript-primitives and fix the sending
of the generic request to the consent client plugin.
---
routes/api/dlhandler.js | 28 ++++++++++++----------------
yarn.lock | 4 ++--
2 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 33ea0557..60d90ea1 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -1,24 +1,21 @@
const {
+ GENERIC_REQUEST_DEEPLINK_VDXF_KEY,
+ GenericRequest,
LOGIN_CONSENT_REQUEST_VDXF_KEY,
LoginConsentRequest,
VERUSPAY_INVOICE_VDXF_KEY,
- VerusPayInvoice,
- IDENTITY_UPDATE_REQUEST_VDXF_KEY,
- IdentityUpdateRequest,
- DEEPLINK_PROTOCOL_URL_CURRENT_VERSION,
- GenericRequest
+ VerusPayInvoice
} = require('verus-typescript-primitives');
-const base64url = require("base64url");
-const { ROOT_SYSTEM_NAME } = require('./utils/constants/dev_options');
-const { SUPPORTED_DLS, CALLBACK_HOST } = require('./utils/constants/supported_dls');
+const {ROOT_SYSTEM_NAME} = require('./utils/constants/dev_options');
+const {SUPPORTED_DLS, CALLBACK_HOST} = require('./utils/constants/supported_dls');
module.exports = (api) => {
api.dlhandler = (urlstring) => {
const deeplinkHandler = (urlstring) => {
const url = new URL(urlstring);
- let dl;
let id;
+ let data;
// Handle v1 and v2 requests separately.
if (url.host === CALLBACK_HOST) {
@@ -28,6 +25,7 @@ module.exports = (api) => {
throw new Error('Unsupported deeplink url path.');
}
+ let dl;
switch (id) {
case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
@@ -36,23 +34,21 @@ module.exports = (api) => {
case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
break;
-
- case IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid:
- dl = IdentityUpdateRequest.fromWalletDeeplinkUri(urlstring);
- break;
default:
throw new Error(`Unsupported deeplink ID: ${urlstring}`);
}
+ data = dl.toJson();
} else {
- dl = GenericRequest.fromWalletDeeplinkUri(urlstring);
- id = DEEPLINK_PROTOCOL_URL_CURRENT_VERSION.toString();
+ const req = GenericRequest.fromWalletDeeplinkUri(urlstring);
+ id = GENERIC_REQUEST_DEEPLINK_VDXF_KEY.vdxfid;
+ data = req.toBuffer();
}
return api.loginConsentUi.deeplink(
{
id: id,
- data: dl.toJson()
+ data: data
},
{
id: "VERUS_DESKTOP_MAIN",
diff --git a/yarn.lock b/yarn.lock
index bae535b6..1326c475 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8007,7 +8007,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#68e47b27669fadbbb3fc4de8db944b79d5b167ea"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#68afe0a4a95cff57be07925f7b575658f8063617"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -8037,7 +8037,7 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys":
version "0.1.0"
- resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#d68031949eb8b64c4919c3b2d18d8c1e63a66883"
+ resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#fcd27b5d915005202c84570a0df607b7d126f42d"
dependencies:
axios "1.7.4"
verus-typescript-primitives "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys"
From 8db5662eb56ff65e3c047f1580e5e97bb5af1f5e Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 19 Dec 2025 14:42:40 -0800
Subject: [PATCH 48/80] Fix the sending of the generic request to the login
consent client.
---
routes/api/dlhandler.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 60d90ea1..2fd29812 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -42,7 +42,10 @@ module.exports = (api) => {
} else {
const req = GenericRequest.fromWalletDeeplinkUri(urlstring);
id = GENERIC_REQUEST_DEEPLINK_VDXF_KEY.vdxfid;
- data = req.toBuffer();
+ // Send the request as a QR string so it's properly serialized.
+ // If the buffer is sent directly, the IPC converts it to a JSON object and increases
+ // the size of the payload.
+ data = req.toQrString();
}
return api.loginConsentUi.deeplink(
From f071708c3f7c09d381d11663f7472fff28dbf569 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 8 Jan 2026 15:07:05 -0800
Subject: [PATCH 49/80] Add WIP generic request verification.
---
.../verusid/generic/verifyGenericRequest.js | 85 +++++++++++++++++++
routes/api/native/verusid/verusid.js | 4 +
2 files changed, 89 insertions(+)
create mode 100644 routes/api/native/verusid/generic/verifyGenericRequest.js
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
new file mode 100644
index 00000000..80cb5352
--- /dev/null
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -0,0 +1,85 @@
+const {GenericRequest, GENERIC_REQUEST_VDXF_KEY} = require("verus-typescript-primitives")
+
+// Time difference threshold in seconds (5 minutes)
+const LOGIN_CONSENT_SIG_TIME_DIFF_THRESHOLD = 300;
+
+module.exports = (api) => {
+ /**
+ * Verifies a generic request
+ * TODO: FIX THIS WHEN THE PROBLEM IS UNDERSTOOD
+ * @param {GenericRequest} Request
+ */
+ api.native.verusid.generic.verify_generic_request = async (coin, request) => {
+ console.log("Verifying Generic Request:", request);
+ console.log("Coin", coin);
+ console.log("Identity ID:", request.signature.identityID.address);
+ console.log("Raw Data SHA256:", request.getRawDataSha256(false).toString('hex'))
+ console.log("Signature:", request.signature.signatureAsVch.toString('base64'))
+
+ const verifiableSig = request.signature;
+ const chainIAddr = request.signature.systemID.address;
+
+ // Get signature info to extract block height
+ const sigInfo = api.getSignatureInfo(
+ coin,
+ verifiableSig.systemID.address,
+ verifiableSig.signatureAsVch.toString('base64'),
+ verifiableSig.identityID.address
+ );
+
+ /*
+ // Validate timestamp if present
+ if (request.hasCreatedAt()) {
+ // Get block time from the signature height
+ const blockRes = await api.native.get_block(coin, sigInfo.height.toString());
+
+ if (blockRes.error) {
+ throw new Error(blockRes.error.message);
+ }
+
+ const blocktime = blockRes.result.time;
+
+ // Check if time difference is within threshold
+ if (Math.abs(blocktime - request.createdAt.toNumber()) > LOGIN_CONSENT_SIG_TIME_DIFF_THRESHOLD) {
+ return { verified: false, message: "Signature timestamp outside acceptable range" };
+ }
+ } else {
+ return { verified: false, message: "Missing createdAt timestamp" };
+ }
+ */
+
+ // Verify the hash with identity signature
+ const verified = await api.native.verify_hash(
+ coin,
+ verifiableSig.identityID.address,
+ request.getDetailsIdentitySignatureHash(sigInfo.height).toString('hex'),
+ verifiableSig.signatureAsVch.toString('base64'),
+ );
+
+ return verified ? { verified } : { verified, message: "Failed to verify signature" };
+ };
+
+ api.setPost("/native/verusid/generic/verify_generic_request", async (req, res, next) => {
+ const { chainTicker, request } = req.body;
+ // The request is sent as a QR string to avoid IPC serialization issues.
+ const genericRequest = GenericRequest.fromQrString(request);
+
+ try {
+ res.send(
+ JSON.stringify({
+ msg: "success",
+ result: await api.native.verusid.generic.verify_generic_request(chainTicker, genericRequest),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: "error",
+ result: e.message,
+ })
+ );
+ }
+ });
+
+ return api;
+};
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index b893cc5b..595bc216 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -3,6 +3,7 @@ module.exports = (api) => {
api.native.verusid.login = {}
api.native.verusid.provision = {}
api.native.verusid.identity = {}
+ api.native.verusid.generic = {}
// Identity
require('./identity/verifyIdentityUpdateRequest')(api);
@@ -17,5 +18,8 @@ module.exports = (api) => {
require('./provision/signIdProvisioningRequest')(api);
require('./provision/verifyIdProvisioningResponse')(api);
+ // Generic
+ require('./generic/verifyGenericRequest')(api);
+
return api;
};
From dbdda84b30182b05bc413f847781ea5eb3d37167 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 12 Jan 2026 17:00:41 -0800
Subject: [PATCH 50/80] Fix the generic request verification.
---
.../verusid/generic/verifyGenericRequest.js | 50 ++-----------------
1 file changed, 3 insertions(+), 47 deletions(-)
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
index 80cb5352..fd54b18b 100644
--- a/routes/api/native/verusid/generic/verifyGenericRequest.js
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -1,61 +1,17 @@
const {GenericRequest, GENERIC_REQUEST_VDXF_KEY} = require("verus-typescript-primitives")
-// Time difference threshold in seconds (5 minutes)
-const LOGIN_CONSENT_SIG_TIME_DIFF_THRESHOLD = 300;
-
module.exports = (api) => {
/**
* Verifies a generic request
- * TODO: FIX THIS WHEN THE PROBLEM IS UNDERSTOOD
* @param {GenericRequest} Request
*/
api.native.verusid.generic.verify_generic_request = async (coin, request) => {
- console.log("Verifying Generic Request:", request);
- console.log("Coin", coin);
- console.log("Identity ID:", request.signature.identityID.address);
- console.log("Raw Data SHA256:", request.getRawDataSha256(false).toString('hex'))
- console.log("Signature:", request.signature.signatureAsVch.toString('base64'))
-
- const verifiableSig = request.signature;
- const chainIAddr = request.signature.systemID.address;
-
- // Get signature info to extract block height
- const sigInfo = api.getSignatureInfo(
- coin,
- verifiableSig.systemID.address,
- verifiableSig.signatureAsVch.toString('base64'),
- verifiableSig.identityID.address
- );
-
- /*
- // Validate timestamp if present
- if (request.hasCreatedAt()) {
- // Get block time from the signature height
- const blockRes = await api.native.get_block(coin, sigInfo.height.toString());
-
- if (blockRes.error) {
- throw new Error(blockRes.error.message);
- }
-
- const blocktime = blockRes.result.time;
-
- // Check if time difference is within threshold
- if (Math.abs(blocktime - request.createdAt.toNumber()) > LOGIN_CONSENT_SIG_TIME_DIFF_THRESHOLD) {
- return { verified: false, message: "Signature timestamp outside acceptable range" };
- }
- } else {
- return { verified: false, message: "Missing createdAt timestamp" };
- }
- */
-
- // Verify the hash with identity signature
const verified = await api.native.verify_hash(
coin,
- verifiableSig.identityID.address,
- request.getDetailsIdentitySignatureHash(sigInfo.height).toString('hex'),
- verifiableSig.signatureAsVch.toString('base64'),
+ request.signature.identityID.toIAddress(),
+ request.getRawDataSha256().toString('hex'),
+ request.signature.signatureAsVch.toString('base64'),
);
-
return verified ? { verified } : { verified, message: "Failed to verify signature" };
};
From 15bd02b5706f01c57281844936a1ccaeb18b7d80 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 13 Jan 2026 16:12:21 -0800
Subject: [PATCH 51/80] Upgrade the project to allow for TypeScript.
---
.gitignore | 3 +-
main.js | 11 +-
package.json | 41 +-
.../{dev_options.js => dev_options.ts} | 0
tsconfig.json | 93 +--
yarn.lock | 704 +++++++++++++++---
6 files changed, 653 insertions(+), 199 deletions(-)
rename routes/api/utils/constants/{dev_options.js => dev_options.ts} (100%)
diff --git a/.gitignore b/.gitignore
index 77420203..80287976 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,4 +64,5 @@ __MACOSX
react/package.json
# Build files
-dist/*
\ No newline at end of file
+dist/*
+out/*
\ No newline at end of file
diff --git a/main.js b/main.js
index 7beaae2b..1e0a8a57 100644
--- a/main.js
+++ b/main.js
@@ -39,6 +39,9 @@ if (!hasLock) {
const removelink = require('./routes/deeplink/removelink');
const { APP_NAME, APP_MODE, APP_VERSION } = require('./routes/appBasicInfo');
+ // Project root directory (parent of 'out' when compiled, or current dir in dev)
+ const PROJECT_ROOT = path.resolve(__dirname, '..');
+
const guiapp = express();
//TODO: add more things here
@@ -147,7 +150,7 @@ if (!hasLock) {
res.send("Verus app server");
});
- const guipath = path.join(__dirname, "/gui");
+ const guipath = path.join(PROJECT_ROOT, "gui");
guiapp.use("/gui", express.static(guipath));
guiapp.use("/api", api);
@@ -223,7 +226,7 @@ if (!hasLock) {
appCloseWindow.loadURL(
appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
? `http://127.0.0.1:${appConfig.general.main.agamaPort}/gui/startup/app-closing.html`
- : `file://${__dirname}/gui/startup/app-closing.html`
+ : `file://${PROJECT_ROOT}/gui/startup/app-closing.html`
);
appCloseWindow.webContents.on("did-finish-load", () => {
@@ -397,7 +400,7 @@ if (!hasLock) {
alreadyRunningWindow.loadURL(
appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
? `http://127.0.0.1:${appConfig.general.main.agamaPort}/gui/startup/agama-instance-error.html`
- : `file://${__dirname}/gui/startup/agama-instance-error.html`
+ : `file://${PROJECT_ROOT}/gui/startup/agama-instance-error.html`
);
alreadyRunningWindow.webContents.on("did-finish-load", () => {
@@ -460,7 +463,7 @@ if (!hasLock) {
mainWindow.loadURL(
appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
? "http://localhost:3000"
- : `file://${__dirname}/gui/Verus-Desktop-GUI/react/build/index.html`
+ : `file://${PROJECT_ROOT}/gui/Verus-Desktop-GUI/react/build/index.html`
);
mainWindow.webContents.on("devtools-opened", () => {
diff --git a/package.json b/package.json
index d7896200..f91ba5ad 100644
--- a/package.json
+++ b/package.json
@@ -3,17 +3,18 @@
"productName": "Verus-Desktop",
"version": "1.2.6",
"description": "Verus Desktop Wallet App",
- "main": "main.js",
+ "main": "out/main.js",
"scripts": {
- "start": "cross-env NODE_ENV=development electron .",
+ "build": "tsc && copyfiles -f version.json out/ && copyfiles -u 0 'assets/**/*' out/",
+ "start": "yarn run build && cross-env NODE_ENV=development electron .",
"start:all": "./scripts/prod.sh",
"debug": "yarn start devmode",
"dev:all": "./scripts/dev.sh",
"make-patch": "./make-patch.sh",
"install:all": "./scripts/setup.sh",
- "pack": "cross-env NODE_ENV=production electron-builder --dir verus-unpacked",
- "dist": "cross-env NODE_ENV=production electron-builder --publish=never ",
- "dist-win": "cross-env NODE_ENV=production electron-builder --publish=never --win",
+ "pack": "yarn run build && cross-env NODE_ENV=production electron-builder --dir verus-unpacked",
+ "dist": "yarn run build && cross-env NODE_ENV=production electron-builder --publish=never ",
+ "dist-win": "yarn run build && cross-env NODE_ENV=production electron-builder --publish=never --win",
"dist:all": "./scripts/create-build.sh",
"dist-win:all": "./scripts/create-build-win.sh",
"test": "mocha",
@@ -41,14 +42,6 @@
"url": "https://verus.io"
},
"license": "MIT",
- "devDependencies": {
- "cross-env": "5.2.1",
- "electron": "22.3.25",
- "electron-builder": "24.13.3",
- "electron-devtools-installer": "3.2.0",
- "tslint": "6.1.3",
- "typescript": "4.4.4"
- },
"dependencies": {
"@bitgo/utxo-lib": "git+https://github.com/VerusCoin/BitGoJS.git#utxo-lib-verus",
"@electron/remote": "1.1.0",
@@ -83,7 +76,7 @@
"sha256": "0.2.0",
"socket.io": "4.6.2",
"systeminformation": "5.23.8",
- "tx-builder": "^0.18.0",
+ "tx-builder": "0.18.0",
"unzipper": "0.10.11",
"verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
@@ -91,13 +84,29 @@
"verusd-rpc-ts-client": "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys",
"wif": "2.0.6"
},
+ "devDependencies": {
+ "@types/node": "18.19.0",
+ "copyfiles": "^2.4.1",
+ "cross-env": "5.2.1",
+ "electron": "22.3.25",
+ "electron-builder": "24.13.3",
+ "electron-devtools-installer": "3.2.0",
+ "eslint": "9.16.0",
+ "ts-node": "^10.9.2",
+ "typescript": "5.8.3"
+ },
"optionalDependencies": {
"osx-temperature-sensor": "1.0.8"
},
"build": {
"appId": "Verus",
"files": [
- "**/*",
+ "package.json",
+ "version.json",
+ "out/**/*",
+ "gui/**/*",
+ "keys/**/*",
+ "!**/*.ts",
"!buildscripts",
"!dist",
"!test${/*}",
@@ -169,7 +178,7 @@
"https-proxy-agent": "2.2.4",
"mem": "4.0.0",
"bin-links": "1.1.6",
- "yargs-parser": "13.1.2",
+ "yargs-parser": "21.1.1",
"minimist": "1.2.6",
"decode-uri-component": "0.2.1",
"elliptic": "6.6.1",
diff --git a/routes/api/utils/constants/dev_options.js b/routes/api/utils/constants/dev_options.ts
similarity index 100%
rename from routes/api/utils/constants/dev_options.js
rename to routes/api/utils/constants/dev_options.ts
diff --git a/tsconfig.json b/tsconfig.json
index 194d0d13..456bc0ed 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,72 +1,27 @@
{
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Basic Options */
- // "incremental": true, /* Enable incremental compilation */
- "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
- // "lib": [], /* Specify library files to be included in the compilation. */
- // "allowJs": true, /* Allow javascript files to be compiled. */
- // "checkJs": true, /* Report errors in .js files. */
- // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
- // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
- // "sourceMap": true, /* Generates corresponding '.map' file. */
- // "outFile": "./", /* Concatenate and emit output to single file. */
- // "outDir": "./", /* Redirect output structure to the directory. */
- // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
- // "composite": true, /* Enable project compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
-
- /* Strict Type-Checking Options */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* Enable strict null checks. */
- // "strictFunctionTypes": true, /* Enable strict checking of function types. */
- // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
- // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
- // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
-
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
-
- /* Module Resolution Options */
- // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- // "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
-
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
-
- /* Advanced Options */
- "skipLibCheck": true, /* Skip type checking of declaration files. */
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
- }
+ "target": "es5",
+ "module": "commonjs",
+ "allowJs": true,
+ "checkJs": false,
+ "outDir": "./out",
+ "rootDir": "./",
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true
+ },
+ "include": [
+ "main.js",
+ "routes/**/*",
+ "private/**/*",
+ "keys/**/*",
+ "assets/js/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "gui",
+ "dist",
+ "out"
+ ]
}
diff --git a/yarn.lock b/yarn.lock
index 1326c475..671d68d8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12,27 +12,6 @@
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069"
integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==
-"@babel/code-frame@^7.0.0":
- version "7.16.0"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
- integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
- dependencies:
- "@babel/highlight" "^7.16.0"
-
-"@babel/helper-validator-identifier@^7.15.7":
- version "7.15.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
- integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
-
-"@babel/highlight@^7.16.0":
- version "7.16.0"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
- integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
- dependencies:
- "@babel/helper-validator-identifier" "^7.15.7"
- chalk "^2.0.0"
- js-tokens "^4.0.0"
-
"@bitgo/blake2b-wasm@^3.0.1":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@bitgo/blake2b-wasm/-/blake2b-wasm-3.2.3.tgz#6ae5e942f2a5fd5b3ed27103af5df0ed50adfbc9"
@@ -73,6 +52,13 @@
verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
wif "2.0.1"
+"@cspotcode/source-map-support@^0.8.0":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
+ integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
+ dependencies:
+ "@jridgewell/trace-mapping" "0.3.9"
+
"@develar/schema-utils@~2.6.5":
version "2.6.5"
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6"
@@ -144,6 +130,74 @@
minimatch "^3.0.4"
plist "^3.0.4"
+"@eslint-community/eslint-utils@^4.2.0":
+ version "4.9.1"
+ resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595"
+ integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==
+ dependencies:
+ eslint-visitor-keys "^3.4.3"
+
+"@eslint-community/regexpp@^4.12.1":
+ version "4.12.2"
+ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b"
+ integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==
+
+"@eslint/config-array@^0.19.0":
+ version "0.19.2"
+ resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa"
+ integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
+ dependencies:
+ "@eslint/object-schema" "^2.1.6"
+ debug "^4.3.1"
+ minimatch "^3.1.2"
+
+"@eslint/core@^0.13.0":
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.13.0.tgz#bf02f209846d3bf996f9e8009db62df2739b458c"
+ integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==
+ dependencies:
+ "@types/json-schema" "^7.0.15"
+
+"@eslint/core@^0.9.0":
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1"
+ integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==
+ dependencies:
+ "@types/json-schema" "^7.0.15"
+
+"@eslint/eslintrc@^3.2.0":
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz#26393a0806501b5e2b6a43aa588a4d8df67880ac"
+ integrity sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==
+ dependencies:
+ ajv "^6.12.4"
+ debug "^4.3.2"
+ espree "^10.0.1"
+ globals "^14.0.0"
+ ignore "^5.2.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.1"
+ minimatch "^3.1.2"
+ strip-json-comments "^3.1.1"
+
+"@eslint/js@9.16.0":
+ version "9.16.0"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4"
+ integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==
+
+"@eslint/object-schema@^2.1.6":
+ version "2.1.7"
+ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad"
+ integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==
+
+"@eslint/plugin-kit@^0.2.3":
+ version "0.2.8"
+ resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz#47488d8f8171b5d4613e833313f3ce708e3525f8"
+ integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==
+ dependencies:
+ "@eslint/core" "^0.13.0"
+ levn "^0.4.1"
+
"@ethereumjs/common@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268"
@@ -772,6 +826,29 @@
"@ethersproject/properties" "^5.1.0"
"@ethersproject/strings" "^5.1.0"
+"@humanfs/core@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
+ integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==
+
+"@humanfs/node@^0.16.6":
+ version "0.16.7"
+ resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.7.tgz#822cb7b3a12c5a240a24f621b5a2413e27a45f26"
+ integrity sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==
+ dependencies:
+ "@humanfs/core" "^0.19.1"
+ "@humanwhocodes/retry" "^0.4.0"
+
+"@humanwhocodes/module-importer@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
+"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.1":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
+ integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
+
"@iarna/cli@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641"
@@ -793,6 +870,24 @@
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
+"@jridgewell/resolve-uri@^3.0.3":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
+ integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
+
+"@jridgewell/trace-mapping@0.3.9":
+ version "0.3.9"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
+ integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.0.3"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@@ -861,6 +956,26 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
+"@tsconfig/node10@^1.0.7":
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4"
+ integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==
+
+"@tsconfig/node12@^1.0.7":
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
+ integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
+
+"@tsconfig/node14@^1.0.0":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
+ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
+
+"@tsconfig/node16@^1.0.2":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
+ integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
+
"@types/bn.js@^4.11.3":
version "4.11.6"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
@@ -914,6 +1029,11 @@
dependencies:
"@types/ms" "*"
+"@types/estree@^1.0.6":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
+ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
+
"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.11":
version "9.0.13"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45"
@@ -931,6 +1051,11 @@
resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64"
integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==
+"@types/json-schema@^7.0.15":
+ version "7.0.15"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
+ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
+
"@types/keyv@*":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
@@ -953,6 +1078,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
+"@types/node@18.19.0":
+ version "18.19.0"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.0.tgz#e86ce256c46661016fa83360bf8738eb4efdc88c"
+ integrity sha512-667KNhaD7U29mT5wf+TZUnrzPrlL2GNQ5N0BMjO2oNULhBxX0/FKCkm6JMu0Jh7Z+1LwUlR21ekd7KhIboNFNw==
+ dependencies:
+ undici-types "~5.26.4"
+
"@types/node@22.7.5":
version "22.7.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
@@ -1060,6 +1192,23 @@ accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
+acorn-jsx@^5.3.2:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn-walk@^8.1.1:
+ version "8.3.4"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7"
+ integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==
+ dependencies:
+ acorn "^8.11.0"
+
+acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1:
+ version "8.15.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
+ integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+
aes-js@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d"
@@ -1130,7 +1279,7 @@ ajv-keywords@^3.4.1:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
-ajv@6.12.3, ajv@^5.1.0, ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.3, ajv@^6.5.5:
+ajv@6.12.3, ajv@^5.1.0, ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.5.5:
version "6.12.3"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
@@ -1248,6 +1397,11 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
+arg@^4.1.0:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
+ integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -1849,11 +2003,6 @@ builder-util@24.13.1:
stat-mode "^1.0.0"
temp-file "^3.4.0"
-builtin-modules@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
- integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
-
builtins@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
@@ -1986,16 +2135,16 @@ call-limit@^1.1.1:
resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==
+callsites@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
+ integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+
camelcase@^4.0.0, camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
-camelcase@^5.0.0:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
- integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@@ -2008,7 +2157,7 @@ chainsaw@~0.1.0:
dependencies:
traverse ">=0.3.0 <0.4"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0:
+chalk@^2.0.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -2017,7 +2166,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@^4.0.2, chalk@^4.1.2:
+chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -2135,6 +2284,15 @@ cliui@^5.0.0:
strip-ansi "^5.2.0"
wrap-ansi "^5.1.0"
+cliui@^7.0.2:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
+ integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^7.0.0"
+
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
@@ -2222,11 +2380,6 @@ combined-stream@^1.0.8, combined-stream@~1.0.5, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.12.1:
- version "2.20.3"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
- integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-
commander@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
@@ -2356,6 +2509,19 @@ copy-concurrently@^1.0.0:
rimraf "^2.5.4"
run-queue "^1.0.0"
+copyfiles@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
+ integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
+ dependencies:
+ glob "^7.0.5"
+ minimatch "^3.0.3"
+ mkdirp "^1.0.4"
+ noms "0.0.0"
+ through2 "^2.0.1"
+ untildify "^4.0.0"
+ yargs "^16.1.0"
+
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -2441,6 +2607,11 @@ create-hmac@^1.1.3, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+create-require@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
+ integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+
cross-env@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d"
@@ -2492,6 +2663,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
+cross-spawn@^7.0.5:
+ version "7.0.6"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
+ integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
crypto-js@4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
@@ -2527,7 +2707,7 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
-debug@2.6.9, debug@3.1.0, debug@4, debug@^2.2.0, debug@^3.1.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@~3.1.0, debug@~4.3.1, debug@~4.3.2:
+debug@2.6.9, debug@3.1.0, debug@4, debug@^2.2.0, debug@^3.1.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~3.1.0, debug@~4.3.1, debug@~4.3.2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2568,6 +2748,11 @@ deep-extend@^0.6.0:
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
+deep-is@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+
default-shell@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc"
@@ -3097,11 +3282,102 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+eslint-scope@^8.2.0:
+ version "8.4.0"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82"
+ integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^5.2.0"
+
+eslint-visitor-keys@^3.4.3:
+ version "3.4.3"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
+ integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
+
+eslint-visitor-keys@^4.2.0, eslint-visitor-keys@^4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
+ integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
+
+eslint@9.16.0:
+ version "9.16.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6"
+ integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.2.0"
+ "@eslint-community/regexpp" "^4.12.1"
+ "@eslint/config-array" "^0.19.0"
+ "@eslint/core" "^0.9.0"
+ "@eslint/eslintrc" "^3.2.0"
+ "@eslint/js" "9.16.0"
+ "@eslint/plugin-kit" "^0.2.3"
+ "@humanfs/node" "^0.16.6"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "@humanwhocodes/retry" "^0.4.1"
+ "@types/estree" "^1.0.6"
+ "@types/json-schema" "^7.0.15"
+ ajv "^6.12.4"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.5"
+ debug "^4.3.2"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^8.2.0"
+ eslint-visitor-keys "^4.2.0"
+ espree "^10.3.0"
+ esquery "^1.5.0"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^8.0.0"
+ find-up "^5.0.0"
+ glob-parent "^6.0.2"
+ ignore "^5.2.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
+ natural-compare "^1.4.0"
+ optionator "^0.9.3"
+
+espree@^10.0.1, espree@^10.3.0:
+ version "10.4.0"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837"
+ integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==
+ dependencies:
+ acorn "^8.15.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^4.2.1"
+
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+esquery@^1.5.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d"
+ integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==
+ dependencies:
+ estraverse "^5.1.0"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^5.1.0, estraverse@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@@ -3418,11 +3694,21 @@ fast-deep-equal@^3.1.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
+fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
+fast-levenshtein@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+ integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
+
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@@ -3435,6 +3721,13 @@ figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
+file-entry-cache@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
+ integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
+ dependencies:
+ flat-cache "^4.0.0"
+
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@@ -3479,6 +3772,14 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"
+find-up@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+ integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+ dependencies:
+ locate-path "^6.0.0"
+ path-exists "^4.0.0"
+
fix-path@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fix-path/-/fix-path-2.1.0.tgz#72ece739de9af4bd63fd02da23e9a70c619b4c38"
@@ -3486,6 +3787,19 @@ fix-path@2.1.0:
dependencies:
shell-path "^2.0.0"
+flat-cache@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
+ integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
+ dependencies:
+ flatted "^3.2.9"
+ keyv "^4.5.4"
+
+flatted@^3.2.9:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358"
+ integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==
+
flush-write-stream@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@@ -3832,6 +4146,13 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
+glob-parent@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
glob@^10.3.10:
version "10.3.10"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
@@ -3843,6 +4164,18 @@ glob@^10.3.10:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
+glob@^7.0.5:
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+ integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.1.1"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
glob@^7.1.1, glob@^7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
@@ -3894,6 +4227,11 @@ global@~4.4.0:
min-document "^2.19.0"
process "^0.11.10"
+globals@^14.0.0:
+ version "14.0.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
+ integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
+
globalthis@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9"
@@ -4228,11 +4566,24 @@ ignore-walk@^3.0.1:
dependencies:
minimatch "^3.0.4"
+ignore@^5.2.0:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
+ integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
+
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
+import-fresh@^3.2.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf"
+ integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==
+ dependencies:
+ parent-module "^1.0.0"
+ resolve-from "^4.0.0"
+
import-lazy@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
@@ -4397,18 +4748,16 @@ is-cidr@^3.0.0:
dependencies:
cidr-regex "^2.0.10"
-is-core-module@^2.2.0:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
- integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
- dependencies:
- has "^1.0.3"
-
is-date-object@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
+is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -4438,6 +4787,13 @@ is-generator-function@^1.0.7:
dependencies:
has-tostringtag "^1.0.0"
+is-glob@^4.0.0, is-glob@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
is-hex-prefixed@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554"
@@ -4644,12 +5000,7 @@ js-sha3@^0.7.0:
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a"
integrity sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==
-js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-js-yaml@3.13.1, js-yaml@^3.13.1, js-yaml@^4.1.0:
+js-yaml@3.13.1, js-yaml@^4.1.0, js-yaml@^4.1.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@@ -4687,6 +5038,11 @@ json-schema@0.2.3, json-schema@0.4.0:
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+ integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
+
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
@@ -4754,6 +5110,13 @@ keyv@^4.0.0:
compress-brotli "^1.3.8"
json-buffer "3.0.1"
+keyv@^4.5.4:
+ version "4.5.4"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
+ integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
+ dependencies:
+ json-buffer "3.0.1"
+
latest-version@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
@@ -4783,6 +5146,14 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
+levn@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+ integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+ dependencies:
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
+
libcipm@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89"
@@ -4955,6 +5326,13 @@ locate-path@^3.0.0:
p-locate "^3.0.0"
path-exists "^3.0.0"
+locate-path@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+ integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+ dependencies:
+ p-locate "^5.0.0"
+
lock-verify@^2.0.2, lock-verify@^2.1.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1"
@@ -4999,6 +5377,11 @@ lodash.isfinite@^3.3.2:
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
lodash.union@~4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
@@ -5063,6 +5446,11 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
+make-error@^1.1.1:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
+ integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+
make-fetch-happen@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz#a8e3fe41d3415dd656fe7b8e8172e1fb4458b38d"
@@ -5203,7 +5591,7 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-minimatch@5.1.0, minimatch@^3.0.4, minimatch@^5.1.1, minimatch@^9.0.1:
+minimatch@5.1.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@^5.1.1, minimatch@^9.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
@@ -5273,12 +5661,12 @@ mkdirp-promise@^5.0.1:
dependencies:
mkdirp "*"
-mkdirp@*:
+mkdirp@*, mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
-"mkdirp@>=0.5 0", mkdirp@^0.5.3, mkdirp@^0.5.5:
+"mkdirp@>=0.5 0", mkdirp@^0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -5399,6 +5787,11 @@ nanoassert@^2.0.0:
resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09"
integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+ integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
+
negotiator@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@@ -5484,6 +5877,14 @@ nodejs-aes256@1.0.1, nodejs-aes256@^1.0.1:
resolved "https://registry.yarnpkg.com/nodejs-aes256/-/nodejs-aes256-1.0.1.tgz#bb68cb3f3591c2888c1a136e9667cc1a8ee15448"
integrity sha1-u2jLPzWRwoiMGhNulmfMGo7hVEg=
+noms@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"
+ integrity sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "~1.0.31"
+
nopt@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
@@ -5868,6 +6269,18 @@ opener@^1.5.2:
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
+optionator@^0.9.3:
+ version "0.9.4"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
+ integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==
+ dependencies:
+ deep-is "^0.1.3"
+ fast-levenshtein "^2.0.6"
+ levn "^0.4.1"
+ prelude-ls "^1.2.1"
+ type-check "^0.4.0"
+ word-wrap "^1.2.5"
+
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
@@ -5934,6 +6347,13 @@ p-limit@^2.0.0:
dependencies:
p-try "^2.0.0"
+p-limit@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+ dependencies:
+ yocto-queue "^0.1.0"
+
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@@ -5948,6 +6368,13 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
+p-locate@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+ integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+ dependencies:
+ p-limit "^3.0.2"
+
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -6018,6 +6445,13 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"
+parent-module@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
+ integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+ dependencies:
+ callsites "^3.0.0"
+
parse-headers@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
@@ -6048,6 +6482,11 @@ path-exists@^3.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
@@ -6167,6 +6606,11 @@ possible-typed-array-names@^1.0.0:
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
+prelude-ls@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+ integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
pretty-bytes@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.1.0.tgz#6237ecfbdc6525beaef4de722cc60a58ae0e6c6d"
@@ -6516,6 +6960,16 @@ readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
+readable-stream@~1.0.31:
+ version "1.0.34"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
readable-stream@~1.1.10:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
@@ -6685,14 +7139,6 @@ resolve@^1.10.0:
dependencies:
path-parse "^1.0.6"
-resolve@^1.3.2:
- version "1.20.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
- integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
- dependencies:
- is-core-module "^2.2.0"
- path-parse "^1.0.6"
-
responselike@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
@@ -6851,7 +7297,7 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
-"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.3:
+"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.3:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
@@ -7427,6 +7873,11 @@ strip-hex-prefix@1.0.0:
dependencies:
is-hex-prefixed "1.0.0"
+strip-json-comments@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+ integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -7508,7 +7959,7 @@ text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-through2@^2.0.0:
+through2@^2.0.0, through2@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
@@ -7597,47 +8048,35 @@ truncate-utf8-bytes@^1.0.0:
dependencies:
utf8-byte-length "^1.0.1"
+ts-node@^10.9.2:
+ version "10.9.2"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f"
+ integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==
+ dependencies:
+ "@cspotcode/source-map-support" "^0.8.0"
+ "@tsconfig/node10" "^1.0.7"
+ "@tsconfig/node12" "^1.0.7"
+ "@tsconfig/node14" "^1.0.0"
+ "@tsconfig/node16" "^1.0.2"
+ acorn "^8.4.1"
+ acorn-walk "^8.1.1"
+ arg "^4.1.0"
+ create-require "^1.1.0"
+ diff "^4.0.1"
+ make-error "^1.1.1"
+ v8-compile-cache-lib "^3.0.1"
+ yn "3.1.1"
+
tslib@2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
-tslib@^1.13.0, tslib@^1.8.1:
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
- integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-
tslib@^2.1.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
-tslint@6.1.3:
- version "6.1.3"
- resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904"
- integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- builtin-modules "^1.1.1"
- chalk "^2.3.0"
- commander "^2.12.1"
- diff "^4.0.1"
- glob "^7.1.1"
- js-yaml "^3.13.1"
- minimatch "^3.0.4"
- mkdirp "^0.5.3"
- resolve "^1.3.2"
- semver "^5.3.0"
- tslib "^1.13.0"
- tsutils "^2.29.0"
-
-tsutils@^2.29.0:
- version "2.29.0"
- resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
- integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
- dependencies:
- tslib "^1.8.1"
-
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -7650,7 +8089,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-tx-builder@^0.18.0:
+tx-builder@0.18.0, tx-builder@^0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/tx-builder/-/tx-builder-0.18.0.tgz#efa063790020a5fea63056bad0f44ef0b03d6fa4"
integrity sha512-pr6v2JNdT2KXcZm1vaPgSLg5//wrXlYTY+Tw+6O0hEL1f+cH20cmWooTop2DLWikPBN/qnrUiUzxVIRrYkDpYQ==
@@ -7667,6 +8106,13 @@ tx-builder@^0.18.0:
typeforce "^1.11.1"
varuint-bitcoin "^1.0.4"
+type-check@^0.4.0, type-check@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+ integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+ dependencies:
+ prelude-ls "^1.2.1"
+
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
@@ -7722,10 +8168,10 @@ typeforce@^1.11.1, typeforce@^1.11.3, typeforce@^1.11.5, "typeforce@git+https://
version "1.18.0"
resolved "git+https://github.com/michaeltout/typeforce#c9b0abc33ff006d7a6a6150eff034bc7eb8b07de"
-typescript@4.4.4:
- version "4.4.4"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
- integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
+typescript@5.8.3:
+ version "5.8.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
+ integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
typescript@^5.3.3:
version "5.4.2"
@@ -7752,6 +8198,11 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
+undici-types@~5.26.4:
+ version "5.26.5"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
+ integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
+
undici-types@~6.19.2:
version "6.19.8"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
@@ -7808,6 +8259,11 @@ unpipe@1.0.0, unpipe@~1.0.0:
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
+untildify@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
+ integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+
unzip-crx-3@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz#d5324147b104a8aed9ae8639c95521f6f7cda292"
@@ -7939,6 +8395,11 @@ uuid@^9.0.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
+v8-compile-cache-lib@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
+ integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
+
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -8386,6 +8847,11 @@ wif@2.0.6, wif@^2.0.1, wif@^2.0.6:
dependencies:
bs58check "<3.0.0"
+word-wrap@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
+ integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
+
worker-farm@^1.6.0, worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
@@ -8541,13 +9007,10 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yargs-parser@13.1.2, yargs-parser@^15.0.1, yargs-parser@^21.1.1, yargs-parser@^7.0.0:
- version "13.1.2"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
- integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
+yargs-parser@21.1.1, yargs-parser@^15.0.1, yargs-parser@^20.2.2, yargs-parser@^21.1.1, yargs-parser@^7.0.0:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^14.2.3:
version "14.2.3"
@@ -8566,6 +9029,19 @@ yargs@^14.2.3:
y18n "^4.0.0"
yargs-parser "^15.0.1"
+yargs@^16.1.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+ integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+ dependencies:
+ cliui "^7.0.2"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.0"
+ y18n "^5.0.5"
+ yargs-parser "^20.2.2"
+
yargs@^17.6.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
@@ -8605,3 +9081,13 @@ yauzl@^2.10.0:
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
+
+yn@3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
+ integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
+
+yocto-queue@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+ integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
From 563923b7e2629fd8df48c85b75f48a05fcaef52a Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 13 Jan 2026 16:27:59 -0800
Subject: [PATCH 52/80] Setup the project with eslint.
---
eslint.config.mjs | 28 ++
package.json | 11 +-
tslint.json | 11 -
yarn.lock | 1202 ++++++++++++++++++++++++++++++++++++++-------
4 files changed, 1073 insertions(+), 179 deletions(-)
create mode 100644 eslint.config.mjs
delete mode 100644 tslint.json
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 00000000..80669df5
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,28 @@
+import js from "@eslint/js";
+import globals from "globals";
+import tseslint from "typescript-eslint";
+import pluginReact from "eslint-plugin-react";
+import { defineConfig } from "eslint/config";
+
+export default defineConfig([
+ {
+ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
+ plugins: { js },
+ extends: ["js/recommended"],
+ languageOptions: {
+ globals: { ...globals.browser, ...globals.node },
+ },
+ },
+ {
+ files: ["**/*.js"],
+ languageOptions: { sourceType: "commonjs" },
+ },
+ tseslint.configs.recommended,
+ pluginReact.configs.flat.recommended,
+ {
+ files: ["**/*.js"],
+ rules: {
+ "@typescript-eslint/no-require-imports": "off",
+ },
+ },
+]);
diff --git a/package.json b/package.json
index f91ba5ad..4878b7c4 100644
--- a/package.json
+++ b/package.json
@@ -85,15 +85,18 @@
"wif": "2.0.6"
},
"devDependencies": {
+ "@eslint/js": "9.39.2",
"@types/node": "18.19.0",
- "copyfiles": "^2.4.1",
+ "copyfiles": "2.4.1",
"cross-env": "5.2.1",
"electron": "22.3.25",
"electron-builder": "24.13.3",
"electron-devtools-installer": "3.2.0",
- "eslint": "9.16.0",
- "ts-node": "^10.9.2",
- "typescript": "5.8.3"
+ "eslint": "9.39.2",
+ "eslint-plugin-react": "7.37.5",
+ "globals": "17.0.0",
+ "typescript": "5.8.3",
+ "typescript-eslint": "8.53.0"
},
"optionalDependencies": {
"osx-temperature-sensor": "1.0.8"
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index 0a27bf74..00000000
--- a/tslint.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "defaultSeverity": "error",
- "extends": [
- "tslint:recommended"
- ],
- "jsRules": {},
- "rules": {
- "no-console": false
- },
- "rulesDirectory": []
-}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 671d68d8..a5117174 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -52,13 +52,6 @@
verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
wif "2.0.1"
-"@cspotcode/source-map-support@^0.8.0":
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
- integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
- dependencies:
- "@jridgewell/trace-mapping" "0.3.9"
-
"@develar/schema-utils@~2.6.5":
version "2.6.5"
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6"
@@ -130,42 +123,42 @@
minimatch "^3.0.4"
plist "^3.0.4"
-"@eslint-community/eslint-utils@^4.2.0":
+"@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1":
version "4.9.1"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595"
integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==
dependencies:
eslint-visitor-keys "^3.4.3"
-"@eslint-community/regexpp@^4.12.1":
+"@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.12.2":
version "4.12.2"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b"
integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==
-"@eslint/config-array@^0.19.0":
- version "0.19.2"
- resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa"
- integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
+"@eslint/config-array@^0.21.1":
+ version "0.21.1"
+ resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.1.tgz#7d1b0060fea407f8301e932492ba8c18aff29713"
+ integrity sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==
dependencies:
- "@eslint/object-schema" "^2.1.6"
+ "@eslint/object-schema" "^2.1.7"
debug "^4.3.1"
minimatch "^3.1.2"
-"@eslint/core@^0.13.0":
- version "0.13.0"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.13.0.tgz#bf02f209846d3bf996f9e8009db62df2739b458c"
- integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==
+"@eslint/config-helpers@^0.4.2":
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda"
+ integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==
dependencies:
- "@types/json-schema" "^7.0.15"
+ "@eslint/core" "^0.17.0"
-"@eslint/core@^0.9.0":
- version "0.9.1"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1"
- integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==
+"@eslint/core@^0.17.0":
+ version "0.17.0"
+ resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c"
+ integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==
dependencies:
"@types/json-schema" "^7.0.15"
-"@eslint/eslintrc@^3.2.0":
+"@eslint/eslintrc@^3.3.1":
version "3.3.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz#26393a0806501b5e2b6a43aa588a4d8df67880ac"
integrity sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==
@@ -180,22 +173,22 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@9.16.0":
- version "9.16.0"
- resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4"
- integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==
+"@eslint/js@9.39.2", "@eslint/js@^9.39.2":
+ version "9.39.2"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.2.tgz#2d4b8ec4c3ea13c1b3748e0c97ecd766bdd80599"
+ integrity sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==
-"@eslint/object-schema@^2.1.6":
+"@eslint/object-schema@^2.1.7":
version "2.1.7"
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad"
integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==
-"@eslint/plugin-kit@^0.2.3":
- version "0.2.8"
- resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz#47488d8f8171b5d4613e833313f3ce708e3525f8"
- integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==
+"@eslint/plugin-kit@^0.4.1":
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2"
+ integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==
dependencies:
- "@eslint/core" "^0.13.0"
+ "@eslint/core" "^0.17.0"
levn "^0.4.1"
"@ethereumjs/common@2.5.0":
@@ -844,7 +837,7 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
-"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.1":
+"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2":
version "0.4.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
@@ -870,24 +863,6 @@
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
-"@jridgewell/resolve-uri@^3.0.3":
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
- integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
-
-"@jridgewell/sourcemap-codec@^1.4.10":
- version "1.5.5"
- resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
- integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
-
-"@jridgewell/trace-mapping@0.3.9":
- version "0.3.9"
- resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
- integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
- dependencies:
- "@jridgewell/resolve-uri" "^3.0.3"
- "@jridgewell/sourcemap-codec" "^1.4.10"
-
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@@ -956,26 +931,6 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
-"@tsconfig/node10@^1.0.7":
- version "1.0.12"
- resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4"
- integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==
-
-"@tsconfig/node12@^1.0.7":
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
- integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
-
-"@tsconfig/node14@^1.0.0":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
- integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
-
-"@tsconfig/node16@^1.0.2":
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
- integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
-
"@types/bn.js@^4.11.3":
version "4.11.6"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
@@ -1148,6 +1103,102 @@
dependencies:
"@types/node" "*"
+"@typescript-eslint/eslint-plugin@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz#afb966c66a2fdc6158cf81118204a971a36d0fc5"
+ integrity sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==
+ dependencies:
+ "@eslint-community/regexpp" "^4.12.2"
+ "@typescript-eslint/scope-manager" "8.53.0"
+ "@typescript-eslint/type-utils" "8.53.0"
+ "@typescript-eslint/utils" "8.53.0"
+ "@typescript-eslint/visitor-keys" "8.53.0"
+ ignore "^7.0.5"
+ natural-compare "^1.4.0"
+ ts-api-utils "^2.4.0"
+
+"@typescript-eslint/parser@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.53.0.tgz#d8bed6f12dc74e03751e5f947510ff2b165990c6"
+ integrity sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==
+ dependencies:
+ "@typescript-eslint/scope-manager" "8.53.0"
+ "@typescript-eslint/types" "8.53.0"
+ "@typescript-eslint/typescript-estree" "8.53.0"
+ "@typescript-eslint/visitor-keys" "8.53.0"
+ debug "^4.4.3"
+
+"@typescript-eslint/project-service@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.53.0.tgz#327c67c61c16a1c8b12a440b0779b41eb77cc7df"
+ integrity sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==
+ dependencies:
+ "@typescript-eslint/tsconfig-utils" "^8.53.0"
+ "@typescript-eslint/types" "^8.53.0"
+ debug "^4.4.3"
+
+"@typescript-eslint/scope-manager@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz#f922fcbf0d42e72f065297af31779ccf19de9a97"
+ integrity sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==
+ dependencies:
+ "@typescript-eslint/types" "8.53.0"
+ "@typescript-eslint/visitor-keys" "8.53.0"
+
+"@typescript-eslint/tsconfig-utils@8.53.0", "@typescript-eslint/tsconfig-utils@^8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz#105279d7969a7abdc8345cc9c57cff83cf910f8f"
+ integrity sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==
+
+"@typescript-eslint/type-utils@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz#81a0de5c01fc68f6df0591d03cd8226bda01c91f"
+ integrity sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==
+ dependencies:
+ "@typescript-eslint/types" "8.53.0"
+ "@typescript-eslint/typescript-estree" "8.53.0"
+ "@typescript-eslint/utils" "8.53.0"
+ debug "^4.4.3"
+ ts-api-utils "^2.4.0"
+
+"@typescript-eslint/types@8.53.0", "@typescript-eslint/types@^8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.53.0.tgz#1adcad3fa32bc2c4cbf3785ba07a5e3151819efb"
+ integrity sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==
+
+"@typescript-eslint/typescript-estree@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz#7805b46b7a8ce97e91b7bb56fc8b1ba26ca8ef52"
+ integrity sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==
+ dependencies:
+ "@typescript-eslint/project-service" "8.53.0"
+ "@typescript-eslint/tsconfig-utils" "8.53.0"
+ "@typescript-eslint/types" "8.53.0"
+ "@typescript-eslint/visitor-keys" "8.53.0"
+ debug "^4.4.3"
+ minimatch "^9.0.5"
+ semver "^7.7.3"
+ tinyglobby "^0.2.15"
+ ts-api-utils "^2.4.0"
+
+"@typescript-eslint/utils@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.53.0.tgz#bf0a4e2edaf1afc9abce209fc02f8cab0b74af13"
+ integrity sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.9.1"
+ "@typescript-eslint/scope-manager" "8.53.0"
+ "@typescript-eslint/types" "8.53.0"
+ "@typescript-eslint/typescript-estree" "8.53.0"
+
+"@typescript-eslint/visitor-keys@8.53.0":
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz#9a785664ddae7e3f7e570ad8166e48dbc9c6cf02"
+ integrity sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==
+ dependencies:
+ "@typescript-eslint/types" "8.53.0"
+ eslint-visitor-keys "^4.2.1"
+
"@xmldom/xmldom@0.8.4":
version "0.8.4"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.4.tgz#05b76034d3e09d4b9d309d9b862994de23e7687d"
@@ -1197,14 +1248,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-acorn-walk@^8.1.1:
- version "8.3.4"
- resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7"
- integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==
- dependencies:
- acorn "^8.11.0"
-
-acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1:
+acorn@^8.15.0:
version "8.15.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
@@ -1397,11 +1441,6 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
-arg@^4.1.0:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
- integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
-
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -1409,11 +1448,89 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b"
+ integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==
+ dependencies:
+ call-bound "^1.0.3"
+ is-array-buffer "^3.0.5"
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
+array-includes@^3.1.6, array-includes@^3.1.8:
+ version "3.1.9"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a"
+ integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.4"
+ define-properties "^1.2.1"
+ es-abstract "^1.24.0"
+ es-object-atoms "^1.1.1"
+ get-intrinsic "^1.3.0"
+ is-string "^1.1.1"
+ math-intrinsics "^1.1.0"
+
+array.prototype.findlast@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904"
+ integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==
+ dependencies:
+ call-bind "^1.0.7"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.2"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.0.0"
+ es-shim-unscopables "^1.0.2"
+
+array.prototype.flat@^1.3.1:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5"
+ integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==
+ dependencies:
+ call-bind "^1.0.8"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.5"
+ es-shim-unscopables "^1.0.2"
+
+array.prototype.flatmap@^1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b"
+ integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==
+ dependencies:
+ call-bind "^1.0.8"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.5"
+ es-shim-unscopables "^1.0.2"
+
+array.prototype.tosorted@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc"
+ integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==
+ dependencies:
+ call-bind "^1.0.7"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.3"
+ es-errors "^1.3.0"
+ es-shim-unscopables "^1.0.2"
+
+arraybuffer.prototype.slice@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c"
+ integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==
+ dependencies:
+ array-buffer-byte-length "^1.0.1"
+ call-bind "^1.0.8"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.5"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.6"
+ is-array-buffer "^3.0.4"
+
asap@^2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
@@ -1441,6 +1558,11 @@ async-exit-hook@^2.0.1:
resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3"
integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==
+async-function@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b"
+ integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==
+
async@2.6.4, async@^2.6.0, async@^2.6.1, async@^3.2.3, async@^3.2.4:
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
@@ -2112,7 +2234,7 @@ call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
-call-bind@^1.0.8:
+call-bind@^1.0.7, call-bind@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
@@ -2122,7 +2244,7 @@ call-bind@^1.0.8:
get-intrinsic "^1.2.4"
set-function-length "^1.2.2"
-call-bound@^1.0.3, call-bound@^1.0.4:
+call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a"
integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
@@ -2509,7 +2631,7 @@ copy-concurrently@^1.0.0:
rimraf "^2.5.4"
run-queue "^1.0.0"
-copyfiles@^2.4.1:
+copyfiles@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
@@ -2607,11 +2729,6 @@ create-hmac@^1.1.3, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-create-require@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
- integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
-
cross-env@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d"
@@ -2663,7 +2780,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
-cross-spawn@^7.0.5:
+cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
@@ -2707,7 +2824,34 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
-debug@2.6.9, debug@3.1.0, debug@4, debug@^2.2.0, debug@^3.1.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~3.1.0, debug@~4.3.1, debug@~4.3.2:
+data-view-buffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570"
+ integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==
+ dependencies:
+ call-bound "^1.0.3"
+ es-errors "^1.3.0"
+ is-data-view "^1.0.2"
+
+data-view-byte-length@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz#9e80f7ca52453ce3e93d25a35318767ea7704735"
+ integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==
+ dependencies:
+ call-bound "^1.0.3"
+ es-errors "^1.3.0"
+ is-data-view "^1.0.2"
+
+data-view-byte-offset@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz#068307f9b71ab76dbbe10291389e020856606191"
+ integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==
+ dependencies:
+ call-bound "^1.0.2"
+ es-errors "^1.3.0"
+ is-data-view "^1.0.1"
+
+debug@2.6.9, debug@3.1.0, debug@4, debug@^2.2.0, debug@^3.1.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.3, debug@~3.1.0, debug@~4.3.1, debug@~4.3.2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2770,7 +2914,7 @@ defer-to-connect@^2.0.0:
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
-define-data-property@^1.1.4:
+define-data-property@^1.0.1, define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
@@ -2794,6 +2938,15 @@ define-properties@^1.1.4:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
+define-properties@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
+ integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
+ dependencies:
+ define-data-property "^1.0.1"
+ has-property-descriptors "^1.0.0"
+ object-keys "^1.1.1"
+
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -2842,11 +2995,6 @@ dezalgo@^1.0.0, dezalgo@~1.0.3:
asap "^2.0.0"
wrappy "1"
-diff@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
- integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
-
dir-compare@^3.0.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-3.3.0.tgz#2c749f973b5c4b5d087f11edaae730db31788416"
@@ -2883,6 +3031,13 @@ dmg-license@^1.0.11:
smart-buffer "^4.0.2"
verror "^1.10.0"
+doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
+ integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
+ dependencies:
+ esutils "^2.0.2"
+
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
@@ -2919,7 +3074,7 @@ drbg.js@^1.0.1:
create-hash "^1.1.2"
create-hmac "^1.1.4"
-dunder-proto@^1.0.1:
+dunder-proto@^1.0.0, dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
@@ -3136,6 +3291,66 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
+es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0, es-abstract@^1.24.1:
+ version "1.24.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.1.tgz#f0c131ed5ea1bb2411134a8dd94def09c46c7899"
+ integrity sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==
+ dependencies:
+ array-buffer-byte-length "^1.0.2"
+ arraybuffer.prototype.slice "^1.0.4"
+ available-typed-arrays "^1.0.7"
+ call-bind "^1.0.8"
+ call-bound "^1.0.4"
+ data-view-buffer "^1.0.2"
+ data-view-byte-length "^1.0.2"
+ data-view-byte-offset "^1.0.1"
+ es-define-property "^1.0.1"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.1.1"
+ es-set-tostringtag "^2.1.0"
+ es-to-primitive "^1.3.0"
+ function.prototype.name "^1.1.8"
+ get-intrinsic "^1.3.0"
+ get-proto "^1.0.1"
+ get-symbol-description "^1.1.0"
+ globalthis "^1.0.4"
+ gopd "^1.2.0"
+ has-property-descriptors "^1.0.2"
+ has-proto "^1.2.0"
+ has-symbols "^1.1.0"
+ hasown "^2.0.2"
+ internal-slot "^1.1.0"
+ is-array-buffer "^3.0.5"
+ is-callable "^1.2.7"
+ is-data-view "^1.0.2"
+ is-negative-zero "^2.0.3"
+ is-regex "^1.2.1"
+ is-set "^2.0.3"
+ is-shared-array-buffer "^1.0.4"
+ is-string "^1.1.1"
+ is-typed-array "^1.1.15"
+ is-weakref "^1.1.1"
+ math-intrinsics "^1.1.0"
+ object-inspect "^1.13.4"
+ object-keys "^1.1.1"
+ object.assign "^4.1.7"
+ own-keys "^1.0.1"
+ regexp.prototype.flags "^1.5.4"
+ safe-array-concat "^1.1.3"
+ safe-push-apply "^1.0.0"
+ safe-regex-test "^1.1.0"
+ set-proto "^1.0.0"
+ stop-iteration-iterator "^1.1.0"
+ string.prototype.trim "^1.2.10"
+ string.prototype.trimend "^1.0.9"
+ string.prototype.trimstart "^1.0.8"
+ typed-array-buffer "^1.0.3"
+ typed-array-byte-length "^1.0.3"
+ typed-array-byte-offset "^1.0.4"
+ typed-array-length "^1.0.7"
+ unbox-primitive "^1.1.0"
+ which-typed-array "^1.1.19"
+
es-abstract@^1.18.0-next.1:
version "1.18.0-next.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
@@ -3193,6 +3408,28 @@ es-errors@^1.3.0:
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+es-iterator-helpers@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz#d979a9f686e2b0b72f88dbead7229924544720bc"
+ integrity sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.4"
+ define-properties "^1.2.1"
+ es-abstract "^1.24.1"
+ es-errors "^1.3.0"
+ es-set-tostringtag "^2.1.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.3.0"
+ globalthis "^1.0.4"
+ gopd "^1.2.0"
+ has-property-descriptors "^1.0.2"
+ has-proto "^1.2.0"
+ has-symbols "^1.1.0"
+ internal-slot "^1.1.0"
+ iterator.prototype "^1.1.5"
+ safe-array-concat "^1.1.3"
+
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
@@ -3210,6 +3447,13 @@ es-set-tostringtag@^2.1.0:
has-tostringtag "^1.0.2"
hasown "^2.0.2"
+es-shim-unscopables@^1.0.2:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5"
+ integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==
+ dependencies:
+ hasown "^2.0.2"
+
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -3219,6 +3463,15 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
+es-to-primitive@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18"
+ integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==
+ dependencies:
+ is-callable "^1.2.7"
+ is-date-object "^1.0.5"
+ is-symbol "^1.0.4"
+
es5-ext@^0.10.35, es5-ext@^0.10.50:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
@@ -3282,7 +3535,31 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-eslint-scope@^8.2.0:
+eslint-plugin-react@^7.37.5:
+ version "7.37.5"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065"
+ integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==
+ dependencies:
+ array-includes "^3.1.8"
+ array.prototype.findlast "^1.2.5"
+ array.prototype.flatmap "^1.3.3"
+ array.prototype.tosorted "^1.1.4"
+ doctrine "^2.1.0"
+ es-iterator-helpers "^1.2.1"
+ estraverse "^5.3.0"
+ hasown "^2.0.2"
+ jsx-ast-utils "^2.4.1 || ^3.0.0"
+ minimatch "^3.1.2"
+ object.entries "^1.1.9"
+ object.fromentries "^2.0.8"
+ object.values "^1.2.1"
+ prop-types "^15.8.1"
+ resolve "^2.0.0-next.5"
+ semver "^6.3.1"
+ string.prototype.matchall "^4.0.12"
+ string.prototype.repeat "^1.0.0"
+
+eslint-scope@^8.4.0:
version "8.4.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82"
integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==
@@ -3295,36 +3572,36 @@ eslint-visitor-keys@^3.4.3:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-eslint-visitor-keys@^4.2.0, eslint-visitor-keys@^4.2.1:
+eslint-visitor-keys@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
-eslint@9.16.0:
- version "9.16.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6"
- integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==
+eslint@^9.39.2:
+ version "9.39.2"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.2.tgz#cb60e6d16ab234c0f8369a3fe7cc87967faf4b6c"
+ integrity sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==
dependencies:
- "@eslint-community/eslint-utils" "^4.2.0"
+ "@eslint-community/eslint-utils" "^4.8.0"
"@eslint-community/regexpp" "^4.12.1"
- "@eslint/config-array" "^0.19.0"
- "@eslint/core" "^0.9.0"
- "@eslint/eslintrc" "^3.2.0"
- "@eslint/js" "9.16.0"
- "@eslint/plugin-kit" "^0.2.3"
+ "@eslint/config-array" "^0.21.1"
+ "@eslint/config-helpers" "^0.4.2"
+ "@eslint/core" "^0.17.0"
+ "@eslint/eslintrc" "^3.3.1"
+ "@eslint/js" "9.39.2"
+ "@eslint/plugin-kit" "^0.4.1"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
- "@humanwhocodes/retry" "^0.4.1"
+ "@humanwhocodes/retry" "^0.4.2"
"@types/estree" "^1.0.6"
- "@types/json-schema" "^7.0.15"
ajv "^6.12.4"
chalk "^4.0.0"
- cross-spawn "^7.0.5"
+ cross-spawn "^7.0.6"
debug "^4.3.2"
escape-string-regexp "^4.0.0"
- eslint-scope "^8.2.0"
- eslint-visitor-keys "^4.2.0"
- espree "^10.3.0"
+ eslint-scope "^8.4.0"
+ eslint-visitor-keys "^4.2.1"
+ espree "^10.4.0"
esquery "^1.5.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
@@ -3340,7 +3617,7 @@ eslint@9.16.0:
natural-compare "^1.4.0"
optionator "^0.9.3"
-espree@^10.0.1, espree@^10.3.0:
+espree@^10.0.1, espree@^10.4.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837"
integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==
@@ -3368,7 +3645,7 @@ esrecurse@^4.3.0:
dependencies:
estraverse "^5.2.0"
-estraverse@^5.1.0, estraverse@^5.2.0:
+estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
@@ -3716,6 +3993,11 @@ fd-slicer@~1.1.0:
dependencies:
pend "~1.2.0"
+fdir@^6.5.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
+ integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -3994,7 +4276,19 @@ function.prototype.name@^1.1.5:
es-abstract "^1.19.0"
functions-have-names "^1.2.2"
-functions-have-names@^1.2.2:
+function.prototype.name@^1.1.6, function.prototype.name@^1.1.8:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78"
+ integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
+ define-properties "^1.2.1"
+ functions-have-names "^1.2.3"
+ hasown "^2.0.2"
+ is-callable "^1.2.7"
+
+functions-have-names@^1.2.2, functions-have-names@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
@@ -4013,6 +4307,11 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
+generator-function@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2"
+ integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==
+
genfun@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
@@ -4080,7 +4379,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.3"
-get-intrinsic@^1.2.4, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0:
+get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
@@ -4096,7 +4395,7 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0:
hasown "^2.0.2"
math-intrinsics "^1.1.0"
-get-proto@^1.0.1:
+get-proto@^1.0.0, get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
@@ -4139,6 +4438,15 @@ get-symbol-description@^1.0.0:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"
+get-symbol-description@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee"
+ integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==
+ dependencies:
+ call-bound "^1.0.3"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.6"
+
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
@@ -4232,6 +4540,11 @@ globals@^14.0.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
+globals@^17.0.0:
+ version "17.0.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-17.0.0.tgz#a4196d9cfeb4d627ba165b4647b1f5853bf90a30"
+ integrity sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==
+
globalthis@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9"
@@ -4239,6 +4552,14 @@ globalthis@^1.0.1:
dependencies:
define-properties "^1.1.3"
+globalthis@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
+ integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
+ dependencies:
+ define-properties "^1.2.1"
+ gopd "^1.0.1"
+
gopd@^1.0.1, gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
@@ -4334,6 +4655,13 @@ has-property-descriptors@^1.0.2:
dependencies:
es-define-property "^1.0.0"
+has-proto@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5"
+ integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==
+ dependencies:
+ dunder-proto "^1.0.0"
+
has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
@@ -4571,6 +4899,11 @@ ignore@^5.2.0:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
+ignore@^7.0.5:
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9"
+ integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==
+
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
@@ -4650,6 +4983,15 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"
+internal-slot@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961"
+ integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==
+ dependencies:
+ es-errors "^1.3.0"
+ hasown "^2.0.2"
+ side-channel "^1.1.0"
+
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
@@ -4692,11 +5034,31 @@ is-arguments@^1.0.4:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280"
+ integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
+ get-intrinsic "^1.2.6"
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+is-async-function@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.1.1.tgz#3e69018c8e04e73b738793d020bfe884b9fd3523"
+ integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==
+ dependencies:
+ async-function "^1.0.0"
+ call-bound "^1.0.3"
+ get-proto "^1.0.1"
+ has-tostringtag "^1.0.2"
+ safe-regex-test "^1.1.0"
+
is-bigint@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@@ -4704,6 +5066,13 @@ is-bigint@^1.0.1:
dependencies:
has-bigints "^1.0.1"
+is-bigint@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672"
+ integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==
+ dependencies:
+ has-bigints "^1.0.2"
+
is-boolean-object@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
@@ -4712,6 +5081,14 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-boolean-object@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e"
+ integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==
+ dependencies:
+ call-bound "^1.0.3"
+ has-tostringtag "^1.0.2"
+
is-callable@^1.1.3, is-callable@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
@@ -4748,16 +5125,47 @@ is-cidr@^3.0.0:
dependencies:
cidr-regex "^2.0.10"
+is-core-module@^2.13.0:
+ version "2.16.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
+ integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
+ dependencies:
+ hasown "^2.0.2"
+
+is-data-view@^1.0.1, is-data-view@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e"
+ integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==
+ dependencies:
+ call-bound "^1.0.2"
+ get-intrinsic "^1.2.6"
+ is-typed-array "^1.1.13"
+
is-date-object@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
+is-date-object@^1.0.5, is-date-object@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7"
+ integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==
+ dependencies:
+ call-bound "^1.0.2"
+ has-tostringtag "^1.0.2"
+
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+is-finalizationregistry@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90"
+ integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==
+ dependencies:
+ call-bound "^1.0.3"
+
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -4780,6 +5188,17 @@ is-function@^1.0.1:
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
+is-generator-function@^1.0.10:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5"
+ integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==
+ dependencies:
+ call-bound "^1.0.4"
+ generator-function "^2.0.0"
+ get-proto "^1.0.1"
+ has-tostringtag "^1.0.2"
+ safe-regex-test "^1.1.0"
+
is-generator-function@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
@@ -4807,6 +5226,11 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
+is-map@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
+ integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
+
is-negative-zero@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@@ -4817,6 +5241,11 @@ is-negative-zero@^2.0.2:
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
+is-negative-zero@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
+ integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==
+
is-npm@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
@@ -4836,6 +5265,14 @@ is-number-object@^1.0.4:
dependencies:
has-tostringtag "^1.0.0"
+is-number-object@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541"
+ integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==
+ dependencies:
+ call-bound "^1.0.3"
+ has-tostringtag "^1.0.2"
+
is-obj@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
@@ -4863,6 +5300,21 @@ is-regex@^1.1.4:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-regex@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
+ integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==
+ dependencies:
+ call-bound "^1.0.2"
+ gopd "^1.2.0"
+ has-tostringtag "^1.0.2"
+ hasown "^2.0.2"
+
+is-set@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d"
+ integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==
+
is-shared-array-buffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
@@ -4870,6 +5322,13 @@ is-shared-array-buffer@^1.0.2:
dependencies:
call-bind "^1.0.2"
+is-shared-array-buffer@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f"
+ integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==
+ dependencies:
+ call-bound "^1.0.3"
+
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -4882,6 +5341,14 @@ is-string@^1.0.5, is-string@^1.0.7:
dependencies:
has-tostringtag "^1.0.0"
+is-string@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9"
+ integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==
+ dependencies:
+ call-bound "^1.0.3"
+ has-tostringtag "^1.0.2"
+
is-symbol@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
@@ -4896,7 +5363,16 @@ is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-typed-array@^1.1.14:
+is-symbol@^1.0.4, is-symbol@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634"
+ integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==
+ dependencies:
+ call-bound "^1.0.2"
+ has-symbols "^1.1.0"
+ safe-regex-test "^1.1.0"
+
+is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15:
version "1.1.15"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
@@ -4919,6 +5395,11 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0:
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+is-weakmap@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd"
+ integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==
+
is-weakref@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
@@ -4926,6 +5407,21 @@ is-weakref@^1.0.2:
dependencies:
call-bind "^1.0.2"
+is-weakref@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.1.tgz#eea430182be8d64174bd96bffbc46f21bf3f9293"
+ integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==
+ dependencies:
+ call-bound "^1.0.3"
+
+is-weakset@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca"
+ integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==
+ dependencies:
+ call-bound "^1.0.3"
+ get-intrinsic "^1.2.6"
+
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@@ -4961,6 +5457,18 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+iterator.prototype@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39"
+ integrity sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==
+ dependencies:
+ define-data-property "^1.1.4"
+ es-object-atoms "^1.0.0"
+ get-intrinsic "^1.2.6"
+ get-proto "^1.0.0"
+ has-symbols "^1.1.0"
+ set-function-name "^2.0.2"
+
jackspeak@^2.3.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8"
@@ -5000,6 +5508,11 @@ js-sha3@^0.7.0:
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a"
integrity sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==
+"js-tokens@^3.0.0 || ^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
js-yaml@3.13.1, js-yaml@^4.1.0, js-yaml@^4.1.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
@@ -5084,6 +5597,16 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
+"jsx-ast-utils@^2.4.1 || ^3.0.0":
+ version "3.3.5"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a"
+ integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==
+ dependencies:
+ array-includes "^3.1.6"
+ array.prototype.flat "^1.3.1"
+ object.assign "^4.1.4"
+ object.values "^1.1.6"
+
jszip@^3.1.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
@@ -5407,6 +5930,13 @@ long@5.2.0:
resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61"
integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==
+loose-envify@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
@@ -5446,11 +5976,6 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
-make-error@^1.1.1:
- version "1.3.6"
- resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
- integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-
make-fetch-happen@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz#a8e3fe41d3415dd656fe7b8e8172e1fb4458b38d"
@@ -5591,7 +6116,7 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-minimatch@5.1.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@^5.1.1, minimatch@^9.0.1:
+minimatch@5.1.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@^5.1.1, minimatch@^9.0.1, minimatch@^9.0.5:
version "5.1.0"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
@@ -6207,6 +6732,11 @@ object-inspect@^1.12.0, object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
+object-inspect@^1.13.3, object-inspect@^1.13.4:
+ version "1.13.4"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213"
+ integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
+
object-inspect@^1.8.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
@@ -6227,6 +6757,38 @@ object.assign@^4.1.1, object.assign@^4.1.2:
has-symbols "^1.0.1"
object-keys "^1.1.1"
+object.assign@^4.1.4, object.assign@^4.1.7:
+ version "4.1.7"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d"
+ integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
+ define-properties "^1.2.1"
+ es-object-atoms "^1.0.0"
+ has-symbols "^1.1.0"
+ object-keys "^1.1.1"
+
+object.entries@^1.1.9:
+ version "1.1.9"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.9.tgz#e4770a6a1444afb61bd39f984018b5bede25f8b3"
+ integrity sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.4"
+ define-properties "^1.2.1"
+ es-object-atoms "^1.1.1"
+
+object.fromentries@^2.0.8:
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65"
+ integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==
+ dependencies:
+ call-bind "^1.0.7"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.2"
+ es-object-atoms "^1.0.0"
+
object.getownpropertydescriptors@^2.0.3:
version "2.1.1"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544"
@@ -6236,6 +6798,16 @@ object.getownpropertydescriptors@^2.0.3:
define-properties "^1.1.3"
es-abstract "^1.18.0-next.1"
+object.values@^1.1.6, object.values@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216"
+ integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
+ define-properties "^1.2.1"
+ es-object-atoms "^1.0.0"
+
oboe@2.1.5:
version "2.1.5"
resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd"
@@ -6313,6 +6885,15 @@ osx-temperature-sensor@1.0.8:
resolved "https://registry.yarnpkg.com/osx-temperature-sensor/-/osx-temperature-sensor-1.0.8.tgz#14665adefb85d5a1e752e755eeb7ce9708d67c49"
integrity sha512-Gl3b+bn7+oDDnqPa+4v/cg3yg9lnE8ppS7ivL3opBZh4i7h99JNmkm6zWmo0m2a83UUJu+C9D7lGP0OS8IlehA==
+own-keys@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358"
+ integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==
+ dependencies:
+ get-intrinsic "^1.2.6"
+ object-keys "^1.1.1"
+ safe-push-apply "^1.0.0"
+
p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
@@ -6507,7 +7088,7 @@ path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-path-parse@1.0.7, path-parse@^1.0.6:
+path-parse@1.0.7, path-parse@^1.0.6, path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
@@ -6554,6 +7135,11 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+picomatch@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
+ integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
+
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -6659,6 +7245,15 @@ promzard@^0.3.0:
dependencies:
read "1"
+prop-types@^15.8.1:
+ version "15.8.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+ integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.13.1"
+
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
@@ -6836,6 +7431,11 @@ rc@^1.0.1, rc@^1.1.6:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
+react-is@^16.13.1:
+ version "16.13.1"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
"react-native-cache@git+https://github.com/michaeltout/react-native-cache.git":
version "1.1.7"
resolved "git+https://github.com/michaeltout/react-native-cache.git#f8c1a72b50177aa93de5e8c329b1523409505dd6"
@@ -6990,6 +7590,20 @@ readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0:
graceful-fs "^4.1.2"
once "^1.3.0"
+reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9"
+ integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==
+ dependencies:
+ call-bind "^1.0.8"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.9"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.0.0"
+ get-intrinsic "^1.2.7"
+ get-proto "^1.0.1"
+ which-builtin-type "^1.2.1"
+
regexp.prototype.flags@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
@@ -6999,6 +7613,18 @@ regexp.prototype.flags@^1.4.3:
define-properties "^1.1.3"
functions-have-names "^1.2.2"
+regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4:
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19"
+ integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==
+ dependencies:
+ call-bind "^1.0.8"
+ define-properties "^1.2.1"
+ es-errors "^1.3.0"
+ get-proto "^1.0.1"
+ gopd "^1.2.0"
+ set-function-name "^2.0.2"
+
registry-auth-token@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e"
@@ -7139,6 +7765,15 @@ resolve@^1.10.0:
dependencies:
path-parse "^1.0.6"
+resolve@^2.0.0-next.5:
+ version "2.0.0-next.5"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
+ integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==
+ dependencies:
+ is-core-module "^2.13.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
responselike@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
@@ -7224,6 +7859,17 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
+safe-array-concat@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3"
+ integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.2"
+ get-intrinsic "^1.2.6"
+ has-symbols "^1.1.0"
+ isarray "^2.0.5"
+
safe-buffer@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
@@ -7244,6 +7890,23 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+safe-push-apply@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5"
+ integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==
+ dependencies:
+ es-errors "^1.3.0"
+ isarray "^2.0.5"
+
+safe-regex-test@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1"
+ integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==
+ dependencies:
+ call-bound "^1.0.2"
+ es-errors "^1.3.0"
+ is-regex "^1.2.1"
+
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -7297,7 +7960,7 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
-"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.3:
+"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.3, semver@^7.7.3:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
@@ -7366,6 +8029,25 @@ set-function-length@^1.2.2:
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
+set-function-name@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985"
+ integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
+ dependencies:
+ define-data-property "^1.1.4"
+ es-errors "^1.3.0"
+ functions-have-names "^1.2.3"
+ has-property-descriptors "^1.0.2"
+
+set-proto@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/set-proto/-/set-proto-1.0.0.tgz#0760dbcff30b2d7e801fd6e19983e56da337565e"
+ integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==
+ dependencies:
+ dunder-proto "^1.0.1"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.0.0"
+
setimmediate@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f"
@@ -7445,6 +8127,35 @@ shell-path@^2.0.0:
dependencies:
shell-env "^0.3.0"
+side-channel-list@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"
+ integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
+ dependencies:
+ es-errors "^1.3.0"
+ object-inspect "^1.13.3"
+
+side-channel-map@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42"
+ integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
+ dependencies:
+ call-bound "^1.0.2"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.5"
+ object-inspect "^1.13.3"
+
+side-channel-weakmap@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea"
+ integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
+ dependencies:
+ call-bound "^1.0.2"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.5"
+ object-inspect "^1.13.3"
+ side-channel-map "^1.0.1"
+
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -7454,6 +8165,17 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
+side-channel@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
+ integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
+ dependencies:
+ es-errors "^1.3.0"
+ object-inspect "^1.13.3"
+ side-channel-list "^1.0.0"
+ side-channel-map "^1.0.1"
+ side-channel-weakmap "^1.0.2"
+
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -7656,6 +8378,14 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
+stop-iteration-iterator@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad"
+ integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==
+ dependencies:
+ es-errors "^1.3.0"
+ internal-slot "^1.1.0"
+
stream-each@^1.1.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
@@ -7749,6 +8479,46 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
+string.prototype.matchall@^4.0.12:
+ version "4.0.12"
+ resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0"
+ integrity sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.3"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.6"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.0.0"
+ get-intrinsic "^1.2.6"
+ gopd "^1.2.0"
+ has-symbols "^1.1.0"
+ internal-slot "^1.1.0"
+ regexp.prototype.flags "^1.5.3"
+ set-function-name "^2.0.2"
+ side-channel "^1.1.0"
+
+string.prototype.repeat@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a"
+ integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.17.5"
+
+string.prototype.trim@^1.2.10:
+ version "1.2.10"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81"
+ integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.2"
+ define-data-property "^1.1.4"
+ define-properties "^1.2.1"
+ es-abstract "^1.23.5"
+ es-object-atoms "^1.0.0"
+ has-property-descriptors "^1.0.2"
+
string.prototype.trimend@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b"
@@ -7766,6 +8536,16 @@ string.prototype.trimend@^1.0.5:
define-properties "^1.1.4"
es-abstract "^1.19.5"
+string.prototype.trimend@^1.0.9:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942"
+ integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==
+ dependencies:
+ call-bind "^1.0.8"
+ call-bound "^1.0.2"
+ define-properties "^1.2.1"
+ es-object-atoms "^1.0.0"
+
string.prototype.trimstart@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa"
@@ -7783,6 +8563,15 @@ string.prototype.trimstart@^1.0.5:
define-properties "^1.1.4"
es-abstract "^1.19.5"
+string.prototype.trimstart@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde"
+ integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==
+ dependencies:
+ call-bind "^1.0.7"
+ define-properties "^1.2.1"
+ es-object-atoms "^1.0.0"
+
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@@ -7904,6 +8693,11 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
swarm-js@^0.1.40:
version "0.1.40"
resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99"
@@ -7993,6 +8787,14 @@ tiny-secp256k1@1.1.7, tiny-secp256k1@^1.0.0:
elliptic "^6.4.0"
nan "^2.13.2"
+tinyglobby@^0.2.15:
+ version "0.2.15"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"
+ integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
+ dependencies:
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+
tmp-promise@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7"
@@ -8048,24 +8850,10 @@ truncate-utf8-bytes@^1.0.0:
dependencies:
utf8-byte-length "^1.0.1"
-ts-node@^10.9.2:
- version "10.9.2"
- resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f"
- integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==
- dependencies:
- "@cspotcode/source-map-support" "^0.8.0"
- "@tsconfig/node10" "^1.0.7"
- "@tsconfig/node12" "^1.0.7"
- "@tsconfig/node14" "^1.0.0"
- "@tsconfig/node16" "^1.0.2"
- acorn "^8.4.1"
- acorn-walk "^8.1.1"
- arg "^4.1.0"
- create-require "^1.1.0"
- diff "^4.0.1"
- make-error "^1.1.1"
- v8-compile-cache-lib "^3.0.1"
- yn "3.1.1"
+ts-api-utils@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8"
+ integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==
tslib@2.7.0:
version "2.7.0"
@@ -8145,6 +8933,42 @@ typed-array-buffer@^1.0.3:
es-errors "^1.3.0"
is-typed-array "^1.1.14"
+typed-array-byte-length@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce"
+ integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==
+ dependencies:
+ call-bind "^1.0.8"
+ for-each "^0.3.3"
+ gopd "^1.2.0"
+ has-proto "^1.2.0"
+ is-typed-array "^1.1.14"
+
+typed-array-byte-offset@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355"
+ integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==
+ dependencies:
+ available-typed-arrays "^1.0.7"
+ call-bind "^1.0.8"
+ for-each "^0.3.3"
+ gopd "^1.2.0"
+ has-proto "^1.2.0"
+ is-typed-array "^1.1.15"
+ reflect.getprototypeof "^1.0.9"
+
+typed-array-length@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d"
+ integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==
+ dependencies:
+ call-bind "^1.0.7"
+ for-each "^0.3.3"
+ gopd "^1.0.1"
+ is-typed-array "^1.1.13"
+ possible-typed-array-names "^1.0.0"
+ reflect.getprototypeof "^1.0.6"
+
typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@@ -8168,6 +8992,16 @@ typeforce@^1.11.1, typeforce@^1.11.3, typeforce@^1.11.5, "typeforce@git+https://
version "1.18.0"
resolved "git+https://github.com/michaeltout/typeforce#c9b0abc33ff006d7a6a6150eff034bc7eb8b07de"
+typescript-eslint@^8.53.0:
+ version "8.53.0"
+ resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.53.0.tgz#c35ca6403cd381753aee325f67e10d6101d55f04"
+ integrity sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==
+ dependencies:
+ "@typescript-eslint/eslint-plugin" "8.53.0"
+ "@typescript-eslint/parser" "8.53.0"
+ "@typescript-eslint/typescript-estree" "8.53.0"
+ "@typescript-eslint/utils" "8.53.0"
+
typescript@5.8.3:
version "5.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
@@ -8198,6 +9032,16 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
+unbox-primitive@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2"
+ integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==
+ dependencies:
+ call-bound "^1.0.3"
+ has-bigints "^1.0.2"
+ has-symbols "^1.1.0"
+ which-boxed-primitive "^1.1.1"
+
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
@@ -8395,11 +9239,6 @@ uuid@^9.0.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
-v8-compile-cache-lib@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
- integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
-
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -8775,12 +9614,52 @@ which-boxed-primitive@^1.0.2:
is-string "^1.0.5"
is-symbol "^1.0.3"
+which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e"
+ integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==
+ dependencies:
+ is-bigint "^1.1.0"
+ is-boolean-object "^1.2.1"
+ is-number-object "^1.1.1"
+ is-string "^1.1.1"
+ is-symbol "^1.1.1"
+
+which-builtin-type@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e"
+ integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==
+ dependencies:
+ call-bound "^1.0.2"
+ function.prototype.name "^1.1.6"
+ has-tostringtag "^1.0.2"
+ is-async-function "^2.0.0"
+ is-date-object "^1.1.0"
+ is-finalizationregistry "^1.1.0"
+ is-generator-function "^1.0.10"
+ is-regex "^1.2.1"
+ is-weakref "^1.0.2"
+ isarray "^2.0.5"
+ which-boxed-primitive "^1.1.0"
+ which-collection "^1.0.2"
+ which-typed-array "^1.1.16"
+
+which-collection@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0"
+ integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==
+ dependencies:
+ is-map "^2.0.3"
+ is-set "^2.0.3"
+ is-weakmap "^2.0.2"
+ is-weakset "^2.0.3"
+
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-which-typed-array@^1.1.16:
+which-typed-array@^1.1.16, which-typed-array@^1.1.19:
version "1.1.19"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
@@ -9082,11 +9961,6 @@ yauzl@^2.10.0:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
-yn@3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
- integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
-
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
From bf6ab975de0e472fe9fcc2a5142d93411d079700 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 15 Jan 2026 16:04:16 -0800
Subject: [PATCH 53/80] Fix using the restricted name 'arguments' and update
the spelling of the response uri class to match verus-typescript-primitives.
---
routes/api/native/decryptdata.js | 14 +++++++-------
routes/api/native/signdata.js | 12 ++++++------
routes/api/plugin/builtin/loginconsentui.js | 10 +++++-----
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/routes/api/native/decryptdata.js b/routes/api/native/decryptdata.js
index 2b37bb81..0dbe33bc 100644
--- a/routes/api/native/decryptdata.js
+++ b/routes/api/native/decryptdata.js
@@ -1,15 +1,15 @@
module.exports = (api) => {
/**
- * Decrypts data given the arguments of a data descriptor, and optionally
+ * Decrypts data given the parameters of a data descriptor, and optionally
* evk, ivk, txid and/or if to retrieve the data from its reference.
*
* @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} arguments The arguments to pass to decryptdata
+ * @param {Object} params The parameters to pass to decryptdata
*/
api.native.decrypt_data = (
coin,
- arguments,
+ params,
) => {
return new Promise((resolve, reject) => {
api.native
@@ -17,7 +17,7 @@ module.exports = (api) => {
coin,
"decryptdata",
[
- arguments,
+ params,
]
)
.then(resultObj => {
@@ -29,16 +29,16 @@ module.exports = (api) => {
});
};
- api.setPost('/native/decrypt_data', (req, res, next) => {
+ api.setPost('/native/decrypt_data', (req, res) => {
const {
chainTicker,
- arguments
+ parameters
} = req.body;
api.native
.decrypt_data(
chainTicker,
- arguments
+ parameters
)
.then(resultObj => {
const retObj = {
diff --git a/routes/api/native/signdata.js b/routes/api/native/signdata.js
index 0cb05ac8..f3422d4b 100644
--- a/routes/api/native/signdata.js
+++ b/routes/api/native/signdata.js
@@ -69,15 +69,15 @@ module.exports = (api) => {
};
/**
- * Signs data given the arguments including an identity/address currently in the wallet
+ * Signs data given the parameters including an identity/address currently in the wallet
* and the data to be signed
*
* @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} arguments The arguments to pass to signdata
+ * @param {Object} params The parameters to pass to signdata
*/
api.native.sign_data = (
coin,
- arguments,
+ params,
) => {
return new Promise((resolve, reject) => {
api.native
@@ -85,7 +85,7 @@ module.exports = (api) => {
coin,
"signdata",
[
- arguments,
+ params,
]
)
.then(resultObj => {
@@ -98,7 +98,7 @@ module.exports = (api) => {
};
- api.setPost('/native/sign_message', (req, res, next) => {
+ api.setPost('/native/sign_message', (req, res) => {
const {
chainTicker,
address,
@@ -131,7 +131,7 @@ module.exports = (api) => {
});
});
- api.setPost('/native/sign_file', (req, res, next) => {
+ api.setPost('/native/sign_file', (req, res) => {
const {
chainTicker,
address,
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.js
index 4ccf94e6..bcc573c6 100644
--- a/routes/api/plugin/builtin/loginconsentui.js
+++ b/routes/api/plugin/builtin/loginconsentui.js
@@ -5,7 +5,7 @@ const {
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
IDENTITY_UPDATE_RESPONSE_VDXF_KEY,
- ResponseUri,
+ ResponseURI,
} = require("verus-typescript-primitives");
const { pushMessage } = require('../../../ipc/ipc');
const { ReservedPluginTypes } = require('../../utils/plugin/builtin');
@@ -24,8 +24,8 @@ module.exports = (api) => {
// Type can either be a string vdxfkey or a BN converted into a number.
const usesResponseUri = responseKey === IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid;
if (usesResponseUri) {
- const responseUri = ResponseUri.fromJson(redirectinfo);
- processedType = ResponseUri.type;
+ const responseUri = ResponseURI.fromJson(redirectinfo);
+ processedType = responseUri.type;
}
const post = async () => {
@@ -85,8 +85,8 @@ module.exports = (api) => {
const handlers = {
[LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: post,
[LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: redirect,
- [ResponseUri.TYPE_POST]: post,
- [ResponseUri.TYPE_REDIRECT]: redirect,
+ [ResponseURI.TYPE_POST]: post,
+ [ResponseURI.TYPE_REDIRECT]: redirect,
};
return handlers[processedType] == null ? null : handlers[processedType]();
From 26622fade93d3ca0ce0e142f261c86f3e4b52660 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 23 Jan 2026 17:00:10 -0800
Subject: [PATCH 54/80] Add signing of the generic response.
---
.../verusid/generic/signGenericResponse.ts | 52 +++++++++++++++++++
.../verusid/generic/verifyGenericRequest.js | 2 +-
routes/api/native/verusid/verusid.js | 1 +
yarn.lock | 18 +++----
4 files changed, 63 insertions(+), 10 deletions(-)
create mode 100644 routes/api/native/verusid/generic/signGenericResponse.ts
diff --git a/routes/api/native/verusid/generic/signGenericResponse.ts b/routes/api/native/verusid/generic/signGenericResponse.ts
new file mode 100644
index 00000000..0801761c
--- /dev/null
+++ b/routes/api/native/verusid/generic/signGenericResponse.ts
@@ -0,0 +1,52 @@
+import {
+ GenericResponse,
+} from "verus-typescript-primitives";
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default (api: any) => {
+ api.native.verusid.generic.sign_response = async (coin: string, response: GenericResponse) => {
+
+ console.log("Signing Generic Response:", response);
+
+ const signdataResult = await api.native.sign_data(coin, {
+ address: response.signature.identityID.toIAddress(),
+ datahash: response.getRawDataSha256().toString('hex'),
+ });
+
+ console.log("Signature Data Result:", signdataResult);
+ console.log("Signature Data (base64):", signdataResult.signature);
+ console.log("Signature Data Buffer:", Buffer.from(signdataResult.signature, 'base64'));
+
+ response.signature.signatureAsVch = Buffer.from(signdataResult.signature, 'base64');
+
+ return response;
+ };
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api.setPost("/native/verusid/generic/sign_generic_response", async (req: any, res: any) => {
+ const { chainTicker, response } = req.body;
+
+ // The response comes in as a hex string of the buffer representation.
+ const genericResponse = new GenericResponse();
+ genericResponse.fromBuffer(Buffer.from(response, 'hex'));
+
+ try {
+ const signedResponse = await api.native.verusid.generic.sign_response(chainTicker, genericResponse);
+ res.send(
+ JSON.stringify({
+ msg: "success",
+ result: signedResponse.toBuffer().toString('hex'),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: "error",
+ result: e.message,
+ })
+ );
+ }
+ });
+
+ return api;
+};
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
index fd54b18b..9349df2c 100644
--- a/routes/api/native/verusid/generic/verifyGenericRequest.js
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -1,4 +1,4 @@
-const {GenericRequest, GENERIC_REQUEST_VDXF_KEY} = require("verus-typescript-primitives")
+const {GenericRequest} = require("verus-typescript-primitives")
module.exports = (api) => {
/**
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index 595bc216..cc2a5c82 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -20,6 +20,7 @@ module.exports = (api) => {
// Generic
require('./generic/verifyGenericRequest')(api);
+ require('./generic/signGenericResponse').default(api);
return api;
};
diff --git a/yarn.lock b/yarn.lock
index a5117174..ccf1a5e1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -173,7 +173,7 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@9.39.2", "@eslint/js@^9.39.2":
+"@eslint/js@9.39.2":
version "9.39.2"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.2.tgz#2d4b8ec4c3ea13c1b3748e0c97ecd766bdd80599"
integrity sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==
@@ -3535,7 +3535,7 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-eslint-plugin-react@^7.37.5:
+eslint-plugin-react@7.37.5:
version "7.37.5"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065"
integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==
@@ -3577,7 +3577,7 @@ eslint-visitor-keys@^4.2.1:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
-eslint@^9.39.2:
+eslint@9.39.2:
version "9.39.2"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.2.tgz#cb60e6d16ab234c0f8369a3fe7cc87967faf4b6c"
integrity sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==
@@ -4535,16 +4535,16 @@ global@~4.4.0:
min-document "^2.19.0"
process "^0.11.10"
+globals@17.0.0:
+ version "17.0.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-17.0.0.tgz#a4196d9cfeb4d627ba165b4647b1f5853bf90a30"
+ integrity sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==
+
globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
-globals@^17.0.0:
- version "17.0.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-17.0.0.tgz#a4196d9cfeb4d627ba165b4647b1f5853bf90a30"
- integrity sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==
-
globalthis@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9"
@@ -8992,7 +8992,7 @@ typeforce@^1.11.1, typeforce@^1.11.3, typeforce@^1.11.5, "typeforce@git+https://
version "1.18.0"
resolved "git+https://github.com/michaeltout/typeforce#c9b0abc33ff006d7a6a6150eff034bc7eb8b07de"
-typescript-eslint@^8.53.0:
+typescript-eslint@8.53.0:
version "8.53.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.53.0.tgz#c35ca6403cd381753aee325f67e10d6101d55f04"
integrity sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==
From 1f43fd8ebe91890b9cae5ce130b2cac7dd26d844 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 26 Jan 2026 10:04:59 -0800
Subject: [PATCH 55/80] Add prettier for formatting.
---
.prettierignore | 5 +++++
.prettierrc | 0
package.json | 2 ++
yarn.lock | 10 ++++++++++
4 files changed, 17 insertions(+)
create mode 100644 .prettierignore
create mode 100644 .prettierrc
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..2c6543d5
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,5 @@
+node_modules/
+assets/
+out/
+dist/
+yarn.lock
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..e69de29b
diff --git a/package.json b/package.json
index 4878b7c4..14e21913 100644
--- a/package.json
+++ b/package.json
@@ -93,8 +93,10 @@
"electron-builder": "24.13.3",
"electron-devtools-installer": "3.2.0",
"eslint": "9.39.2",
+ "eslint-config-prettier": "10.1.8",
"eslint-plugin-react": "7.37.5",
"globals": "17.0.0",
+ "prettier": "3.6.0",
"typescript": "5.8.3",
"typescript-eslint": "8.53.0"
},
diff --git a/yarn.lock b/yarn.lock
index ccf1a5e1..cdc16288 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3535,6 +3535,11 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+eslint-config-prettier@10.1.8:
+ version "10.1.8"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz#15734ce4af8c2778cc32f0b01b37b0b5cd1ecb97"
+ integrity sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==
+
eslint-plugin-react@7.37.5:
version "7.37.5"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065"
@@ -7197,6 +7202,11 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+prettier@3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.0.tgz#18ec98d62cb0757a5d4eab40253ff3e6d0fc8dea"
+ integrity sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==
+
pretty-bytes@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.1.0.tgz#6237ecfbdc6525beaef4de722cc60a58ae0e6c6d"
From 1719b6e8fff8034860955c6448b6e813d142a7b9 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 26 Jan 2026 10:53:17 -0800
Subject: [PATCH 56/80] Start updating the login consent plugin handler to
typescript.
---
.../api/plugin/builtin/{loginconsentui.js => loginconsentui.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename routes/api/plugin/builtin/{loginconsentui.js => loginconsentui.ts} (100%)
diff --git a/routes/api/plugin/builtin/loginconsentui.js b/routes/api/plugin/builtin/loginconsentui.ts
similarity index 100%
rename from routes/api/plugin/builtin/loginconsentui.js
rename to routes/api/plugin/builtin/loginconsentui.ts
From 75dbf3e756b67eda830d82cdf85d7ffe0f7aa49d Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 27 Jan 2026 21:48:43 -0800
Subject: [PATCH 57/80] Handle the generic response after the login consent
plugin closes.
---
.prettierrc | 11 +
.../verusid/generic/signGenericResponse.ts | 24 +-
routes/api/plugin/builtin/loginconsentui.ts | 356 ++++++++++++------
3 files changed, 259 insertions(+), 132 deletions(-)
diff --git a/.prettierrc b/.prettierrc
index e69de29b..2a412871 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "bracketSpacing": false,
+ "bracketSameLine": false,
+ "printWidth": 100,
+ "semi": true,
+ "singleQuote": true,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "useTabs": false,
+ "arrowParens": "avoid"
+}
diff --git a/routes/api/native/verusid/generic/signGenericResponse.ts b/routes/api/native/verusid/generic/signGenericResponse.ts
index 0801761c..406c33fc 100644
--- a/routes/api/native/verusid/generic/signGenericResponse.ts
+++ b/routes/api/native/verusid/generic/signGenericResponse.ts
@@ -1,47 +1,41 @@
-import {
- GenericResponse,
-} from "verus-typescript-primitives";
+import {GenericResponse} from 'verus-typescript-primitives';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default (api: any) => {
api.native.verusid.generic.sign_response = async (coin: string, response: GenericResponse) => {
-
- console.log("Signing Generic Response:", response);
-
const signdataResult = await api.native.sign_data(coin, {
address: response.signature.identityID.toIAddress(),
datahash: response.getRawDataSha256().toString('hex'),
});
- console.log("Signature Data Result:", signdataResult);
- console.log("Signature Data (base64):", signdataResult.signature);
- console.log("Signature Data Buffer:", Buffer.from(signdataResult.signature, 'base64'));
-
response.signature.signatureAsVch = Buffer.from(signdataResult.signature, 'base64');
return response;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- api.setPost("/native/verusid/generic/sign_generic_response", async (req: any, res: any) => {
- const { chainTicker, response } = req.body;
+ api.setPost('/native/verusid/generic/sign_generic_response', async (req: any, res: any) => {
+ const {chainTicker, response} = req.body;
// The response comes in as a hex string of the buffer representation.
const genericResponse = new GenericResponse();
genericResponse.fromBuffer(Buffer.from(response, 'hex'));
try {
- const signedResponse = await api.native.verusid.generic.sign_response(chainTicker, genericResponse);
+ const signedResponse = await api.native.verusid.generic.sign_response(
+ chainTicker,
+ genericResponse
+ );
res.send(
JSON.stringify({
- msg: "success",
+ msg: 'success',
result: signedResponse.toBuffer().toString('hex'),
})
);
} catch (e) {
res.send(
JSON.stringify({
- msg: "error",
+ msg: 'error',
result: e.message,
})
);
diff --git a/routes/api/plugin/builtin/loginconsentui.ts b/routes/api/plugin/builtin/loginconsentui.ts
index bcc573c6..e2e6490d 100644
--- a/routes/api/plugin/builtin/loginconsentui.ts
+++ b/routes/api/plugin/builtin/loginconsentui.ts
@@ -1,166 +1,288 @@
-const axios = require('axios');
-const {
+import axios, {AxiosResponse} from 'axios';
+import {
LOGIN_CONSENT_RESPONSE_VDXF_KEY,
LOGIN_CONSENT_WEBHOOK_VDXF_KEY,
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
- IDENTITY_UPDATE_RESPONSE_VDXF_KEY,
ResponseURI,
-} = require("verus-typescript-primitives");
-const { pushMessage } = require('../../../ipc/ipc');
-const { ReservedPluginTypes } = require('../../utils/plugin/builtin');
-const { shell } = require('electron')
-const { URL } = require('url');
-const base64url = require('base64url');
-
-module.exports = (api) => {
- api.loginConsentUi = {}
-
- api.loginConsentUi.handle_redirect = (responseKey, response, redirectinfo) => {
- const { type, uri } = redirectinfo;
-
- let processedType = type;
-
- // Type can either be a string vdxfkey or a BN converted into a number.
- const usesResponseUri = responseKey === IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid;
- if (usesResponseUri) {
- const responseUri = ResponseURI.fromJson(redirectinfo);
- processedType = responseUri.type;
+ GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY,
+} from 'verus-typescript-primitives';
+import {pushMessage} from '../../../ipc/ipc';
+import {ReservedPluginTypes} from '../../utils/plugin/builtin';
+import {shell, BrowserWindow} from 'electron';
+import base64url from 'base64url';
+
+interface RedirectInfo {
+ type: string;
+ uri: string;
+}
+
+interface OriginInfo {
+ id: string;
+ search_builtin: boolean;
+}
+
+interface ResponseURIJson {
+ type: string;
+ uri: string;
+}
+
+interface SingleURIResult {
+ type: 'v1';
+ responseKey: string;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ response: any;
+ redirect: RedirectInfo;
+}
+
+interface MultiURIResult {
+ type: 'v2';
+ response: string;
+ uris: ResponseURIJson[];
+}
+
+type DeeplinkResponse = SingleURIResult | MultiURIResult | {error: string};
+
+interface RequestBody {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ request: any;
+}
+
+interface ApiHeader {
+ app_id: string;
+ builtin: boolean;
+}
+
+interface Request {
+ body: RequestBody;
+ api_header: ApiHeader;
+}
+
+interface Response {
+ send: (data: string) => void;
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+type AnyApi = any;
+
+// Temporary typing before the rest of the project is converted.
+interface Api {
+ loginConsentUi: {
+ handle_redirect: (
+ responseKey: string,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ response: any,
+ redirectinfo: RedirectInfo
+ ) => Promise | null;
+ handle_multi_uris: (
+ responseKey: string,
+ response: string,
+ uris: ResponseURIJson[]
+ ) => Promise;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ deeplink: (deeplink: any, originInfo: OriginInfo) => Promise;
+ };
+ minimizeApp: () => void;
+ startPlugin: (
+ type: string,
+ builtin: boolean,
+ onComplete: (data: DeeplinkResponse) => void,
+ onFinishLoad: (pluginWindow: BrowserWindow) => void,
+ width: number,
+ height: number,
+ frame: boolean
+ ) => void;
+ setPost: (path: string, handler: (req: Request, res: Response) => Promise) => void;
+}
+
+// Wraps shell.openExternal to prevent opening any urls that don't go to the browser for security reasons.
+function safeOpenExternal(url: URL): void {
+ if (!['https:', 'http:'].includes(url.protocol)) {
+ return null;
+ }
+
+ try {
+ shell.openExternal(url.toString());
+ } catch (error) {
+ console.error('Failed to open URL:', error);
+ }
+}
+
+export = (api: AnyApi): Api => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api.loginConsentUi = {} as any;
+
+ // Handles the multiple responses in V2 requests.
+ api.loginConsentUi.respond = async (response: string, uris: ResponseURIJson[]): Promise => {
+ if (!uris || uris.length === 0) return;
+
+ // Convert JSON objects to ResponseURI instances and find the first POST URI, fallback to REDIRECT
+ const responseUris = uris.map(uri => ResponseURI.fromJson(uri));
+ const selectedUri =
+ responseUris.find(uri => uri.type.eq(ResponseURI.TYPE_POST)) ??
+ responseUris.find(uri => uri.type.eq(ResponseURI.TYPE_REDIRECT));
+
+ if (!selectedUri) return;
+
+ // Deserialize the response from hex string to Buffer
+ const responseBuffer = Buffer.from(response, 'hex');
+
+ // Handle POST URI
+ if (selectedUri.type.eq(ResponseURI.TYPE_POST)) {
+ setTimeout(() => {
+ api.minimizeApp();
+ }, 250);
+
+ const uri = selectedUri.getUriString();
+
+ try {
+ await axios.post(uri, responseBuffer, {
+ headers: {'Content-Type': 'application/octet-stream'},
+ });
+ } catch (e) {
+ console.error(`Failed to post to webhook ${e}`);
+ }
+ return;
}
- const post = async () => {
+ // Handle REDIRECT URI
+ if (selectedUri.type.eq(ResponseURI.TYPE_REDIRECT)) {
+ const url = new URL(selectedUri.getUriString());
+
+ // TODO: Use the response key when the library is updated
+ url.searchParams.set(GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY.vdxfid, base64url(responseBuffer));
+ safeOpenExternal(url);
+ }
+ };
+
+ // Handles the old redirect URIs in V1 requests.
+ api.loginConsentUi.handle_redirect = (
+ responseKey: string,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ response: any,
+ redirectinfo: RedirectInfo
+ ): Promise => {
+ const {type, uri} = redirectinfo;
+
+ const post = async (): Promise => {
// Add a slight delay to allow the user to see the desktop GUI briefly.
setTimeout(() => {
api.minimizeApp();
}, 250);
- let result
try {
- result = await axios.post(
- uri,
- response
- );
+ await axios.post(uri, response);
} catch (e) {
- console.error(`Failed to post to webhook ${e}`)
+ console.error(`Failed to post to webhook ${e}`);
}
-
- return result;
+
+ return;
};
- const redirect = async () => {
+ const redirect = async (): Promise => {
const url = new URL(uri);
- // Prevent opening any urls that don't go to the browser for security reasons.
- if (!['https:', 'http:'].includes(url.protocol)) {
- return null;
- }
-
- let res;
+ let res: LoginConsentResponse;
switch (responseKey) {
case LOGIN_CONSENT_RESPONSE_VDXF_KEY.vdxfid:
- res = new LoginConsentResponse(response)
- break;
-
- case IDENTITY_UPDATE_RESPONSE_VDXF_KEY.vdxfid:
- // Always convert from JSON when handling Identity Update Responses
- // since they need to be sent as JSON from the plugin to avoid
- // issues with the response being malformed.
- res = IdentityUpdateResponse.fromJson(response);
+ res = new LoginConsentResponse(response);
break;
default:
throw new Error(`Unsupported response key for redirecting: ${responseKey}`);
}
- url.searchParams.set(
- responseKey,
- base64url(res.toBuffer())
- );
+ url.searchParams.set(responseKey, base64url(res.toBuffer()));
- shell.openExternal(url.toString());
- return null;
+ safeOpenExternal(url);
};
- const handlers = {
+ const handlers: Record Promise> = {
[LOGIN_CONSENT_WEBHOOK_VDXF_KEY.vdxfid]: post,
[LOGIN_CONSENT_REDIRECT_VDXF_KEY.vdxfid]: redirect,
- [ResponseURI.TYPE_POST]: post,
- [ResponseURI.TYPE_REDIRECT]: redirect,
};
- return handlers[processedType] == null ? null : handlers[processedType]();
- }
+ return handlers[type]?.() ?? Promise.resolve();
+ };
api.loginConsentUi.deeplink = async (
- deeplink,
- originInfo
- ) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ deeplink: any,
+ originInfo: OriginInfo
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ ): Promise => {
return new Promise((resolve, reject) => {
- try {
- api.startPlugin(
- ReservedPluginTypes.VERUS_LOGIN_CONSENT_UI,
- true,
- (data) => {
- try {
- if (data.redirect) {
- api.loginConsentUi.handle_redirect(
- data.responseKey,
- data.response,
- data.redirect
- );
- }
- resolve(data.response);
- } catch(e) {
- reject(e)
+ api.startPlugin(
+ ReservedPluginTypes.VERUS_LOGIN_CONSENT_UI,
+ true,
+ async (data: DeeplinkResponse) => {
+ try {
+ if ('error' in data) {
+ reject(new Error(data.error));
+ return;
}
- },
- (pluginWindow) => {
- pushMessage(
- pluginWindow,
- {
- deeplink: deeplink,
- origin_app_info: originInfo,
- },
- "VERUS_LOGIN_CONSENT_REQUEST"
- );
- },
- 830,
- 550,
- false
- );
- } catch (e) {
- reject(e);
- }
+
+ // Handle v2 multi-URI result
+ if (data.type === 'v2') {
+ await api.loginConsentUi.respond(data.response, data.uris);
+ } else if (data.type === 'v1') {
+ // Handle v1 single-URI result
+ await api.loginConsentUi.handle_redirect(
+ data.responseKey,
+ data.response,
+ data.redirect
+ );
+ }
+
+ resolve(data.response);
+ } catch (e) {
+ reject(e);
+ }
+ },
+ (pluginWindow: BrowserWindow) => {
+ pushMessage(
+ pluginWindow,
+ {
+ deeplink: deeplink,
+ origin_app_info: originInfo,
+ },
+ 'VERUS_LOGIN_CONSENT_REQUEST'
+ );
+ },
+ 830,
+ 550,
+ false
+ );
});
};
- api.setPost('/plugin/builtin/verus_login_consent_ui/request', async (req, res, next) => {
- const { request } = req.body;
- const { app_id, builtin } = req.api_header
-
- try {
- const retObj = {
- msg: "success",
- result: await api.loginConsentUi.deeplink(
- request,
- {
+ api.setPost(
+ '/plugin/builtin/verus_login_consent_ui/request',
+ async (req: Request, res: Response) => {
+ const {request} = req.body;
+ const {app_id, builtin} = req.api_header;
+
+ try {
+ const retObj = {
+ msg: 'success',
+ result: await api.loginConsentUi.deeplink(request, {
id: app_id,
search_builtin: builtin,
- }
- ),
- };
+ }),
+ };
- res.send(JSON.stringify(retObj));
- } catch (e) {
- const retObj = {
- msg: 'error',
- result: e.message,
- };
+ res.send(JSON.stringify(retObj));
+ } catch (e) {
+ const retObj = {
+ msg: 'error',
+ result: (e as Error).message,
+ };
- res.send(JSON.stringify(retObj));
+ res.send(JSON.stringify(retObj));
+ }
}
- });
+ );
return api;
-};
\ No newline at end of file
+};
From edfd3c9617e03c0014f67652d4feaca6bff92d99 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 30 Jan 2026 18:48:57 -0800
Subject: [PATCH 58/80] Update verus libraries.
---
yarn.lock | 90 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 72 insertions(+), 18 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index cdc16288..12a379c6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1640,7 +1640,12 @@ base64id@2.0.0, base64id@~2.0.0:
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
-base64url@3.0.1, "base64url@git+https://github.com/VerusCoin/base64url.git":
+base64url@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
+ integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
+
+"base64url@git+https://github.com/VerusCoin/base64url.git":
version "3.0.1"
resolved "git+https://github.com/VerusCoin/base64url.git#3217a593e0e665078aa4a71c9f887f8d2e5424fb"
@@ -2001,7 +2006,7 @@ bs58@^3.0.0, bs58@^3.1.0:
bs58@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
- integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo=
+ integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==
dependencies:
base-x "^3.0.2"
@@ -2344,13 +2349,22 @@ cids@^0.7.1:
multicodec "^1.0.0"
multihashes "~0.4.15"
-cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.5.tgz#749f80731c7821e9a5fabd51f6998b696f296686"
- integrity sha512-xq7ICKB4TMHUx7Tz1L9O2SGKOhYMOTR32oir45Bq28/AQTpHogKgHcoYFSdRbMtddl+ozNXfXY9jWcgYKmde0w==
+cipher-base@^1.0.0, cipher-base@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
+ integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+cipher-base@^1.0.1:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.7.tgz#bd094bfef42634ccfd9e13b9fc73274997111e39"
+ integrity sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==
dependencies:
inherits "^2.0.4"
safe-buffer "^5.2.1"
+ to-buffer "^1.2.2"
class-is@^1.1.0:
version "1.1.0"
@@ -4715,13 +4729,15 @@ hash-base@^2.0.0:
dependencies:
inherits "^2.0.1"
-hash-base@^3.0.0:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
- integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
+hash-base@^3.0.0, hash-base@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.2.tgz#79d72def7611c3f6e3c3b5730652638001b10a74"
+ integrity sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==
dependencies:
- inherits "^2.0.1"
- safe-buffer "^5.0.1"
+ inherits "^2.0.4"
+ readable-stream "^2.3.8"
+ safe-buffer "^5.2.1"
+ to-buffer "^1.2.1"
hash.js@1.1.3:
version "1.1.3"
@@ -7561,6 +7577,19 @@ readable-stream@^2.0.2:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
+readable-stream@^2.3.8:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
@@ -7828,7 +7857,7 @@ ripemd160@^1.0.0:
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e"
integrity sha512-J0YlH2ow/i7d5PJX9RC1XnjmZc7cNNYWe89PIlFszvHeiEtxzA1/VYePkjQ7l1SkUejAcHeDo3IVp2WIzstXXQ==
-ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
+ripemd160@^2.0.0, ripemd160@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
@@ -7836,6 +7865,14 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
hash-base "^3.0.0"
inherits "^2.0.1"
+ripemd160@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.3.tgz#9be54e4ba5e3559c8eee06a25cd7648bbccdf5a8"
+ integrity sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==
+ dependencies:
+ hash-base "^3.1.2"
+ inherits "^2.0.4"
+
rlp@^2.2.3:
version "2.2.6"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c"
@@ -7885,12 +7922,12 @@ safe-buffer@5.0.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
integrity sha512-cr7dZWLwOeaFBLTIuZeYdkfO7UzGIKhjYENJFAxUOMKWGaWDm2nJM2rzxNRm5Owu0DH3ApwNo6kx5idXZfb/Iw==
-safe-buffer@5.2.1, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
+safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0:
+safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
@@ -8073,7 +8110,15 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
-sha.js@^2.3.6, sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8:
+sha.js@^2.3.6, sha.js@^2.4.8:
+ version "2.4.11"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
+ integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+sha.js@^2.4.0, sha.js@^2.4.11:
version "2.4.12"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f"
integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==
@@ -8828,6 +8873,15 @@ to-buffer@^1.2.0:
safe-buffer "^5.2.1"
typed-array-buffer "^1.0.3"
+to-buffer@^1.2.1, to-buffer@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133"
+ integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==
+ dependencies:
+ isarray "^2.0.5"
+ safe-buffer "^5.2.1"
+ typed-array-buffer "^1.0.3"
+
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
@@ -9317,7 +9371,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys":
version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#68afe0a4a95cff57be07925f7b575658f8063617"
+ resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#10e8bb13c5ec788dd75ac120deef78841d127650"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -9347,7 +9401,7 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys":
version "0.1.0"
- resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#fcd27b5d915005202c84570a0df607b7d126f42d"
+ resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#3514847c578b44e3463693de78500f15c59aef17"
dependencies:
axios "1.7.4"
verus-typescript-primitives "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys"
From e5c9f398704bc1131086f8270746ecd24f3078d2 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:11:00 -0800
Subject: [PATCH 59/80] Start updating the identity update request execution to
typescript.
---
...teIdentityUpdateRequest.js => executeIdentityUpdateRequest.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename routes/api/native/verusid/identity/{executeIdentityUpdateRequest.js => executeIdentityUpdateRequest.ts} (100%)
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.js b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
similarity index 100%
rename from routes/api/native/verusid/identity/executeIdentityUpdateRequest.js
rename to routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
From a27d4e1def2b680e63b6b44e89e7fcd74103f2aa Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:40:05 -0800
Subject: [PATCH 60/80] Finish updating the identity update request execution
for requests v2.
---
.../identity/executeIdentityUpdateRequest.ts | 104 ++++++++++--------
.../identity/signIdentityUpdateResponse.js | 47 --------
.../identity/verifyIdentityUpdateRequest.js | 43 --------
3 files changed, 58 insertions(+), 136 deletions(-)
delete mode 100644 routes/api/native/verusid/identity/signIdentityUpdateResponse.js
delete mode 100644 routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 7f7a2529..7b234099 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -1,41 +1,43 @@
-const { IdentityUpdateRequest } = require("verus-typescript-primitives")
-const { encryptCredentialsInContentMultiMap } = require("../../../utils/credentials/encryptCredentials")
-
-module.exports = (api) => {
- api.native.verusid.identity.execute_identity_update_request = async (coin, request) => {
- const identityUpdateRequest = IdentityUpdateRequest.fromJson(request);
+import {IdentityUpdateRequestDetails} from 'verus-typescript-primitives';
+import {encryptCredentialsInContentMultiMap} from '../../../utils/credentials/encryptCredentials';
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+module.exports = (api: any) => {
+ api.native.verusid.identity.execute_identity_update_request = async (
+ coin: string,
+ detail: IdentityUpdateRequestDetails
+ ) => {
// Replace any values that need to be encrypted before updating the identity.
- if (!identityUpdateRequest.details.identity) {
- throw new Error("IdentityUpdateRequest does not contain an identity.");
+ if (!detail.identity) {
+ throw new Error('IdentityUpdateRequest does not contain an identity.');
}
- const address = identityUpdateRequest.details.identity.name;
- const identity = await api.native.get_identity(coin, identityUpdateRequest.details.identity.name);
+ // Change the identity name in the detail to include `@` at the end so that it is valid.
+ detail.identity.name = detail.identity.name + '@';
+ const address = detail.identity.name;
+ const identity = await api.native.get_identity(coin, detail.identity.name);
const zaddress = identity.identity.privateaddress;
-
+
if (!zaddress) {
throw new Error(`No z-address found for identity ${address}`);
}
+ console.log('Generating the viewing key and encryption address to encrypt the credentials.');
+
// Generate the viewing key and encryption address to encrypt the credentials.
- const encryptionAddressInfo = await api.native.z_get_encryption_address(
- coin,
- {
- address: zaddress,
- fromid: address,
- toid: address
- }
- );
+ const encryptionAddressInfo = await api.native.z_get_encryption_address(coin, {
+ address: zaddress,
+ fromid: address,
+ toid: address,
+ });
- if (!encryptionAddressInfo
- || !encryptionAddressInfo.address
- || !encryptionAddressInfo.ivk
- ) {
+ if (!encryptionAddressInfo || !encryptionAddressInfo.address || !encryptionAddressInfo.ivk) {
throw new Error(`Failed to get the personal encryption address for ${address}`);
}
- const contentmultimap = identityUpdateRequest.details.identity.content_multimap;
+ console.log('Encrypting the credentials.');
+
+ const contentmultimap = detail.identity.content_multimap;
if (contentmultimap) {
await encryptCredentialsInContentMultiMap(
@@ -48,33 +50,43 @@ module.exports = (api) => {
);
}
- const txid = await api.native.update_identity(
- coin,
- identityUpdateRequest.details.toCLIJson()
- );
+ console.log('Updating the identity: ', detail);
+
+ const txid = await api.native.update_identity(coin, detail.toCLIJson());
- return { txid: txid };
+ console.log('Transaction ID: ', txid);
+
+ return {txid: txid};
};
- api.setPost("/native/verusid/identity/execute_identity_update_request", async (req, res, next) => {
- const { chainTicker, request } = req.body;
+ api.setPost(
+ '/native/verusid/identity/execute_identity_update_request',
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async (req: any, res: any) => {
+ const {chainTicker, detailJSON} = req.body;
- try {
- res.send(
- JSON.stringify({
- msg: "success",
- result: await api.native.verusid.identity.execute_identity_update_request(chainTicker, request),
- })
- );
- } catch (e) {
- res.send(
- JSON.stringify({
- msg: "error",
- result: e.message,
- })
- );
+ try {
+ const detail = IdentityUpdateRequestDetails.fromJson(detailJSON);
+
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ result: await api.native.verusid.identity.execute_identity_update_request(
+ chainTicker,
+ detail
+ ),
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: 'error',
+ result: e.message,
+ })
+ );
+ }
}
- });
+ );
return api;
};
diff --git a/routes/api/native/verusid/identity/signIdentityUpdateResponse.js b/routes/api/native/verusid/identity/signIdentityUpdateResponse.js
deleted file mode 100644
index 087ec004..00000000
--- a/routes/api/native/verusid/identity/signIdentityUpdateResponse.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const {
- VerusIDSignature,
- IdentityUpdateResponse,
- LOGIN_CONSENT_RESPONSE_SIG_VDXF_KEY,
-} = require("verus-typescript-primitives");
-
-module.exports = (api) => {
- api.native.verusid.identity.sign_identity_update_response = async (coin, response) => {
- const identityUpdateResponse = IdentityUpdateResponse.fromJson(response);
-
- const signdataResult = await api.native.sign_data(coin,
- {
- "address": identityUpdateResponse.signingid.toAddress(),
- "datahash": identityUpdateResponse.details.toSha256().toString("hex")
- }
- )
-
- identityUpdateResponse.signature = new VerusIDSignature(
- { signature: signdataResult.signature },
- LOGIN_CONSENT_RESPONSE_SIG_VDXF_KEY
- );
-
- return { response: identityUpdateResponse.toJson()};
- };
-
- api.setPost("/native/verusid/identity/sign_identity_update_response", async (req, res, next) => {
- const { chainTicker, response } = req.body;
-
- try {
- res.send(
- JSON.stringify({
- msg: "success",
- result: await api.native.verusid.identity.sign_identity_update_response(chainTicker, response),
- })
- );
- } catch (e) {
- res.send(
- JSON.stringify({
- msg: "error",
- result: e.message,
- })
- );
- }
- });
-
- return api;
-};
diff --git a/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js b/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
deleted file mode 100644
index 27e4afa1..00000000
--- a/routes/api/native/verusid/identity/verifyIdentityUpdateRequest.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const { IdentityUpdateRequest, IDENTITY_UPDATE_REQUEST_VDXF_KEY } = require("verus-typescript-primitives")
-
-module.exports = (api) => {
- /**
- * Verifies an identity update request
- * @param {IdentityUpdateRequest} Request
- */
- api.native.verusid.identity.verify_identity_update_request = async (coin, request) => {
- const identityUpdateRequest = IdentityUpdateRequest.fromJson(request);
-
- const verified = await api.native.verify_hash(
- coin,
- identityUpdateRequest.signingid.toAddress(),
- identityUpdateRequest.details.toSha256().toString('hex'),
- // The nesting of the signature does not match the expected structure.
- identityUpdateRequest.signature.signature.signature
- );
-
- return verified ? { verified } : { verified, message: "Failed to verify signature" };
- };
-
- api.setPost("/native/verusid/identity/verify_identity_update_request", async (req, res, next) => {
- const { chainTicker, request } = req.body;
-
- try {
- res.send(
- JSON.stringify({
- msg: "success",
- result: await api.native.verusid.identity.verify_identity_update_request(chainTicker, request),
- })
- );
- } catch (e) {
- res.send(
- JSON.stringify({
- msg: "error",
- result: e.message,
- })
- );
- }
- });
-
- return api;
-};
\ No newline at end of file
From 954d045c28a4174b1b5815b5a2e0d92c41bbc8f6 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 10 Feb 2026 17:17:05 -0800
Subject: [PATCH 61/80] Support executing and encrypting the app encryption
request
---
.../generic/encryptAppEncryptionResponse.ts | 72 ++++++++++++++++++
.../generic/executeAppEncryptionRequest.ts | 73 +++++++++++++++++++
.../identity/executeIdentityUpdateRequest.ts | 8 --
routes/api/native/verusid/verusid.js | 20 ++---
4 files changed, 155 insertions(+), 18 deletions(-)
create mode 100644 routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
create mode 100644 routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
diff --git a/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
new file mode 100644
index 00000000..d52b7f25
--- /dev/null
+++ b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
@@ -0,0 +1,72 @@
+import {
+ AppEncryptionResponseDetails,
+ AppEncryptionResponseDetailsJson,
+ DataDescriptor,
+} from 'verus-typescript-primitives';
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default (api: any) => {
+ api.native.verusid.generic.encrypt_app_encryption_response = async (
+ coin: string,
+ detail: AppEncryptionResponseDetails,
+ identity: string,
+ zaddress: string
+ ) => {
+ const signdataResult = await api.native.sign_data(coin, {
+ address: identity,
+ messagehex: detail.toBuffer().toString('hex'),
+ encrypttoaddress: zaddress,
+ });
+
+ const encryptedDescriptor = signdataResult.mmrdescriptor_encrypted;
+
+ if (
+ !encryptedDescriptor ||
+ !encryptedDescriptor.datadescriptors ||
+ encryptedDescriptor.datadescriptors.length === 0
+ ) {
+ throw new Error('No encrypted data descriptor returned from signdata');
+ }
+
+ const dataDescriptor = DataDescriptor.fromJson(encryptedDescriptor.datadescriptors[0]);
+
+ return dataDescriptor.toJson();
+ };
+
+ api.setPost(
+ '/native/verusid/generic/encrypt_app_encryption_response',
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async (req: any, res: any) => {
+ const {chainTicker, detailJSON, identity, zaddress} = req.body;
+
+ try {
+ const detail = AppEncryptionResponseDetails.fromJson(
+ detailJSON as AppEncryptionResponseDetailsJson
+ );
+
+ const result = await api.native.verusid.generic.encrypt_app_encryption_response(
+ chainTicker,
+ detail,
+ identity,
+ zaddress
+ );
+
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ result: result,
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: 'error',
+ result: e.message,
+ })
+ );
+ }
+ }
+ );
+
+ return api;
+};
diff --git a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
new file mode 100644
index 00000000..14561991
--- /dev/null
+++ b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
@@ -0,0 +1,73 @@
+import {AppEncryptionRequestDetails} from 'verus-typescript-primitives';
+
+interface AppEncryptionResult {
+ incomingViewingKey: string;
+ extendedViewingKey: string;
+ address: string;
+ extendedSpendingKey?: string;
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default (api: any) => {
+ api.native.verusid.generic.execute_app_encryption_request = async (
+ coin: string,
+ detail: AppEncryptionRequestDetails,
+ fromID: string,
+ toID: string
+ ): Promise => {
+ const walletinfo = await api.native.callDaemon(coin, 'getwalletinfo', []);
+ const seed = walletinfo.seedfp;
+
+ // TODO: Add fetching returnsecret via RETURN_ESK from the detail
+ // once it is able to be handled.
+
+ const keys = await api.native.z_get_encryption_address(coin, {
+ seed: seed,
+ hdindex: detail.derivationNumber.toNumber(),
+ fromid: fromID,
+ toid: toID,
+ });
+
+ return {
+ extendedViewingKey: keys.extendedviewingkey,
+ incomingViewingKey: keys.ivk,
+ address: keys.address,
+ extendedSpendingKey: keys?.extendedspendingkey,
+ };
+ };
+
+ api.setPost(
+ '/native/verusid/generic/execute_app_encryption_request',
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async (req: any, res: any) => {
+ const {chainTicker, detailJSON, fromID, toID} = req.body;
+
+ try {
+ const detail = AppEncryptionRequestDetails.fromJson(detailJSON);
+
+ const result = await api.native.verusid.generic.execute_app_encryption_request(
+ chainTicker,
+ detail,
+ fromID,
+ toID
+ );
+
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ result: result,
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: 'error',
+ result: e.message,
+ })
+ );
+ }
+ }
+ );
+
+ return api;
+};
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 7b234099..49f239b1 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -22,8 +22,6 @@ module.exports = (api: any) => {
throw new Error(`No z-address found for identity ${address}`);
}
- console.log('Generating the viewing key and encryption address to encrypt the credentials.');
-
// Generate the viewing key and encryption address to encrypt the credentials.
const encryptionAddressInfo = await api.native.z_get_encryption_address(coin, {
address: zaddress,
@@ -35,8 +33,6 @@ module.exports = (api: any) => {
throw new Error(`Failed to get the personal encryption address for ${address}`);
}
- console.log('Encrypting the credentials.');
-
const contentmultimap = detail.identity.content_multimap;
if (contentmultimap) {
@@ -50,12 +46,8 @@ module.exports = (api: any) => {
);
}
- console.log('Updating the identity: ', detail);
-
const txid = await api.native.update_identity(coin, detail.toCLIJson());
- console.log('Transaction ID: ', txid);
-
return {txid: txid};
};
diff --git a/routes/api/native/verusid/verusid.js b/routes/api/native/verusid/verusid.js
index cc2a5c82..ecade0cf 100644
--- a/routes/api/native/verusid/verusid.js
+++ b/routes/api/native/verusid/verusid.js
@@ -1,19 +1,17 @@
-module.exports = (api) => {
- api.native.verusid = {}
- api.native.verusid.login = {}
- api.native.verusid.provision = {}
- api.native.verusid.identity = {}
- api.native.verusid.generic = {}
+module.exports = api => {
+ api.native.verusid = {};
+ api.native.verusid.login = {};
+ api.native.verusid.provision = {};
+ api.native.verusid.identity = {};
+ api.native.verusid.generic = {};
// Identity
- require('./identity/verifyIdentityUpdateRequest')(api);
require('./identity/executeIdentityUpdateRequest')(api);
- require('./identity/signIdentityUpdateResponse')(api);
-
+
// Login
require('./login/verifyRequest')(api);
require('./login/signResponse')(api);
-
+
// Provisioning
require('./provision/signIdProvisioningRequest')(api);
require('./provision/verifyIdProvisioningResponse')(api);
@@ -21,6 +19,8 @@ module.exports = (api) => {
// Generic
require('./generic/verifyGenericRequest')(api);
require('./generic/signGenericResponse').default(api);
+ require('./generic/executeAppEncryptionRequest').default(api);
+ require('./generic/encryptAppEncryptionResponse').default(api);
return api;
};
From 7f591936be62c476ed1bd0980ce40400562b7e83 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 13 Feb 2026 11:25:51 -0800
Subject: [PATCH 62/80] Add the signdata API endpoint and improve formatting in
signdata.js.
---
routes/api/native/signdata.js | 161 +++++++++++++---------------------
1 file changed, 63 insertions(+), 98 deletions(-)
diff --git a/routes/api/native/signdata.js b/routes/api/native/signdata.js
index f3422d4b..bcc494cd 100644
--- a/routes/api/native/signdata.js
+++ b/routes/api/native/signdata.js
@@ -1,130 +1,83 @@
-
-module.exports = (api) => {
+module.exports = api => {
/**
* Signs a message given the message, and an identity/address currently in the wallet
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to sign the message
* @param {String} message The message to verify
* @param {String} cursig The current signature if multisig
*/
- api.native.sign_message = (
- coin,
- address,
- message,
- cursig = ""
- ) => {
+ api.native.sign_message = (coin, address, message, cursig = '') => {
return new Promise((resolve, reject) => {
api.native
- .callDaemon(
- coin,
- "signmessage",
- [
- address,
- message,
- cursig
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
+ .callDaemon(coin, 'signmessage', [address, message, cursig])
+ .then(resultObj => {
+ resolve(resultObj);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
/**
* Signs a file given the file, and an identity/address currently in the wallet
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to sign the file
* @param {String} file The file to verify
* @param {String} cursig The current signature if multisig
*/
- api.native.sign_file = (
- coin,
- address,
- file,
- cursig = ""
- ) => {
+ api.native.sign_file = (coin, address, file, cursig = '') => {
return new Promise((resolve, reject) => {
api.native
- .callDaemon(
- coin,
- "signfile",
- [
- address,
- file,
- cursig
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
+ .callDaemon(coin, 'signfile', [address, file, cursig])
+ .then(resultObj => {
+ resolve(resultObj);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
/**
* Signs data given the parameters including an identity/address currently in the wallet
* and the data to be signed
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {Object} params The parameters to pass to signdata
*/
- api.native.sign_data = (
- coin,
- params,
- ) => {
+ api.native.sign_data = (coin, params) => {
return new Promise((resolve, reject) => {
api.native
- .callDaemon(
- coin,
- "signdata",
- [
- params,
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
+ .callDaemon(coin, 'signdata', [params])
+ .then(resultObj => {
+ resolve(resultObj);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
-
api.setPost('/native/sign_message', (req, res) => {
- const {
- chainTicker,
- address,
- data,
- cursig
- } = req.body;
+ const {chainTicker, address, data, cursig} = req.body;
api.native
- .sign_message(
- chainTicker,
- address,
- data,
- cursig
- )
+ .sign_message(chainTicker, address, data, cursig)
.then(resultObj => {
const retObj = {
- msg: "success",
- result: resultObj
+ msg: 'success',
+ result: resultObj,
};
res.send(JSON.stringify(retObj));
})
.catch(error => {
const retObj = {
- msg: "error",
- result: error.message
+ msg: 'error',
+ result: error.message,
};
res.send(JSON.stringify(retObj));
@@ -132,37 +85,49 @@ module.exports = (api) => {
});
api.setPost('/native/sign_file', (req, res) => {
- const {
- chainTicker,
- address,
- data,
- cursig
- } = req.body;
+ const {chainTicker, address, data, cursig} = req.body;
api.native
- .sign_file(
- chainTicker,
- address,
- data,
- cursig
- )
+ .sign_file(chainTicker, address, data, cursig)
.then(resultObj => {
const retObj = {
- msg: "success",
- result: resultObj
+ msg: 'success',
+ result: resultObj,
};
res.send(JSON.stringify(retObj));
})
.catch(error => {
const retObj = {
- msg: "error",
- result: error.message
+ msg: 'error',
+ result: error.message,
};
res.send(JSON.stringify(retObj));
});
});
+ api.setPost('/native/sign_data', async (req, res) => {
+ const {chainTicker, params} = req.body;
+
+ try {
+ const resultObj = await api.native.sign_data(chainTicker, params);
+
+ const retObj = {
+ msg: 'success',
+ result: resultObj,
+ };
+
+ res.send(JSON.stringify(retObj));
+ } catch (error) {
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
+
+ res.send(JSON.stringify(retObj));
+ }
+ });
+
return api;
-};
\ No newline at end of file
+};
From c9e16683cc0af4289417302d945d9ffcdcf1157f Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 26 Feb 2026 17:12:42 -0800
Subject: [PATCH 63/80] Start updating getCredential.js to TypeScript.
---
.../{getCredentials.js => getCredentials.ts} | 153 +++++++-----------
1 file changed, 61 insertions(+), 92 deletions(-)
rename routes/api/native/credentials/{getCredentials.js => getCredentials.ts} (74%)
diff --git a/routes/api/native/credentials/getCredentials.js b/routes/api/native/credentials/getCredentials.ts
similarity index 74%
rename from routes/api/native/credentials/getCredentials.js
rename to routes/api/native/credentials/getCredentials.ts
index 16e4b22c..2a401cae 100644
--- a/routes/api/native/credentials/getCredentials.js
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -2,87 +2,76 @@ const {
DATA_TYPE_OBJECT_DATADESCRIPTOR,
fromBase58Check,
IDENTITY_CREDENTIAL,
-} = require("verus-typescript-primitives");
-const { parseCredential } = require("../../utils/credentials/parseCredential");
+} = require('verus-typescript-primitives');
+const {parseCredential} = require('../../utils/credentials/parseCredential');
-module.exports = (api) => {
+module.exports = api => {
/**
* Extracts and decrypts the list of credentials in the given identity
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to get the credentials from
*/
- api.native.get_credentials_list = async (
- coin,
- address
- ) => {
+ api.native.get_credentials_list = async (coin, address) => {
// Get the z-address and contentmultimap from the address.
const identity = await api.native.get_identity_content(coin, address);
-
+
if (!identity || !identity.identity) {
throw new Error(`Identity not found for ${address}`);
}
const zaddress = identity.identity.privateaddress;
-
+
if (!zaddress) {
throw new Error(`No z-address found for identity ${address}`);
}
-
+
// Generate the viewing key to decrypt the credentials.
- const keys = await api.native.z_get_encryption_address(
- coin,
- {
- address: zaddress,
- fromid: address,
- toid: address
- }
- );
-
+ const keys = await api.native.z_get_encryption_address(coin, {
+ address: zaddress,
+ fromid: address,
+ toid: address,
+ });
+
if (!keys || !keys.extendedviewingkey || !keys.ivk) {
throw new Error(`Failed to get keys for ${address}`);
}
-
+
const evk = keys.extendedviewingkey;
const ivk = keys.ivk;
-
+
// Generate the credential key using the ivk.
- const credentialKeyResult = await api.native.get_vdxf_id(
- coin,
- IDENTITY_CREDENTIAL.vdxfid,
- { uint256: ivk }
- );
-
+ const credentialKeyResult = await api.native.get_vdxf_id(coin, IDENTITY_CREDENTIAL.vdxfid, {
+ uint256: ivk,
+ });
+
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
- throw new Error("Failed to generate credential key");
+ throw new Error('Failed to generate credential key');
}
-
+
const credentialKey = credentialKeyResult.vdxfid;
-
+
if (!identity.identity.contentmultimap || !identity.identity.contentmultimap[credentialKey]) {
return [];
}
const credentialEntries = identity.identity.contentmultimap[credentialKey];
const credentials = [];
-
+
for (const entry of credentialEntries) {
// Convert single univalues to an array to make the processing consistent.
const entriesToProcess = Array.isArray(entry) ? entry : [entry];
-
+
for (const singleEntry of entriesToProcess) {
if (singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid]) {
const dataDescriptor = singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid];
-
+
try {
- const decryptedData = await api.native.decrypt_data(
- coin,
- {
- datadescriptor: dataDescriptor,
- evk: evk
- }
- );
-
+ const decryptedData = await api.native.decrypt_data(coin, {
+ datadescriptor: dataDescriptor,
+ evk: evk,
+ });
+
// The data descriptor is in a list.
if (decryptedData && Array.isArray(decryptedData)) {
const credObj = decryptedData[0];
@@ -96,33 +85,30 @@ module.exports = (api) => {
}
}
}
-
+
return credentials;
};
/**
* Creates a map of credentials organized by scope
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to get the credentials from
*/
- api.native.get_credentials_map = async (
- coin,
- address
- ) => {
+ api.native.get_credentials_map = async (coin, address) => {
// Get the list of credentials.
const credentialsList = await api.native.get_credentials_list(coin, address);
-
+
const credentialsMap = {};
-
+
// Track seen credential keys by scope to avoid duplicates.
const seenCredentials = {};
-
- // Process each credential and organize by the main scope in reverse order so
+
+ // Process each credential and organize by the main scope in reverse order so
// the newest credentials are first.
for (let i = credentialsList.length - 1; i >= 0; i--) {
const credential = credentialsList[i];
-
+
// Try to convert the main scope into an i-address, if it isn't one already.
let mainScope = credential.scopes[0];
try {
@@ -139,83 +125,66 @@ module.exports = (api) => {
}
const credentialKey = credential.credentialKey;
-
+
if (!credentialsMap[mainScope]) {
credentialsMap[mainScope] = [];
}
-
+
if (!seenCredentials[mainScope]) {
seenCredentials[mainScope] = new Set();
}
-
- // Skip duplicate credentials that come later since they are
+
+ // Skip duplicate credentials that come later since they are
// the previous credentials for that scope.
if (!seenCredentials[mainScope].has(credentialKey)) {
credentialsMap[mainScope].push(credential);
seenCredentials[mainScope].add(credentialKey);
}
}
-
+
return credentialsMap;
};
/**
* Creates a map of credentials organized by scope
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {String} address The identity or address to get the credentials from
* @param {String} scope The scope of the credentials to get
* @param {string[]} credentialKeys - Optional list of credential keys to filter the result by
*/
- api.native.get_credentials_by_scope = async (
- coin,
- address,
- scope,
- credentialKeys
- ) => {
+ api.native.get_credentials_by_scope = async (coin, address, scope, credentialKeys) => {
const credentialsMap = await api.native.get_credentials_map(coin, address);
const scopeCredentials = credentialsMap[scope] || [];
-
+
if (!credentialKeys || credentialKeys.length === 0) {
return scopeCredentials;
}
- return scopeCredentials.filter(cred =>
- credentialKeys.includes(cred.credentialKey)
- );
+ return scopeCredentials.filter(cred => credentialKeys.includes(cred.credentialKey));
};
- api.setPost("/native/get_credentials_by_scope", async (req, res, next) => {
- const {
- coin,
- address,
- scope,
- credentialKeys
- } = req.body;
+ api.setPost('/native/get_credentials_by_scope', async (req, res, next) => {
+ const {coin, address, scope, credentialKeys} = req.body;
api.native
- .get_credentials_by_scope(
- coin,
- address,
- scope,
- credentialKeys
- )
+ .get_credentials_by_scope(coin, address, scope, credentialKeys)
.then(resultObj => {
- const retObj = {
- msg: "success",
- result: resultObj
- };
+ const retObj = {
+ msg: 'success',
+ result: resultObj,
+ };
- res.send(JSON.stringify(retObj));
+ res.send(JSON.stringify(retObj));
})
.catch(error => {
- const retObj = {
- msg: "error",
- result: error.message
- };
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
- res.send(JSON.stringify(retObj));
+ res.send(JSON.stringify(retObj));
});
});
From 5636266cbc88e2717da0b9c1791a28fb4ba71100 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 26 Feb 2026 19:01:54 -0800
Subject: [PATCH 64/80] Update to the latest version of
verus-typescript-primitives and finish updating getCredentials to TypeScript
to help with the version upgrade.
---
package.json | 4 +-
routes/api.js | 50 +++---
.../api/native/credentials/getCredentials.ts | 166 ++++++++++++------
yarn.lock | 84 +++++----
4 files changed, 177 insertions(+), 127 deletions(-)
diff --git a/package.json b/package.json
index 14e21913..b6776158 100644
--- a/package.json
+++ b/package.json
@@ -78,10 +78,10 @@
"systeminformation": "5.23.8",
"tx-builder": "0.18.0",
"unzipper": "0.10.11",
- "verus-typescript-primitives": "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys",
+ "verus-typescript-primitives": "git+https://github.com/VerusCoin/verus-typescript-primitives.git",
"verus-wallet-endpoints": "git+https://github.com/VerusCoin/verus-wallet-endpoints.git",
"verus_bridgekeeper": "git+https://github.com/VerusCoin/verusbridgekeeper.git",
- "verusd-rpc-ts-client": "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys",
+ "verusd-rpc-ts-client": "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git",
"wif": "2.0.6"
},
"devDependencies": {
diff --git a/routes/api.js b/routes/api.js
index 97689038..a2d6a18b 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -3,8 +3,8 @@ const express = require('express');
let api = express.Router();
api.rpcCalls = {
GET: {},
- POST: {}
-}
+ POST: {},
+};
api.coinsInitializing = {};
api.startedDaemonRegistry = {};
@@ -18,16 +18,16 @@ api.appRuntimeLog = [];
api.plugins = api.plugins = {
registry: {},
- builtin: {}
-}
+ builtin: {},
+};
api.pluginWindows = {
registry: {},
- builtin: {}
-}
+ builtin: {},
+};
api.pluginOnCompletes = {
registry: {},
- builtin: {}
-}
+ builtin: {},
+};
api.lockDownAddCoin = false;
api._isWatchOnly = false;
@@ -59,9 +59,7 @@ api.electrumCache = {};
api.electrumJSCore = require('./electrumjs/electrumjs.core.js');
api.electrumJSNetworks = require('./electrumjs/electrumjs.networks.js');
-const {
- electrumServers,
-} = require('./electrumjs/electrumServers.js');
+const {electrumServers} = require('./electrumjs/electrumServers.js');
api.electrumServers = electrumServers;
api.electrumServersV1_4 = {};
api.nspvProcesses = {};
@@ -77,7 +75,7 @@ api.native = {
tx_cache: {},
addr_balance_cache: {},
currency_definition_cache: {},
- }
+ },
};
// eth
@@ -85,15 +83,15 @@ api.eth = {
wallet: null,
interface: null,
temp: {
- pending_txs: {}
- }
+ pending_txs: {},
+ },
};
// erc20
api.erc20 = {
wallet: null,
- contracts: {}
-}
+ contracts: {},
+};
api.setconf = require('../private/setconf.js');
api.nativeCoind = require('./nativeCoind.js');
@@ -165,7 +163,7 @@ api = require('./api/native/coinSupply.js')(api);
api = require('./api/native/blockSubsidy.js')(api);
api = require('./api/native/shieldcoinbase.js')(api);
api = require('./api/native/verusid/verusid.js')(api);
-api = require('./api/native/credentials/getCredentials.js')(api);
+api = require('./api/native/credentials/getCredentials').default(api);
api = require('./api/native/makeoffer')(api);
api = require('./api/native/getoffers')(api);
api = require('./api/native/closeoffers')(api);
@@ -177,17 +175,17 @@ api = require('./api/native/getNetworkGraph')(api);
api = require('./api/native/verusbridge/verusbridge.js')(api);
api = require('./api/native/verusbridge/vethconf.js')(api);
-// lite
+// lite
api = require('./api/getSignatureInfo.js')(api);
// general network calls
-api.networkFees = {}
-api.coinSupply = {}
-api = require('./api/network/fees/btc/btcFees')(api)
-api = require('./api/network/fees/networkFees')(api)
-api = require('./api/network/supply/vrsc/vrscCoinSupply')(api)
-api = require('./api/network/supply/zec/zecCoinSupply')(api)
-api = require('./api/network/supply/coinSupply')(api)
+api.networkFees = {};
+api.coinSupply = {};
+api = require('./api/network/fees/btc/btcFees')(api);
+api = require('./api/network/fees/networkFees')(api);
+api = require('./api/network/supply/vrsc/vrscCoinSupply')(api);
+api = require('./api/network/supply/zec/zecCoinSupply')(api);
+api = require('./api/network/supply/coinSupply')(api);
// core
api = require('./api/binsUtils.js')(api);
@@ -259,4 +257,4 @@ api = require('./api/diagnostics.js')(api);
api = require('./api/construct')(api);
-module.exports = api;
\ No newline at end of file
+module.exports = api;
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index 2a401cae..7fa47697 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -1,20 +1,49 @@
-const {
- DATA_TYPE_OBJECT_DATADESCRIPTOR,
- fromBase58Check,
+import {
+ DATA_DESCRIPTOR_VDXF_KEY,
IDENTITY_CREDENTIAL,
-} = require('verus-typescript-primitives');
-const {parseCredential} = require('../../utils/credentials/parseCredential');
+ fromBase58Check,
+ Credential,
+ DATA_TYPE_OBJECT_CREDENTIAL,
+} from 'verus-typescript-primitives';
+
+interface EncryptionKeys {
+ extendedviewingkey: string;
+ ivk: string;
+}
+
+interface VdxfIdResult {
+ vdxfid: string;
+}
+
+interface IdentityContent {
+ identity: {
+ privateaddress?: string;
+ contentmultimap?: Record<
+ string,
+ Array | Array>>
+ >;
+ identityaddress?: string;
+ };
+}
-module.exports = api => {
+interface CredentialsMap {
+ [scope: string]: Credential[];
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default (api: any) => {
/**
* Extracts and decrypts the list of credentials in the given identity
*
- * @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} address The identity or address to get the credentials from
+ * @param coin The chainTicker of the coin to make the call on
+ * @param address The identity or address to get the credentials from
*/
- api.native.get_credentials_list = async (coin, address) => {
+ api.native.get_credentials_list = async (
+ coin: string,
+ address: string
+ ): Promise => {
// Get the z-address and contentmultimap from the address.
- const identity = await api.native.get_identity_content(coin, address);
+ const identity: IdentityContent | null = await api.native.get_identity_content(coin, address);
if (!identity || !identity.identity) {
throw new Error(`Identity not found for ${address}`);
@@ -27,7 +56,7 @@ module.exports = api => {
}
// Generate the viewing key to decrypt the credentials.
- const keys = await api.native.z_get_encryption_address(coin, {
+ const keys: EncryptionKeys | null = await api.native.z_get_encryption_address(coin, {
address: zaddress,
fromid: address,
toid: address,
@@ -41,9 +70,11 @@ module.exports = api => {
const ivk = keys.ivk;
// Generate the credential key using the ivk.
- const credentialKeyResult = await api.native.get_vdxf_id(coin, IDENTITY_CREDENTIAL.vdxfid, {
- uint256: ivk,
- });
+ const credentialKeyResult: VdxfIdResult | null = await api.native.get_vdxf_id(
+ coin,
+ IDENTITY_CREDENTIAL.vdxfid,
+ {uint256: ivk}
+ );
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
throw new Error('Failed to generate credential key');
@@ -56,15 +87,17 @@ module.exports = api => {
}
const credentialEntries = identity.identity.contentmultimap[credentialKey];
- const credentials = [];
+ const credentials: Credential[] = [];
for (const entry of credentialEntries) {
// Convert single univalues to an array to make the processing consistent.
- const entriesToProcess = Array.isArray(entry) ? entry : [entry];
+ const entriesToProcess: Array> = Array.isArray(entry)
+ ? entry
+ : [entry];
for (const singleEntry of entriesToProcess) {
- if (singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid]) {
- const dataDescriptor = singleEntry[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid];
+ if (singleEntry[DATA_DESCRIPTOR_VDXF_KEY.vdxfid]) {
+ const dataDescriptor = singleEntry[DATA_DESCRIPTOR_VDXF_KEY.vdxfid];
try {
const decryptedData = await api.native.decrypt_data(coin, {
@@ -74,12 +107,16 @@ module.exports = api => {
// The data descriptor is in a list.
if (decryptedData && Array.isArray(decryptedData)) {
- const credObj = decryptedData[0];
- const cred = parseCredential(credObj);
+ const credObj = decryptedData[0] as Record;
+ const credJson = credObj[DATA_TYPE_OBJECT_CREDENTIAL.vdxfid];
+ const cred = Credential.fromJson(
+ credJson as Parameters[0]
+ );
credentials.push(cred);
}
- } catch (err) {
- console.error(`Failed to decrypt credential: ${err.message}`);
+ } catch (err: unknown) {
+ const message = err instanceof Error ? err.message : String(err);
+ console.error(`Failed to decrypt credential: ${message}`);
// Decrypt the other credentials even if one fails.
}
}
@@ -92,17 +129,20 @@ module.exports = api => {
/**
* Creates a map of credentials organized by scope
*
- * @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} address The identity or address to get the credentials from
+ * @param coin The chainTicker of the coin to make the call on
+ * @param address The identity or address to get the credentials from
*/
- api.native.get_credentials_map = async (coin, address) => {
+ api.native.get_credentials_map = async (
+ coin: string,
+ address: string
+ ): Promise => {
// Get the list of credentials.
- const credentialsList = await api.native.get_credentials_list(coin, address);
+ const credentialsList: Credential[] = await api.native.get_credentials_list(coin, address);
- const credentialsMap = {};
+ const credentialsMap: CredentialsMap = {};
// Track seen credential keys by scope to avoid duplicates.
- const seenCredentials = {};
+ const seenCredentials: Record> = {};
// Process each credential and organize by the main scope in reverse order so
// the newest credentials are first.
@@ -110,9 +150,9 @@ module.exports = api => {
const credential = credentialsList[i];
// Try to convert the main scope into an i-address, if it isn't one already.
- let mainScope = credential.scopes[0];
+ let mainScope = credential.scopes[0] as string;
try {
- fromBase58Check(scope);
+ fromBase58Check(mainScope);
} catch {
try {
const scopeId = await api.native.get_identity(coin, mainScope);
@@ -121,7 +161,9 @@ module.exports = api => {
}
// If there is an error getting the identity, then the scope is not an identity.
// In that case, just leave the scope as is.
- } catch {}
+ } catch {
+ // Scope is not an identity, leave as is.
+ }
}
const credentialKey = credential.credentialKey;
@@ -146,15 +188,19 @@ module.exports = api => {
};
/**
- * Creates a map of credentials organized by scope
+ * Gets credentials filtered by scope and optionally by credential keys
*
- * @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} address The identity or address to get the credentials from
- * @param {String} scope The scope of the credentials to get
- * @param {string[]} credentialKeys - Optional list of credential keys to filter the result by
+ * @param coin The chainTicker of the coin to make the call on
+ * @param address The identity or address to get the credentials from
+ * @param scope The scope of the credentials to get
+ * @param credentialKeys Optional list of credential keys to filter the result by
*/
-
- api.native.get_credentials_by_scope = async (coin, address, scope, credentialKeys) => {
+ api.native.get_credentials_by_scope = async (
+ coin: string,
+ address: string,
+ scope: string,
+ credentialKeys?: string[]
+ ): Promise => {
const credentialsMap = await api.native.get_credentials_map(coin, address);
const scopeCredentials = credentialsMap[scope] || [];
@@ -162,30 +208,38 @@ module.exports = api => {
return scopeCredentials;
}
- return scopeCredentials.filter(cred => credentialKeys.includes(cred.credentialKey));
+ return scopeCredentials.filter((cred: Credential) =>
+ credentialKeys.includes(cred.credentialKey)
+ );
};
- api.setPost('/native/get_credentials_by_scope', async (req, res, next) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api.setPost('/native/get_credentials_by_scope', async (req: any, res: any) => {
const {coin, address, scope, credentialKeys} = req.body;
- api.native
- .get_credentials_by_scope(coin, address, scope, credentialKeys)
- .then(resultObj => {
- const retObj = {
- msg: 'success',
- result: resultObj,
- };
+ try {
+ const result = await api.native.get_credentials_by_scope(
+ coin,
+ address,
+ scope,
+ credentialKeys
+ );
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ result: result,
+ })
+ );
+ } catch (e: unknown) {
+ const message = e instanceof Error ? e.message : String(e);
+ res.send(
+ JSON.stringify({
msg: 'error',
- result: error.message,
- };
-
- res.send(JSON.stringify(retObj));
- });
+ result: message,
+ })
+ );
+ }
});
return api;
diff --git a/yarn.lock b/yarn.lock
index 12a379c6..3772287b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1573,7 +1573,7 @@ async@2.6.4, async@^2.6.0, async@^2.6.1, async@^3.2.3, async@^3.2.4:
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
- integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+ integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
at-least-node@^1.0.0:
version "1.0.0"
@@ -1602,7 +1602,7 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-axios@0.25.0, axios@1.7.4:
+axios@0.25.0, axios@1.11.0, axios@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
@@ -2658,11 +2658,16 @@ copyfiles@2.4.1:
untildify "^4.0.0"
yargs "^16.1.0"
-core-util-is@1.0.2, core-util-is@~1.0.0:
+core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
cors@^2.8.1, cors@~2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
@@ -2964,7 +2969,7 @@ define-properties@^1.2.1:
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
- integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+ integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
delegates@^1.0.0:
version "1.0.0"
@@ -4686,12 +4691,12 @@ has-symbols@^1.0.1:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
-has-symbols@^1.0.2, has-symbols@^1.0.3:
+has-symbols@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
-has-symbols@^1.1.0:
+has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
@@ -5456,7 +5461,7 @@ isarray@^2.0.5:
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+ integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
isbinaryfile@^4.0.8:
version "4.0.10"
@@ -6086,20 +6091,20 @@ mime-db@1.52.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
- version "2.1.24"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
- integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
- dependencies:
- mime-db "1.40.0"
-
-mime-types@^2.1.16, mime-types@~2.1.34:
+mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
+mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
+ version "2.1.24"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
+ integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
+ dependencies:
+ mime-db "1.40.0"
+
mime@1.4.1, mime@1.6.0, mime@^2.5.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
@@ -8864,16 +8869,7 @@ tmp@^0.2.0:
dependencies:
rimraf "^3.0.0"
-to-buffer@^1.2.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.1.tgz#2ce650cdb262e9112a18e65dc29dcb513c8155e0"
- integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==
- dependencies:
- isarray "^2.0.5"
- safe-buffer "^5.2.1"
- typed-array-buffer "^1.0.3"
-
-to-buffer@^1.2.1, to-buffer@^1.2.2:
+to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133"
integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==
@@ -9253,7 +9249,7 @@ utf8@3.0.0:
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
- integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
util-extend@^1.0.1:
version "1.0.3"
@@ -9360,18 +9356,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#93a1fdea07e81c7d570ad0803685336d4d7ea838"
- dependencies:
- base64url "3.0.1"
- bech32 "2.0.0"
- blake2b "https://github.com/VerusCoin/blake2b"
- bn.js "5.2.1"
- bs58check "2.0.0"
- create-hash "1.2.0"
-
-"verus-typescript-primitives@git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys":
- version "1.0.0"
- resolved "git+https://github.com/mcstoer/verus-typescript-primitives.git#10e8bb13c5ec788dd75ac120deef78841d127650"
+ resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#a4fbacd6da2c7840e4fb0a8845d156e0727af4bf"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -9399,12 +9384,12 @@ verror@^1.10.0:
react-native-cache "git+https://github.com/michaeltout/react-native-cache.git"
web3 "1.10.0"
-"verusd-rpc-ts-client@git+https://github.com/mcstoer/verusd-rpc-ts-client.git#generic-request-credential-keys":
+"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client.git":
version "0.1.0"
- resolved "git+https://github.com/mcstoer/verusd-rpc-ts-client.git#3514847c578b44e3463693de78500f15c59aef17"
+ resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#1ffe2e7abd52941d2c4263a4ab7a5853edc7369a"
dependencies:
- axios "1.7.4"
- verus-typescript-primitives "git+https://github.com/mcstoer/verus-typescript-primitives.git#generic-request-credential-keys"
+ axios "1.11.0"
+ verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
wcwidth@^1.0.0:
version "1.0.1"
@@ -9723,7 +9708,20 @@ which-module@^2.0.0:
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-which-typed-array@^1.1.16, which-typed-array@^1.1.19:
+which-typed-array@^1.1.16:
+ version "1.1.20"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.20.tgz#3fdb7adfafe0ea69157b1509f3a1cd892bd1d122"
+ integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==
+ dependencies:
+ available-typed-arrays "^1.0.7"
+ call-bind "^1.0.8"
+ call-bound "^1.0.4"
+ for-each "^0.3.5"
+ get-proto "^1.0.1"
+ gopd "^1.2.0"
+ has-tostringtag "^1.0.2"
+
+which-typed-array@^1.1.19:
version "1.1.19"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
From dc9106ff352b553a96a8a36a9d185de59bab92c9 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 27 Feb 2026 19:16:11 -0800
Subject: [PATCH 65/80] Start updating the z_getencryptionaddress api to
TypeScript.
---
.../native/{zgetencryptionaddress.js => zgetencryptionaddress.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename routes/api/native/{zgetencryptionaddress.js => zgetencryptionaddress.ts} (100%)
diff --git a/routes/api/native/zgetencryptionaddress.js b/routes/api/native/zgetencryptionaddress.ts
similarity index 100%
rename from routes/api/native/zgetencryptionaddress.js
rename to routes/api/native/zgetencryptionaddress.ts
From b95bb8740448a4ca58b669a3e125acc29095df73 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 27 Feb 2026 23:09:25 -0800
Subject: [PATCH 66/80] Change the z_getencryptionaddress API to TypeScript and
use its parameter and return value types in other parts of the API.
---
routes/api.js | 2 +-
.../api/native/credentials/getCredentials.ts | 19 ++-
.../generic/encryptAppEncryptionResponse.ts | 2 +-
.../generic/executeAppEncryptionRequest.ts | 11 +-
.../identity/executeIdentityUpdateRequest.ts | 10 +-
routes/api/native/zgetencryptionaddress.ts | 108 +++++++++---------
6 files changed, 81 insertions(+), 71 deletions(-)
diff --git a/routes/api.js b/routes/api.js
index a2d6a18b..04a0d444 100644
--- a/routes/api.js
+++ b/routes/api.js
@@ -136,7 +136,7 @@ api = require('./api/native/mininginfo')(api);
api = require('./api/native/getTransaction.js')(api);
api = require('./api/native/transactions')(api);
api = require('./api/native/zoperations')(api);
-api = require('./api/native/zgetencryptionaddress.js')(api);
+api = require('./api/native/zgetencryptionaddress').default(api);
api = require('./api/native/remove')(api);
api = require('./api/native/restart')(api);
api = require('./api/native/send.js')(api);
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index 7fa47697..75bef929 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -5,11 +5,7 @@ import {
Credential,
DATA_TYPE_OBJECT_CREDENTIAL,
} from 'verus-typescript-primitives';
-
-interface EncryptionKeys {
- extendedviewingkey: string;
- ivk: string;
-}
+import {ZGetEncryptionAddressResult} from '../zgetencryptionaddress';
interface VdxfIdResult {
vdxfid: string;
@@ -56,11 +52,14 @@ export default (api: any) => {
}
// Generate the viewing key to decrypt the credentials.
- const keys: EncryptionKeys | null = await api.native.z_get_encryption_address(coin, {
- address: zaddress,
- fromid: address,
- toid: address,
- });
+ const keys: ZGetEncryptionAddressResult | null = await api.native.z_get_encryption_address(
+ coin,
+ {
+ address: zaddress,
+ fromid: address,
+ toid: address,
+ }
+ );
if (!keys || !keys.extendedviewingkey || !keys.ivk) {
throw new Error(`Failed to get keys for ${address}`);
diff --git a/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
index d52b7f25..126a0a00 100644
--- a/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
+++ b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
@@ -25,7 +25,7 @@ export default (api: any) => {
!encryptedDescriptor.datadescriptors ||
encryptedDescriptor.datadescriptors.length === 0
) {
- throw new Error('No encrypted data descriptor returned from signdata');
+ throw new Error('No encrypted data descriptor returned from signdata.');
}
const dataDescriptor = DataDescriptor.fromJson(encryptedDescriptor.datadescriptors[0]);
diff --git a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
index 14561991..16592628 100644
--- a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
+++ b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
@@ -1,4 +1,5 @@
import {AppEncryptionRequestDetails} from 'verus-typescript-primitives';
+import {ZGetEncryptionAddressArgs, ZGetEncryptionAddressResult} from '../../zgetencryptionaddress';
interface AppEncryptionResult {
incomingViewingKey: string;
@@ -18,15 +19,15 @@ export default (api: any) => {
const walletinfo = await api.native.callDaemon(coin, 'getwalletinfo', []);
const seed = walletinfo.seedfp;
- // TODO: Add fetching returnsecret via RETURN_ESK from the detail
- // once it is able to be handled.
-
- const keys = await api.native.z_get_encryption_address(coin, {
+ const args: ZGetEncryptionAddressArgs = {
seed: seed,
hdindex: detail.derivationNumber.toNumber(),
fromid: fromID,
toid: toID,
- });
+ returnsecret: detail.returnESK(detail.flags),
+ };
+
+ const keys: ZGetEncryptionAddressResult = await api.native.z_get_encryption_address(coin, args);
return {
extendedViewingKey: keys.extendedviewingkey,
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 49f239b1..702a3896 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -1,5 +1,6 @@
import {IdentityUpdateRequestDetails} from 'verus-typescript-primitives';
import {encryptCredentialsInContentMultiMap} from '../../../utils/credentials/encryptCredentials';
+import {ZGetEncryptionAddressArgs, ZGetEncryptionAddressResult} from '../../zgetencryptionaddress';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
module.exports = (api: any) => {
@@ -22,12 +23,15 @@ module.exports = (api: any) => {
throw new Error(`No z-address found for identity ${address}`);
}
- // Generate the viewing key and encryption address to encrypt the credentials.
- const encryptionAddressInfo = await api.native.z_get_encryption_address(coin, {
+ const args: ZGetEncryptionAddressArgs = {
address: zaddress,
fromid: address,
toid: address,
- });
+ };
+
+ // Generate the viewing key and encryption address to encrypt the credentials.
+ const encryptionAddressInfo: ZGetEncryptionAddressResult =
+ await api.native.z_get_encryption_address(coin, args);
if (!encryptionAddressInfo || !encryptionAddressInfo.address || !encryptionAddressInfo.ivk) {
throw new Error(`Failed to get the personal encryption address for ${address}`);
diff --git a/routes/api/native/zgetencryptionaddress.ts b/routes/api/native/zgetencryptionaddress.ts
index 9df1e222..75014f7d 100644
--- a/routes/api/native/zgetencryptionaddress.ts
+++ b/routes/api/native/zgetencryptionaddress.ts
@@ -1,62 +1,68 @@
-module.exports = (api) => {
-
+// Temporarily export the interfaces since the API has no defined type yet.
+export interface ZGetEncryptionAddressArgs {
+ address?: string;
+ seed?: string;
+ hdindex?: number;
+ rootkey?: string;
+ fromid?: string;
+ toid?: string;
+ encryptionindex?: number;
+ returnsecret?: boolean;
+}
+
+export interface ZGetEncryptionAddressResult {
+ extendedviewingkey: string;
+ ivk: string;
+ address: string;
+ extendedspendingkey?: string;
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default (api: any) => {
/**
* Generates a z-address, viewing key, and optionally an extended secret key using either
* a z-address in the wallet, wallet seed and hdindex, or root key (extended private key).
- *
- * @param {String} coin The chainTicker of the coin to make the call on
- * @param {String} args The arguments to pass to z_getencryptionaddress
+ *
+ * @param {string} coin The chainTicker of the coin to make the call on
+ * @param {ZGetEncryptionAddressArgs} args The arguments to pass to z_getencryptionaddress
+ * - address: z-address that is present in this wallet
+ * - seed: raw wallet seed
+ * - hdindex: address to derive from seed (default=0)
+ * - rootkey: extended private key
+ * - fromid: a key to be used between the fromid and the toid
+ * - toid: a key to be used between the fromid and the toid
+ * - encryptionindex: index to derive the final encryption HD address from the derived seed (default=0)
+ * - returnsecret: if true, returns extended private key (default=false)
*/
- api.native.z_get_encryption_address = (
- coin,
- args,
- ) => {
- return new Promise((resolve, reject) => {
- api.native
- .callDaemon(
- coin,
- "z_getencryptionaddress",
- [
- args,
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
- });
+ api.native.z_get_encryption_address = async (
+ coin: string,
+ args: ZGetEncryptionAddressArgs
+ ): Promise => {
+ return api.native.callDaemon(coin, 'z_getencryptionaddress', [args]);
};
- api.setPost('/native/z_get_encryption_address', (req, res, next) => {
- const {
- chainTicker,
- args
- } = req.body;
-
- api.native
- .z_get_encryption_address(
- chainTicker,
- args
- )
- .then(resultObj => {
- const retObj = {
- msg: "success",
- result: resultObj
- };
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api.setPost('/native/z_get_encryption_address', async (req: any, res: any) => {
+ const {chainTicker, args}: {chainTicker: string; args: ZGetEncryptionAddressArgs} = req.body;
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
- msg: "error",
- result: error.message
- };
+ try {
+ const result = await api.native.z_get_encryption_address(chainTicker, args);
- res.send(JSON.stringify(retObj));
- });
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ result,
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: 'error',
+ result: e.message,
+ })
+ );
+ }
});
return api;
-};
\ No newline at end of file
+};
From be6722620b81ce5d4700ec26d5ab0b63fc5d28b5 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 5 Mar 2026 09:53:40 -0800
Subject: [PATCH 67/80] Add import sorting to prettier.
---
.prettierrc | 11 --
package.json | 1 +
prettier.config.mjs | 40 ++++++
.../api/native/credentials/getCredentials.ts | 11 +-
.../generic/executeAppEncryptionRequest.ts | 1 +
yarn.lock | 123 +++++++++++++++++-
6 files changed, 170 insertions(+), 17 deletions(-)
delete mode 100644 .prettierrc
create mode 100644 prettier.config.mjs
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index 2a412871..00000000
--- a/.prettierrc
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "bracketSpacing": false,
- "bracketSameLine": false,
- "printWidth": 100,
- "semi": true,
- "singleQuote": true,
- "tabWidth": 2,
- "trailingComma": "es5",
- "useTabs": false,
- "arrowParens": "avoid"
-}
diff --git a/package.json b/package.json
index b6776158..d0261225 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,7 @@
"dependencies": {
"@bitgo/utxo-lib": "git+https://github.com/VerusCoin/BitGoJS.git#utxo-lib-verus",
"@electron/remote": "1.1.0",
+ "@ianvs/prettier-plugin-sort-imports": "4.7.0",
"@noble/curves": "1.2.0",
"@xmldom/xmldom": "0.8.4",
"agama-wallet-lib": "git+https://github.com/VerusCoin/agama-wallet-lib.git#dev",
diff --git a/prettier.config.mjs b/prettier.config.mjs
new file mode 100644
index 00000000..32a76675
--- /dev/null
+++ b/prettier.config.mjs
@@ -0,0 +1,40 @@
+/**
+ * @type {import("prettier").Config}
+ */
+const config = {
+ plugins: ["@ianvs/prettier-plugin-sort-imports"],
+ // Based on sentry.js's prettier config.
+ importOrder: [
+ // Node.js builtins.
+ "",
+ "",
+ // Packages. `react` related packages come first.
+ "^react",
+ "",
+ "",
+ // Internal alias imports.
+ "^#/(.*)$",
+ "",
+ // Parent imports. Put `..` last.
+ "^\\.\\./(?!/?$)",
+ "^\\.\\./\\.?$",
+ "",
+ // Other relative imports. Put same-folder imports and `.` last.
+ "^\\./(?=.*/)(?!/?$)",
+ "^\\.(?!/?$)",
+ "^\\./?$",
+ // Newline after imports.
+ "",
+ ],
+ bracketSpacing: false,
+ bracketSameLine: false,
+ printWidth: 100,
+ semi: true,
+ singleQuote: true,
+ tabWidth: 2,
+ trailingComma: "es5",
+ useTabs: false,
+ arrowParens: "avoid",
+};
+
+export default config;
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index 75bef929..72a4a94f 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -1,10 +1,11 @@
import {
- DATA_DESCRIPTOR_VDXF_KEY,
- IDENTITY_CREDENTIAL,
- fromBase58Check,
Credential,
+ DATA_DESCRIPTOR_VDXF_KEY,
DATA_TYPE_OBJECT_CREDENTIAL,
+ fromBase58Check,
+ IDENTITY_CREDENTIAL,
} from 'verus-typescript-primitives';
+
import {ZGetEncryptionAddressResult} from '../zgetencryptionaddress';
interface VdxfIdResult {
@@ -72,7 +73,9 @@ export default (api: any) => {
const credentialKeyResult: VdxfIdResult | null = await api.native.get_vdxf_id(
coin,
IDENTITY_CREDENTIAL.vdxfid,
- {uint256: ivk}
+ {
+ uint256: ivk,
+ }
);
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
diff --git a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
index 16592628..c6042560 100644
--- a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
+++ b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
@@ -1,4 +1,5 @@
import {AppEncryptionRequestDetails} from 'verus-typescript-primitives';
+
import {ZGetEncryptionAddressArgs, ZGetEncryptionAddressResult} from '../../zgetencryptionaddress';
interface AppEncryptionResult {
diff --git a/yarn.lock b/yarn.lock
index 3772287b..2db01b20 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12,6 +12,78 @@
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069"
integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==
+"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
+ integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.28.5"
+ js-tokens "^4.0.0"
+ picocolors "^1.1.1"
+
+"@babel/generator@^7.26.2", "@babel/generator@^7.29.0":
+ version "7.29.1"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
+ integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
+ dependencies:
+ "@babel/parser" "^7.29.0"
+ "@babel/types" "^7.29.0"
+ "@jridgewell/gen-mapping" "^0.3.12"
+ "@jridgewell/trace-mapping" "^0.3.28"
+ jsesc "^3.0.2"
+
+"@babel/helper-globals@^7.28.0":
+ version "7.28.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674"
+ integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==
+
+"@babel/helper-string-parser@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
+ integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
+
+"@babel/helper-validator-identifier@^7.28.5":
+ version "7.28.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4"
+ integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
+
+"@babel/parser@^7.26.2", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6"
+ integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==
+ dependencies:
+ "@babel/types" "^7.29.0"
+
+"@babel/template@^7.28.6":
+ version "7.28.6"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57"
+ integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==
+ dependencies:
+ "@babel/code-frame" "^7.28.6"
+ "@babel/parser" "^7.28.6"
+ "@babel/types" "^7.28.6"
+
+"@babel/traverse@^7.25.9":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
+ integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
+ dependencies:
+ "@babel/code-frame" "^7.29.0"
+ "@babel/generator" "^7.29.0"
+ "@babel/helper-globals" "^7.28.0"
+ "@babel/parser" "^7.29.0"
+ "@babel/template" "^7.28.6"
+ "@babel/types" "^7.29.0"
+ debug "^4.3.1"
+
+"@babel/types@^7.26.0", "@babel/types@^7.28.6", "@babel/types@^7.29.0":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
+ integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
+ dependencies:
+ "@babel/helper-string-parser" "^7.27.1"
+ "@babel/helper-validator-identifier" "^7.28.5"
+
"@bitgo/blake2b-wasm@^3.0.1":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@bitgo/blake2b-wasm/-/blake2b-wasm-3.2.3.tgz#6ae5e942f2a5fd5b3ed27103af5df0ed50adfbc9"
@@ -842,6 +914,17 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
+"@ianvs/prettier-plugin-sort-imports@4.7.0":
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.7.0.tgz#9e556548071744837c274d59226ce717ff4fea36"
+ integrity sha512-soa2bPUJAFruLL4z/CnMfSEKGznm5ebz29fIa9PxYtu8HHyLKNE1NXAs6dylfw1jn/ilEIfO2oLLN6uAafb7DA==
+ dependencies:
+ "@babel/generator" "^7.26.2"
+ "@babel/parser" "^7.26.2"
+ "@babel/traverse" "^7.25.9"
+ "@babel/types" "^7.26.0"
+ semver "^7.5.2"
+
"@iarna/cli@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641"
@@ -863,6 +946,32 @@
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
+"@jridgewell/gen-mapping@^0.3.12":
+ version "0.3.13"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
+ integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/resolve-uri@^3.1.0":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
+ integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
+
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
+ version "0.3.31"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
+ integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@@ -5534,7 +5643,7 @@ js-sha3@^0.7.0:
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a"
integrity sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==
-"js-tokens@^3.0.0 || ^4.0.0":
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
@@ -5552,6 +5661,11 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+jsesc@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
+ integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
+
json-buffer@3.0.1, json-buffer@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
@@ -7161,6 +7275,11 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
@@ -8012,7 +8131,7 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
-"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.3, semver@^7.7.3:
+"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@6.3.1, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1, semver@^6.2.0, semver@^6.3.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.7.3:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
From 59539b717a902ea70eadbd682bc5654fb2e38d56 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Fri, 6 Mar 2026 15:34:39 -0800
Subject: [PATCH 68/80] Normalize code style across project through formatting
files that were changed on this branch.
---
main.js | 305 +++++++++---------
routes/api/dlhandler.js | 20 +-
routes/api/native/decryptdata.js | 50 +--
.../verusid/generic/verifyGenericRequest.js | 21 +-
.../identity/executeIdentityUpdateRequest.ts | 1 +
routes/api/plugin/builtin/loginconsentui.ts | 9 +-
routes/api/utils/constants/dev_options.ts | 10 +-
routes/deeplink/removelink.js | 6 +-
routes/deeplink/setuplink.js | 14 +-
tsconfig.json | 17 +-
10 files changed, 213 insertions(+), 240 deletions(-)
diff --git a/main.js b/main.js
index 1e0a8a57..49ed2b64 100644
--- a/main.js
+++ b/main.js
@@ -1,43 +1,40 @@
const electron = require('electron');
-const {
- Menu,
-} = require('electron');
-const { userAgreesToTerms } = require('./routes/children/userAgreement/window');
+const {Menu} = require('electron');
+const {userAgreesToTerms} = require('./routes/children/userAgreement/window');
const app = electron.app;
-const hasLock = app.requestSingleInstanceLock()
+const hasLock = app.requestSingleInstanceLock();
if (!hasLock) {
- app.quit()
+ app.quit();
} else {
- let api = require("./routes/api");
+ let api = require('./routes/api');
Object.freeze(Object.prototype);
Object.freeze(Object);
const BrowserWindow = electron.BrowserWindow;
- const path = require("path");
- const os = require("os");
- const version = require("./version.json");
- const portscanner = require("portscanner");
+ const path = require('path');
+ const os = require('os');
+ const portscanner = require('portscanner');
const osPlatform = os.platform();
- const express = require("express");
- const bodyParser = require("body-parser");
- const { formatBytes } = require("agama-wallet-lib/src/utils");
- const { dialog } = require("electron");
- require("@electron/remote/main").initialize();
+ const express = require('express');
+ const bodyParser = require('body-parser');
+ const {formatBytes} = require('agama-wallet-lib/src/utils');
+ const {dialog} = require('electron');
+ require('@electron/remote/main').initialize();
- global.USB_HOME_DIR = path.resolve(__dirname, "./usb_home");
- global.HOME = os.platform() === "win32" ? process.env.APPDATA : process.env.HOME;
+ global.USB_HOME_DIR = path.resolve(__dirname, './usb_home');
+ global.HOME = os.platform() === 'win32' ? process.env.APPDATA : process.env.HOME;
api.construct();
- const openurlhandler = require("./routes/deeplink/openurlhandler");
+ const openurlhandler = require('./routes/deeplink/openurlhandler');
api.clearWriteLog();
- const { MasterSecret, BuiltinSecret } = require("./routes/preloads/keys");
- const setuplink = require("./routes/deeplink/setuplink");
+ const {MasterSecret, BuiltinSecret} = require('./routes/preloads/keys');
+ const setuplink = require('./routes/deeplink/setuplink');
const removelink = require('./routes/deeplink/removelink');
- const { APP_NAME, APP_MODE, APP_VERSION } = require('./routes/appBasicInfo');
+ const {APP_NAME, APP_MODE, APP_VERSION} = require('./routes/appBasicInfo');
// Project root directory (parent of 'out' when compiled, or current dir in dev)
const PROJECT_ROOT = path.resolve(__dirname, '..');
@@ -45,7 +42,7 @@ if (!hasLock) {
const guiapp = express();
//TODO: add more things here
- const { appConfig } = api;
+ const {appConfig} = api;
const appBasicInfo = {
name: APP_NAME,
@@ -60,53 +57,53 @@ if (!hasLock) {
let _argv = {};
for (let i = 0; i < process.argv.length; i++) {
- if (process.argv[i].indexOf("nogui") > -1) {
+ if (process.argv[i].indexOf('nogui') > -1) {
_argv.nogui = true;
- api.log("enable nogui mode", "init");
+ api.log('enable nogui mode', 'init');
}
- if (process.argv[i].indexOf("=") > -1) {
- const _argvSplit = process.argv[i].split("=");
+ if (process.argv[i].indexOf('=') > -1) {
+ const _argvSplit = process.argv[i].split('=');
_argv[_argvSplit[0]] = _argvSplit[1];
}
if (!_argv.nogui) {
_argv = {};
} else {
- api.log("arguments", "init");
- api.log(_argv, "init");
+ api.log('arguments', 'init');
+ api.log(_argv, 'init');
api.argv = _argv;
}
}
- api.log(`app info: ${appBasicInfo.name} ${appBasicInfo.version}`, "init");
- api.log("sys info:", "init");
- api.log(`totalmem_readable: ${formatBytes(os.totalmem())}`, "init");
- api.log(`arch: ${os.arch()}`, "init");
- api.log(`cpu: ${os.cpus()[0].model}`, "init");
- api.log(`cpu_cores: ${os.cpus().length}`, "init");
- api.log(`platform: ${osPlatform}`, "init");
- api.log(`os_release: ${os.release()}`, "init");
- api.log(`os_type: ${os.type()}`, "init");
+ api.log(`app info: ${appBasicInfo.name} ${appBasicInfo.version}`, 'init');
+ api.log('sys info:', 'init');
+ api.log(`totalmem_readable: ${formatBytes(os.totalmem())}`, 'init');
+ api.log(`arch: ${os.arch()}`, 'init');
+ api.log(`cpu: ${os.cpus()[0].model}`, 'init');
+ api.log(`cpu_cores: ${os.cpus().length}`, 'init');
+ api.log(`platform: ${osPlatform}`, 'init');
+ api.log(`os_release: ${os.release()}`, 'init');
+ api.log(`os_type: ${os.type()}`, 'init');
api.log(
`app started in ${
- appConfig.general.main.dev || process.argv.indexOf("devmode") > -1 ? "dev mode" : " user mode"
+ appConfig.general.main.dev || process.argv.indexOf('devmode') > -1 ? 'dev mode' : ' user mode'
}`,
- "init"
+ 'init'
);
//api.setConfKMD();
guiapp.use((req, res, next) => {
- if (!appConfig.general.main.dev && !(process.argv.indexOf("devmode") > -1)) {
- res.header("Access-Control-Allow-Origin", "http://localhost:3000");
+ if (!appConfig.general.main.dev && !(process.argv.indexOf('devmode') > -1)) {
+ res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
} else {
- res.header("Access-Control-Allow-Origin", "*");
+ res.header('Access-Control-Allow-Origin', '*');
}
- res.header("Access-Control-Allow-Headers", "X-Requested-With,content-type");
- res.header("Access-Control-Allow-Credentials", "true");
- res.header("Access-Control-Allow-Methods", "GET, POST");
+ res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
+ res.header('Access-Control-Allow-Credentials', 'true');
+ res.header('Access-Control-Allow-Methods', 'GET, POST');
next();
});
@@ -114,54 +111,54 @@ if (!hasLock) {
const _setImmediate = setImmediate;
const _clearImmediate = clearImmediate;
- process.once("loaded", () => {
+ process.once('loaded', () => {
global.setImmediate = _setImmediate;
global.clearImmediate = _clearImmediate;
- if (osPlatform === "darwin") {
+ if (osPlatform === 'darwin') {
process.setFdLimit(appConfig.general.main.maxDescriptors.darwin);
app.setAboutPanelOptions({
applicationName: app.getName(),
applicationVersion: `${app.getVersion()}`,
- copyright: "Released under the MIT license",
+ copyright: 'Released under the MIT license',
});
- } else if (osPlatform === "linux") {
+ } else if (osPlatform === 'linux') {
process.setFdLimit(appConfig.general.main.maxDescriptors.linux);
}
});
// silent errors
- if (!appConfig.general.main.dev && !process.argv.indexOf("devmode") > -1) {
- process.on("uncaughtException", (err) => {
- api.log(`${new Date().toUTCString()} uncaughtException: ${err.message}`, "exception");
- api.log(err.stack, "exception");
+ if (!appConfig.general.main.dev && !process.argv.indexOf('devmode') > -1) {
+ process.on('uncaughtException', err => {
+ api.log(`${new Date().toUTCString()} uncaughtException: ${err.message}`, 'exception');
+ api.log(err.stack, 'exception');
});
}
- guiapp.use(bodyParser.json({ limit: "500mb" })); // support json encoded bodies
+ guiapp.use(bodyParser.json({limit: '500mb'})); // support json encoded bodies
guiapp.use(
bodyParser.urlencoded({
- limit: "500mb",
+ limit: '500mb',
extended: true,
})
); // support encoded bodies
- guiapp.get("/", (req, res) => {
- res.send("Verus app server");
+ guiapp.get('/', (req, res) => {
+ res.send('Verus app server');
});
- const guipath = path.join(PROJECT_ROOT, "gui");
- guiapp.use("/gui", express.static(guipath));
- guiapp.use("/api", api);
+ const guipath = path.join(PROJECT_ROOT, 'gui');
+ guiapp.use('/gui', express.static(guipath));
+ guiapp.use('/api', api);
- const server = require("http").createServer(guiapp);
- let io = require("socket.io")(server, {
+ const server = require('http').createServer(guiapp);
+ let io = require('socket.io')(server, {
cors: {
origin:
- appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
- ? "http://localhost:3000"
+ appConfig.general.main.dev || process.argv.indexOf('devmode') > -1
+ ? 'http://localhost:3000'
: null,
- methods: ["GET", "POST"],
+ methods: ['GET', 'POST'],
},
});
@@ -176,11 +173,11 @@ if (!hasLock) {
module.exports = guiapp;
let agamaIcon;
- if (os.platform() === "linux") {
- agamaIcon = path.join(__dirname, "/assets/icons/vrsc_512x512x32.png");
+ if (os.platform() === 'linux') {
+ agamaIcon = path.join(__dirname, '/assets/icons/vrsc_512x512x32.png');
}
- if (os.platform() === "win32") {
- agamaIcon = path.join(__dirname, "/assets/icons/vrsc.ico");
+ if (os.platform() === 'win32') {
+ agamaIcon = path.join(__dirname, '/assets/icons/vrsc.ico');
}
// close app
@@ -193,9 +190,9 @@ if (!hasLock) {
if (!_argv.nogui) {
startApp()
.then(() => createMainWindow())
- .catch((e) => api.log(e, "init"));
+ .catch(e => api.log(e, 'init'));
} else startApp();
- })
+ });
function createAppCloseWindow() {
// initialise window
@@ -224,24 +221,24 @@ if (!hasLock) {
appCloseWindow.setResizable(false);
appCloseWindow.loadURL(
- appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
+ appConfig.general.main.dev || process.argv.indexOf('devmode') > -1
? `http://127.0.0.1:${appConfig.general.main.agamaPort}/gui/startup/app-closing.html`
: `file://${PROJECT_ROOT}/gui/startup/app-closing.html`
);
- appCloseWindow.webContents.on("did-finish-load", () => {
+ appCloseWindow.webContents.on('did-finish-load', () => {
setTimeout(() => {
appCloseWindow.show();
}, 40);
});
- appCloseWindow.webContents.on("devtools-opened", () => {
+ appCloseWindow.webContents.on('devtools-opened', () => {
dialog.showMessageBox(appCloseWindow, {
- type: "warning",
- title: "Be Careful!",
+ type: 'warning',
+ title: 'Be Careful!',
message:
- "WARNING! You are opening the developer tools menu. ONLY enter commands here if you know exactly what you are doing.\n\nNEVER copy+paste any commands given to you into here. No trustworthy support person will EVER ask you to do that.\n\nANY CODE COPY+PASTED INTO DEV TOOLS CAN CONTROL YOUR FUNDS.",
- buttons: ["OK"],
+ 'WARNING! You are opening the developer tools menu. ONLY enter commands here if you know exactly what you are doing.\n\nNEVER copy+paste any commands given to you into here. No trustworthy support person will EVER ask you to do that.\n\nANY CODE COPY+PASTED INTO DEV TOOLS CAN CONTROL YOUR FUNDS.',
+ buttons: ['OK'],
});
});
}
@@ -249,24 +246,24 @@ if (!hasLock) {
function appExit() {
const CloseDaemons = () => {
return new Promise((resolve, reject) => {
- api.log("Closing Main Window...", "quit");
+ api.log('Closing Main Window...', 'quit');
api.quitKomodod(appConfig.general.native.cliStopTimeout);
- const result = "Closing daemons: done";
+ const result = 'Closing daemons: done';
- api.log(result, "quit");
+ api.log(result, 'quit');
resolve(result);
});
};
const HideMainWindow = () => {
return new Promise((resolve, reject) => {
- const result = "Hiding Main Window: done";
+ const result = 'Hiding Main Window: done';
- api.log("Exiting App...", "quit");
+ api.log('Exiting App...', 'quit');
mainWindow = null;
- api.log(result, "quit");
+ api.log(result, 'quit');
resolve(result);
});
};
@@ -280,11 +277,11 @@ if (!hasLock) {
const QuitApp = () => {
return new Promise((resolve, reject) => {
- const result = "Quiting App: done";
+ const result = 'Quiting App: done';
forceQuitApp = true;
app.quit();
- api.log(result, "quit");
+ api.log(result, 'quit');
resolve(result);
});
};
@@ -303,10 +300,7 @@ if (!hasLock) {
api.quitKomodod(appConfig.general.native.cliStopTimeout);
setInterval(async () => {
- if (
- !Object.keys(api.startedDaemonRegistry).length &&
- !(await api.isAnyDaemonRunning())
- ) {
+ if (!Object.keys(api.startedDaemonRegistry).length && !(await api.isAnyDaemonRunning())) {
closeApp();
}
}, 1000);
@@ -318,10 +312,10 @@ if (!hasLock) {
// check if agama is already running
portscanner.checkPortStatus(
appConfig.general.main.agamaPort,
- "127.0.0.1",
+ '127.0.0.1',
async (error, status) => {
// Status is 'open' if currently in use or 'closed' if available
- if (status === "closed") {
+ if (status === 'closed') {
let termsAgreed = appConfig.general.main.agreedToTerms;
if (!termsAgreed && (await userAgreesToTerms())) {
@@ -330,38 +324,35 @@ if (!hasLock) {
}
if (termsAgreed) {
- api.log(
- "user agreed to terms of use",
- "init"
- );
+ api.log('user agreed to terms of use', 'init');
server.listen(appConfig.general.main.agamaPort, () => {
api.log(
`guiapp and sockets.io are listening on port ${appConfig.general.main.agamaPort}`,
- "init"
+ 'init'
);
});
api.setIO(io); // pass sockets object to api router
- api.setVar("appBasicInfo", appBasicInfo);
- api.setVar("MasterSecret", MasterSecret);
- api.setVar("BuiltinSecret", BuiltinSecret);
+ api.setVar('appBasicInfo', appBasicInfo);
+ api.setVar('MasterSecret', MasterSecret);
+ api.setVar('BuiltinSecret', BuiltinSecret);
- api.log("saving plugin builtin secret...", "init");
+ api.log('saving plugin builtin secret...', 'init');
try {
await api.saveBuiltinSecret({
BuiltinSecret,
});
} catch (e) {
- api.log("error plugin builtin secret!", "init");
- api.log(e, "init");
+ api.log('error plugin builtin secret!', 'init');
+ api.log(e, 'init');
}
} else {
app.quit();
}
} else {
openAlreadyRunningWindow();
- reject("another api instance is already running");
+ reject('another api instance is already running');
}
if (error) reject(error);
@@ -398,20 +389,20 @@ if (!hasLock) {
willQuitApp = true;
alreadyRunningWindow.loadURL(
- appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
+ appConfig.general.main.dev || process.argv.indexOf('devmode') > -1
? `http://127.0.0.1:${appConfig.general.main.agamaPort}/gui/startup/agama-instance-error.html`
: `file://${PROJECT_ROOT}/gui/startup/agama-instance-error.html`
);
- alreadyRunningWindow.webContents.on("did-finish-load", () => {
+ alreadyRunningWindow.webContents.on('did-finish-load', () => {
alreadyRunningWindow.show();
});
- api.log("another agama app is already running", "init");
+ api.log('another agama app is already running', 'init');
}
function createMainWindow() {
- require(path.join(__dirname, "private/mainmenu"));
+ require(path.join(__dirname, 'private/mainmenu'));
if (closeAppAfterLoading) {
mainWindow = null;
@@ -420,21 +411,21 @@ if (!hasLock) {
const staticMenu = Menu.buildFromTemplate([
// if static
- { role: "copy" },
- { type: "separator" },
- { role: "selectall" },
+ {role: 'copy'},
+ {type: 'separator'},
+ {role: 'selectall'},
]);
const editMenu = Menu.buildFromTemplate([
// if editable
- { role: "undo" },
- { role: "redo" },
- { type: "separator" },
- { role: "cut" },
- { role: "copy" },
- { role: "paste" },
- { type: "separator" },
- { role: "selectall" },
+ {role: 'undo'},
+ {role: 'redo'},
+ {type: 'separator'},
+ {role: 'cut'},
+ {role: 'copy'},
+ {role: 'paste'},
+ {type: 'separator'},
+ {role: 'selectall'},
]);
// initialise window
@@ -456,27 +447,27 @@ if (!hasLock) {
webviewTag: false,
sandbox: false,
- preload: path.resolve(__dirname, "routes", "preloads", "plugin", "preload-builtin.js"),
+ preload: path.resolve(__dirname, 'routes', 'preloads', 'plugin', 'preload-builtin.js'),
},
});
mainWindow.loadURL(
- appConfig.general.main.dev || process.argv.indexOf("devmode") > -1
- ? "http://localhost:3000"
+ appConfig.general.main.dev || process.argv.indexOf('devmode') > -1
+ ? 'http://localhost:3000'
: `file://${PROJECT_ROOT}/gui/Verus-Desktop-GUI/react/build/index.html`
);
- mainWindow.webContents.on("devtools-opened", () => {
+ mainWindow.webContents.on('devtools-opened', () => {
dialog.showMessageBox(mainWindow, {
- type: "warning",
- title: "Be Careful!",
+ type: 'warning',
+ title: 'Be Careful!',
message:
- "WARNING! You are opening the developer tools menu. ONLY enter commands here if you know exactly what you are doing. If someone told you to copy+paste commands into here, you should probably ignore them, close dev tools, and stay safe.",
- buttons: ["OK"],
+ 'WARNING! You are opening the developer tools menu. ONLY enter commands here if you know exactly what you are doing. If someone told you to copy+paste commands into here, you should probably ignore them, close dev tools, and stay safe.',
+ buttons: ['OK'],
});
});
- mainWindow.webContents.on("did-finish-load", () => {
+ mainWindow.webContents.on('did-finish-load', () => {
setTimeout(() => {
mainWindow.show();
@@ -484,19 +475,19 @@ if (!hasLock) {
}, 40);
});
- mainWindow.webContents.on("context-menu", (e, params) => {
+ mainWindow.webContents.on('context-menu', (e, params) => {
// context-menu returns params
- const { selectionText, isEditable } = params; // params obj
+ const {selectionText, isEditable} = params; // params obj
if (isEditable) {
editMenu.popup(mainWindow);
- } else if (selectionText && selectionText.trim() !== "") {
+ } else if (selectionText && selectionText.trim() !== '') {
staticMenu.popup(mainWindow);
}
});
// close app
- mainWindow.on("close", (event) => {
+ mainWindow.on('close', event => {
if (_argv.nogui && mainWindow.isVisible()) {
event.preventDefault();
mainWindow.hide();
@@ -508,8 +499,8 @@ if (!hasLock) {
return mainWindow;
}
- app.on("web-contents-created", (event, contents) => {
- contents.on("will-attach-webview", (event, webPreferences, params) => {
+ app.on('web-contents-created', (event, contents) => {
+ contents.on('will-attach-webview', (event, webPreferences, params) => {
// Strip away preload scripts if unused or verify their location is legitimate
delete webPreferences.preload;
delete webPreferences.preloadURL;
@@ -520,26 +511,26 @@ if (!hasLock) {
event.preventDefault();
});
- contents.on("will-navigate", (event, url) => {
+ contents.on('will-navigate', (event, url) => {
console.log(`[will-navigate] ${url}`);
console.log(event);
event.preventDefault();
});
- contents.on("will-redirect", (event, url) => {
+ contents.on('will-redirect', (event, url) => {
console.log(`[will-redirect] ${url}`);
console.log(event);
event.preventDefault();
});
- contents.on("new-window", async (event, navigationUrl) => {
+ contents.on('new-window', async (event, navigationUrl) => {
// In this example, we'll ask the operating system
// to open this event's url in the default browser.
event.preventDefault();
});
contents.setWindowOpenHandler(() => {
- return { action: "deny" };
+ return {action: 'deny'};
});
});
@@ -566,8 +557,8 @@ if (!hasLock) {
function handleSecondInstance(event, argv, cwd) {
focusMain();
- if (process.platform == "win32" || process.platform == "linux") {
- const argIndex = process.platform === "win32" ? 1 : 2;
+ if (process.platform == 'win32' || process.platform == 'linux') {
+ const argIndex = process.platform === 'win32' ? 1 : 2;
openurlhandler(null, argv.slice(1)[argIndex], api.dlhandler);
}
}
@@ -575,43 +566,43 @@ if (!hasLock) {
api.setupFocusApis(focusMain);
api.setupMinimizeApis(minimizeMain);
- app.on("activate", focusMain);
- app.on("second-instance", handleSecondInstance);
+ app.on('activate', focusMain);
+ app.on('second-instance', handleSecondInstance);
// Deep linking
if (!appConfig.general.main.disableDeeplink) {
- api.log("setting up deeplink", "init");
+ api.log('setting up deeplink', 'init');
try {
- api.installLinuxDeeplinkIntegration()
+ api
+ .installLinuxDeeplinkIntegration()
.then(() => {
- api.log("deeplink integration created", "init");
+ api.log('deeplink integration created', 'init');
})
- .catch((e) => {
- api.log("deeplink integration failed", "init");
- api.log(e, "init");
+ .catch(e => {
+ api.log('deeplink integration failed', 'init');
+ api.log(e, 'init');
});
} catch (e) {
- api.log("deeplink integration failed", "init");
- api.log(e, "init");
+ api.log('deeplink integration failed', 'init');
+ api.log(e, 'init');
}
setuplink(app);
} else {
- api.log("removing deeplink", "init");
- removelink(app)
+ api.log('removing deeplink', 'init');
+ removelink(app);
}
- app.on("open-url", (event, url) => openurlhandler(event, url, api.dlhandler));
+ app.on('open-url', (event, url) => openurlhandler(event, url, api.dlhandler));
// Emitted when all windows have been closed and the application will quit.
// Calling event.preventDefault() will prevent the default behaviour, which is terminating the application.
- app.on("will-quit", (event) => {
+ app.on('will-quit', event => {
if (!forceQuitApp && mainWindow != null) {
// loading window is still open
- api.log("will-quit while loading window active", "quit");
+ api.log('will-quit while loading window active', 'quit');
event.preventDefault();
appExit();
}
});
}
-
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 2fd29812..c1710bd1 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -4,14 +4,14 @@ const {
LOGIN_CONSENT_REQUEST_VDXF_KEY,
LoginConsentRequest,
VERUSPAY_INVOICE_VDXF_KEY,
- VerusPayInvoice
+ VerusPayInvoice,
} = require('verus-typescript-primitives');
const {ROOT_SYSTEM_NAME} = require('./utils/constants/dev_options');
const {SUPPORTED_DLS, CALLBACK_HOST} = require('./utils/constants/supported_dls');
-module.exports = (api) => {
- api.dlhandler = (urlstring) => {
- const deeplinkHandler = (urlstring) => {
+module.exports = api => {
+ api.dlhandler = urlstring => {
+ const deeplinkHandler = urlstring => {
const url = new URL(urlstring);
let id;
@@ -34,7 +34,7 @@ module.exports = (api) => {
case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
break;
-
+
default:
throw new Error(`Unsupported deeplink ID: ${urlstring}`);
}
@@ -51,18 +51,18 @@ module.exports = (api) => {
return api.loginConsentUi.deeplink(
{
id: id,
- data: data
+ data: data,
},
{
- id: "VERUS_DESKTOP_MAIN",
+ id: 'VERUS_DESKTOP_MAIN',
search_builtin: true,
- main_chain_ticker: ROOT_SYSTEM_NAME
+ main_chain_ticker: ROOT_SYSTEM_NAME,
}
);
};
return deeplinkHandler(urlstring);
- }
+ };
return api;
-};
\ No newline at end of file
+};
diff --git a/routes/api/native/decryptdata.js b/routes/api/native/decryptdata.js
index 0dbe33bc..41a77358 100644
--- a/routes/api/native/decryptdata.js
+++ b/routes/api/native/decryptdata.js
@@ -1,57 +1,41 @@
-module.exports = (api) => {
-
+module.exports = api => {
/**
* Decrypts data given the parameters of a data descriptor, and optionally
* evk, ivk, txid and/or if to retrieve the data from its reference.
- *
+ *
* @param {String} coin The chainTicker of the coin to make the call on
* @param {Object} params The parameters to pass to decryptdata
*/
- api.native.decrypt_data = (
- coin,
- params,
- ) => {
+ api.native.decrypt_data = (coin, params) => {
return new Promise((resolve, reject) => {
api.native
- .callDaemon(
- coin,
- "decryptdata",
- [
- params,
- ]
- )
- .then(resultObj => {
- resolve(resultObj)
- })
- .catch(err => {
- reject(err);
- });
+ .callDaemon(coin, 'decryptdata', [params])
+ .then(resultObj => {
+ resolve(resultObj);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
api.setPost('/native/decrypt_data', (req, res) => {
- const {
- chainTicker,
- parameters
- } = req.body;
+ const {chainTicker, parameters} = req.body;
api.native
- .decrypt_data(
- chainTicker,
- parameters
- )
+ .decrypt_data(chainTicker, parameters)
.then(resultObj => {
const retObj = {
- msg: "success",
- result: resultObj
+ msg: 'success',
+ result: resultObj,
};
res.send(JSON.stringify(retObj));
})
.catch(error => {
const retObj = {
- msg: "error",
- result: error.message
+ msg: 'error',
+ result: error.message,
};
res.send(JSON.stringify(retObj));
@@ -59,4 +43,4 @@ module.exports = (api) => {
});
return api;
-};
\ No newline at end of file
+};
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
index 9349df2c..6b7e3638 100644
--- a/routes/api/native/verusid/generic/verifyGenericRequest.js
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -1,6 +1,6 @@
-const {GenericRequest} = require("verus-typescript-primitives")
+const {GenericRequest} = require('verus-typescript-primitives');
-module.exports = (api) => {
+module.exports = api => {
/**
* Verifies a generic request
* @param {GenericRequest} Request
@@ -10,27 +10,30 @@ module.exports = (api) => {
coin,
request.signature.identityID.toIAddress(),
request.getRawDataSha256().toString('hex'),
- request.signature.signatureAsVch.toString('base64'),
+ request.signature.signatureAsVch.toString('base64')
);
- return verified ? { verified } : { verified, message: "Failed to verify signature" };
+ return verified ? {verified} : {verified, message: 'Failed to verify signature'};
};
- api.setPost("/native/verusid/generic/verify_generic_request", async (req, res, next) => {
- const { chainTicker, request } = req.body;
+ api.setPost('/native/verusid/generic/verify_generic_request', async (req, res) => {
+ const {chainTicker, request} = req.body;
// The request is sent as a QR string to avoid IPC serialization issues.
const genericRequest = GenericRequest.fromQrString(request);
try {
res.send(
JSON.stringify({
- msg: "success",
- result: await api.native.verusid.generic.verify_generic_request(chainTicker, genericRequest),
+ msg: 'success',
+ result: await api.native.verusid.generic.verify_generic_request(
+ chainTicker,
+ genericRequest
+ ),
})
);
} catch (e) {
res.send(
JSON.stringify({
- msg: "error",
+ msg: 'error',
result: e.message,
})
);
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 702a3896..3e643640 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -1,4 +1,5 @@
import {IdentityUpdateRequestDetails} from 'verus-typescript-primitives';
+
import {encryptCredentialsInContentMultiMap} from '../../../utils/credentials/encryptCredentials';
import {ZGetEncryptionAddressArgs, ZGetEncryptionAddressResult} from '../../zgetencryptionaddress';
diff --git a/routes/api/plugin/builtin/loginconsentui.ts b/routes/api/plugin/builtin/loginconsentui.ts
index e2e6490d..219352ea 100644
--- a/routes/api/plugin/builtin/loginconsentui.ts
+++ b/routes/api/plugin/builtin/loginconsentui.ts
@@ -1,16 +1,17 @@
import axios, {AxiosResponse} from 'axios';
+import base64url from 'base64url';
+import {BrowserWindow, shell} from 'electron';
import {
+ GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY,
+ LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LOGIN_CONSENT_RESPONSE_VDXF_KEY,
LOGIN_CONSENT_WEBHOOK_VDXF_KEY,
- LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LoginConsentResponse,
ResponseURI,
- GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY,
} from 'verus-typescript-primitives';
+
import {pushMessage} from '../../../ipc/ipc';
import {ReservedPluginTypes} from '../../utils/plugin/builtin';
-import {shell, BrowserWindow} from 'electron';
-import base64url from 'base64url';
interface RedirectInfo {
type: string;
diff --git a/routes/api/utils/constants/dev_options.ts b/routes/api/utils/constants/dev_options.ts
index a363c29d..9115e237 100644
--- a/routes/api/utils/constants/dev_options.ts
+++ b/routes/api/utils/constants/dev_options.ts
@@ -1,9 +1,11 @@
const IS_TESTNET = false;
-const ROOT_SYSTEM_ID = IS_TESTNET ? "iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq" : "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV";
-const ROOT_SYSTEM_NAME = IS_TESTNET ? "VRSCTEST" : "VRSC";
+const ROOT_SYSTEM_ID = IS_TESTNET
+ ? 'iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq'
+ : 'i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV';
+const ROOT_SYSTEM_NAME = IS_TESTNET ? 'VRSCTEST' : 'VRSC';
module.exports = {
IS_TESTNET,
ROOT_SYSTEM_ID,
- ROOT_SYSTEM_NAME
-}
\ No newline at end of file
+ ROOT_SYSTEM_NAME,
+};
diff --git a/routes/deeplink/removelink.js b/routes/deeplink/removelink.js
index a9b56932..5edf0d00 100644
--- a/routes/deeplink/removelink.js
+++ b/routes/deeplink/removelink.js
@@ -1,4 +1,4 @@
-const { WALLET_VDXF_KEY } = require("verus-typescript-primitives")
+const {WALLET_VDXF_KEY} = require('verus-typescript-primitives');
function removelink(app) {
const protocols = [WALLET_VDXF_KEY.vdxfid, 'verus'];
@@ -6,10 +6,10 @@ function removelink(app) {
for (const protocol of protocols) {
const res = app.removeAsDefaultProtocolClient(protocol);
- results.push({ protocol, success: res });
+ results.push({protocol, success: res});
}
return results;
}
-module.exports = removelink
\ No newline at end of file
+module.exports = removelink;
diff --git a/routes/deeplink/setuplink.js b/routes/deeplink/setuplink.js
index 80aeb544..35878158 100644
--- a/routes/deeplink/setuplink.js
+++ b/routes/deeplink/setuplink.js
@@ -1,5 +1,5 @@
-const path = require('path')
-const { WALLET_VDXF_KEY } = require('verus-typescript-primitives');
+const path = require('path');
+const {WALLET_VDXF_KEY} = require('verus-typescript-primitives');
function setuplink(app) {
const protocols = [WALLET_VDXF_KEY.vdxfid, 'verus'];
@@ -9,15 +9,17 @@ function setuplink(app) {
let res;
if (process.defaultApp) {
if (process.argv.length >= 2) {
- res = app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(process.argv[1])])
+ res = app.setAsDefaultProtocolClient(protocol, process.execPath, [
+ path.resolve(process.argv[1]),
+ ]);
}
} else {
- res = app.setAsDefaultProtocolClient(protocol)
+ res = app.setAsDefaultProtocolClient(protocol);
}
- results.push({ protocol, success: res });
+ results.push({protocol, success: res});
}
return results;
}
-module.exports = setuplink
\ No newline at end of file
+module.exports = setuplink;
diff --git a/tsconfig.json b/tsconfig.json
index 456bc0ed..7c26890b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,19 +9,8 @@
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
- "forceConsistentCasingInFileNames": true
+ "forceConsistentCasingInFileNames": true,
},
- "include": [
- "main.js",
- "routes/**/*",
- "private/**/*",
- "keys/**/*",
- "assets/js/**/*"
- ],
- "exclude": [
- "node_modules",
- "gui",
- "dist",
- "out"
- ]
+ "include": ["main.js", "routes/**/*", "private/**/*", "keys/**/*", "assets/js/**/*"],
+ "exclude": ["node_modules", "gui", "dist", "out"],
}
From 2bf9345c6baf1c1c501146c38fcca2a09ca71436 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 10 Mar 2026 15:56:00 -0700
Subject: [PATCH 69/80] Clean up code based on code review.
---
.../generic/encryptAppEncryptionResponse.ts | 3 +-
.../generic/executeAppEncryptionRequest.ts | 8 +++-
.../verusid/generic/signGenericResponse.ts | 3 +-
.../identity/executeIdentityUpdateRequest.ts | 6 ++-
routes/api/native/zgetencryptionaddress.ts | 3 +-
routes/api/plugin/builtin/loginconsentui.ts | 2 +-
.../utils/credentials/encryptCredentials.js | 39 +++++++++----------
.../api/utils/credentials/parseCredential.js | 15 -------
8 files changed, 37 insertions(+), 42 deletions(-)
delete mode 100644 routes/api/utils/credentials/parseCredential.js
diff --git a/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
index 126a0a00..0704da78 100644
--- a/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
+++ b/routes/api/native/verusid/generic/encryptAppEncryptionResponse.ts
@@ -58,10 +58,11 @@ export default (api: any) => {
})
);
} catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
res.send(
JSON.stringify({
msg: 'error',
- result: e.message,
+ result: message,
})
);
}
diff --git a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
index c6042560..25124f4e 100644
--- a/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
+++ b/routes/api/native/verusid/generic/executeAppEncryptionRequest.ts
@@ -18,6 +18,11 @@ export default (api: any) => {
toID: string
): Promise => {
const walletinfo = await api.native.callDaemon(coin, 'getwalletinfo', []);
+
+ if (!walletinfo.seedfp) {
+ throw new Error('No seedfp found in walletinfo.');
+ }
+
const seed = walletinfo.seedfp;
const args: ZGetEncryptionAddressArgs = {
@@ -61,10 +66,11 @@ export default (api: any) => {
})
);
} catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
res.send(
JSON.stringify({
msg: 'error',
- result: e.message,
+ result: message,
})
);
}
diff --git a/routes/api/native/verusid/generic/signGenericResponse.ts b/routes/api/native/verusid/generic/signGenericResponse.ts
index 406c33fc..5293558b 100644
--- a/routes/api/native/verusid/generic/signGenericResponse.ts
+++ b/routes/api/native/verusid/generic/signGenericResponse.ts
@@ -33,10 +33,11 @@ export default (api: any) => {
})
);
} catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
res.send(
JSON.stringify({
msg: 'error',
- result: e.message,
+ result: message,
})
);
}
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 3e643640..be112485 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -14,7 +14,8 @@ module.exports = (api: any) => {
throw new Error('IdentityUpdateRequest does not contain an identity.');
}
- // Change the identity name in the detail to include `@` at the end so that it is valid.
+ // Change the identity name in the detail to include `@` at the end so that it is valid
+ // for the getidentity and updateidentity daemon calls.
detail.identity.name = detail.identity.name + '@';
const address = detail.identity.name;
const identity = await api.native.get_identity(coin, detail.identity.name);
@@ -75,10 +76,11 @@ module.exports = (api: any) => {
})
);
} catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
res.send(
JSON.stringify({
msg: 'error',
- result: e.message,
+ result: message,
})
);
}
diff --git a/routes/api/native/zgetencryptionaddress.ts b/routes/api/native/zgetencryptionaddress.ts
index 75014f7d..e8541b01 100644
--- a/routes/api/native/zgetencryptionaddress.ts
+++ b/routes/api/native/zgetencryptionaddress.ts
@@ -55,10 +55,11 @@ export default (api: any) => {
})
);
} catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
res.send(
JSON.stringify({
msg: 'error',
- result: e.message,
+ result: message,
})
);
}
diff --git a/routes/api/plugin/builtin/loginconsentui.ts b/routes/api/plugin/builtin/loginconsentui.ts
index 219352ea..5ebfdfc8 100644
--- a/routes/api/plugin/builtin/loginconsentui.ts
+++ b/routes/api/plugin/builtin/loginconsentui.ts
@@ -99,7 +99,7 @@ interface Api {
// Wraps shell.openExternal to prevent opening any urls that don't go to the browser for security reasons.
function safeOpenExternal(url: URL): void {
if (!['https:', 'http:'].includes(url.protocol)) {
- return null;
+ return;
}
try {
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 43c5d68c..81efeb71 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -2,7 +2,7 @@ const {
IDENTITY_CREDENTIAL,
DATA_TYPE_OBJECT_CREDENTIAL,
DataDescriptor,
- DATA_TYPE_OBJECT_DATADESCRIPTOR
+ DATA_TYPE_OBJECT_DATADESCRIPTOR,
} = require('verus-typescript-primitives');
const encryptCredentialsInContentMultiMap = async (
@@ -20,44 +20,43 @@ const encryptCredentialsInContentMultiMap = async (
for (const valueObj of vdxfUniValue.values) {
// Each valueObj contains exactly one key-value pair.
const valueKey = Object.keys(valueObj)[0];
-
+
if (valueKey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
// Replace the credential with the encrypted data descriptor.
const vdxfUniType = valueObj[valueKey];
- const signdataResult = await api.native.sign_data(coin,
- {
- "address": address,
- "vdxfdata": {[valueKey]: vdxfUniType.toJson()},
- "encrypttoaddress": encryptionAddress
- }
- );
+ const signdataResult = await api.native.sign_data(coin, {
+ address: address,
+ vdxfdata: {[valueKey]: vdxfUniType.toJson()},
+ encrypttoaddress: encryptionAddress,
+ });
- const dataDescriptor = DataDescriptor.fromJson(signdataResult.mmrdescriptor_encrypted.datadescriptors[0]);
+ const dataDescriptor = DataDescriptor.fromJson(
+ signdataResult.mmrdescriptor_encrypted.datadescriptors[0]
+ );
delete valueObj[valueKey];
valueObj[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid] = dataDescriptor;
}
}
}
// Replace the credentials key with a hashed key.
- const credentialKeyResult = await api.native.get_vdxf_id(
- coin,
- IDENTITY_CREDENTIAL.vdxfid,
- { uint256: ivk }
- );
-
+ const credentialKeyResult = await api.native.get_vdxf_id(coin, IDENTITY_CREDENTIAL.vdxfid, {
+ uint256: ivk,
+ });
+
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
- throw new Error("Failed to generate credential key");
+ throw new Error('Failed to generate credential key');
}
-
+
const credentialKey = credentialKeyResult.vdxfid;
-
+
contentmultimap.kv_content.set(credentialKey, valueArray);
contentmultimap.kv_content.delete(IDENTITY_CREDENTIAL.vdxfid);
+ break;
}
}
};
module.exports = {
- encryptCredentialsInContentMultiMap
+ encryptCredentialsInContentMultiMap,
};
diff --git a/routes/api/utils/credentials/parseCredential.js b/routes/api/utils/credentials/parseCredential.js
deleted file mode 100644
index 90c1552b..00000000
--- a/routes/api/utils/credentials/parseCredential.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const {
- Credential,
- DATA_TYPE_OBJECT_CREDENTIAL,
-} = require("verus-typescript-primitives");
-
-// parseCredential converts a credential object from a data descriptor into a credential class.
-const parseCredential = (credObj) => {
- const credJson = credObj[DATA_TYPE_OBJECT_CREDENTIAL.vdxfid];
-
- return Credential.fromJson(credJson);
-};
-
-module.exports = {
- parseCredential
-};
\ No newline at end of file
From 8a314e27486d22ca292d0369ec85195bcb2a3959 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 11 Mar 2026 15:11:18 -0700
Subject: [PATCH 70/80] Improve code based on code review.
---
routes/api/dlhandler.js | 3 +-
routes/api/utility_apis/deeplinkSetup.js | 106 +++++++++---------
.../utils/credentials/encryptCredentials.js | 2 +
3 files changed, 59 insertions(+), 52 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index c1710bd1..5bc4cca3 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -31,10 +31,11 @@ module.exports = api => {
dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
break;
+ /* Currently VerusPay invoices are unsupported.
case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
break;
-
+ */
default:
throw new Error(`Unsupported deeplink ID: ${urlstring}`);
}
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index fd608c50..2a6c053d 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -1,12 +1,11 @@
const fs = require('fs-extra');
const path = require('path');
const os = require('os');
-const { execFile, exec } = require('child_process');
+const {execFile} = require('child_process');
const util = require('util');
-const { IS_TESTNET } = require('../utils/constants/dev_options');
-const run = util.promisify(exec);
+const {IS_TESTNET} = require('../utils/constants/dev_options');
const runFile = util.promisify(execFile);
-const { APP_NAME } = require('../../appBasicInfo');
+const {APP_NAME} = require('../../appBasicInfo');
// Increase maxBuffer to handle large outputs (e.g., AppImage extraction).
const MAX_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
@@ -16,9 +15,9 @@ function xdgDataHome() {
}
async function extractAppImage(appImage, tmpDir) {
- await runFile(appImage, ['--appimage-extract'], {
+ await runFile(appImage, ['--appimage-extract'], {
cwd: tmpDir,
- maxBuffer: MAX_BUFFER_SIZE
+ maxBuffer: MAX_BUFFER_SIZE,
});
const extractedPath = path.join(tmpDir, 'squashfs-root');
return extractedPath;
@@ -34,25 +33,25 @@ async function installIcons(squashRoot) {
}
let iconsCopied = 0;
-
+
// Copy all available icon sizes from the hicolor structure.
const sizeDirs = await fs.readdir(sourceHicolorBase).catch(() => []);
-
+
for (const sizeDir of sizeDirs) {
const sourceSizeDir = path.join(sourceHicolorBase, sizeDir, 'apps');
const destSizeDir = path.join(hicolorBase, sizeDir, 'apps');
-
+
if (await fs.pathExists(sourceSizeDir)) {
const iconFiles = await fs.readdir(sourceSizeDir).catch(() => []);
const pngFiles = iconFiles.filter(f => f.toLowerCase().endsWith('.png'));
-
+
if (pngFiles.length > 0) {
await fs.mkdirp(destSizeDir);
-
+
for (const pngFile of pngFiles) {
const sourceIcon = path.join(sourceSizeDir, pngFile);
const destIcon = path.join(destSizeDir, pngFile);
-
+
await fs.copyFile(sourceIcon, destIcon);
iconsCopied++;
}
@@ -63,14 +62,14 @@ async function installIcons(squashRoot) {
if (iconsCopied > 0) {
// Update icon caches if possible.
const iconCacheCommands = [
- `gtk-update-icon-cache-3.0 -t "${hicolorBase}"`,
- `gtk-update-icon-cache -f "${hicolorBase}"`,
- `update-icon-caches "${path.dirname(hicolorBase)}"`
+ ['gtk-update-icon-cache-3.0', ['-t', hicolorBase]],
+ ['gtk-update-icon-cache', ['-f', hicolorBase]],
+ ['update-icon-caches', [path.dirname(hicolorBase)]],
];
-
- for (const command of iconCacheCommands) {
+
+ for (const [cmd, args] of iconCacheCommands) {
try {
- await run(command, { maxBuffer: MAX_BUFFER_SIZE });
+ await runFile(cmd, args, {maxBuffer: MAX_BUFFER_SIZE});
} catch {}
}
}
@@ -81,17 +80,17 @@ async function installIcons(squashRoot) {
async function installDesktopFile(squashRoot, appImage) {
const appsDir = path.join(xdgDataHome(), 'applications');
await fs.mkdirp(appsDir);
-
+
// Find the desktop file in the extracted AppImage dynamically.
const files = await fs.readdir(squashRoot);
const desktopFileName = files.find(file => file.endsWith('.desktop'));
-
+
if (!desktopFileName) {
throw new Error('No desktop file found in AppImage');
}
const sourceDesktopFile = path.join(squashRoot, desktopFileName);
-
+
if (!(await fs.pathExists(sourceDesktopFile))) {
throw new Error(`Desktop file not found in AppImage at ${sourceDesktopFile}`);
}
@@ -105,17 +104,14 @@ async function installDesktopFile(squashRoot, appImage) {
const versionMatch = desktopFileContent.match(/^X-AppImage-Version=(.+)$/m);
if (versionMatch) {
const version = versionMatch[1].trim();
-
- desktopFileContent = desktopFileContent.replace(
- /^Name=(.+)$/m,
- (match, name) => {
- const trimmedName = name.trim();
- if (!trimmedName.includes(`(${version})`)) {
- return `Name=${trimmedName} (${version})`;
- }
- return match;
+
+ desktopFileContent = desktopFileContent.replace(/^Name=(.+)$/m, (match, name) => {
+ const trimmedName = name.trim();
+ if (!trimmedName.includes(`(${version})`)) {
+ return `Name=${trimmedName} (${version})`;
}
- );
+ return match;
+ });
// Add the version if possible to the desktop file name.
const versionSuffix = `-${version}`;
@@ -128,7 +124,6 @@ async function installDesktopFile(squashRoot, appImage) {
// Remove stale desktop files to clean up the cache.
for (const filename of await fs.readdir(appsDir)) {
if (filename.startsWith(desktopFileBaseName) && filename.endsWith('.desktop')) {
-
// Don't delete testnet files if not installing testnet and vice versa.
if (IS_TESTNET === filename.includes('testnet')) {
await fs.remove(path.join(appsDir, filename)).catch(() => {});
@@ -138,10 +133,7 @@ async function installDesktopFile(squashRoot, appImage) {
// Replace AppRun with the actual AppImage path and append --no-sandbox %U
// Need to have --no-sandbox for Electron otherwise the deeplinks fail.
- desktopFileContent = desktopFileContent.replace(
- /^Exec=.*$/m,
- `Exec=${appImage} --no-sandbox %U`
- );
+ desktopFileContent = desktopFileContent.replace(/^Exec=.*$/m, `Exec=${appImage} --no-sandbox %U`);
// Update the StartupWMClass to properly associate the running app with the desktop icon.
// The name used by electron doesn't match the one used by electron builder, so we need to set it here.
@@ -150,10 +142,17 @@ async function installDesktopFile(squashRoot, appImage) {
/^StartupWMClass=.*$/m,
`StartupWMClass=${wmClass}`
);
-
- await fs.writeFile(desktopFile, desktopFileContent, { mode: 0o644 });
-
- return { content: desktopFileContent, path: desktopFile };
+
+ await fs.writeFile(desktopFile, desktopFileContent, {mode: 0o644});
+
+ return {content: desktopFileContent, path: desktopFile};
+}
+
+// MIME types must be in the form "type/subtype" or "x-scheme-handler/scheme", with only
+// alphanumeric characters, hyphens, dots, underscores, and plus signs allowed in each part.
+// This prevents a maliciously crafted AppImage from injecting shell commands via MimeType entries.
+function isValidMimeType(mimeType) {
+ return /^[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_.+]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_.+]*$/.test(mimeType);
}
async function registerDesktopFile(desktopFileName, desktopFileContent) {
@@ -163,7 +162,10 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
let mimeTypes = [];
const mimeTypeMatch = desktopFileContent.match(/^MimeType=(.+)$/m);
if (mimeTypeMatch) {
- mimeTypes = mimeTypeMatch[1].split(';').map(m => m.trim()).filter(m => m.length > 0);
+ mimeTypes = mimeTypeMatch[1]
+ .split(';')
+ .map(m => m.trim())
+ .filter(m => m.length > 0 && isValidMimeType(m));
}
// Skip registration if no MIME types found in desktop file
@@ -172,27 +174,29 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
}
// Create the desktop integration.
- await run(`update-desktop-database "${appsDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
-
+ await runFile('update-desktop-database', [appsDir], {maxBuffer: MAX_BUFFER_SIZE});
+
// Force update desktop menu.
try {
- await run(`xdg-desktop-menu forceupdate`, { maxBuffer: MAX_BUFFER_SIZE });
+ await runFile('xdg-desktop-menu', ['forceupdate'], {maxBuffer: MAX_BUFFER_SIZE});
} catch {}
for (const mimeType of mimeTypes) {
try {
- await run(`xdg-mime default "${path.basename(desktopFileName)}" "${mimeType}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ await runFile('xdg-mime', ['default', path.basename(desktopFileName), mimeType], {
+ maxBuffer: MAX_BUFFER_SIZE,
+ });
} catch {}
}
-
+
// Update MIME database.
try {
const mimeDir = path.join(xdgDataHome(), 'mime');
- await run(`update-mime-database "${mimeDir}"`, { maxBuffer: MAX_BUFFER_SIZE });
+ await runFile('update-mime-database', [mimeDir], {maxBuffer: MAX_BUFFER_SIZE});
} catch {}
}
-module.exports = (api) => {
+module.exports = api => {
api.installLinuxDeeplinkIntegration = async () => {
if (process.platform !== 'linux') return;
@@ -200,14 +204,14 @@ module.exports = (api) => {
// the user will always have a working integration.
const appImage = process.env.APPIMAGE;
-
+
// Skip it if not running from an AppImage.
if (!appImage || !(await fs.pathExists(appImage))) {
return;
}
const tmpBase = await fs.mkdtemp(path.join(os.tmpdir(), 'verus-appimage-'));
-
+
try {
const squashRoot = await extractAppImage(appImage, tmpBase);
await installIcons(squashRoot);
@@ -216,7 +220,7 @@ module.exports = (api) => {
} finally {
await fs.remove(tmpBase);
}
- }
+ };
return api;
};
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.js
index 81efeb71..8195fd1a 100644
--- a/routes/api/utils/credentials/encryptCredentials.js
+++ b/routes/api/utils/credentials/encryptCredentials.js
@@ -5,6 +5,8 @@ const {
DATA_TYPE_OBJECT_DATADESCRIPTOR,
} = require('verus-typescript-primitives');
+// Replaces the credentials in the contentmultimap with their encrypted forms
+// in data descriptors.
const encryptCredentialsInContentMultiMap = async (
api,
coin,
From e87d5d556de3dad5a775981a55e01afd34f0956c Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 11 Mar 2026 18:29:39 -0700
Subject: [PATCH 71/80] Start updating encryptCredentials to TypeScript in
order to update it for the contentmultimap changes.
---
.../credentials/{encryptCredentials.js => encryptCredentials.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename routes/api/utils/credentials/{encryptCredentials.js => encryptCredentials.ts} (100%)
diff --git a/routes/api/utils/credentials/encryptCredentials.js b/routes/api/utils/credentials/encryptCredentials.ts
similarity index 100%
rename from routes/api/utils/credentials/encryptCredentials.js
rename to routes/api/utils/credentials/encryptCredentials.ts
From a9dccb767fd50b874c3dd5087a81f333b2ed4021 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 12 Mar 2026 14:54:00 -0700
Subject: [PATCH 72/80] Update to the newest version of
verus-typescript-primitives and improve the code quality of the desktop
integration setup.
---
routes/api/dlhandler.js | 2 -
.../identity/executeIdentityUpdateRequest.ts | 6 +-
routes/api/utility_apis/deeplinkSetup.js | 32 +++++---
.../utils/credentials/encryptCredentials.ts | 75 ++++++++++++-------
yarn.lock | 11 +--
5 files changed, 78 insertions(+), 48 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 5bc4cca3..867ad716 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -3,8 +3,6 @@ const {
GenericRequest,
LOGIN_CONSENT_REQUEST_VDXF_KEY,
LoginConsentRequest,
- VERUSPAY_INVOICE_VDXF_KEY,
- VerusPayInvoice,
} = require('verus-typescript-primitives');
const {ROOT_SYSTEM_NAME} = require('./utils/constants/dev_options');
const {SUPPORTED_DLS, CALLBACK_HOST} = require('./utils/constants/supported_dls');
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index be112485..657ccd5a 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -22,7 +22,7 @@ module.exports = (api: any) => {
const zaddress = identity.identity.privateaddress;
if (!zaddress) {
- throw new Error(`No z-address found for identity ${address}`);
+ throw new Error(`No z-address found for identity ${address}.`);
}
const args: ZGetEncryptionAddressArgs = {
@@ -32,11 +32,11 @@ module.exports = (api: any) => {
};
// Generate the viewing key and encryption address to encrypt the credentials.
- const encryptionAddressInfo: ZGetEncryptionAddressResult =
+ const encryptionAddressInfo: ZGetEncryptionAddressResult | null =
await api.native.z_get_encryption_address(coin, args);
if (!encryptionAddressInfo || !encryptionAddressInfo.address || !encryptionAddressInfo.ivk) {
- throw new Error(`Failed to get the personal encryption address for ${address}`);
+ throw new Error(`Failed to get the personal encryption address for ${address}.`);
}
const contentmultimap = detail.identity.content_multimap;
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index 2a6c053d..b7ccd353 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -4,7 +4,7 @@ const os = require('os');
const {execFile} = require('child_process');
const util = require('util');
const {IS_TESTNET} = require('../utils/constants/dev_options');
-const runFile = util.promisify(execFile);
+const execFileAsync = util.promisify(execFile);
const {APP_NAME} = require('../../appBasicInfo');
// Increase maxBuffer to handle large outputs (e.g., AppImage extraction).
@@ -15,7 +15,7 @@ function xdgDataHome() {
}
async function extractAppImage(appImage, tmpDir) {
- await runFile(appImage, ['--appimage-extract'], {
+ await execFileAsync(appImage, ['--appimage-extract'], {
cwd: tmpDir,
maxBuffer: MAX_BUFFER_SIZE,
});
@@ -69,8 +69,10 @@ async function installIcons(squashRoot) {
for (const [cmd, args] of iconCacheCommands) {
try {
- await runFile(cmd, args, {maxBuffer: MAX_BUFFER_SIZE});
- } catch {}
+ await execFileAsync(cmd, args, {maxBuffer: MAX_BUFFER_SIZE});
+ } catch (e) {
+ console.warn(`${cmd} ${args.join(' ')} failed:`, e);
+ }
}
}
}
@@ -174,26 +176,32 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
}
// Create the desktop integration.
- await runFile('update-desktop-database', [appsDir], {maxBuffer: MAX_BUFFER_SIZE});
+ await execFileAsync('update-desktop-database', [appsDir], {maxBuffer: MAX_BUFFER_SIZE});
// Force update desktop menu.
try {
- await runFile('xdg-desktop-menu', ['forceupdate'], {maxBuffer: MAX_BUFFER_SIZE});
- } catch {}
+ await execFileAsync('xdg-desktop-menu', ['forceupdate'], {maxBuffer: MAX_BUFFER_SIZE});
+ } catch (e) {
+ console.warn(`xdg-desktop-menu forceupdate failed:`, e);
+ }
for (const mimeType of mimeTypes) {
try {
- await runFile('xdg-mime', ['default', path.basename(desktopFileName), mimeType], {
+ await execFileAsync('xdg-mime', ['default', path.basename(desktopFileName), mimeType], {
maxBuffer: MAX_BUFFER_SIZE,
});
- } catch {}
+ } catch (e) {
+ console.warn(`xdg-mime default ${path.basename(desktopFileName)} ${mimeType} failed:`, e);
+ }
}
// Update MIME database.
+ const mimeDir = path.join(xdgDataHome(), 'mime');
try {
- const mimeDir = path.join(xdgDataHome(), 'mime');
- await runFile('update-mime-database', [mimeDir], {maxBuffer: MAX_BUFFER_SIZE});
- } catch {}
+ await execFileAsync('update-mime-database', [mimeDir], {maxBuffer: MAX_BUFFER_SIZE});
+ } catch (e) {
+ console.warn(`update-mime-database with ${mimeDir} failed:`, e);
+ }
}
module.exports = api => {
diff --git a/routes/api/utils/credentials/encryptCredentials.ts b/routes/api/utils/credentials/encryptCredentials.ts
index 8195fd1a..a789e93b 100644
--- a/routes/api/utils/credentials/encryptCredentials.ts
+++ b/routes/api/utils/credentials/encryptCredentials.ts
@@ -1,31 +1,50 @@
-const {
- IDENTITY_CREDENTIAL,
+import {
+ CompactIAddressObject,
+ ContentMultiMap,
+ Credential,
+ DATA_DESCRIPTOR_VDXF_KEY,
DATA_TYPE_OBJECT_CREDENTIAL,
DataDescriptor,
- DATA_TYPE_OBJECT_DATADESCRIPTOR,
-} = require('verus-typescript-primitives');
+ IDENTITY_CREDENTIAL,
+ VdxfUniValue,
+} from 'verus-typescript-primitives';
+
+interface GetVdxfIdResult {
+ vdxfid: string;
+ indexid: string;
+ hash160result: string;
+ qualifiedname: {
+ namespace: string;
+ name: string;
+ };
+ bounddata?: {
+ vdxfkey: string;
+ };
+}
// Replaces the credentials in the contentmultimap with their encrypted forms
// in data descriptors.
-const encryptCredentialsInContentMultiMap = async (
- api,
- coin,
- address,
- contentmultimap,
- ivk,
- encryptionAddress
-) => {
- for (const [key, valueArray] of contentmultimap.kv_content.entries()) {
- if (key === IDENTITY_CREDENTIAL.vdxfid) {
+export async function encryptCredentialsInContentMultiMap(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api: any,
+ coin: string,
+ address: string,
+ contentmultimap: ContentMultiMap,
+ ivk: string,
+ encryptionAddress: string
+): Promise {
+ for (const [key, valueArray] of Array.from(contentmultimap.kvContent.entries())) {
+ if (key.toIAddress() === IDENTITY_CREDENTIAL.vdxfid) {
for (let i = 0; i < valueArray.length; i++) {
const vdxfUniValue = valueArray[i];
+ if (!(vdxfUniValue instanceof VdxfUniValue)) continue;
for (const valueObj of vdxfUniValue.values) {
// Each valueObj contains exactly one key-value pair.
const valueKey = Object.keys(valueObj)[0];
if (valueKey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
// Replace the credential with the encrypted data descriptor.
- const vdxfUniType = valueObj[valueKey];
+ const vdxfUniType = valueObj[valueKey] as Credential;
const signdataResult = await api.native.sign_data(coin, {
address: address,
@@ -33,18 +52,26 @@ const encryptCredentialsInContentMultiMap = async (
encrypttoaddress: encryptionAddress,
});
+ if (!signdataResult) {
+ throw new Error('Failed to encrypt the credential.');
+ }
+
const dataDescriptor = DataDescriptor.fromJson(
signdataResult.mmrdescriptor_encrypted.datadescriptors[0]
);
delete valueObj[valueKey];
- valueObj[DATA_TYPE_OBJECT_DATADESCRIPTOR.vdxfid] = dataDescriptor;
+ valueObj[DATA_DESCRIPTOR_VDXF_KEY.vdxfid] = dataDescriptor;
}
}
}
// Replace the credentials key with a hashed key.
- const credentialKeyResult = await api.native.get_vdxf_id(coin, IDENTITY_CREDENTIAL.vdxfid, {
- uint256: ivk,
- });
+ const credentialKeyResult: GetVdxfIdResult | null = await api.native.get_vdxf_id(
+ coin,
+ IDENTITY_CREDENTIAL.vdxfid,
+ {
+ uint256: ivk,
+ }
+ );
if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
throw new Error('Failed to generate credential key');
@@ -52,13 +79,9 @@ const encryptCredentialsInContentMultiMap = async (
const credentialKey = credentialKeyResult.vdxfid;
- contentmultimap.kv_content.set(credentialKey, valueArray);
- contentmultimap.kv_content.delete(IDENTITY_CREDENTIAL.vdxfid);
+ contentmultimap.kvContent.set(CompactIAddressObject.fromAddress(credentialKey), valueArray);
+ contentmultimap.kvContent.delete(key);
break;
}
}
-};
-
-module.exports = {
- encryptCredentialsInContentMultiMap,
-};
+}
diff --git a/yarn.lock b/yarn.lock
index 2db01b20..d576ec5f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1711,7 +1711,7 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-axios@0.25.0, axios@1.11.0, axios@1.7.4:
+axios@0.25.0, axios@1.13.5, axios@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
@@ -9475,12 +9475,12 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#a4fbacd6da2c7840e4fb0a8845d156e0727af4bf"
+ resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#f9633091ba7fc03c4fbe2657d901a81cac2d45e1"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
blake2b "https://github.com/VerusCoin/blake2b"
- bn.js "5.2.1"
+ bn.js "5.2.3"
bs58check "2.0.0"
create-hash "1.2.0"
@@ -9505,9 +9505,10 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client.git":
version "0.1.0"
- resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#1ffe2e7abd52941d2c4263a4ab7a5853edc7369a"
+ resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#31a48b3e377a78ed23767f15355d30d5055b3f27"
dependencies:
- axios "1.11.0"
+ axios "1.13.5"
+ blake2b "https://github.com/VerusCoin/blake2b"
verus-typescript-primitives "git+https://github.com/VerusCoin/verus-typescript-primitives.git"
wcwidth@^1.0.0:
From f911532cac20f7d0d6804a6512cf3125c6172978 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 12 Mar 2026 15:59:51 -0700
Subject: [PATCH 73/80] Further improve the code based on review.
---
routes/api/dlhandler.js | 10 ++----
routes/api/minimize.js | 34 +++++++++++--------
.../api/native/credentials/getCredentials.ts | 17 +++-------
.../verusid/generic/signGenericResponse.ts | 4 +++
.../verusid/generic/verifyGenericRequest.js | 4 +--
.../identity/executeIdentityUpdateRequest.ts | 11 +++---
routes/api/utils/constants/supported_dls.js | 16 ++++-----
7 files changed, 44 insertions(+), 52 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 867ad716..592a4eb4 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -5,7 +5,7 @@ const {
LoginConsentRequest,
} = require('verus-typescript-primitives');
const {ROOT_SYSTEM_NAME} = require('./utils/constants/dev_options');
-const {SUPPORTED_DLS, CALLBACK_HOST} = require('./utils/constants/supported_dls');
+const {SUPPORTED_V1_DLS, CALLBACK_HOST} = require('./utils/constants/supported_dls');
module.exports = api => {
api.dlhandler = urlstring => {
@@ -19,7 +19,7 @@ module.exports = api => {
if (url.host === CALLBACK_HOST) {
id = url.pathname.split('/')[1];
- if (!SUPPORTED_DLS.includes(id)) {
+ if (!SUPPORTED_V1_DLS.includes(id)) {
throw new Error('Unsupported deeplink url path.');
}
@@ -28,12 +28,6 @@ module.exports = api => {
case LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid:
dl = LoginConsentRequest.fromWalletDeeplinkUri(urlstring);
break;
-
- /* Currently VerusPay invoices are unsupported.
- case VERUSPAY_INVOICE_VDXF_KEY.vdxfid:
- dl = VerusPayInvoice.fromWalletDeeplinkUri(urlstring);
- break;
- */
default:
throw new Error(`Unsupported deeplink ID: ${urlstring}`);
}
diff --git a/routes/api/minimize.js b/routes/api/minimize.js
index 012040bf..82a463a4 100644
--- a/routes/api/minimize.js
+++ b/routes/api/minimize.js
@@ -1,22 +1,26 @@
-module.exports = (api) => {
- api.setupMinimizeApis = (minimizeFunction) => {
- api.minimizeApp = minimizeFunction
+module.exports = api => {
+ api.setupMinimizeApis = minimizeFunction => {
+ api.minimizeApp = minimizeFunction;
- api.setPost('/plugin/minimize', async (req, res, next) => {
+ api.setPost('/plugin/minimize', async (req, res) => {
try {
- api.minimizeApp()
+ api.minimizeApp();
- res.send(JSON.stringify({
- msg: 'success'
- }))
- } catch(e) {
- res.send(JSON.stringify({
- msg: 'error',
- error: e.message
- }))
+ res.send(
+ JSON.stringify({
+ msg: 'success',
+ })
+ );
+ } catch (e) {
+ res.send(
+ JSON.stringify({
+ msg: 'error',
+ result: e.message,
+ })
+ );
}
});
- }
+ };
return api;
-};
\ No newline at end of file
+};
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index 72a4a94f..f43d38a1 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -53,18 +53,11 @@ export default (api: any) => {
}
// Generate the viewing key to decrypt the credentials.
- const keys: ZGetEncryptionAddressResult | null = await api.native.z_get_encryption_address(
- coin,
- {
- address: zaddress,
- fromid: address,
- toid: address,
- }
- );
-
- if (!keys || !keys.extendedviewingkey || !keys.ivk) {
- throw new Error(`Failed to get keys for ${address}`);
- }
+ const keys: ZGetEncryptionAddressResult = await api.native.z_get_encryption_address(coin, {
+ address: zaddress,
+ fromid: address,
+ toid: address,
+ });
const evk = keys.extendedviewingkey;
const ivk = keys.ivk;
diff --git a/routes/api/native/verusid/generic/signGenericResponse.ts b/routes/api/native/verusid/generic/signGenericResponse.ts
index 5293558b..57cff9c5 100644
--- a/routes/api/native/verusid/generic/signGenericResponse.ts
+++ b/routes/api/native/verusid/generic/signGenericResponse.ts
@@ -8,6 +8,10 @@ export default (api: any) => {
datahash: response.getRawDataSha256().toString('hex'),
});
+ if (!signdataResult || !signdataResult.signature) {
+ throw new Error('No signature returned from signdata.');
+ }
+
response.signature.signatureAsVch = Buffer.from(signdataResult.signature, 'base64');
return response;
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
index 6b7e3638..e9d9dfa5 100644
--- a/routes/api/native/verusid/generic/verifyGenericRequest.js
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -17,10 +17,10 @@ module.exports = api => {
api.setPost('/native/verusid/generic/verify_generic_request', async (req, res) => {
const {chainTicker, request} = req.body;
- // The request is sent as a QR string to avoid IPC serialization issues.
- const genericRequest = GenericRequest.fromQrString(request);
try {
+ // The request is sent as a QR string to avoid IPC serialization issues.
+ const genericRequest = GenericRequest.fromQrString(request);
res.send(
JSON.stringify({
msg: 'success',
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index 657ccd5a..de98f8c0 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -19,6 +19,11 @@ module.exports = (api: any) => {
detail.identity.name = detail.identity.name + '@';
const address = detail.identity.name;
const identity = await api.native.get_identity(coin, detail.identity.name);
+
+ if (!identity) {
+ throw new Error(`No identity found for ${address}.`);
+ }
+
const zaddress = identity.identity.privateaddress;
if (!zaddress) {
@@ -32,13 +37,9 @@ module.exports = (api: any) => {
};
// Generate the viewing key and encryption address to encrypt the credentials.
- const encryptionAddressInfo: ZGetEncryptionAddressResult | null =
+ const encryptionAddressInfo: ZGetEncryptionAddressResult =
await api.native.z_get_encryption_address(coin, args);
- if (!encryptionAddressInfo || !encryptionAddressInfo.address || !encryptionAddressInfo.ivk) {
- throw new Error(`Failed to get the personal encryption address for ${address}.`);
- }
-
const contentmultimap = detail.identity.content_multimap;
if (contentmultimap) {
diff --git a/routes/api/utils/constants/supported_dls.js b/routes/api/utils/constants/supported_dls.js
index 864293a3..6a3a6cad 100644
--- a/routes/api/utils/constants/supported_dls.js
+++ b/routes/api/utils/constants/supported_dls.js
@@ -1,14 +1,10 @@
-const { LOGIN_CONSENT_REQUEST_VDXF_KEY, VERUSPAY_INVOICE_VDXF_KEY, IDENTITY_UPDATE_REQUEST_VDXF_KEY } = require("verus-typescript-primitives")
+const {LOGIN_CONSENT_REQUEST_VDXF_KEY} = require('verus-typescript-primitives');
-const CALLBACK_HOST = 'x-callback-url'
+const CALLBACK_HOST = 'x-callback-url';
-const SUPPORTED_DLS = [
- LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid,
- VERUSPAY_INVOICE_VDXF_KEY.vdxfid,
- IDENTITY_UPDATE_REQUEST_VDXF_KEY.vdxfid
-]
+const SUPPORTED_V1_DLS = [LOGIN_CONSENT_REQUEST_VDXF_KEY.vdxfid];
module.exports = {
- SUPPORTED_DLS,
- CALLBACK_HOST
-}
\ No newline at end of file
+ SUPPORTED_V1_DLS,
+ CALLBACK_HOST,
+};
From a53017228a75362eebadeaab995fd758d80110f7 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 12 Mar 2026 17:10:50 -0700
Subject: [PATCH 74/80] Move the sort import plugin to the dev dependencies.
(cherry picked from commit 613c3e00535e7ffe076c8cb791404b81001ac01e)
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index d0261225..2f95cd84 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,6 @@
"dependencies": {
"@bitgo/utxo-lib": "git+https://github.com/VerusCoin/BitGoJS.git#utxo-lib-verus",
"@electron/remote": "1.1.0",
- "@ianvs/prettier-plugin-sort-imports": "4.7.0",
"@noble/curves": "1.2.0",
"@xmldom/xmldom": "0.8.4",
"agama-wallet-lib": "git+https://github.com/VerusCoin/agama-wallet-lib.git#dev",
@@ -97,6 +96,7 @@
"eslint-config-prettier": "10.1.8",
"eslint-plugin-react": "7.37.5",
"globals": "17.0.0",
+ "@ianvs/prettier-plugin-sort-imports": "4.7.0",
"prettier": "3.6.0",
"typescript": "5.8.3",
"typescript-eslint": "8.53.0"
From 488d0203b1975f071e8b0e89c7dfa183864d600d Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 23 Mar 2026 16:53:30 -0700
Subject: [PATCH 75/80] Update to the latest version of
verus-typescript-primitives and update encrypting the credentials as part of
the identity update request execution.
(cherry picked from commit cde457b2c8f728157978d81f72c7691778be5277)
---
package.json | 2 +-
.../identity/executeIdentityUpdateRequest.ts | 2 +-
.../utils/credentials/encryptCredentials.ts | 38 ++++++++++++-------
yarn.lock | 4 +-
4 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/package.json b/package.json
index 2f95cd84..89d9c6c1 100644
--- a/package.json
+++ b/package.json
@@ -86,6 +86,7 @@
},
"devDependencies": {
"@eslint/js": "9.39.2",
+ "@ianvs/prettier-plugin-sort-imports": "4.7.0",
"@types/node": "18.19.0",
"copyfiles": "2.4.1",
"cross-env": "5.2.1",
@@ -96,7 +97,6 @@
"eslint-config-prettier": "10.1.8",
"eslint-plugin-react": "7.37.5",
"globals": "17.0.0",
- "@ianvs/prettier-plugin-sort-imports": "4.7.0",
"prettier": "3.6.0",
"typescript": "5.8.3",
"typescript-eslint": "8.53.0"
diff --git a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
index de98f8c0..7fde3582 100644
--- a/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
+++ b/routes/api/native/verusid/identity/executeIdentityUpdateRequest.ts
@@ -40,7 +40,7 @@ module.exports = (api: any) => {
const encryptionAddressInfo: ZGetEncryptionAddressResult =
await api.native.z_get_encryption_address(coin, args);
- const contentmultimap = detail.identity.content_multimap;
+ const contentmultimap = detail.identity.contentMultiMap;
if (contentmultimap) {
await encryptCredentialsInContentMultiMap(
diff --git a/routes/api/utils/credentials/encryptCredentials.ts b/routes/api/utils/credentials/encryptCredentials.ts
index a789e93b..50ce10fd 100644
--- a/routes/api/utils/credentials/encryptCredentials.ts
+++ b/routes/api/utils/credentials/encryptCredentials.ts
@@ -1,12 +1,13 @@
import {
CompactIAddressObject,
- ContentMultiMap,
Credential,
DATA_DESCRIPTOR_VDXF_KEY,
DATA_TYPE_OBJECT_CREDENTIAL,
DataDescriptor,
+ FqnContentMultiMap,
+ FqnVdxfUniValue,
IDENTITY_CREDENTIAL,
- VdxfUniValue,
+ VdxfUniType,
} from 'verus-typescript-primitives';
interface GetVdxfIdResult {
@@ -29,7 +30,7 @@ export async function encryptCredentialsInContentMultiMap(
api: any,
coin: string,
address: string,
- contentmultimap: ContentMultiMap,
+ contentmultimap: FqnContentMultiMap,
ivk: string,
encryptionAddress: string
): Promise {
@@ -37,18 +38,22 @@ export async function encryptCredentialsInContentMultiMap(
if (key.toIAddress() === IDENTITY_CREDENTIAL.vdxfid) {
for (let i = 0; i < valueArray.length; i++) {
const vdxfUniValue = valueArray[i];
- if (!(vdxfUniValue instanceof VdxfUniValue)) continue;
- for (const valueObj of vdxfUniValue.values) {
+ if (!(vdxfUniValue instanceof FqnVdxfUniValue)) continue;
+ // vdxfUniValue.values doesn't work for key comparison since it uses a
+ // different method for generating string keys than toIAddress() or toAddress().
+ // We also have to completely rebuild the values array since we can't modify
+ // it in place.
+ const newValues: Array<{[key: string]: VdxfUniType}> = [];
+ for (const [valueKey, valueType] of Array.from(vdxfUniValue.entries())) {
// Each valueObj contains exactly one key-value pair.
- const valueKey = Object.keys(valueObj)[0];
-
- if (valueKey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
+ const vdxfkey = valueKey.toAddress();
+ if (vdxfkey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
// Replace the credential with the encrypted data descriptor.
- const vdxfUniType = valueObj[valueKey] as Credential;
+ const credential = valueType as Credential;
const signdataResult = await api.native.sign_data(coin, {
address: address,
- vdxfdata: {[valueKey]: vdxfUniType.toJson()},
+ vdxfdata: {[vdxfkey]: credential.toJson()},
encrypttoaddress: encryptionAddress,
});
@@ -59,13 +64,20 @@ export async function encryptCredentialsInContentMultiMap(
const dataDescriptor = DataDescriptor.fromJson(
signdataResult.mmrdescriptor_encrypted.datadescriptors[0]
);
- delete valueObj[valueKey];
- valueObj[DATA_DESCRIPTOR_VDXF_KEY.vdxfid] = dataDescriptor;
+ const descriptorKey = CompactIAddressObject.fromAddress(
+ DATA_DESCRIPTOR_VDXF_KEY.vdxfid
+ );
+ // The setter for the values array converts using Buffer.from(key, 'hex')
+ // so we need to use hex buffer representations.
+ newValues.push({[descriptorKey.toBuffer().toString('hex')]: dataDescriptor});
+ } else {
+ newValues.push({[valueKey.toBuffer().toString('hex')]: valueType});
}
}
+ vdxfUniValue.values = newValues;
}
// Replace the credentials key with a hashed key.
- const credentialKeyResult: GetVdxfIdResult | null = await api.native.get_vdxf_id(
+ const credentialKeyResult: GetVdxfIdResult = await api.native.get_vdxf_id(
coin,
IDENTITY_CREDENTIAL.vdxfid,
{
diff --git a/yarn.lock b/yarn.lock
index d576ec5f..660cfacd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9475,7 +9475,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#f9633091ba7fc03c4fbe2657d901a81cac2d45e1"
+ resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#54dc62aecec3337e3b5672cb061a51445c3c8acd"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -9505,7 +9505,7 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client.git":
version "0.1.0"
- resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#31a48b3e377a78ed23767f15355d30d5055b3f27"
+ resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#e393236112a3bf5d51e25db541f986531d381fbd"
dependencies:
axios "1.13.5"
blake2b "https://github.com/VerusCoin/blake2b"
From 25d5f01ec12e27a6f97124230027603703386317 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 26 Mar 2026 00:15:51 -0700
Subject: [PATCH 76/80] Further review and clean up code.
(cherry picked from commit 26ca7de484abde00e935fe183aa60ba0dad2d897)
---
routes/api/dlhandler.js | 16 +++--
.../verusid/generic/verifyGenericRequest.js | 5 +-
routes/api/plugin/builtin/loginconsentui.ts | 71 +++----------------
routes/api/utility_apis/deeplinkSetup.js | 10 +--
scripts/dev.sh | 4 +-
scripts/setup.sh | 4 +-
6 files changed, 28 insertions(+), 82 deletions(-)
diff --git a/routes/api/dlhandler.js b/routes/api/dlhandler.js
index 592a4eb4..64464c19 100644
--- a/routes/api/dlhandler.js
+++ b/routes/api/dlhandler.js
@@ -33,12 +33,16 @@ module.exports = api => {
}
data = dl.toJson();
} else {
- const req = GenericRequest.fromWalletDeeplinkUri(urlstring);
- id = GENERIC_REQUEST_DEEPLINK_VDXF_KEY.vdxfid;
- // Send the request as a QR string so it's properly serialized.
- // If the buffer is sent directly, the IPC converts it to a JSON object and increases
- // the size of the payload.
- data = req.toQrString();
+ if (api.appConfig.general.main.experimentalFeatures) {
+ const req = GenericRequest.fromWalletDeeplinkUri(urlstring);
+ id = GENERIC_REQUEST_DEEPLINK_VDXF_KEY.vdxfid;
+ // Send the request as the hex string of the buffer so it's properly serialized.
+ // If the buffer is sent directly, the IPC converts it to a JSON object and increases
+ // the size of the payload.
+ data = req.toBuffer().toString('hex');
+ } else {
+ throw new Error('Generic requests are only allowed with experimental features enabled.');
+ }
}
return api.loginConsentUi.deeplink(
diff --git a/routes/api/native/verusid/generic/verifyGenericRequest.js b/routes/api/native/verusid/generic/verifyGenericRequest.js
index e9d9dfa5..ebbda37f 100644
--- a/routes/api/native/verusid/generic/verifyGenericRequest.js
+++ b/routes/api/native/verusid/generic/verifyGenericRequest.js
@@ -19,8 +19,9 @@ module.exports = api => {
const {chainTicker, request} = req.body;
try {
- // The request is sent as a QR string to avoid IPC serialization issues.
- const genericRequest = GenericRequest.fromQrString(request);
+ // The request is sent as a hex string of the buffer to avoid IPC serialization issues.
+ const genericRequest = new GenericRequest();
+ genericRequest.fromBuffer(Buffer.from(request, 'hex'));
res.send(
JSON.stringify({
msg: 'success',
diff --git a/routes/api/plugin/builtin/loginconsentui.ts b/routes/api/plugin/builtin/loginconsentui.ts
index 5ebfdfc8..e05525ba 100644
--- a/routes/api/plugin/builtin/loginconsentui.ts
+++ b/routes/api/plugin/builtin/loginconsentui.ts
@@ -1,8 +1,8 @@
-import axios, {AxiosResponse} from 'axios';
+import axios from 'axios';
import base64url from 'base64url';
import {BrowserWindow, shell} from 'electron';
import {
- GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY,
+ GENERIC_RESPONSE_DEEPLINK_VDXF_KEY,
LOGIN_CONSENT_REDIRECT_VDXF_KEY,
LOGIN_CONSENT_RESPONSE_VDXF_KEY,
LOGIN_CONSENT_WEBHOOK_VDXF_KEY,
@@ -44,58 +44,6 @@ interface MultiURIResult {
type DeeplinkResponse = SingleURIResult | MultiURIResult | {error: string};
-interface RequestBody {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- request: any;
-}
-
-interface ApiHeader {
- app_id: string;
- builtin: boolean;
-}
-
-interface Request {
- body: RequestBody;
- api_header: ApiHeader;
-}
-
-interface Response {
- send: (data: string) => void;
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type AnyApi = any;
-
-// Temporary typing before the rest of the project is converted.
-interface Api {
- loginConsentUi: {
- handle_redirect: (
- responseKey: string,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- response: any,
- redirectinfo: RedirectInfo
- ) => Promise | null;
- handle_multi_uris: (
- responseKey: string,
- response: string,
- uris: ResponseURIJson[]
- ) => Promise;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- deeplink: (deeplink: any, originInfo: OriginInfo) => Promise;
- };
- minimizeApp: () => void;
- startPlugin: (
- type: string,
- builtin: boolean,
- onComplete: (data: DeeplinkResponse) => void,
- onFinishLoad: (pluginWindow: BrowserWindow) => void,
- width: number,
- height: number,
- frame: boolean
- ) => void;
- setPost: (path: string, handler: (req: Request, res: Response) => Promise) => void;
-}
-
// Wraps shell.openExternal to prevent opening any urls that don't go to the browser for security reasons.
function safeOpenExternal(url: URL): void {
if (!['https:', 'http:'].includes(url.protocol)) {
@@ -109,7 +57,8 @@ function safeOpenExternal(url: URL): void {
}
}
-export = (api: AnyApi): Api => {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export = (api: any) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
api.loginConsentUi = {} as any;
@@ -117,7 +66,7 @@ export = (api: AnyApi): Api => {
api.loginConsentUi.respond = async (response: string, uris: ResponseURIJson[]): Promise => {
if (!uris || uris.length === 0) return;
- // Convert JSON objects to ResponseURI instances and find the first POST URI, fallback to REDIRECT
+ // Convert JSON objects to ResponseURI instances and find the first POST URI, fallback to REDIRECT.
const responseUris = uris.map(uri => ResponseURI.fromJson(uri));
const selectedUri =
responseUris.find(uri => uri.type.eq(ResponseURI.TYPE_POST)) ??
@@ -128,7 +77,7 @@ export = (api: AnyApi): Api => {
// Deserialize the response from hex string to Buffer
const responseBuffer = Buffer.from(response, 'hex');
- // Handle POST URI
+ // Handle POST URI.
if (selectedUri.type.eq(ResponseURI.TYPE_POST)) {
setTimeout(() => {
api.minimizeApp();
@@ -146,12 +95,11 @@ export = (api: AnyApi): Api => {
return;
}
- // Handle REDIRECT URI
+ // Handle REDIRECT URI.
if (selectedUri.type.eq(ResponseURI.TYPE_REDIRECT)) {
const url = new URL(selectedUri.getUriString());
- // TODO: Use the response key when the library is updated
- url.searchParams.set(GENERIC_ENVELOPE_DEEPLINK_VDXF_KEY.vdxfid, base64url(responseBuffer));
+ url.searchParams.set(GENERIC_RESPONSE_DEEPLINK_VDXF_KEY.vdxfid, base64url(responseBuffer));
safeOpenExternal(url);
}
};
@@ -260,7 +208,8 @@ export = (api: AnyApi): Api => {
api.setPost(
'/plugin/builtin/verus_login_consent_ui/request',
- async (req: Request, res: Response) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async (req: any, res: any) => {
const {request} = req.body;
const {app_id, builtin} = req.api_header;
diff --git a/routes/api/utility_apis/deeplinkSetup.js b/routes/api/utility_apis/deeplinkSetup.js
index b7ccd353..573b8fed 100644
--- a/routes/api/utility_apis/deeplinkSetup.js
+++ b/routes/api/utility_apis/deeplinkSetup.js
@@ -150,13 +150,6 @@ async function installDesktopFile(squashRoot, appImage) {
return {content: desktopFileContent, path: desktopFile};
}
-// MIME types must be in the form "type/subtype" or "x-scheme-handler/scheme", with only
-// alphanumeric characters, hyphens, dots, underscores, and plus signs allowed in each part.
-// This prevents a maliciously crafted AppImage from injecting shell commands via MimeType entries.
-function isValidMimeType(mimeType) {
- return /^[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_.+]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-^_.+]*$/.test(mimeType);
-}
-
async function registerDesktopFile(desktopFileName, desktopFileContent) {
const appsDir = path.dirname(desktopFileName);
@@ -167,7 +160,7 @@ async function registerDesktopFile(desktopFileName, desktopFileContent) {
mimeTypes = mimeTypeMatch[1]
.split(';')
.map(m => m.trim())
- .filter(m => m.length > 0 && isValidMimeType(m));
+ .filter(m => m.length > 0);
}
// Skip registration if no MIME types found in desktop file
@@ -210,7 +203,6 @@ module.exports = api => {
// Always run the integration so that if the appimage moves or a new version is being used,
// the user will always have a working integration.
-
const appImage = process.env.APPIMAGE;
// Skip it if not running from an AppImage.
diff --git a/scripts/dev.sh b/scripts/dev.sh
index b943a50f..962cce05 100755
--- a/scripts/dev.sh
+++ b/scripts/dev.sh
@@ -24,7 +24,7 @@ if [ -d "${LOGIN_CONSENT_CLIENT_DIR}" ]; then
) &
fi
-# Check if the pbass visualizer exists and start it if possible
+# Check if the pbaas visualizer exists and start it if possible
if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
(
echo ""
@@ -49,4 +49,4 @@ cleanup() {
sleep 1
}
-trap cleanup EXIT
\ No newline at end of file
+trap cleanup EXIT
diff --git a/scripts/setup.sh b/scripts/setup.sh
index 5333a041..6a97065c 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -26,7 +26,7 @@ if [ -d "${LOGIN_CONSENT_CLIENT_DIR}" ]; then
)
fi
-# Check if the pbass visualizer exists and install dependencies if possible
+# Check if the pbaas visualizer exists and install dependencies if possible
if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
(
echo ""
@@ -40,4 +40,4 @@ fi
# Install dependencies for the electron app
echo ""
echo "Installing dependencies for Verus-Desktop..."
-yarn install
\ No newline at end of file
+yarn install
From 3f495d6e2dbc77b8c27006ba6c858f1de2782df5 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Mon, 30 Mar 2026 10:24:32 -0700
Subject: [PATCH 77/80] Use the new KvMap functions to streamline credential
encryption and switch to using an already existing identity type for the
return type of getIdentityContent.
(cherry picked from commit 8d779f405d6d684654cdb68d9a69963d7168e6c7)
---
.../api/native/credentials/getCredentials.ts | 10 +-
.../utils/credentials/encryptCredentials.ts | 105 +++++++++---------
yarn.lock | 4 +-
3 files changed, 55 insertions(+), 64 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index f43d38a1..3c5ac92a 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -4,6 +4,7 @@ import {
DATA_TYPE_OBJECT_CREDENTIAL,
fromBase58Check,
IDENTITY_CREDENTIAL,
+ IdentityDefinition,
} from 'verus-typescript-primitives';
import {ZGetEncryptionAddressResult} from '../zgetencryptionaddress';
@@ -13,14 +14,7 @@ interface VdxfIdResult {
}
interface IdentityContent {
- identity: {
- privateaddress?: string;
- contentmultimap?: Record<
- string,
- Array | Array>>
- >;
- identityaddress?: string;
- };
+ identity: IdentityDefinition & {privateaddress?: string};
}
interface CredentialsMap {
diff --git a/routes/api/utils/credentials/encryptCredentials.ts b/routes/api/utils/credentials/encryptCredentials.ts
index 50ce10fd..12ede8f2 100644
--- a/routes/api/utils/credentials/encryptCredentials.ts
+++ b/routes/api/utils/credentials/encryptCredentials.ts
@@ -34,66 +34,63 @@ export async function encryptCredentialsInContentMultiMap(
ivk: string,
encryptionAddress: string
): Promise {
- for (const [key, valueArray] of Array.from(contentmultimap.kvContent.entries())) {
- if (key.toIAddress() === IDENTITY_CREDENTIAL.vdxfid) {
- for (let i = 0; i < valueArray.length; i++) {
- const vdxfUniValue = valueArray[i];
- if (!(vdxfUniValue instanceof FqnVdxfUniValue)) continue;
- // vdxfUniValue.values doesn't work for key comparison since it uses a
- // different method for generating string keys than toIAddress() or toAddress().
- // We also have to completely rebuild the values array since we can't modify
- // it in place.
- const newValues: Array<{[key: string]: VdxfUniType}> = [];
- for (const [valueKey, valueType] of Array.from(vdxfUniValue.entries())) {
- // Each valueObj contains exactly one key-value pair.
- const vdxfkey = valueKey.toAddress();
- if (vdxfkey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
- // Replace the credential with the encrypted data descriptor.
- const credential = valueType as Credential;
+ const searchKey = IDENTITY_CREDENTIAL.vdxfid;
+ const valueArray = contentmultimap.kvContent.getByAddress(searchKey);
+ if (!valueArray) return;
- const signdataResult = await api.native.sign_data(coin, {
- address: address,
- vdxfdata: {[vdxfkey]: credential.toJson()},
- encrypttoaddress: encryptionAddress,
- });
+ for (let i = 0; i < valueArray.length; i++) {
+ const vdxfUniValue = valueArray[i];
+ if (!(vdxfUniValue instanceof FqnVdxfUniValue)) continue;
+ // vdxfUniValue.values doesn't work for key comparison since it uses a
+ // different method for generating string keys than toIAddress() or toAddress().
+ // We also have to completely rebuild the values array since we can't modify
+ // it in place.
+ const newValues: Array<{[key: string]: VdxfUniType}> = [];
+ for (const [valueKey, valueType] of Array.from(vdxfUniValue.entries())) {
+ // Each valueObj contains exactly one key-value pair.
+ const vdxfkey = valueKey.toAddress();
+ if (vdxfkey === DATA_TYPE_OBJECT_CREDENTIAL.vdxfid) {
+ // Replace the credential with the encrypted data descriptor.
+ const credential = valueType as Credential;
- if (!signdataResult) {
- throw new Error('Failed to encrypt the credential.');
- }
+ const signdataResult = await api.native.sign_data(coin, {
+ address: address,
+ vdxfdata: {[vdxfkey]: credential.toJson()},
+ encrypttoaddress: encryptionAddress,
+ });
- const dataDescriptor = DataDescriptor.fromJson(
- signdataResult.mmrdescriptor_encrypted.datadescriptors[0]
- );
- const descriptorKey = CompactIAddressObject.fromAddress(
- DATA_DESCRIPTOR_VDXF_KEY.vdxfid
- );
- // The setter for the values array converts using Buffer.from(key, 'hex')
- // so we need to use hex buffer representations.
- newValues.push({[descriptorKey.toBuffer().toString('hex')]: dataDescriptor});
- } else {
- newValues.push({[valueKey.toBuffer().toString('hex')]: valueType});
- }
+ if (!signdataResult) {
+ throw new Error('Failed to encrypt the credential.');
}
- vdxfUniValue.values = newValues;
- }
- // Replace the credentials key with a hashed key.
- const credentialKeyResult: GetVdxfIdResult = await api.native.get_vdxf_id(
- coin,
- IDENTITY_CREDENTIAL.vdxfid,
- {
- uint256: ivk,
- }
- );
- if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
- throw new Error('Failed to generate credential key');
+ const dataDescriptor = DataDescriptor.fromJson(
+ signdataResult.mmrdescriptor_encrypted.datadescriptors[0]
+ );
+ const descriptorKey = CompactIAddressObject.fromAddress(DATA_DESCRIPTOR_VDXF_KEY.vdxfid);
+ // The setter for the values array converts using Buffer.from(key, 'hex')
+ // so we need to use hex buffer representations.
+ newValues.push({[descriptorKey.toBuffer().toString('hex')]: dataDescriptor});
+ } else {
+ newValues.push({[valueKey.toBuffer().toString('hex')]: valueType});
}
-
- const credentialKey = credentialKeyResult.vdxfid;
-
- contentmultimap.kvContent.set(CompactIAddressObject.fromAddress(credentialKey), valueArray);
- contentmultimap.kvContent.delete(key);
- break;
}
+ vdxfUniValue.values = newValues;
}
+ // Replace the credentials key with a hashed key.
+ const credentialKeyResult: GetVdxfIdResult = await api.native.get_vdxf_id(
+ coin,
+ IDENTITY_CREDENTIAL.vdxfid,
+ {
+ uint256: ivk,
+ }
+ );
+
+ if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
+ throw new Error('Failed to generate credential key');
+ }
+
+ const credentialKey = credentialKeyResult.vdxfid;
+
+ contentmultimap.kvContent.setByAddress(credentialKey, valueArray);
+ contentmultimap.kvContent.deleteByAddress(searchKey);
}
diff --git a/yarn.lock b/yarn.lock
index 660cfacd..6c32b63f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9475,7 +9475,7 @@ verror@^1.10.0:
"verus-typescript-primitives@git+https://github.com/VerusCoin/verus-typescript-primitives.git":
version "1.0.0"
- resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#54dc62aecec3337e3b5672cb061a51445c3c8acd"
+ resolved "git+https://github.com/VerusCoin/verus-typescript-primitives.git#27e6c076def4416c20a568e31e4c406b10612807"
dependencies:
base64url "3.0.1"
bech32 "2.0.0"
@@ -9505,7 +9505,7 @@ verror@^1.10.0:
"verusd-rpc-ts-client@git+https://github.com/VerusCoin/verusd-rpc-ts-client.git":
version "0.1.0"
- resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#e393236112a3bf5d51e25db541f986531d381fbd"
+ resolved "git+https://github.com/VerusCoin/verusd-rpc-ts-client.git#fff4dd8bd94432cd050ec41c5535a1f0233e5178"
dependencies:
axios "1.13.5"
blake2b "https://github.com/VerusCoin/blake2b"
From 34605a8c034ed045fa15ba4f586eb0ba935f9a01 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Thu, 7 May 2026 18:53:17 -0700
Subject: [PATCH 78/80] Update axios to 1.16.0 for CVE fixes affecting versions
below 1.15.2.
(cherry picked from commit 28c8f27d4a60034bad5c42ac406ee24043c0ad5a)
---
package.json | 3 +--
yarn.lock | 37 +++++++++++++++++++++++++++++--------
2 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/package.json b/package.json
index 89d9c6c1..373d781f 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,7 @@
"agama-wallet-lib": "git+https://github.com/VerusCoin/agama-wallet-lib.git#dev",
"arch": "2.1.0",
"async": "2.6.4",
- "axios": "1.7.4",
+ "axios": "1.16.0",
"base64url": "git+https://github.com/VerusCoin/base64url.git",
"bigi": "1.4.2",
"bitgo-utxo-lib": "git+https://github.com/VerusCoin/bitgo-utxo-lib.git",
@@ -210,7 +210,6 @@
"minimatch": "5.1.0",
"json-schema": "0.4.0",
"got": "11.8.5",
- "axios": "1.7.4",
"json5": "2.2.2",
"semver": "6.3.1",
"tough-cookie": "4.1.3",
diff --git a/yarn.lock b/yarn.lock
index 6c32b63f..0916cf90 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1711,15 +1711,31 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-axios@0.25.0, axios@1.13.5, axios@1.7.4:
- version "1.7.4"
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
- integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
+axios@0.25.0:
+ version "0.25.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a"
+ integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==
dependencies:
- follow-redirects "^1.15.6"
- form-data "^4.0.0"
+ follow-redirects "^1.14.7"
+
+axios@1.13.5:
+ version "1.13.5"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.13.5.tgz#5e464688fa127e11a660a2c49441c009f6567a43"
+ integrity sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==
+ dependencies:
+ follow-redirects "^1.15.11"
+ form-data "^4.0.5"
proxy-from-env "^1.1.0"
+axios@1.16.0:
+ version "1.16.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.16.0.tgz#f8e5dd931cef2a5f8c32216d5784eda2f8750eb7"
+ integrity sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==
+ dependencies:
+ follow-redirects "^1.16.0"
+ form-data "^4.0.5"
+ proxy-from-env "^2.1.0"
+
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -4223,7 +4239,7 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
-follow-redirects@1.15.4, follow-redirects@^1.15.6:
+follow-redirects@1.15.4, follow-redirects@^1.14.7, follow-redirects@^1.15.11, follow-redirects@^1.16.0:
version "1.15.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
@@ -4255,7 +4271,7 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-form-data@4.0.4, form-data@^4.0.0, form-data@~2.3.1, form-data@~2.3.2:
+form-data@4.0.4, form-data@^4.0.0, form-data@^4.0.5, form-data@~2.3.1, form-data@~2.3.2:
version "4.0.4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
@@ -7429,6 +7445,11 @@ proxy-from-env@^1.1.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+proxy-from-env@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz#a7487568adad577cfaaa7e88c49cab3ab3081aba"
+ integrity sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==
+
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
From 9bdd44b5115a9585e4e28b33e04cee6c7a7dfcaa Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Wed, 13 May 2026 20:51:47 -0700
Subject: [PATCH 79/80] Add optional args to the getidentitycontent api, use
vdxfkeys in getting credentials, and remove unneeded null checks.
(cherry picked from commit 7e47307ec5038af5596d6b1be9d48203dc7c61e2)
---
.../api/native/credentials/getCredentials.ts | 32 +-
routes/api/native/idInformation.js | 642 ++++++++++--------
2 files changed, 359 insertions(+), 315 deletions(-)
diff --git a/routes/api/native/credentials/getCredentials.ts b/routes/api/native/credentials/getCredentials.ts
index 3c5ac92a..0a12843b 100644
--- a/routes/api/native/credentials/getCredentials.ts
+++ b/routes/api/native/credentials/getCredentials.ts
@@ -13,7 +13,7 @@ interface VdxfIdResult {
vdxfid: string;
}
-interface IdentityContent {
+interface Identity {
identity: IdentityDefinition & {privateaddress?: string};
}
@@ -33,12 +33,8 @@ export default (api: any) => {
coin: string,
address: string
): Promise => {
- // Get the z-address and contentmultimap from the address.
- const identity: IdentityContent | null = await api.native.get_identity_content(coin, address);
-
- if (!identity || !identity.identity) {
- throw new Error(`Identity not found for ${address}`);
- }
+ // Get the z-address to generate the viewing key.
+ const identity: Identity = await api.native.get_identity(coin, address);
const zaddress = identity.identity.privateaddress;
@@ -57,7 +53,7 @@ export default (api: any) => {
const ivk = keys.ivk;
// Generate the credential key using the ivk.
- const credentialKeyResult: VdxfIdResult | null = await api.native.get_vdxf_id(
+ const credentialKeyResult: VdxfIdResult = await api.native.get_vdxf_id(
coin,
IDENTITY_CREDENTIAL.vdxfid,
{
@@ -65,17 +61,24 @@ export default (api: any) => {
}
);
- if (!credentialKeyResult || !credentialKeyResult.vdxfid) {
+ if (!credentialKeyResult.vdxfid) {
throw new Error('Failed to generate credential key');
}
const credentialKey = credentialKeyResult.vdxfid;
- if (!identity.identity.contentmultimap || !identity.identity.contentmultimap[credentialKey]) {
+ const identityContent: Identity = await api.native.get_identity_content(coin, address, {
+ vdxfkey: credentialKey,
+ });
+
+ if (
+ !identityContent.identity.contentmultimap ||
+ !identityContent.identity.contentmultimap[credentialKey]
+ ) {
return [];
}
- const credentialEntries = identity.identity.contentmultimap[credentialKey];
+ const credentialEntries = identityContent.identity.contentmultimap[credentialKey];
const credentials: Credential[] = [];
for (const entry of credentialEntries) {
@@ -145,13 +148,10 @@ export default (api: any) => {
} catch {
try {
const scopeId = await api.native.get_identity(coin, mainScope);
- if (scopeId && scopeId.identity && scopeId.identity.identityaddress) {
- mainScope = scopeId.identity.identityaddress;
- }
+ mainScope = scopeId.identity.identityaddress;
+ } catch {
// If there is an error getting the identity, then the scope is not an identity.
// In that case, just leave the scope as is.
- } catch {
- // Scope is not an identity, leave as is.
}
}
diff --git a/routes/api/native/idInformation.js b/routes/api/native/idInformation.js
index fde78298..16aae39a 100644
--- a/routes/api/native/idInformation.js
+++ b/routes/api/native/idInformation.js
@@ -1,348 +1,392 @@
-const { GetOffersRequest } = require('verus-typescript-primitives');
+const {GetOffersRequest} = require('verus-typescript-primitives');
-module.exports = (api) => {
- api.native.get_identities = (coin, includeCanSpend = true, includeCanSign = false, includeWatchOnly = false, includeOffers = false) => {
+module.exports = api => {
+ api.native.get_identities = (
+ coin,
+ includeCanSpend = true,
+ includeCanSign = false,
+ includeWatchOnly = false,
+ includeOffers = false
+ ) => {
const promiseArr = [
- api.native.callDaemon(coin, 'listidentities', [includeCanSpend, includeCanSign, includeWatchOnly]),
- api.native.callDaemon(coin, "z_gettotalbalance", [])
- ]
+ api.native.callDaemon(coin, 'listidentities', [
+ includeCanSpend,
+ includeCanSign,
+ includeWatchOnly,
+ ]),
+ api.native.callDaemon(coin, 'z_gettotalbalance', []),
+ ];
- return new Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
Promise.all(promiseArr)
- .then(async (resultArr) => {
- const identities = resultArr[0]
- const balances = resultArr[1]
- const totalBalance = Number(balances.total)
-
- if (!identities) {
- resolve([])
- } else {
- let formattedIds = identities.slice()
- let txcount = null
- let reserve_balance = null
- let useCache = true
- let openOffers = {}
+ .then(async resultArr => {
+ const identities = resultArr[0];
+ const balances = resultArr[1];
+ const totalBalance = Number(balances.total);
- try {
- const walletinfo = await api.native.callDaemon(coin, "getwalletinfo", [])
- txcount = walletinfo.txcount
- reserve_balance = walletinfo.reserve_balance
- } catch (e) {
- useCache = false
- api.log('Not using address balance cache:', 'get_identities')
- api.log(e, 'get_identities')
- }
+ if (!identities) {
+ resolve([]);
+ } else {
+ let formattedIds = identities.slice();
+ let txcount = null;
+ let reserve_balance = null;
+ let useCache = true;
+ let openOffers = {};
- try {
- openOffers = await api.native.callDaemon(coin, "listopenoffers", [])
- } catch (e) {
- api.log('Failed to fetch open offers:', 'get_identities')
- api.log(e, 'get_identities')
- }
-
- for (let i = 0; i < formattedIds.length; i++) {
- const iAddr = identities[i].identity.identityaddress
- const zAddr = identities[i].identity.privateaddress
- let zBalance = null
- let iBalances = {}
-
- iBalances = await api.native.get_addr_balance(
- coin,
- iAddr,
- useCache,
- txcount,
- totalBalance,
- reserve_balance
- );
- const tBalance = iBalances[coin]
-
- if (zAddr != null) {
- try {
- zBalance = Number(
- await api.native.get_addr_balance(
- coin,
- zAddr,
- useCache,
- txcount,
- totalBalance,
- reserve_balance
- )
- );
- } catch (e) {
- api.log(e, "get_identities");
- }
+ try {
+ const walletinfo = await api.native.callDaemon(coin, 'getwalletinfo', []);
+ txcount = walletinfo.txcount;
+ reserve_balance = walletinfo.reserve_balance;
+ } catch (e) {
+ useCache = false;
+ api.log('Not using address balance cache:', 'get_identities');
+ api.log(e, 'get_identities');
}
-
- formattedIds[i].balances = {
- native: {
- public: {
- confirmed: tBalance,
- unconfirmed: null,
- immature: null
- },
- private: {
- confirmed: zBalance
- }
- },
- reserve: {...iBalances, [coin]: null}
+
+ try {
+ openOffers = await api.native.callDaemon(coin, 'listopenoffers', []);
+ } catch (e) {
+ api.log('Failed to fetch open offers:', 'get_identities');
+ api.log(e, 'get_identities');
}
- formattedIds[i].addresses = {
- public: [{
- address: iAddr,
- balances: {
- native: tBalance,
- reserve: {...iBalances, [coin]: null}
- },
- tag: "identity"
- }],
- private: zAddr == null ? [] : [{
- address: zAddr,
- balances: {
- native: zBalance,
- reserve: {}
+ for (let i = 0; i < formattedIds.length; i++) {
+ const iAddr = identities[i].identity.identityaddress;
+ const zAddr = identities[i].identity.privateaddress;
+ let zBalance = null;
+ let iBalances = {};
+
+ iBalances = await api.native.get_addr_balance(
+ coin,
+ iAddr,
+ useCache,
+ txcount,
+ totalBalance,
+ reserve_balance
+ );
+ const tBalance = iBalances[coin];
+
+ if (zAddr != null) {
+ try {
+ zBalance = Number(
+ await api.native.get_addr_balance(
+ coin,
+ zAddr,
+ useCache,
+ txcount,
+ totalBalance,
+ reserve_balance
+ )
+ );
+ } catch (e) {
+ api.log(e, 'get_identities');
+ }
+ }
+
+ formattedIds[i].balances = {
+ native: {
+ public: {
+ confirmed: tBalance,
+ unconfirmed: null,
+ immature: null,
+ },
+ private: {
+ confirmed: zBalance,
+ },
},
- tag: "sapling"
- }]
- }
+ reserve: {...iBalances, [coin]: null},
+ };
+
+ formattedIds[i].addresses = {
+ public: [
+ {
+ address: iAddr,
+ balances: {
+ native: tBalance,
+ reserve: {...iBalances, [coin]: null},
+ },
+ tag: 'identity',
+ },
+ ],
+ private:
+ zAddr == null
+ ? []
+ : [
+ {
+ address: zAddr,
+ balances: {
+ native: zBalance,
+ reserve: {},
+ },
+ tag: 'sapling',
+ },
+ ],
+ };
- const recoveryId = identities.find(
- (listIdentityObject) => {
+ const recoveryId = identities.find(listIdentityObject => {
return (
listIdentityObject.identity.identityaddress ===
formattedIds[i].identity.recoveryauthority
);
- }
- );
+ });
- formattedIds[i].canwriterecovery = recoveryId != null && recoveryId.status === 'active'
- formattedIds[i].canwriterevocation = formattedIds[i].canwriterecovery
-
- if (
- formattedIds[i].identity.parent !==
- "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV" &&
- formattedIds[i].identity.parent !==
- "iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq" &&
- formattedIds[i].identity.parent !==
- "i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk"
- ) {
- try {
- formattedIds[i].identity.name = `${
- formattedIds[i].identity.name
- }.${
- (
- await api.native.get_currency_definition(
- coin,
- formattedIds[i].identity.parent
- )
- ).name
- }`;
- } catch(e) {
- api.log('Failed to get parent for ' + formattedIds[i].identity.name, 'get_identities')
- api.log(e, 'get_identities')
+ formattedIds[i].canwriterecovery =
+ recoveryId != null && recoveryId.status === 'active';
+ formattedIds[i].canwriterevocation = formattedIds[i].canwriterecovery;
+
+ if (
+ formattedIds[i].identity.parent !== 'i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV' &&
+ formattedIds[i].identity.parent !== 'iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq' &&
+ formattedIds[i].identity.parent !== 'i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk'
+ ) {
+ try {
+ formattedIds[i].identity.name = `${formattedIds[i].identity.name}.${
+ (
+ await api.native.get_currency_definition(
+ coin,
+ formattedIds[i].identity.parent
+ )
+ ).name
+ }`;
+ } catch (e) {
+ api.log(
+ 'Failed to get parent for ' + formattedIds[i].identity.name,
+ 'get_identities'
+ );
+ api.log(e, 'get_identities');
+ }
}
- }
- if (formattedIds[i].status === 'active') {
- formattedIds[i].canrevoke = identities.some(
- (listIdentityObject) => {
+ if (formattedIds[i].status === 'active') {
+ formattedIds[i].canrevoke = identities.some(listIdentityObject => {
return (
listIdentityObject.identity.identityaddress !==
formattedIds[i].identity.identityaddress &&
listIdentityObject.identity.identityaddress ===
- formattedIds[i].identity.revocationauthority &&
+ formattedIds[i].identity.revocationauthority &&
listIdentityObject.status === 'active'
);
- }
- );
- } else formattedIds[i].canrevoke = false
-
- if (
- formattedIds[i].status === "revoked" &&
- recoveryId != null &&
- recoveryId.status === "active"
- ) {
- formattedIds[i].canrecover =
- recoveryId.identity.identityaddress !==
- formattedIds[i].identity.identityaddress;
- } else formattedIds[i].canrecover = false;
- }
+ });
+ } else formattedIds[i].canrevoke = false;
- if (includeOffers) {
- for (let i = 0; i < formattedIds.length; i++) {
- try {
- formattedIds[i].offers = (await api.native.getoffers(
- new GetOffersRequest(
- coin,
- formattedIds[i].identity.identityaddress,
- false,
- false
- ),
- formattedIds,
- openOffers
- ))
- } catch(e) {
- api.log(`Failed to get offers for ${formattedIds[i].identity.name}`, 'get_identities');
- api.log(e, 'get_identities');
+ if (
+ formattedIds[i].status === 'revoked' &&
+ recoveryId != null &&
+ recoveryId.status === 'active'
+ ) {
+ formattedIds[i].canrecover =
+ recoveryId.identity.identityaddress !== formattedIds[i].identity.identityaddress;
+ } else formattedIds[i].canrecover = false;
+ }
+
+ if (includeOffers) {
+ for (let i = 0; i < formattedIds.length; i++) {
+ try {
+ formattedIds[i].offers = await api.native.getoffers(
+ new GetOffersRequest(
+ coin,
+ formattedIds[i].identity.identityaddress,
+ false,
+ false
+ ),
+ formattedIds,
+ openOffers
+ );
+ } catch (e) {
+ api.log(
+ `Failed to get offers for ${formattedIds[i].identity.name}`,
+ 'get_identities'
+ );
+ api.log(e, 'get_identities');
+ }
}
}
- }
- resolve(formattedIds)
- }
- })
- .catch(err => {
- reject(err)
- })
+ resolve(formattedIds);
+ }
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
- api.setPost('/native/get_identities', (req, res, next) => {
- const { chainTicker, includeCanSpend, includeCanSign, includeWatchOnly, includeOffers } =
+ api.setPost('/native/get_identities', (req, res, next) => {
+ const {chainTicker, includeCanSpend, includeCanSign, includeWatchOnly, includeOffers} =
req.body;
- api.native.get_identities(chainTicker, includeCanSpend, includeCanSign, includeWatchOnly, includeOffers)
- .then((identities) => {
- const retObj = {
- msg: 'success',
- result: identities,
- };
-
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
- msg: 'error',
- result: error.message,
- };
-
- res.send(JSON.stringify(retObj));
- })
+ api.native
+ .get_identities(chainTicker, includeCanSpend, includeCanSign, includeWatchOnly, includeOffers)
+ .then(identities => {
+ const retObj = {
+ msg: 'success',
+ result: identities,
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
});
api.native.get_identity = (coin, name) => {
- return new Promise((resolve, reject) => {
- api.native.callDaemon(coin, 'getidentity', [name])
- .then(async (identity) => {
- if (
- identity.identity.parent !==
- "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV" &&
- identity.identity.parent !==
- "iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq" &&
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(coin, 'getidentity', [name])
+ .then(async identity => {
+ if (
+ identity.identity.parent !== 'i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV' &&
+ identity.identity.parent !== 'iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq' &&
// Avoid trying to get the null parent of VRSC or VRSCTEST.
- identity.identity.parent !==
- "i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk"
- ) {
- identity.identity.name = `${identity.identity.name}.${
- (
- await api.native.get_currency_definition(
- coin,
- identity.identity.parent
- )
- ).name
- }`;
- }
-
- try {
- identity.offers = await api.native.getoffers(
- new GetOffersRequest(coin, identity.identity.identityaddress, false, false)
- );
- } catch (e) {
- api.log(`Failed to get offers for ${identity.identity.name}`, "get_identity");
- api.log(e, "get_identity");
- }
-
- resolve(identity)
- })
- .catch(err => {
- reject(err)
- })
+ identity.identity.parent !== 'i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk'
+ ) {
+ identity.identity.name = `${identity.identity.name}.${
+ (await api.native.get_currency_definition(coin, identity.identity.parent)).name
+ }`;
+ }
+
+ try {
+ identity.offers = await api.native.getoffers(
+ new GetOffersRequest(coin, identity.identity.identityaddress, false, false)
+ );
+ } catch (e) {
+ api.log(`Failed to get offers for ${identity.identity.name}`, 'get_identity');
+ api.log(e, 'get_identity');
+ }
+
+ resolve(identity);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
- api.setPost('/native/get_identity', (req, res, next) => {
- const { chainTicker, name } = req.body
-
- api.native.get_identity(chainTicker, name)
- .then((identity) => {
- const retObj = {
- msg: 'success',
- result: identity,
- };
-
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
- msg: 'error',
- result: error.message,
- };
-
- res.send(JSON.stringify(retObj));
- })
+ api.setPost('/native/get_identity', (req, res) => {
+ const {chainTicker, name} = req.body;
+
+ api.native
+ .get_identity(chainTicker, name)
+ .then(identity => {
+ const retObj = {
+ msg: 'success',
+ result: identity,
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
});
- api.native.get_identity_content = (coin, name) => {
- return new Promise((resolve, reject) => {
- api.native.callDaemon(coin, 'getidentitycontent', [name])
- .then(async (identity) => {
- if (
- identity.identity.parent !==
- "i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV" &&
- identity.identity.parent !==
- "iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq" &&
+ api.native.get_identity_content = (
+ coin,
+ name,
+ {
+ heightstart = 0,
+ heightend = 0,
+ txproofs = false,
+ txproofheight = 0,
+ vdxfkey = undefined,
+ keepdeleted = false,
+ } = {}
+ ) => {
+ // The daemon only accepts valid vdxfkeys and keepdeleted is after the vdxfkey in the arguments,
+ // so we can only have keepdeleted with a valid vdxfkey.
+ if (keepdeleted && !vdxfkey) {
+ return Promise.reject(new Error('vdxfkey must be defined when keepdeleted is provided'));
+ }
+
+ const args = [name, heightstart, heightend, txproofs, txproofheight];
+ if (vdxfkey) {
+ args.push(vdxfkey);
+ }
+ if (keepdeleted) {
+ args.push(true);
+ }
+
+ return new Promise((resolve, reject) => {
+ api.native
+ .callDaemon(coin, 'getidentitycontent', args)
+ .then(async identity => {
+ if (
+ identity.identity.parent !== 'i5w5MuNik5NtLcYmNzcvaoixooEebB6MGV' &&
+ identity.identity.parent !== 'iJhCezBExJHvtyH3fGhNnt2NhU4Ztkf2yq' &&
// Avoid trying to get the null parent of VRSC or VRSCTEST.
- identity.identity.parent !==
- "i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk"
- ) {
- identity.identity.name = `${identity.identity.name}.${
- (
- await api.native.get_currency_definition(
- coin,
- identity.identity.parent
- )
- ).name
- }`;
- }
-
- try {
- identity.offers = await api.native.getoffers(
- new GetOffersRequest(coin, identity.identity.identityaddress, false, false)
- );
- } catch (e) {
- api.log(`Failed to get offers for ${identity.identity.name}`, "get_identity_content");
- api.log(e, "get_identity_content");
- }
-
- resolve(identity)
- })
- .catch(err => {
- reject(err)
- })
+ identity.identity.parent !== 'i3UXS5QPRQGNRDDqVnyWTnmFCTHDbzmsYk'
+ ) {
+ identity.identity.name = `${identity.identity.name}.${
+ (await api.native.get_currency_definition(coin, identity.identity.parent)).name
+ }`;
+ }
+
+ try {
+ identity.offers = await api.native.getoffers(
+ new GetOffersRequest(coin, identity.identity.identityaddress, false, false)
+ );
+ } catch (e) {
+ api.log(`Failed to get offers for ${identity.identity.name}`, 'get_identity_content');
+ api.log(e, 'get_identity_content');
+ }
+
+ resolve(identity);
+ })
+ .catch(err => {
+ reject(err);
+ });
});
};
- api.setPost('/native/get_identity_content', (req, res, next) => {
- const { chainTicker, name } = req.body
-
- api.native.get_identity_content(chainTicker, name)
- .then((identity) => {
- const retObj = {
- msg: 'success',
- result: identity,
- };
-
- res.send(JSON.stringify(retObj));
- })
- .catch(error => {
- const retObj = {
- msg: 'error',
- result: error.message,
- };
-
- res.send(JSON.stringify(retObj));
- })
+ api.setPost('/native/get_identity_content', (req, res) => {
+ const {
+ chainTicker,
+ name,
+ heightstart,
+ heightend,
+ txproofs,
+ txproofheight,
+ vdxfkey,
+ keepdeleted,
+ } = req.body;
+
+ api.native
+ .get_identity_content(chainTicker, name, {
+ heightstart,
+ heightend,
+ txproofs,
+ txproofheight,
+ vdxfkey,
+ keepdeleted,
+ })
+ .then(identity => {
+ const retObj = {
+ msg: 'success',
+ result: identity,
+ };
+
+ res.send(JSON.stringify(retObj));
+ })
+ .catch(error => {
+ const retObj = {
+ msg: 'error',
+ result: error.message,
+ };
+
+ res.send(JSON.stringify(retObj));
+ });
});
return api;
-};
\ No newline at end of file
+};
From 28ad2f103697c20dbd80c3b151cb74721ad7ee97 Mon Sep 17 00:00:00 2001
From: mcstoer <49734282+mcstoer@users.noreply.github.com>
Date: Tue, 19 May 2026 10:31:45 -0700
Subject: [PATCH 80/80] Fix script for switching node versions when run by
yarn.
(cherry picked from commit 182ff92d05c5df71f64bc7bd9e57ba021ce7f4af)
---
scripts/build-gui-and-plugins.sh | 4 ++--
scripts/create-build-win.sh | 4 ++--
scripts/create-build.sh | 4 ++--
scripts/dev.sh | 2 +-
scripts/prod.sh | 4 ++--
scripts/setup-node.sh | 7 ++++++-
scripts/setup.sh | 2 +-
7 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/scripts/build-gui-and-plugins.sh b/scripts/build-gui-and-plugins.sh
index 53e2bc63..cd976474 100755
--- a/scripts/build-gui-and-plugins.sh
+++ b/scripts/build-gui-and-plugins.sh
@@ -3,7 +3,7 @@
FULL_PATH=$(dirname $0)
source ${FULL_PATH}/directories.sh
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
# Build the desktop GUI
(
@@ -49,4 +49,4 @@ if [ -d "${PBAAS_VISUALIZER_DIR}" ]; then
mkdir -p ${PBAAS_VISUALIZER_PLUGIN_DIR}
fi
cp -r ${PBAAS_VISUALIZER_DIR}/build/* ${PBAAS_VISUALIZER_PLUGIN_DIR}
-fi
\ No newline at end of file
+fi
diff --git a/scripts/create-build-win.sh b/scripts/create-build-win.sh
index 91965ad6..26d26aa1 100755
--- a/scripts/create-build-win.sh
+++ b/scripts/create-build-win.sh
@@ -2,10 +2,10 @@
FULL_PATH=$(dirname $0)
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
${FULL_PATH}/build-gui-and-plugins.sh
# Build the the electron app
echo "Building Verus-Desktop for Windows..."
-yarn dist-win
\ No newline at end of file
+yarn dist-win
diff --git a/scripts/create-build.sh b/scripts/create-build.sh
index 3ad0d20a..0ad82911 100755
--- a/scripts/create-build.sh
+++ b/scripts/create-build.sh
@@ -2,11 +2,11 @@
FULL_PATH=$(dirname $0)
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
${FULL_PATH}/build-gui-and-plugins.sh
# Build the the electron app
echo ""
echo "Building Verus-Desktop..."
-yarn dist
\ No newline at end of file
+yarn dist
diff --git a/scripts/dev.sh b/scripts/dev.sh
index 962cce05..be8936ca 100755
--- a/scripts/dev.sh
+++ b/scripts/dev.sh
@@ -3,7 +3,7 @@
FULL_PATH=$(dirname $0)
source ${FULL_PATH}/directories.sh
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
# Start desktop GUI
(
diff --git a/scripts/prod.sh b/scripts/prod.sh
index d6e4470a..8b3c1c94 100755
--- a/scripts/prod.sh
+++ b/scripts/prod.sh
@@ -2,11 +2,11 @@
FULL_PATH=$(dirname $0)
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
${FULL_PATH}/build-gui-and-plugins.sh
# Start the electron app
echo ""
echo "Starting Verus-Desktop..."
-yarn start
\ No newline at end of file
+yarn start
diff --git a/scripts/setup-node.sh b/scripts/setup-node.sh
index 2618b115..78effe10 100755
--- a/scripts/setup-node.sh
+++ b/scripts/setup-node.sh
@@ -2,4 +2,9 @@
# Try to switch to node 20 using nvm if possible
. ~/.nvm/nvm.sh
-nvm use 20
+
+# When running with yarn, this inserts the switched to node version's bin before previous version
+# that yarn inserts. This allows for using the switched version of node with yarn.
+if nvm use 20 && [ -n "${NVM_BIN}" ]; then
+ export PATH="${NVM_BIN}:${PATH}"
+fi
diff --git a/scripts/setup.sh b/scripts/setup.sh
index 6a97065c..aad953e7 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -5,7 +5,7 @@ set -e
FULL_PATH=$(dirname $0)
source ${FULL_PATH}/directories.sh
-${FULL_PATH}/setup-node.sh
+source ${FULL_PATH}/setup-node.sh
# Install dependencies for the desktop GUI
(