From 184f8dfab54cdf859f9f82cdef18a02bb90f3a40 Mon Sep 17 00:00:00 2001 From: kylehoang92 Date: Wed, 18 Dec 2024 08:57:53 +0700 Subject: [PATCH] feat: announcement banner on deposit/withdraw screens --- .github/markets/pr_template.md | 23 +++++++++----- config.schema.json | 55 ++++++++++++++++++++++++++++++++++ configs/devnet.json | 5 ++++ configs/mainnet.json | 9 ++++-- configs/testnet.json | 5 ++++ scripts/check_configs.ts | 55 ++++++++++++++++++++++++++++++++-- 6 files changed, 140 insertions(+), 12 deletions(-) diff --git a/.github/markets/pr_template.md b/.github/markets/pr_template.md index 6ecb128..158c99e 100644 --- a/.github/markets/pr_template.md +++ b/.github/markets/pr_template.md @@ -26,7 +26,7 @@ Each json file under the [configs](../../configs) folder correspond to their res |`wswth_contract` |`string` |false |wSWTH ERC-20 contract. | |`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 +| `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. | |`spot_pool_config` |`SpotPoolConfig` |false |Object that contains the config parameters for the [Spot Pools](https://app.dem.exchange/pools/spot) page on Demex | @@ -94,19 +94,19 @@ Each json file under the [configs](../../configs) folder correspond to their res |---|---|---|---|---| |`perp_pool_id` |`string` |true |Perp pool id where the banner will be shown. |Perp pool id **MUST** match one of the existing perp pool ids from the PerpPool PoolInfoAll RPC call.

To view the values of PoolInfoAll RPC call, simply run `yarn get-perp-pool-ids [network]` on the command line. Sample for mainnet: `yarn get-perp-pool-ids mainnet` | |`show_from` |`string` |false |The date and time when the perp pool banner is scheduled to begin displaying. |If not provided, the banner will be shown immediately.

This field **MUST** follow the valid ISO 8601 format
e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) | -|`show_until` |`string` |false |The date and time when the perp pool banner is scheduled to stop displaying. |If not provided, the banner will continue to display indefinitely.

This field **MUST** follow the valid ISO 8601 format
e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) | -|`title` |`string` |true |The title shown on the perp pool banner. | +|`show_until` |`string` |false |The date and time when the perp pool banner is scheduled to stop displaying. |If not provided, the banner will continue to display indefinitely.

This field **MUST** follow the valid ISO 8601 format
e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) | +|`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). | +|`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). | ## MarketBanner |Field |Type |Required |Description |Notes | |---|---|---|---|---| |`market_id` |`string` |true |Market id where the banner will be shown. |Market id **MUST** match one of the existing market ids from the Market MarketAll RPC call.

To view the values of MarketAll RPC call, simply run `yarn get-market-ids [network]` on the command line. Sample for mainnet: `yarn get-market-ids mainnet` | |`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.

This field **MUST** follow the valid ISO 8601 format
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.

This field **MUST** follow the valid ISO 8601 format
e.g. *2024-01-23T09:00+00:00* (23 Jan 2024, 9am UTC) | -|`content` |`string` |true |The content shown on the market banner. | +|`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.

This field **MUST** follow the valid ISO 8601 format
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. | ## MarketPromo Data Structure @@ -119,4 +119,11 @@ Each json file under the [configs](../../configs) folder correspond to their res ## SpotPoolConfig Data Structure |Field |Type |Required |Description |Notes | |---|---|---|---|---| -|`show_apr_tooltip` |`boolean` |true |Indicates whether or not to show the Annual Percentage Returns (APR) tooltip on [Spot Pools](https://app.dem.exchange/pools/spot) page | \ No newline at end of file +|`show_apr_tooltip` |`boolean` |true |Indicates whether or not to show the Annual Percentage Returns (APR) tooltip on [Spot Pools](https://app.dem.exchange/pools/spot) page | + +## TransferBanner Data Structure +|Field |Type |Required |Description |Notes | +|---|---|---|---|---| +|`no_longer_supported_tokens` |`array` |false |List of tokens are no longer supported | +|`temporary_disabled_transfer_tokens` |`TransferBanner` |false |List of tokens for which deposits and withdrawals have been temporarily disabled | +|`temporary_disabled_bridges` |`TransferBanner` |false |List of bridges for which deposits and withdrawals have been temporarily disabled | diff --git a/config.schema.json b/config.schema.json index 683a082..0542a1a 100644 --- a/config.schema.json +++ b/config.schema.json @@ -515,6 +515,61 @@ "description": "Indicates whether or not to show APR tooltip on Spot Pools page" } } + }, + "transfer_banner": { + "type": "object", + "description": "Config parameters to show banner for deposit and withdraw screens", + "properties": { + "no_longer_supported_tokens": { + "type": "array", + "description": "List of tokens are no longer supported", + "items": { + "type": "string" + } + }, + "temporary_disabled_transfer_tokens": { + "type": "object", + "description": "List of tokens for which deposits and withdrawals have been temporarily disabled", + "patternProperties": { + ".*": { + "type": "object", + "required": [ + "start", + "end" + ], + "properties": { + "start": { + "$ref": "#/$defs/start" + }, + "end": { + "$ref": "#/$defs/end" + } + } + } + } + }, + "temporary_disabled_bridges": { + "type": "object", + "description": "List of bridges for which deposits and withdrawals have been temporarily disabled", + "patternProperties": { + ".*": { + "type": "object", + "required": [ + "start", + "end" + ], + "properties": { + "start": { + "$ref": "#/$defs/start" + }, + "end": { + "$ref": "#/$defs/end" + } + } + } + } + } + } } } } diff --git a/configs/devnet.json b/configs/devnet.json index 86d3aff..f199c0b 100644 --- a/configs/devnet.json +++ b/configs/devnet.json @@ -45,5 +45,10 @@ ], "spot_pool_config": { "show_apr_tooltip": false + }, + "transfer_banner": { + "no_longer_supported_tokens": [], + "temporary_disabled_transfer_tokens": {}, + "temporary_disabled_bridges": {} } } \ No newline at end of file diff --git a/configs/mainnet.json b/configs/mainnet.json index 94b3eaf..b871920 100644 --- a/configs/mainnet.json +++ b/configs/mainnet.json @@ -500,5 +500,10 @@ "label_denom": "brdg/a02afc2c1edf77cc023eefa25fc036c184612faf9365cda9c1daa3b1675ebf8f", "target_denom": "brdg/a02afc2c1edf77cc023eefa25fc036c184612faf9365cda9c1daa3b1675ebf8f" } - ] -} \ No newline at end of file + ], + "transfer_banner": { + "no_longer_supported_tokens": [], + "temporary_disabled_transfer_tokens": {}, + "temporary_disabled_bridges": {} + } +} diff --git a/configs/testnet.json b/configs/testnet.json index 2d3c393..732779f 100644 --- a/configs/testnet.json +++ b/configs/testnet.json @@ -59,5 +59,10 @@ }, "spot_pool_config": { "show_apr_tooltip": false + }, + "transfer_banner": { + "no_longer_supported_tokens": [], + "temporary_disabled_transfer_tokens": {}, + "temporary_disabled_bridges": {} } } diff --git a/scripts/check_configs.ts b/scripts/check_configs.ts index c13f7d3..be01174 100644 --- a/scripts/check_configs.ts +++ b/scripts/check_configs.ts @@ -34,6 +34,7 @@ interface ConfigJSON { market_banners?: MarketBanner[]; market_promo?: {[marketId: string]: MarketPromo}; spot_pool_config?: SpotPoolConfig; + transfer_banner?: TransferBanner; } interface InvalidEntry { @@ -132,6 +133,22 @@ interface SpotPoolConfig { show_apr_tooltip: boolean; } +interface TransferBanner { + no_longer_supported_tokens: [], + temporary_disabled_transfer_tokens: { + [denom: string]: { + start: string, + end: string + } + }, + temporary_disabled_bridges: { + [bridgeAddress: string]: { + start: string, + end: string + } + } +} + type OutcomeMap = { [key in CarbonSDK.Network]: boolean }; // true = success, false = failure const outcomeMap: OutcomeMap = { @@ -201,7 +218,7 @@ function joinEntriesIntoStr(entriesArr: string[]): string { : entriesArr[0]; } -// check list of markets to ensure that it does not have blacklisted markets +// check list of markets to ensure that it does not have blacklisted markets function checkBlacklistedMarkets(marketData: string[], blacklistedMarkets: string[]): InvalidEntry { let overlappingMarkets: string[] = []; marketData.forEach(market => { @@ -420,6 +437,35 @@ function isValidMarketPromo(marketPromo: {[marketId: string]: MarketPromo}, netw return true; } +function isValidTransferBanner(transferBanner: TransferBanner, network: CarbonSDK.Network): boolean { + const { temporary_disabled_transfer_tokens, temporary_disabled_bridges } = transferBanner; + if (Object.keys(temporary_disabled_transfer_tokens).length > 0) { + Object.keys(temporary_disabled_transfer_tokens).map((key) => { + const { start, end } = temporary_disabled_transfer_tokens[key]; + const startTime = new Date(start); + const endTime = new Date(end); + if (endTime < startTime) { + console.error(`ERROR: ${network}.json has invalid end time (${end}) is before start time (${start}) for token denom ${key}.`); + return false; + } + }); + } + + if (Object.keys(temporary_disabled_bridges).length > 0) { + Object.keys(temporary_disabled_bridges).map((key) => { + const { start, end } = temporary_disabled_bridges[key]; + const startTime = new Date(start); + const endTime = new Date(end); + if (endTime < startTime) { + console.error(`ERROR: ${network}.json has invalid end time (${end}) is before start time (${start}) for bridge address ${key}.`); + return false; + } + }); + } + + return true +} + async function main() { for (const net of myArgs) { let network: CarbonSDK.Network; @@ -752,7 +798,7 @@ async function main() { if(jsonData.market_promo && !isValidMarketPromo(jsonData.market_promo, network, marketIds)) { outcomeMap[network] = false; } - + // check for spot pool config if (jsonData.spot_pool_config) { const spotPoolConfig = jsonData.spot_pool_config @@ -775,6 +821,11 @@ async function main() { const isDemexTradingLeagueConfigValid = isValidDemexTradingLeagueConfig(jsonData.demex_trading_league_config, network, marketIds, jsonData.blacklisted_markets, perpPoolIds, tokenSymbols) if (!isDemexTradingLeagueConfigValid) outcomeMap[network] = false; } + + // transfer banner check + if (jsonData.transfer_banner && !isValidTransferBanner(jsonData.transfer_banner, network)) { + outcomeMap[network] = false; + } } } const outcomeArr = Object.values(outcomeMap);