mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
Add support for regtest
This commit is contained in:
parent
0e6f9a7621
commit
a23850de14
43 changed files with 277 additions and 36 deletions
|
|
@ -483,7 +483,7 @@ class BitcoinRoutes {
|
||||||
|
|
||||||
private async getBlocks(req: Request, res: Response) {
|
private async getBlocks(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
||||||
const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10);
|
const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10);
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
res.json(await blocks.$getBlocks(height, 15));
|
res.json(await blocks.$getBlocks(height, 15));
|
||||||
|
|
@ -497,7 +497,7 @@ class BitcoinRoutes {
|
||||||
|
|
||||||
private async getBlocksByBulk(req: Request, res: Response) {
|
private async getBlocksByBulk(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) === false) { // Liquid - Not implemented
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) === false) { // Liquid - Not implemented
|
||||||
handleError(req, res, 404, `This API is only available for Bitcoin networks`);
|
handleError(req, res, 404, `This API is only available for Bitcoin networks`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +539,7 @@ class BitcoinRoutes {
|
||||||
|
|
||||||
private async getChainTips(req: Request, res: Response) {
|
private async getChainTips(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
const tips = await chainTips.getChainTips();
|
const tips = await chainTips.getChainTips();
|
||||||
if (tips.length > 0) {
|
if (tips.length > 0) {
|
||||||
|
|
@ -559,7 +559,7 @@ class BitcoinRoutes {
|
||||||
|
|
||||||
private async getStaleTips(req: Request, res: Response) {
|
private async getStaleTips(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
const tips = await chainTips.getStaleTips();
|
const tips = await chainTips.getStaleTips();
|
||||||
if (tips.length > 0) {
|
if (tips.length > 0) {
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ class Blocks {
|
||||||
extras.totalInputAmt = null;
|
extras.totalInputAmt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
let pool: PoolTag;
|
let pool: PoolTag;
|
||||||
if (coinbaseTx !== undefined) {
|
if (coinbaseTx !== undefined) {
|
||||||
pool = await this.$findBlockMiner(coinbaseTx);
|
pool = await this.$findBlockMiner(coinbaseTx);
|
||||||
|
|
@ -1282,7 +1282,7 @@ class Blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not Bitcoin network, return the block as it from the bitcoin backend
|
// Not Bitcoin network, return the block as it from the bitcoin backend
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) === false) {
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) === false) {
|
||||||
return await bitcoinCoreApi.$getBlock(hash);
|
return await bitcoinCoreApi.$getBlock(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1525,7 +1525,7 @@ class Blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $getBlockAuditSummary(hash: string): Promise<BlockAudit | null> {
|
public async $getBlockAuditSummary(hash: string): Promise<BlockAudit | null> {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
||||||
return BlocksAuditsRepository.$getBlockAudit(hash);
|
return BlocksAuditsRepository.$getBlockAudit(hash);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -1533,7 +1533,7 @@ class Blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $getBlockTxAuditSummary(hash: string, txid: string): Promise<TransactionAudit | null> {
|
public async $getBlockTxAuditSummary(hash: string, txid: string): Promise<TransactionAudit | null> {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
||||||
return BlocksAuditsRepository.$getBlockTxAudit(hash, txid);
|
return BlocksAuditsRepository.$getBlockTxAudit(hash, txid);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -376,6 +376,7 @@ export class Common {
|
||||||
'testnet4': 42_000,
|
'testnet4': 42_000,
|
||||||
'testnet': 2_900_000,
|
'testnet': 2_900_000,
|
||||||
'signet': 211_000,
|
'signet': 211_000,
|
||||||
|
'regtest': 0,
|
||||||
'': 863_500,
|
'': 863_500,
|
||||||
};
|
};
|
||||||
static isNonStandardVersion(tx: TransactionExtended, height?: number): boolean {
|
static isNonStandardVersion(tx: TransactionExtended, height?: number): boolean {
|
||||||
|
|
@ -399,6 +400,7 @@ export class Common {
|
||||||
'testnet4': 42_000,
|
'testnet4': 42_000,
|
||||||
'testnet': 2_900_000,
|
'testnet': 2_900_000,
|
||||||
'signet': 211_000,
|
'signet': 211_000,
|
||||||
|
'regtest': 0,
|
||||||
'': 863_500,
|
'': 863_500,
|
||||||
};
|
};
|
||||||
static isNonStandardAnchor(vin: IEsploraApi.Vin, height?: number): boolean {
|
static isNonStandardAnchor(vin: IEsploraApi.Vin, height?: number): boolean {
|
||||||
|
|
@ -419,6 +421,7 @@ export class Common {
|
||||||
'testnet4': 90_500,
|
'testnet4': 90_500,
|
||||||
'testnet': 4_550_000,
|
'testnet': 4_550_000,
|
||||||
'signet': 260_000,
|
'signet': 260_000,
|
||||||
|
'regtest': 0,
|
||||||
'': 905_000,
|
'': 905_000,
|
||||||
};
|
};
|
||||||
static isStandardEphemeralDust(tx: TransactionExtended, height?: number): boolean {
|
static isStandardEphemeralDust(tx: TransactionExtended, height?: number): boolean {
|
||||||
|
|
@ -439,6 +442,7 @@ export class Common {
|
||||||
'testnet4': 108_000,
|
'testnet4': 108_000,
|
||||||
'testnet': 4_750_000,
|
'testnet': 4_750_000,
|
||||||
'signet': 276_500,
|
'signet': 276_500,
|
||||||
|
'regtest': 0,
|
||||||
'': 921_000,
|
'': 921_000,
|
||||||
};
|
};
|
||||||
static MAX_DATACARRIER_BYTES = 83;
|
static MAX_DATACARRIER_BYTES = 83;
|
||||||
|
|
@ -461,6 +465,7 @@ export class Common {
|
||||||
'testnet4': 108_000,
|
'testnet4': 108_000,
|
||||||
'testnet': 4_750_000,
|
'testnet': 4_750_000,
|
||||||
'signet': 276_500,
|
'signet': 276_500,
|
||||||
|
'regtest': 0,
|
||||||
'': 921_000,
|
'': 921_000,
|
||||||
};
|
};
|
||||||
static isNonStandardLegacySigops(tx: TransactionExtended, height?: number): boolean {
|
static isNonStandardLegacySigops(tx: TransactionExtended, height?: number): boolean {
|
||||||
|
|
@ -854,7 +859,7 @@ export class Common {
|
||||||
|
|
||||||
static indexingEnabled(): boolean {
|
static indexingEnabled(): boolean {
|
||||||
return (
|
return (
|
||||||
['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) &&
|
['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) &&
|
||||||
config.DATABASE.ENABLED === true &&
|
config.DATABASE.ENABLED === true &&
|
||||||
config.MEMPOOL.INDEXING_BLOCKS_AMOUNT !== 0
|
config.MEMPOOL.INDEXING_BLOCKS_AMOUNT !== 0
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ class DatabaseMigration {
|
||||||
private async $createMissingTablesAndIndexes(databaseSchemaVersion: number) {
|
private async $createMissingTablesAndIndexes(databaseSchemaVersion: number) {
|
||||||
await this.$setStatisticsAddedIndexedFlag(databaseSchemaVersion);
|
await this.$setStatisticsAddedIndexedFlag(databaseSchemaVersion);
|
||||||
|
|
||||||
const isBitcoin = ['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK);
|
const isBitcoin = ['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK);
|
||||||
|
|
||||||
await this.$executeQuery(this.getCreateElementsTableQuery(), await this.$checkIfTableExists('elements_pegs'));
|
await this.$executeQuery(this.getCreateElementsTableQuery(), await this.$checkIfTableExists('elements_pegs'));
|
||||||
await this.$executeQuery(this.getCreateStatisticsQuery(), await this.$checkIfTableExists('statistics'));
|
await this.$executeQuery(this.getCreateStatisticsQuery(), await this.$checkIfTableExists('statistics'));
|
||||||
|
|
@ -1300,7 +1300,7 @@ class DatabaseMigration {
|
||||||
*/
|
*/
|
||||||
private getMigrationQueriesFromVersion(version: number): string[] {
|
private getMigrationQueriesFromVersion(version: number): string[] {
|
||||||
const queries: string[] = [];
|
const queries: string[] = [];
|
||||||
const isBitcoin = ['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK);
|
const isBitcoin = ['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK);
|
||||||
|
|
||||||
if (version < 1) {
|
if (version < 1) {
|
||||||
if (config.MEMPOOL.NETWORK !== 'liquid' && config.MEMPOOL.NETWORK !== 'liquidtestnet') {
|
if (config.MEMPOOL.NETWORK !== 'liquid' && config.MEMPOOL.NETWORK !== 'liquidtestnet') {
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ class LiquidRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
|
||||||
if (['testnet', 'signet', 'liquidtestnet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['testnet', 'signet', 'liquidtestnet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Prices are not available on testnets.');
|
handleError(req, res, 400, 'Prices are not available on testnets.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class MempoolBlocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updatePools$(): Promise<void> {
|
public async updatePools$(): Promise<void> {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) === false) {
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) === false) {
|
||||||
this.pools = {};
|
this.pools = {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
|
||||||
if (['testnet', 'signet', 'liquidtestnet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['testnet', 'signet', 'liquidtestnet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Prices are not available on testnets.');
|
handleError(req, res, 400, 'Prices are not available on testnets.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -394,7 +394,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Acceleration data is not available.');
|
handleError(req, res, 400, 'Acceleration data is not available.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +409,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Acceleration data is not available.');
|
handleError(req, res, 400, 'Acceleration data is not available.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +425,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Acceleration data is not available.');
|
handleError(req, res, 400, 'Acceleration data is not available.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -440,7 +440,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Acceleration data is not available.');
|
handleError(req, res, 400, 'Acceleration data is not available.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -455,7 +455,7 @@ class MiningRoutes {
|
||||||
res.header('Pragma', 'public');
|
res.header('Pragma', 'public');
|
||||||
res.header('Cache-control', 'public');
|
res.header('Cache-control', 'public');
|
||||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
handleError(req, res, 400, 'Acceleration data is not available.');
|
handleError(req, res, 400, 'Acceleration data is not available.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ class PoolsParser {
|
||||||
let firstKnownBlockPool = 130635; // https://mempool.space/block/0000000000000a067d94ff753eec72830f1205ad3a4c216a08a80c832e551a52
|
let firstKnownBlockPool = 130635; // https://mempool.space/block/0000000000000a067d94ff753eec72830f1205ad3a4c216a08a80c832e551a52
|
||||||
if (config.MEMPOOL.NETWORK === 'testnet') {
|
if (config.MEMPOOL.NETWORK === 'testnet') {
|
||||||
firstKnownBlockPool = 21106; // https://mempool.space/testnet/block/0000000070b701a5b6a1b965f6a38e0472e70b2bb31b973e4638dec400877581
|
firstKnownBlockPool = 21106; // https://mempool.space/testnet/block/0000000070b701a5b6a1b965f6a38e0472e70b2bb31b973e4638dec400877581
|
||||||
} else if (['signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
} else if (['signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
firstKnownBlockPool = 0;
|
firstKnownBlockPool = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ interface IConfig {
|
||||||
MEMPOOL: {
|
MEMPOOL: {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
OFFICIAL: boolean;
|
OFFICIAL: boolean;
|
||||||
NETWORK: 'mainnet' | 'testnet' | 'signet' | 'liquid' | 'liquidtestnet';
|
NETWORK: 'mainnet' | 'testnet' | 'signet' | 'liquid' | 'liquidtestnet' | 'regtest';
|
||||||
BACKEND: 'esplora' | 'electrum' | 'none';
|
BACKEND: 'esplora' | 'electrum' | 'none';
|
||||||
HTTP_PORT: number;
|
HTTP_PORT: number;
|
||||||
UNIX_SOCKET_PATH: string;
|
UNIX_SOCKET_PATH: string;
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ class Server {
|
||||||
this.setUpWebsocketHandling();
|
this.setUpWebsocketHandling();
|
||||||
|
|
||||||
await poolsUpdater.updatePoolsJson(); // Needs to be done before loading the disk cache because we sometimes wipe it
|
await poolsUpdater.updatePoolsJson(); // Needs to be done before loading the disk cache because we sometimes wipe it
|
||||||
if (config.DATABASE.ENABLED === true && config.MEMPOOL.ENABLED && ['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) && !poolsUpdater.currentSha) {
|
if (config.DATABASE.ENABLED === true && config.MEMPOOL.ENABLED && ['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) && !poolsUpdater.currentSha) {
|
||||||
logger.err(`Failed to retreive pools-v2.json sha, cannot run block indexing. Please make sure you've set valid urls in your mempool-config.json::MEMPOOL::POOLS_JSON_URL and mempool-config.json::MEMPOOL::POOLS_JSON_TREE_UR, aborting now`);
|
logger.err(`Failed to retreive pools-v2.json sha, cannot run block indexing. Please make sure you've set valid urls in your mempool-config.json::MEMPOOL::POOLS_JSON_URL and mempool-config.json::MEMPOOL::POOLS_JSON_TREE_UR, aborting now`);
|
||||||
return process.exit(1);
|
return process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ class Indexer {
|
||||||
|
|
||||||
switch (task) {
|
switch (task) {
|
||||||
case 'blocksPrices': {
|
case 'blocksPrices': {
|
||||||
if (!['testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) && config.FIAT_PRICE.ENABLED) {
|
if (!['testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) && config.FIAT_PRICE.ENABLED) {
|
||||||
let lastestPriceId;
|
let lastestPriceId;
|
||||||
try {
|
try {
|
||||||
lastestPriceId = await PricesRepository.$getLatestPriceId();
|
lastestPriceId = await PricesRepository.$getLatestPriceId();
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class PoolsRepository {
|
||||||
if (parse) {
|
if (parse) {
|
||||||
rows[0].regexes = JSON.parse(rows[0].regexes);
|
rows[0].regexes = JSON.parse(rows[0].regexes);
|
||||||
}
|
}
|
||||||
if (['testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
rows[0].addresses = []; // pools-v2.json only contains mainnet addresses
|
rows[0].addresses = []; // pools-v2.json only contains mainnet addresses
|
||||||
} else if (parse) {
|
} else if (parse) {
|
||||||
rows[0].addresses = JSON.parse(rows[0].addresses);
|
rows[0].addresses = JSON.parse(rows[0].addresses);
|
||||||
|
|
@ -134,7 +134,7 @@ class PoolsRepository {
|
||||||
if (parse) {
|
if (parse) {
|
||||||
rows[0].regexes = JSON.parse(rows[0].regexes);
|
rows[0].regexes = JSON.parse(rows[0].regexes);
|
||||||
}
|
}
|
||||||
if (['testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
rows[0].addresses = []; // pools.json only contains mainnet addresses
|
rows[0].addresses = []; // pools.json only contains mainnet addresses
|
||||||
} else if (parse) {
|
} else if (parse) {
|
||||||
rows[0].addresses = JSON.parse(rows[0].addresses);
|
rows[0].addresses = JSON.parse(rows[0].addresses);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class PoolsUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updatePoolsJson(): Promise<void> {
|
public async updatePoolsJson(): Promise<void> {
|
||||||
if (['mainnet', 'testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK) === false ||
|
if (['mainnet', 'testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK) === false ||
|
||||||
config.MEMPOOL.ENABLED === false
|
config.MEMPOOL.ENABLED === false
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ class PriceUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $run(): Promise<void> {
|
public async $run(): Promise<void> {
|
||||||
if (['testnet', 'signet', 'testnet4'].includes(config.MEMPOOL.NETWORK)) {
|
if (['testnet', 'signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
// Coins have no value on testnet/signet, so we want to always show 0
|
// Coins have no value on testnet/signet, so we want to always show 0
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ __MAINNET_ENABLED__=${MAINNET_ENABLED:=true}
|
||||||
__TESTNET_ENABLED__=${TESTNET_ENABLED:=false}
|
__TESTNET_ENABLED__=${TESTNET_ENABLED:=false}
|
||||||
__TESTNET4_ENABLED__=${TESTNET_ENABLED:=false}
|
__TESTNET4_ENABLED__=${TESTNET_ENABLED:=false}
|
||||||
__SIGNET_ENABLED__=${SIGNET_ENABLED:=false}
|
__SIGNET_ENABLED__=${SIGNET_ENABLED:=false}
|
||||||
|
__REGTEST_ENABLED__=${REGTEST_ENABLED:=false}
|
||||||
__LIQUID_ENABLED__=${LIQUID_ENABLED:=false}
|
__LIQUID_ENABLED__=${LIQUID_ENABLED:=false}
|
||||||
__LIQUID_TESTNET_ENABLED__=${LIQUID_TESTNET_ENABLED:=false}
|
__LIQUID_TESTNET_ENABLED__=${LIQUID_TESTNET_ENABLED:=false}
|
||||||
__ITEMS_PER_PAGE__=${ITEMS_PER_PAGE:=10}
|
__ITEMS_PER_PAGE__=${ITEMS_PER_PAGE:=10}
|
||||||
|
|
@ -46,6 +47,7 @@ __AUDIT__=${AUDIT:=false}
|
||||||
__MAINNET_BLOCK_AUDIT_START_HEIGHT__=${MAINNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
__MAINNET_BLOCK_AUDIT_START_HEIGHT__=${MAINNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
||||||
__TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
__TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
||||||
__SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
__SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0}
|
||||||
|
__REGTEST_BLOCK_AUDIT_START_HEIGHT__=${REGTEST_BLOCK_AUDIT_START_HEIGHT:=0}
|
||||||
__ACCELERATOR__=${ACCELERATOR:=false}
|
__ACCELERATOR__=${ACCELERATOR:=false}
|
||||||
__ACCELERATOR_BUTTON__=${ACCELERATOR_BUTTON:=true}
|
__ACCELERATOR_BUTTON__=${ACCELERATOR_BUTTON:=true}
|
||||||
__SERVICES_API__=${SERVICES_API:=https://mempool.space/api/v1/services}
|
__SERVICES_API__=${SERVICES_API:=https://mempool.space/api/v1/services}
|
||||||
|
|
@ -59,6 +61,7 @@ export __MAINNET_ENABLED__
|
||||||
export __TESTNET_ENABLED__
|
export __TESTNET_ENABLED__
|
||||||
export __TESTNET4_ENABLED__
|
export __TESTNET4_ENABLED__
|
||||||
export __SIGNET_ENABLED__
|
export __SIGNET_ENABLED__
|
||||||
|
export __REGTEST_ENABLED__
|
||||||
export __LIQUID_ENABLED__
|
export __LIQUID_ENABLED__
|
||||||
export __LIQUID_TESTNET_ENABLED__
|
export __LIQUID_TESTNET_ENABLED__
|
||||||
export __ITEMS_PER_PAGE__
|
export __ITEMS_PER_PAGE__
|
||||||
|
|
@ -78,6 +81,7 @@ export __AUDIT__
|
||||||
export __MAINNET_BLOCK_AUDIT_START_HEIGHT__
|
export __MAINNET_BLOCK_AUDIT_START_HEIGHT__
|
||||||
export __TESTNET_BLOCK_AUDIT_START_HEIGHT__
|
export __TESTNET_BLOCK_AUDIT_START_HEIGHT__
|
||||||
export __SIGNET_BLOCK_AUDIT_START_HEIGHT__
|
export __SIGNET_BLOCK_AUDIT_START_HEIGHT__
|
||||||
|
export __REGTEST_BLOCK_AUDIT_START_HEIGHT__
|
||||||
export __ACCELERATOR__
|
export __ACCELERATOR__
|
||||||
export __ACCELERATOR_BUTTON__
|
export __ACCELERATOR_BUTTON__
|
||||||
export __SERVICES_API__
|
export __SERVICES_API__
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
"TESTNET_ENABLED": false,
|
"TESTNET_ENABLED": false,
|
||||||
"TESTNET4_ENABLED": false,
|
"TESTNET4_ENABLED": false,
|
||||||
"SIGNET_ENABLED": false,
|
"SIGNET_ENABLED": false,
|
||||||
|
"REGTEST_ENABLED": false,
|
||||||
"LIQUID_ENABLED": false,
|
"LIQUID_ENABLED": false,
|
||||||
"LIQUID_TESTNET_ENABLED": false,
|
"LIQUID_TESTNET_ENABLED": false,
|
||||||
"MAINNET_ENABLED": true,
|
"MAINNET_ENABLED": true,
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
"MAINNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
"MAINNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
||||||
"TESTNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
"TESTNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
||||||
"SIGNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
"SIGNET_BLOCK_AUDIT_START_HEIGHT": 0,
|
||||||
|
"REGTEST_BLOCK_AUDIT_START_HEIGHT": 0,
|
||||||
"LIGHTNING": false,
|
"LIGHTNING": false,
|
||||||
"HISTORICAL_PRICE": true,
|
"HISTORICAL_PRICE": true,
|
||||||
"ADDITIONAL_CURRENCIES": false,
|
"ADDITIONAL_CURRENCIES": false,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ PROXY_CONFIG = [
|
||||||
'/api/**', '!/api/v1/ws',
|
'/api/**', '!/api/v1/ws',
|
||||||
'!/liquid', '!/liquid/**', '!/liquid/',
|
'!/liquid', '!/liquid/**', '!/liquid/',
|
||||||
'!/liquidtestnet', '!/liquidtestnet/**', '!/liquidtestnet/',
|
'!/liquidtestnet', '!/liquidtestnet/**', '!/liquidtestnet/',
|
||||||
'/testnet/api/**', '/signet/api/**', '/testnet4/api/**'
|
'/testnet/api/**', '/signet/api/**', '/testnet4/api/**', '/regtest/api/**'
|
||||||
],
|
],
|
||||||
target: "https://mempool.space",
|
target: "https://mempool.space",
|
||||||
ws: true,
|
ws: true,
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,27 @@ PROXY_CONFIG.push(...[
|
||||||
"^/testnet": ""
|
"^/testnet": ""
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/v1/**'],
|
||||||
|
target: `http://127.0.0.1:8999`,
|
||||||
|
secure: false,
|
||||||
|
ws: true,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest": ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/**'],
|
||||||
|
target: `http://127.0.0.1:3000`,
|
||||||
|
secure: false,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest/api": ""
|
||||||
|
},
|
||||||
|
},
|
||||||
/* Optional proxy to route dev to official acceleration services
|
/* Optional proxy to route dev to official acceleration services
|
||||||
{
|
{
|
||||||
context: ['/api/v1/services/accelerator/**'],
|
context: ['/api/v1/services/accelerator/**'],
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,27 @@ PROXY_CONFIG.push(...[
|
||||||
"^/testnet": ""
|
"^/testnet": ""
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/v1/**'],
|
||||||
|
target: `http://localhost:8999`,
|
||||||
|
secure: false,
|
||||||
|
ws: true,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest": ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/**'],
|
||||||
|
target: `http://localhost:8999`,
|
||||||
|
secure: false,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest/api/": "/api/v1/"
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
context: ['/api/v1/services/**'],
|
context: ['/api/v1/services/**'],
|
||||||
target: `http://localhost:9000`,
|
target: `http://localhost:9000`,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,27 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
|
||||||
}
|
}
|
||||||
|
|
||||||
PROXY_CONFIG.push(...[
|
PROXY_CONFIG.push(...[
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/v1/**'],
|
||||||
|
target: `http://localhost:8999`,
|
||||||
|
secure: false,
|
||||||
|
ws: true,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest": ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
context: ['/regtest/api/**'],
|
||||||
|
target: `http://localhost:8999`,
|
||||||
|
secure: false,
|
||||||
|
changeOrigin: true,
|
||||||
|
proxyTimeout: 30000,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/regtest/api/": "/api/v1/"
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
context: ['/api/v1/services/**'],
|
context: ['/api/v1/services/**'],
|
||||||
target: `http://localhost:9000`,
|
target: `http://localhost:9000`,
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,49 @@ let routes: Routes = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'regtest',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'mining/blocks',
|
||||||
|
redirectTo: 'blocks',
|
||||||
|
pathMatch: 'full'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
pathMatch: 'full',
|
||||||
|
loadChildren: () => import('@app/bitcoin-graphs.module').then(m => m.BitcoinGraphsModule),
|
||||||
|
data: { preload: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
loadChildren: () => import('@app/master-page.module').then(m => m.MasterPageModule),
|
||||||
|
data: { preload: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'widget/wallet',
|
||||||
|
children: [],
|
||||||
|
component: AddressGroupComponent,
|
||||||
|
data: {
|
||||||
|
networkSpecific: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'status',
|
||||||
|
data: { networks: ['bitcoin', 'liquid'] },
|
||||||
|
component: StatusViewComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
loadChildren: () => import('@app/bitcoin-graphs.module').then(m => m.BitcoinGraphsModule),
|
||||||
|
data: { preload: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '**',
|
||||||
|
redirectTo: '/regtest'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
|
|
@ -177,6 +220,10 @@ let routes: Routes = [
|
||||||
path: 'signet',
|
path: 'signet',
|
||||||
loadChildren: () => import('@app/previews.module').then(m => m.PreviewsModule)
|
loadChildren: () => import('@app/previews.module').then(m => m.PreviewsModule)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'regtest',
|
||||||
|
loadChildren: () => import('@app/previews.module').then(m => m.PreviewsModule)
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
signet: ['var(--signet)', 'var(--signet-alt)'],
|
signet: ['var(--signet)', 'var(--signet-alt)'],
|
||||||
|
regtest: ['var(--regtest)', 'var(--regtest-alt)'],
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export class ClockComponent implements OnInit {
|
||||||
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
signet: ['var(--signet)', 'var(--signet-alt)'],
|
signet: ['var(--signet)', 'var(--signet-alt)'],
|
||||||
|
regtest: ['var(--regtest)', 'var(--regtest-alt)'],
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div ngbDropdown (window:resize)="onResize()" class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED">
|
<div ngbDropdown (window:resize)="onResize()" class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.REGTEST_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED">
|
||||||
<button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split d-flex justify-content-center align-items-center" aria-haspopup="true">
|
<button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split d-flex justify-content-center align-items-center" aria-haspopup="true">
|
||||||
<app-svg-images class="d-flex justify-content-center align-items-center current-network-svg" [name]="network.val === '' ? 'liquid' : network.val" width="20" height="20" viewBox="0 0 125 125"></app-svg-images>
|
<app-svg-images class="d-flex justify-content-center align-items-center current-network-svg" [name]="network.val === '' ? 'liquid' : network.val" width="20" height="20" viewBox="0 0 125 125"></app-svg-images>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['signet'] || '/signet')" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
|
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['signet'] || '/signet')" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
|
||||||
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet'] || '/testnet')" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
|
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet'] || '/testnet')" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
|
||||||
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet4'] || '/testnet4')" ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
|
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet4'] || '/testnet4')" ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
|
||||||
|
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['regtest'] || '/regtest')" ngbDropdownItem *ngIf="env.REGTEST_ENABLED" class="regtest"><app-svg-images name="regtest" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Regtest</a>
|
||||||
<h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
|
<h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
|
||||||
<a ngbDropdownItem class="liquid mr-1" [class.active]="network.val === 'liquid'" [routerLink]="networkPaths['liquid'] || '/'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
|
<a ngbDropdownItem class="liquid mr-1" [class.active]="network.val === 'liquid'" [routerLink]="networkPaths['liquid'] || '/'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
|
||||||
<a ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquidtestnet'" [routerLink]="networkPaths['liquidtestnet'] || '/testnet'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
|
<a ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquidtestnet'" [routerLink]="networkPaths['liquidtestnet'] || '/testnet'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,10 @@ nav {
|
||||||
background-color: var(--signet);
|
background-color: var(--signet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.regtest.active {
|
||||||
|
background-color: var(--regtest);
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-divider {
|
.dropdown-divider {
|
||||||
border-top: 1px solid #121420;
|
border-top: 1px solid #121420;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@
|
||||||
<a ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" [routerLink]="networkPaths['signet'] || '/signet'"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
|
<a ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" [routerLink]="networkPaths['signet'] || '/signet'"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
|
||||||
<a ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" [routerLink]="networkPaths['testnet'] || '/testnet'"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
|
<a ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" [routerLink]="networkPaths['testnet'] || '/testnet'"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
|
||||||
<a ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet4" [class.active]="network.val === 'testnet4'" [routerLink]="networkPaths['testnet4'] || '/testnet4'"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
|
<a ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet4" [class.active]="network.val === 'testnet4'" [routerLink]="networkPaths['testnet4'] || '/testnet4'"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
|
||||||
|
<a ngbDropdownItem *ngIf="env.REGTEST_ENABLED" class="regtest" [class.active]="network.val === 'regtest'" [routerLink]="networkPaths['regtest'] || '/regtest'"><app-svg-images name="regtest" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Regtest</a>
|
||||||
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquid'] || '')" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
|
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquid'] || '')" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
|
||||||
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquidtestnet'] || '/testnet')" ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquid'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
|
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquidtestnet'] || '/testnet')" ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquid'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,10 @@ nav {
|
||||||
background-color: var(--signet);
|
background-color: var(--signet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.regtest.active {
|
||||||
|
background-color: var(--regtest);
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-divider {
|
.dropdown-divider {
|
||||||
border-top: 1px solid #121420;
|
border-top: 1px solid #121420;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ export class MasterPageComponent implements OnInit, OnDestroy {
|
||||||
this.env.TESTNET_ENABLED,
|
this.env.TESTNET_ENABLED,
|
||||||
this.env.TESTNET4_ENABLED,
|
this.env.TESTNET4_ENABLED,
|
||||||
this.env.SIGNET_ENABLED,
|
this.env.SIGNET_ENABLED,
|
||||||
|
this.env.REGTEST_ENABLED,
|
||||||
this.env.LIQUID_ENABLED,
|
this.env.LIQUID_ENABLED,
|
||||||
this.env.LIQUID_TESTNET_ENABLED,
|
this.env.LIQUID_TESTNET_ENABLED,
|
||||||
this.env.MAINNET_ENABLED,
|
this.env.MAINNET_ENABLED,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export class StaleList implements OnInit {
|
||||||
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
|
||||||
signet: ['var(--signet)', 'var(--signet-alt)'],
|
signet: ['var(--signet)', 'var(--signet-alt)'],
|
||||||
|
regtest: ['var(--regtest)', 'var(--regtest-alt)'],
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,9 @@
|
||||||
<ng-container *ngSwitchCase="'testnet4'">
|
<ng-container *ngSwitchCase="'testnet4'">
|
||||||
<ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#5fd15c', width, height, viewBox}"></ng-component>
|
<ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#5fd15c', width, height, viewBox}"></ng-component>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="'regtest'">
|
||||||
|
<ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#a5a5a5', width, height, viewBox}"></ng-component>
|
||||||
|
</ng-container>
|
||||||
<ng-container *ngSwitchCase="'liquid'">
|
<ng-container *ngSwitchCase="'liquid'">
|
||||||
<ng-component *ngTemplateOutlet="liquidLogo; context: {$implicit: '', width, height, viewBox}"></ng-component>
|
<ng-component *ngTemplateOutlet="liquidLogo; context: {$implicit: '', width, height, viewBox}"></ng-component>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
||||||
testnet4: ['#4edf77', '#10a0af', '#4edf7700'],
|
testnet4: ['#4edf77', '#10a0af', '#4edf7700'],
|
||||||
// signet: ['#6f1d5d', '#471850'],
|
// signet: ['#6f1d5d', '#471850'],
|
||||||
signet: ['#d24fc8', '#a84fd2', '#d24fc800'],
|
signet: ['#d24fc8', '#a84fd2', '#d24fc800'],
|
||||||
|
regtest: ['var(--regtest)', 'var(--regtest-alt)', '#7d7d7d00'],
|
||||||
};
|
};
|
||||||
|
|
||||||
gradient: string[] = ['var(--primary)', 'var(--primary)'];
|
gradient: string[] = ['var(--primary)', 'var(--primary)'];
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export class EnterpriseService {
|
||||||
this.stateService.env.LIQUID_ENABLED = false;
|
this.stateService.env.LIQUID_ENABLED = false;
|
||||||
this.stateService.env.LIQUID_TESTNET_ENABLED = false;
|
this.stateService.env.LIQUID_TESTNET_ENABLED = false;
|
||||||
this.stateService.env.SIGNET_ENABLED = false;
|
this.stateService.env.SIGNET_ENABLED = false;
|
||||||
|
this.stateService.env.REGTEST_ENABLED = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchSubdomainInfo(): void {
|
fetchSubdomainInfo(): void {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export class NavigationService {
|
||||||
{ name: 'testnet', path: this.stateService.env.ROOT_NETWORK === 'testnet' ? '/' : '/testnet' },
|
{ name: 'testnet', path: this.stateService.env.ROOT_NETWORK === 'testnet' ? '/' : '/testnet' },
|
||||||
{ name: 'testnet4', path: this.stateService.env.ROOT_NETWORK === 'testnet4' ? '/' : '/testnet4' },
|
{ name: 'testnet4', path: this.stateService.env.ROOT_NETWORK === 'testnet4' ? '/' : '/testnet4' },
|
||||||
{ name: 'signet', path: this.stateService.env.ROOT_NETWORK === 'signet' ? '/' : '/signet' },
|
{ name: 'signet', path: this.stateService.env.ROOT_NETWORK === 'signet' ? '/' : '/signet' },
|
||||||
|
{ name: 'regtest', path: this.stateService.env.ROOT_NETWORK === 'regtest' ? '/' : '/regtest' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
liquid: {
|
liquid: {
|
||||||
|
|
@ -89,7 +90,7 @@ export class NavigationService {
|
||||||
}
|
}
|
||||||
if (route.url?.length) {
|
if (route.url?.length) {
|
||||||
path = [path, ...route.url.map(segment => segment.path).filter(path => {
|
path = [path, ...route.url.map(segment => segment.path).filter(path => {
|
||||||
return path.length && !['testnet', 'testnet4', 'signet'].includes(path);
|
return path.length && !['testnet', 'testnet4', 'signet', 'regtest'].includes(path);
|
||||||
})].join('/');
|
})].join('/');
|
||||||
}
|
}
|
||||||
route = route.firstChild;
|
route = route.firstChild;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ export interface Env {
|
||||||
TESTNET_ENABLED: boolean;
|
TESTNET_ENABLED: boolean;
|
||||||
TESTNET4_ENABLED: boolean;
|
TESTNET4_ENABLED: boolean;
|
||||||
SIGNET_ENABLED: boolean;
|
SIGNET_ENABLED: boolean;
|
||||||
|
REGTEST_ENABLED: boolean;
|
||||||
LIQUID_ENABLED: boolean;
|
LIQUID_ENABLED: boolean;
|
||||||
LIQUID_TESTNET_ENABLED: boolean;
|
LIQUID_TESTNET_ENABLED: boolean;
|
||||||
ITEMS_PER_PAGE: number;
|
ITEMS_PER_PAGE: number;
|
||||||
|
|
@ -73,10 +74,12 @@ export interface Env {
|
||||||
TESTNET_BLOCK_AUDIT_START_HEIGHT: number;
|
TESTNET_BLOCK_AUDIT_START_HEIGHT: number;
|
||||||
TESTNET4_BLOCK_AUDIT_START_HEIGHT: number;
|
TESTNET4_BLOCK_AUDIT_START_HEIGHT: number;
|
||||||
SIGNET_BLOCK_AUDIT_START_HEIGHT: number;
|
SIGNET_BLOCK_AUDIT_START_HEIGHT: number;
|
||||||
|
REGTEST_BLOCK_AUDIT_START_HEIGHT: number;
|
||||||
MAINNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
MAINNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
||||||
TESTNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
TESTNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
||||||
TESTNET4_TX_FIRST_SEEN_START_HEIGHT: number;
|
TESTNET4_TX_FIRST_SEEN_START_HEIGHT: number;
|
||||||
SIGNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
SIGNET_TX_FIRST_SEEN_START_HEIGHT: number;
|
||||||
|
REGTEST_TX_FIRST_SEEN_START_HEIGHT: number;
|
||||||
HISTORICAL_PRICE: boolean;
|
HISTORICAL_PRICE: boolean;
|
||||||
ACCELERATOR: boolean;
|
ACCELERATOR: boolean;
|
||||||
ACCELERATOR_BUTTON: boolean;
|
ACCELERATOR_BUTTON: boolean;
|
||||||
|
|
@ -95,6 +98,7 @@ const defaultEnv: Env = {
|
||||||
'TESTNET_ENABLED': false,
|
'TESTNET_ENABLED': false,
|
||||||
'TESTNET4_ENABLED': false,
|
'TESTNET4_ENABLED': false,
|
||||||
'SIGNET_ENABLED': false,
|
'SIGNET_ENABLED': false,
|
||||||
|
'REGTEST_ENABLED': false,
|
||||||
'LIQUID_ENABLED': false,
|
'LIQUID_ENABLED': false,
|
||||||
'LIQUID_TESTNET_ENABLED': false,
|
'LIQUID_TESTNET_ENABLED': false,
|
||||||
'BASE_MODULE': 'mempool',
|
'BASE_MODULE': 'mempool',
|
||||||
|
|
@ -118,10 +122,12 @@ const defaultEnv: Env = {
|
||||||
'TESTNET_BLOCK_AUDIT_START_HEIGHT': 0,
|
'TESTNET_BLOCK_AUDIT_START_HEIGHT': 0,
|
||||||
'TESTNET4_BLOCK_AUDIT_START_HEIGHT': 0,
|
'TESTNET4_BLOCK_AUDIT_START_HEIGHT': 0,
|
||||||
'SIGNET_BLOCK_AUDIT_START_HEIGHT': 0,
|
'SIGNET_BLOCK_AUDIT_START_HEIGHT': 0,
|
||||||
|
'REGTEST_BLOCK_AUDIT_START_HEIGHT': 0,
|
||||||
'MAINNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
'MAINNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
||||||
'TESTNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
'TESTNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
||||||
'TESTNET4_TX_FIRST_SEEN_START_HEIGHT': 0,
|
'TESTNET4_TX_FIRST_SEEN_START_HEIGHT': 0,
|
||||||
'SIGNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
'SIGNET_TX_FIRST_SEEN_START_HEIGHT': 0,
|
||||||
|
'REGTEST_TX_FIRST_SEEN_START_HEIGHT': 0,
|
||||||
'HISTORICAL_PRICE': true,
|
'HISTORICAL_PRICE': true,
|
||||||
'ACCELERATOR': false,
|
'ACCELERATOR': false,
|
||||||
'ACCELERATOR_BUTTON': true,
|
'ACCELERATOR_BUTTON': true,
|
||||||
|
|
@ -399,7 +405,7 @@ export class StateService {
|
||||||
// (?:preview\/)? optional "preview" prefix (non-capturing)
|
// (?:preview\/)? optional "preview" prefix (non-capturing)
|
||||||
// (testnet|signet)/ network string (captured as networkMatches[1])
|
// (testnet|signet)/ network string (captured as networkMatches[1])
|
||||||
// ($|\/) network string must end or end with a slash
|
// ($|\/) network string must end or end with a slash
|
||||||
let networkMatches: object = url.match(/^\/(?:[a-z]{2}(?:-[A-Z]{2})?\/)?(?:preview\/)?(testnet4?|signet)($|\/)/);
|
let networkMatches: object = url.match(/^\/(?:[a-z]{2}(?:-[A-Z]{2})?\/)?(?:preview\/)?(testnet4?|signet|regtest)($|\/)/);
|
||||||
|
|
||||||
if (!networkMatches && this.env.ROOT_NETWORK) {
|
if (!networkMatches && this.env.ROOT_NETWORK) {
|
||||||
networkMatches = { 1: this.env.ROOT_NETWORK };
|
networkMatches = { 1: this.env.ROOT_NETWORK };
|
||||||
|
|
@ -429,6 +435,12 @@ export class StateService {
|
||||||
this.networkChanged$.next('testnet4');
|
this.networkChanged$.next('testnet4');
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case 'regtest':
|
||||||
|
if (this.network !== 'regtest') {
|
||||||
|
this.network = 'regtest';
|
||||||
|
this.networkChanged$.next('regtest');
|
||||||
|
}
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
if (this.env.BASE_MODULE !== 'mempool') {
|
if (this.env.BASE_MODULE !== 'mempool') {
|
||||||
if (this.network !== this.env.BASE_MODULE) {
|
if (this.network !== this.env.BASE_MODULE) {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,13 @@ const ADDRESS_PREFIXES = {
|
||||||
},
|
},
|
||||||
bech32: 'tb1',
|
bech32: 'tb1',
|
||||||
},
|
},
|
||||||
|
regtest: {
|
||||||
|
base58: {
|
||||||
|
pubkey: ['m', 'n'],
|
||||||
|
script: '2',
|
||||||
|
},
|
||||||
|
bech32: 'bcrt1',
|
||||||
|
},
|
||||||
liquid: {
|
liquid: {
|
||||||
base58: {
|
base58: {
|
||||||
pubkey: ['P','Q'],
|
pubkey: ['P','Q'],
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ export function nextRoundNumber(num: number): number {
|
||||||
export function seoDescriptionNetwork(network: string): string {
|
export function seoDescriptionNetwork(network: string): string {
|
||||||
if( network === 'liquidtestnet' || network === 'testnet' ) {
|
if( network === 'liquidtestnet' || network === 'testnet' ) {
|
||||||
return ' Testnet';
|
return ' Testnet';
|
||||||
} else if( network === 'signet' || network === 'testnet' || network === 'testnet4') {
|
} else if( network === 'signet' || network === 'testnet' || network === 'testnet4' || network === 'regtest') {
|
||||||
return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
|
return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,13 @@
|
||||||
<p *ngIf="mempoolSpaceBuild"><a [routerLink]="['/research' | relativeUrl]" i18n="mempool-research">Research</a></p>
|
<p *ngIf="mempoolSpaceBuild"><a [routerLink]="['/research' | relativeUrl]" i18n="mempool-research">Research</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="links" *ngIf="officialMempoolSpace || env.TESTNET_ENABLED || env.TESTNET4_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED else toolBox" >
|
<div class="links" *ngIf="officialMempoolSpace || env.TESTNET_ENABLED || env.TESTNET4_ENABLED || env.SIGNET_ENABLED || env.REGTEST_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED else toolBox" >
|
||||||
<p class="category" i18n="footer.networks">Networks</p>
|
<p class="category" i18n="footer.networks">Networks</p>
|
||||||
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== '') && (currentNetwork !== 'mainnet')"><a [href]="networkLink('mainnet')" i18n="footer.mainnet-explorer">Mainnet Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== '') && (currentNetwork !== 'mainnet')"><a [href]="networkLink('mainnet')" i18n="footer.mainnet-explorer">Mainnet Explorer</a></p>
|
||||||
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet') && env.TESTNET_ENABLED"><a [href]="networkLink('testnet')" i18n="footer.testnet3-explorer">Testnet3 Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet') && env.TESTNET_ENABLED"><a [href]="networkLink('testnet')" i18n="footer.testnet3-explorer">Testnet3 Explorer</a></p>
|
||||||
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet4') && env.TESTNET4_ENABLED"><a [href]="networkLink('testnet4')" i18n="footer.testnet4-explorer">Testnet4 Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet4') && env.TESTNET4_ENABLED"><a [href]="networkLink('testnet4')" i18n="footer.testnet4-explorer">Testnet4 Explorer</a></p>
|
||||||
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'signet') && env.SIGNET_ENABLED"><a [href]="networkLink('signet')" i18n="footer.signet-explorer">Signet Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'signet') && env.SIGNET_ENABLED"><a [href]="networkLink('signet')" i18n="footer.signet-explorer">Signet Explorer</a></p>
|
||||||
|
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'regtest') && env.REGTEST_ENABLED"><a [href]="networkLink('regtest')" i18n="footer.regtest-explorer">Regtest Explorer</a></p>
|
||||||
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquidtestnet')"><a [href]="networkLink('liquidtestnet')" i18n="footer.liquid-testnet-explorer">Liquid Testnet Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquidtestnet')"><a [href]="networkLink('liquidtestnet')" i18n="footer.liquid-testnet-explorer">Liquid Testnet Explorer</a></p>
|
||||||
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquid')"><a [href]="networkLink('liquid')" i18n="footer.liquid-explorer">Liquid Explorer</a></p>
|
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquid')"><a [href]="networkLink('liquid')" i18n="footer.liquid-explorer">Liquid Explorer</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,20 @@ const ADDRESS_CHARS: {
|
||||||
+ `{6,100}`
|
+ `{6,100}`
|
||||||
+ `)`,
|
+ `)`,
|
||||||
},
|
},
|
||||||
|
regtest: {
|
||||||
|
base58: `[mn2]` // Same as testnet
|
||||||
|
+ BASE58_CHARS
|
||||||
|
+ `{33,34}`,
|
||||||
|
bech32: `(?:`
|
||||||
|
+ `bcrt1` // Starts with bcrt1
|
||||||
|
+ BECH32_CHARS_LW
|
||||||
|
+ `{6,100}`
|
||||||
|
+ `|`
|
||||||
|
+ `BCRT1` // All upper case version
|
||||||
|
+ BECH32_CHARS_UP
|
||||||
|
+ `{6,100}`
|
||||||
|
+ `)`,
|
||||||
|
},
|
||||||
liquid: {
|
liquid: {
|
||||||
base58: `[GHPQ]` // PQ is P2PKH, GH is P2SH
|
base58: `[GHPQ]` // PQ is P2PKH, GH is P2SH
|
||||||
+ BASE58_CHARS
|
+ BASE58_CHARS
|
||||||
|
|
@ -142,7 +156,7 @@ const ADDRESS_CHARS: {
|
||||||
type RegexTypeNoAddrNoBlockHash = | `transaction` | `blockheight` | `date` | `timestamp`;
|
type RegexTypeNoAddrNoBlockHash = | `transaction` | `blockheight` | `date` | `timestamp`;
|
||||||
export type RegexType = `address` | `blockhash` | RegexTypeNoAddrNoBlockHash;
|
export type RegexType = `address` | `blockhash` | RegexTypeNoAddrNoBlockHash;
|
||||||
|
|
||||||
export const NETWORKS = [`mainnet`, `testnet4`, `testnet`, `signet`, `liquid`, `liquidtestnet`] as const;
|
export const NETWORKS = [`mainnet`, `testnet4`, `testnet`, `signet`, `regtest`, `liquid`, `liquidtestnet`] as const;
|
||||||
export type Network = typeof NETWORKS[number]; // Turn const array into union type
|
export type Network = typeof NETWORKS[number]; // Turn const array into union type
|
||||||
|
|
||||||
export const ADDRESS_REGEXES: [RegExp, Network][] = NETWORKS
|
export const ADDRESS_REGEXES: [RegExp, Network][] = NETWORKS
|
||||||
|
|
@ -162,6 +176,8 @@ function isNetworkAvailable(network: Network, env: Env): boolean {
|
||||||
return env.TESTNET4_ENABLED === true;
|
return env.TESTNET4_ENABLED === true;
|
||||||
case 'signet':
|
case 'signet':
|
||||||
return env.SIGNET_ENABLED === true;
|
return env.SIGNET_ENABLED === true;
|
||||||
|
case 'regtest':
|
||||||
|
return env.REGTEST_ENABLED === true;
|
||||||
case 'liquid':
|
case 'liquid':
|
||||||
return env.LIQUID_ENABLED === true;
|
return env.LIQUID_ENABLED === true;
|
||||||
case 'liquidtestnet':
|
case 'liquidtestnet':
|
||||||
|
|
@ -176,7 +192,7 @@ function isNetworkAvailable(network: Network, env: Env): boolean {
|
||||||
export function needBaseModuleChange(fromBaseModule: 'mempool' | 'liquid', toNetwork: Network): boolean {
|
export function needBaseModuleChange(fromBaseModule: 'mempool' | 'liquid', toNetwork: Network): boolean {
|
||||||
if (!toNetwork) {return false;} // No target network means no change needed
|
if (!toNetwork) {return false;} // No target network means no change needed
|
||||||
if (fromBaseModule === 'mempool') {
|
if (fromBaseModule === 'mempool') {
|
||||||
return toNetwork !== 'mainnet' && toNetwork !== 'testnet' && toNetwork !== 'testnet4' && toNetwork !== 'signet';
|
return toNetwork !== 'mainnet' && toNetwork !== 'testnet' && toNetwork !== 'testnet4' && toNetwork !== 'signet' && toNetwork !== 'regtest';
|
||||||
}
|
}
|
||||||
if (fromBaseModule === 'liquid') {
|
if (fromBaseModule === 'liquid') {
|
||||||
return toNetwork !== 'liquid' && toNetwork !== 'liquidtestnet';
|
return toNetwork !== 'liquid' && toNetwork !== 'liquidtestnet';
|
||||||
|
|
@ -191,7 +207,7 @@ export function getTargetUrl(toNetwork: Network, address: string, env: Env): str
|
||||||
targetUrl += '/address/';
|
targetUrl += '/address/';
|
||||||
targetUrl += address;
|
targetUrl += address;
|
||||||
}
|
}
|
||||||
if (toNetwork === 'mainnet' || toNetwork === 'testnet' || toNetwork === 'testnet4' || toNetwork === 'signet') {
|
if (toNetwork === 'mainnet' || toNetwork === 'testnet' || toNetwork === 'testnet4' || toNetwork === 'signet' || toNetwork === 'regtest') {
|
||||||
targetUrl = env.MEMPOOL_WEBSITE_URL;
|
targetUrl = env.MEMPOOL_WEBSITE_URL;
|
||||||
targetUrl += (toNetwork === 'mainnet' ? '' : `/${toNetwork}`);
|
targetUrl += (toNetwork === 'mainnet' ? '' : `/${toNetwork}`);
|
||||||
targetUrl += '/address/';
|
targetUrl += '/address/';
|
||||||
|
|
@ -231,6 +247,9 @@ export function getRegex(type: RegexType, network?: Network): RegExp {
|
||||||
case `signet`:
|
case `signet`:
|
||||||
leadingZeroes = 5;
|
leadingZeroes = 5;
|
||||||
break;
|
break;
|
||||||
|
case `regtest`:
|
||||||
|
leadingZeroes = 1; // Regtest has very low difficulty
|
||||||
|
break;
|
||||||
case `liquid`:
|
case `liquid`:
|
||||||
leadingZeroes = 8; // We are not interested in Liquid block hashes
|
leadingZeroes = 8; // We are not interested in Liquid block hashes
|
||||||
break;
|
break;
|
||||||
|
|
@ -298,6 +317,15 @@ export function getRegex(type: RegexType, network?: Network): RegExp {
|
||||||
regex += `|`; // OR
|
regex += `|`; // OR
|
||||||
regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
|
regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
|
||||||
break;
|
break;
|
||||||
|
case `regtest`:
|
||||||
|
regex += ADDRESS_CHARS.regtest.base58;
|
||||||
|
regex += `|`; // OR
|
||||||
|
regex += ADDRESS_CHARS.regtest.bech32;
|
||||||
|
regex += `|`; // OR
|
||||||
|
regex += `04${HEX_CHARS}{128}`; // Uncompressed pubkey
|
||||||
|
regex += `|`; // OR
|
||||||
|
regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
|
||||||
|
break;
|
||||||
case `liquid`:
|
case `liquid`:
|
||||||
regex += ADDRESS_CHARS.liquid.base58;
|
regex += ADDRESS_CHARS.liquid.base58;
|
||||||
regex += `|`; // OR
|
regex += `|`; // OR
|
||||||
|
|
|
||||||
|
|
@ -121,12 +121,14 @@ $dropdown-link-active-bg: $active-bg;
|
||||||
|
|
||||||
--testnet: #1d486f;
|
--testnet: #1d486f;
|
||||||
--signet: #6f1d5d;
|
--signet: #6f1d5d;
|
||||||
|
--regtest: #7d7d7d;
|
||||||
--liquid: #116761;
|
--liquid: #116761;
|
||||||
--liquidtestnet: #494a4a;
|
--liquidtestnet: #494a4a;
|
||||||
|
|
||||||
--mainnet-alt: #9339f4;
|
--mainnet-alt: #9339f4;
|
||||||
--testnet-alt: #183550;
|
--testnet-alt: #183550;
|
||||||
--signet-alt: #471850;
|
--signet-alt: #471850;
|
||||||
|
--regtest-alt: #4a4a4a;
|
||||||
--liquidtestnet-alt: #272e46;
|
--liquidtestnet-alt: #272e46;
|
||||||
|
|
||||||
--taproot: #eba814;
|
--taproot: #eba814;
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,14 @@ $dropdown-link-active-bg: $active-bg;
|
||||||
|
|
||||||
--testnet: #1d486f;
|
--testnet: #1d486f;
|
||||||
--signet: #6f1d5d;
|
--signet: #6f1d5d;
|
||||||
|
--regtest: #7d7d7d;
|
||||||
--liquid: #116761;
|
--liquid: #116761;
|
||||||
--liquidtestnet: #494a4a;
|
--liquidtestnet: #494a4a;
|
||||||
|
|
||||||
--mainnet-alt: #9339f4;
|
--mainnet-alt: #9339f4;
|
||||||
--testnet-alt: #183550;
|
--testnet-alt: #183550;
|
||||||
--signet-alt: #471850;
|
--signet-alt: #471850;
|
||||||
|
--regtest-alt: #4a4a4a;
|
||||||
--liquidtestnet-alt: #272e46;
|
--liquidtestnet-alt: #272e46;
|
||||||
|
|
||||||
--taproot: #eba814;
|
--taproot: #eba814;
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,14 @@ $dropdown-link-active-bg: $active-bg;
|
||||||
|
|
||||||
--testnet: #1d486f;
|
--testnet: #1d486f;
|
||||||
--signet: #6f1d5d;
|
--signet: #6f1d5d;
|
||||||
|
--regtest: #7d7d7d;
|
||||||
--liquid: #116761;
|
--liquid: #116761;
|
||||||
--liquidtestnet: #494a4a;
|
--liquidtestnet: #494a4a;
|
||||||
|
|
||||||
--mainnet-alt: #9339f4;
|
--mainnet-alt: #9339f4;
|
||||||
--testnet-alt: #183550;
|
--testnet-alt: #183550;
|
||||||
--signet-alt: #471850;
|
--signet-alt: #471850;
|
||||||
|
--regtest-alt: #4a4a4a;
|
||||||
--liquidtestnet-alt: #272e46;
|
--liquidtestnet-alt: #272e46;
|
||||||
|
|
||||||
--taproot: #eba814;
|
--taproot: #eba814;
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,14 @@ $dropdown-link-active-bg: $active-bg;
|
||||||
|
|
||||||
--testnet: #1d486f;
|
--testnet: #1d486f;
|
||||||
--signet: #6f1d5d;
|
--signet: #6f1d5d;
|
||||||
|
--regtest: #7d7d7d;
|
||||||
--liquid: #116761;
|
--liquid: #116761;
|
||||||
--liquidtestnet: #494a4a;
|
--liquidtestnet: #494a4a;
|
||||||
|
|
||||||
--mainnet-alt: #9339f4;
|
--mainnet-alt: #9339f4;
|
||||||
--testnet-alt: #183550;
|
--testnet-alt: #183550;
|
||||||
--signet-alt: #471850;
|
--signet-alt: #471850;
|
||||||
|
--regtest-alt: #4a4a4a;
|
||||||
--liquidtestnet-alt: #272e46;
|
--liquidtestnet-alt: #272e46;
|
||||||
|
|
||||||
--taproot: #eba814;
|
--taproot: #eba814;
|
||||||
|
|
|
||||||
44
production/mempool-config.regtest.json
Normal file
44
production/mempool-config.regtest.json
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"MEMPOOL": {
|
||||||
|
"OFFICIAL": true,
|
||||||
|
"NETWORK": "regtest",
|
||||||
|
"BACKEND": "esplora",
|
||||||
|
"HTTP_PORT": 8989,
|
||||||
|
"MINED_BLOCKS_CACHE": 144,
|
||||||
|
"SPAWN_CLUSTER_PROCS": 0,
|
||||||
|
"API_URL_PREFIX": "/api/v1/",
|
||||||
|
"INDEXING_BLOCKS_AMOUNT": -1,
|
||||||
|
"AUTOMATIC_POOLS_UPDATE": false,
|
||||||
|
"POOLS_UPDATE_DELAY": 3600,
|
||||||
|
"AUDIT": true,
|
||||||
|
"RUST_GBT": true,
|
||||||
|
"POLL_RATE_MS": 500,
|
||||||
|
"DISK_CACHE_BLOCK_INTERVAL": 1,
|
||||||
|
"MAX_PUSH_TX_SIZE_WEIGHT": 4000000,
|
||||||
|
"ALLOW_UNREACHABLE": true,
|
||||||
|
"MAX_TRACKED_ADDRESSES": 10
|
||||||
|
},
|
||||||
|
"SYSLOG" : {
|
||||||
|
"MIN_PRIORITY": "debug"
|
||||||
|
},
|
||||||
|
"CORE_RPC": {
|
||||||
|
"PORT": 18443,
|
||||||
|
"USERNAME": "__BITCOIN_RPC_USER__",
|
||||||
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
|
},
|
||||||
|
"ESPLORA": {
|
||||||
|
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-regtest"
|
||||||
|
},
|
||||||
|
"DATABASE": {
|
||||||
|
"ENABLED": true,
|
||||||
|
"HOST": "127.0.0.1",
|
||||||
|
"SOCKET": "/var/run/mysql/mysql.sock",
|
||||||
|
"USERNAME": "__MEMPOOL_REGTEST_USER__",
|
||||||
|
"PASSWORD": "__MEMPOOL_REGTEST_PASS__",
|
||||||
|
"DATABASE": "mempool_regtest"
|
||||||
|
},
|
||||||
|
"STATISTICS": {
|
||||||
|
"ENABLED": true,
|
||||||
|
"TX_PER_SECOND_SAMPLE_PERIOD": 150
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue