Skip to content

Commit

Permalink
Add Market promotion boosted tag
Browse files Browse the repository at this point in the history
  • Loading branch information
thanhpn committed Dec 4, 2024
1 parent 0ec010c commit 59eb777
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 2 deletions.
10 changes: 9 additions & 1 deletion .github/markets/pr_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`market_banners` |`MarketBanner[]` |true |market banner configs. |
| `native_token_contracts_map` | `object` | false | Map of token denoms to their respective contract addresses on the native chain. | |
| `native_depositor_contracts_map` | `object` | false | Map of axelar connection ids to their respective native depositor contract addresses
|`market_promo` |`MarketPromo` |false |Map of Objects that contains market promo parameters for each market |If the `market_promo` property is omitted, no promo will be shown. The key of each entry is the ids of the market with existing promo. |

## Maintenance Data Structure
|Field |Type |Required |Description |Notes |
Expand Down Expand Up @@ -97,4 +98,11 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`show_from` |`string` |false |The date and time when the market banner is scheduled to begin displaying. |If not provided, the banner will be shown immediately.<br /><br /> This field **MUST** follow the valid ISO 8601 format <br /> e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) |
|`show_until` |`string` |false |The date and time when the market banner is scheduled to stop displaying. |If not provided, the banner will continue to display indefinitely.<br /><br /> This field **MUST** follow the valid ISO 8601 format <br /> e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) |
|`content` |`string` |true |The content shown on the market banner. |
|`hideable` |`boolean` |false |Indicates if user can hide the banner by clicking on the close button |If set to `false`, the close button will not be rendered on the banner, and user will not be able to dismiss the banner. |
|`hideable` |`boolean` |false |Indicates if user can hide the banner by clicking on the close button |If set to `false`, the close button will not be rendered on the banner, and user will not be able to dismiss the banner. |

## MarketPromo Data Structure
|Field |Type |Required |Description |Notes |
|---|---|---|---|---|
|`start` |`string` |true |Start time of the promo. |
|`end` |`string` |true |End time of the promo. |
|`tooltip` |`string` |true |Tooltip message for perp trading boost tag. |
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Additionally, the JSON file for mainnet contains the following data to support o
- perp pool promotion parameters
- typeform survey parameters
- market banner parameters for information banners to be displayed on the TradingView charts on Trade UI
- market promo parameters for showing boosted tag on market select on Trade UI

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

Expand Down
29 changes: 29 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,31 @@
}
}
},
"market_promo": {
"type": "object",
"description": "Market Promo config",
"patternProperties": {
"^\\d+$": {
"type": "object",
"required": [
"start",
"end",
"tooltip"
],
"properties": {
"start": {
"$ref": "#/$defs/start"
},
"end": {
"$ref": "#/$defs/end"
},
"tooltip": {
"$ref": "#/$defs/tooltip"
}
}
}
}
},
"$defs": {
"prelaunch_market": {
"type": "string",
Expand Down Expand Up @@ -357,6 +382,10 @@
"type": "string",
"description": "The content shown on the banner, we can render hyperlink in the content eg: You can visit [here](url)"
},
"tooltip": {
"type": "string",
"description": "The tooltip shown on the market select dropdown tag"
},
"additional_ibc_token_info": {
"type": "object",
"description": "Information for token that (1) is not added on Carbon blockchain or (2) requires packet forwarding.",
Expand Down
9 changes: 8 additions & 1 deletion configs/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -450,5 +450,12 @@
"content": "This is a pre-launch perp for Hyperliquid's HYPE and assumes a total supply of 1 billion. [Learn more.](https://guide.dem.exchange/trade/futures/market-specifications/pre-launch-perpetuals)",
"show_from": "2024-11-04T09:00+00:00"
}
]
],
"market_promo": {
"cmkt/142": {
"start": "2024-11-20T08:00:00Z",
"end": "2024-12-20T08:00:00Z",
"tooltip": "Trade MNT-PERP to earn 3x points in the Mantle Trading League!"
}
}
}
50 changes: 50 additions & 0 deletions scripts/check_configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface ConfigJSON {
perp_pools: PerpPoolConfig;
wswth_contract?: string;
market_banners?: MarketBanner[];
market_promo?: {[marketId: string]: MarketPromo};
}

interface InvalidEntry {
Expand Down Expand Up @@ -109,6 +110,12 @@ interface MarketBanner {
hideable?: boolean;
}

interface MarketPromo {
start: string;
end: string;
tooltip: string;
}

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

const outcomeMap: OutcomeMap = {
Expand Down Expand Up @@ -308,6 +315,45 @@ function isValidMarketBanners(marketBanners: MarketBanner[], network: CarbonSDK.
return true;
}

function isValidMarketPromo(marketPromo: {[marketId: string]: MarketPromo}, network: CarbonSDK.Network, marketIds: string[]): boolean {
const marketPromoIds = Object.keys(marketPromo)
const hasInvalidMarketPromoIds = checkValidEntries(marketPromoIds, marketIds)
const hasDuplicateMarketPromoIds = checkDuplicateEntries(marketPromoIds)

// check for valid market id
if (hasInvalidMarketPromoIds.status && hasInvalidMarketPromoIds.entry) {
let listOfInvalidIds: string = hasInvalidMarketPromoIds.entry.join(", ");
console.error(`ERROR: ${network}.json has the following invalid market ids under the market_promo field: ${listOfInvalidIds}`)
outcomeMap[network] = false;
}

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

for (const promoId in marketPromoIds) {
const promoInfo = marketPromo[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 market promo id ${promoId}.`);
outcomeMap[network] = false;
break; // Exit the loop early upon encountering an error
}
}

return true;
}

async function main() {
for (const net of myArgs) {
let network: CarbonSDK.Network;
Expand Down Expand Up @@ -629,6 +675,10 @@ async function main() {
outcomeMap[network] = false;
}

if(jsonData.market_promo && !isValidMarketPromo(jsonData.market_promo, network, marketIds)) {
outcomeMap[network] = false;
}

// external chain channels check
const isExternalChannelsValid = isValidExternalChainChannels(jsonData.external_chain_channels, ibcBridgeNames, network);
if (!isExternalChannelsValid) outcomeMap[network] = false;
Expand Down

0 comments on commit 59eb777

Please sign in to comment.