From 0b3162011dcf5fc2dc17672e017652faa014eda4 Mon Sep 17 00:00:00 2001 From: mistakia <1823355+mistakia@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:00:07 -0400 Subject: [PATCH] chore: remove dependencies --- api/routes/auth/message.mjs | 11 +++- api/routes/auth/register.mjs | 23 ++++--- api/routes/auth/revoke.mjs | 21 ++++--- cli/index.mjs | 31 ++++------ common/binary-to-hex.mjs | 5 ++ common/decode-nano-address.mjs | 13 ++++ common/encode-nano-address.mjs | 13 ++++ common/index.mjs | 6 ++ common/is-nano-address-valid.mjs | 32 ++++++++++ common/nano-base-32.mjs | 103 +++++++++++++++++++++++++++++++ package.json | 3 +- scripts/generate-account.mjs | 36 ----------- test/auth.register.key.test.mjs | 18 +++--- test/auth.revoke.key.test.mjs | 28 +++++---- yarn.lock | 52 ---------------- 15 files changed, 250 insertions(+), 145 deletions(-) create mode 100644 common/binary-to-hex.mjs create mode 100644 common/decode-nano-address.mjs create mode 100644 common/encode-nano-address.mjs create mode 100644 common/is-nano-address-valid.mjs create mode 100644 common/nano-base-32.mjs delete mode 100644 scripts/generate-account.mjs diff --git a/api/routes/auth/message.mjs b/api/routes/auth/message.mjs index 3b779c22..db6f9bef 100644 --- a/api/routes/auth/message.mjs +++ b/api/routes/auth/message.mjs @@ -1,8 +1,11 @@ import express from 'express' -import { tools } from 'nanocurrency-web' import BigNumber from 'bignumber.js' -import { rpc, verify_nano_community_message_signature } from '#common' +import { + rpc, + verify_nano_community_message_signature, + encode_nano_address +} from '#common' import { ACCOUNT_TRACKING_MINIMUM_BALANCE, REPRESENTATIVE_TRACKING_MINIMUM_VOTING_WEIGHT @@ -118,7 +121,9 @@ router.post('/?', async (req, res) => { .select('account') .where({ public_key }) .whereNull('revoked_at') - const nano_account = tools.publicKeyToAddress(public_key) + const nano_account = encode_nano_address({ + public_key_buf: Buffer.from(public_key, 'hex') + }) const all_accounts = [ ...linked_accounts.map((row) => row.account), diff --git a/api/routes/auth/register.mjs b/api/routes/auth/register.mjs index 0f478961..1a45fceb 100644 --- a/api/routes/auth/register.mjs +++ b/api/routes/auth/register.mjs @@ -1,11 +1,16 @@ import express from 'express' -import nano from 'nanocurrency' import ed25519 from '@trashman/ed25519-blake2b' -import { verify_nano_community_link_key_signature } from '#common' +import { + verify_nano_community_link_key_signature, + is_nano_address_valid, + decode_nano_address +} from '#common' const router = express.Router() const USERNAME_RE = /^[A-Za-z][a-zA-Z0-9_]+$/ +const PUBLIC_KEY_RE = /^[0-9a-fA-F]{64}$/ +const SIGNATURE_RE = /^[0-9a-fA-F]{128}$/ router.post('/?', async (req, res) => { const { logger, db } = req.app.locals @@ -19,7 +24,7 @@ router.post('/?', async (req, res) => { const { public_key, signature, username } = req.body - if (!nano.checkKey(public_key)) { + if (typeof public_key !== 'string' || !PUBLIC_KEY_RE.test(public_key)) { return res.status(401).send({ error: 'invalid public_key param' }) } @@ -27,7 +32,7 @@ router.post('/?', async (req, res) => { return res.status(401).send({ error: 'invalid username param' }) } - if (!nano.checkSignature(signature)) { + if (typeof signature !== 'string' || !SIGNATURE_RE.test(signature)) { return res.status(401).send({ error: 'invalid signature' }) } @@ -78,19 +83,21 @@ router.post('/key/?', async (req, res) => { const { public_key, signature, account } = req.body - if (!nano.checkKey(public_key)) { + if (typeof public_key !== 'string' || !PUBLIC_KEY_RE.test(public_key)) { return res.status(401).send({ error: 'invalid public_key param' }) } - if (!nano.checkAddress(account)) { + if (!is_nano_address_valid(account)) { return res.status(401).send({ error: 'invalid account param' }) } - if (!nano.checkSignature(signature)) { + if (typeof signature !== 'string' || !SIGNATURE_RE.test(signature)) { return res.status(401).send({ error: 'invalid signature' }) } - const account_public_key = nano.derivePublicKey(account) + const { public_key: account_public_key } = decode_nano_address({ + address: account + }) const valid_signature = verify_nano_community_link_key_signature({ linked_public_key: public_key, nano_account: account, diff --git a/api/routes/auth/revoke.mjs b/api/routes/auth/revoke.mjs index df6fd0dd..34b5e1f0 100644 --- a/api/routes/auth/revoke.mjs +++ b/api/routes/auth/revoke.mjs @@ -1,8 +1,13 @@ import express from 'express' -import nano from 'nanocurrency' -import { verify_nano_community_revoke_key_signature } from '#common' +import { + verify_nano_community_revoke_key_signature, + is_nano_address_valid, + decode_nano_address +} from '#common' const router = express.Router() +const PUBLIC_KEY_RE = /^[0-9a-fA-F]{64}$/ +const SIGNATURE_RE = /^[0-9a-fA-F]{128}$/ router.post('/key/?', async (req, res) => { const { logger, db } = req.app.locals @@ -16,19 +21,21 @@ router.post('/key/?', async (req, res) => { const { account, public_key, signature } = req.body - if (!nano.checkAddress(account)) { + if (!is_nano_address_valid(account)) { return res.status(401).send({ error: 'invalid account param' }) } - if (!nano.checkKey(public_key)) { + if (typeof public_key !== 'string' || !PUBLIC_KEY_RE.test(public_key)) { return res.status(401).send({ error: 'invalid public_key param' }) } - if (!nano.checkSignature(signature)) { - return res.status(401).send({ error: 'invalid signature' }) + if (typeof signature !== 'string' || !SIGNATURE_RE.test(signature)) { + return res.status(401).send({ error: 'invalid signature param' }) } - const account_public_key = nano.derivePublicKey(account) + const { public_key: account_public_key } = decode_nano_address({ + address: account + }) const valid_signature = verify_nano_community_revoke_key_signature({ linked_public_key: public_key, nano_account: account, diff --git a/cli/index.mjs b/cli/index.mjs index 2190e144..b851adc5 100644 --- a/cli/index.mjs +++ b/cli/index.mjs @@ -5,22 +5,17 @@ import crypto from 'crypto' import { hideBin } from 'yargs/helpers' import inquirer from 'inquirer' import process from 'process' -import nano from 'nanocurrency' -import { - sign_nano_community_link_key, - sign_nano_community_revoke_key, - sign_nano_community_message, - request -} from '#common' -import config from '#config' +import sign_nano_community_link_key from '#common/sign-nano-community-link-key.mjs' +import sign_nano_community_revoke_key from '#common/sign-nano-community-revoke-key.mjs' +import sign_nano_community_message from '#common/sign-nano-community-message.mjs' +import encode_nano_address from '#common/encode-nano-address.mjs' +import request from '#common/request.mjs' import ed25519 from '@trashman/ed25519-blake2b' const is_test = process.env.NODE_ENV === 'test' -const base_url = is_test - ? `http://localhost:${config.port}` - : 'https://nano.community' +const base_url = is_test ? 'http://localhost:8080' : 'https://nano.community' const load_private_key = async () => { let private_key = process.env.NANO_PRIVATE_KEY @@ -41,11 +36,11 @@ const load_private_key = async () => { private_key = answers.private_key } - const public_key = nano.derivePublicKey(private_key) - const nano_account_address = nano.deriveAddress(public_key) + const public_key_buf = ed25519.publicKey(Buffer.from(private_key, 'hex')) + const nano_account_address = encode_nano_address({ public_key_buf }) return { private_key, - public_key, + public_key: public_key_buf.toString('hex'), nano_account_address } } @@ -153,13 +148,13 @@ const revoke_signing_key = { const update_rep_meta = { command: 'update-rep-meta', describe: 'Update representative metadata', - handler: async () => await sendMessageHandler('update-rep-meta') + handler: async () => await send_message_handler('update-rep-meta') } const update_account_meta = { command: 'update-account-meta', describe: 'Update account metadata', - handler: async () => await sendMessageHandler('update-account-meta') + handler: async () => await send_message_handler('update-account-meta') } const update_block_meta = { @@ -171,10 +166,10 @@ const update_block_meta = { type: 'string' }), handler: async ({ block_hash }) => - await sendMessageHandler('update-block-meta', block_hash) + await send_message_handler('update-block-meta', block_hash) } -const sendMessageHandler = async (type, block_hash = null) => { +const send_message_handler = async (type, block_hash = null) => { const { private_key, public_key } = await load_private_key() let message_content_prompts = [] diff --git a/common/binary-to-hex.mjs b/common/binary-to-hex.mjs new file mode 100644 index 00000000..f2e376e6 --- /dev/null +++ b/common/binary-to-hex.mjs @@ -0,0 +1,5 @@ +export default function binary_to_hex(buf) { + return Array.prototype.map + .call(new Uint8Array(buf), (x) => ('00' + x.toString(16)).slice(-2)) + .join('') +} diff --git a/common/decode-nano-address.mjs b/common/decode-nano-address.mjs new file mode 100644 index 00000000..cbe7e1ac --- /dev/null +++ b/common/decode-nano-address.mjs @@ -0,0 +1,13 @@ +import { decode_nano_base32 } from './nano-base-32.mjs' +import binary_to_hex from './binary-to-hex.mjs' + +export default function decode_nano_address({ address }) { + const cleaned_address = address.replace('nano_', '').replace('xrb_', '') + const decoded = decode_nano_base32(cleaned_address) + const public_key = binary_to_hex(decoded.subarray(0, 32)) + const checksum = binary_to_hex(decoded.subarray(32, 32 + 5)) + return { + public_key, + checksum + } +} diff --git a/common/encode-nano-address.mjs b/common/encode-nano-address.mjs new file mode 100644 index 00000000..1d6dbb0a --- /dev/null +++ b/common/encode-nano-address.mjs @@ -0,0 +1,13 @@ +import ed25519 from '@trashman/ed25519-blake2b' + +import { encode_nano_base32 } from './nano-base-32.mjs' + +export default function encode_nano_address({ + public_key_buf, + prefix = 'nano_' +}) { + const encoded_public_key = encode_nano_base32(public_key_buf) + const checksum = ed25519.hash(public_key_buf, 5).reverse() + const encoded_checksum = encode_nano_base32(checksum) + return prefix + encoded_public_key + encoded_checksum +} diff --git a/common/index.mjs b/common/index.mjs index ee2b771c..f5f714f8 100644 --- a/common/index.mjs +++ b/common/index.mjs @@ -5,6 +5,7 @@ import path, { dirname } from 'path' import config from '#config' import { BURN_ACCOUNT } from '#constants' import request from './request.mjs' +import { encode_nano_base32, decode_nano_base32 } from './nano-base-32.mjs' export * as cloudflare from './cloudflare.mjs' export { request } @@ -16,6 +17,11 @@ export { default as sign_nano_community_revoke_key } from './sign-nano-community export { default as verify_nano_community_revoke_key_signature } from './verify-nano-community-revoke-key-signature.mjs' export { default as sign_nano_community_link_key } from './sign-nano-community-link-key.mjs' export { default as verify_nano_community_link_key_signature } from './verify-nano-community-link-key-signature.mjs' +export { default as encode_nano_address } from './encode-nano-address.mjs' +export { default as decode_nano_address } from './decode-nano-address.mjs' +export { default as binary_to_hex } from './binary-to-hex.mjs' +export { default as is_nano_address_valid } from './is-nano-address-valid.mjs' +export { encode_nano_base32, decode_nano_base32 } const POST = (data) => ({ method: 'POST', diff --git a/common/is-nano-address-valid.mjs b/common/is-nano-address-valid.mjs new file mode 100644 index 00000000..d6b8f3be --- /dev/null +++ b/common/is-nano-address-valid.mjs @@ -0,0 +1,32 @@ +import ed25519 from '@trashman/ed25519-blake2b' + +import decode_nano_address from './decode-nano-address.mjs' + +const NANO_ADDRESS_RE = /^(xrb_|nano_)[13][13-9a-km-uw-z]{59}$/ + +const compare_arrays = (a, b) => { + if (a.length !== b.length) { + return false + } + + return a.every((byte, index) => byte === b[index]) +} + +export default function is_nano_address_valid(address) { + if (typeof address !== 'string') { + return false + } + + if (!NANO_ADDRESS_RE.test(address)) { + return false + } + + const { public_key, checksum } = decode_nano_address({ address }) + + const public_key_bytes = Buffer.from(public_key, 'hex') + const checksum_bytes = Buffer.from(checksum, 'hex') + const computed_checksum_bytes = ed25519.hash(public_key_bytes, 5).reverse() + const valid = compare_arrays(checksum_bytes, computed_checksum_bytes) + + return valid +} diff --git a/common/nano-base-32.mjs b/common/nano-base-32.mjs new file mode 100644 index 00000000..779cbf78 --- /dev/null +++ b/common/nano-base-32.mjs @@ -0,0 +1,103 @@ +/* +MIT License + +Copyright (c) 2018 Gray Olson + +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 above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. +*/ + +const alphabet = '13456789abcdefghijkmnopqrstuwxyz' + +/** + * Encode provided Uint8Array using the Nano-specific Base-32 implementeation. + * @param view Input buffer formatted as a Uint8Array + * @returns + * @hidden + */ +export function encode_nano_base32(view) { + const length = view.length + const leftover = (length * 8) % 5 + const offset = leftover === 0 ? 0 : 5 - leftover + + let value = 0 + let output = '' + let bits = 0 + + for (let i = 0; i < length; i++) { + value = (value << 8) | view[i] + bits += 8 + + while (bits >= 5) { + output += alphabet[(value >>> (bits + offset - 5)) & 31] + bits -= 5 + } + } + + if (bits > 0) { + output += alphabet[(value << (5 - (bits + offset))) & 31] + } + + return output +} + +function readChar(char) { + const idx = alphabet.indexOf(char) + + if (idx === -1) { + throw new Error(`Invalid character found: ${char}`) + } + + return idx +} + +/** + * Decodes a Nano-implementation Base32 encoded string into a Uint8Array + * @param input A Nano-Base32 encoded string + * @returns + * @hidden + */ +export function decode_nano_base32(input) { + const length = input.length + const leftover = (length * 5) % 8 + const offset = leftover === 0 ? 0 : 8 - leftover + + let bits = 0 + let value = 0 + + let index = 0 + let output = new Uint8Array(Math.ceil((length * 5) / 8)) + + for (let i = 0; i < length; i++) { + value = (value << 5) | readChar(input[i]) + bits += 5 + + if (bits >= 8) { + output[index++] = (value >>> (bits + offset - 8)) & 255 + bits -= 8 + } + } + if (bits > 0) { + output[index++] = (value << (bits + offset - 8)) & 255 + } + + if (leftover !== 0) { + output = output.slice(1) + } + return output +} diff --git a/package.json b/package.json index 70b56341..f7edba2e 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "#api/*": "./api/*", "#root/*": "./*", "#common": "./common/index.mjs", + "#common/*": "./common/*", "#constants": "./constants.mjs", "#config": "./config.js", "#db": "./db/index.mjs" @@ -111,8 +112,6 @@ "morgan": "^1.10.0", "morgan-debug": "^2.0.0", "mysql2": "^3.9.7", - "nanocurrency": "^2.5.0", - "nanocurrency-web": "^1.4.3", "node-cache": "^5.1.2", "node-cron": "^3.0.3", "node-fetch": "2.7.0", diff --git a/scripts/generate-account.mjs b/scripts/generate-account.mjs deleted file mode 100644 index 77aa5c8d..00000000 --- a/scripts/generate-account.mjs +++ /dev/null @@ -1,36 +0,0 @@ -import yargs from 'yargs' -import { hideBin } from 'yargs/helpers' -import nano from 'nanocurrency' -import { tools, wallet } from 'nanocurrency-web' - -const argv = yargs(hideBin(process.argv)).argv - -if (!argv.secret) { - console.log('missing --secret') - process.exit() -} - -const generateAccount = async () => { - let publicKey = argv.key - if (!argv.key) { - const w = wallet.generateLegacy() - const account = w.accounts[0] - publicKey = account.publicKey - } - - // sign new public key with account secret key - const signature = tools.sign(argv.secret, publicKey) - - const accountPublicKey = nano.derivePublicKey(argv.secret) - const accountAddress = nano.deriveAddress(accountPublicKey) - - console.log(`public key: ${publicKey}`) - console.log(`signature: ${signature}`) - console.log(`address: ${accountAddress}`) -} - -try { - generateAccount() -} catch (err) { - console.log(err) -} diff --git a/test/auth.register.key.test.mjs b/test/auth.register.key.test.mjs index 9a3ed034..69b236e3 100644 --- a/test/auth.register.key.test.mjs +++ b/test/auth.register.key.test.mjs @@ -2,11 +2,10 @@ import chai from 'chai' import chaiHTTP from 'chai-http' import ed25519 from '@trashman/ed25519-blake2b' -import nano from 'nanocurrency' import server from '#api/server.mjs' import knex from '#db' -import { sign_nano_community_link_key } from '#common' +import { sign_nano_community_link_key, encode_nano_address } from '#common' import { mochaGlobalSetup } from './global.mjs' process.env.NODE_ENV = 'test' @@ -32,9 +31,9 @@ describe('API /auth/register/key', () => { const nano_account_public_key = ed25519.publicKey( nano_account_private_key ) - const nano_account = nano.deriveAddress( - nano_account_public_key.toString('hex') - ) + const nano_account = encode_nano_address({ + public_key_buf: nano_account_public_key + }) const signature = sign_nano_community_link_key({ linked_public_key: public_key.toString('hex'), @@ -150,9 +149,12 @@ describe('API /auth/register/key', () => { ) const public_key = ed25519.publicKey(private_key) - const nano_account = nano.deriveAddress( - '0000000000000000000000000000000000000000000000000000000000000001' - ) + const nano_account = encode_nano_address({ + public_key_buf: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000001', + 'hex' + ) + }) // private key used is different from the stated nano account const nano_account_private_key = Buffer.from( diff --git a/test/auth.revoke.key.test.mjs b/test/auth.revoke.key.test.mjs index 78f12272..576faf2b 100644 --- a/test/auth.revoke.key.test.mjs +++ b/test/auth.revoke.key.test.mjs @@ -2,13 +2,13 @@ import chai from 'chai' import chaiHTTP from 'chai-http' import ed25519 from '@trashman/ed25519-blake2b' -import nano from 'nanocurrency' import server from '#api/server.mjs' import knex from '#db' import { sign_nano_community_link_key, - sign_nano_community_revoke_key + sign_nano_community_revoke_key, + encode_nano_address } from '#common' import { mochaGlobalSetup } from './global.mjs' @@ -35,9 +35,9 @@ describe('API /auth/revoke/key', () => { const nano_account_public_key = ed25519.publicKey( nano_account_private_key ) - const nano_account = nano.deriveAddress( - nano_account_public_key.toString('hex') - ) + const nano_account = encode_nano_address({ + public_key_buf: nano_account_public_key + }) // Register/Link the key const link_signature = sign_nano_community_link_key({ @@ -128,9 +128,12 @@ describe('API /auth/revoke/key', () => { }) it('should return 401 if public_key param is invalid', async () => { - const nano_account = nano.deriveAddress( - '0000000000000000000000000000000000000000000000000000000000000001' - ) + const nano_account = encode_nano_address({ + public_key_buf: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000001', + 'hex' + ) + }) const response = await chai .request(server) .post('/api/auth/revoke/key') @@ -168,9 +171,12 @@ describe('API /auth/revoke/key', () => { ) const public_key = ed25519.publicKey(private_key) - const nano_account = nano.deriveAddress( - '0000000000000000000000000000000000000000000000000000000000000000' - ) + const nano_account = encode_nano_address({ + public_key_buf: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000000', + 'hex' + ) + }) const nano_account_different_private_key = Buffer.from( '00000000000000000000000000000000000000000000000000000000000000001', diff --git a/yarn.lock b/yarn.lock index df95d426..228e0020 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5832,13 +5832,6 @@ __metadata: languageName: node linkType: hard -"bignumber.js@npm:9.0.2": - version: 9.0.2 - resolution: "bignumber.js@npm:9.0.2" - checksum: 8637b71d0a99104b20413c47578953970006fec6b4df796b9dcfd9835ea9c402ea0e727eba9a5ca9f9a393c1d88b6168c5bbe0887598b708d4f8b4870ad62e1f - languageName: node - linkType: hard - "bignumber.js@npm:^9.0.0": version: 9.0.1 resolution: "bignumber.js@npm:9.0.1" @@ -5950,13 +5943,6 @@ __metadata: languageName: node linkType: hard -"blakejs@npm:1.2.1": - version: 1.2.1 - resolution: "blakejs@npm:1.2.1" - checksum: d699ba116cfa21d0b01d12014a03e484dd76d483133e6dc9eb415aa70a119f08beb3bcefb8c71840106a00b542cba77383f8be60cd1f0d4589cb8afb922eefbe - languageName: node - linkType: hard - "blakejs@npm:^1.1.0": version: 1.1.0 resolution: "blakejs@npm:1.1.0" @@ -6291,13 +6277,6 @@ __metadata: languageName: node linkType: hard -"byte-base64@npm:1.1.0": - version: 1.1.0 - resolution: "byte-base64@npm:1.1.0" - checksum: 95851fc758882ba6b28422d70c685f86257eb635be10eb37528765f39fc1c8766972f9bb39e0684539fafc7d9625145d26e5ab310a52c9eb9df3506952586e0c - languageName: node - linkType: hard - "byte-size@npm:^8.1.0": version: 8.1.1 resolution: "byte-size@npm:8.1.1" @@ -7384,13 +7363,6 @@ __metadata: languageName: node linkType: hard -"crypto-js@npm:3.1.9-1": - version: 3.1.9-1 - resolution: "crypto-js@npm:3.1.9-1" - checksum: 2dc7a7024fd02a88ef3f673e949c7a98d0d61da8b57c95a8207e22d8dd2135b29124bc28dfb2770d8a5f3cf8a46d81e68b3a4bde982a71bae479a9ce666f4cd8 - languageName: node - linkType: hard - "crypto-random-string@npm:^2.0.0": version: 2.0.0 resolution: "crypto-random-string@npm:2.0.0" @@ -14652,28 +14624,6 @@ __metadata: languageName: node linkType: hard -"nanocurrency-web@npm:^1.4.3": - version: 1.4.3 - resolution: "nanocurrency-web@npm:1.4.3" - dependencies: - bignumber.js: 9.0.2 - blakejs: 1.2.1 - byte-base64: 1.1.0 - crypto-js: 3.1.9-1 - checksum: 62cb82d651259a137e03e27d6a4be3910dd21f7b41fc36b2e7957dd9320534c7cbafed392d4285ff37a944296b7d5cabb261fe13c7fdcdee72285d3cc9019330 - languageName: node - linkType: hard - -"nanocurrency@npm:^2.5.0": - version: 2.5.0 - resolution: "nanocurrency@npm:2.5.0" - dependencies: - bignumber.js: ^9.0.0 - blakejs: ^1.1.0 - checksum: 5db534bc725438dcaec2c858ff93c6c730d959a1feaa8cbc0cfe8dabb562477723655d982692cfeaca7ce7e3f7635afb10aac55344319635b2061979e133ba8d - languageName: node - linkType: hard - "nanoid@npm:^3.0.2": version: 3.1.22 resolution: "nanoid@npm:3.1.22" @@ -17257,8 +17207,6 @@ __metadata: morgan: ^1.10.0 morgan-debug: ^2.0.0 mysql2: ^3.9.7 - nanocurrency: ^2.5.0 - nanocurrency-web: ^1.4.3 nib: ^1.2.0 nock: ^13.5.4 node-cache: ^5.1.2