From 2195b43c3e3f6ff2d2d1a33e11e1b46353d8889a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C4=B1z=C4=B1r=20Sefa=20=C4=B0rken?= Date: Mon, 9 Sep 2024 20:23:44 +0300 Subject: [PATCH 1/3] feat: add custom network support --- README.md | 9 ++- genesis/mainnet/byron_genesis.json | 6 ++ genesis/mainnet/genesis.json | 12 ++++ genesis/preprod/byron_genesis.json | 6 ++ genesis/preprod/genesis.json | 12 ++++ genesis/preview/byron_genesis.json | 6 ++ genesis/preview/genesis.json | 12 ++++ genesis/sanchonet/byron_genesis.json | 6 ++ genesis/sanchonet/genesis.json | 12 ++++ genesis/testnet/byron_genesis.json | 6 ++ genesis/testnet/genesis.json | 12 ++++ src/config.ts | 21 +++++- src/constants/genesis.ts | 99 +------------------------- src/routes/epochs/latest/index.ts | 4 +- src/routes/epochs/number/index.ts | 4 +- src/routes/epochs/number/next.ts | 4 +- src/routes/epochs/number/previous.ts | 4 +- src/routes/ledger/index.ts | 4 +- src/routes/network/eras.ts | 7 +- src/types/common.ts | 4 +- src/utils/validation.ts | 24 +++++-- test/unit/tests/routes/ledger.unit.ts | 13 ++-- test/unit/tests/routes/network.unit.ts | 7 +- 23 files changed, 155 insertions(+), 139 deletions(-) create mode 100644 genesis/mainnet/byron_genesis.json create mode 100644 genesis/mainnet/genesis.json create mode 100644 genesis/preprod/byron_genesis.json create mode 100644 genesis/preprod/genesis.json create mode 100644 genesis/preview/byron_genesis.json create mode 100644 genesis/preview/genesis.json create mode 100644 genesis/sanchonet/byron_genesis.json create mode 100644 genesis/sanchonet/genesis.json create mode 100644 genesis/testnet/byron_genesis.json create mode 100644 genesis/testnet/genesis.json diff --git a/README.md b/README.md index 980f477f..1160aa7c 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,10 @@ If you are using an authenticated db connection that requires a password, you'd database: 'dbname' # Optionally define a password password: 'randomstringthatissolongandpowerfulthatnoonecanguess' - # Cardano network - mainnet, testnet, preview, preprod + # Cardano network - mainnet, testnet, preview, preprod, custom network: 'mainnet' + # path to the folder containing genesis data. If left blank, ./genesis/${network} will be used + genesisDataFolder: './genesis/mainnet' # Path to token registry directory (see next section for more details) tokenRegistryUrl: 'https://tokens.cardano.org' # Experimental Mithril proxy @@ -71,7 +73,7 @@ If you are using an authenticated db connection that requires a password, you'd
:bulb: All config variables can be also set via environment variables which take precedence over values from a config file. -These values are `BLOCKFROST_CONFIG_SERVER_PORT`, `BLOCKFROST_CONFIG_SERVER_DEBUG`, `BLOCKFROST_CONFIG_SERVER_PROMETHEUS_METRICS`, `BLOCKFROST_CONFIG_DBSYNC_HOST`, `BLOCKFROST_CONFIG_DBSYNC_USER`, `BLOCKFROST_CONFIG_DBSYNC_DATABASE`, `BLOCKFROST_CONFIG_DBSYNC_MAX_CONN`, `BLOCKFROST_CONFIG_NETWORK`, `BLOCKFROST_CONFIG_TOKEN_REGISTRY_URL`. +These values are `BLOCKFROST_CONFIG_SERVER_PORT`, `BLOCKFROST_CONFIG_SERVER_DEBUG`, `BLOCKFROST_CONFIG_SERVER_PROMETHEUS_METRICS`, `BLOCKFROST_CONFIG_DBSYNC_HOST`, `BLOCKFROST_CONFIG_DBSYNC_USER`, `BLOCKFROST_CONFIG_DBSYNC_DATABASE`, `BLOCKFROST_CONFIG_DBSYNC_MAX_CONN`, `BLOCKFROST_CONFIG_NETWORK`, `BLOCKFROST_CONFIG_GENESIS_DATA_FOLDER`, `BLOCKFROST_CONFIG_TOKEN_REGISTRY_URL`.
@@ -229,6 +231,9 @@ A minimal usage example is: Check the [nixos-module.nix file](./nixos-module.nix) to check options and the default values. +## Custom Networks +blockfrost-ryo can be configured to run with any genesis parameters. Setting network to `custom`, and using `genesisDataFolder` value in the yaml configuration or environment variable `BLOCKFROST_CONFIG_GENESIS_DATA_FOLDER` you can specify your genesis details. + ## Developing This is an open-source project and anyone is welcome to contribute, please see [CONTRIBUTING](CONTRIBUTING.md) for more information. diff --git a/genesis/mainnet/byron_genesis.json b/genesis/mainnet/byron_genesis.json new file mode 100644 index 00000000..e4f42ba0 --- /dev/null +++ b/genesis/mainnet/byron_genesis.json @@ -0,0 +1,6 @@ +{ + "epoch_length": 21600, + "slot_length": 20, + "safe_zone": 4320, + "end_epoch": 208 +} diff --git a/genesis/mainnet/genesis.json b/genesis/mainnet/genesis.json new file mode 100644 index 00000000..28e490bb --- /dev/null +++ b/genesis/mainnet/genesis.json @@ -0,0 +1,12 @@ +{ + "active_slots_coefficient": 0.05, + "update_quorum": 5, + "max_lovelace_supply": "45000000000000000", + "network_magic": 764824073, + "epoch_length": 432000, + "system_start": 1506203091, + "slots_per_kes_period": 129600, + "slot_length": 1, + "max_kes_evolutions": 62, + "security_param": 2160 +} diff --git a/genesis/preprod/byron_genesis.json b/genesis/preprod/byron_genesis.json new file mode 100644 index 00000000..14dd5b24 --- /dev/null +++ b/genesis/preprod/byron_genesis.json @@ -0,0 +1,6 @@ +{ + "epoch_length": 21600, + "slot_length": 20, + "safe_zone": 4320, + "end_epoch": 4 +} diff --git a/genesis/preprod/genesis.json b/genesis/preprod/genesis.json new file mode 100644 index 00000000..caf3833a --- /dev/null +++ b/genesis/preprod/genesis.json @@ -0,0 +1,12 @@ +{ + "active_slots_coefficient": 0.05, + "update_quorum": 5, + "max_lovelace_supply": "45000000000000000", + "network_magic": 1, + "epoch_length": 432000, + "system_start": 1654041600, + "slots_per_kes_period": 129600, + "slot_length": 1, + "max_kes_evolutions": 62, + "security_param": 2160 +} diff --git a/genesis/preview/byron_genesis.json b/genesis/preview/byron_genesis.json new file mode 100644 index 00000000..1de72dd5 --- /dev/null +++ b/genesis/preview/byron_genesis.json @@ -0,0 +1,6 @@ +{ + "epoch_length": 4320, + "slot_length": 20, + "safe_zone": 864, + "end_epoch": 0 +} diff --git a/genesis/preview/genesis.json b/genesis/preview/genesis.json new file mode 100644 index 00000000..cf0f69f2 --- /dev/null +++ b/genesis/preview/genesis.json @@ -0,0 +1,12 @@ +{ + "active_slots_coefficient": 0.05, + "update_quorum": 5, + "max_lovelace_supply": "45000000000000000", + "network_magic": 2, + "epoch_length": 86400, + "system_start": 1666656000, + "slots_per_kes_period": 129600, + "slot_length": 1, + "max_kes_evolutions": 62, + "security_param": 432 +} diff --git a/genesis/sanchonet/byron_genesis.json b/genesis/sanchonet/byron_genesis.json new file mode 100644 index 00000000..1de72dd5 --- /dev/null +++ b/genesis/sanchonet/byron_genesis.json @@ -0,0 +1,6 @@ +{ + "epoch_length": 4320, + "slot_length": 20, + "safe_zone": 864, + "end_epoch": 0 +} diff --git a/genesis/sanchonet/genesis.json b/genesis/sanchonet/genesis.json new file mode 100644 index 00000000..a0b44428 --- /dev/null +++ b/genesis/sanchonet/genesis.json @@ -0,0 +1,12 @@ +{ + "active_slots_coefficient": 0.05, + "update_quorum": 3, + "max_lovelace_supply": "45000000000000000", + "network_magic": 4, + "epoch_length": 86400, + "system_start": 1686789000, + "slots_per_kes_period": 129600, + "slot_length": 1, + "max_kes_evolutions": 62, + "security_param": 432 +} diff --git a/genesis/testnet/byron_genesis.json b/genesis/testnet/byron_genesis.json new file mode 100644 index 00000000..de37607a --- /dev/null +++ b/genesis/testnet/byron_genesis.json @@ -0,0 +1,6 @@ +{ + "epoch_length": 21600, + "slot_length": 20, + "safe_zone": 4320, + "end_epoch": 74 +} diff --git a/genesis/testnet/genesis.json b/genesis/testnet/genesis.json new file mode 100644 index 00000000..f548be84 --- /dev/null +++ b/genesis/testnet/genesis.json @@ -0,0 +1,12 @@ +{ + "active_slots_coefficient": 0.05, + "update_quorum": 5, + "max_lovelace_supply": "45000000000000000", + "network_magic": 1097911063, + "epoch_length": 432000, + "system_start": 1563999616, + "slots_per_kes_period": 129600, + "slot_length": 1, + "max_kes_evolutions": 62, + "security_param": 2160 +} diff --git a/src/config.ts b/src/config.ts index 17519ec1..c63ce34c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,7 @@ import config from 'config'; -import { CARDANO_NETWORKS, Network } from './types/common.js'; +import { ByronEraParameters, CARDANO_NETWORKS, Network } from './types/common.js'; +import { readFileSync } from 'node:fs'; +import * as ResponseTypes from './types/responses/ledger.js'; const MITHRIL_ENDPOINT_ALLOWLIST_DEFAULT = [ '', // root endpoint, same as "/", but some env are trimming trailing slash so request to /mithril/ could be received as /mithril @@ -60,7 +62,7 @@ export const loadConfig = () => { const network = process.env.BLOCKFROST_CONFIG_NETWORK ?? config.get('network'); if (!network || !CARDANO_NETWORKS.includes(network)) { - throw new Error('Invalid network configuration.'); + throw new Error(`Invalid network configuration: ${network}`); } // token registry const tokenRegistryUrl = @@ -98,6 +100,19 @@ export const loadConfig = () => { throw new Error('Invalid Mithril Aggregator configuration'); } + // genesis + const genesisDataFolder = + process.env.BLOCKFROST_CONFIG_GENESIS_DATA_FOLDER ?? config.has('genesisDataFolder') + ? config.get('genesisDataFolder') + : `./genesis/${network}`; + + const genesis = JSON.parse( + readFileSync(genesisDataFolder + '/genesis.json', 'utf8'), + ) as ResponseTypes.Ledger; + const byronGenesis = JSON.parse( + readFileSync(genesisDataFolder + '/byron_genesis.json', 'utf8'), + ) as ByronEraParameters; + return { server: { listenAddress, @@ -116,6 +131,8 @@ export const loadConfig = () => { ssl, }, network: network as Network, + genesis, + byronGenesis, tokenRegistryUrl, mithril: { enabled: mithrilEnabled, diff --git a/src/constants/genesis.ts b/src/constants/genesis.ts index 39b53db8..0c79ed05 100644 --- a/src/constants/genesis.ts +++ b/src/constants/genesis.ts @@ -1,101 +1,4 @@ -import * as ResponseTypes from '../types/responses/ledger.js'; -import { Network, ByronEraParameters, ProtocolInfo } from '../types/common.js'; - -export const GENESIS: Record = { - mainnet: { - active_slots_coefficient: 0.05, - update_quorum: 5, - max_lovelace_supply: '45000000000000000', - network_magic: 764_824_073, - epoch_length: 432_000, - system_start: 1_506_203_091, - slots_per_kes_period: 129_600, - slot_length: 1, - max_kes_evolutions: 62, - security_param: 2160, - }, - testnet: { - active_slots_coefficient: 0.05, - update_quorum: 5, - max_lovelace_supply: '45000000000000000', - network_magic: 1_097_911_063, - epoch_length: 432_000, - system_start: 1_563_999_616, - slots_per_kes_period: 129_600, - slot_length: 1, - max_kes_evolutions: 62, - security_param: 2160, - }, - preview: { - active_slots_coefficient: 0.05, - update_quorum: 5, - max_lovelace_supply: '45000000000000000', - network_magic: 2, - epoch_length: 86_400, - system_start: 1_666_656_000, - slots_per_kes_period: 129_600, - slot_length: 1, - max_kes_evolutions: 62, - security_param: 432, - }, - preprod: { - active_slots_coefficient: 0.05, - update_quorum: 5, - max_lovelace_supply: '45000000000000000', - network_magic: 1, - epoch_length: 432_000, - system_start: 1_654_041_600, - slots_per_kes_period: 129_600, - slot_length: 1, - max_kes_evolutions: 62, - security_param: 2160, - }, - sanchonet: { - active_slots_coefficient: 0.05, - update_quorum: 3, - max_lovelace_supply: '45000000000000000', - network_magic: 4, - epoch_length: 86_400, - system_start: 1_686_789_000, - slots_per_kes_period: 129_600, - slot_length: 1, - max_kes_evolutions: 62, - security_param: 432, - }, -}; - -export const BYRON_GENESIS: Record = { - mainnet: { - epoch_length: 21_600, - slot_length: 20, - safe_zone: 4320, - end_epoch: 208, - }, - testnet: { - epoch_length: 21_600, - slot_length: 20, - safe_zone: 4320, - end_epoch: 74, - }, - preprod: { - epoch_length: 21_600, - slot_length: 20, - safe_zone: 4320, - end_epoch: 4, - }, - preview: { - epoch_length: 4320, - slot_length: 20, - safe_zone: 864, - end_epoch: 0, - }, - sanchonet: { - epoch_length: 4320, - slot_length: 20, - safe_zone: 864, - end_epoch: 0, - }, -}; +import { ProtocolInfo } from '../types/common.js'; export const PROTOCOL_VERSIONS: Record = { 0: { diff --git a/src/routes/epochs/latest/index.ts b/src/routes/epochs/latest/index.ts index 4beb927a..855fa83f 100644 --- a/src/routes/epochs/latest/index.ts +++ b/src/routes/epochs/latest/index.ts @@ -2,7 +2,6 @@ import { getSchemaForEndpoint } from '@blockfrost/openapi'; import { FastifyInstance } from 'fastify'; import { getConfig } from '../../../config.js'; -import { GENESIS } from '../../../constants/genesis.js'; import { SQLQuery } from '../../../sql/index.js'; import * as QueryTypes from '../../../types/queries/epochs.js'; import * as ResponseTypes from '../../../types/responses/epochs.js'; @@ -18,8 +17,7 @@ async function route(fastify: FastifyInstance) { const clientDbSync = await getDbSync(fastify); try { - const network = getConfig().network; - const epochLength = GENESIS[network].epoch_length; + const epochLength = getConfig().genesis.epoch_length; const { rows }: { rows: ResponseTypes.Epoch[] } = await clientDbSync.query(SQLQuery.get('epochs_latest'), [epochLength]); diff --git a/src/routes/epochs/number/index.ts b/src/routes/epochs/number/index.ts index 9a77e321..7a302d54 100644 --- a/src/routes/epochs/number/index.ts +++ b/src/routes/epochs/number/index.ts @@ -2,7 +2,6 @@ import { getSchemaForEndpoint } from '@blockfrost/openapi'; import { FastifyInstance, FastifyRequest } from 'fastify'; import { getConfig } from '../../../config.js'; -import { GENESIS } from '../../../constants/genesis.js'; import { SQLQuery } from '../../../sql/index.js'; import * as QueryTypes from '../../../types/queries/epochs.js'; import * as ResponseTypes from '../../../types/responses/epochs.js'; @@ -24,8 +23,7 @@ async function route(fastify: FastifyInstance) { return handle400Custom(reply, 'Missing, out of range or malformed epoch_number.'); } - const network = getConfig().network; - const epochLength = GENESIS[network].epoch_length; + const epochLength = getConfig().genesis.epoch_length; const { rows }: { rows: ResponseTypes.Epoch[] } = await clientDbSync.query(SQLQuery.get('epochs_number'), [ request.params.number, diff --git a/src/routes/epochs/number/next.ts b/src/routes/epochs/number/next.ts index 27b4832a..a444caad 100644 --- a/src/routes/epochs/number/next.ts +++ b/src/routes/epochs/number/next.ts @@ -3,7 +3,6 @@ import { isUnpaged } from '../../../utils/routes.js'; import { toJSONStream } from '../../../utils/string-utils.js'; import { FastifyInstance, FastifyRequest } from 'fastify'; import { getConfig } from '../../../config.js'; -import { GENESIS } from '../../../constants/genesis.js'; import { SQLQuery } from '../../../sql/index.js'; import * as QueryTypes from '../../../types/queries/epochs.js'; import * as ResponseTypes from '../../../types/responses/epochs.js'; @@ -35,8 +34,7 @@ async function route(fastify: FastifyInstance) { return handle404(reply); } - const network = getConfig().network; - const epochLength = GENESIS[network].epoch_length; + const epochLength = getConfig().genesis.epoch_length; const unpaged = isUnpaged(request); const { rows }: { rows: ResponseTypes.Epoch[] } = unpaged diff --git a/src/routes/epochs/number/previous.ts b/src/routes/epochs/number/previous.ts index c199b950..b61740ad 100644 --- a/src/routes/epochs/number/previous.ts +++ b/src/routes/epochs/number/previous.ts @@ -4,7 +4,6 @@ import { toJSONStream } from '../../../utils/string-utils.js'; import { FastifyInstance, FastifyRequest } from 'fastify'; import { getConfig } from '../../../config.js'; -import { GENESIS } from '../../../constants/genesis.js'; import { SQLQuery } from '../../../sql/index.js'; import * as QueryTypes from '../../../types/queries/epochs.js'; import * as ResponseTypes from '../../../types/responses/epochs.js'; @@ -36,8 +35,7 @@ async function route(fastify: FastifyInstance) { return handle404(reply); } - const network = getConfig().network; - const epochLength = GENESIS[network].epoch_length; + const epochLength = getConfig().genesis.epoch_length; const unpaged = isUnpaged(request); const { rows }: { rows: ResponseTypes.Epoch[] } = unpaged diff --git a/src/routes/ledger/index.ts b/src/routes/ledger/index.ts index 564d0ba4..f1ef25a1 100644 --- a/src/routes/ledger/index.ts +++ b/src/routes/ledger/index.ts @@ -2,7 +2,6 @@ import { FastifyInstance } from 'fastify'; import { getSchemaForEndpoint } from '@blockfrost/openapi'; import * as ResponseTypes from '../../types/responses/ledger.js'; import { getConfig } from '../../config.js'; -import { GENESIS } from '../../constants/genesis.js'; async function route(fastify: FastifyInstance) { fastify.route({ @@ -10,8 +9,7 @@ async function route(fastify: FastifyInstance) { method: 'GET', schema: getSchemaForEndpoint('/genesis'), handler: async (_request, reply) => { - const network = getConfig().network; - const genesisData: ResponseTypes.Ledger | undefined = GENESIS[network]; + const genesisData: ResponseTypes.Ledger = getConfig().genesis; if (genesisData) { return reply.send(genesisData); diff --git a/src/routes/network/eras.ts b/src/routes/network/eras.ts index 4d348bad..af755e4b 100644 --- a/src/routes/network/eras.ts +++ b/src/routes/network/eras.ts @@ -2,7 +2,7 @@ import { getSchemaForEndpoint } from '@blockfrost/openapi'; import { FastifyInstance, FastifyRequest } from 'fastify'; import { getConfig } from '../../config.js'; -import { BYRON_GENESIS, GENESIS, PROTOCOL_VERSIONS } from '../../constants/genesis.js'; +import { PROTOCOL_VERSIONS } from '../../constants/genesis.js'; import { SQLQuery } from '../../sql/index.js'; import { ByronEraParameters } from '../../types/common.js'; import { Block } from '../../types/queries/blocks.js'; @@ -18,9 +18,8 @@ async function route(fastify: FastifyInstance) { method: 'GET', schema: getSchemaForEndpoint('/network/eras'), handler: async (request: FastifyRequest, reply) => { - const network = getConfig().network; - const genesisData: LedgerResponseTypes.Ledger | undefined = GENESIS[network]; - const byronGenesisData: ByronEraParameters | undefined = BYRON_GENESIS[network]; + const genesisData: LedgerResponseTypes.Ledger = getConfig().genesis; + const byronGenesisData: ByronEraParameters = getConfig().byronGenesis; if (!genesisData && !byronGenesisData) { return handle500(reply, 'No genesis or Byron genesis data', request); diff --git a/src/types/common.ts b/src/types/common.ts index c02d8c3f..81ae15f4 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -5,9 +5,9 @@ import { components } from '@blockfrost/openapi'; export type Order = 'asc' | 'desc'; export type AddressType = 'byron' | 'shelley'; -export const CARDANO_NETWORKS = ['mainnet', 'testnet', 'preview', 'preprod', 'sanchonet']; +export const CARDANO_NETWORKS = ['mainnet', 'testnet', 'preview', 'preprod', 'sanchonet', 'custom']; -export type Network = 'mainnet' | 'testnet' | 'preview' | 'preprod' | 'sanchonet'; +export type Network = 'mainnet' | 'testnet' | 'preview' | 'preprod' | 'sanchonet' | 'custom'; export interface ResultFound { result: number; diff --git a/src/utils/validation.ts b/src/utils/validation.ts index bb9f6cf1..e47c074c 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -2,20 +2,36 @@ import { validation } from '@blockfrost/blockfrost-utils'; import { getConfig } from '../config.js'; import { bech32 } from 'bech32'; +type BlockfrostNetwork = 'mainnet' | 'testnet' | 'preview' | 'preprod' | 'sanchonet'; + +// This is a workaround till blockfrost-utils is updated with custom network support +const getNetwork = () => { + const network = getConfig().network; + + if (network === 'custom') { + return 'testnet' as BlockfrostNetwork; + } else { + return network as BlockfrostNetwork; + } +}; + export const isNumber = validation.isNumber; export const validateHex = validation.validateHex; export const detectAndValidateAddressType = (address: string) => - validation.detectAndValidateAddressType(address, getConfig().network); + validation.detectAndValidateAddressType( + address, + getConfig().network as BlockfrostNetwork, + ) as BlockfrostNetwork; export const getAddressTypeAndPaymentCred = (address: string) => - validation.getAddressTypeAndPaymentCred(address, getConfig().network); + validation.getAddressTypeAndPaymentCred(address, getNetwork()); export const validateStakeAddress = (address: string) => - validation.validateStakeAddress(address, getConfig().network); + validation.validateStakeAddress(address, getNetwork()); export const convertStakeAddress = (address: string) => - validation.convertStakeAddress(address, getConfig().network); + validation.convertStakeAddress(address, getNetwork()); export const validateAndConvertPool = validation.validateAndConvertPool; export const paymentCredToBech32Address = validation.paymentCredToBech32Address; diff --git a/test/unit/tests/routes/ledger.unit.ts b/test/unit/tests/routes/ledger.unit.ts index 6dcab747..94e2f021 100644 --- a/test/unit/tests/routes/ledger.unit.ts +++ b/test/unit/tests/routes/ledger.unit.ts @@ -5,10 +5,8 @@ import { describe, expect, test, vi } from 'vitest'; describe('ledger service', () => { test('network - Mainnet', async () => { - vi.spyOn(config, 'getConfig').mockReturnValue({ - ...config.mainConfig, - network: 'mainnet', - }); + vi.stubEnv('BLOCKFROST_CONFIG_NETWORK', 'mainnet'); + vi.spyOn(config, 'getConfig').mockReturnValue(config.loadConfig()); const fastify = buildFastify(); @@ -33,10 +31,9 @@ describe('ledger service', () => { }); test('network - Testnet', async () => { - vi.spyOn(config, 'getConfig').mockReturnValue({ - ...config.mainConfig, - network: 'testnet', - }); + vi.stubEnv('BLOCKFROST_CONFIG_NETWORK', 'testnet'); + vi.spyOn(config, 'getConfig').mockReturnValue(config.loadConfig()); + const fastify = buildFastify(); await fastify.ready(); diff --git a/test/unit/tests/routes/network.unit.ts b/test/unit/tests/routes/network.unit.ts index 6e56526d..f1f4aed8 100644 --- a/test/unit/tests/routes/network.unit.ts +++ b/test/unit/tests/routes/network.unit.ts @@ -9,10 +9,9 @@ import { describe, expect, test, vi } from 'vitest'; describe('network service', () => { fixtures.map(fixture => { test(fixture.name, async () => { - vi.spyOn(config, 'getConfig').mockReturnValue({ - ...config.mainConfig, - network: fixture.network, - }); + vi.stubEnv('BLOCKFROST_CONFIG_NETWORK', fixture.network); + vi.spyOn(config, 'getConfig').mockReturnValue(config.loadConfig()); + const fastify = buildFastify({ maxParamLength: 32_768 }); const queryMock = sinon.stub(); From 3c28f826922c54dd76be8c6b0ddfa7ad637745e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C4=B1z=C4=B1r=20Sefa=20=C4=B0rken?= Date: Fri, 27 Sep 2024 14:45:11 +0300 Subject: [PATCH 2/3] feat: add ability to disable token registery lookups --- src/config.ts | 7 +++++++ src/utils/token-registry.ts | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/config.ts b/src/config.ts index c63ce34c..1f564b63 100644 --- a/src/config.ts +++ b/src/config.ts @@ -65,6 +65,12 @@ export const loadConfig = () => { throw new Error(`Invalid network configuration: ${network}`); } // token registry + const tokenRegistryEnabled = Boolean( + process.env.BLOCKFROST_CONFIG_TOKEN_REGISTRY_ENABLED ?? config.has('tokenRegistryEnabled') + ? config.get('tokenRegistryEnabled') + : true, + ); + const tokenRegistryUrl = process.env.BLOCKFROST_CONFIG_TOKEN_REGISTRY_URL ?? config.get('tokenRegistryUrl'); @@ -134,6 +140,7 @@ export const loadConfig = () => { genesis, byronGenesis, tokenRegistryUrl, + tokenRegistryEnabled, mithril: { enabled: mithrilEnabled, aggregator: mithrilAggregator as string, diff --git a/src/utils/token-registry.ts b/src/utils/token-registry.ts index a26c044a..3b98e3ee 100644 --- a/src/utils/token-registry.ts +++ b/src/utils/token-registry.ts @@ -4,6 +4,7 @@ import { Asset } from '../types/responses/assets.js'; import { getConfig } from '../config.js'; const CONFIG_TOKEN_REGISTRY_URL = getConfig().tokenRegistryUrl; +const CONFIG_TOKEN_REGISTRY_ENABLED = getConfig().tokenRegistryEnabled; interface TokenRegistryValue { signatures: { @@ -43,8 +44,11 @@ export const transformTokenRegistryAsset = ( export const fetchAssetMetadata = async ( asset: string, tokenRegistryUrl = CONFIG_TOKEN_REGISTRY_URL, + tokenRegistryEnabled: boolean = CONFIG_TOKEN_REGISTRY_ENABLED, ) => { try { + if (!tokenRegistryEnabled) return null; + const url = `${tokenRegistryUrl}/metadata/${asset}`; const response = await axios.get(url, { From ad84cedb6b223058f2ecc72a27f80545cbfd7b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C4=B1z=C4=B1r=20Sefa=20=C4=B0rken?= Date: Mon, 11 Nov 2024 13:54:05 +0300 Subject: [PATCH 3/3] chore: update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c45fbe2..f2b10113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Added custom network support +- Added option to disable token registery lookups + ## [2.3.1] - 2024-11-04 ### Fixed