diff --git a/README.md b/README.md index e4c1ad8..879fc0f 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ The YAML file includes details for multiple objects (PT, YT, LP), each correspon - name: The name of the protocol. - icon: The protocol’s logo (circular logo in PNG). The string on this field should be the same as the name of the logo file uploaded. Size limit for logo is 20KB. + - category: The protocol's category. It must belong to one of the following categories: `money market`, `vault` or `liquid locker`. If no category is specified, the protocol will automatically default to the `others` type. - metadata: This section contains detailed information about the protocol's integration assets. #### Asset fields @@ -25,6 +26,7 @@ The YAML file includes details for multiple objects (PT, YT, LP), each correspon ```yaml name: Protocol Name 2 icon: logo.png +category: 'vault' metadata: pt: - chainId: 1 diff --git a/const.js b/const.js new file mode 100644 index 0000000..3e4a291 --- /dev/null +++ b/const.js @@ -0,0 +1,7 @@ +const DEFAULT_PROTOCOL_CATEGORY = 'others'; +const PROTOCOL_CATEGORIES = ['money market', 'vault', 'liquid locker']; + +module.exports = { + DEFAULT_PROTOCOL_CATEGORY, + PROTOCOL_CATEGORIES, +} \ No newline at end of file diff --git a/merge-config.js b/merge-config.js index b02265e..c3df586 100644 --- a/merge-config.js +++ b/merge-config.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const yaml = require("js-yaml"); +const {DEFAULT_PROTOCOL_CATEGORY} = require("./const"); async function run() { const protocolsPath = path.join(__dirname, 'protocols'); @@ -51,19 +52,35 @@ async function run() { } function formatProtocolConfig(config) { - const {metadata} = config; + const {id, name, icon, category, metadata} = config; const {pt, yt, lp} = metadata; - lowercaseAddressOfMetadata(pt); - lowercaseAddressOfMetadata(yt); - lowercaseAddressOfMetadata(lp); - return config; + return { + id, + name, + icon, + category: category ?? DEFAULT_PROTOCOL_CATEGORY, + metadata: { + pt: formatMetadataAssets(pt), + yt: formatMetadataAssets(yt), + lp: formatMetadataAssets(lp), + }, + }; } -function lowercaseAddressOfMetadata(assets) { +function formatMetadataAssets(assets) { + const result = []; for (const asset of (assets ?? [])) { - asset.address = asset.address.toLowerCase(); + const {chainId, address, integrationUrl, description} = asset; + result.push({ + chainId, + address: address.toLowerCase(), + integrationUrl, + description, + }) } + + return result; } function createMD5(filePath) { diff --git a/validate-config.js b/validate-config.js index 7495c34..f67308e 100644 --- a/validate-config.js +++ b/validate-config.js @@ -1,6 +1,7 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); +const {PROTOCOL_CATEGORIES} = require("./const"); const LIMIT_ICON_KB_SIZE = 20; const BUFFER_LIMIT_ICON_KB_SIZE = LIMIT_ICON_KB_SIZE + 1; @@ -15,6 +16,16 @@ function isKebabCase(str) { return kebabCaseRegex.test(str); } +function validateCategory(protocol, category) { + if (category === undefined) { + return; + } + + if (!mustBeNonEmptyString(category) || !PROTOCOL_CATEGORIES.includes(category)) { + throw new Error(`protocol ${protocol}: invalid field 'category', category must be one of the values (${PROTOCOL_CATEGORIES.join(', ')}) or left unset`); + } +} + async function main() { const CHANGED_PROTOCOLS = process.env.CHANGED_PROTOCOLS; const GET_ASSET_LIST_URL = process.env.GET_ASSET_LIST_URL; @@ -81,12 +92,14 @@ function validateConfig(protocol, assetMap) { throw new Error(`protocol ${protocol}: config is not an object`); } - const {name, icon, metadata} = protocolConfig; + const {name, icon, metadata, category} = protocolConfig; if (!mustBeNonEmptyString(name)) { throw new Error(`protocol ${protocol}: invalid field 'name'`); } + validateCategory(protocol, category); + if (!mustBeNonEmptyString(icon)) { throw new Error(`protocol ${protocol}: invalid field 'icon'`); } @@ -113,7 +126,6 @@ function validateConfig(protocol, assetMap) { throw new Error(`protocol ${protocol}: icon size must be less than ${LIMIT_ICON_KB_SIZE}KB file`); } - const {pt, yt, lp} = metadata; checkMetadataField(pt, protocol, 'pt', ptMap); checkMetadataField(yt, protocol, 'yt', ytMap);