diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts
index ee9df9151..6cb361ffd 100644
--- a/backend/src/api/database-migration.ts
+++ b/backend/src/api/database-migration.ts
@@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
import { RowDataPacket } from 'mysql2';
class DatabaseMigration {
- private static currentVersion = 83;
+ private static currentVersion = 93;
private queryTimeout = 3600_000;
private statisticsAddedIndexed = false;
private uniqueLogs: string[] = [];
@@ -710,6 +710,97 @@ class DatabaseMigration {
await this.$executeQuery('ALTER TABLE `blocks` ADD first_seen datetime(6) DEFAULT NULL');
await this.updateToSchemaVersion(83);
}
+
+ // add new pools indexes
+ if (databaseSchemaVersion < 84 && isBitcoin === true) {
+ await this.$executeQuery(`
+ ALTER TABLE \`pools\`
+ ADD INDEX \`slug\` (\`slug\`),
+ ADD INDEX \`unique_id\` (\`unique_id\`)
+ `);
+ await this.updateToSchemaVersion(84);
+ }
+
+ // lightning channels indexes
+ if (databaseSchemaVersion < 85 && isBitcoin === true) {
+ await this.$executeQuery(`
+ ALTER TABLE \`channels\`
+ ADD INDEX \`created\` (\`created\`),
+ ADD INDEX \`capacity\` (\`capacity\`),
+ ADD INDEX \`closing_reason\` (\`closing_reason\`),
+ ADD INDEX \`closing_resolved\` (\`closing_resolved\`)
+ `);
+ await this.updateToSchemaVersion(85);
+ }
+
+ // lightning nodes indexes
+ if (databaseSchemaVersion < 86 && isBitcoin === true) {
+ await this.$executeQuery(`
+ ALTER TABLE \`nodes\`
+ ADD INDEX \`status\` (\`status\`),
+ ADD INDEX \`channels\` (\`channels\`),
+ ADD INDEX \`country_id\` (\`country_id\`),
+ ADD INDEX \`as_number\` (\`as_number\`),
+ ADD INDEX \`first_seen\` (\`first_seen\`)
+ `);
+ await this.updateToSchemaVersion(86);
+ }
+
+ // lightning node sockets indexes
+ if (databaseSchemaVersion < 87 && isBitcoin === true) {
+ await this.$executeQuery('ALTER TABLE `nodes_sockets` ADD INDEX `type` (`type`)');
+ await this.updateToSchemaVersion(87);
+ }
+
+ // lightning stats indexes
+ if (databaseSchemaVersion < 88 && isBitcoin === true) {
+ await this.$executeQuery('ALTER TABLE `lightning_stats` ADD INDEX `added` (`added`)');
+ await this.updateToSchemaVersion(88);
+ }
+
+ // geo names indexes
+ if (databaseSchemaVersion < 89 && isBitcoin === true) {
+ await this.$executeQuery('ALTER TABLE `geo_names` ADD INDEX `names` (`names`)');
+ await this.updateToSchemaVersion(89);
+ }
+
+ // hashrates indexes
+ if (databaseSchemaVersion < 90 && isBitcoin === true) {
+ await this.$executeQuery('ALTER TABLE `hashrates` ADD INDEX `type` (`type`)');
+ await this.updateToSchemaVersion(90);
+ }
+
+ // block audits indexes
+ if (databaseSchemaVersion < 91 && isBitcoin === true) {
+ await this.$executeQuery('ALTER TABLE `blocks_audits` ADD INDEX `time` (`time`)');
+ await this.updateToSchemaVersion(91);
+ }
+
+ // elements_pegs indexes
+ if (databaseSchemaVersion < 92 && config.MEMPOOL.NETWORK === 'liquid') {
+ await this.$executeQuery(`
+ ALTER TABLE \`elements_pegs\`
+ ADD INDEX \`block\` (\`block\`),
+ ADD INDEX \`datetime\` (\`datetime\`),
+ ADD INDEX \`amount\` (\`amount\`),
+ ADD INDEX \`bitcoinaddress\` (\`bitcoinaddress\`),
+ ADD INDEX \`bitcointxid\` (\`bitcointxid\`)
+ `);
+ await this.updateToSchemaVersion(92);
+ }
+
+ // federation_txos indexes
+ if (databaseSchemaVersion < 93 && config.MEMPOOL.NETWORK === 'liquid') {
+ await this.$executeQuery(`
+ ALTER TABLE \`federation_txos\`
+ ADD INDEX \`unspent\` (\`unspent\`),
+ ADD INDEX \`lastblockupdate\` (\`lastblockupdate\`),
+ ADD INDEX \`blocktime\` (\`blocktime\`),
+ ADD INDEX \`emergencyKey\` (\`emergencyKey\`),
+ ADD INDEX \`expiredAt\` (\`expiredAt\`)
+ `);
+ await this.updateToSchemaVersion(93);
+ }
}
/**
diff --git a/backend/src/api/mempool-blocks.ts b/backend/src/api/mempool-blocks.ts
index 6e547e653..ba4ce2ed0 100644
--- a/backend/src/api/mempool-blocks.ts
+++ b/backend/src/api/mempool-blocks.ts
@@ -382,7 +382,7 @@ class MempoolBlocks {
const ancestors: Ancestor[] = [];
const descendants: Ancestor[] = [];
- let ancestor: MempoolTransactionExtended
+ let ancestor: MempoolTransactionExtended;
for (const cluster of clusters) {
for (const memberTxid of cluster) {
const mempoolTx = mempool[memberTxid];
@@ -462,7 +462,7 @@ class MempoolBlocks {
for (let i = 0; i < block.length; i++) {
const txid = block[i];
- if (txid) {
+ if (txid in mempool) {
mempoolTx = mempool[txid];
// save position in projected blocks
mempoolTx.position = {
@@ -481,6 +481,9 @@ class MempoolBlocks {
mempoolTx.acceleratedAt = acceleration?.added;
mempoolTx.feeDelta = acceleration?.feeDelta;
for (const ancestor of mempoolTx.ancestors || []) {
+ if (!(ancestor.txid in mempool)) {
+ continue;
+ }
if (!mempool[ancestor.txid].acceleration) {
mempool[ancestor.txid].cpfpDirty = true;
}
@@ -688,7 +691,7 @@ class MempoolBlocks {
[pool: string]: { name: string, block: number, vsize: number, accelerations: string[], complete: boolean };
} = {};
// prepare a list of accelerations in ascending order (we'll pop items off the end of the list)
- const accQueue: { acceleration: Acceleration, rate: number, vsize: number }[] = Object.values(accelerations).map(acc => {
+ const accQueue: { acceleration: Acceleration, rate: number, vsize: number }[] = Object.values(accelerations).filter(acc => acc.txid in mempoolCache).map(acc => {
let vsize = mempoolCache[acc.txid].vsize;
for (const ancestor of mempoolCache[acc.txid].ancestors || []) {
vsize += (ancestor.weight / 4);
diff --git a/backend/src/api/services/acceleration.ts b/backend/src/api/services/acceleration.ts
index e18bcf464..053da6e82 100644
--- a/backend/src/api/services/acceleration.ts
+++ b/backend/src/api/services/acceleration.ts
@@ -246,17 +246,22 @@ class AccelerationApi {
this.startedWebsocketLoop = true;
if (!this.ws) {
this.ws = new WebSocket(this.websocketPath);
- this.websocketConnected = true;
+ this.lastPing = 0;
this.ws.on('open', () => {
logger.info(`Acceleration websocket opened to ${this.websocketPath}`);
+ this.websocketConnected = true;
this.ws?.send(JSON.stringify({
'watch-accelerations': true
}));
});
this.ws.on('error', (error) => {
- logger.err(`Acceleration websocket error on ${this.websocketPath}: ` + error);
+ let errMsg = `Acceleration websocket error on ${this.websocketPath}: ${error['code']}`;
+ if (error['errors']) {
+ errMsg += ' - ' + error['errors'].join(' - ');
+ }
+ logger.err(errMsg);
this.ws = null;
this.websocketConnected = false;
});
@@ -285,16 +290,28 @@ class AccelerationApi {
logger.debug('received pong from acceleration websocket server');
this.lastPong = Date.now();
});
- } else {
- if (this.lastPing > this.lastPong && Date.now() - this.lastPing > 10000) {
+ } else if (this.websocketConnected) {
+ if (this.lastPing && this.lastPing > this.lastPong && (Date.now() - this.lastPing > 10000)) {
logger.warn('No pong received within 10 seconds, terminating connection');
- this.ws.terminate();
- this.ws = null;
- this.websocketConnected = false;
- } else if (Date.now() - this.lastPing > 30000) {
+ try {
+ this.ws?.terminate();
+ } catch (e) {
+ logger.warn('failed to terminate acceleration websocket connection: ' + (e instanceof Error ? e.message : e));
+ } finally {
+ this.ws = null;
+ this.websocketConnected = false;
+ this.lastPing = 0;
+ }
+ } else if (!this.lastPing || (Date.now() - this.lastPing > 30000)) {
logger.debug('sending ping to acceleration websocket server');
- this.ws.ping();
- this.lastPing = Date.now();
+ if (this.ws?.readyState === WebSocket.OPEN) {
+ try {
+ this.ws?.ping();
+ this.lastPing = Date.now();
+ } catch (e) {
+ logger.warn('failed to send ping to acceleration websocket server: ' + (e instanceof Error ? e.message : e));
+ }
+ }
}
}
await new Promise(resolve => setTimeout(resolve, 5000));
diff --git a/frontend/custom-meta-config.json b/frontend/custom-meta-config.json
new file mode 100644
index 000000000..6fa46192a
--- /dev/null
+++ b/frontend/custom-meta-config.json
@@ -0,0 +1,51 @@
+{
+ "theme": "contrast",
+ "enterprise": "meta",
+ "branding": {
+ "name": "metaplanet",
+ "title": "Metaplanet",
+ "site_id": 21,
+ "header_img": "/resources/metalogo.svg",
+ "footer_img": "/resources/metalogo.svg"
+ },
+ "dashboard": {
+ "widgets": [
+ {
+ "component": "fees",
+ "mobileOrder": 4
+ },
+ {
+ "component": "walletBalance",
+ "mobileOrder": 1,
+ "props": {
+ "wallet": "3350"
+ }
+ },
+ {
+ "component": "twitter",
+ "mobileOrder": 5,
+ "props": {
+ "handle": "Metaplanet_JP"
+ }
+ },
+ {
+ "component": "wallet",
+ "mobileOrder": 2,
+ "props": {
+ "wallet": "3350",
+ "period": "all"
+ }
+ },
+ {
+ "component": "blocks"
+ },
+ {
+ "component": "walletTransactions",
+ "mobileOrder": 3,
+ "props": {
+ "wallet": "3350"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts b/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts
index 425e00d9e..1a5ace34f 100644
--- a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts
+++ b/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts
@@ -2,7 +2,7 @@
import { Component, OnInit, OnDestroy, Output, EventEmitter, Input, ChangeDetectorRef, SimpleChanges, HostListener } from '@angular/core';
import { Subscription, tap, of, catchError, Observable, switchMap } from 'rxjs';
import { ServicesApiServices } from '@app/services/services-api.service';
-import { md5, insecureRandomUUID } from '@app/shared/common.utils';
+import { md5 } from '@app/shared/common.utils';
import { StateService } from '@app/services/state.service';
import { AudioService } from '@app/services/audio.service';
import { ETA, EtaService } from '@app/services/eta.service';
@@ -94,7 +94,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
auth: IAuth | null = null;
// accelerator stuff
- accelerationUUID: string;
accelerationSubscription: Subscription;
difficultySubscription: Subscription;
estimateSubscription: Subscription;
@@ -138,7 +137,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
private enterpriseService: EnterpriseService,
) {
this.isProdDomain = this.stateService.env.PROD_DOMAINS.indexOf(document.location.hostname) > -1;
- this.accelerationUUID = insecureRandomUUID();
// Check if Apple Pay available
// https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/checking_for_apple_pay_availability#overview
@@ -388,7 +386,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
this.accelerationSubscription = this.servicesApiService.accelerate$(
this.tx.txid,
this.userBid,
- this.accelerationUUID
).subscribe({
next: () => {
this.processing = false;
@@ -522,7 +519,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
tokenResult.token,
cardTag,
`accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
- this.accelerationUUID,
costUSD
).subscribe({
next: () => {
@@ -622,7 +618,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
tokenResult.token,
cardTag,
`accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
- this.accelerationUUID,
costUSD
).subscribe({
next: () => {
@@ -713,7 +708,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
tokenResult.token,
tokenResult.details.cashAppPay.cashtag,
tokenResult.details.cashAppPay.referenceId,
- this.accelerationUUID,
costUSD
).subscribe({
next: () => {
diff --git a/frontend/src/app/components/address-graph/address-graph.component.ts b/frontend/src/app/components/address-graph/address-graph.component.ts
index e8762fbec..e4c38c897 100644
--- a/frontend/src/app/components/address-graph/address-graph.component.ts
+++ b/frontend/src/app/components/address-graph/address-graph.component.ts
@@ -10,7 +10,6 @@ import { RelativeUrlPipe } from '@app/shared/pipes/relative-url/relative-url.pip
import { StateService } from '@app/services/state.service';
import { PriceService } from '@app/services/price.service';
import { FiatCurrencyPipe } from '@app/shared/pipes/fiat-currency.pipe';
-import { FiatShortenerPipe } from '@app/shared/pipes/fiat-shortener.pipe';
const periodSeconds = {
'1d': (60 * 60 * 24),
@@ -77,7 +76,6 @@ export class AddressGraphComponent implements OnChanges, OnDestroy {
private relativeUrlPipe: RelativeUrlPipe,
private priceService: PriceService,
private fiatCurrencyPipe: FiatCurrencyPipe,
- private fiatShortenerPipe: FiatShortenerPipe,
private zone: NgZone,
) {}
@@ -245,18 +243,19 @@ export class AddressGraphComponent implements OnChanges, OnDestroy {
let tooltip = '
';
const hasTx = data[0].data[2].txid;
+ const date = new Date(data[0].data[0]).toLocaleTimeString(this.locale, { year: 'numeric', month: 'short', day: 'numeric' });
+
+ tooltip += `
+
+
${date}
`;
+
if (hasTx) {
const header = data.length === 1
? `${data[0].data[2].txid.slice(0, 6)}...${data[0].data[2].txid.slice(-6)}`
: `${data.length} transactions`;
- tooltip += `
${header} `;
+ tooltip += `
${header}
`;
}
- const date = new Date(data[0].data[0]).toLocaleTimeString(this.locale, { year: 'numeric', month: 'short', day: 'numeric' });
-
- tooltip += `
-
`;
-
const formatBTC = (val, decimal) => (val / 100_000_000).toFixed(decimal);
const formatFiat = (val) => this.fiatCurrencyPipe.transform(val, null, 'USD');
@@ -291,7 +290,7 @@ export class AddressGraphComponent implements OnChanges, OnDestroy {
}
}
- tooltip += `
${date} `;
+ tooltip += `
`;
return tooltip;
}.bind(this)
},
@@ -311,18 +310,21 @@ export class AddressGraphComponent implements OnChanges, OnDestroy {
formatter: (val): string => {
let valSpan = maxValue - (this.period === 'all' ? 0 : minValue);
if (valSpan > 100_000_000_000) {
- return `${this.amountShortenerPipe.transform(Math.round(val / 100_000_000), 0)} BTC`;
+ return `${this.amountShortenerPipe.transform(Math.round(val / 100_000_000), 0, undefined, true)} BTC`;
}
else if (valSpan > 1_000_000_000) {
- return `${this.amountShortenerPipe.transform(Math.round(val / 100_000_000), 2)} BTC`;
+ return `${this.amountShortenerPipe.transform(Math.round(val / 100_000_000), 2, undefined, true)} BTC`;
} else if (valSpan > 100_000_000) {
return `${(val / 100_000_000).toFixed(1)} BTC`;
} else if (valSpan > 10_000_000) {
return `${(val / 100_000_000).toFixed(2)} BTC`;
} else if (valSpan > 1_000_000) {
+ if (maxValue > 100_000_000_000) {
+ return `${this.amountShortenerPipe.transform(Math.round(val / 100_000_000), 3, undefined, true)} BTC`;
+ }
return `${(val / 100_000_000).toFixed(3)} BTC`;
} else {
- return `${this.amountShortenerPipe.transform(val, 0)} sats`;
+ return `${this.amountShortenerPipe.transform(val, 0, undefined, true)} sats`;
}
}
},
@@ -336,7 +338,7 @@ export class AddressGraphComponent implements OnChanges, OnDestroy {
axisLabel: {
color: 'rgb(110, 112, 121)',
formatter: function(val) {
- return this.fiatShortenerPipe.transform(val, null, 'USD');
+ return `$${this.amountShortenerPipe.transform(val, 0, undefined, true)}`;
}.bind(this)
},
splitLine: {
diff --git a/frontend/src/app/components/clipboard/clipboard.component.html b/frontend/src/app/components/clipboard/clipboard.component.html
index d23ccdf8c..c3a18d90b 100644
--- a/frontend/src/app/components/clipboard/clipboard.component.html
+++ b/frontend/src/app/components/clipboard/clipboard.component.html
@@ -1,15 +1,17 @@
-
-
+
+
+ {{ copiedMessage }}
-
-
+
+
+ {{ copiedMessage }}
diff --git a/frontend/src/app/components/clipboard/clipboard.component.scss b/frontend/src/app/components/clipboard/clipboard.component.scss
index 49294e548..6ae620ae7 100644
--- a/frontend/src/app/components/clipboard/clipboard.component.scss
+++ b/frontend/src/app/components/clipboard/clipboard.component.scss
@@ -7,7 +7,19 @@
padding-left: 0.4rem;
}
-img {
- position: relative;
- left: -3px;
-}
\ No newline at end of file
+.copied-message {
+ background: color-mix(in srgb, var(--active-bg) 95%, transparent);
+ color: var(--fg);
+ font-family: sans-serif;
+ font-size: .8rem;
+ font-weight: 400;
+ text-decoration: none;
+ text-align: left;
+ padding: .6em .75rem;
+ border-radius: 4px;
+ position: absolute;
+ white-space: nowrap;
+ box-shadow: 0 .5rem 1rem -.5rem #000;
+ z-index: 1000;
+ opacity: .9;
+}
diff --git a/frontend/src/app/components/clipboard/clipboard.component.ts b/frontend/src/app/components/clipboard/clipboard.component.ts
index 6e577d8b3..31f882d12 100644
--- a/frontend/src/app/components/clipboard/clipboard.component.ts
+++ b/frontend/src/app/components/clipboard/clipboard.component.ts
@@ -1,6 +1,4 @@
-import { Component, ViewChild, ElementRef, AfterViewInit, Input, ChangeDetectionStrategy } from '@angular/core';
-import * as ClipboardJS from 'clipboard';
-import * as tlite from 'tlite';
+import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-clipboard',
@@ -8,15 +6,14 @@ import * as tlite from 'tlite';
styleUrls: ['./clipboard.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class ClipboardComponent implements AfterViewInit {
- @ViewChild('btn') btn: ElementRef;
- @ViewChild('buttonWrapper') buttonWrapper: ElementRef;
+export class ClipboardComponent {
@Input() button = false;
@Input() class = 'btn btn-secondary ml-1';
@Input() size: 'small' | 'normal' | 'large' = 'normal';
@Input() text: string;
@Input() leftPadding = true;
copiedMessage: string = $localize`:@@clipboard.copied-message:Copied!`;
+ showMessage = false;
widths = {
small: '10',
@@ -24,22 +21,40 @@ export class ClipboardComponent implements AfterViewInit {
large: '18',
};
- clipboard: any;
+ constructor(
+ private cd: ChangeDetectorRef,
+ ) { }
- constructor() { }
-
- ngAfterViewInit() {
- this.clipboard = new ClipboardJS(this.btn.nativeElement);
- this.clipboard.on('success', () => {
- tlite.show(this.buttonWrapper.nativeElement);
- setTimeout(() => {
- tlite.hide(this.buttonWrapper.nativeElement);
- }, 1000);
- });
+ async copyText() {
+ if (this.text && !this.showMessage) {
+ try {
+ await this.copyToClipboard(this.text);
+ this.showMessage = true;
+ this.cd.markForCheck();
+ setTimeout(() => {
+ this.showMessage = false;
+ this.cd.markForCheck();
+ }, 1000);
+ } catch (error) {
+ console.error('Clipboard copy failed:', error);
+ }
+ }
}
- onDestroy() {
- this.clipboard.destroy();
+ async copyToClipboard(text: string) {
+ if (navigator.clipboard) {
+ await navigator.clipboard.writeText(text);
+ } else {
+ // Use the 'out of viewport hidden text area' trick on non-secure contexts
+ const textarea = document.createElement('textarea');
+ textarea.value = this.text;
+ textarea.style.opacity = '0';
+ textarea.setAttribute('readonly', 'true'); // Don't trigger keyboard on mobile
+ document.body.appendChild(textarea);
+ textarea.select();
+ document.execCommand('copy');
+ textarea.remove();
+ }
}
}
diff --git a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html
index acadc8818..9bdf4066a 100644
--- a/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html
+++ b/frontend/src/app/components/transaction/transaction-details/transaction-details.component.html
@@ -217,10 +217,10 @@
Fee
{{ tx.fee | number }} sats
- @if (accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
+ @if (isAcceleration && accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
+{{ accelerationInfo?.bidBoost ?? tx.feeDelta | number }} sats
}
-
+
} @else {
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index f19a5bcbd..a1b48766a 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -879,6 +879,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.tx.acceleratedAt = cpfpInfo.acceleratedAt;
this.tx.feeDelta = cpfpInfo.feeDelta;
this.setIsAccelerated(firstCpfp);
+ } else if (this.tx.acceleration) { // Acceleration was cancelled while on the tx page, reset acceleration state
+ this.tx.acceleration = false;
+ this.setIsAccelerated(firstCpfp);
}
if (this.notAcceleratedOnLoad === null) {
diff --git a/frontend/src/app/docs/api-docs/api-docs-data.ts b/frontend/src/app/docs/api-docs/api-docs-data.ts
index cad4b47bf..1f83cabc9 100644
--- a/frontend/src/app/docs/api-docs/api-docs-data.ts
+++ b/frontend/src/app/docs/api-docs/api-docs-data.ts
@@ -9339,7 +9339,7 @@ export const restApiDocsData = [
fragment: "accelerator-history",
title: "GET Acceleration History",
description: {
- default: "
Returns the user's past acceleration requests.
Pass one of the following for :status
: all
, requested
, accelerating
, mined
, completed
, failed
. Pass true
in :details
to get a detailed history
of the acceleration request.
"
+ default: "
Returns the user's past acceleration requests.
Pass one of the following for :status
(required): all
, requested
, accelerating
, mined
, completed
, failed
. Pass true
in :details
to get a detailed history
of the acceleration request.
"
},
urlString: "/v1/services/accelerator/history?status=:status&details=:details",
showConditions: [""],
@@ -9449,6 +9449,36 @@ export const restApiDocsData = [
}
}
},
+ {
+ options: { officialOnly: true },
+ type: "endpoint",
+ category: "accelerator-private",
+ httpRequestMethod: "POST",
+ fragment: "accelerator-cancel",
+ title: "POST Cancel Acceleration (Pro)",
+ description: {
+ default: "
Sends a request to cancel an acceleration in the accelerating
status. You can retreive eligible acceleration id
using the history endpoint GET /api/v1/services/accelerator/history?status=accelerating
."
+ },
+ urlString: "/v1/services/accelerator/cancel",
+ showConditions: [""],
+ showJsExamples: showJsExamplesDefaultFalse,
+ codeExample: {
+ default: {
+ codeTemplate: {
+ curl: `%{1}" "[[hostname]][[baseNetworkUrl]]/api/v1/services/accelerator/cancel`, //custom interpolation technique handled in replaceCurlPlaceholder()
+ commonJS: ``,
+ esModule: ``
+ },
+ codeSampleMainnet: {
+ esModule: [],
+ commonJS: [],
+ curl: ["id=42"],
+ headers: "X-Mempool-Auth: stacksats",
+ response: `HTTP/1.1 200 OK`,
+ },
+ }
+ }
+ },
];
export const faqData = [
diff --git a/frontend/src/app/services/services-api.service.ts b/frontend/src/app/services/services-api.service.ts
index 2b0f884ff..2ecfe06ff 100644
--- a/frontend/src/app/services/services-api.service.ts
+++ b/frontend/src/app/services/services-api.service.ts
@@ -131,20 +131,20 @@ export class ServicesApiServices {
return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/estimate`, { txInput: txInput }, { observe: 'response' });
}
- accelerate$(txInput: string, userBid: number, accelerationUUID: string) {
- return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate`, { txInput: txInput, userBid: userBid, accelerationUUID: accelerationUUID });
+ accelerate$(txInput: string, userBid: number) {
+ return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate`, { txInput: txInput, userBid: userBid});
}
- accelerateWithCashApp$(txInput: string, token: string, cashtag: string, referenceId: string, accelerationUUID: string, userApprovedUSD: number) {
- return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/cashapp`, { txInput: txInput, token: token, cashtag: cashtag, referenceId: referenceId, accelerationUUID: accelerationUUID, userApprovedUSD: userApprovedUSD });
+ accelerateWithCashApp$(txInput: string, token: string, cashtag: string, referenceId: string, userApprovedUSD: number) {
+ return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/cashapp`, { txInput: txInput, token: token, cashtag: cashtag, referenceId: referenceId, userApprovedUSD: userApprovedUSD });
}
- accelerateWithApplePay$(txInput: string, token: string, cardTag: string, referenceId: string, accelerationUUID: string, userApprovedUSD: number) {
- return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/applePay`, { txInput: txInput, cardTag: cardTag, token: token, referenceId: referenceId, accelerationUUID: accelerationUUID, userApprovedUSD: userApprovedUSD });
+ accelerateWithApplePay$(txInput: string, token: string, cardTag: string, referenceId: string, userApprovedUSD: number) {
+ return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/applePay`, { txInput: txInput, cardTag: cardTag, token: token, referenceId: referenceId, userApprovedUSD: userApprovedUSD });
}
- accelerateWithGooglePay$(txInput: string, token: string, cardTag: string, referenceId: string, accelerationUUID: string, userApprovedUSD: number) {
- return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/googlePay`, { txInput: txInput, cardTag: cardTag, token: token, referenceId: referenceId, accelerationUUID: accelerationUUID, userApprovedUSD: userApprovedUSD });
+ accelerateWithGooglePay$(txInput: string, token: string, cardTag: string, referenceId: string, userApprovedUSD: number) {
+ return this.httpClient.post(`${this.stateService.env.SERVICES_API}/accelerator/accelerate/googlePay`, { txInput: txInput, cardTag: cardTag, token: token, referenceId: referenceId, userApprovedUSD: userApprovedUSD });
}
getAccelerations$(): Observable {
diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts
index 5ec13c03f..0f5368244 100644
--- a/frontend/src/app/services/websocket.service.ts
+++ b/frontend/src/app/services/websocket.service.ts
@@ -37,6 +37,7 @@ export class WebsocketService {
private isTrackingWallet: boolean = false;
private trackingWalletName: string;
private trackingMempoolBlock: number;
+ private trackingMempoolBlockNetwork: string;
private stoppingTrackMempoolBlock: any | null = null;
private latestGitCommit = '';
private onlineCheckTimeout: number;
@@ -226,10 +227,11 @@ export class WebsocketService {
clearTimeout(this.stoppingTrackMempoolBlock);
}
// skip duplicate tracking requests
- if (force || this.trackingMempoolBlock !== block) {
+ if (force || this.trackingMempoolBlock !== block || this.network !== this.trackingMempoolBlockNetwork) {
this.websocketSubject.next({ 'track-mempool-block': block });
this.isTrackingMempoolBlock = true;
this.trackingMempoolBlock = block;
+ this.trackingMempoolBlockNetwork = this.network;
return true;
}
return false;
diff --git a/frontend/src/app/shared/common.utils.ts b/frontend/src/app/shared/common.utils.ts
index f329b55e4..9b53600c1 100644
--- a/frontend/src/app/shared/common.utils.ts
+++ b/frontend/src/app/shared/common.utils.ts
@@ -214,19 +214,6 @@ export function renderSats(value: number, network: string, mode: 'sats' | 'btc'
}
}
-export function insecureRandomUUID(): string {
- const hexDigits = '0123456789abcdef';
- const uuidLengths = [8, 4, 4, 4, 12];
- let uuid = '';
- for (const length of uuidLengths) {
- for (let i = 0; i < length; i++) {
- uuid += hexDigits[Math.floor(Math.random() * 16)];
- }
- uuid += '-';
- }
- return uuid.slice(0, -1);
-}
-
export function sleep$(ms: number): Promise {
return new Promise((resolve) => {
setTimeout(() => {
diff --git a/frontend/src/index.mempool.meta.html b/frontend/src/index.mempool.meta.html
new file mode 100644
index 000000000..92154f8db
--- /dev/null
+++ b/frontend/src/index.mempool.meta.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ Metaplanet Inc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/resources/meta/favicons/android-chrome-192x192.png b/frontend/src/resources/meta/favicons/android-chrome-192x192.png
new file mode 100644
index 000000000..448d5ce91
Binary files /dev/null and b/frontend/src/resources/meta/favicons/android-chrome-192x192.png differ
diff --git a/frontend/src/resources/meta/favicons/android-chrome-512x512.png b/frontend/src/resources/meta/favicons/android-chrome-512x512.png
new file mode 100644
index 000000000..5164c7746
Binary files /dev/null and b/frontend/src/resources/meta/favicons/android-chrome-512x512.png differ
diff --git a/frontend/src/resources/meta/favicons/apple-touch-icon.png b/frontend/src/resources/meta/favicons/apple-touch-icon.png
new file mode 100644
index 000000000..bd5b04f4b
Binary files /dev/null and b/frontend/src/resources/meta/favicons/apple-touch-icon.png differ
diff --git a/frontend/src/resources/meta/favicons/favicon-16x16.png b/frontend/src/resources/meta/favicons/favicon-16x16.png
new file mode 100644
index 000000000..2c9716325
Binary files /dev/null and b/frontend/src/resources/meta/favicons/favicon-16x16.png differ
diff --git a/frontend/src/resources/meta/favicons/favicon-32x32.png b/frontend/src/resources/meta/favicons/favicon-32x32.png
new file mode 100644
index 000000000..6fb88e678
Binary files /dev/null and b/frontend/src/resources/meta/favicons/favicon-32x32.png differ
diff --git a/frontend/src/resources/meta/favicons/favicon.ico b/frontend/src/resources/meta/favicons/favicon.ico
new file mode 100644
index 000000000..bd25b818f
Binary files /dev/null and b/frontend/src/resources/meta/favicons/favicon.ico differ
diff --git a/frontend/src/resources/meta/favicons/site.webmanifest b/frontend/src/resources/meta/favicons/site.webmanifest
new file mode 100644
index 000000000..45dc8a206
--- /dev/null
+++ b/frontend/src/resources/meta/favicons/site.webmanifest
@@ -0,0 +1 @@
+{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
\ No newline at end of file
diff --git a/frontend/src/resources/meta/meta-preview.png b/frontend/src/resources/meta/meta-preview.png
new file mode 100644
index 000000000..d569aae0e
Binary files /dev/null and b/frontend/src/resources/meta/meta-preview.png differ
diff --git a/frontend/src/resources/metalogo.svg b/frontend/src/resources/metalogo.svg
new file mode 100644
index 000000000..e3174dc62
--- /dev/null
+++ b/frontend/src/resources/metalogo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/production/bitcoin.conf b/production/bitcoin.conf
index 63baa32b5..57d993eb4 100644
--- a/production/bitcoin.conf
+++ b/production/bitcoin.conf
@@ -4,7 +4,6 @@ txindex=1
coinstatsindex=1
listen=1
discover=1
-par=16
dbcache=8192
mempoolfullrbf=1
maxconnections=100
diff --git a/production/mempool-config.mainnet.json b/production/mempool-config.mainnet.json
index f57978043..39d82d8d1 100644
--- a/production/mempool-config.mainnet.json
+++ b/production/mempool-config.mainnet.json
@@ -153,6 +153,6 @@
},
"WALLETS": {
"ENABLED": true,
- "WALLETS": ["BITB"]
+ "WALLETS": ["BITB", "3350"]
}
}