diff --git a/.github/markets/pr_template.md b/.github/markets/pr_template.md index 842e88e..a625be0 100644 --- a/.github/markets/pr_template.md +++ b/.github/markets/pr_template.md @@ -10,7 +10,6 @@ Each json file under the [configs](../../configs) folder correspond to their res |`blacklisted_markets` |`string[]` |true |The array of market names that are blacklisted. A market can be blacklisted for a number of reasons, such as it being invalid/duplicate/wrongly-added/etc. |The market names listed here **MUST** match the market names listed under the Carbon [Markets API](https://api.carbon.network/carbon/market/v1/markets?pagination.limit=10000). The market names listed here **CANNOT** be under the `prelaunch_markets` field at the same time. | |`blacklisted_pools` |`string[]` |true |The array of pool ids that are blacklisted. A pool can be blacklisted for a number of reasons, such as it being invalid/duplicate/wrongly-added/etc. |The pool ids listed here **MUST** match the pool ids listed under the Carbon [Liquidity Pool API](https://api.carbon.network/carbon/liquiditypool/v1/pools?pagination.limit=10000). | |`blacklisted_tokens` |`string[]` |true |The array of token denoms that are blacklisted. A token can be blacklisted for a number of reasons, such as it being invalid/deprecated/etc. |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). | -| `transfer_disabled_tokens` |`TransferDisabledTokens` |true |Object that contains tokens for which deposits and withdrawals are temporarily disabled | | | `token_name_override_map` |`object` |true |Object that contains token denoms and their respective token name overrides. This is used if we need to override the full token name of the tokens listed here. |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). | |`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.

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.

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`| @@ -26,17 +25,11 @@ 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 | |`quick_select_tokens` |`QuickSelectToken[]` |true |List of quick select tokens for deposit and withdrawal forms. | - -## TransferDisabledTokens Data Structure -|Field |Type |Required |Description |Notes | -|---|---|---|---|---| -|`deposit` |`string[]` |true |List of tokens for which deposits are temporarily disabled |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). | -|`withdraw` |`string[]` |true |List of tokens for which withdrawals are temporarily disabled |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). | -|`announcement_banner` |`AnnouncementBanner` |false |Custom announcement banner through all or only on specificed paths | +|`disabled_transfer_banner_config` |`DisabledTransferBannerConfig` |false |Config parameters for displaying banner to inform users that transfers for the relevant tokens are disabled | ## Maintenance Data Structure |Field |Type |Required |Description |Notes | @@ -96,19 +89,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 @@ -127,8 +120,8 @@ Each json file under the [configs](../../configs) folder correspond to their res |Field |Type |Required |Description |Notes | |---|---|---|---|---| |`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. | |`show_only_on` |`string[]` |true |Default is empty list, then banner will be shown on all pages |If list has specified path(s), the banner will be shown on these/that path(s) only, sample: `['/rewards', '/nitron']` | @@ -137,3 +130,10 @@ Each json file under the [configs](../../configs) folder correspond to their res |---|---|---|---|---| |`label_denom` |`string` |true |The default token will be show on UI deposit/withdrawal forms | |`target_denom` |`string` |true |The default token will be use to transfer in deposit/withdrawal | + +## DisabledTransferBannerConfig Data Structure +|Field |Type |Required |Description |Notes | +|---|---|---|---|---| +|`unsupported_tokens` |`string[]` |false |List of tokens that are no longer supported | The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000) | +|`temp_disabled_transfer_tokens` |`object` |false |List of tokens for which deposits and withdrawals have been temporarily disabled | The token denoms listed in this object **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000) | +|`temp_disabled_bridges` |`object` |false |List of bridges for which deposits and withdrawals have been temporarily disabled | Blockchain network listed here **MUST** match the valid chainName of the bridges listed under BridgeAll RPC call.

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`` | diff --git a/README.md b/README.md index ccb3137..e00971a 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,6 @@ More metadata will be added in the future if required by the Demex frontend. Ple "blacklisted_token_2", "blacklisted_token_3" ], - "transfer_disabled_tokens": [ - "transfer_disabled_token_1", - "transfer_disabled_token_2", - "transfer_disabled_token_3" - ], "token_name_override_map": { "token_1": "token_name_override_1", "token_2": "token_name_override_2" @@ -90,7 +85,7 @@ More metadata will be added in the future if required by the Demex frontend. Ple "baseDenom": "denom_3", "chainRoutes": ["blockchain_5", "blockchain_6"], "denomOnCarbon": "carbon_denom_1" - }], + }], "demex_trading_league_config": { "promoMarkets": [ "promo_market_1", @@ -99,6 +94,23 @@ More metadata will be added in the future if required by the Demex frontend. Ple ], "currentPrizeSymbol": "market_symbol", "currentCompPerpPoolId": 1 + }, + "disabled_transfer_banner_config": { + "unsupported_tokens": ["denom_1", "denom_2"], + "temp_disabled_transfer_tokens": { + "denom_1": { + "start": "", + "end": "" + } + }, + "temp_disabled_bridges": { + "bridge_address_1": { + "start": "", + "end": "" + }, + "src_channel": {}, // for ibcBridges + "connectionId": {} // for axelarBridges + } } } ``` diff --git a/config.schema.json b/config.schema.json index 277dd0d..6488c9d 100644 --- a/config.schema.json +++ b/config.schema.json @@ -8,7 +8,6 @@ "blacklisted_markets", "blacklisted_pools", "blacklisted_tokens", - "transfer_disabled_tokens", "token_name_override_map", "transfer_options", "network_fees", @@ -53,27 +52,6 @@ "$ref": "#/$defs/blacklisted_token" } }, - "transfer_disabled_tokens": { - "type": "object", - "description": "Object containing tokens for which deposits and withdrawals have been temporarily disabled", - "required": ["deposit", "withdraw"], - "properties": { - "deposit": { - "type": "array", - "description": "List of tokens for which deposits have been temporarily disabled", - "items": { - "type": "string" - } - }, - "withdraw": { - "type": "array", - "description": "List of tokens for which withdrawals have been temporarily disabled", - "items": { - "type": "string" - } - } - } - }, "token_name_override_map": { "type": "object", "description": "Object that contains token denoms and their respective token name overrides.", @@ -388,12 +366,12 @@ }, "start": { "type": "string", - "description": "The start time of perp pool promo", + "description": "The start time of the relevant program (in timestamp format)", "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", + "description": "The end time of the relevant program (in timestamp format)", "pattern": "^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$" }, "perpPoolDepositBoost": { @@ -584,6 +562,53 @@ "items": { "$ref": "#/$defs/quick_select_token" } + }, + "disabled_transfer_banner_config": { + "type": "object", + "description": "Config parameters for displaying banner to inform users that transfers for the relevant tokens are disabled", + "properties": { + "unsupported_tokens": { + "type": "array", + "description": "List of tokens are no longer supported", + "items": { + "type": "string" + } + }, + "temp_disabled_transfer_tokens": { + "type": "object", + "description": "List of tokens for which deposits and withdrawals have been temporarily disabled", + "patternProperties": { + ".*": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/start" + }, + "end": { + "$ref": "#/$defs/end" + } + } + } + } + }, + "temp_disabled_bridges": { + "type": "object", + "description": "List of bridges for which deposits and withdrawals have been temporarily disabled", + "patternProperties": { + ".*": { + "type": "object", + "properties": { + "start": { + "$ref": "#/$defs/start" + }, + "end": { + "$ref": "#/$defs/end" + } + } + } + } + } + } } } } \ No newline at end of file diff --git a/configs/devnet.json b/configs/devnet.json index 8540a65..6e8711a 100644 --- a/configs/devnet.json +++ b/configs/devnet.json @@ -8,10 +8,6 @@ ], "blacklisted_pools": [], "blacklisted_tokens": [], - "transfer_disabled_tokens": { - "deposit": [], - "withdraw": [] - }, "token_name_override_map": {}, "transfer_options": {}, "network_fees": { @@ -68,7 +64,7 @@ }, { "label_denom": "dai", - "target_denom" : "dai" + "target_denom" : "dai" } ] } \ No newline at end of file diff --git a/configs/mainnet.json b/configs/mainnet.json index ee9b14b..599fb0a 100644 --- a/configs/mainnet.json +++ b/configs/mainnet.json @@ -17,26 +17,6 @@ "usdc.1.6.e70e14", "bit.1.2.9d68c4" ], - "transfer_disabled_tokens": { - "deposit": [ - "nex.1.17.59c1ba", - "gmx.1.19.70275d", - "wbnb.1.6.ad598c", - "blur.1.2.0c0069", - "bnb.1.6.773edb", - "zbnb.1.18.c406be", - "usdc.1.17.851a3a" - ], - "withdraw": [ - "nex.1.17.59c1ba", - "gmx.1.19.70275d", - "wbnb.1.6.ad598c", - "blur.1.2.0c0069", - "bnb.1.6.773edb", - "zbnb.1.18.c406be", - "usdc.1.17.851a3a" - ] - }, "token_name_override_map": { "brdg/1299d2e94c483e72f64100088886b8a5b7c13595047e53e032c9938d07a98c20": "Ether (Arbitrum)", "brdg/e3877e2c8ed05e404e04417747e2f430285c11dc839663b943b39ff7cbb56377": "Ether (Ethereum)" diff --git a/configs/testnet.json b/configs/testnet.json index 3d76c22..5f212a7 100644 --- a/configs/testnet.json +++ b/configs/testnet.json @@ -10,10 +10,6 @@ ], "blacklisted_pools": [], "blacklisted_tokens": [], - "transfer_disabled_tokens": { - "deposit": [], - "withdraw": [] - }, "token_name_override_map": {}, "transfer_options": {}, "network_fees": { diff --git a/scripts/check_configs.ts b/scripts/check_configs.ts index 97be1b3..81168cf 100644 --- a/scripts/check_configs.ts +++ b/scripts/check_configs.ts @@ -1,5 +1,6 @@ -import { BlockchainUtils, CarbonSDK } from "carbon-js-sdk"; +import { CarbonSDK } from "carbon-js-sdk"; import { PageRequest } from "carbon-js-sdk/lib/codec/cosmos/base/query/v1beta1/pagination"; +import { BridgeMap } from "carbon-js-sdk/lib/util/blockchain"; import * as fs from "fs"; import Long from "long"; @@ -12,7 +13,6 @@ interface ConfigJSON { blacklisted_markets: string[]; blacklisted_pools: string[]; blacklisted_tokens: string[]; - transfer_disabled_tokens: TransferDisabledTokensObj; token_name_override_map: TokenNameOverrideMap; transfer_options: { [chainKey: string]: number; @@ -34,6 +34,7 @@ interface ConfigJSON { market_banners?: MarketBanner[]; market_promo?: {[marketId: string]: MarketPromo}; spot_pool_config?: SpotPoolConfig; + disabled_transfer_banner_config?: DisabledTransferBannerConfig; announcement_banner: AnnouncementBanner; quick_select_deposit_options?: QuickSelectToken[]; } @@ -61,11 +62,6 @@ interface PerpPoolBanner { subtext?: string; } -interface TransferDisabledTokensObj { - deposit: string[]; - withdraw: string[]; -} - type TokenNameOverrideMap = { [denom: string]: string; } @@ -134,6 +130,22 @@ interface SpotPoolConfig { show_apr_tooltip: boolean; } +interface DisabledTransferBannerConfig { + unsupported_tokens?: [], + temp_disabled_transfer_tokens?: { + [denom: string]: { + start?: string, + end?: string + } + }, + temp_disabled_bridges?: { + [bridgeAddress: string]: { + start?: string, + end?: string + } + } +} + interface AnnouncementBanner { show_from?: string; show_until?: string; @@ -216,7 +228,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 => { @@ -232,39 +244,6 @@ function checkBlacklistedMarkets(marketData: string[], blacklistedMarkets: strin }; } -function isValidTransferDisabledTokens(transferDisabledTokens: TransferDisabledTokensObj, denoms: string[], network: CarbonSDK.Network): boolean { - const dupDepositTknsOutcome = checkDuplicateEntries(transferDisabledTokens.deposit); - const dupWithdrawTknsOutcome = checkDuplicateEntries(transferDisabledTokens.withdraw); - - if (dupDepositTknsOutcome.status || dupWithdrawTknsOutcome.status) { - if (isErrorOutcome(dupDepositTknsOutcome)) { - const duplicateDepositTokensStr = joinEntriesIntoStr(dupDepositTknsOutcome.entry!); - console.error(`[ERROR] transfer_disabled_tokens.deposit of ${network}.json has the following duplicate token denoms: ${duplicateDepositTokensStr}. Please make sure to input each denom only once.`); - } - if (isErrorOutcome(dupWithdrawTknsOutcome)) { - const duplicateWithdrawTokensStr = joinEntriesIntoStr(dupWithdrawTknsOutcome.entry!); - console.error(`[ERROR] transfer_disabled_tokens.withdraw of ${network}.json has the following duplicate token denoms: ${duplicateWithdrawTokensStr}. Please make sure to input each denom only once.`); - } - return false; - } - - const validDepositTknsOutcome = checkValidEntries(transferDisabledTokens.deposit, denoms); - const validWithdrawTknsOutcome = checkValidEntries(transferDisabledTokens.withdraw, denoms); - if (validDepositTknsOutcome.status || dupWithdrawTknsOutcome.status) { - if (isErrorOutcome(validDepositTknsOutcome)) { - const invalidDepositTokensStr = joinEntriesIntoStr(validDepositTknsOutcome.entry!); - console.error(`[ERROR] transfer_disabled_tokens.deposit of ${network}.json has the following invalid token denoms: ${invalidDepositTokensStr}. Please make sure to input only valid token denoms.`); - } - if (isErrorOutcome(validWithdrawTknsOutcome)) { - const invalidWithdrawTokensStr = joinEntriesIntoStr(validWithdrawTknsOutcome.entry!); - console.error(`[ERROR] transfer_disabled_tokens.withdraw of ${network}.json has the following invalid token denoms: ${invalidWithdrawTokensStr}. Please make sure to input only valid token denoms.`); - } - return false; - } - - return true; -} - function isValidTokenNameOverrideMap(tokenNameOverrideMap: TokenNameOverrideMap, denoms: string[], network: CarbonSDK.Network): boolean { const denomKeysArr = Object.keys(tokenNameOverrideMap); const invalidDenomsOutcome = checkValidEntries(denomKeysArr, denoms); @@ -449,6 +428,67 @@ function isValidMarketPromo(marketPromo: {[marketId: string]: MarketPromo}, netw return true; } +function isValidDisabledTransferBannerConfig(transferBanner: DisabledTransferBannerConfig, denoms: string[], bridges: string[], network: CarbonSDK.Network): boolean { + const { unsupported_tokens = [], temp_disabled_transfer_tokens = {}, temp_disabled_bridges = {} } = transferBanner; + + if (unsupported_tokens.length > 0) { + const validUnsupportedTokensOutcome = checkValidEntries(unsupported_tokens, denoms); + + if (validUnsupportedTokensOutcome.status && isErrorOutcome(validUnsupportedTokensOutcome)) { + const invalidUnsupportedTokensStr = joinEntriesIntoStr(validUnsupportedTokensOutcome.entry!); + console.error(`[ERROR] disabled_transfer_banner_config.unsupported_tokens of ${network}.json has the following invalid token denoms: ${invalidUnsupportedTokensStr}. Please make sure to input only valid token denoms.`); + return false + } + } + + const disabledTokenKeys = Object.keys(temp_disabled_transfer_tokens) + if (disabledTokenKeys.length > 0) { + const validDisabledTknsOutcome = checkValidEntries(disabledTokenKeys, denoms); + + if (validDisabledTknsOutcome.status && isErrorOutcome(validDisabledTknsOutcome)) { + const invalidDisabledTokensStr = joinEntriesIntoStr(validDisabledTknsOutcome.entry!); + console.error(`[ERROR] disabled_transfer_banner_config.temp_disabled_transfer_tokens of ${network}.json has the following invalid token denoms: ${invalidDisabledTokensStr}. Please make sure to input only valid token denoms.`); + return false + } + + disabledTokenKeys.forEach((key) => { + const { start, end } = temp_disabled_transfer_tokens[key]; + if (end && start) { + const startTime = new Date(start); + const endTime = new Date(end); + if (endTime < startTime) { + console.error(`ERROR: disabled_transfer_banner_config.temp_disabled_transfer_tokens on ${network}.json has an invalid end time (${end}) for denom ${key} as it is before start time (${start}).`); + return false; + } + } + }); + } + + const disabledBridgeKeys = Object.keys(temp_disabled_bridges) + if (disabledBridgeKeys.length > 0) { + const validDisabledBridgesOutcome = checkValidEntries(disabledBridgeKeys, bridges); + if (validDisabledBridgesOutcome.status && isErrorOutcome(validDisabledBridgesOutcome)) { + const invalidDisabledBridgesStr = joinEntriesIntoStr(validDisabledBridgesOutcome.entry!); + console.error(`[ERROR] disabled_transfer_banner_config.temp_disabled_bridges of ${network}.json has the following invalid bridge addresses: ${invalidDisabledBridgesStr}. Please make sure to input only valid bridge addresses.`); + return false + } + + disabledBridgeKeys.forEach((key) => { + const { start, end } = temp_disabled_bridges[key]; + if (start && end) { + const startTime = new Date(start); + const endTime = new Date(end); + if (endTime < startTime) { + console.error(`ERROR: disabled_transfer_banner_config.temp_disabled_bridges on ${network}.json has an invalid end time (${end}) for bridge ${key} as it is before start time (${start}).`); + return false; + } + } + }); + } + + return true +} + function isValidQuickSelectTokens(quickSelectTokens: QuickSelectToken[], network: CarbonSDK.Network, denoms: string[]): boolean { const duplicateQuickSelectTokens = checkDuplicateEntries(quickSelectTokens.map(token => token.label_denom)); const invalidQuickSelectTokens = checkValidEntries(quickSelectTokens.map(token => token.label_denom), denoms); @@ -596,9 +636,27 @@ async function main() { outcomeMap[network] = false; } - // transfer disabled tokens object check - const isTransferDisabledTokensValid = isValidTransferDisabledTokens(jsonData.transfer_disabled_tokens, tokens, network); - if (!isTransferDisabledTokensValid) outcomeMap[network] = false; + // query all bridges + const bridgesMap: BridgeMap | undefined = sdk?.token?.bridges + let bridgesArr: string[] = [] + + const { polynetwork = [], ibc = [], axelar = [] } = bridgesMap ?? {} + const polynetworkBridges = polynetwork.reduce((acc: string[], bridge) => { + if (bridge.enabled) acc.push(...bridge.bridgeAddresses) + return acc + }, []) + + const axelarBridges = axelar.reduce((acc: string[], bridge) => { + if (bridge.enabled) acc.push(bridge.bridgeAddress) + return acc + }, []); + + const ibcBridges = ibc.reduce((acc: string[], bridge) => { + if (bridge.enabled) acc.push(bridge.channels.src_channel) + return acc + }, []); + + bridgesArr = polynetworkBridges.concat(ibcBridges).concat(axelarBridges) // token_name_override_map check const isTokenNameOverrideMapValid = isValidTokenNameOverrideMap(jsonData.token_name_override_map, tokens, network); @@ -807,11 +865,11 @@ async function main() { if(jsonData.market_promo && !isValidMarketPromo(jsonData.market_promo, network, marketIds)) { outcomeMap[network] = false; } - + if(jsonData.announcement_banner && !isValidAnnouncementBanner(jsonData.announcement_banner, network)) { outcomeMap[network] = false; } - + // check for spot pool config if (jsonData.spot_pool_config) { const spotPoolConfig = jsonData.spot_pool_config @@ -835,6 +893,11 @@ async function main() { if (!isDemexTradingLeagueConfigValid) outcomeMap[network] = false; } + // transfer banner check + if (jsonData.disabled_transfer_banner_config && !isValidDisabledTransferBannerConfig(jsonData.disabled_transfer_banner_config, tokens, bridgesArr, network)) { + outcomeMap[network] = false; + } + // check for validate quick select tokens if (jsonData.quick_select_deposit_options && !isValidQuickSelectTokens(jsonData.quick_select_deposit_options, network, tokens)) { outcomeMap[network] = false; diff --git a/scripts/get_all_bridges.ts b/scripts/get_all_bridges.ts index 96b2e4e..d7b69b1 100644 --- a/scripts/get_all_bridges.ts +++ b/scripts/get_all_bridges.ts @@ -1,5 +1,6 @@ -import { CarbonSDK } from "carbon-js-sdk"; +import { Carbon, CarbonSDK } from "carbon-js-sdk"; import { PageRequest } from "carbon-js-sdk/lib/codec/cosmos/base/query/v1beta1/pagination"; +import { BRIDGE_IDS } from "carbon-js-sdk/lib/util/blockchain"; import Long from "long"; const myArgs = process.argv.slice(2); @@ -22,10 +23,33 @@ const myArgs = process.argv.slice(2); } const sdk = await CarbonSDK.instance({ network }); - const bridges = await sdk.query.coin.BridgeAll({ + const legacyBridges = await sdk.query.coin.BridgeAll({ pagination: PageRequest.fromPartial({ limit: new Long(10000), }), - }) - console.log(bridges) + }); + const axelarBridges = await sdk.query.bridge.ConnectionAll( + Carbon.Bridge.QueryAllConnectionsRequest.fromPartial({ + pagination: PageRequest.fromPartial({ + limit: new Long(10000), + }), + }) + ); + + console.log("Chain Name | Bridge Name | Bridge Address(es)") + + legacyBridges.bridges.forEach((bridge: Carbon.Coin.Bridge) => { + if (!bridge.enabled) return; + + let bridgeAddressStr = JSON.stringify(bridge.bridgeAddresses); + if (bridge.bridgeId.eq(BRIDGE_IDS.ibc)) { + bridgeAddressStr = `channel-${bridge.chainId.subtract(1).toString(10)}`; + } + console.log(`${bridge.chainName} | ${bridge.bridgeName} | ${bridgeAddressStr}`); + }); + + axelarBridges.connections.forEach((bridge: Carbon.Bridge.Connection) => { + if (!bridge.isEnabled) return; + console.log(`${bridge.chainDisplayName} | Axelar | ${bridge.connectionId}`); + }); })().catch(console.error).finally(() => process.exit(0));