row.toggleExpanded()}>
@@ -56,7 +59,7 @@ export const ActionsRow = ({ row, type }: Props) => {
text={
}
size='small'
text={t('redbank.deposit')}
@@ -64,12 +67,14 @@ export const ActionsRow = ({ row, type }: Props) => {
/>
}
tooltip={
- hasBalance
- ? null
- : t('redbank.toDepositAssetOnChain', {
+ !assetPrice
+ ? t('redbank.noPriceAvailable', { symbol: row.original.symbol })
+ : !hasBalance
+ ? t('redbank.toDepositAssetOnChain', {
asset: assetID,
chain: chainInfo?.name,
})
+ : null
}
/>
{hasDeposits && (
@@ -131,16 +136,20 @@ export const ActionsRow = ({ row, type }: Props) => {
}
- disabled={row.original.marketLiquidity === '0' || hasNeverDeposited}
+ disabled={
+ row.original.marketLiquidity === '0' || hasNeverDeposited || !assetPrice
+ }
size='small'
text={t('common.borrow')}
onClick={() => router.push(`/redbank/borrow/${assetID}`)}
/>
}
tooltip={
- row.original.marketLiquidity === '0' || hasNeverDeposited
+ row.original.marketLiquidity === '0' || hasNeverDeposited || !assetPrice
? hasNeverDeposited
? t('redbank.warning.borrow')
+ : !assetPrice
+ ? t('redbank.noPriceAvailable', { symbol: row.original.symbol })
: t('redbank.notEnoughMarketLiquidity')
: null
}
diff --git a/src/components/redbank/BorrowColumns/useBorrowColumns.module.scss b/src/components/redbank/BorrowColumns/useBorrowColumns.module.scss
deleted file mode 100644
index 0ff0d6e..0000000
--- a/src/components/redbank/BorrowColumns/useBorrowColumns.module.scss
+++ /dev/null
@@ -1,44 +0,0 @@
-@import 'src/styles/master';
-
-.color {
- position: absolute;
- top: 0;
- width: rem-calc(7);
- height: space(16);
- margin-left: rem-calc(-7);
-
- &.OSMO {
- background-image: $colorGradientOSMO;
- }
-
- &.ATOM {
- background-image: $colorGradientATOM;
- }
-
- &.AXL {
- background-image: $colorGradientAXL;
- }
-
- &.JUNO {
- background-image: $colorGradientJUNO;
- }
-
- &.axlUSDC,
- &.nUSDC {
- background-image: $colorGradientAxlUSDC;
- }
-
- &.axlWBTC {
- background-image: $colorGradientAxlWBTC;
- }
-
- &.axlWETH {
- background-image: $colorGradientAxlWETH;
- }
-}
-
-.logo {
- display: grid;
- margin: auto;
- width: rem-calc(32);
-}
diff --git a/src/components/redbank/BorrowColumns/useBorrowColumns.tsx b/src/components/redbank/BorrowColumns/useBorrowColumns.tsx
index ade9b44..53a9895 100644
--- a/src/components/redbank/BorrowColumns/useBorrowColumns.tsx
+++ b/src/components/redbank/BorrowColumns/useBorrowColumns.tsx
@@ -5,7 +5,7 @@ import { useMemo } from 'react'
import { isMobile, isTablet } from 'react-device-detect'
import { useTranslation } from 'react-i18next'
-import styles from './useBorrowColumns.module.scss'
+import styles from '../RedbankColumns.module.scss'
export const useBorrowColumns = () => {
const { t } = useTranslation()
@@ -19,7 +19,7 @@ export const useBorrowColumns = () => {
header: '',
cell: (info) => (
diff --git a/src/components/redbank/DepositColumns/useDepositColumns.tsx b/src/components/redbank/DepositColumns/useDepositColumns.tsx
index 3286939..8b2d828 100644
--- a/src/components/redbank/DepositColumns/useDepositColumns.tsx
+++ b/src/components/redbank/DepositColumns/useDepositColumns.tsx
@@ -8,7 +8,7 @@ import { useMemo } from 'react'
import { isMobile, isTablet } from 'react-device-detect'
import { useTranslation } from 'react-i18next'
-import styles from './useDepositColumns.module.scss'
+import styles from '../RedbankColumns.module.scss'
export const useDepositColumns = () => {
const { t } = useTranslation()
@@ -23,7 +23,7 @@ export const useDepositColumns = () => {
header: '',
cell: (info) => (
diff --git a/src/components/redbank/RedbankAction/RedbankAction.tsx b/src/components/redbank/RedbankAction/RedbankAction.tsx
index ad9e615..edfd963 100644
--- a/src/components/redbank/RedbankAction/RedbankAction.tsx
+++ b/src/components/redbank/RedbankAction/RedbankAction.tsx
@@ -69,7 +69,7 @@ export const RedbankAction = React.memo(
// Read only states
const borrowAssetName = redBankAssets.find((asset) => asset.denom === denom)
- const redBankContractAddress = networkConfig?.contracts.redBank
+ const redBankContractAddress = networkConfig.contracts.redBank
const totalScaledDepositbaseCurrencyBalance = useMemo(() => {
if (!userCollateral) return 0
return ltvWeightedDepositValue(
diff --git a/src/components/redbank/DepositColumns/useDepositColumns.module.scss b/src/components/redbank/RedbankColumns.module.scss
similarity index 79%
rename from src/components/redbank/DepositColumns/useDepositColumns.module.scss
rename to src/components/redbank/RedbankColumns.module.scss
index b5e26c8..0a67ff6 100644
--- a/src/components/redbank/DepositColumns/useDepositColumns.module.scss
+++ b/src/components/redbank/RedbankColumns.module.scss
@@ -7,38 +7,42 @@
height: space(16);
@include margin(0, 0, 0, -2);
- &.OSMO {
+ &.osmo {
background-image: $colorGradientOSMO;
}
- &.ATOM {
+ &.atom {
background-image: $colorGradientATOM;
}
- &.AXL {
+ &.axl {
background-image: $colorGradientAXL;
}
- &.JUNO {
+ &.juno {
background-image: $colorGradientJUNO;
}
- &.axlUSDC,
- &.nUSDC {
+ &.axlusdc,
+ &.nusdc {
background-image: $colorGradientAxlUSDC;
}
- &.stATOM {
+ &.statom {
background-image: $colorGradientStATOM;
}
- &.axlWBTC {
+ &.axlwbtc {
background-image: $colorGradientAxlWBTC;
}
- &.axlWETH {
+ &.axlweth {
background-image: $colorGradientAxlWETH;
}
+
+ &.ntrn {
+ background-image: $colorGradientNTRN;
+ }
}
.logo {
diff --git a/src/configs/osmo-test-5.ts b/src/configs/osmo-test-5.ts
index 4ec4dd0..1996538 100644
--- a/src/configs/osmo-test-5.ts
+++ b/src/configs/osmo-test-5.ts
@@ -1,5 +1,4 @@
-import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
-import { URL_GQL, URL_REST, URL_RPC } from 'constants/env'
+import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg'
@@ -8,7 +7,7 @@ import nusdc from 'images/nusdc.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
-export const ASSETS: { [denom: string]: Asset } = {
+const ASSETS: NetworkAssets = {
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
@@ -17,6 +16,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.osmo,
logo: osmo,
decimals: 6,
+ priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
atom: {
symbol: 'ATOM',
@@ -26,6 +26,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.atom,
logo: atom,
decimals: 6,
+ priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
axl: {
symbol: 'AXL',
@@ -44,6 +45,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: axlusdc,
+ priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
nusdc: {
symbol: 'USDC.n',
@@ -53,6 +55,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: nusdc,
+ priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
}
@@ -60,10 +63,12 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
name: 'Mars',
- denom: 'ibc/DB9D326CF53EA07610C394D714D78F8BB4DC7E312D4213193791A9046BF45E20',
+ id: 'MARS',
+ denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
color: colors.mars,
logo: mars,
decimals: 6,
+ poolId: 9,
},
usd: {
symbol: '',
@@ -77,20 +82,23 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
}
export const NETWORK_CONFIG: NetworkConfig = {
- name: ChainInfoID.OsmosisTestnet5,
+ name: ChainInfoID.OsmosisTestnet,
+ displayName: 'Osmosis Testnet',
hiveUrl:
- URL_GQL ??
+ process.env.NEXT_PUBLIC_OSMOSIS_TEST_GQL ??
'https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql',
- rpcUrl: URL_RPC ?? 'https://rpc.osmotest5.osmosis.zone/',
- restUrl: URL_REST ?? 'https://lcd.osmotest5.osmosis.zone/',
+ rpcUrl: process.env.NEXT_PUBLIC_OSMOSIS_TEST_RPC ?? 'https://rpc.osmotest5.osmosis.zone/',
+ restUrl: process.env.NEXT_PUBLIC_OSMOSIS_TEST_REST ?? 'https://lcd.osmotest5.osmosis.zone/',
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-5',
- osmoUsdPriceUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
+ usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
+ chainIcon: osmo,
contracts: {
redBank: 'osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u',
incentives: 'osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d',
- oracle: 'osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2',
+ oracle: 'osmo1tx9987hjkx3kc9jvxmdzaf9uz8ukzscl88c476r7854205rkhecsc20tnk',
creditManager: 'osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp',
accountNft: 'osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4',
+ pyth: 'osmo12u2vqdecdte84kg6c3d40nwzjsya59hsj048n687m9q3t6wdmqgsq6zrlx',
},
assets: {
base: ASSETS.osmo,
@@ -108,7 +116,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://testnet.osmosis.zone',
- wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation],
+ isFieldsEnabled: true,
}
export const VAULT_CONFIGS: Vault[] = [
diff --git a/src/configs/osmosis-1.ts b/src/configs/osmosis-1.ts
index 19f1f16..8994137 100644
--- a/src/configs/osmosis-1.ts
+++ b/src/configs/osmosis-1.ts
@@ -1,5 +1,4 @@
-import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
-import { URL_GQL, URL_REST, URL_RPC } from 'constants/env'
+import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg'
@@ -10,7 +9,7 @@ import osmo from 'images/osmo.svg'
import statom from 'images/statom.svg'
import colors from 'styles/_assets.module.scss'
-export const ASSETS: { [denom: string]: Asset } = {
+const ASSETS: NetworkAssets = {
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
@@ -19,6 +18,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.osmo,
logo: osmo,
decimals: 6,
+ priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
axlusdc: {
symbol: 'USDC.axl',
@@ -28,6 +28,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: axlusdc,
+ priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
axlwbtc: {
symbol: 'WBTC.axl',
@@ -37,6 +38,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.wbtc,
logo: axlwbtc,
decimals: 8,
+ priceFeedId: 'e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
},
axlweth: {
symbol: 'WETH.axl',
@@ -46,6 +48,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.weth,
logo: axlweth,
decimals: 18,
+ priceFeedId: 'ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace',
},
atom: {
symbol: 'ATOM',
@@ -55,6 +58,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.atom,
logo: atom,
decimals: 6,
+ priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
axl: {
symbol: 'AXL',
@@ -64,6 +68,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.axl,
logo: axl,
decimals: 6,
+ priceFeedId: '60144b1d5c9e9851732ad1d9760e3485ef80be39b984f6bf60f82b28a2b7f126',
},
statom: {
symbol: 'stATOM',
@@ -73,7 +78,6 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.statom,
logo: statom,
decimals: 6,
- poolBase: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
},
}
@@ -81,6 +85,7 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
name: 'Mars',
+ id: 'MARS',
denom: 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580',
color: colors.mars,
logo: mars,
@@ -100,12 +105,15 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.Osmosis1,
+ displayName: 'Osmosis',
hiveUrl:
- URL_GQL ?? 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql',
- rpcUrl: URL_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
- restUrl: URL_REST ?? 'https://lcd-osmosis.blockapsis.com/',
+ process.env.NEXT_PUBLIC_OSMOSIS_GQL ??
+ 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql',
+ rpcUrl: process.env.NEXT_PUBLIC_OSMOSIS_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
+ restUrl: process.env.NEXT_PUBLIC_OSMOSIS_REST ?? 'https://lcd-osmosis.blockapsis.com/',
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmosis-1',
- osmoUsdPriceUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
+ usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
+ chainIcon: osmo,
contracts: {
redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg',
incentives: 'osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm',
@@ -138,15 +146,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://app.osmosis.zone',
- wallets: [
- WalletID.Keplr,
- WalletID.Xdefi,
- WalletID.StationWallet,
- WalletID.Leap,
- WalletID.Cosmostation,
- WalletID.KeplrMobile,
- WalletID.CosmostationMobile,
- ],
+ isFieldsEnabled: true,
}
export const VAULT_CONFIGS: Vault[] = [
@@ -234,4 +234,60 @@ export const VAULT_CONFIGS: Vault[] = [
vaultAddress: '',
},
},
+ {
+ address: 'osmo185gqewrlde8vrqw7j8lpad67v8jfrx9u7770k9q87tqqecctp5tq50wt2c',
+ name: { name: 'OSMO-WBTC.axl', unlockDuration: 14, unlockTimeframe: 'days' },
+ denoms: {
+ primary: 'uosmo',
+ secondary: 'ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F',
+ lpToken: 'gamm/pool/712',
+ },
+ symbols: {
+ primary: 'OSMO',
+ secondary: 'WBTC.axl',
+ },
+ color: colors.wbtc,
+ lockup: 86400 * 14,
+ provider: 'Apollo vault',
+ description: { maxLeverage: 2.44, lpName: 'OSMO-WBTC.axl' },
+ ltv: {
+ max: 0.58,
+ contract: 0.59,
+ liq: 0.62,
+ },
+ apy: {
+ apys: null,
+ fees: null,
+ total: null,
+ vaultAddress: '',
+ },
+ },
+ {
+ address: 'osmo1r235f4tdkwrsnj3mdm9hf647l754y6g6xsmz0nas5r4vr5tda3qsgtftef',
+ name: { name: 'OSMO-WETH.axl', unlockDuration: 14, unlockTimeframe: 'days' },
+ denoms: {
+ primary: 'uosmo',
+ secondary: 'ibc/EA1D43981D5C9A1C4AAEA9C23BB1D4FA126BA9BC7020A25E0AE4AA841EA25DC5',
+ lpToken: 'gamm/pool/704',
+ },
+ symbols: {
+ primary: 'OSMO',
+ secondary: 'WETH.axl',
+ },
+ color: colors.weth,
+ lockup: 86400 * 14,
+ provider: 'Apollo vault',
+ description: { maxLeverage: 2.86, lpName: 'OSMO-WETH.axl' },
+ ltv: {
+ max: 0.645,
+ contract: 0.65,
+ liq: 0.67,
+ },
+ apy: {
+ apys: null,
+ fees: null,
+ total: null,
+ vaultAddress: '',
+ },
+ },
]
diff --git a/src/configs/pion-1.ts b/src/configs/pion-1.ts
new file mode 100644
index 0000000..d1fb774
--- /dev/null
+++ b/src/configs/pion-1.ts
@@ -0,0 +1,84 @@
+import { ChainInfoID } from '@marsprotocol/wallet-connector'
+import atom from 'images/atom.svg'
+import axlusdc from 'images/axlusdc.svg'
+import mars from 'images/mars.svg'
+import ntrn from 'images/ntrn.svg'
+import colors from 'styles/_assets.module.scss'
+
+export const ASSETS: NetworkAssets = {
+ ntrn: {
+ symbol: 'NTRN',
+ name: 'Neutron',
+ id: 'NTRN',
+ denom: 'untrn',
+ color: colors.ntrn,
+ logo: ntrn,
+ decimals: 6,
+ },
+ atom: {
+ symbol: 'ATOM',
+ name: 'Atom',
+ id: 'ATOM',
+ denom: 'ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9',
+ color: colors.atom,
+ logo: atom,
+ decimals: 6,
+ },
+ axlusdc: {
+ symbol: 'USDC.axl',
+ name: 'Axelar USDC',
+ id: 'axlUSDC',
+ denom: 'ibc/EFB00E728F98F0C4BBE8CA362123ACAB466EDA2826DC6837E49F4C1902F21BBA',
+ color: colors.usdc,
+ decimals: 6,
+ logo: axlusdc,
+ },
+}
+
+const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
+ mars: {
+ symbol: 'MARS',
+ id: 'MARS',
+ name: 'Mars',
+ denom: 'ibc/FAD9EE91F499D275D9135F95F52D59D90C621B8438A9CFF1757BB886EEE90E3E',
+ color: colors.mars,
+ logo: mars,
+ decimals: 6,
+ },
+ usd: {
+ symbol: '',
+ prefix: '$',
+ name: 'US Dollar',
+ denom: 'usd',
+ color: '',
+ logo: '',
+ decimals: 2,
+ },
+}
+
+export const NETWORK_CONFIG: NetworkConfig = {
+ name: ChainInfoID.NeutronTestnet,
+ displayName: 'Neutron Testnet',
+ hiveUrl:
+ process.env.NEXT_PUBLIC_NEUTRON_TEST_GQL ??
+ 'https://testnet-neutron-gql.marsprotocol.io/graphql',
+ rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_RPC ?? 'https://rpc-palvus.pion-1.ntrn.tech/',
+ restUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_REST ?? 'https://rest-palvus.pion-1.ntrn.tech/',
+ chainIcon: ntrn,
+ contracts: {
+ redBank: 'neutron15dld0kmz0zl89zt4yeks4gy8mhmawy3gp4x5rwkcgkj5krqvu9qs4q7wve',
+ incentives: 'neutron1t8fectc2ntxhuee2f9ty2mxh8l0ykzm6yxfsp9k35vdktksm2vfsd2d6rl',
+ oracle: 'neutron1nx9txtmpmkt58gxka20z72wdkguw4n0606zkeqvelv7q7uc06zmsym3qgx',
+ },
+ assets: {
+ base: ASSETS.ntrn,
+ whitelist: [ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc],
+ other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars],
+ currencies: [OTHER_ASSETS.usd, ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc, OTHER_ASSETS.mars],
+ },
+ displayCurrency: OTHER_ASSETS.usd,
+ appUrl: 'https://app.astroport.fi/swap',
+ isFieldsEnabled: false,
+}
+
+export const VAULT_CONFIGS: Vault[] = []
diff --git a/src/constants/appConstants.ts b/src/constants/appConstants.ts
index a4fc8a3..85ddafe 100644
--- a/src/constants/appConstants.ts
+++ b/src/constants/appConstants.ts
@@ -1,3 +1,5 @@
+import { ChainInfoID } from '@marsprotocol/wallet-connector'
+
/* cosmos:network */
export const FORUM_URL = 'https://forum.marsprotocol.io/'
@@ -14,11 +16,6 @@ export const SESSION_WALLET_KEY = 'shuttle'
export const SWAP_THRESHOLD = 10
export const VAULT_DEPOSIT_BUFFER = 0.99
export const GAS_ADJUSTMENT = 1.3
-export const GAS_PRICE = '0.025uosmo'
-
-/* feature flags */
-export const FIELDS_FEATURE = true
-export const PROPOSAL_ACTION_BUTTONS_FEATURE = false
/* fields query keys */
export const CONFIG = 'config'
@@ -37,4 +34,12 @@ export const FIELDS_TUTORIAL_KEY = 'fieldsHideTutorial'
export const RED_BANK_TUTORIAL_KEY = 'redbankHideTutorial'
export const DISPLAY_CURRENCY_KEY = 'displayCurrency'
export const ENABLE_ANIMATIONS_KEY = 'enableAnimations'
+export const CHAIN_ID_KEY = 'currentChainId'
export const TERMS_OF_SERVICE = 'termsOfService'
+
+/* chains */
+export const SUPPORTED_CHAINS: { chainId: ChainInfoID; type: 'testnet' | 'mainnet' }[] = [
+ { chainId: ChainInfoID.Osmosis1, type: 'mainnet' },
+ { chainId: ChainInfoID.OsmosisTestnet, type: 'testnet' },
+ { chainId: ChainInfoID.NeutronTestnet, type: 'testnet' },
+]
diff --git a/src/functions/fields/getTokenValueFromCoins.ts b/src/functions/fields/getTokenValueFromCoins.ts
index 18db90b..ef849e8 100644
--- a/src/functions/fields/getTokenValueFromCoins.ts
+++ b/src/functions/fields/getTokenValueFromCoins.ts
@@ -9,13 +9,6 @@ export const getTokenValueFromCoins = (assets: Asset[], coins: Coin[] = []) => {
const convertedValue = lookup(Number(token.amount), asset.symbol, asset.decimals)
- return formatValue(
- convertedValue,
- 2,
- asset.decimals,
- true,
- convertedValue >= 0.01 ? false : '>',
- ` ${asset.symbol}`,
- )
+ return formatValue(convertedValue, 2, asset.decimals, true, false, ` ${asset.symbol}`)
})
}
diff --git a/src/functions/index.ts b/src/functions/index.ts
index 91daf8a..6c6ac2b 100644
--- a/src/functions/index.ts
+++ b/src/functions/index.ts
@@ -4,5 +4,6 @@ export { findByDenom } from './findByDenom'
export { formatToValueSymbol } from './formatToValueSymbol'
export { getFeeFromResponse } from './getFeeFromResponse'
export { getSwapUrl } from './getSwapUrl'
+export { updateAssetPrices } from './updateAssetPrices'
export { updateExchangeRate } from './updateExchangeRate'
// @endindex
diff --git a/src/functions/redbank/produceUpdatedAssetData.test.tsx b/src/functions/redbank/produceUpdatedAssetData.test.tsx
index 4ae115d..fe66218 100644
--- a/src/functions/redbank/produceUpdatedAssetData.test.tsx
+++ b/src/functions/redbank/produceUpdatedAssetData.test.tsx
@@ -12,6 +12,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@@ -27,6 +28,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(2)
expect(assets[1]).toEqual({
@@ -42,6 +44,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(2)
expect(assets[1]).toEqual({
@@ -59,6 +62,7 @@ describe('produceUpdatedAssetData', () => {
50,
ViewType.Deposit,
'depositBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@@ -74,6 +78,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'depositBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@@ -92,6 +97,7 @@ describe('produceUpdatedAssetData', () => {
50,
ViewType.Borrow,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@@ -107,6 +113,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Borrow,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@@ -125,6 +132,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Repay,
'borrowBalanceBaseCurrency',
+ 6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
diff --git a/src/functions/redbank/produceUpdatedAssetData.ts b/src/functions/redbank/produceUpdatedAssetData.ts
index dd8fd35..e56d43c 100644
--- a/src/functions/redbank/produceUpdatedAssetData.ts
+++ b/src/functions/redbank/produceUpdatedAssetData.ts
@@ -1,3 +1,4 @@
+import { demagnify } from 'libs/parse'
import { ViewType } from 'types/enums'
export const produceUpdatedAssetData = (
@@ -7,6 +8,7 @@ export const produceUpdatedAssetData = (
updateAmount: number,
activeView: ViewType,
key: 'depositBalanceBaseCurrency' | 'borrowBalanceBaseCurrency',
+ baseCurrencyDecimals: number,
) => {
const alreadyPresent = assetData.some((asset: RedBankAsset) => asset.denom === denom)
// For first use, when the user has no borrow balance yet and this list will be empty
@@ -14,15 +16,19 @@ export const produceUpdatedAssetData = (
const asset = redBankAssets.find((redBankAsset) => redBankAsset.denom === denom)
if (!asset) return assetData
+ const additionalDecimals = asset.decimals - baseCurrencyDecimals
+ const amountAdjustedForDecimals = demagnify(updateAmount, additionalDecimals)
// We are only interested in display currency balance. The asset will update post tx.
assetData.push({
...asset,
- [key]: updateAmount,
+ [key]: amountAdjustedForDecimals,
})
return assetData
}
return assetData.map((asset) => {
+ const additionalDecimals = asset.decimals - baseCurrencyDecimals
+ const amountAdjustedForDecimals = demagnify(updateAmount, additionalDecimals)
const newAsset = { ...asset }
const assetbaseCurrencyBalance = asset[key] || 0
let updatedAssetbaseCurrencyBalance = asset[key]
@@ -31,8 +37,8 @@ export const produceUpdatedAssetData = (
// if we are repaaying or redeeming, we decrease the amount
updatedAssetbaseCurrencyBalance =
activeView === ViewType.Borrow || activeView === ViewType.Deposit
- ? assetbaseCurrencyBalance + updateAmount
- : assetbaseCurrencyBalance - updateAmount
+ ? assetbaseCurrencyBalance + amountAdjustedForDecimals
+ : assetbaseCurrencyBalance - amountAdjustedForDecimals
}
newAsset[key] = updatedAssetbaseCurrencyBalance
return newAsset
diff --git a/src/functions/updateAssetPrices.ts b/src/functions/updateAssetPrices.ts
new file mode 100644
index 0000000..f36c9cb
--- /dev/null
+++ b/src/functions/updateAssetPrices.ts
@@ -0,0 +1,12 @@
+import { Coin } from '@cosmjs/proto-signing'
+
+export const updateAssetPrices = (coin: Coin, assetPricesUSD: Coin[], override?: boolean) => {
+ const assetIndex = assetPricesUSD.findIndex((asset) => asset.denom === coin.denom)
+ if (assetIndex > -1) {
+ if (Number(coin.amount) > 0 && override) assetPricesUSD[assetIndex] = coin
+ } else {
+ if (Number(coin.amount) > 0) assetPricesUSD.push(coin)
+ }
+
+ return assetPricesUSD
+}
diff --git a/src/hooks/mutations/useCreateCreditAccount.tsx b/src/hooks/mutations/useCreateCreditAccount.tsx
index f5eb5f0..76816e3 100644
--- a/src/hooks/mutations/useCreateCreditAccount.tsx
+++ b/src/hooks/mutations/useCreateCreditAccount.tsx
@@ -9,12 +9,13 @@ export const useCreateCreditAccount = () => {
return useMutation(async (fee: StdFee) => {
const message = { create_credit_account: {} }
+ const creditManagerAddress = networkConfig.contracts?.creditManager
- if (!networkConfig) return null
+ if (!creditManagerAddress) return null
return executeMsg({
msg: message,
fee,
- contract: networkConfig.contracts.creditManager,
+ contract: creditManagerAddress,
}).then((broadcastResult) => {
if (broadcastResult) {
try {
diff --git a/src/hooks/mutations/useUpdateAccount.tsx b/src/hooks/mutations/useUpdateAccount.tsx
index bc292d7..b6dfe48 100644
--- a/src/hooks/mutations/useUpdateAccount.tsx
+++ b/src/hooks/mutations/useUpdateAccount.tsx
@@ -16,6 +16,7 @@ export const useUpdateAccount = () => {
const executeMsg = useStore((s) => s.executeMsg)
const networkConfig = useStore((s) => s.networkConfig)
const getVaults = useStore((s) => s.getVaults)
+ const creditManagerAddress = networkConfig.contracts?.creditManager
return useMutation(async (props: Props) => {
queryClient.removeQueries([QUERY_KEYS.ESTIMATE_FARM_FEE])
@@ -26,12 +27,12 @@ export const useUpdateAccount = () => {
},
}
- if (!networkConfig) return
+ if (!creditManagerAddress) return
return executeMsg({
msg: message,
fee: props.fee,
- contract: networkConfig.contracts.creditManager,
+ contract: creditManagerAddress,
funds: props.funds,
}).then((broadcastResult) => {
if (broadcastResult?.response.code === 0) {
diff --git a/src/hooks/queries/index.ts b/src/hooks/queries/index.ts
index 9cde6c1..11e2bc0 100644
--- a/src/hooks/queries/index.ts
+++ b/src/hooks/queries/index.ts
@@ -7,6 +7,7 @@ export { useEstimateFarmFee } from './useEstimateFarmFee'
export { useEstimateFee } from './useEstimateFee'
export { useMarsOracle } from './useMarsOracle'
export { useProvideLiquidity } from './useProvideLiquidity'
+export { usePythVaa } from './usePythVaa'
export { useRedBank } from './useRedBank'
export { useRepayPosition } from './useRepayPosition'
export { useRequestUnlockPosition } from './useRequestUnlockPosition'
diff --git a/src/hooks/queries/useBlockHeight.tsx b/src/hooks/queries/useBlockHeight.tsx
index 45adf9b..4cfc911 100644
--- a/src/hooks/queries/useBlockHeight.tsx
+++ b/src/hooks/queries/useBlockHeight.tsx
@@ -24,7 +24,7 @@ export interface BlockHeightData {
}
export const useBlockHeight = () => {
- const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
+ const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const processBlockHeightQuery = useStore((s) => s.processBlockHeightQuery)
useQuery(
[QUERY_KEYS.BLOCK_HEIGHT],
diff --git a/src/hooks/queries/useDepositAndDebt.tsx b/src/hooks/queries/useDepositAndDebt.tsx
index 5dacfd6..ac9d141 100644
--- a/src/hooks/queries/useDepositAndDebt.tsx
+++ b/src/hooks/queries/useDepositAndDebt.tsx
@@ -25,13 +25,15 @@ export interface DepositAndDebtData {
axlWETHDebt: string
stATOMDeposits: string
stATOMDebt: string
+ NTRNDeposits: string
+ NTRNDebt: string
}
}
export const useDepositAndDebt = () => {
- const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
+ const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
- const redBankAddress = useStore((s) => s.networkConfig?.contracts.redBank) || ''
+ const redBankAddress = useStore((s) => s.networkConfig.contracts.redBank) || ''
const marketInfo = useStore((s) => s.marketInfo)
const processDepositAndDebtQuery = useStore((s) => s.processDepositAndDebtQuery)
diff --git a/src/hooks/queries/useEditPosition.tsx b/src/hooks/queries/useEditPosition.tsx
index f6177d2..63e643c 100644
--- a/src/hooks/queries/useEditPosition.tsx
+++ b/src/hooks/queries/useEditPosition.tsx
@@ -148,18 +148,19 @@ export const useEditPosition = (props: Props) => {
const primaryBaseAmount = convertToBaseCurrency({
denom: props.vault.denoms.primary,
- amount: String(editPosition.amounts.primary + editPosition.amounts.borrowedPrimary),
+ amount: (editPosition.amounts.primary + editPosition.amounts.borrowedPrimary).toString(),
})
const secondaryBaseAmount = convertToBaseCurrency({
denom: props.vault.denoms.secondary,
- amount: String(editPosition.amounts.secondary + editPosition.amounts.borrowedSecondary),
+ amount: (editPosition.amounts.secondary + editPosition.amounts.borrowedSecondary).toString(),
})
const swapMessage: Action[] = []
// If difference is larger than 10 ubase, initiate a swap
const difference = primaryBaseAmount - secondaryBaseAmount
+
if (Math.abs(difference) > SWAP_THRESHOLD) {
const inputDenom = difference > 0 ? props.vault.denoms.primary : props.vault.denoms.secondary
const outputDenom = difference < 0 ? props.vault.denoms.primary : props.vault.denoms.secondary
diff --git a/src/hooks/queries/useEstimateFarmFee.tsx b/src/hooks/queries/useEstimateFarmFee.tsx
index 3053669..b7513c2 100644
--- a/src/hooks/queries/useEstimateFarmFee.tsx
+++ b/src/hooks/queries/useEstimateFarmFee.tsx
@@ -2,6 +2,7 @@ import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { GAS_ADJUSTMENT } from 'constants/appConstants'
+import { getPythVaaMessage } from 'libs/pyth'
import useStore from 'store'
import { QUERY_KEYS } from 'types/enums/queryKeys'
import { Action, Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
@@ -18,34 +19,45 @@ export const useEstimateFarmFee = (props: Props) => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const client = useStore((s) => s.client)
const networkConfig = useStore((s) => s.networkConfig)
+ const pythVaa = useStore((s) => s.pythVaa)
+ const pythContractAddress = useStore((s) => s.networkConfig.contracts?.pyth)
+ const pythVaaMessage = getPythVaaMessage(
+ pythVaa,
+ networkConfig.assets.base.denom,
+ pythContractAddress,
+ userWalletAddress,
+ )
+
+ const creditManagerAddress = networkConfig.contracts?.creditManager
return useQuery(
[QUERY_KEYS.ESTIMATE_FARM_FEE, props.actions],
async () => {
const gasAdjustment = GAS_ADJUSTMENT
- if (!client) return null
+ if (!client || !creditManagerAddress || !networkConfig) return null
+ const messages = [
+ new MsgExecuteContract({
+ sender: userWalletAddress,
+ contract: creditManagerAddress,
+ msg: props.isCreate
+ ? { create_credit_account: {} }
+ : {
+ update_credit_account: {
+ account_id: props.accountId,
+ actions: props.actions,
+ },
+ },
+ funds: props.funds,
+ }),
+ ]
- if (!networkConfig) return null
+ if (pythVaaMessage) messages.unshift(pythVaaMessage)
try {
const simulateOptions = {
- messages: [
- new MsgExecuteContract({
- sender: userWalletAddress,
- contract: networkConfig.contracts.creditManager,
- msg: props.isCreate
- ? { create_credit_account: {} }
- : {
- update_credit_account: {
- account_id: props.accountId,
- actions: props.actions,
- },
- },
- funds: props.funds,
- }),
- ],
- wallet: client.recentWallet,
+ messages,
+ wallet: client.connectedWallet,
}
const result = await client.simulate(simulateOptions)
@@ -60,6 +72,7 @@ export const useEstimateFarmFee = (props: Props) => {
}
throw result.error
} catch (e) {
+ console.error(e)
throw e
}
},
diff --git a/src/hooks/queries/useEstimateFee.tsx b/src/hooks/queries/useEstimateFee.tsx
index 427c5a7..371c9ef 100644
--- a/src/hooks/queries/useEstimateFee.tsx
+++ b/src/hooks/queries/useEstimateFee.tsx
@@ -4,6 +4,7 @@ import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { GAS_ADJUSTMENT } from 'constants/appConstants'
+import { getPythVaaMessage } from 'libs/pyth'
import useStore from 'store'
import { QUERY_KEYS } from 'types/enums/queryKeys'
import { ContractMsg } from 'types/types'
@@ -19,6 +20,16 @@ interface Props {
export const useEstimateFee = (props: Props) => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const client = useStore((s) => s.client)
+ const pythVaa = useStore((s) => s.pythVaa)
+ const networkConfig = useStore((s) => s.networkConfig)
+ const baseCurrencyDenom = networkConfig.assets.base.denom
+ const pythContractAddress = networkConfig.contracts?.pyth
+ const pythVaaMessage = getPythVaaMessage(
+ pythVaa,
+ baseCurrencyDenom,
+ pythContractAddress,
+ userWalletAddress,
+ )
return useQuery(
[QUERY_KEYS.ESTIMATE_FEE, props.msg],
@@ -28,17 +39,20 @@ export const useEstimateFee = (props: Props) => {
if (!client || !props.contract || !props.msg) return
+ const messages = [
+ new MsgExecuteContract({
+ sender: sender,
+ contract: props.contract,
+ msg: props.msg,
+ funds: props.funds,
+ }),
+ ]
+ if (pythVaaMessage) messages.unshift(pythVaaMessage)
+
try {
const simulateOptions = {
- messages: [
- new MsgExecuteContract({
- sender: sender,
- contract: props.contract,
- msg: props.msg,
- funds: props.funds,
- }),
- ],
- wallet: client.recentWallet,
+ messages,
+ wallet: client.connectedWallet,
}
const result = await client.simulate(simulateOptions)
@@ -53,6 +67,7 @@ export const useEstimateFee = (props: Props) => {
}
throw result.error
} catch (e) {
+ console.error(e)
throw e
}
},
diff --git a/src/hooks/queries/useMarsOracle.tsx b/src/hooks/queries/useMarsOracle.tsx
index 5aace93..3522c97 100644
--- a/src/hooks/queries/useMarsOracle.tsx
+++ b/src/hooks/queries/useMarsOracle.tsx
@@ -1,26 +1,25 @@
import { useQuery } from '@tanstack/react-query'
+import { getContractQuery } from 'functions/queries'
import { gql, request } from 'graphql-request'
import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
-export interface MarsOracleData {
- prices: {
- [key: string]: {
- denom: string
- price: string
- }
- }
-}
-
export const useMarsOracle = () => {
- const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
- const oracleAddress = useStore((s) => s.networkConfig?.contracts.oracle)
+ const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
+ const oracleAddress = useStore((s) => s.networkConfig.contracts.oracle)
const whitelistedAssets = useStore((s) => s.whitelistedAssets) || []
+ const basePriceState = useStore((s) => s.basePriceState)
const processMarsOracleQuery = useStore((s) => s.processMarsOracleQuery)
const setExchangeRatesState = useStore((s) => s.setExchangeRatesState)
- let queries = ``
+ let priceQueries = ``
+ const configQuery = getContractQuery('config', oracleAddress || '', '{ config: {} }')
+ const priceSourcesQuery = getContractQuery(
+ 'price_sources',
+ oracleAddress || '',
+ '{ price_sources: {} }',
+ )
whitelistedAssets
.filter((asset: Asset) => !!asset.denom)
@@ -28,33 +27,39 @@ export const useMarsOracle = () => {
const denom = whitelistAsset.denom
const asset = `{
- denom: "${denom}"
- }`
+ denom: "${denom}"
+ }`
const querySegment = `
- ${whitelistAsset.id}: contractQuery(contractAddress: "${oracleAddress}", query: {
- price: ${asset}
- })
- `
- queries = queries + querySegment
+ ${whitelistAsset.id}: contractQuery(contractAddress: "${oracleAddress}", query: {
+ price: ${asset}
+ })
+ `
+ priceQueries = priceQueries + querySegment
})
- useQuery(
+ useQuery(
[QUERY_KEYS.MARS_ORACLE],
async () => {
return await request(
hiveUrl!,
gql`
- query MarsOracle {
- prices: wasm {
- ${queries}
- }
- }
- `,
+ query MarsOracle {
+ oracle: wasm {
+ ${configQuery}
+ },
+ sources: wasm {
+ ${priceSourcesQuery}
+ },
+ prices: wasm {
+ ${priceQueries}
+ }
+ }
+ `,
)
},
{
- enabled: !!hiveUrl && !!oracleAddress,
+ enabled: !!hiveUrl && !!oracleAddress && basePriceState === State.READY,
staleTime: 30000,
refetchInterval: 30000,
onError: () => setExchangeRatesState(State.ERROR),
diff --git a/src/hooks/queries/usePythVaa.tsx b/src/hooks/queries/usePythVaa.tsx
new file mode 100644
index 0000000..f4f24bd
--- /dev/null
+++ b/src/hooks/queries/usePythVaa.tsx
@@ -0,0 +1,39 @@
+import { useQuery } from '@tanstack/react-query'
+import useStore from 'store'
+import { QUERY_KEYS } from 'types/enums/queryKeys'
+
+export const usePythVaa = () => {
+ let pythVaaUrl = useStore((s) => s.networkConfig.usdPriceUrl)
+ const pythVaa = useStore((s) => s.pythVaa)
+ const hasPriceFeeds = pythVaa.priceFeeds.length > 0
+
+ if (pythVaaUrl && hasPriceFeeds) {
+ const pythApiUrl = new URL(pythVaaUrl + 'latest_vaas')
+ pythVaa.priceFeeds.forEach((priceFeedId) => {
+ pythApiUrl.searchParams.append('ids[]', priceFeedId)
+ })
+ pythVaaUrl = pythApiUrl.href
+ }
+
+ useQuery(
+ [QUERY_KEYS.PYTH_VAA],
+ async () => {
+ if (!pythVaaUrl || !hasPriceFeeds) return
+ const res = await fetch(pythVaaUrl)
+ return res.json()
+ },
+ {
+ enabled: hasPriceFeeds && !!pythVaaUrl,
+ staleTime: 30000,
+ refetchInterval: 30000,
+ onSuccess: (data) => {
+ useStore.setState({
+ pythVaa: {
+ priceFeeds: pythVaa.priceFeeds,
+ data,
+ },
+ })
+ },
+ },
+ )
+}
diff --git a/src/hooks/queries/useRedBank.tsx b/src/hooks/queries/useRedBank.tsx
index 2d513ea..248dd46 100644
--- a/src/hooks/queries/useRedBank.tsx
+++ b/src/hooks/queries/useRedBank.tsx
@@ -6,11 +6,11 @@ import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
export const useRedBank = () => {
- const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
+ const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
- const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
- const incentivesContractAddress = useStore((s) => s.networkConfig?.contracts.incentives)
+ const redbankAddress = useStore((s) => s.networkConfig.contracts.redBank)
+ const incentivesAddress = useStore((s) => s.networkConfig.contracts.incentives)
const processRedBankQuery = useStore((s) => s.processRedBankQuery)
const setRedBankState = useStore((s) => s.setRedBankState)
@@ -21,20 +21,15 @@ export const useRedBank = () => {
hiveUrl!,
gql`
${getRedbankQuery(
- userWalletAddress!,
- redbankContractAddress!,
- incentivesContractAddress!,
+ userWalletAddress,
+ redbankAddress,
+ incentivesAddress,
whitelistedAssets,
)}
`,
),
{
- enabled:
- !!hiveUrl &&
- !!userWalletAddress &&
- !!redbankContractAddress &&
- !!incentivesContractAddress &&
- !!whitelistedAssets?.length,
+ enabled: !!userWalletAddress && !!whitelistedAssets?.length,
staleTime: 30000,
refetchInterval: 30000,
onError: () => setRedBankState(State.ERROR),
diff --git a/src/hooks/queries/useSpotPrice.tsx b/src/hooks/queries/useSpotPrice.tsx
index 4d0c506..09e7326 100644
--- a/src/hooks/queries/useSpotPrice.tsx
+++ b/src/hooks/queries/useSpotPrice.tsx
@@ -1,18 +1,25 @@
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
+import { updateAssetPrices } from 'functions/updateAssetPrices'
import { updateExchangeRate } from 'functions/updateExchangeRate'
import { useAsset } from 'hooks/data'
import useStore from 'store'
+import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
export const useSpotPrice = (symbol: string) => {
const networkConfig = useStore((s) => s.networkConfig)
- const displayCurrency = networkConfig?.displayCurrency
- const lcd = useStore((s) => s.chainInfo?.rest)
+ const baseCurrency = networkConfig.assets.base
+ const displayCurrency = networkConfig.displayCurrency
const exchangeRates = useStore((s) => s.exchangeRates)
+ const assetPricesUSD = useStore((s) => s.assetPricesUSD)
+ const exchangeRatesState = useStore((s) => s.assetPricesUSDState)
+ const basePriceState = useStore((s) => s.assetPricesUSDState)
const asset = useAsset({ symbol })
+ const lcd = networkConfig.restUrl ?? ''
+
const poolBase = asset?.poolBase
? exchangeRates?.find((ratesAsset) => ratesAsset.denom === asset.poolBase)
: true
@@ -26,41 +33,70 @@ export const useSpotPrice = (symbol: string) => {
})
},
{
- enabled: !!lcd && !!asset && !!asset.poolId && !!poolBase,
+ enabled:
+ !!asset &&
+ !!asset.poolId &&
+ !!poolBase &&
+ basePriceState === State.READY &&
+ exchangeRatesState === State.READY,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
- if (!asset || !displayCurrency) return
+ if (!asset || !assetPricesUSD) return
const poolDataAssets = data.pool.pool_assets
const assetFirst = poolDataAssets[0].token.denom === asset.denom
- const targetAsset = poolDataAssets[assetFirst ? 0 : 1]
- const otherAsset = poolDataAssets[assetFirst ? 1 : 0]
+ const primaryAsset = poolDataAssets[assetFirst ? 0 : 1]
+ const secondaryAsset = poolDataAssets[assetFirst ? 1 : 0]
- const targetAssetAmount = new BigNumber(targetAsset.token.amount)
- const targetAssetWeight = new BigNumber(targetAsset.weight)
- const otherAssetAmount = new BigNumber(otherAsset.token.amount)
- const otherAssetWeight = new BigNumber(otherAsset.weight)
+ const primaryAssetAmount = new BigNumber(primaryAsset.token.amount)
+ const primaryAssetWeight = new BigNumber(primaryAsset.weight)
+ const secondaryAssetAmount = new BigNumber(secondaryAsset.token.amount)
+ const secondaryAssetWeight = new BigNumber(secondaryAsset.weight)
- const rate = otherAssetAmount
- .div(targetAssetAmount)
- .multipliedBy(otherAssetWeight.div(targetAssetWeight))
+ const rate = secondaryAssetAmount
+ .div(primaryAssetAmount)
+ .multipliedBy(secondaryAssetWeight.div(primaryAssetWeight))
const hasDisplayCurrency = exchangeRates?.find(
(ratesAsset) => ratesAsset.denom === displayCurrency.denom,
)
if (displayCurrency.denom === asset.denom && !hasDisplayCurrency) {
- useStore.setState({ baseToDisplayCurrencyRatio: 1 / rate.toNumber() })
+ const coinExchangeRate = { denom: asset.denom, amount: '1' }
+ useStore.setState({
+ exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
+ })
} else {
- const coin = { denom: asset.denom, amount: rate.toString() }
+ const secondaryRate =
+ exchangeRates?.find((rate) => rate.denom === secondaryAsset.token.denom)?.amount ?? 1
+ const coinExchangeRate = {
+ denom: asset.denom,
+ amount: rate.times(secondaryRate).toString(),
+ }
if (typeof poolBase === 'object') {
const baseRate = Number(rate.toString()) * Number(poolBase.amount)
- coin.amount = baseRate.toString()
- useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
+ coinExchangeRate.amount = baseRate.toString()
+ useStore.setState({
+ exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
+ })
} else {
- useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
+ useStore.setState({
+ exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
+ })
}
+ const baseCurrencyPrice = assetPricesUSD.find(
+ (asset) => asset.denom === baseCurrency.denom,
+ )?.amount
+ if (!baseCurrencyPrice) return
+
+ const assetPriceCoin = {
+ denom: coinExchangeRate.denom,
+ amount: new BigNumber(coinExchangeRate.amount).times(baseCurrencyPrice).toString(),
+ }
+ useStore.setState({
+ assetPricesUSD: updateAssetPrices(assetPriceCoin, assetPricesUSD || []),
+ })
}
},
},
diff --git a/src/hooks/queries/useUsdPrice.tsx b/src/hooks/queries/useUsdPrice.tsx
index d7d1a5a..55a650d 100644
--- a/src/hooks/queries/useUsdPrice.tsx
+++ b/src/hooks/queries/useUsdPrice.tsx
@@ -1,45 +1,68 @@
+import { Coin } from '@cosmjs/proto-signing'
import { useQuery } from '@tanstack/react-query'
-import { updateExchangeRate } from 'functions'
+import BigNumber from 'bignumber.js'
+import { updateAssetPrices } from 'functions/updateAssetPrices'
import useStore from 'store'
+import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
-interface CoinPriceData {
- price: number
- denom: string
- symbol: string
- liquidity: number
- liquidity_24h_change: number
- volume_24h: number
- volume_24h_change: number
- name: string
- price_24h_change: number
- exponent: number
- display: string
-}
-
export const useUsdPrice = () => {
- const osmoUsdPriceUrl = useStore((s) => s.networkConfig?.osmoUsdPriceUrl ?? '')
- const exchangeRates = useStore((s) => s.exchangeRates ?? [])
- const networkConfig = useStore((s) => s.networkConfig)
- const displayCurrency = networkConfig?.displayCurrency
+ let usdPriceUrl = useStore((s) => s.networkConfig.usdPriceUrl)
+ let hasPriceFeeds = false
+ const whitelistedAssets = useStore((s) => s.whitelistedAssets)
+ const assetPricesUSD = useStore((s) => s.assetPricesUSD ?? [])
+ const basePriceState = useStore((s) => s.basePriceState)
+ const baseAsset = useStore((s) => s.networkConfig.assets.base)
+
+ if (!usdPriceUrl && basePriceState !== State.READY) {
+ useStore.setState({ basePriceState: State.READY })
+ }
+
+ if (usdPriceUrl && whitelistedAssets) {
+ const pythApiUrl = new URL(usdPriceUrl + 'latest_price_feeds')
+ whitelistedAssets.forEach((asset) => {
+ if (asset.priceFeedId) {
+ hasPriceFeeds = true
+ pythApiUrl.searchParams.append('ids[]', asset.priceFeedId)
+ }
+ })
+ usdPriceUrl = pythApiUrl.href
+ }
useQuery(
[QUERY_KEYS.USD_PRICE],
async () => {
- const res = await fetch(osmoUsdPriceUrl)
+ if (!usdPriceUrl || !whitelistedAssets || !hasPriceFeeds) return
+ const res = await fetch(usdPriceUrl)
return res.json()
},
{
- enabled: !!osmoUsdPriceUrl && !!exchangeRates.length && !!displayCurrency,
+ enabled: !!usdPriceUrl || !!whitelistedAssets,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
- const coin = { denom: 'usd', amount: (1 / data[0].price).toString() }
- if (displayCurrency.denom === coin.denom) {
- useStore.setState({ baseToDisplayCurrencyRatio: data[0].price })
- }
+ let updatedAssetPricesUSD: Coin[] = []
+ data.map((priceData) => {
+ const denom = whitelistedAssets.find(
+ (asset) => asset?.priceFeedId === priceData.id,
+ )?.denom
- useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates) })
+ if (denom) {
+ const amount = new BigNumber(priceData.price.price)
+ .times(new BigNumber(10).pow(priceData.price.expo))
+ .toString()
+
+ const coin = { denom, amount }
+
+ updatedAssetPricesUSD = updateAssetPrices(coin, assetPricesUSD, true)
+ if (denom === baseAsset?.denom) {
+ useStore.setState({
+ basePriceState: State.READY,
+ })
+ }
+ }
+ })
+ useStore.setState({ assetPricesUSD: updatedAssetPricesUSD })
},
},
)
diff --git a/src/hooks/queries/useUserBalance.tsx b/src/hooks/queries/useUserBalance.tsx
index 0d0d807..f3418c1 100644
--- a/src/hooks/queries/useUserBalance.tsx
+++ b/src/hooks/queries/useUserBalance.tsx
@@ -12,7 +12,7 @@ export interface UserBalanceData {
}
export const useUserBalance = () => {
- const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
+ const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const processUserBalanceQuery = useStore((s) => s.processUserBalanceQuery)
@@ -36,7 +36,7 @@ export const useUserBalance = () => {
)
},
{
- enabled: (!!hiveUrl && !!userWalletAddress) || false,
+ enabled: !!userWalletAddress,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: processUserBalanceQuery,
diff --git a/src/hooks/queries/useUserCollaterals.tsx b/src/hooks/queries/useUserCollaterals.tsx
index e8d1ca2..32d8549 100644
--- a/src/hooks/queries/useUserCollaterals.tsx
+++ b/src/hooks/queries/useUserCollaterals.tsx
@@ -7,7 +7,7 @@ const QUERY_LIMIT = 10
export const useUserCollaterals = () => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
- const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
+ const redbankContractAddress = useStore((s) => s.networkConfig.contracts.redBank)
const client = useStore((s) => s.client)
const resolveUserDeposits = (collaterals: UserCollateral[]): Coin[] => {
diff --git a/src/hooks/queries/useUserDebt.tsx b/src/hooks/queries/useUserDebt.tsx
index 564c8ae..40d0226 100644
--- a/src/hooks/queries/useUserDebt.tsx
+++ b/src/hooks/queries/useUserDebt.tsx
@@ -14,7 +14,7 @@ export interface UserDebtData {
export const useUserDebt = () => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
- const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
+ const redbankContractAddress = useStore((s) => s.networkConfig.contracts.redBank)
const client = useStore((s) => s.client)
const resolveDebtResponse = (debts: UserDebtData[]): Coin[] => {
diff --git a/src/hooks/queries/useUserIcns.tsx b/src/hooks/queries/useUserIcns.tsx
index 9351a93..f69639a 100644
--- a/src/hooks/queries/useUserIcns.tsx
+++ b/src/hooks/queries/useUserIcns.tsx
@@ -1,5 +1,4 @@
import { useQuery } from '@tanstack/react-query'
-import { NETWORK_CONFIG } from 'configs/osmosis-1'
import { gql, request } from 'graphql-request'
import { useMemo } from 'react'
import useStore from 'store'
@@ -16,17 +15,16 @@ export interface UserIcnsData {
export const useUserIcns = () => {
/* only possible to query on mainnet */
- const hiveUrl = NETWORK_CONFIG.hiveUrl
const resolverContract = 'osmo1xk0s8xgktn9x5vwcgtjdxqzadg88fgn33p8u9cnpdxwemvxscvast52cdd'
-
+ const networkConfig = useStore((s) => s.networkConfig)
const userWalletAddress = useStore((s) => s.userWalletAddress)
- const setUserIcns = useStore((s) => s.setUserIcns)
+ const hiveUrl = networkConfig.hiveUrl
const result = useQuery(
[QUERY_KEYS.USER_ICNS],
async () => {
return await request(
- hiveUrl!,
+ hiveUrl,
gql`
query UserIcnsQuery {
wasm {
@@ -40,10 +38,10 @@ export const useUserIcns = () => {
)
},
{
- enabled: !!userWalletAddress || false,
+ enabled: !!userWalletAddress,
onSuccess: (data) => {
- const icns = data.wasm.contractQuery.primary_name
- if (icns !== '') setUserIcns(icns)
+ const userIcns = data.wasm.contractQuery.primary_name
+ if (userIcns !== '') useStore.setState({ userIcns })
},
},
)
diff --git a/src/images/atom.svg b/src/images/atom.svg
index ed377e8..48f105b 100644
--- a/src/images/atom.svg
+++ b/src/images/atom.svg
@@ -1,44 +1,20 @@
- |