diff --git a/backend/.gitignore b/backend/.gitignore index c4339712c..5476d633c 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -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 diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index 6ff103bf1..ea656c1de 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -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", diff --git a/backend/src/api/liquid/icons.ts b/backend/src/api/liquid/icons.ts new file mode 100644 index 000000000..1c7c658af --- /dev/null +++ b/backend/src/api/liquid/icons.ts @@ -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(); diff --git a/backend/src/config.ts b/backend/src/config.ts index 2addc176a..9513324d8 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -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', diff --git a/backend/src/index.ts b/backend/src/index.ts index 3a3bdb197..d1bd86994 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -21,6 +21,8 @@ import backendInfo from './api/backend-info'; import loadingIndicators from './api/loading-indicators'; import mempool from './api/mempool'; import elementsParser from './api/liquid/elements-parser'; +import syncAssets from './sync-assets'; +import icons from './api/liquid/icons'; class Server { private wss: WebSocket.Server | undefined; @@ -77,6 +79,7 @@ class Server { this.setUpWebsocketHandling(); + await syncAssets.syncAssets(); diskCache.loadMempoolCache(); if (config.DATABASE.ENABLED) { @@ -87,6 +90,10 @@ class Server { statistics.startStatistics(); } + if (config.MEMPOOL.NETWORK === 'liquid') { + icons.loadIcons(); + } + fiatConversion.startService(); this.setUpHttpApiRoutes(); @@ -270,6 +277,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) diff --git a/backend/src/routes.ts b/backend/src/routes.ts index 06cebeae1..53387511f 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -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(); diff --git a/backend/src/sync-assets.ts b/backend/src/sync-assets.ts new file mode 100644 index 000000000..302196458 --- /dev/null +++ b/backend/src/sync-assets.ts @@ -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(); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 717134fca..8aa1c675e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -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", diff --git a/frontend/package.json b/frontend/package.json index 91f7f3682..f25f8bc32 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -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", diff --git a/frontend/src/app/components/docs/api-docs-nav.component.html b/frontend/src/app/components/docs/api-docs-nav.component.html index a4da93428..63ed8d4e1 100644 --- a/frontend/src/app/components/docs/api-docs-nav.component.html +++ b/frontend/src/app/components/docs/api-docs-nav.component.html @@ -30,8 +30,10 @@

Assets

GET Assets + GET Assets Icons GET Asset Transactions GET Asset Supply + GET Asset Icon

Blocks

diff --git a/frontend/src/app/components/docs/api-docs-nav.component.ts b/frontend/src/app/components/docs/api-docs-nav.component.ts index 967b355f3..5109e2dc0 100644 --- a/frontend/src/app/components/docs/api-docs-nav.component.ts +++ b/frontend/src/app/components/docs/api-docs-nav.component.ts @@ -8,7 +8,7 @@ import { Component, OnInit, Input } from '@angular/core'; export class ApiDocsNavComponent implements OnInit { @Input() network: any; - @Input() collapseItem: any; + @Input() collapseItem: any = { toggle: () => {} }; constructor() { } diff --git a/frontend/src/app/components/docs/api-docs.component.html b/frontend/src/app/components/docs/api-docs.component.html index 8358129f5..c41bc57c7 100644 --- a/frontend/src/app/components/docs/api-docs.component.html +++ b/frontend/src/app/components/docs/api-docs.component.html @@ -275,6 +275,32 @@ +
+ GET Asset Icons Assets +
+
Endpoint
+ GET /liquid/api/v1/assets/icons +
+
+
Description
+
Get all the Asset IDs that has icons.
+
+ +
+ +
+ GET Asset Icon Assets +
+
Endpoint
+ GET /liquid/api/v1/asset/:asset_id/icon +
+
+
Description
+
Get the icon of the specified asset.
+
+ +
+
diff --git a/frontend/src/app/components/docs/api-docs.component.ts b/frontend/src/app/components/docs/api-docs.component.ts index bbc8cad76..02cca44b2 100644 --- a/frontend/src/app/components/docs/api-docs.component.ts +++ b/frontend/src/app/components/docs/api-docs.component.ts @@ -642,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`], @@ -693,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: ``, + }, + codeSampleLiquid: { + esModule: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`], + commonJS: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`], + curl: [`6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d`], + response: `PNG`, + }, + }, assetTransactions: { codeTemplate: { curl: `/api/asset/%{1}/txs`, diff --git a/frontend/src/app/components/docs/code-template.component.ts b/frontend/src/app/components/docs/code-template.component.ts index e84297f80..0c46c7a9d 100644 --- a/frontend/src/app/components/docs/code-template.component.ts +++ b/frontend/src/app/components/docs/code-template.component.ts @@ -164,6 +164,10 @@ init();`; codeText = this.replaceJSPlaceholder(codeText, code.codeSampleBisq.esModule); } + if (code.noWrap) { + return codeText; + } + let importText = ``; if (this.env.BASE_MODULE === 'bisq') { importText = ``;