Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update config schema and add validation #159

Merged
merged 5 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/markets/pr_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`transfer_options` |`object` |true |A collection of blockchain networks along with their associated priority numbers, used to establish their order in the transfer options list for deposit and withdrawal forms. |Blockchain network listed here **MUST** match the valid chainName of the bridges listed under BridgeAll RPC call.<br /><br /> To view the values of BridgeAll RPC call, simply run `yarn get-bridges [network]` on the command line. Sample for mainnet: `yarn get-bridges mainnet`|
|`network_fees` |`object` |true |List of token denoms along with their associated priority numbers, used to establish their default order in the network fees preference list. |Token denoms listed here **MUST** match the valid denoms listed under MinGasPriceAll RPC call.<br /><br /> To view the values of MinGasPriceAll RPC call, simply run `yarn get-min-gas-prices [network]` on the command line. Sample for mainnet: `yarn get-min-gas-prices mainnet`|
|`maintenance` |`Maintenance` |false |Object that dictates whether or not the maintenance page is displayed on each particular network. The maintenance page is displayed when the Carbon chain is down (i.e. blocks are not moving). | If the `maintenance` property is omitted, the maintenance page will not be shown.
|`perp_pool_banners` |`PerpPoolBanner` |true |List of Objects that indicate the banner content on specific perp pool pages. |
|`perp_pool_banners` |`PerpPoolBanner` |true |List of Objects that indicate the banner content on specific perp pool pages. |
|`demex_points_config` |`DemexPointsConfig` |false |Object that contains the parameters to earn demex points. |This object **must** be included for mainnet.json as demex points is already live on mainnet. |
andrewsoon marked this conversation as resolved.
Show resolved Hide resolved
|`perp_pool_promo` |`PerpPoolPromo` |false |Map of Objects that contains perp pool promo parameters for each pool |If the `perp_pool_promo` property is omitted, no promo will be shown. The key of each entry is the ids of the perp pools with existing promo. |

## Maintenance Data Structure
|Field |Type |Required |Description |Notes |
Expand All @@ -30,4 +32,18 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`title` |`string` |true |The title shown on the perp pool banner. |
|`removed_markets` |`string` |false |The message describing markets being removed, shown below the perp-pool banner title. | e.g. "BTCETH Perp will be removed on 6 Mar, 09:00AM UTC". If the field is omitted, no message describing markets being removed will be shown. |
|`added_markets` |`string` |false |The message describing markets being added, shown below the markets being removed (if any). | e.g. "ATOM Perp & SOL Perp will be added on 8 Mar, 12:00AM UTC". If the field is omitted, no message describing markets being added will be shown. |
|`subtext` |`string` |false |The subtext shown on the perp pool banner (below the removed and added market descriptions). |
|`subtext` |`string` |false |The subtext shown on the perp pool banner (below the removed and added market descriptions). |

## DemexPointsConfig Data Structure
|Field |Type |Required |Description |Notes |
|---|---|---|---|---|
|`depositsPerSpin` |`integer` |true |Amount deposited in the perp pool that will earn 1 spin after 1 week. |
sarah-thong marked this conversation as resolved.
Show resolved Hide resolved
|`tradingVolumePerSpin` |`integer` |true |Volume traded on perp markets that will earn 1 spin. |

## PerpPoolPromo
|Field |Type |Required |Description |Notes |
|---|---|---|---|---|
|`start` |`string` |true |Start time of the promo. |
|`end` |`string` |true |End time of the promo. |
|`perpPoolDepositBoost` |`integer` |true |Boost to perp pool deposits required to earn 1 demex point spin. |
|`perpTradingBoost` |`integer` |true |Boost to trading volume required to earn 1 demex point spin. |
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Currently, each JSON file contain the following data on its corresponding networ
- default blockchain transfer option order in deposit/withdrawal forms dropdown
- default network token fee order

Additionally, the JSON file for mainnet contains the following data to support ongoing campaigns/promotions:
- demex points config
- perp pool promotion parameters

More metadata will be added in the future if required by the Demex frontend. Please see below the structure of the JSON file:

```json
Expand Down
61 changes: 60 additions & 1 deletion config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"required": [
"perp_pool_id",
"title"
],
],
"properties": {
"perp_pool_id": {
"$ref": "#/$defs/perp_pool_id"
Expand All @@ -116,6 +116,47 @@
}
}
}
},
"demex_points_config": {
"type": "object",
"description": "Config for demex points",
"properties": {
"depositsPerSpin": {
"type": "integer"
},
"tradingVolumePerSpin": {
"type": "integer"
}
}
},
"perp_pool_promo": {
"type": "object",
"description": "Perp Pool Promo config",
"patternProperties": {
"^\\d+$": {
"type": "object",
"required": [
"start",
"end",
"perpPoolDepositBoost",
"perpTradingBoost"
],
"properties": {
"start": {
"$ref": "#/$defs/start"
},
"end": {
"$ref": "#/$defs/end"
},
"perpPoolDepositBoost": {
"$ref": "#/$defs/perpPoolDepositBoost"
},
"perpTradingBoost": {
"$ref": "#/$defs/perpTradingBoost"
}
}
}
}
}
},
"$defs": {
Expand Down Expand Up @@ -166,6 +207,24 @@
"subtext": {
"type": "string",
"description": "The subtext shown on the banner"
},
"start": {
"type": "string",
"description": "The start time of perp pool promo",
"pattern": "^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$"
},
"end": {
"type": "string",
"description": "The end time of perp pool promo",
"pattern": "^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$"
},
"perpPoolDepositBoost": {
"type": "integer",
"description": "The spin boost multiplier for deposits in perp pool"
},
andrewsoon marked this conversation as resolved.
Show resolved Hide resolved
"perpTradingBoost": {
"type": "integer",
"description": "The spin boost multiplier for boosted perp markets trading volume"
}
andrewsoon marked this conversation as resolved.
Show resolved Hide resolved
}
}
6 changes: 3 additions & 3 deletions configs/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@
},
"perp_pool_promo": {
"9": {
"start": "2024-05-14T06:00:00Z",
"start": "2024-05-14T08:00:00Z",
"end": "2024-05-21T08:00:00Z",
"perpPoolDepositBoost": "2",
"perpTradingBoost": "3"
"perpPoolDepositBoost": 2,
"perpTradingBoost": 3
}
}
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
"get-perp-pool-ids": "ts-node scripts/get_perp_pool_ids"
},
"dependencies": {
"@cosmjs/tendermint-rpc": "^0.29.4",
"@cosmjs/tendermint-rpc": "~0.31.3",
"@types/node": "^18.11.9",
"@types/node-fetch": "^2.6.2",
"carbon-js-sdk": "^0.7.1-beta.2",
"carbon-js-sdk": "^0.10.5",
"long": "^4.0.0",
"node-fetch": "^2.6.1",
"pajv": "^1.2.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.3"
}
}
}
73 changes: 65 additions & 8 deletions scripts/check_configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ interface ConfigJSON {
network_fees: {
[denom: string]: number
},
perp_pool_banners: PerpPoolBanner[]
perp_pool_banners: PerpPoolBanner[],
demex_points_config: DemexPointsConfig,
perp_pool_promo: {
[perpPoolId: string]: PerpPoolPromo,
}
}

interface InvalidEntry {
Expand All @@ -41,6 +45,18 @@ interface PerpPoolBanner {
subtext?: string;
}

interface DemexPointsConfig {
depositsPerSpin: number;
tradingVolumePerSpin: number;
}

interface PerpPoolPromo {
start: string;
end: string;
perpPoolDepositBoost: string;
perpTradingBoost: string;
}

type OutcomeMap = { [key in CarbonSDK.Network]: boolean }; // true = success, false = failure

const outcomeMap: OutcomeMap = {
Expand Down Expand Up @@ -140,7 +156,7 @@ async function main() {
reverse: false,
},
});
const markets: string[] = allMarkets.markets.map(market => market.name);
const markets: string[] = allMarkets.markets.map(market => market.id);

// look for invalid market entries
const hasInvalidPrelaunchMarkets = checkValidEntries(jsonData.prelaunch_markets, markets);
Expand Down Expand Up @@ -290,20 +306,61 @@ async function main() {
const perpPoolIds = perpPoolsQuery.pools.map((pool) => pool.poolId.toString())
const perpPoolBannerIds = Object.values(jsonData.perp_pool_banners).map((banner) => banner.perp_pool_id)

const hasInvalidPerpPoolIds = checkValidEntries(perpPoolBannerIds, perpPoolIds)
const hasDuplicatePerpPoolIds = checkDuplicateEntries(perpPoolBannerIds)
const hasInvalidPerpPoolBannerIds = checkValidEntries(perpPoolBannerIds, perpPoolIds)
const hasDuplicatePerpPoolBannerIds = checkDuplicateEntries(perpPoolBannerIds)

if(hasInvalidPerpPoolIds.status && hasInvalidPerpPoolIds.entry) {
let listOfInvalidIds: string = hasInvalidPerpPoolIds.entry.join(", ");
if (hasInvalidPerpPoolBannerIds.status && hasInvalidPerpPoolBannerIds.entry) {
let listOfInvalidIds: string = hasInvalidPerpPoolBannerIds.entry.join(", ");
console.error(`ERROR: ${network}.json has the following invalid perp pool ids under the perp_pool_banners field: ${listOfInvalidIds}`)
outcomeMap[network] = false;
}

if (hasDuplicatePerpPoolIds.status && hasDuplicatePerpPoolIds.entry) {
let listOfDuplicates: string = hasDuplicatePerpPoolIds.entry.join(", ");
if (hasDuplicatePerpPoolBannerIds.status && hasDuplicatePerpPoolBannerIds.entry) {
let listOfDuplicates: string = hasDuplicatePerpPoolBannerIds.entry.join(", ");
console.error(`ERROR: ${network}.json has duplicated perp pool banners for the following perp pool ids: ${listOfDuplicates}. Please make sure to input each perp pool banner only once in ${network}`);
outcomeMap[network] = false;
}

const perpPoolPromoIds = Object.keys(jsonData.perp_pool_promo)
const hasInvalidPerpPoolPromoIds = checkValidEntries(perpPoolPromoIds, perpPoolIds)
const hasDuplicatePerpPoolPromoIds = checkDuplicateEntries(perpPoolPromoIds)

if (hasInvalidPerpPoolPromoIds.status && hasInvalidPerpPoolPromoIds.entry) {
let listOfInvalidIds: string = hasInvalidPerpPoolPromoIds.entry.join(", ");
console.error(`ERROR: ${network}.json has the following invalid perp pool ids under the perp_pool_promo field: ${listOfInvalidIds}`)
outcomeMap[network] = false;
}

if (hasDuplicatePerpPoolPromoIds.status && hasDuplicatePerpPoolPromoIds.entry) {
let listOfDuplicates: string = hasDuplicatePerpPoolPromoIds.entry.join(", ");
console.error(`ERROR: ${network}.json has duplicated perp pool promos for the following perp pool ids: ${listOfDuplicates}. Please make sure to input each perp pool promo only once in ${network}`);
outcomeMap[network] = false;
}

if (network === CarbonSDK.Network.MainNet && !jsonData.demex_points_config) {
console.error(`ERROR: ${network}.json is missing demex_points_config`)
outcomeMap[network] = false;
}

if (jsonData.perp_pool_promo) {
const perpPoolPromo = jsonData.perp_pool_promo
for (const promoId in jsonData.perp_pool_promo) {
const promoInfo = perpPoolPromo[promoId];
const startTimeStr = promoInfo.start;
const endTimeStr = promoInfo.end;

// Parse start and end times into Date objects
const startTime = new Date(startTimeStr);
const endTime = new Date(endTimeStr);

// Check if end time is before start time
if (endTime < startTime) {
console.error(`ERROR: ${network}.json has invalid end time (${endTimeStr}) is before start time (${startTimeStr}) for perp_pool_promo id ${promoId}.`);
outcomeMap[network] = false;
break; // Exit the loop early upon encountering an error
}
}
}
}
}
const outcomeArr = Object.values(outcomeMap);
Expand Down
Loading
Loading