Compare commits

..

38 Commits

Author SHA1 Message Date
wiz
5d360d4156 Merge pull request #1003 from mempool/simon/database-migration-feature
Automated database creation and migration
2021-12-23 21:50:10 +00:00
softsimon
91e30fbc3c Merge branch 'master' into simon/database-migration-feature
# Conflicts:
#	backend/src/index.ts
2021-12-24 00:26:33 +04:00
wiz
5b22e2a000 Merge pull request #1010 from mempool/simon/liquid-icons-api
Liquid icons api
2021-12-23 12:28:54 +00:00
softsimon
533653e54a Change Asset Icon API example to only show HTML 2021-12-23 15:35:17 +04:00
wiz
3dc0dc13ad Merge pull request #1038 from nymkappa/feature/increase-resolution-24h
Switch the 24h chart to 1 min data ticks
2021-12-22 18:33:32 +00:00
softsimon
e332789afc Bumping mempool.js to 2.3.0-dev1 and removing unused tsc build step 2021-12-22 19:33:10 +04:00
nymkappa
e4a9fd06b4 Switch the 24h chart to 1 min data ticks 2021-12-22 23:01:32 +09:00
softsimon
5845f2380e Adding sync external assets feature. 2021-12-21 02:00:50 +04:00
softsimon
c29311d831 Upgrading mempool-js with separated Liquid and Bisq 2021-12-20 23:48:26 +04:00
softsimon
252db109bc Adding icons.json to .gitignore 2021-12-20 04:01:40 +04:00
softsimon
b1c9334119 Changing API path and updating API Docs for asset icons. 2021-12-20 04:01:04 +04:00
wiz
ab04247726 Merge pull request #1033 from mempool/simon/extract-i18n
Extracting i18n string
2021-12-19 19:06:11 +00:00
softsimon
e94a85b989 Extracting i18n string 2021-12-19 22:57:31 +04:00
softsimon
a4569788f8 Liquid icons api 2021-12-19 22:09:49 +04:00
wiz
b455814e90 Merge pull request #1027 from hunicus/change-docs-layout
Revamp docs layout
2021-12-19 17:48:26 +00:00
softsimon
7afd0f3fe7 Merge pull request #1032 from mempool/wiz/update-about-page-links
Update links on About page
2021-12-19 21:36:10 +04:00
hunicus
a2a85469cf Streamline api-docs-navs conditionals 2021-12-19 12:29:52 -05:00
wiz
94488a6029 Merge pull request #1031 from mempool/wiz/update-issue-templates
Update GitHub issue templates to redirect support requests to chat
2021-12-19 17:02:57 +00:00
wiz
8e4829146a Rename About page section: Project Staff -> Project Members 2021-12-20 01:54:06 +09:00
wiz
08f185525c Update About page chat links: replace telegram with matrix 2021-12-20 01:52:58 +09:00
wiz
d6b00fe39e Update GitHub issue templates to redirect support requests to chat 2021-12-20 01:31:29 +09:00
softsimon
cec3baeaa4 Merge pull request #1024 from nymkappa/feature/blocks-mouse-scroll
User can drag the blockchain blocks horizontally with the mouse
2021-12-19 12:59:04 +04:00
nymkappa
6e59733cac User can drag the blockchain blocks horizontally with the mouse 2021-12-19 15:20:21 +09:00
hunicus
c5b705ede7 Adjust bisq cypress tests 2021-12-17 16:22:16 -05:00
hunicus
2819e24efe Remove unnecessary file change 2021-12-17 15:08:21 -05:00
hunicus
5f9bc4497a Customize mobile nav button appearance point
Since there are different numbers of topics across
bitcoin, liquid, bisq, faq, etc.
2021-12-17 14:42:21 -05:00
hunicus
086b14e816 Add various ux improvements for mobile doc menu 2021-12-17 11:42:54 -05:00
hunicus
958bfe6d25 Separate docs-nav into new component
Since same markup will be needed for desktop
and mobile menus.
2021-12-16 19:11:54 -05:00
hunicus
e01ab449cf Add skeleton for mobile docs nav 2021-12-16 18:44:39 -05:00
hunicus
9a18019d9d Add :before element for space before anchors
@angular-router's `scrollOffset` property seems to be
global, so it might mess up something else, and it also
wasn't taking effect when navigating directly to an
anchor anyway (i.e. from browser's address bar).
2021-12-16 13:20:30 -05:00
hunicus
5d8c970351 Update anchor links and add on-page links 2021-12-16 11:30:03 -05:00
hunicus
89fede9e48 Fix inconsistencies in api-docs markup 2021-12-16 09:54:07 -05:00
hunicus
f8a54784d0 Improve styling + switch section headings for tags 2021-12-16 09:54:07 -05:00
hunicus
010381aac4 Convert accordions to plain html 2021-12-16 08:46:51 -05:00
hunicus
1a8fd23b05 Add links and styling to fixed desktop docs nav 2021-12-16 00:04:47 -05:00
hunicus
3ae46e6ba1 Make desktop docs-nav sticky on scroll 2021-12-15 22:57:10 -05:00
hunicus
40f1949654 Create skeleton layout for desktop docs nav
This includes switching to a 2-column layout
(1 for nav and 1 for content) and moving footer
links to docs component so floats can be cleared
properly.
2021-12-15 13:17:37 -05:00
softsimon
2281116504 Automated database creation and migration
fixes #1002
2021-12-13 11:32:04 +04:00
35 changed files with 1738 additions and 1429 deletions

View File

@@ -1,7 +1,14 @@
---
name: 🐛 Bug Report
about: Report bugs or other issues to us on GitHub
---
<!--
SUPPORT REQUESTS: This is for reporting bugs in Mempool.
If you have a support request, please join our Keybase group:
SUPPORT REQUESTS:
This is for reporting bugs in Mempool, not for support requests.
If you have a support request, please join our Keybase or Matrix:
https://keybase.io/team/mempool
https://matrix.to/#/#mempool:bitcoin.kyoto
-->
### Description

View File

@@ -0,0 +1,28 @@
---
name: ✨ Feature Request
about: Request a feature or suggest other enhancements 💡
---
<!--
SUPPORT REQUESTS:
This is for requesting features in Mempool, not for support requests.
If you have a support request, please join our Keybase or Matrix:
https://keybase.io/team/mempool
https://matrix.to/#/#mempool:bitcoin.kyoto
-->
### Description
<!-- brief description of the feature request -->
### Problem to be solved
<!-- description of the the problem you're having -->
### Proposed solution
<!-- explain how you think we should solve the problem -->
#### Additional info
<!-- Additional information useful for implementing (e.g. docs, links, etc.) -->

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Need help? Chat with us on Matrix
url: https://matrix.to/#/#mempool:bitcoin.kyoto
about: For support requests or general questions
- name: 💬 Need help? Chat with us on Keybase
url: https://keybase.io/team/mempool
about: For support requests or general questions

7
backend/.gitignore vendored
View File

@@ -1,7 +1,10 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# production config
mempool-config.json
# production config and external assets
*.json
!mempool-config.sample.json
icons.json
# compiled output
/dist

View File

@@ -13,7 +13,8 @@
"INITIAL_BLOCKS_AMOUNT": 8,
"MEMPOOL_BLOCKS_AMOUNT": 8,
"PRICE_FEED_UPDATE_INTERVAL": 3600,
"USE_SECOND_NODE_FOR_MINFEE": false
"USE_SECOND_NODE_FOR_MINFEE": false,
"EXTERNAL_ASSETS": []
},
"CORE_RPC": {
"HOST": "127.0.0.1",

View File

@@ -0,0 +1,39 @@
import * as fs from 'fs';
import config from '../../config';
import logger from '../../logger';
class Icons {
private static FILE_NAME = './icons.json';
private iconIds: string[] = [];
private icons: { [assetId: string]: string; } = {};
constructor() {}
public loadIcons() {
if (!fs.existsSync(Icons.FILE_NAME)) {
logger.warn(`${Icons.FILE_NAME} does not exist. No Liquid icons loaded.`);
return;
}
const cacheData = fs.readFileSync(Icons.FILE_NAME, 'utf8');
this.icons = JSON.parse(cacheData);
for (const i in this.icons) {
this.iconIds.push(i);
}
logger.debug(`Liquid icons has been loaded.`);
}
public getIconByAssetId(assetId: string): Buffer | undefined {
const icon = this.icons[assetId];
if (icon) {
return Buffer.from(icon, 'base64');
}
}
public getAllIconIds() {
return this.iconIds;
}
}
export default new Icons();

View File

@@ -394,7 +394,7 @@ class Statistics {
public async $list24H(): Promise<OptimizedStatistic[]> {
try {
const connection = await DB.pool.getConnection();
const query = this.getQueryForDaysAvg(120, '1 DAY'); // 2m interval
const query = `SELECT *, UNIX_TIMESTAMP(added) as added FROM statistics ORDER BY id DESC LIMIT 1440`;
const [rows] = await connection.query<any>({ sql: query, timeout: this.queryTimeout });
connection.release();
return this.mapStatisticToOptimizedStatistic(rows);

View File

@@ -16,6 +16,7 @@ interface IConfig {
MEMPOOL_BLOCKS_AMOUNT: number;
PRICE_FEED_UPDATE_INTERVAL: number;
USE_SECOND_NODE_FOR_MINFEE: boolean;
EXTERNAL_ASSETS: string[];
};
ESPLORA: {
REST_API_URL: string;
@@ -78,6 +79,7 @@ const defaults: IConfig = {
'MEMPOOL_BLOCKS_AMOUNT': 8,
'PRICE_FEED_UPDATE_INTERVAL': 3600,
'USE_SECOND_NODE_FOR_MINFEE': false,
'EXTERNAL_ASSETS': [],
},
'ESPLORA': {
'REST_API_URL': 'http://127.0.0.1:3000',

View File

@@ -22,6 +22,8 @@ import loadingIndicators from './api/loading-indicators';
import mempool from './api/mempool';
import elementsParser from './api/liquid/elements-parser';
import databaseMigration from './api/database-migration';
import syncAssets from './sync-assets';
import icons from './api/liquid/icons';
class Server {
private wss: WebSocket.Server | undefined;
@@ -78,6 +80,7 @@ class Server {
this.setUpWebsocketHandling();
await syncAssets.syncAssets();
diskCache.loadMempoolCache();
if (config.DATABASE.ENABLED) {
@@ -93,6 +96,10 @@ class Server {
statistics.startStatistics();
}
if (config.MEMPOOL.NETWORK === 'liquid') {
icons.loadIcons();
}
fiatConversion.startService();
this.setUpHttpApiRoutes();
@@ -276,6 +283,13 @@ class Server {
;
}
if (config.MEMPOOL.NETWORK === 'liquid') {
this.app
.get(config.MEMPOOL.API_URL_PREFIX + 'assets/icons', routes.getAllLiquidIcon)
.get(config.MEMPOOL.API_URL_PREFIX + 'asset/:assetId/icon', routes.getLiquidIcon)
;
}
if (config.MEMPOOL.NETWORK === 'liquid' && config.DATABASE.ENABLED) {
this.app
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/month', routes.$getElementsPegsByMonth)

View File

@@ -19,6 +19,7 @@ import loadingIndicators from './api/loading-indicators';
import { Common } from './api/common';
import bitcoinClient from './api/bitcoin/bitcoin-client';
import elementsParser from './api/liquid/elements-parser';
import icons from './api/liquid/icons';
class Routes {
constructor() {}
@@ -807,6 +808,26 @@ class Routes {
: (e.message || 'Error'));
}
}
public getLiquidIcon(req: Request, res: Response) {
const result = icons.getIconByAssetId(req.params.assetId);
if (result) {
res.setHeader('content-type', 'image/png');
res.setHeader('content-length', result.length);
res.send(result);
} else {
res.status(404).send('Asset icon not found');
}
}
public getAllLiquidIcon(req: Request, res: Response) {
const result = icons.getAllIconIds();
if (result) {
res.json(result);
} else {
res.status(404).send('Asset icons not found');
}
}
}
export default new Routes();

View File

@@ -0,0 +1,32 @@
import axios from 'axios';
import * as fs from 'fs';
const fsPromises = fs.promises;
import config from './config';
import logger from './logger';
const PATH = './';
class SyncAssets {
constructor() { }
public async syncAssets() {
for (const url of config.MEMPOOL.EXTERNAL_ASSETS) {
await this.downloadFile(url);
}
}
private async downloadFile(url: string) {
const fileName = url.split('/').slice(-1)[0];
logger.info(`Downloading external asset: ${fileName}...`);
try {
const response = await axios.get(url, {
responseType: 'stream', timeout: 30000
});
await fsPromises.writeFile(PATH + fileName, response.data);
} catch (e: any) {
throw new Error(`Failed to download external asset. ` + e);
}
}
}
export default new SyncAssets();

View File

@@ -59,9 +59,8 @@ describe('Bisq', () => {
cy.visit(`${basePath}`);
cy.waitForSkeletonGone();
cy.get('li:nth-of-type(5) > a').click().then(() => {
cy.get('.card').should('have.length.at.least', 1);
cy.get('.card').first().click();
cy.get('.card-body');
cy.get('.section-header').should('have.length.at.least', 1);
cy.get('.endpoint-container').should('have.length.at.least', 1);
});
});

View File

@@ -26,7 +26,7 @@
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@juggle/resize-observer": "^3.3.1",
"@mempool/mempool.js": "^2.2.4",
"@mempool/mempool.js": "2.3.0-dev1",
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@nguniversal/express-engine": "11.2.1",
"@types/qrcode": "1.4.1",
@@ -3230,12 +3230,40 @@
"integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw=="
},
"node_modules/@mempool/mempool.js": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.2.4.tgz",
"integrity": "sha512-G9Ga2jHLfAuU/qXikRBtTecYr7BhLJH1WbIahefnGpgP48DCQaj1jizvuRZHhoElUvUT5flRt/O9kLjlbToqhw==",
"version": "2.3.0-dev1",
"resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.3.0-dev1.tgz",
"integrity": "sha512-+UYGuG8qqdgrtC4J94hCs7+Dry8OprIixEarIC6rww1Nb5POz8n3NTDH8to1r0XLjPr+Du6/OX8fEN1QW94rNA==",
"dependencies": {
"axios": "^0.21.1",
"ws": "^7.4.3"
"axios": "0.24.0",
"ws": "8.3.0"
}
},
"node_modules/@mempool/mempool.js/node_modules/axios": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"dependencies": {
"follow-redirects": "^1.14.4"
}
},
"node_modules/@mempool/mempool.js/node_modules/ws": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/@ng-bootstrap/ng-bootstrap": {
@@ -4541,6 +4569,7 @@
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"devOptional": true,
"dependencies": {
"follow-redirects": "^1.14.0"
}
@@ -7264,7 +7293,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=0.3.1"
}
@@ -9122,7 +9151,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=4"
}
@@ -9131,7 +9160,7 @@
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"devOptional": true,
"dev": true,
"dependencies": {
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
@@ -9416,7 +9445,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"devOptional": true,
"dev": true,
"dependencies": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
@@ -10385,7 +10414,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"devOptional": true
"dev": true
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
@@ -10453,7 +10482,7 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"devOptional": true,
"dev": true,
"dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
@@ -17962,6 +17991,7 @@
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"devOptional": true,
"engines": {
"node": ">=8.3.0"
}
@@ -20409,12 +20439,28 @@
"integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw=="
},
"@mempool/mempool.js": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.2.4.tgz",
"integrity": "sha512-G9Ga2jHLfAuU/qXikRBtTecYr7BhLJH1WbIahefnGpgP48DCQaj1jizvuRZHhoElUvUT5flRt/O9kLjlbToqhw==",
"version": "2.3.0-dev1",
"resolved": "https://registry.npmjs.org/@mempool/mempool.js/-/mempool.js-2.3.0-dev1.tgz",
"integrity": "sha512-+UYGuG8qqdgrtC4J94hCs7+Dry8OprIixEarIC6rww1Nb5POz8n3NTDH8to1r0XLjPr+Du6/OX8fEN1QW94rNA==",
"requires": {
"axios": "^0.21.1",
"ws": "^7.4.3"
"axios": "0.24.0",
"ws": "8.3.0"
},
"dependencies": {
"axios": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"requires": {
"follow-redirects": "^1.14.4"
}
},
"ws": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"requires": {}
}
}
},
"@ng-bootstrap/ng-bootstrap": {
@@ -21532,6 +21578,7 @@
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"devOptional": true,
"requires": {
"follow-redirects": "^1.14.0"
}
@@ -23795,7 +23842,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true
"dev": true
},
"diffie-hellman": {
"version": "5.0.3",
@@ -25290,13 +25337,13 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
"devOptional": true
"dev": true
},
"har-validator": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"devOptional": true,
"dev": true,
"requires": {
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
@@ -25544,7 +25591,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"devOptional": true,
"dev": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
@@ -26286,7 +26333,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"devOptional": true
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
@@ -26339,7 +26386,7 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"devOptional": true,
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
@@ -32158,7 +32205,8 @@
"ws": {
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"devOptional": true
},
"xhr2": {
"version": "0.2.0",

View File

@@ -34,7 +34,10 @@
"sync-assets": "node sync-assets.js && rsync -av ./dist/mempool/browser/en-US/resources ./dist/mempool/browser/resources",
"sync-assets-dev": "node sync-assets.js dev",
"generate-config": "node generate-config.js",
"build-mempool.js": "tsc | browserify -p tinyify ./node_modules/@mempool/mempool.js/lib/index.js --standalone mempoolJS > ./dist/mempool/browser/en-US/mempool.js",
"build-mempool.js": "npm run build-mempool-js && npm run build-mempool-liquid-js && npm run build-mempool-bisq-js",
"build-mempool-js": "browserify -p tinyify ./node_modules/@mempool/mempool.js/lib/index.js --standalone mempoolJS > ./dist/mempool/browser/en-US/mempool.js",
"build-mempool-bisq-js": "browserify -p tinyify ./node_modules/@mempool/mempool.js/lib/index-bisq.js --standalone bisqJS > ./dist/mempool/browser/en-US/bisq.js",
"build-mempool-liquid-js": "browserify -p tinyify ./node_modules/@mempool/mempool.js/lib/index-liquid.js --standalone liquidJS > ./dist/mempool/browser/en-US/liquid.js",
"test": "ng test",
"lint": "ng lint",
"e2e": "npm run generate-config && ng e2e",
@@ -70,7 +73,7 @@
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@juggle/resize-observer": "^3.3.1",
"@mempool/mempool.js": "^2.2.4",
"@mempool/mempool.js": "2.3.0-dev1",
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@nguniversal/express-engine": "11.2.1",
"@types/qrcode": "1.4.1",

View File

@@ -48,9 +48,10 @@ import { FeesBoxComponent } from './components/fees-box/fees-box.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { faFilter, faAngleDown, faAngleUp, faAngleRight, faAngleLeft, faBolt, faChartArea, faCogs, faCubes, faDatabase, faExchangeAlt, faInfoCircle,
faLink, faList, faSearch, faCaretUp, faCaretDown, faTachometerAlt, faThList, faTint, faTv, faAngleDoubleDown, faSortUp, faAngleDoubleUp, faChevronDown, faFileAlt, faRedoAlt, faArrowAltCircleRight, faExternalLinkAlt, faBook } from '@fortawesome/free-solid-svg-icons';
faLink, faList, faSearch, faCaretUp, faCaretDown, faTachometerAlt, faThList, faTint, faTv, faAngleDoubleDown, faSortUp, faAngleDoubleUp, faChevronDown, faFileAlt, faRedoAlt, faArrowAltCircleRight, faExternalLinkAlt, faBook, faListUl } from '@fortawesome/free-solid-svg-icons';
import { ApiDocsComponent } from './components/docs/api-docs.component';
import { DocsComponent } from './components/docs/docs.component';
import { ApiDocsNavComponent } from './components/docs/api-docs-nav.component';
import { CodeTemplateComponent } from './components/docs/code-template.component';
import { TermsOfServiceComponent } from './components/terms-of-service/terms-of-service.component';
import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component';
@@ -59,6 +60,7 @@ import { StorageService } from './services/storage.service';
import { HttpCacheInterceptor } from './services/http-cache.interceptor';
import { SponsorComponent } from './components/sponsor/sponsor.component';
import { PushTransactionComponent } from './components/push-transaction/push-transaction.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
declarations: [
@@ -102,6 +104,7 @@ import { PushTransactionComponent } from './components/push-transaction/push-tra
SponsorComponent,
PushTransactionComponent,
DocsComponent,
ApiDocsNavComponent,
],
imports: [
BrowserModule.withServerTransition({ appId: 'serverApp' }),
@@ -111,6 +114,7 @@ import { PushTransactionComponent } from './components/push-transaction/push-tra
BrowserAnimationsModule,
InfiniteScrollModule,
NgbTypeaheadModule,
NgbModule,
FontAwesomeModule,
SharedModule,
NgxEchartsModule.forRoot({
@@ -161,5 +165,6 @@ export class AppModule {
library.addIcons(faAngleRight);
library.addIcons(faAngleLeft);
library.addIcons(faBook);
library.addIcons(faListUl);
}
}

View File

@@ -23,12 +23,12 @@
<a target="_blank" href="https://twitter.com/mempool">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="twitter" class="svg-inline--fa fa-twitter fa-w-16 fa-4x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path></svg>
</a>
<a target="_blank" href="https://t.me/mempoolspace">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="telegram-plane" class="svg-inline--fa fa-telegram-plane fa-w-14 fa-4x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"></path></svg>
</a>
<a target="_blank" href="https://keybase.io/team/mempool">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="keybase" class="svg-inline--fa fa-keybase fa-w-14 fa-4x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M286.17 419a18 18 0 1 0 18 18 18 18 0 0 0-18-18zm111.92-147.6c-9.5-14.62-39.37-52.45-87.26-73.71q-9.1-4.06-18.38-7.27a78.43 78.43 0 0 0-47.88-104.13c-12.41-4.1-23.33-6-32.41-5.77-.6-2-1.89-11 9.4-35L198.66 32l-5.48 7.56c-8.69 12.06-16.92 23.55-24.34 34.89a51 51 0 0 0-8.29-1.25c-41.53-2.45-39-2.33-41.06-2.33-50.61 0-50.75 52.12-50.75 45.88l-2.36 36.68c-1.61 27 19.75 50.21 47.63 51.85l8.93.54a214 214 0 0 0-46.29 35.54C14 304.66 14 374 14 429.77v33.64l23.32-29.8a148.6 148.6 0 0 0 14.56 37.56c5.78 10.13 14.87 9.45 19.64 7.33 4.21-1.87 10-6.92 3.75-20.11a178.29 178.29 0 0 1-15.76-53.13l46.82-59.83-24.66 74.11c58.23-42.4 157.38-61.76 236.25-38.59 34.2 10.05 67.45.69 84.74-23.84.72-1 1.2-2.16 1.85-3.22a156.09 156.09 0 0 1 2.8 28.43c0 23.3-3.69 52.93-14.88 81.64-2.52 6.46 1.76 14.5 8.6 15.74 7.42 1.57 15.33-3.1 18.37-11.15C429 443 434 414 434 382.32c0-38.58-13-77.46-35.91-110.92zM142.37 128.58l-15.7-.93-1.39 21.79 13.13.78a93 93 0 0 0 .32 19.57l-22.38-1.34a12.28 12.28 0 0 1-11.76-12.79L107 119c1-12.17 13.87-11.27 13.26-11.32l29.11 1.73a144.35 144.35 0 0 0-7 19.17zm148.42 172.18a10.51 10.51 0 0 1-14.35-1.39l-9.68-11.49-34.42 27a8.09 8.09 0 0 1-11.13-1.08l-15.78-18.64a7.38 7.38 0 0 1 1.34-10.34l34.57-27.18-14.14-16.74-17.09 13.45a7.75 7.75 0 0 1-10.59-1s-3.72-4.42-3.8-4.53a7.38 7.38 0 0 1 1.37-10.34L214 225.19s-18.51-22-18.6-22.14a9.56 9.56 0 0 1 1.74-13.42 10.38 10.38 0 0 1 14.3 1.37l81.09 96.32a9.58 9.58 0 0 1-1.74 13.44zM187.44 419a18 18 0 1 0 18 18 18 18 0 0 0-18-18z"></path></svg>
</a>
<a target="_blank" href="https://matrix.to/#/#mempool:bitcoin.kyoto">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="matrix" class="svg-inline--fa fa-matrix fa-w-16 fa-4x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1536 1792"><path fill="currentColor" d="M40.467 163.152v1465.696H145.92V1664H0V128h145.92v35.152zm450.757 464.64v74.14h2.069c19.79-28.356 43.717-50.215 71.483-65.575 27.765-15.656 59.963-23.336 96-23.336 34.56 0 66.165 6.795 94.818 20.086 28.652 13.293 50.216 37.22 65.28 70.893 16.246-23.926 38.4-45.194 66.166-63.507 27.766-18.314 60.848-27.472 98.954-27.472 28.948 0 55.828 3.545 80.64 10.635 24.812 7.088 45.785 18.314 63.508 33.968 17.722 15.656 31.31 35.742 41.354 60.85 9.747 25.107 14.768 55.236 14.768 90.683v366.573h-150.35V865.28c0-18.314-.59-35.741-2.068-51.987-1.476-16.247-5.316-30.426-11.52-42.24-6.499-12.112-15.656-21.563-28.062-28.653-12.405-7.088-29.242-10.634-50.214-10.634-21.268 0-38.4 4.135-51.397 12.112-12.997 8.27-23.336 18.608-30.72 31.901-7.386 12.997-12.407 27.765-14.77 44.602-2.363 16.542-3.84 33.379-3.84 50.216v305.133H692.971v-307.2c0-16.247-.294-32.197-1.18-48.149-.591-15.95-3.84-30.424-9.157-44.011-5.317-13.293-14.178-24.223-26.585-32.197-12.406-7.976-30.425-12.112-54.646-12.112-7.088 0-16.542 1.478-28.062 4.726-11.52 3.25-23.04 9.157-33.968 18.02-10.93 8.86-20.383 21.563-28.063 38.103-7.68 16.543-11.52 38.4-11.52 65.28v317.834H349.44V627.792zm1004.309 1001.056V163.152H1390.08V128H1536v1536h-145.92v-35.152z"/></svg>
</a>
</div>
<div class="enterprise-sponsor">
@@ -178,7 +178,7 @@
</div>
<div class="maintainers" *ngIf="contributors.core.length">
<h3 i18n="about.project_staff">Project Staff</h3>
<h3 i18n="about.project_members">Project Members</h3>
<div class="wrapper">
<ng-template ngFor let-contributor [ngForOf]="contributors.core">
<a [href]="'https://github.com/' + contributor.name" target="_blank" [title]="contributor.name">

View File

@@ -1,7 +1,8 @@
<div class="blocks-container blockchain-blocks-container" *ngIf="(loadingBlocks$ | async) === false; else loadingBlocksTemplate">
<div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn" >
<div class="text-center bitcoin-block mined-block blockchain-blocks-{{ i }}" id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]" [class.blink-bg]="(specialBlocks[block.height] !== undefined)">
<a [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }" class="blockLink">&nbsp;</a>
<a draggable="false" [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }"
class="blockLink" [ngClass]="{'disabled': (this.stateService.blockScrolling$ | async)}">&nbsp;</a>
<div class="block-height">
<a [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a>
</div>

View File

@@ -15,6 +15,10 @@
text-decoration: none;
}
.blockLink.disabled {
pointer-events: none;
}
.mined-block {
position: absolute;
top: 0px;

View File

@@ -41,7 +41,7 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
};
constructor(
private stateService: StateService,
public stateService: StateService,
private router: Router,
private cd: ChangeDetectorRef,
) { }

View File

@@ -18,6 +18,11 @@
.blockchain-wrapper {
overflow: hidden;
height: 250px;
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+/Edge */
user-select: none; /* Standard */
}
.position-container {

View File

@@ -0,0 +1,76 @@
<ng-template [ngIf]="network.val !== 'bisq' && network.val !== 'liquid'">
<p>General</p>
<a [routerLink]="['./']" fragment="get-difficulty-adjustment" (click)="collapseItem.toggle()">GET Difficulty Adjustment</a>
</ng-template>
<ng-template [ngIf]="network.val === 'bisq'">
<p>Markets</p>
<a [routerLink]="['./']" fragment="get-market-currencies" (click)="collapseItem.toggle()">GET Market Currencies</a>
<a [routerLink]="['./']" fragment="get-market-depth" (click)="collapseItem.toggle()">GET Market Depth</a>
<a [routerLink]="['./']" fragment="get-market-hloc" (click)="collapseItem.toggle()">GET Market HLOC</a>
<a [routerLink]="['./']" fragment="get-markets" (click)="collapseItem.toggle()">GET Markets</a>
<a [routerLink]="['./']" fragment="get-market-offers" (click)="collapseItem.toggle()">GET Market Offers</a>
<a [routerLink]="['./']" fragment="get-market-ticker" (click)="collapseItem.toggle()">GET Market Ticker</a>
<a [routerLink]="['./']" fragment="get-market-trades" (click)="collapseItem.toggle()">GET Market Trades</a>
<a [routerLink]="['./']" fragment="get-market-volumes" (click)="collapseItem.toggle()">GET Market Volumes</a>
</ng-template>
<ng-template [ngIf]="network.val === 'bisq'">
<p>General</p>
<a [routerLink]="['./']" fragment="get-stats" (click)="collapseItem.toggle()">GET Stats</a>
</ng-template>
<p>Addresses</p>
<a [routerLink]="['./']" fragment="get-address" (click)="collapseItem.toggle()">GET Address</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-address-transactions" (click)="collapseItem.toggle()">GET Address Transactions</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-address-transactions-chain" (click)="collapseItem.toggle()">GET Address Transactions Chain</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-address-transactions-mempool" (click)="collapseItem.toggle()">GET Address Transactions Mempool</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-address-utxo" (click)="collapseItem.toggle()">GET Address UTXO</a>
<ng-template [ngIf]="network.val === 'liquid'">
<p>Assets</p>
<a [routerLink]="['./']" fragment="get-assets" (click)="collapseItem.toggle()">GET Assets</a>
<a [routerLink]="['./']" fragment="get-assets-icons" (click)="collapseItem.toggle()">GET Assets Icons</a>
<a [routerLink]="['./']" fragment="get-asset-transactions" (click)="collapseItem.toggle()">GET Asset Transactions</a>
<a [routerLink]="['./']" fragment="get-asset-supply" (click)="collapseItem.toggle()">GET Asset Supply</a>
<a [routerLink]="['./']" fragment="get-asset-icon" (click)="collapseItem.toggle()">GET Asset Icon</a>
</ng-template>
<p>Blocks</p>
<a [routerLink]="['./']" fragment="get-block" (click)="collapseItem.toggle()">GET Block</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-header" (click)="collapseItem.toggle()">GET Block Header</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-height" (click)="collapseItem.toggle()">GET Block Height</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-raw" (click)="collapseItem.toggle()">GET Block Raw</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-status" (click)="collapseItem.toggle()">GET Block Status</a>
<a [routerLink]="['./']" fragment="get-block-tip-height" (click)="collapseItem.toggle()">GET Block Tip Height</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-tip-hash" (click)="collapseItem.toggle()">GET Block Tip Hash</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-transaction-id" (click)="collapseItem.toggle()">GET Block Transaction ID</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-transaction-ids" (click)="collapseItem.toggle()">GET Block Transaction IDs</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-block-transactions" (click)="collapseItem.toggle()">GET Block Transactions</a>
<a [routerLink]="['./']" fragment="get-blocks" (click)="collapseItem.toggle()">GET Blocks</a>
<ng-template [ngIf]="network.val !== 'bisq'">
<p>Fees</p>
<a [routerLink]="['./']" fragment="get-mempool-blocks-fees" (click)="collapseItem.toggle()">GET Mempool Blocks Fees</a>
<a [routerLink]="['./']" fragment="get-recommended-fees" (click)="collapseItem.toggle()">GET Recommended Fees</a>
</ng-template>
<ng-template [ngIf]="network.val !== 'bisq'">
<p>Mempool</p>
<a [routerLink]="['./']" fragment="get-mempool" (click)="collapseItem.toggle()">GET Mempool</a>
<a [routerLink]="['./']" fragment="get-mempool-transaction-ids" (click)="collapseItem.toggle()">GET Mempool Transaction IDs</a>
<a [routerLink]="['./']" fragment="get-mempool-recent" (click)="collapseItem.toggle()">GET Mempool Recent</a>
</ng-template>
<p>Transactions</p>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-cpfp" (click)="collapseItem.toggle()">GET Children Pay for Parent</a>
<a [routerLink]="['./']" fragment="get-transaction" (click)="collapseItem.toggle()">GET Transaction</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-hex" (click)="collapseItem.toggle()">GET Transaction Hex</a>
<a *ngIf="network.val !== 'bisq' && network.val !== 'liquid'" [routerLink]="['./']" fragment="get-transaction-merkleblock-proof" (click)="collapseItem.toggle()">GET Transaction Merkleblock Proof</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-merkle-proof" (click)="collapseItem.toggle()">GET Transaction Merkle Proof</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-outspend" (click)="collapseItem.toggle()">GET Transaction Outspend</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-outspends" (click)="collapseItem.toggle()">GET Transaction Outspends</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-raw" (click)="collapseItem.toggle()">GET Transaction Raw</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="get-transaction-status" (click)="collapseItem.toggle()">GET Transaction Status</a>
<a *ngIf="network.val === 'bisq'" [routerLink]="['./']" fragment="get-transactions" (click)="collapseItem.toggle()">GET Transactions</a>
<a *ngIf="network.val !== 'bisq'" [routerLink]="['./']" fragment="post-transaction" (click)="collapseItem.toggle()">POST Transaction</a>

View File

@@ -0,0 +1,17 @@
p {
color: #4a68b9;
font-weight: 700;
margin: 10px 0;
margin: 15px 0 10px 0;
}
p:first-child {
margin-top: 0
}
a {
color: #fff;
text-decoration: none;
display: block;
margin: 5px 0;
}

View File

@@ -0,0 +1,18 @@
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-api-docs-nav',
templateUrl: './api-docs-nav.component.html',
styleUrls: ['./api-docs-nav.component.scss']
})
export class ApiDocsNavComponent implements OnInit {
@Input() network: any;
@Input() collapseItem: any = { toggle: () => {} };
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -3,18 +3,31 @@
<div id="restAPI" *ngIf="restTabActivated">
<p>Reference for the {{ network.val === '' ? 'Bitcoin' : network.val.charAt(0).toUpperCase() + network.val.slice(1) }} <ng-container i18n="api-docs.title">API service</ng-container>.</p>
<div id="doc-nav-desktop" class="hide-on-mobile" [ngClass]="desktopDocsNavPosition">
<app-api-docs-nav [network]="{ val: network$ | async }"></app-api-docs-nav>
</div>
<div class="doc-content">
<p class="hide-on-mobile no-bottom-space">Reference for the {{ network.val === '' ? 'Bitcoin' : network.val.charAt(0).toUpperCase() + network.val.slice(1) }} <ng-container i18n="api-docs.title">API service</ng-container>.</p>
<div id="doc-nav-mobile" class="hide-on-desktop" *ngIf="showFloatingDocsNav">
<button type="button" class="btn btn-outline-primary" (click)="collapse.toggle()" [attr.aria-expanded]="mobileMenuOpen" aria-controls="collapseExample"><fa-icon [icon]="['fas', 'list-ul']" [fixedWidth]="true"></fa-icon> {{ network.val === '' ? 'Bitcoin' : network.val.charAt(0).toUpperCase() + network.val.slice(1) }} REST API Overview</button>
<div #collapse="ngbCollapse" [(ngbCollapse)]="mobileMenuOpen">
<div class="card">
<div class="card-body">
<app-api-docs-nav [collapseItem]="collapse" [network]="{ val: network$ | async }"></app-api-docs-nav>
</div>
</div>
</div>
</div>
<div id="mobile-top-doc-nav" #mobileFixedApiNav class="hide-on-desktop"><app-api-docs-nav [network]="{ val: network$ | async }"></app-api-docs-nav></div>
<div class="api-category" *ngIf="network.val !== 'bisq' && network.val !== 'liquid'">
<h4 i18n="api-docs.tab.general|API Docs tab for General">General</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark">
<ngb-panel id="difficultyAdjustment" *ngIf="network.val !== 'liquid'">
<ng-template ngbPanelTitle>
<span>GET Difficulty Adjustment</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="difficulty">
<div class="endpoint-container" id="get-difficulty-adjustment">
<a class="section-header" [routerLink]="['./']" fragment="get-difficulty-adjustment">GET Difficulty Adjustment <span>General</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.difficulty)" target="_blank">GET {{ baseNetworkUrl }}/api/v1/difficulty-adjustment</a>
@@ -25,21 +38,13 @@
</div>
<app-code-template [hostname]="hostname" [code]="code.difficulty" [network]="network.val" ></app-code-template>
</div>
</ng-template>
</ngb-panel>
</ngb-accordion>
</div>
<div class="api-category" *ngIf="network.val === 'bisq'">
<h4 i18n="Bisq All Markets">Markets</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="bisqMarketsCurrencies">
<ng-template ngbPanelTitle>
<span>GET Market Currencies</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-currencies">
<a class="section-header" [routerLink]="['./']" fragment="get-market-currencies">GET Market Currencies <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketsCurrencies)" target="_blank">GET {{ baseNetworkUrl }}/api/currencies</a>
@@ -49,14 +54,10 @@
<div i18n>Provides list of available currencies for a given base currency. </div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketsCurrencies" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="marketDepth">
<ng-template ngbPanelTitle>
<span>GET Market Depth</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-depth">
<a class="section-header" [routerLink]="['./']" fragment="get-market-depth">GET Market Depth <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketDepth)" target="_blank">GET {{ baseNetworkUrl }}/api/depth?market=[:market]</a>
@@ -66,14 +67,10 @@
<div i18n>Provides list of open offer prices for a single market.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketDepth" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsHloc">
<ng-template ngbPanelTitle>
<span>GET Market HLOC</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-hloc">
<a class="section-header" [routerLink]="['./']" fragment="get-market-hloc">GET Market HLOC <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketHloc)" target="_blank">GET {{ baseNetworkUrl }}/api/hloc?market=[:market]</a>
@@ -83,14 +80,10 @@
<div i18n>Provides hi/low/open/close data for a given market. This can be used to generate a candlestick chart.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketHloc" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsMarkets">
<ng-template ngbPanelTitle>
<span>GET Markets</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-markets">
<a class="section-header" [routerLink]="['./']" fragment="get-markets">GET Markets <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.markets)" target="_blank">GET {{ baseNetworkUrl }}/api/markets</a>
@@ -100,14 +93,10 @@
<div i18n>Provides list of available markets.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.markets" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsOffers">
<ng-template ngbPanelTitle>
<span>GET Market Offers</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-offers">
<a class="section-header" [routerLink]="['./']" fragment="get-market-offers">GET Market Offers <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketOffers)" target="_blank">GET {{ baseNetworkUrl }}/api/offers?market=[:market]</a>
@@ -117,14 +106,10 @@
<div i18n>Provides list of open offer details for a single market.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketOffers" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsTicker">
<ng-template ngbPanelTitle>
<span>GET Market Ticker</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-ticker">
<a class="section-header" [routerLink]="['./']" fragment="get-market-ticker">GET Market Ticker <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketTicker)" target="_blank">GET {{ baseNetworkUrl }}/api/ticker?market=[:market]</a>
@@ -134,14 +119,10 @@
<div i18n>Provides 24 hour price ticker for single market or all markets</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketTicker" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsTrades">
<ng-template ngbPanelTitle>
<span>GET Market Trades</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-trades">
<a class="section-header" [routerLink]="['./']" fragment="get-market-trades">GET Market Trades <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketTrades)" target="_blank">GET {{ baseNetworkUrl }}/api/trades?market=[:market]&limit=[:limit]</a>
@@ -151,14 +132,10 @@
<div i18n>Provides list of completed trades for a single market.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketTrades" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="bisqMarketsVolumes">
<ng-template ngbPanelTitle>
<span>GET Market Volumes</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-market-volumes">
<a class="section-header" [routerLink]="['./']" fragment="get-market-volumes">GET Market Volumes <span>Markets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.marketVolumes)" target="_blank">GET {{ baseNetworkUrl }}/api/volumes?basecurrency=[:basecurrency]</a>
@@ -168,21 +145,14 @@
<div i18n>Provides periodic volume data in terms of base currency for one or all markets.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.marketVolumes" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category" *ngIf="network.val === 'bisq'">
<h4 ngbNavLink i18n="api-docs.tab.bsq|API Docs tab for BSQ">General</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="bisqStats">
<ng-template ngbPanelTitle>
<span>GET Stats</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-stats">
<a class="section-header" [routerLink]="['./']" fragment="get-stats">GET Stats <span>General</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.stats)" target="_blank'" target="_blank">GET {{ baseNetworkUrl }}/api/stats</a>
@@ -192,21 +162,14 @@
<div i18n>Returns statistics about all Bisq transactions.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.stats" [network]="network.val"></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category">
<h4 i18n="api-docs.tab.addresses|API Docs tab for Addresses">Addresses</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="address">
<ng-template ngbPanelTitle>
<span>GET Address</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-address">
<a class="section-header" [routerLink]="['./']" fragment="get-address">GET Address <span>Addresses</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.address)" target="_blank">GET {{ baseNetworkUrl }}/api/address/:address</a>
@@ -216,14 +179,10 @@
<div i18n>Returns details about an address. Available fields: <code>address</code>, <code>chain_stats</code>, and <code>mempool_stats</code>. {{ '{' }}chain,mempool{{ '}' }}_stats each contain an object with <code>tx_count</code>, <code>funded_txo_count</code>, <code>funded_txo_sum</code>, <code>spent_txo_count</code>, and <code>spent_txo_sum</code>.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.address" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="addressTransactions">
<ng-template ngbPanelTitle>
<span>GET Address Transactions</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-address-transactions">
<a class="section-header" [routerLink]="['./']" fragment="get-address-transactions">GET Address Transactions <span>Addresses</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.addressTransactions)" target="_blank">GET {{ baseNetworkUrl }}/api/address/:address/txs</a>
@@ -233,14 +192,10 @@
<div i18n>Get transaction history for the specified address/scripthash, sorted with newest first. Returns up to 50 mempool transactions plus the first 25 confirmed transactions. You can request more confirmed transactions using <code>:last_seen_txid</code> (see below).</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.addressTransactions" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="addressTransactionsChain">
<ng-template ngbPanelTitle>
<span>GET Address Transactions Chain</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-address-transactions-chain">
<a class="section-header" [routerLink]="['./']" fragment="get-address-transactions-chain">GET Address Transactions Chain <span>Addresses</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.addressTransactionsChain)" target="_blank">GET {{ baseNetworkUrl }}/api/address/:address/txs/chain</a>
@@ -250,14 +205,10 @@
<div i18n>Get confirmed transaction history for the specified address/scripthash, sorted with newest first. Returns 25 transactions per page. More can be requested by specifying the last txid seen by the previous query.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.addressTransactionsChain" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="addressTransactionsMempool">
<ng-template ngbPanelTitle>
<span>GET Address Transactions Mempool</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-address-transactions-mempool">
<a class="section-header" [routerLink]="['./']" fragment="get-address-transactions-mempool">GET Address Transactions Mempool <span>Addresses</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.addressTransactionsMempool)" target="_blank">GET {{ baseNetworkUrl }}/api/address/:address/txs/mempool</a>
@@ -267,14 +218,10 @@
<div i18n>Get unconfirmed transaction history for the specified address/scripthash. Returns up to 50 transactions (no paging).</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.addressTransactionsMempool" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="addressUTXO">
<ng-template ngbPanelTitle>
<span>GET Address UTXO</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-address-utxo">
<a class="section-header" [routerLink]="['./']" fragment="get-address-utxo">GET Address UTXO <span>Addresses</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.addressUTXO)" target="_blank">GET {{ baseNetworkUrl }}/api/address/:address/utxo</a>
@@ -284,21 +231,14 @@
<div i18n>Get the list of unspent transaction outputs associated with the address/scripthash. Available fields: <code>txid</code>, <code>vout</code>, <code>value</code>, and <code>status</code> (with the status of the funding tx).<ng-container *ngIf="network.val === 'liquid'">There is also a <code>valuecommitment</code> field that may appear in place of <code>value</code>, plus the following additional fields: <code>asset</code>/<code>assetcommitment</code>, <code>nonce</code>/<code>noncecommitment</code>, <code>surjection_proof</code>, and <code>range_proof</code>.</ng-container></div>
</div>
<app-code-template [hostname]="hostname" [code]="code.addressUTXO" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category" *ngIf="network.val === 'liquid'">
<h4 i18n="api-docs.tab.assets|API Docs tab for Assets">Assets</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="assets">
<ng-template ngbPanelTitle>
<span>GET Assets</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-assets">
<a class="section-header" [routerLink]="['./']" fragment="get-assets">GET Assets <span>Assets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.assets)" target="_blank">GET /liquid/api/asset/:asset_id</a>
@@ -308,14 +248,10 @@
<div i18n>Returns information about a Liquid asset.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.assets" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="assetTransactions">
<ng-template ngbPanelTitle>
<span>GET Asset Transactions</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-asset-transactions">
<a class="section-header" [routerLink]="['./']" fragment="get-asset-transactions">GET Asset Transactions <span>Assets</span></a>
<div class="endpoint">
<a [href]="wrapUrl(network.val, code.assetTransactions)" target="_blank">GET /liquid/api/asset/:asset_id/txs[/mempool|/chain]</a>
</div>
@@ -324,14 +260,10 @@
<div i18n>Returns transactions associated with the specified Liquid asset. For the network's native asset, returns a list of peg in, peg out, and burn transactions. For user-issued assets, returns a list of issuance, reissuance, and burn transactions. Does not include regular transactions transferring this asset.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.assetTransactions" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="assetSupply">
<ng-template ngbPanelTitle>
<span>GET Asset Supply</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-asset-supply">
<a class="section-header" [routerLink]="['./']" fragment="get-asset-supply">GET Asset Supply <span>Assets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.assetSupply)" target="_blank">GET /liquid/api/asset/:asset_id/supply[/decimal]</a>
@@ -341,21 +273,40 @@
<div i18n>Get the current total supply of the specified asset. For the native asset (L-BTC), this is calculated as [chain,mempool]_stats.peg_in_amount - [chain,mempool]_stats.peg_out_amount - [chain,mempool]_stats.burned_amount. For issued assets, this is calculated as [chain,mempool]_stats.issued_amount - [chain,mempool]_stats.burned_amount. Not available for assets with blinded issuances. If /decimal is specified, returns the supply as a decimal according to the asset's divisibility. Otherwise, returned in base units.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.assetSupply" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<div class="endpoint-container" id="get-assets-icons">
<a class="section-header" [routerLink]="['./']" fragment="get-assets-icons">GET Asset Icons <span>Assets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.assetIcons)" target="_blank">GET /liquid/api/v1/assets/icons</a>
</div>
<div class="description">
<div class="subtitle" i18n>Description</div>
<div>Get all the Asset IDs that has icons.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.assetIcons" [network]="network.val" ></app-code-template>
</div>
<div class="endpoint-container" id="get-asset-icon">
<a class="section-header" [routerLink]="['./']" fragment="get-asset-icon">GET Asset Icon <span>Assets</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.assetIcon)" target="_blank">GET /liquid/api/v1/asset/:asset_id/icon</a>
</div>
<div class="description">
<div class="subtitle" i18n>Description</div>
<div>Get the icon of the specified asset.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.assetIcon" [network]="network.val" ></app-code-template>
</div>
</ngb-accordion>
</div>
<div class="api-category">
<h4 i18n="api-docs.tab.blocks|API Docs tab for Blocks">Blocks</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="block">
<ng-template ngbPanelTitle>
<span>GET Block</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-block">
<a class="section-header" [routerLink]="['./']" fragment="get-block">GET Block <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.block)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash</a>
@@ -365,14 +316,10 @@
<div i18n>Returns details about a block. Available fields: <code>id</code>, <code>height</code>, <code>version</code>, <code>timestamp</code>, <code>bits</code>, <code>nonce</code>, <code>merkle_root</code>, <code>tx_count</code>, <code>size</code>, <code>weight</code>,<ng-container *ngIf="network.val === 'liquid'"> <code>proof</code>,</ng-container> and <code>previousblockhash</code>.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.block" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockHeader">
<ng-template ngbPanelTitle>
<span>GET Block Header</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-header">
<a class="section-header" [routerLink]="['./']" fragment="get-block-header">GET Block Header <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockHeader)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/header</a>
@@ -382,14 +329,10 @@
<div i18n>Returns the hex-encoded block header.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockHeader" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockHeight">
<ng-template ngbPanelTitle>
<span>GET Block Height</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-height">
<a class="section-header" [routerLink]="['./']" fragment="get-block-height">GET Block Height <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockHeader)" target="_blank">GET {{ baseNetworkUrl }}/api/block-height/:height</a>
@@ -399,15 +342,12 @@
<div i18n>Returns the hash of the block currently at <code>:height</code>.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockHeight" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockRaw">
<ng-template ngbPanelTitle>
<span>GET Block Raw</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-raw">
<a class="section-header" [routerLink]="['./']" fragment="get-block-raw">GET Block Raw <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockRaw)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/raw</a>
</div>
<div class="description">
@@ -415,15 +355,10 @@
<div i18n>Returns the raw block representation in binary.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockRaw" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockStatus">
<ng-template ngbPanelTitle>
<span>GET Block Status</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="title">Get Block Status</div>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-status">
<a class="section-header" [routerLink]="['./']" fragment="get-block-status">GET Block Status <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockStatus)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/status</a>
@@ -433,14 +368,10 @@
<div i18n>Returns the confirmation status of a block. Available fields: <code>in_best_chain</code> (boolean, false for orphaned blocks), <code>next_best</code> (the hash of the next block, only available for blocks in the best chain).</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockStatus" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="blockTipHeight">
<ng-template ngbPanelTitle>
<span>GET Block Tip Height</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-block-tip-height">
<a class="section-header" [routerLink]="['./']" fragment="get-block-tip-height">GET Block Tip Height <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockTipHeight)" target="_blank">GET {{ baseNetworkUrl }}/api/blocks/tip/height</a>
@@ -450,14 +381,10 @@
<div i18n>Returns the height of the last block.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockTipHeight" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockTipHash">
<ng-template ngbPanelTitle>
<span>GET Block Tip Hash</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-tip-hash">
<a class="section-header" [routerLink]="['./']" fragment="get-block-tip-hash">GET Block Tip Hash <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockTipHash)" target="_blank">GET {{ baseNetworkUrl }}/api/blocks/tip/hash</a>
@@ -467,14 +394,10 @@
<div i18n>Returns the hash of the last block.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockTipHash" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockTxId">
<ng-template ngbPanelTitle>
<span>GET Block Transaction ID</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-transaction-id">
<a class="section-header" [routerLink]="['./']" fragment="get-block-transaction-id">GET Block Transaction ID <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockTxId)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/txid/:index</a>
@@ -484,14 +407,10 @@
<div i18n>Returns the transaction at index <code>:index</code> within the specified block.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockTxId" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockTxIds">
<ng-template ngbPanelTitle>
<span>GET Block Transaction IDs</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-transaction-ids">
<a class="section-header" [routerLink]="['./']" fragment="get-block-transaction-ids">GET Block Transaction IDs <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockTxIds)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/txids</a>
@@ -501,14 +420,10 @@
<div i18n>Returns a list of all txids in the block.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockTxIds" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blockTxs">
<ng-template ngbPanelTitle>
<span>GET Block Transactions</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-block-transactions">
<a class="section-header" [routerLink]="['./']" fragment="get-block-transactions">GET Block Transactions <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blockTxs)" target="_blank">GET {{ baseNetworkUrl }}/api/block/:hash/txs[/:start_index]</a>
@@ -518,14 +433,10 @@
<div i18n>Returns a list of transactions in the block (up to 25 transactions beginning at <code>start_index</code>). Transactions returned here do not have the <code>status</code> field, since all the transactions share the same block and confirmation status.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blockTxs" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="blocks">
<ng-template ngbPanelTitle>
<span>GET Blocks</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-blocks">
<a class="section-header" [routerLink]="['./']" fragment="get-blocks">GET Blocks <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blocks)" target="_blank">GET {{ baseNetworkUrl }}/api/blocks[/:start_height]</a>
@@ -535,14 +446,10 @@
<div i18n>Returns the 10 newest blocks starting at the tip or at <code>:start_height</code> if specified.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blocks" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val === 'bisq'" id="blocks">
<ng-template ngbPanelTitle>
<span>GET Blocks</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val === 'bisq'" id="get-blocks">
<a class="section-header" [routerLink]="['./']" fragment="get-blocks">GET Blocks <span>Blocks</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.blocksBisq)" target="_blank">GET {{ baseNetworkUrl }}/api/blocks/:index/:length</a>
@@ -552,21 +459,14 @@
<div i18n>Returns the 10 newest blocks starting at the tip or at <code>:start_height</code> if specified.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.blocksBisq" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category" *ngIf="network.val !== 'bisq'">
<h4 i18n="api-docs.tab.fees|API Docs tab for Fees">Fees</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark">
<ngb-panel id="feeMempoolBlocks">
<ng-template ngbPanelTitle>
<span>GET Mempool Blocks Fees</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-mempool-blocks-fees">
<a class="section-header" [routerLink]="['./']" fragment="get-mempool-blocks-fees">GET Mempool Blocks Fees <span>Fees</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.feeMempoolBlocks)" target="_blank">GET {{ baseNetworkUrl }}/api/v1/fees/mempool-blocks</a>
@@ -576,14 +476,10 @@
<div i18n="api-docs.fees.mempool-blocks|API Docs for /api/v1/fees/mempool-blocks">Returns current mempool as projected blocks.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.feeMempoolBlocks" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="feeRecommended">
<ng-template ngbPanelTitle>
<span>GET Recommended Fees</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-recommended-fees">
<a class="section-header" [routerLink]="['./']" fragment="get-recommended-fees">GET Recommended Fees <span>Fees</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.feeRecommended)" target="_blank">GET {{ baseNetworkUrl }}/api/v1/fees/recommended</a>
@@ -593,21 +489,14 @@
<div i18n="api-docs.fees.recommended|API Docs for /api/v1/fees/recommended">Returns our currently suggested fees for new transactions.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.feeRecommended" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category" *ngIf="network.val !== 'bisq'">
<h4 i18n="api-docs.tab.mempool|API Docs tab for Mempool">Mempool</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel id="mempool">
<ng-template ngbPanelTitle>
<span>GET Mempool</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-mempool">
<a class="section-header" [routerLink]="['./']" fragment="get-mempool">GET Mempool <span>Fees</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.mempool)" target="_blank">GET {{ baseNetworkUrl }}/api/mempool</a>
@@ -617,14 +506,10 @@
<div i18n="api-docs.mempool.mempool|API Docs for /api/mempool">Returns current mempool backlog statistics.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.mempool" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="mempoolTxs">
<ng-template ngbPanelTitle>
<span>GET Mempool Transactions IDs</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-mempool-transaction-ids">
<a class="section-header" [routerLink]="['./']" fragment="get-mempool-transaction-ids">GET Mempool Transactions IDs <span>Fees</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.mempoolTxs)" target="_blank">GET {{ baseNetworkUrl }}/api/mempool/txids</a>
@@ -634,14 +519,10 @@
<div i18n="api-docs.mempool.txids|API Docs for /api/mempool/txids">Get the full list of txids in the mempool as an array. The order of the txids is arbitrary and does not match bitcoind.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.mempoolTxs" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="mempoolRecent">
<ng-template ngbPanelTitle>
<span>GET Mempool Recent</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-mempool-recent">
<a class="section-header" [routerLink]="['./']" fragment="get-mempool-recent">GET Mempool Recent <span>Fees</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.mempoolRecent)" target="_blank">GET {{ baseNetworkUrl }}/api/mempool/recent</a>
@@ -651,21 +532,14 @@
<div i18n="api-docs.mempool.recent|API Docs for /api/mempool/recent">Get a list of the last 10 transactions to enter the mempool. Each transaction object contains simplified overview data, with the following fields: <code>txid</code>, <code>fee</code>, <code>vsize</code>, and <code>value</code>.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.mempoolRecent" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
<div class="api-category">
<h4 i18n="api-docs.tab.transactions|API Docs tab for Transactions">Transactions</h4>
<ngb-accordion [closeOthers]="true" animated="true" type="dark" >
<ngb-panel *ngIf="network.val !== 'bisq'" id="cpfp">
<ng-template ngbPanelTitle>
<span>GET Children Pay for Parent</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-cpfp">
<a class="section-header" [routerLink]="['./']" fragment="get-cpfp">GET Children Pay for Parent <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionCpfp)" target="_blank">GET {{ baseNetworkUrl }}/api/v1/cpfp/:txid</a>
@@ -675,15 +549,12 @@
<div i18n="api-docs.fees.cpfp|API Docs for /api/v1/fees/cpfp">Returns the ancestors and the best descendant fees for a transaction.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionCpfp" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel id="transaction">
<ng-template ngbPanelTitle>
<span>GET Transaction</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" id="get-transaction">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction">GET Transaction <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transaction)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid</a>
</div>
<div class="description">
@@ -691,14 +562,10 @@
<div i18n>Returns details about a transaction. Available fields: <code>txid</code>, <code>version</code>, <code>locktime</code>, <code>size</code>, <code>weight</code>, <code>fee</code>, <code>vin</code>, <code>vout</code>, and <code>status</code>.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transaction" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionHex">
<ng-template ngbPanelTitle>
<span>GET Transaction Hex</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-hex">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-hex">GET Transaction Hex <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionHex)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/hex</a>
@@ -708,14 +575,10 @@
<div i18n>Returns a transaction serialized as hex.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionHex" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq' && network.val !== 'liquid'" id="transactionMerkleBlockProof">
<ng-template ngbPanelTitle>
<span>GET Transaction Merkleblock Proof</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq' && network.val !== 'liquid'" id="get-transaction-merkleblock-proof">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-merkleblock-proof">GET Transaction Merkleblock Proof <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionMerkleBlockProof)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/merkleblock-proof</a>
@@ -725,14 +588,10 @@
<div i18n>Returns a merkle inclusion proof for the transaction using <a href="https://bitcoin.org/en/glossary/merkle-block">bitcoind's merkleblock</a> format.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionMerkleBlockProof" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionMerkleProof">
<ng-template ngbPanelTitle>
<span>GET Transaction Merkle Proof</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-merkle-proof">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-merkle-proof">GET Transaction Merkle Proof <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionMerkleProof)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/merkle-proof</a>
@@ -742,14 +601,10 @@
<div i18n>Returns a merkle inclusion proof for the transaction using <a href="https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get-merkle">Electrum's blockchain.transaction.get_merkle format.</a></div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionMerkleProof" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionOutspend">
<ng-template ngbPanelTitle>
<span>GET Transaction Outspend</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-outspend">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-outspend">GET Transaction Outspend <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionOutspend)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/outspend/:vout</a>
@@ -759,14 +614,10 @@
<div i18n>Returns the spending status of a transaction output. Available fields: <code>spent</code> (boolean), <code>txid</code> (optional), <code>vin</code> (optional), and <code>status</code> (optional, the status of the spending tx).</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionOutspend" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionOutspends">
<ng-template ngbPanelTitle>
<span>GET Transaction Outspends</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-outspends">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-outspends">GET Transaction Outspends <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionOutspends)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/outspends</a>
@@ -776,14 +627,10 @@
<div i18n>Returns the spending status of all transaction outputs.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionOutspends" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionRaw">
<ng-template ngbPanelTitle>
<span>GET Transaction Raw</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-raw">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-raw">GET Transaction Raw <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionRaw)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/raw</a>
@@ -793,14 +640,10 @@
<div i18n>Returns a transaction as binary data.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionRaw" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="transactionStatus">
<ng-template ngbPanelTitle>
<span>GET Transaction Status</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="get-transaction-status">
<a class="section-header" [routerLink]="['./']" fragment="get-transaction-status">GET Transaction Status <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionStatus)" target="_blank">GET {{ baseNetworkUrl }}/api/tx/:txid/status</a>
@@ -810,15 +653,10 @@
<div i18n>Returns the confirmation status of a transaction. Available fields: <code>confirmed</code> (boolean), <code>block_height</code> (optional), and <code>block_hash</code> (optional).</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionStatus" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val === 'bisq'" id="transactionsBisq">
<ng-template ngbPanelTitle>
<span>GET Transactions</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="title">Get Mempool Txids</div>
<div class="endpoint-container" *ngIf="network.val === 'bisq'" id="get-transactions">
<a class="section-header" [routerLink]="['./']" fragment="get-transactions">GET Transactions <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<a [href]="wrapUrl(network.val, code.transactionsBisq)" target="_blank">GET {{ baseNetworkUrl }}/api/txs/:index/:length</a>
@@ -828,14 +666,10 @@
<div i18n>Returns :length of latest Bisq transactions, starting from :index.</div>
</div>
<app-code-template [hostname]="hostname" [code]="code.transactionsBisq" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
<ngb-panel *ngIf="network.val !== 'bisq'" id="postTransaction">
<ng-template ngbPanelTitle>
<span>POST Transaction</span>
</ng-template>
<ng-template ngbPanelContent>
<div class="endpoint-container" *ngIf="network.val !== 'bisq'" id="post-transaction">
<a class="section-header" [routerLink]="['./']" fragment="post-transaction">POST Transaction <span>Transactions</span></a>
<div class="endpoint">
<div class="subtitle" i18n="Api docs endpoint">Endpoint</div>
<div>POST /api/tx</div>
@@ -845,10 +679,9 @@
<div i18n>Broadcast a raw transaction to the network. The transaction should be provided as hex in the request body. The <code>txid</code> will be returned on success.</div>
</div>
<app-code-template [method]="'post'" [hostname]="hostname" [code]="code.transactionPost" [network]="network.val" ></app-code-template>
</ng-template>
</ngb-panel>
</div>
</ngb-accordion>
</div>
</div>
</div>
@@ -868,13 +701,5 @@
</div>
</div>
<br>
<div class="text-center">
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>
|
<a [routerLink]="['/privacy-policy']" i18n="shared.privacy-policy|Privacy Policy">Privacy Policy</a>
</div>
</div>
</ng-container>

View File

@@ -22,6 +22,10 @@ li.nav-item {
}
}
.no-bottom-space {
margin-bottom: 0;
}
.nav-tabs .nav-link.active {
border-bottom: 1px solid #fff;
@media (min-width: 676px){
@@ -72,10 +76,131 @@ li.nav-item {
padding: 15px;
}
#restAPI .api-category {
margin: 30px 0;
#doc-nav-desktop {
width: 300px;
}
.api-category h4 {
margin-bottom: 15px;
#doc-nav-desktop.relative {
float: left;
overflow: hidden;
}
#doc-nav-desktop.fixed {
float: unset;
position: fixed;
top: 20px;
overflow-y: auto;
height: calc(100vh - 50px);
scrollbar-color: #2d3348 #11131f;
scrollbar-width: thin;
}
::-webkit-scrollbar {
width: 3px;
}
::-webkit-scrollbar-track {
background: #11131f;
}
::-webkit-scrollbar-thumb {
background-color: #2d3348;
border-radius: 5px;
border: none;
}
.doc-content {
width: calc(100% - 330px);
float: right;
}
.endpoint-container:before {
display: block;
content: " ";
height: 1px;
margin-top: -1px;
visibility: hidden;
}
.endpoint-container .section-header {
display: block;
background-color: #2d3348;
color: #1bd8f4;
padding: 1rem 1.3rem 1rem 1.3rem;
font-weight: bold;
border-radius: 0.25rem;
margin: 20px 0 20px 0;
font-size: 24px;
position: relative;
}
.endpoint-container .section-header:hover {
text-decoration: none;
}
.endpoint-container .section-header span {
color: #fff;
background-color: #653b9c;
font-size: 12px;
text-transform: uppercase;
font-weight: 400;
padding: 8px 10px;
letter-spacing: 1px;
border-radius: 0.25rem;
font-family: monospace;
float: right;
}
#doc-nav-mobile {
position: fixed;
top: 20px;
width: calc(100% - 60px);
z-index: 100;
}
#doc-nav-mobile > div {
background-color: #2d3348;
z-index: 100;
border-radius: 0 0 0.5rem 0.5rem;
height: 55vh;
overflow-y: auto;
}
#doc-nav-mobile button {
width: 100%;
background-color: #105fb0;
color: #fff;
border-color: #105fb0;
border-radius: 0.5rem 0.5rem 0 0;
}
@media (max-width: 992px) {
.hide-on-mobile {
display: none;
}
.doc-content {
width: 100%;
}
.endpoint-container .section-header {
margin: 40px 0 70px 0;
}
.endpoint-container .section-header span {
float: none;
position: absolute;
top: unset;
left: 0;
bottom: -50px;
}
.endpoint-container:before {
height: 30px;
margin-top: -12px;
}
}
@media (min-width: 992px) {
.hide-on-desktop {
display: none;
}
}

View File

@@ -1,4 +1,4 @@
import { Component, OnInit, Input } from '@angular/core';
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
import { Env, StateService } from 'src/app/services/state.service';
import { Observable, merge, of } from 'rxjs';
import { SeoService } from 'src/app/services/seo.service';
@@ -17,12 +17,26 @@ export class ApiDocsComponent implements OnInit {
code: any;
baseNetworkUrl = '';
@Input() restTabActivated: Boolean;
@ViewChild( "mobileFixedApiNav", { static: false } ) mobileFixedApiNav: ElementRef;
desktopDocsNavPosition = "relative";
showFloatingDocsNav = false;
mobileMenuOpen = true;
constructor(
private stateService: StateService,
private seoService: SeoService,
) { }
ngAfterViewInit() {
const that = this;
setTimeout( () => {
window.addEventListener('scroll', function() {
that.desktopDocsNavPosition = ( window.pageYOffset > 182 ) ? "fixed" : "relative";
that.showFloatingDocsNav = ( window.pageYOffset > ( that.mobileFixedApiNav.nativeElement.offsetHeight + 188 ) ) ? true : false;
});
}, 1 );
}
ngOnInit(): void {
this.env = this.stateService.env;
this.seoService.setTitle($localize`:@@e351b40b3869a5c7d19c3d4918cb1ac7aaab95c4:API`);
@@ -628,24 +642,6 @@ export class ApiDocsComponent implements OnInit {
console.log(asset);
`,
},
codeSampleMainnet: {
esModule: [],
commonJS: [],
curl: [],
response: ''
},
codeSampleTestnet: {
esModule: [],
commonJS: [],
curl: [],
response: ''
},
codeSampleSignet: {
esModule: [],
commonJS: [],
curl: [],
response: ''
},
codeSampleLiquid: {
esModule: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
commonJS: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
@@ -679,6 +675,47 @@ export class ApiDocsComponent implements OnInit {
response: ''
},
},
assetIcons: {
codeTemplate: {
curl: `/api/v1/assets/icons`,
commonJS: `
const { %{0}: { assets } } = mempoolJS();
const assetsIcons = await assets.getAssetsIcons();
document.getElementById("result").textContent = JSON.stringify(assetsIcons, undefined, 2);
`,
esModule: `
const { %{0}: { assets } } = mempoolJS();
const assetsIcons = await assets.getAssetsIcons();
console.log(assetsIcons);
`,
},
codeSampleLiquid: {
esModule: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
commonJS: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
curl: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
response: `[
"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d",
"ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
...
]`,
},
},
assetIcon: {
noWrap: true,
codeTemplate: {
curl: `/api/v1/asset/%{1}/icon`,
commonJS: `<img src="https://liquid.place/api/v1/asset/%{1}/icon">`,
},
codeSampleLiquid: {
esModule: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
commonJS: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
curl: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`],
response: `PNG`,
},
},
assetTransactions: {
codeTemplate: {
curl: `/api/asset/%{1}/txs`,

View File

@@ -164,6 +164,10 @@ init();`;
codeText = this.replaceJSPlaceholder(codeText, code.codeSampleBisq.esModule);
}
if (code.noWrap) {
return codeText;
}
let importText = `<script src="https://mempool.space/mempool.js"></script>`;
if (this.env.BASE_MODULE === 'bisq') {
importText = `<script src="https://bisq.markets/bisq.js"></script>`;

View File

@@ -27,5 +27,13 @@
<div id="main-tab-content" [ngbNavOutlet]="nav" class="mt-2"></div>
<br>
<div id="footer" class="text-center">
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>
|
<a [routerLink]="['/privacy-policy']" i18n="shared.privacy-policy|Privacy Policy">Privacy Policy</a>
</div>
</div>
</div>

View File

@@ -1,4 +1,9 @@
#main-tab-content {
text-align: left;
padding-top: 10px;
scroll-behavior: smooth;
}
#footer {
clear: both;
}

View File

@@ -3,7 +3,8 @@
<div class="flashing">
<ng-template ngFor let-projectedBlock [ngForOf]="mempoolBlocks$ | async" let-i="index" [ngForTrackBy]="trackByFn">
<div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink">
<a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink">&nbsp;</a>
<a draggable="false" [routerLink]="['/mempool-block/' | relativeUrl, i]"
class="blockLink" [ngClass]="{'disabled': (this.stateService.blockScrolling$ | async)}">&nbsp;</a>
<div class="block-body">
<div class="fees">
~{{ projectedBlock.medianFee | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>

View File

@@ -117,6 +117,10 @@
z-index: 10;
}
.blockLink.disabled {
pointer-events: none;
}
.blockLink:hover {
text-decoration: none;
}

View File

@@ -8,7 +8,10 @@
<div *ngIf="countdown > 0" class="warning-label">{{ eventName }} in {{ countdown | number }} block{{ countdown === 1 ? '' : 's' }}!</div>
<div id="blockchain-container" dir="ltr">
<div id="blockchain-container" dir="ltr" #blockchainContainer
(mousedown)="onMouseDown($event)"
(dragstart)="onDragStart($event)"
>
<app-blockchain></app-blockchain>
</div>

View File

@@ -1,8 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { WebsocketService } from 'src/app/services/websocket.service';
import { StateService } from 'src/app/services/state.service';
import { specialBlocks } from 'src/app/app.constants';
import { takeLast } from 'rxjs/operators';
@Component({
selector: 'app-start',
@@ -16,6 +15,9 @@ export class StartComponent implements OnInit {
countdown = 0;
specialEvent = false;
eventName = '';
mouseDragStartX: number;
blockchainScrollLeftInit: number;
@ViewChild('blockchainContainer') blockchainContainer: ElementRef;
constructor(
private websocketService: WebsocketService,
@@ -50,4 +52,27 @@ export class StartComponent implements OnInit {
});
}
onMouseDown(event: MouseEvent) {
this.mouseDragStartX = event.clientX;
this.blockchainScrollLeftInit = this.blockchainContainer.nativeElement.scrollLeft;
}
onDragStart(event: MouseEvent) { // Ignore Firefox annoying default drag behavior
event.preventDefault();
}
// We're catching the whole page event here because we still want to scroll blocks
// even if the mouse leave the blockchain blocks container. Same idea for mouseup below.
@HostListener('document:mousemove', ['$event'])
onMouseMove(event: MouseEvent): void {
if (this.mouseDragStartX != null) {
this.stateService.setBlockScrollingInProgress(true);
this.blockchainContainer.nativeElement.scrollLeft =
this.blockchainScrollLeftInit + this.mouseDragStartX - event.clientX
}
}
@HostListener('document:mouseup', [])
onMouseUp() {
this.mouseDragStartX = null;
this.stateService.setBlockScrollingInProgress(false);
}
}

View File

@@ -89,6 +89,8 @@ export class StateService {
markBlock$ = new ReplaySubject<MarkBlockState>();
keyNavigation$ = new Subject<KeyboardEvent>();
blockScrolling$: Subject<boolean> = new Subject<boolean>();
constructor(
@Inject(PLATFORM_ID) private platformId: any,
private router: Router,
@@ -176,4 +178,8 @@ export class StateService {
if (!prop) { return false; }
return document[prop];
}
setBlockScrollingInProgress(value: boolean) {
this.blockScrolling$.next(value);
}
}

File diff suppressed because it is too large Load Diff