Mp 2344 fund credit account flow (#179)
* tidy: refactor text * feat: added unstyled select * tidy: useToggle * tidy: useToggle * MP-2344: first unstyled version of Select * fix: fixed the build * MP-2344: progress on the Select * MP-2344: almost finished the Select * env: update wallet-connector * fix: relative imports * env: started adding osmo-test-5 contracts * refactor: rename stargate.ts to d.ts * env: adjusted tsconfig.json * feat: updated modals to use the dialog element * env: added mainnet config * env: enabled osmosis-1 * tidy: refactor * fix: fixed decimals * fix: fixed the NaN issue for ETH * fix: fixed price calculations for large decimals * feat: finished conversion to <dialog> * fix: fixed some logic issues * fix: layout fix * fix: fixed token slider and input * tidy: format * fix: added currentAccount hook * Mp 2345 withdraw from credit account flow (#180) * MP-2345: created the barebone for withdraw * MP-2351: changed the AccountHealth logic * MP-2345: enabled withdraw function * MP-2351: added animation to Accordion * fix: adjusted according to feedback * fix: reduced complexity * tidy: format * env: enabled osmo-test-5 support * feat: added USDC.n * env: updated dependencies * fix: hotfixed react-draggable * fix: fixed vault info
35
.env.example
@ -1,15 +1,32 @@
|
||||
NEXT_PUBLIC_NETWORK=testnet
|
||||
NEXT_PUBLIC_CHAIN_ID=osmo-test-4
|
||||
NEXT_PUBLIC_CHAIN_ID=osmo-test-5
|
||||
NEXT_PUBLIC_RPC=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-rpc-front/
|
||||
NEXT_PUBLIC_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql
|
||||
NEXT_PUBLIC_REST=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-lcd-front/
|
||||
NEXT_PUBLIC_SWAP=https://testnet.osmosis.zone
|
||||
NEXT_PUBLIC_WALLETS=keplr,cosmostation
|
||||
NEXT_PUBLIC_ACCOUNT_NFT=osmo1xpgx06z2c6zjk49feq75swgv78m6dvht6wramu2gltzjz5j959nq4hggxz
|
||||
NEXT_PUBLIC_ORACLE=osmo1dqz2u3c8rs5e7w5fnchsr2mpzzsxew69wtdy0aq4jsd76w7upmsstqe0s8
|
||||
NEXT_PUBLIC_RED_BANK=osmo1t0dl6r27phqetfu0geaxrng0u9zn8qgrdwztapt5xr32adtwptaq6vwg36
|
||||
NEXT_PUBLIC_CREDIT_MANAGER=osmo169xhpftsee275j3cjudj6qfzdpfp8sdllgeeprud4ynwr4sj6m4qel2ezp
|
||||
NEXT_PUBLIC_INCENTIVES=osmo1zxs8fry3m8j94pqg7h4muunyx86en27cl0xgk76fc839xg2qnn6qtpjs48
|
||||
NEXT_PUBLIC_ZAPPER=osmo1ua8dwc9v8qjh7n3qf8kg6xvrwjm5yu9xxln7yjvgmrvfzaxvzsuqfcdnjq
|
||||
NEXT_PUBLIC_SWAPPER=osmo1uj6r9tu440wwp2mhtagh48yvmeyeaqt2xa7kdnlhyrqcuthlj4ss7ghg6n
|
||||
NEXT_PUBLIC_API=http://localhost:3000/api
|
||||
NEXT_PUBLIC_ACCOUNT_NFT=osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4
|
||||
NEXT_PUBLIC_ORACLE=osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2
|
||||
NEXT_PUBLIC_RED_BANK=osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u
|
||||
NEXT_PUBLIC_CREDIT_MANAGER=osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp
|
||||
NEXT_PUBLIC_INCENTIVES=osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d
|
||||
NEXT_PUBLIC_ZAPPER=osmo1m77x80a5rgsdw3ak0hmxkhzltlh2qf3hjdu24fsnl9v3ekhvdugsmy94uh
|
||||
NEXT_PUBLIC_SWAPPER=osmo183uu809nq80xuh0r86dkadq9djza6ln5cf5hmszt6zcfdy454chq3dcgm4
|
||||
NEXT_PUBLIC_API=http://localhost:3000/api
|
||||
|
||||
# MAINNET #
|
||||
# NEXT_PUBLIC_NETWORK=mainnet
|
||||
# NEXT_PUBLIC_CHAIN_ID=osmosis-1
|
||||
# NEXT_PUBLIC_RPC=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-rpc-front/
|
||||
# NEXT_PUBLIC_GQL=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql
|
||||
# NEXT_PUBLIC_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/
|
||||
# NEXT_PUBLIC_SWAP=https://app.osmosis.zone
|
||||
# NEXT_PUBLIC_WALLETS=keplr,xfi-cosmos,leap-cosmos,cosmostation,mobile-keplr,mobile-cosmostation
|
||||
# NEXT_PUBLIC_ACCOUNT_NFT=osmo1450hrg6dv2l58c0rvdwx8ec2a0r6dd50hn4frk370tpvqjhy8khqw7sw09
|
||||
# NEXT_PUBLIC_ORACLE=osmo1mhznfr60vjdp2gejhyv2gax9nvyyzhd3z0qcwseyetkfustjauzqycsy2g
|
||||
# NEXT_PUBLIC_RED_BANK=osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg
|
||||
# NEXT_PUBLIC_CREDIT_MANAGER=osmo1f2m24wktq0sw3c0lexlg7fv4kngwyttvzws3a3r3al9ld2s2pvds87jqvf
|
||||
# NEXT_PUBLIC_INCENTIVES=osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm
|
||||
# NEXT_PUBLIC_ZAPPER=osmo17qwvc70pzc9mudr8t02t3pl74hhqsgwnskl734p4hug3s8mkerdqzduf7c
|
||||
# NEXT_PUBLIC_SWAPPER=osmo1wee0z8c7tcawyl647eapqs4a88q8jpa7ddy6nn2nrs7t47p2zhxswetwla
|
||||
# NEXT_PUBLIC_API=http://localhost:3000/api
|
2
.gitignore
vendored
@ -37,5 +37,7 @@ next-env.d.ts
|
||||
|
||||
# Environment variables
|
||||
.env.local
|
||||
.env.local.testnet
|
||||
.env.local.mainnet
|
||||
.env.production
|
||||
.env
|
26
package.json
@ -13,15 +13,15 @@
|
||||
"dependencies": {
|
||||
"@cosmjs/cosmwasm-stargate": "^0.30.1",
|
||||
"@cosmjs/stargate": "^0.30.1",
|
||||
"@marsprotocol/wallet-connector": "^1.5.4",
|
||||
"@sentry/nextjs": "^7.48.0",
|
||||
"@tanstack/react-table": "^8.8.5",
|
||||
"@marsprotocol/wallet-connector": "^1.5.8",
|
||||
"@sentry/nextjs": "^7.51.0",
|
||||
"@tanstack/react-table": "^8.9.1",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"bignumber.js": "^9.1.1",
|
||||
"classnames": "^2.3.2",
|
||||
"graphql-request": "^6.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"next": "^13.3.0",
|
||||
"next": "^13.4.1",
|
||||
"react": "^18.2.0",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -30,22 +30,22 @@
|
||||
"react-toastify": "^9.1.2",
|
||||
"react-use-clipboard": "^1.0.9",
|
||||
"recharts": "^2.5.0",
|
||||
"swr": "^2.1.3",
|
||||
"swr": "^2.1.5",
|
||||
"tailwind-scrollbar-hide": "^1.1.7",
|
||||
"zustand": "^4.3.7"
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@svgr/webpack": "^7.0.0",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/react": "18.0.35",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"@types/node": "^20.1.0",
|
||||
"@types/react": "18.2.6",
|
||||
"@types/react-dom": "18.2.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "8.38.0",
|
||||
"eslint-config-next": "^13.3.0",
|
||||
"eslint": "8.40.0",
|
||||
"eslint-config-next": "^13.4.1",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"postcss": "^8.4.23",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-tailwindcss": "^0.2.7",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-tailwindcss": "^0.2.8",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "5.0.4"
|
||||
},
|
||||
|
11
public/tokens/axlusdc.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 24C18.6499 24 24 18.6499 24 12C24 5.3501 18.6499 0 12 0C5.3501 0 0 5.3501 0 12C0 18.6499 5.3501 24 12 24Z" fill="#2775CA"/>
|
||||
<path d="M15.2997 13.8998C15.2997 12.1497 14.2494 11.5497 12.1501 11.2996C10.6501 11.0994 10.3501 10.6996 10.3501 9.99977C10.3501 9.29998 10.8503 8.84967 11.8501 8.84967C12.7501 8.84967 13.2503 9.14967 13.4997 9.89998C13.5496 10.0503 13.7 10.1501 13.8496 10.1501H14.6498C14.8501 10.1501 14.9997 9.99977 14.9997 9.80019V9.7503C14.7995 8.65009 13.8995 7.80061 12.7501 7.70019V6.50019C12.7501 6.29998 12.5997 6.1503 12.3503 6.1004H11.6C11.3997 6.1004 11.2501 6.25009 11.2002 6.50019V7.6503C9.70016 7.85051 8.75027 8.8503 8.75027 10.1002C8.75027 11.7499 9.75006 12.4004 11.8501 12.6499C13.2503 12.9 13.7 13.2 13.7 13.9996C13.7 14.7991 13.0002 15.3492 12.0503 15.3492C10.7505 15.3492 10.3002 14.7991 10.1505 14.0495C10.1006 13.8492 9.95027 13.7495 9.80059 13.7495H8.95048C8.75027 13.7495 8.60059 13.8998 8.60059 14.0993V14.1492C8.8008 15.3991 9.60037 16.2991 11.2507 16.5492V17.7492C11.2507 17.9495 11.401 18.0991 11.6505 18.149H12.4008C12.601 18.149 12.7507 17.9987 12.8006 17.7492V16.5492C14.3006 16.2991 15.3004 15.2495 15.3004 13.8991L15.2997 13.8998Z" fill="white"/>
|
||||
<path d="M9.45047 19.1501C5.55047 17.7499 3.55026 13.4002 5.00036 9.55014C5.75068 7.45014 7.40036 5.85035 9.45047 5.10003C9.65068 5.00024 9.75047 4.84993 9.75047 4.59982V3.90003C9.75047 3.69982 9.65068 3.55014 9.45047 3.50024C9.40057 3.50024 9.30015 3.50024 9.25026 3.55014C4.50015 5.05014 1.89994 10.1002 3.39994 14.8503C4.29994 17.6501 6.44984 19.8 9.24963 20.7C9.44984 20.7998 9.64941 20.7 9.69994 20.4998C9.74984 20.4499 9.74984 20.4 9.74984 20.2996V19.5998C9.74984 19.4495 9.60015 19.2499 9.44984 19.1501H9.45047ZM14.75 3.55014C14.5498 3.45035 14.3503 3.55014 14.2997 3.75035C14.2498 3.80024 14.2498 3.85014 14.2498 3.95056V4.65035C14.2498 4.85056 14.4002 5.05014 14.5498 5.15056C18.4498 6.55077 20.45 10.9005 18.9999 14.7506C18.2496 16.8506 16.5999 18.4503 14.5498 19.2007C14.3496 19.3005 14.2498 19.4508 14.2498 19.7009V20.4007C14.2498 20.6009 14.3496 20.7506 14.5498 20.8005C14.5997 20.8005 14.7002 20.8005 14.75 20.7506C19.5002 19.2506 22.0997 14.2005 20.5997 9.45035C19.6997 6.60067 17.4999 4.45014 14.75 3.55014V3.55014Z" fill="white"/>
|
||||
<path d="M20 24C22.2091 24 24 22.2091 24 20C24 17.7909 22.2091 16 20 16C17.7909 16 16 17.7909 16 20C16 22.2091 17.7909 24 20 24Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 23.5C21.933 23.5 23.5 21.933 23.5 20C23.5 18.067 21.933 16.5 20 16.5C18.067 16.5 16.5 18.067 16.5 20C16.5 21.933 18.067 23.5 20 23.5ZM24 20C24 22.2091 22.2091 24 20 24C17.7909 24 16 22.2091 16 20C16 17.7909 17.7909 16 20 16C22.2091 16 24 17.7909 24 20Z" fill="black"/>
|
||||
<path d="M20.266 19.6405L21.6634 18.2507L21.1332 17.7236L20.0006 18.8499L18.8681 17.7236L18.3379 18.2507L19.7352 19.6405C19.8086 19.7133 19.9046 19.7497 20 19.7497C20.0954 19.7497 20.192 19.7133 20.2648 19.6405H20.266Z" fill="black"/>
|
||||
<path d="M22.2886 21.1251L21.1561 19.9988L22.2886 18.8725L21.7584 18.3455L20.3611 19.7353C20.2149 19.8808 20.2149 20.1168 20.3611 20.2623L21.7584 21.6521L22.2886 21.1251Z" fill="black"/>
|
||||
<path d="M19.9985 21.1501L21.1311 22.2764L21.6613 21.7493L20.264 20.3595C20.1178 20.214 19.88 20.214 19.7338 20.3595L18.3364 21.7493L18.8666 22.2764L19.9992 21.1501H19.9985Z" fill="black"/>
|
||||
<path d="M19.6385 20.2642C19.7087 20.1945 19.7483 20.0991 19.7483 20.0006C19.7483 19.9021 19.7087 19.8067 19.6385 19.7371L18.2411 18.3473L17.7109 18.8743L18.8435 20.0006L17.7109 21.1269L18.2411 21.654L19.6385 20.2642Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
23
public/tokens/axlwbtc.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#FFFFFF" d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
|
||||
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"/>
|
||||
<path id="Shape" fill="#5A5564" d="M19.6,5l-0.7,0.7c3.3,3.6,3.3,9,0,12.6l0.7,0.7C23.2,15,23.2,9,19.6,5L19.6,5z"/>
|
||||
<path id="Shape-2" fill="#5A5564" d="M5.7,5.1c3.6-3.3,9-3.3,12.6,0L19,4.4C15,0.8,9,0.8,5,4.4L5.7,5.1z"/>
|
||||
<path id="Shape-3" fill="#5A5564" d="M5.1,18.3c-3.3-3.6-3.3-9,0-12.6L4.4,5C0.8,9,0.8,15,4.4,19L5.1,18.3z"/>
|
||||
<path id="Shape-4" fill="#5A5564" d="M18.3,18.9c-3.6,3.3-9,3.3-12.6,0L5,19.6c3.9,3.6,10,3.6,13.9,0L18.3,18.9z"/>
|
||||
<path id="Shape-5" fill="#F09242" d="M16.2,9.8c-0.1-1.4-1.3-1.8-2.8-2V5.9h-1.2v1.9c-0.3,0-0.6,0-0.9,0V5.9h-1.2v1.9H7.8v1.2
|
||||
c0,0,0.9,0,0.8,0c0.3,0,0.6,0.2,0.7,0.5v5.2c0,0.1-0.1,0.2-0.1,0.3c-0.1,0.1-0.2,0.1-0.3,0.1c0,0-0.8,0-0.8,0l-0.2,1.4h2.3v1.9
|
||||
h1.2v-1.9h0.9v1.9h1.2v-1.9c2-0.1,3.3-0.6,3.5-2.4c0.1-1.5-0.6-2.1-1.7-2.4C15.8,11.4,16.3,10.8,16.2,9.8z M14.5,13.9
|
||||
c0,1.4-2.5,1.3-3.3,1.3v-2.6C12.1,12.6,14.5,12.4,14.5,13.9z M14,10.3c0,1.3-2.1,1.2-2.7,1.2V9.2C11.9,9.2,14,9,14,10.3z"/>
|
||||
<path id="Shape-6" fill="#282138" d="M12,24C5.4,24,0,18.6,0,12S5.4,0,12,0c6.6,0,12,5.4,12,12C24,18.6,18.6,24,12,24
|
||||
C12,24,12,24,12,24z M12,0.9c-6.1,0-11.1,5-11,11.1c0,6.1,5,11.1,11.1,11c6.1,0,11-5,11-11.1C23.1,5.9,18.1,0.9,12,0.9
|
||||
C12,0.9,12,0.9,12,0.9z"/>
|
||||
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
|
||||
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"/>
|
||||
<path d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
|
||||
/>
|
||||
<path d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"/>
|
||||
<path d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"/>
|
||||
<path d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
18
public/tokens/axlweth.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#FFFFFF" d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
|
||||
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"/>
|
||||
<polygon fill="#343434" points="11.9,1.2 11.8,1.7 11.8,15.9 11.9,16.1 18.5,12.2"/>
|
||||
<polygon fill="#8C8C8C" points="11.9,1.2 5.3,12.2 11.9,16.1 11.9,9.2"/>
|
||||
<polygon fill="#3C3C3B" points="11.9,17.3 11.8,17.4 11.8,22.5 11.9,22.7 18.5,13.4"/>
|
||||
<polygon fill="#8C8C8C" points="11.9,22.7 11.9,17.3 5.3,13.4"/>
|
||||
<polygon fill="#141414" points="11.9,16.1 18.5,12.2 11.9,9.2"/>
|
||||
<polygon fill="#393939" points="5.3,12.2 11.9,16.1 11.9,9.2"/>
|
||||
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
|
||||
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"/>
|
||||
<path d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
|
||||
/>
|
||||
<path d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"/>
|
||||
<path d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"/>
|
||||
<path d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
25
public/tokens/nusdc.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
|
||||
<path fill="#2775CA" d="M60,120c33.2,0,60-26.8,60-60S93.2,0,60,0S0,26.8,0,60S26.8,120,60,120z"/>
|
||||
<path fill="#FFFFFF" d="M76.5,69.5c0-8.8-5.3-11.8-15.7-13c-7.5-1-9-3-9-6.5c0-3.5,2.5-5.8,7.5-5.8c4.5,0,7,1.5,8.2,5.3
|
||||
c0.2,0.8,1,1.3,1.7,1.3h4c1,0,1.7-0.8,1.7-1.7v-0.2c-1-5.5-5.5-9.7-11.2-10.3v-6c0-1-0.8-1.7-2-2H58c-1,0-1.7,0.7-2,2v5.8
|
||||
c-7.5,1-12.2,6-12.2,12.2c0,8.2,5,11.5,15.5,12.7c7,1.3,9.2,2.8,9.2,6.7c0,4-3.5,6.7-8.2,6.7c-6.5,0-8.8-2.8-9.5-6.5
|
||||
c-0.2-1-1-1.5-1.7-1.5h-4.3c-1,0-1.7,0.8-1.7,1.7v0.2c1,6.2,5,10.7,13.3,12v6c0,1,0.8,1.7,2,2H62c1,0,1.7-0.8,2-2v-6
|
||||
C71.5,81.5,76.5,76.2,76.5,69.5L76.5,69.5z"/>
|
||||
<path fill="#FFFFFF" d="M47.3,95.8c-19.5-7-29.5-28.7-22.3-48c3.8-10.5,12-18.5,22.3-22.3c1-0.5,1.5-1.3,1.5-2.5v-3.5
|
||||
c0-1-0.5-1.7-1.5-2c-0.2,0-0.8,0-1,0.2C22.5,25.3,9.5,50.5,17,74.3c4.5,14,15.2,24.7,29.2,29.2c1,0.5,2,0,2.3-1
|
||||
c0.2-0.2,0.2-0.5,0.2-1V98C48.7,97.2,48,96.2,47.3,95.8L47.3,95.8z M73.8,17.8c-1-0.5-2,0-2.3,1c-0.2,0.2-0.2,0.5-0.2,1v3.5
|
||||
c0,1,0.8,2,1.5,2.5c19.5,7,29.5,28.7,22.3,48C91.2,84.3,83,92.3,72.7,96c-1,0.5-1.5,1.3-1.5,2.5v3.5c0,1,0.5,1.7,1.5,2
|
||||
c0.2,0,0.8,0,1-0.2C97.5,96.3,110.5,71,103,47.3C98.5,33,87.5,22.3,73.8,17.8L73.8,17.8z"/>
|
||||
<path d="M100,120c11,0,20-9,20-20s-9-20-20-20s-20,9-20,20S89,120,100,120z"/>
|
||||
<path fill="#FFFFFF" d="M109.3,87c-2,0-3.5,1.6-3.5,3.6c0,0.5,0,1.1,0,1.6c-0.3-0.2-0.5-0.5-0.6-0.7
|
||||
c-2.3-3.5-6.5-5.2-10.5-4.2c-4.3,1.1-7.4,4.5-7.6,8.8c-0.2,4.5-0.1,9.1,0,13.6c0,1.9,1.8,3.4,3.7,3.3c1.9-0.1,3.4-1.6,3.5-3.5
|
||||
c0-0.6,0-1.1,0-1.7c0,0,0.1,0,0.1,0c0.2,0.3,0.3,0.5,0.5,0.8c2.3,3.6,6.8,5.2,10.9,4.1c4.1-1.1,7.1-4.9,7.2-9c0.1-4.3,0-8.7,0-13
|
||||
C113,88.6,111.3,87,109.3,87z M93.4,95.9c-0.1,0.4-0.1,0.9-0.1,1.3c0,4,0,7.9,0,11.9c0,1.6-1,2.8-2.5,2.8c-1.6,0.1-2.7-1-2.7-2.7
|
||||
c0-2.1,0-4.2,0-6.3c0,0,0,0,0.1,0c0-2.3-0.1-4.7,0-7c0.2-4,3.9-7.5,7.9-7.9c5.4-0.5,9.9,3.7,9.8,9.2c-0.1,2,0,3.9,0,5.9
|
||||
c0,1.3-1,2.4-2.3,2.6c-1.2,0.2-2.4-0.6-2.8-1.8c-0.1-0.3-0.1-0.6-0.1-1c0-2,0-4.1,0-6.1c0-1.8-1.4-3.3-3-3.5
|
||||
C95.6,93.1,93.9,94.1,93.4,95.9z M111.9,104c-0.1,4-3.5,7.4-7.5,7.9c-4.7,0.6-8.9-2.3-9.9-6.9c-0.2-1.1-0.2-2.2-0.2-3.3
|
||||
c0-1.6,0-3.1,0-4.7c0-1.6,1.1-2.8,2.6-2.8c1.5,0,2.6,1.2,2.6,2.8c0,2,0,4,0,6.1c0,1.7,1,3,2.7,3.5c1.5,0.4,3.2-0.2,4-1.6
|
||||
c0.3-0.6,0.5-1.3,0.5-1.9c0.1-2,0-4,0-6c0-2.1,0-4.2,0-6.3c0-1.1,0.5-2,1.5-2.5c1-0.4,1.9-0.3,2.7,0.3c0.7,0.5,1,1.3,1,2.1
|
||||
C112,95.1,112.1,99.5,111.9,104z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
@ -1,220 +1,340 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 129.7 138.9" style="enable-background:new 0 0 129.7 138.9;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#5E12A0;}
|
||||
.st1{fill:url(#XMLID_35_);}
|
||||
.st2{fill:url(#XMLID_36_);}
|
||||
.st3{opacity:0.6;fill:#A98698;enable-background:new ;}
|
||||
.st4{opacity:0.6;fill:url(#XMLID_185_);enable-background:new ;}
|
||||
.st5{opacity:0.6;fill:url(#XMLID_186_);enable-background:new ;}
|
||||
.st6{fill:url(#XMLID_187_);}
|
||||
.st7{opacity:0.6;}
|
||||
.st8{opacity:0.6;fill:url(#XMLID_188_);enable-background:new ;}
|
||||
.st9{opacity:0.7;}
|
||||
.st10{fill:url(#XMLID_189_);}
|
||||
.st11{fill:url(#XMLID_190_);}
|
||||
.st12{fill:#FFFFFF;}
|
||||
.st13{fill:url(#XMLID_191_);}
|
||||
.st14{opacity:0.2;fill:#FFFFFF;enable-background:new ;}
|
||||
.st15{opacity:0.4;}
|
||||
.st16{opacity:0.6;fill:url(#XMLID_192_);enable-background:new ;}
|
||||
.st17{opacity:0.3;fill:#FFFFFF;enable-background:new ;}
|
||||
.st18{opacity:0.6;fill:url(#XMLID_193_);enable-background:new ;}
|
||||
.st19{opacity:0.6;fill:url(#XMLID_194_);enable-background:new ;}
|
||||
.st20{display:none;}
|
||||
.st21{display:inline;opacity:0.2;fill:#FFFFFF;enable-background:new ;}
|
||||
.st22{display:inline;opacity:0.4;}
|
||||
.st23{opacity:0.6;fill:url(#XMLID_195_);enable-background:new ;}
|
||||
.st24{display:inline;opacity:0.3;fill:#FFFFFF;enable-background:new ;}
|
||||
.st25{opacity:0.6;fill:url(#XMLID_196_);enable-background:new ;}
|
||||
.st26{opacity:0.6;fill:url(#XMLID_197_);enable-background:new ;}
|
||||
</style>
|
||||
<g id="XMLID_2_">
|
||||
<g id="XMLID_3_">
|
||||
<g id="XMLID_66_">
|
||||
<g id="XMLID_67_">
|
||||
<path id="XMLID_68_" class="st0" d="M127.6,25.6c-1.4-5.3-5.9-10.6-14-16.5c-6.5-4.7-13.4-7.4-18.9-7.4c-1.1,0-2.1,0.1-3.1,0.3
|
||||
c-2.5,0.5-4.7,2.3-6.1,5c-1.7,3.2-2.1,7.5-1,10.1c0.4,0.8,0.9,1.8,1.5,2.7c-5.3,3.2-8.3,4.1-8.7,4.2
|
||||
c13.8,4.6,25.3,14.2,32.5,26.7l0.1-1.2c0.3-3.3,1.3-7.1,2.7-11c1.4,0.4,2.8,0.6,4.2,0.6l0,0c3.7,0,6.9-1.5,8.9-4.2
|
||||
C127.7,32.2,128.5,28.6,127.6,25.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="XMLID_62_">
|
||||
<g id="XMLID_64_">
|
||||
|
||||
<radialGradient id="XMLID_35_" cx="122.976" cy="80.6785" r="44.6944" gradientTransform="matrix(1 0 0 -1 0 100.7784)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#FFEAFF;stop-opacity:0.6"/>
|
||||
<stop offset="0.6807" style="stop-color:#A087C9"/>
|
||||
<stop offset="1" style="stop-color:#10002F"/>
|
||||
</radialGradient>
|
||||
<path id="XMLID_65_" class="st1" d="M113.2,35.6c9.1,2.5,12.8-4.5,11.6-9.2c-1.3-4.7-5.5-9.5-12.9-14.9S97,3.9,92.2,4.9
|
||||
s-6.2,8.3-5,11.1c0.5,1.1,1.6,2.7,3.1,4.5c-1.9,1.3-3.7,2.3-5.2,3.2c9.2,4.1,17.2,10.5,23.2,18.5c0.7-2.7,1.7-5.1,2.6-7.2
|
||||
C111.6,35.1,112.4,35.3,113.2,35.6z"/>
|
||||
</g>
|
||||
|
||||
<radialGradient id="XMLID_36_" cx="98.1105" cy="61.6169" r="109.3511" gradientTransform="matrix(1 0 0 -1 0 100.7784)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#FFEAFF;stop-opacity:0.6"/>
|
||||
<stop offset="0.6807" style="stop-color:#A087C9"/>
|
||||
<stop offset="1" style="stop-color:#10002F"/>
|
||||
</radialGradient>
|
||||
<circle id="XMLID_63_" class="st2" cx="61.1" cy="77.7" r="55.9"/>
|
||||
</g>
|
||||
<path id="XMLID_61_" class="st3" d="M120.2,21.8c-7.6-8-14-10.1-21.7-11.8c-6-1.4-4.4-4.8,2.9-4.1c-3.5-1.2-6.8-1.5-9.2-1
|
||||
c-4.8,1-6.2,8.3-5,11.1c0.5,1.1,1.6,2.7,3.1,4.5c-2.7,1.8-5,3.1-6.9,4.1c0.9,0.4,2,0.9,3.3,1.6c3.4,1.8,7.1,4.8,7.1,4.8
|
||||
c-5.6-4.8-4.4-7,3.3-12.4c2.4-1.7,6.8-1.5,10.9,0.6c4.1,2.1,8.9,7.4,8.9,7.4l-4.6,8.8c0.3,0.1,0.6,0.2,0.9,0.3
|
||||
c2.9,0.8,5.2,0.6,7-0.1C122.3,34.3,127.8,29.9,120.2,21.8z"/>
|
||||
<g id="XMLID_56_">
|
||||
<path id="XMLID_57_" class="st0" d="M98.4,14.8c2,0.8,4.6,2.2,7.8,4.3c3.8,2.5,7.1,5.3,9.2,7.5c-3.5,4.6-5.8,10.9-7.2,15.3
|
||||
c0.7,1,1.5,2,2.2,3c0.7-2.5,1.9-6.2,3.5-9.9c0.4,0.1,0.9,0.1,1.4,0.1c1.2,0,2.6-0.2,3.7-1.1c0.8-0.6,1.7-1.7,1.6-3.7
|
||||
c0-1.9-1.5-4.3-4.6-7.2c-2.2-2.1-5.2-4.4-8.2-6.5c-8.6-5.7-14.6-7.3-17.3-4.6c-1.8,1.8-1.6,4-1,5.6c-3.2,2.1-5.9,3.6-7.7,4.6
|
||||
c1.2,0.4,2.3,0.9,3.5,1.4C88.5,21.9,93.1,19,98.4,14.8z M117.3,29.1c0.3,0.5,0.4,1,0.4,1.3c0,0.9-0.3,1.2-0.5,1.4
|
||||
c-0.4,0.3-1.2,0.5-1.9,0.5C115.9,31.1,116.6,30.1,117.3,29.1z M92.6,14.2c0.3-0.3,1.1-0.5,2.4-0.3c-1,0.8-2,1.5-3,2.2
|
||||
C91.9,15.4,92,14.7,92.6,14.2z"/>
|
||||
</g>
|
||||
<g id="XMLID_52_">
|
||||
<path id="XMLID_53_" class="st0" d="M61.1,18.5C28.4,18.5,1.9,45,1.9,77.7s26.5,59.2,59.2,59.2s59.2-26.5,59.2-59.2
|
||||
S93.7,18.5,61.1,18.5z M61.1,133.6c-30.9,0-55.9-25-55.9-55.9s25-55.9,55.9-55.9s55.9,25,55.9,55.9S91.9,133.6,61.1,133.6z"/>
|
||||
</g>
|
||||
|
||||
<linearGradient id="XMLID_185_" gradientUnits="userSpaceOnUse" x1="-1397.5299" y1="-1163.0492" x2="-1285.7112" y2="-1163.0492" gradientTransform="matrix(0.16 -0.9871 -0.9871 -0.16 -872.2866 -1432.7015)">
|
||||
<stop offset="0" style="stop-color:#81FFFF"/>
|
||||
<stop offset="0.6202" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<circle id="XMLID_51_" class="st4" cx="61.1" cy="77.7" r="55.9"/>
|
||||
<g id="XMLID_49_">
|
||||
<path id="XMLID_50_" class="st3" d="M60.7,126.8c-30.5-4.9-51.2-33.6-46.2-64.1c2.2-13.5,9-25,18.6-33.3
|
||||
c-14,8.1-24.4,22.2-27.2,39.4C1,99.3,21.7,128,52.1,132.9c17,2.8,33.4-2.5,45.5-12.9C86.9,126.2,73.9,128.9,60.7,126.8z"/>
|
||||
</g>
|
||||
|
||||
<linearGradient id="XMLID_186_" gradientUnits="userSpaceOnUse" x1="100.4609" y1="61.0791" x2="54.2367" y2="18.6672" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_48_" class="st5" d="M70,22.6c-14.1-2.3-27.8,0.9-39,8c-0.2,0.2-0.4,0.4-0.4,0.4c4.3-2.6,10.6-4.9,10.6-4.9
|
||||
C25,35.5,20,46.2,20,46.2C26.3,34,44.8,25.4,59.3,24.8c14.5-0.6,24,3.7,35.6,13c11.6,9.4,18.6,28.6,17.9,43.8
|
||||
c-0.6,15.2-8.6,27.5-8.6,27.5c5.5-7.1,8.8-12.3,10.9-17.6c0.4-1.6,0.8-3.2,1-4.9C121.1,56.2,100.5,27.5,70,22.6z"/>
|
||||
<g id="XMLID_41_">
|
||||
|
||||
<linearGradient id="XMLID_187_" gradientUnits="userSpaceOnUse" x1="7.9" y1="-2.9716" x2="114.2" y2="-2.9716" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0" style="stop-color:#0002E9"/>
|
||||
<stop offset="0.9952" style="stop-color:#FF00C7"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_47_" class="st6" d="M114.2,77.2c0,29.3-23.8,53.1-53.1,53.1S7.9,106.5,7.9,77.2H114.2z"/>
|
||||
<g id="XMLID_45_" class="st7">
|
||||
|
||||
<linearGradient id="XMLID_188_" gradientUnits="userSpaceOnUse" x1="119.2316" y1="18.8884" x2="61.4115" y2="-35.7548" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_46_" class="st8" d="M110,77.2c0,28.6-22.6,52-51,53.1c0.7,0,1.4,0,2.1,0c29.3,0,53.1-23.8,53.1-53.1H110z"/>
|
||||
</g>
|
||||
<g id="XMLID_43_" class="st9">
|
||||
|
||||
<linearGradient id="XMLID_189_" gradientUnits="userSpaceOnUse" x1="7.9" y1="-2.9716" x2="64.7" y2="-2.9716" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0" style="stop-color:#000292"/>
|
||||
<stop offset="0.9952" style="stop-color:#7D00C7"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_44_" class="st10" d="M15.4,77.2H7.9c0,29.3,23.8,53.1,53.1,53.1c1.3,0,2.5,0,3.7-0.1
|
||||
C37.2,128.2,15.4,105.2,15.4,77.2z"/>
|
||||
</g>
|
||||
|
||||
<linearGradient id="XMLID_190_" gradientUnits="userSpaceOnUse" x1="8.0163" y1="18.6995" x2="114.1029" y2="18.6995" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0" style="stop-color:#000292"/>
|
||||
<stop offset="0.9952" style="stop-color:#BE00C7"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_42_" class="st11" d="M114.1,77.7c0-6.1-10.6-9.6-24.7-10.8c-10.2-0.8-20.5,0.2-32.3,3.8
|
||||
c-10.2,3-19.4,2.5-26.1,1.7c-14.9-1.7-23.1-1.9-23.1,5.3c0,10.4,21.2,23.4,53,18.9c16.1-2.3,24.4-7,33.9-10.2
|
||||
C105.1,83,114.1,83.1,114.1,77.7z"/>
|
||||
</g>
|
||||
<circle id="XMLID_40_" class="st12" cx="78.5" cy="43.5" r="9"/>
|
||||
<circle id="XMLID_39_" class="st12" cx="93.2" cy="55.4" r="3.8"/>
|
||||
<g id="XMLID_37_" class="st7">
|
||||
|
||||
<linearGradient id="XMLID_191_" gradientUnits="userSpaceOnUse" x1="112.3861" y1="75.5507" x2="104.7615" y2="63.1607" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_38_" class="st13" d="M106.8,36.3c-0.1,0-0.2,0-0.2,0c-0.6-0.1-1-0.7-0.9-1.4c0.9-4.6,4.7-9,4.9-9.2
|
||||
c0.4-0.5,1.2-0.5,1.6-0.1c0.5,0.4,0.5,1.2,0.1,1.6c-0.1,0.1-3.6,4.2-4.4,8.2C107.8,36,107.3,36.3,106.8,36.3z"/>
|
||||
</g>
|
||||
<g id="XMLID_29_">
|
||||
<circle id="XMLID_33_" class="st14" cx="57.4" cy="116.6" r="2.8"/>
|
||||
<g id="XMLID_31_" class="st15">
|
||||
|
||||
<linearGradient id="XMLID_192_" gradientUnits="userSpaceOnUse" x1="54.575" y1="-15.8431" x2="58.8059" y2="-15.8431" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_32_" class="st16" d="M55.8,118.4c-1.1-1.1-1.1-2.9,0-4c0.2-0.2,0.4-0.3,0.6-0.5c-0.4,0.1-0.7,0.3-1,0.6
|
||||
c-1.1,1.1-1.1,2.9,0,4c0.9,0.9,2.3,1.1,3.4,0.5C57.8,119.4,56.6,119.2,55.8,118.4z"/>
|
||||
</g>
|
||||
<circle id="XMLID_30_" class="st17" cx="58.4" cy="115.2" r="0.6"/>
|
||||
</g>
|
||||
<g id="XMLID_24_">
|
||||
<circle id="XMLID_28_" class="st14" cx="72" cy="115.2" r="2.8"/>
|
||||
<g id="XMLID_26_" class="st15">
|
||||
|
||||
<linearGradient id="XMLID_193_" gradientUnits="userSpaceOnUse" x1="69.162" y1="-14.4431" x2="73.3929" y2="-14.4431" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_27_" class="st18" d="M70.4,117c-1.1-1.1-1.1-2.9,0-4c0.2-0.2,0.4-0.3,0.6-0.5c-0.4,0.1-0.7,0.3-1,0.6
|
||||
c-1.1,1.1-1.1,2.9,0,4c0.9,0.9,2.3,1.1,3.4,0.5C72.4,118,71.2,117.8,70.4,117z"/>
|
||||
</g>
|
||||
<circle id="XMLID_25_" class="st17" cx="73" cy="113.8" r="0.6"/>
|
||||
</g>
|
||||
<g id="XMLID_19_">
|
||||
<circle id="XMLID_23_" class="st14" cx="64.8" cy="122.4" r="2.1"/>
|
||||
<g id="XMLID_21_" class="st15">
|
||||
|
||||
<linearGradient id="XMLID_194_" gradientUnits="userSpaceOnUse" x1="62.6869" y1="-21.6779" x2="65.8632" y2="-21.6779" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_22_" class="st19" d="M63.6,123.7c-0.8-0.8-0.8-2.2,0-3c0.1-0.1,0.3-0.2,0.4-0.3c-0.3,0.1-0.5,0.3-0.7,0.5
|
||||
c-0.8,0.8-0.8,2.2,0,3c0.7,0.7,1.7,0.8,2.6,0.3C65.1,124.5,64.2,124.3,63.6,123.7z"/>
|
||||
</g>
|
||||
<circle id="XMLID_20_" class="st17" cx="65.5" cy="121.3" r="0.4"/>
|
||||
</g>
|
||||
<g id="XMLID_14_" class="st20">
|
||||
<circle id="XMLID_18_" class="st21" cx="77.7" cy="120.9" r="2.1"/>
|
||||
<g id="XMLID_16_" class="st22">
|
||||
|
||||
<linearGradient id="XMLID_195_" gradientUnits="userSpaceOnUse" x1="75.5437" y1="-20.1779" x2="78.72" y2="-20.1779" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_17_" class="st23" d="M76.5,122.2c-0.8-0.8-0.8-2.2,0-3c0.1-0.1,0.3-0.2,0.4-0.3c-0.3,0.1-0.5,0.3-0.7,0.5
|
||||
c-0.8,0.8-0.8,2.2,0,3c0.7,0.7,1.7,0.8,2.6,0.3C78,123,77.1,122.8,76.5,122.2z"/>
|
||||
</g>
|
||||
<circle id="XMLID_15_" class="st24" cx="78.4" cy="119.8" r="0.4"/>
|
||||
</g>
|
||||
<g id="XMLID_9_">
|
||||
<circle id="XMLID_13_" class="st14" cx="45.5" cy="113.8" r="4.6"/>
|
||||
<g id="XMLID_11_" class="st15">
|
||||
|
||||
<linearGradient id="XMLID_196_" gradientUnits="userSpaceOnUse" x1="40.9041" y1="-13.1521" x2="47.8135" y2="-13.1521" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_12_" class="st25" d="M42.9,116.7c-1.8-1.8-1.8-4.7,0-6.5c0.3-0.3,0.6-0.5,1-0.7c-0.6,0.2-1.1,0.6-1.6,1
|
||||
c-1.8,1.8-1.8,4.7,0,6.5c1.5,1.5,3.8,1.8,5.6,0.7C46.2,118.4,44.2,118.1,42.9,116.7z"/>
|
||||
</g>
|
||||
<circle id="XMLID_10_" class="st17" cx="47.1" cy="111.4" r="1"/>
|
||||
</g>
|
||||
<g id="XMLID_4_">
|
||||
<circle id="XMLID_8_" class="st14" cx="86.6" cy="102.5" r="4.6"/>
|
||||
<g id="XMLID_6_" class="st15">
|
||||
|
||||
<linearGradient id="XMLID_197_" gradientUnits="userSpaceOnUse" x1="81.9424" y1="-1.8521" x2="88.8518" y2="-1.8521" gradientTransform="matrix(1 0 0 -1 0 100.7784)">
|
||||
<stop offset="0.2888" style="stop-color:#FFFFFF"/>
|
||||
<stop offset="0.7796" style="stop-color:#FFFFFF;stop-opacity:0"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_7_" class="st26" d="M83.9,105.4c-1.8-1.8-1.8-4.7,0-6.5c0.3-0.3,0.6-0.5,1-0.7c-0.6,0.2-1.1,0.6-1.6,1
|
||||
c-1.8,1.8-1.8,4.7,0,6.5c1.5,1.5,3.8,1.8,5.6,0.7C87.2,107.1,85.3,106.8,83.9,105.4z"/>
|
||||
</g>
|
||||
<circle id="XMLID_5_" class="st17" cx="88.2" cy="100.1" r="1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<svg fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path
|
||||
d='M22.8084 4.42014C22.5667 3.50503 21.7897 2.58992 20.3912 1.57122C19.2689 0.759705 18.0775 0.293518 17.1279 0.293518C16.9379 0.293518 16.7653 0.310784 16.5926 0.345317C16.1609 0.431648 15.7811 0.742439 15.5394 1.20863C15.2458 1.76114 15.1768 2.50359 15.3667 2.95251C15.4358 3.09064 15.5221 3.2633 15.6257 3.4187C14.7106 3.97122 14.1926 4.12661 14.1235 4.14388C16.5063 4.93812 18.4919 6.59568 19.735 8.75395L19.7523 8.54676C19.8041 7.97697 19.9768 7.32086 20.2185 6.64748C20.4602 6.71654 20.702 6.75107 20.9437 6.75107C21.5825 6.75107 22.135 6.49208 22.4804 6.02589C22.8257 5.55971 22.9638 4.93812 22.8084 4.42014Z'
|
||||
fill='#5E12A0'
|
||||
></path>
|
||||
<path
|
||||
d='M20.3225 6.14679C21.8937 6.57844 22.5326 5.36981 22.3254 4.5583C22.1009 3.74679 21.3757 2.91801 20.098 1.98564C18.8203 1.05326 17.5254 0.673409 16.6966 0.846071C15.8678 1.01873 15.6261 2.27916 15.8333 2.76262C15.9196 2.95255 16.1096 3.2288 16.3685 3.5396C16.0405 3.76406 15.7297 3.93672 15.4707 4.09211C17.0592 4.80003 18.4405 5.90506 19.4765 7.28636C19.5973 6.82017 19.77 6.40578 19.9254 6.04319C20.0462 6.06046 20.1844 6.09499 20.3225 6.14679Z'
|
||||
fill='url(#paint0_radial_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z'
|
||||
fill='url(#paint1_radial_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M21.5307 3.76403C20.2185 2.38274 19.1134 2.02015 17.784 1.72662C16.748 1.4849 17.0242 0.897845 18.2847 1.01871C17.6804 0.811514 17.1106 0.759716 16.6962 0.846047C15.8674 1.01871 15.6257 2.27914 15.8329 2.76259C15.9192 2.95252 16.1091 3.22878 16.3681 3.53957C15.9019 3.85036 15.5048 4.07482 15.1768 4.24749C15.3322 4.31655 15.5221 4.40288 15.7465 4.52375C16.3336 4.83454 16.9724 5.35252 16.9724 5.35252C16.0055 4.52375 16.2127 4.14389 17.5422 3.21151C17.9566 2.91799 18.7163 2.95252 19.4242 3.31511C20.1322 3.6777 20.9609 4.59281 20.9609 4.59281L20.1667 6.11223C20.2185 6.1295 20.2703 6.14677 20.3221 6.16403C20.8228 6.30216 21.2199 6.26763 21.5307 6.14677C21.8933 5.92231 22.8429 5.16259 21.5307 3.76403Z'
|
||||
fill='#A98698'
|
||||
fill-opacity='0.6'
|
||||
></path>
|
||||
<path
|
||||
d='M17.7671 2.55539C18.1124 2.69352 18.5613 2.93525 19.1138 3.29784C19.7699 3.72949 20.3397 4.21295 20.7023 4.5928C20.098 5.38705 19.7009 6.47482 19.4592 7.23453C19.58 7.40719 19.7181 7.57985 19.839 7.75252C19.9599 7.32086 20.1671 6.68201 20.4433 6.04316C20.5124 6.06043 20.5987 6.06043 20.6851 6.06043C20.8922 6.06043 21.134 6.0259 21.3239 5.8705C21.462 5.7669 21.6174 5.57698 21.6002 5.23165C21.6002 4.90359 21.3412 4.48921 20.8059 3.98849C20.4261 3.6259 19.9081 3.22878 19.3901 2.86619C17.9052 1.88201 16.8692 1.60575 16.403 2.07194C16.0922 2.38273 16.1268 2.76259 16.2304 3.03885C15.6779 3.40144 15.2117 3.66043 14.9009 3.83309C15.1081 3.90216 15.298 3.98849 15.5052 4.07482C16.0577 3.78129 16.852 3.28057 17.7671 2.55539ZM21.0304 5.02446C21.0822 5.11079 21.0994 5.19712 21.0994 5.24892C21.0994 5.40431 21.0476 5.45611 21.0131 5.49065C20.944 5.54244 20.8059 5.57698 20.6851 5.57698C20.7886 5.36978 20.9095 5.19712 21.0304 5.02446ZM16.7656 2.4518C16.8174 2.4 16.9556 2.36547 17.18 2.4C17.0074 2.53813 16.8347 2.65899 16.662 2.77985C16.6448 2.65899 16.662 2.53813 16.7656 2.4518Z'
|
||||
fill='#5E12A0'
|
||||
></path>
|
||||
<path
|
||||
d='M11.3266 3.19427C5.68052 3.19427 1.10498 7.76981 1.10498 13.4159C1.10498 19.0619 5.68052 23.6374 11.3266 23.6374C16.9726 23.6374 21.5481 19.0619 21.5481 13.4159C21.5481 7.76981 16.9553 3.19427 11.3266 3.19427ZM11.3266 23.0677C5.99131 23.0677 1.67476 18.7511 1.67476 13.4159C1.67476 8.08061 5.99131 3.76406 11.3266 3.76406C16.6618 3.76406 20.9784 8.08061 20.9784 13.4159C20.9784 18.7511 16.6445 23.0677 11.3266 23.0677Z'
|
||||
fill='#5E12A0'
|
||||
></path>
|
||||
<path
|
||||
d='M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z'
|
||||
fill='url(#paint2_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M11.2577 21.8935C5.99153 21.0475 2.41743 16.0921 3.28074 10.8259C3.6606 8.49494 4.8347 6.50933 6.49225 5.07623C4.07499 6.47479 2.2793 8.90933 1.79585 11.8791C0.949806 17.1453 4.52391 22.1007 9.77283 22.9467C12.7081 23.4302 15.5397 22.5151 17.6289 20.7194C15.7815 21.7899 13.5369 22.2561 11.2577 21.8935Z'
|
||||
fill='#A98698'
|
||||
fill-opacity='0.6'
|
||||
></path>
|
||||
<path
|
||||
d='M12.8631 3.90216C10.4285 3.50504 8.06307 4.05756 6.12926 5.28346C6.09473 5.31799 6.0602 5.35252 6.0602 5.35252C6.80264 4.9036 7.89041 4.50648 7.89041 4.50648C5.09329 6.1295 4.22998 7.97698 4.22998 7.97698C5.31775 5.87051 8.51199 4.38562 11.0156 4.28202C13.5192 4.17842 15.1595 4.92087 17.1624 6.52662C19.1652 8.14964 20.3739 11.4648 20.253 14.0892C20.1494 16.7137 18.7681 18.8374 18.7681 18.8374C19.7177 17.6115 20.2875 16.7137 20.6501 15.7986C20.7192 15.5223 20.7883 15.246 20.8228 14.9525C21.6861 9.7036 18.1293 4.74821 12.8631 3.90216Z'
|
||||
fill='url(#paint3_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M20.4951 13.3295C20.4951 18.3885 16.3857 22.4978 11.3267 22.4978C6.26773 22.4978 2.14111 18.3885 2.14111 13.3295H20.4951Z'
|
||||
fill='url(#paint4_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M19.7696 13.3295C19.7696 18.2676 15.8675 22.3079 10.9639 22.4978H11.3265C16.3855 22.4978 20.4948 18.3885 20.4948 13.3295H19.7696Z'
|
||||
fill='url(#paint5_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M3.43608 13.3295H2.14111C2.14111 18.3885 6.25047 22.4978 11.3095 22.4978C11.5339 22.4978 11.7411 22.4978 11.9483 22.4805C7.20011 22.1352 3.43608 18.164 3.43608 13.3295Z'
|
||||
fill='url(#paint6_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M20.4778 13.4158C20.4778 12.3626 18.6476 11.7583 16.2131 11.5511C14.4519 11.413 12.6735 11.5856 10.6361 12.2072C8.87493 12.7252 7.28644 12.6389 6.1296 12.5007C3.55694 12.2072 2.14111 12.1727 2.14111 13.4158C2.14111 15.2115 5.80155 17.4561 11.2922 16.6792C14.072 16.282 15.5051 15.4705 17.1454 14.918C18.9238 14.331 20.4778 14.3482 20.4778 13.4158Z'
|
||||
fill='url(#paint7_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M14.3308 9.06476C15.1891 9.06476 15.8848 8.36911 15.8848 7.5108C15.8848 6.6525 15.1891 5.95685 14.3308 5.95685C13.4725 5.95685 12.7769 6.6525 12.7769 7.5108C12.7769 8.36911 13.4725 9.06476 14.3308 9.06476Z'
|
||||
fill='white'
|
||||
></path>
|
||||
<path
|
||||
d='M16.869 10.2216C17.2314 10.2216 17.5251 9.9279 17.5251 9.56548C17.5251 9.20306 17.2314 8.90936 16.869 8.90936C16.5066 8.90936 16.2129 9.20306 16.2129 9.56548C16.2129 9.9279 16.5066 10.2216 16.869 10.2216Z'
|
||||
fill='white'
|
||||
></path>
|
||||
<path
|
||||
d='M19.2175 6.2676H19.1829C19.0793 6.25034 19.0103 6.14674 19.0275 6.02588C19.1829 5.23163 19.8391 4.47192 19.8736 4.43739C19.9427 4.35106 20.0808 4.35106 20.1498 4.42012C20.2362 4.48919 20.2362 4.62732 20.1671 4.69638C20.1498 4.71365 19.5455 5.42156 19.4074 6.11221C19.3901 6.2158 19.3038 6.2676 19.2175 6.2676Z'
|
||||
fill='url(#paint8_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M10.6876 20.6158C10.9545 20.6158 11.171 20.3993 11.171 20.1324C11.171 19.8654 10.9545 19.6489 10.6876 19.6489C10.4206 19.6489 10.2041 19.8654 10.2041 20.1324C10.2041 20.3993 10.4206 20.6158 10.6876 20.6158Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M10.4117 20.4432C10.2218 20.2532 10.2218 19.9425 10.4117 19.7525C10.4462 19.718 10.4808 19.7007 10.5153 19.6662C10.4462 19.6835 10.3944 19.718 10.3426 19.7698C10.1527 19.9597 10.1527 20.2705 10.3426 20.4604C10.498 20.6158 10.7398 20.6504 10.9297 20.5468C10.757 20.6158 10.5498 20.5813 10.4117 20.4432Z'
|
||||
fill='url(#paint9_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M10.8604 19.9942C10.9176 19.9942 10.964 19.9478 10.964 19.8906C10.964 19.8335 10.9176 19.787 10.8604 19.787C10.8033 19.787 10.7568 19.8335 10.7568 19.8906C10.7568 19.9478 10.8033 19.9942 10.8604 19.9942Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<path
|
||||
d='M13.2086 20.3741C13.4755 20.3741 13.692 20.1576 13.692 19.8906C13.692 19.6237 13.4755 19.4072 13.2086 19.4072C12.9416 19.4072 12.7251 19.6237 12.7251 19.8906C12.7251 20.1576 12.9416 20.3741 13.2086 20.3741Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M12.9322 20.2014C12.7423 20.0115 12.7423 19.7007 12.9322 19.5108C12.9667 19.4762 13.0013 19.459 13.0358 19.4244C12.9667 19.4417 12.9149 19.4762 12.8631 19.528C12.6732 19.718 12.6732 20.0288 12.8631 20.2187C13.0185 20.3741 13.2603 20.4086 13.4502 20.305C13.2775 20.3741 13.0703 20.3395 12.9322 20.2014Z'
|
||||
fill='url(#paint10_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M13.3814 19.7525C13.4386 19.7525 13.485 19.7061 13.485 19.6489C13.485 19.5918 13.4386 19.5453 13.3814 19.5453C13.3243 19.5453 13.2778 19.5918 13.2778 19.6489C13.2778 19.7061 13.3243 19.7525 13.3814 19.7525Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<path
|
||||
d='M11.9656 21.4964C12.1659 21.4964 12.3282 21.3341 12.3282 21.1338C12.3282 20.9335 12.1659 20.7712 11.9656 20.7712C11.7653 20.7712 11.603 20.9335 11.603 21.1338C11.603 21.3341 11.7653 21.4964 11.9656 21.4964Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M11.7584 21.3583C11.6203 21.2202 11.6203 20.9784 11.7584 20.8403C11.7757 20.823 11.8102 20.8058 11.8275 20.7885C11.7757 20.8058 11.7412 20.8403 11.7066 20.8748C11.5685 21.013 11.5685 21.2547 11.7066 21.3928C11.8275 21.5137 12.0002 21.531 12.1555 21.4446C12.0174 21.4964 11.862 21.4619 11.7584 21.3583Z'
|
||||
fill='url(#paint11_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M12.0862 21.0129C12.1243 21.0129 12.1552 20.982 12.1552 20.9439C12.1552 20.9057 12.1243 20.8748 12.0862 20.8748C12.048 20.8748 12.0171 20.9057 12.0171 20.9439C12.0171 20.982 12.048 21.0129 12.0862 21.0129Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<path
|
||||
d='M14.1927 21.2374C14.393 21.2374 14.5553 21.0751 14.5553 20.8748C14.5553 20.6745 14.393 20.5122 14.1927 20.5122C13.9924 20.5122 13.8301 20.6745 13.8301 20.8748C13.8301 21.0751 13.9924 21.2374 14.1927 21.2374Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M13.9855 21.0993C13.8473 20.9611 13.8473 20.7194 13.9855 20.5813C14.0027 20.564 14.0373 20.5467 14.0545 20.5295C14.0027 20.5467 13.9682 20.5813 13.9337 20.6158C13.7955 20.7539 13.7955 20.9957 13.9337 21.1338C14.0545 21.2547 14.2272 21.2719 14.3826 21.1856C14.2445 21.2374 14.0891 21.2029 13.9855 21.0993Z'
|
||||
fill='url(#paint12_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M14.3137 20.754C14.3519 20.754 14.3828 20.7231 14.3828 20.6849C14.3828 20.6468 14.3519 20.6158 14.3137 20.6158C14.2755 20.6158 14.2446 20.6468 14.2446 20.6849C14.2446 20.7231 14.2755 20.754 14.3137 20.754Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<path
|
||||
d='M8.63311 20.4432C9.07185 20.4432 9.42736 20.0877 9.42736 19.6489C9.42736 19.2104 9.07185 18.8547 8.63311 18.8547C8.19455 18.8547 7.83887 19.2104 7.83887 19.6489C7.83887 20.0877 8.19455 20.4432 8.63311 20.4432Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M8.18435 20.1497C7.87356 19.8389 7.87356 19.3381 8.18435 19.0274C8.23615 18.9756 8.28794 18.941 8.35701 18.9065C8.25341 18.941 8.16708 19.0101 8.08075 19.0792C7.76996 19.3899 7.76996 19.8907 8.08075 20.2015C8.33974 20.4605 8.73687 20.5122 9.04766 20.3223C8.75413 20.4432 8.40881 20.3914 8.18435 20.1497Z'
|
||||
fill='url(#paint13_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M8.90948 19.4072C9.00479 19.4072 9.08214 19.3299 9.08214 19.2346C9.08214 19.1392 9.00479 19.0619 8.90948 19.0619C8.81417 19.0619 8.73682 19.1392 8.73682 19.2346C8.73682 19.3299 8.81417 19.4072 8.90948 19.4072Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<path
|
||||
d='M15.7293 18.4921C16.168 18.4921 16.5235 18.1366 16.5235 17.6979C16.5235 17.2593 16.168 16.9036 15.7293 16.9036C15.2907 16.9036 14.9351 17.2593 14.9351 17.6979C14.9351 18.1366 15.2907 18.4921 15.7293 18.4921Z'
|
||||
fill='white'
|
||||
fill-opacity='0.2'
|
||||
></path>
|
||||
<path
|
||||
d='M15.2634 18.1985C14.9527 17.8878 14.9527 17.387 15.2634 17.0762C15.3152 17.0244 15.367 16.9899 15.4361 16.9554C15.3325 16.9899 15.2462 17.059 15.1599 17.128C14.8491 17.4388 14.8491 17.9396 15.1599 18.2503C15.4188 18.5093 15.816 18.5611 16.1268 18.3712C15.8332 18.4921 15.5052 18.4403 15.2634 18.1985Z'
|
||||
fill='url(#paint14_linear_8766_48743)'
|
||||
></path>
|
||||
<path
|
||||
d='M16.0057 17.4561C16.101 17.4561 16.1783 17.3788 16.1783 17.2834C16.1783 17.1881 16.101 17.1108 16.0057 17.1108C15.9104 17.1108 15.833 17.1881 15.833 17.2834C15.833 17.3788 15.9104 17.4561 16.0057 17.4561Z'
|
||||
fill='white'
|
||||
fill-opacity='0.3'
|
||||
></path>
|
||||
<defs>
|
||||
<radialGradient
|
||||
cx='0'
|
||||
cy='0'
|
||||
gradientTransform='translate(22.0104 3.47051) scale(7.71702 7.71702)'
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint0_radial_8766_48743'
|
||||
r='1'
|
||||
>
|
||||
<stop stop-color='#FFEAFF' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.68' stop-color='#A087C9'></stop>
|
||||
<stop offset='1' stop-color='#10002F'></stop>
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
cx='0'
|
||||
cy='0'
|
||||
gradientTransform='translate(17.7169 6.76169) scale(18.8808)'
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint1_radial_8766_48743'
|
||||
r='1'
|
||||
>
|
||||
<stop stop-color='#FFEAFF' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.68' stop-color='#A087C9'></stop>
|
||||
<stop offset='1' stop-color='#10002F'></stop>
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint2_linear_8766_48743'
|
||||
x1='9.77838'
|
||||
x2='12.8655'
|
||||
y1='22.9307'
|
||||
y2='3.8849'
|
||||
>
|
||||
<stop stop-color='#81FFFF' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.62' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint3_linear_8766_48743'
|
||||
x1='18.1284'
|
||||
x2='10.1473'
|
||||
y1='6.861'
|
||||
y2='14.1839'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint4_linear_8766_48743'
|
||||
x1='2.14889'
|
||||
x2='20.4906'
|
||||
y1='17.9083'
|
||||
y2='17.9083'
|
||||
>
|
||||
<stop stop-color='#0002E9'></stop>
|
||||
<stop offset='1' stop-color='#FF00C7'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint5_linear_8766_48743'
|
||||
x1='21.3586'
|
||||
x2='11.3753'
|
||||
y1='14.134'
|
||||
y2='23.5688'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint6_linear_8766_48743'
|
||||
x1='2.14889'
|
||||
x2='11.9616'
|
||||
y1='17.9083'
|
||||
y2='17.9083'
|
||||
>
|
||||
<stop stop-color='#000292' stop-opacity='0.7'></stop>
|
||||
<stop offset='1' stop-color='#7D00C7' stop-opacity='0.7'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint7_linear_8766_48743'
|
||||
x1='2.1612'
|
||||
x2='20.4784'
|
||||
y1='14.1775'
|
||||
y2='14.1775'
|
||||
>
|
||||
<stop stop-color='#000292'></stop>
|
||||
<stop offset='1' stop-color='#BE00C7'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint8_linear_8766_48743'
|
||||
x1='20.1778'
|
||||
x2='18.8614'
|
||||
y1='4.3533'
|
||||
y2='6.49258'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint9_linear_8766_48743'
|
||||
x1='10.1997'
|
||||
x2='10.9302'
|
||||
y1='20.1472'
|
||||
y2='20.1472'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint10_linear_8766_48743'
|
||||
x1='12.7185'
|
||||
x2='13.449'
|
||||
y1='19.9022'
|
||||
y2='19.9022'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint11_linear_8766_48743'
|
||||
x1='11.6008'
|
||||
x2='12.1492'
|
||||
y1='21.138'
|
||||
y2='21.138'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint12_linear_8766_48743'
|
||||
x1='13.8204'
|
||||
x2='14.3688'
|
||||
y1='20.8783'
|
||||
y2='20.8783'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint13_linear_8766_48743'
|
||||
x1='7.83973'
|
||||
x2='9.03272'
|
||||
y1='19.6691'
|
||||
y2='19.6691'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits='userSpaceOnUse'
|
||||
id='paint14_linear_8766_48743'
|
||||
x1='14.9254'
|
||||
x2='16.1184'
|
||||
y1='17.7175'
|
||||
y2='17.7175'
|
||||
>
|
||||
<stop stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
|
||||
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
|
||||
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 18 KiB |
38
public/tokens/statom.svg
Normal file
@ -0,0 +1,38 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 2500 2500" style="enable-background:new 0 0 2500 2500;" xml:space="preserve">
|
||||
<circle style="fill:#E50571;" cx="1250" cy="1250" r="1250"/>
|
||||
<circle style="fill:#FFFFFF;" cx="1250" cy="1250" r="128.6"/>
|
||||
<path style="fill:#FFFFFF;" d="M1709.1,1253.5c336.5-233.9,543.2-454.9,491.6-544.9c-33.3-58.1-168.1-50.8-359.4,8.1
|
||||
c-13-22.6-36.8-37.7-64.1-37.7c-41.2,0-74.6,34.5-74.6,77.2c0,2.8,0.2,5.6,0.4,8.3c-69.8,26.5-144.5,58.1-222.5,94.3
|
||||
c-35.3-409.1-124.1-699.3-228-699.3c-103.7,0-192.4,289.3-227.8,697.4c-370.9-173.9-665.9-242-718-152.1
|
||||
c-32.5,56.3,35.9,164.2,173.9,294.7c-1.5,6.1-2.3,12.5-2.3,19.1c0,42.6,33.4,77.2,74.6,77.2c10.5,0,20.5-2.3,29.6-6.3
|
||||
c62.9,52.3,134.6,106.9,213.5,162.2c-336.6,233.9-543.3,454.9-491.6,544.9c51.7,90.1,347.6,22.7,720.2-150.2
|
||||
c7.9,91.7,18.5,177.4,31.4,255.2c-19.5,13.9-32.3,37.2-32.3,63.5c0,37.3,25.6,68.4,59.6,75.6c43.9,188.9,103.6,305.1,169.3,305.1
|
||||
c103.8,0,192.4-289.4,227.8-697.6c371,174,665.9,242.2,717.9,152.3C2250.4,1710.6,2044.5,1488.8,1709.1,1253.5z M1725.6,811.8
|
||||
c13.4,13.3,31.6,21.5,51.7,21.5c37.1,0,67.9-28,73.6-64.8c190.7-59.8,268.1-52.8,295.1-45.4c9.1,2.5,15,11.2,14,20.6
|
||||
c-5.1,56-104.2,157-104.2,157c-132.1,131.9-271.4,241.7-387.7,324.4c-54.8-37.5-112.7-75.2-173.3-112.6
|
||||
c-2-69.4-5.4-136.8-10.2-201.5C1576.7,870.1,1656.5,837.6,1725.6,811.8z M1398,1397.6c-47.4,29.1-96.7,57-146.1,83.3
|
||||
c-33.6-18.8-52-30.1-52-30.1c-46.3-25-92.5-52-137.6-79.9c-2.2-85.5-2.7-164-2.4-227.6c71-43.2,136.9-81.4,190.9-112.1
|
||||
c76.2,41.6,145,81.1,199.8,113.2c0.4,34.7-0.1,54.1-0.1,54.1c1.7,55.9,1.3,112.8-0.5,169.1C1417,1387.3,1398,1397.6,1398,1397.6z
|
||||
M1448,1421.5c-2.5,53.4-6.2,105.5-10.4,154.9c-54.3-25.8-101-49.7-138.3-69.6c24.9-13.7,50-27.8,75.2-42.2
|
||||
C1399.3,1450.2,1423.8,1435.9,1448,1421.5z M1203.7,1506c-45.2,23.2-90.1,44.9-133,65c-3-49.4-5.2-98.4-6.8-145.8
|
||||
c21.7,13.1,43.8,26.1,66.1,39C1154.8,1478.5,1179.3,1492.4,1203.7,1506z M1009,1337.3c-43.2-27.8-85-56-124.2-83.4
|
||||
c41.7-27.4,83.5-53.9,124.1-79.1c-0.4,25.7-0.6,51.7-0.6,77.9C1008.2,1281.1,1008.5,1309.3,1009,1337.3z M1066.8,934.6
|
||||
c44.8,22.5,88.9,45.4,131.2,68c-22.3,12.4-44.8,25-67.3,37.9c-23.7,13.6-47.2,27.3-70.2,41.1c0.8-61.8,2.1-99.1,2.1-99.1
|
||||
C1063.9,966.2,1065.4,950.3,1066.8,934.6z M1304.9,1000.9c54.2-30.2,87.3-47.7,87.3-47.7c16.4-7.6,32.4-15,48-22.1
|
||||
c4.9,59.5,7.5,111.6,9,153.5c-24.3-14.6-48.9-29.2-73.9-43.7C1351.8,1027.3,1328.3,1013.9,1304.9,1000.9z M1496.2,1171.4
|
||||
c53.4,31.9,85.3,51.8,85.3,51.8c15.2,10.6,30,21.1,44.5,31.4c-49.7,34.2-93.9,62.7-129.8,85c0.5-28.7,0.8-57.8,0.8-87.1
|
||||
C1496.9,1225.3,1496.7,1198.2,1496.2,1171.4z M1238.2,214.2c6.7-6.6,17.1-7.4,24.7-2c45.9,32.5,84.4,168.5,84.4,168.5
|
||||
c48.7,180.9,74.7,357.1,88.4,499.3c-59.3,28.4-120.2,59.3-182.3,92.6c-61.6-33.4-122.2-64.5-181.2-93
|
||||
C1124.6,369.7,1208.5,243.6,1238.2,214.2z M619.2,1054c5.3-10.6,8.4-22.7,8.4-35.5c0-42.6-33.4-77.2-74.6-77.2
|
||||
c-16.7,0-32,5.7-44.5,15.2C364.1,818,351.7,750.1,351.7,750.1l-0.1-0.3c-10-23.7,11.1-29.4,11.1-29.4
|
||||
c93.5-17.6,224.7,22.6,224.7,22.6c123.5,28.1,280.4,94.2,432.9,168.6c-4.7,64.4-8.1,131.3-10.1,200.3
|
||||
c-59.6,36.5-116.7,73.2-170.8,109.8C736.8,1148.2,656.4,1084.2,619.2,1054z M736.1,1711.7c-280.1,100.9-369.7,68.8-369.7,68.8h0
|
||||
c-25.7-3.2-19.9-24.4-19.9-24.4c31.5-89.7,132-183.2,132-183.2c86.2-92.8,222-195.4,362.8-290c53.6,36.5,110.1,73.2,169,109.7
|
||||
c2,69.5,5.4,136.9,10.2,201.7C859.5,1666.9,736.1,1711.7,736.1,1711.7z M1393.7,1929c-51.8,293.2-124.2,355-124.2,355
|
||||
c-15.4,20.6-30.9,5.1-30.9,5.1c-62.1-72-93.2-205.8-93.2-205.8c-4.9-15.7-9.5-32.1-13.8-49.3c24.5-12.7,41.3-38.8,41.3-69
|
||||
c0-41.1-31-74.7-70.2-77c-12.9-83.4-22.1-174.2-28.5-265.2c57.8-27.8,117.3-58,177.7-90.4c61.7,33.4,122.3,64.5,181.2,93.1
|
||||
C1416.1,1800.5,1393.7,1929,1393.7,1929z M2147.6,1782.8c-51.1,23.4-188.1-11.5-188.1-11.5c-180.4-48.4-345.3-113.9-475.1-173.2
|
||||
c4.9-65.8,8.4-134.4,10.5-205.1c59.6-36.5,116.7-73.3,170.8-109.9c414.9,300.9,482,436.8,492.5,477.1
|
||||
C2160.7,1769.5,2156.1,1778.9,2147.6,1782.8z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
@ -6,7 +6,7 @@ import Background from 'components/Background'
|
||||
import FetchPrices from 'components/FetchPrices'
|
||||
import Footer from 'components/Footer'
|
||||
import DesktopHeader from 'components/Header/DesktopHeader'
|
||||
import { Modals } from 'components/Modals'
|
||||
import ModalsContainer from 'components/Modals/ModalsContainer'
|
||||
import Toaster from 'components/Toaster'
|
||||
import 'react-toastify/dist/ReactToastify.min.css'
|
||||
import 'styles/globals.css'
|
||||
@ -28,11 +28,13 @@ export default function RootLayout(props: { children: React.ReactNode }) {
|
||||
'lg:mt-[65px] lg:h-[calc(100vh-89px)]',
|
||||
)}
|
||||
>
|
||||
<div className='flex max-w-content flex-grow flex-col flex-wrap'>{props.children}</div>
|
||||
<div className='flex w-full max-w-content flex-grow flex-wrap content-start'>
|
||||
{props.children}
|
||||
</div>
|
||||
<AccountDetails />
|
||||
</main>
|
||||
<Footer />
|
||||
<Modals />
|
||||
<ModalsContainer />
|
||||
<Toaster />
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,3 +1,5 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import Card from 'components/Card'
|
||||
import { Plus, Subtract } from 'components/Icons'
|
||||
import Text from 'components/Text'
|
||||
@ -14,9 +16,15 @@ interface Item {
|
||||
export default function Accordion(props: Props) {
|
||||
return (
|
||||
<Card>
|
||||
{props.items.map((item, index) => (
|
||||
{props.items.map((item) => (
|
||||
<details key={item.title} className='group border-b-white/10 [&:not(:last-child)]:border-b'>
|
||||
<summary className='mb-0 flex cursor-pointer items-center justify-between border-t border-white/10 bg-white/10 p-4 text-white group-[&:first-child]:border-t-0 group-[[open]]:border-b [&::marker]:hidden [&::marker]:content-[""]'>
|
||||
<summary
|
||||
className={classNames(
|
||||
'mb-0 flex cursor-pointer items-center justify-between border-t border-white/10 bg-white/10 p-4 text-white',
|
||||
'group-[&:first-child]:border-t-0 group-[[open]]:border-b',
|
||||
'[&::marker]:hidden [&::marker]:content-[""]',
|
||||
)}
|
||||
>
|
||||
<Text>{item.title}</Text>
|
||||
<div className='block h-[14px] w-[14px] group-[[open]]:hidden'>
|
||||
<Plus />
|
||||
@ -25,7 +33,9 @@ export default function Accordion(props: Props) {
|
||||
<Subtract />
|
||||
</div>
|
||||
</summary>
|
||||
<div className='bg-white/5 p-4'>{item.content}</div>
|
||||
<div className='bg-white/5 px-4 py-0 transition-[padding] group-[[open]]:py-4'>
|
||||
{item.content}
|
||||
</div>
|
||||
</details>
|
||||
))}
|
||||
</Card>
|
||||
|
58
src/components/Account/AccountHealth.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
'use client'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { Heart } from 'components/Icons'
|
||||
import Text from 'components/Text'
|
||||
import useStore from 'store'
|
||||
|
||||
interface Props {
|
||||
health: number
|
||||
hasLabel?: boolean
|
||||
classNames?: string
|
||||
}
|
||||
|
||||
export default function AccountHealth(props: Props) {
|
||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||
const healthBarWidth = (props.health / 100) * 53
|
||||
|
||||
return (
|
||||
<div className={classNames('flex items-center gap-1.5', props.classNames)}>
|
||||
<div className='flex h-4 w-3 flex-auto'>
|
||||
<Heart />
|
||||
</div>
|
||||
{props.hasLabel && (
|
||||
<Text size='xs' className='pr-0.5 text-white/70'>
|
||||
Health
|
||||
</Text>
|
||||
)}
|
||||
<div className='flex flex-shrink'>
|
||||
<svg width='100%' viewBox='0 0 53 4' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect width='53' height='4' rx='2' fill='white' fillOpacity='0.1' />
|
||||
<rect
|
||||
width={healthBarWidth}
|
||||
height='4'
|
||||
rx='2'
|
||||
fill='url(#bar)'
|
||||
style={{
|
||||
transition: enableAnimations ? 'width 1s ease' : 'none',
|
||||
}}
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id='bar'
|
||||
x1='0%'
|
||||
y1='0%'
|
||||
x2='100%'
|
||||
y2='0%'
|
||||
gradientUnits='userSpaceOnUse'
|
||||
>
|
||||
<stop stopColor='#FF645F' />
|
||||
<stop offset='0.5' stopColor='#FFB1AE' />
|
||||
<stop offset='1' stopColor='#FFD5D3' />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -99,7 +99,7 @@ export default function AccountList(props: Props) {
|
||||
{isActive ? (
|
||||
<>
|
||||
<div className='w-full border border-transparent border-b-white/20 p-4'>
|
||||
<AccountStats balance={selectedAccountBalance} risk={75} health={0.85} />
|
||||
<AccountStats balance={selectedAccountBalance} risk={75} health={85} />
|
||||
</div>
|
||||
<div className='grid grid-flow-row grid-cols-2 gap-4 p-4'>
|
||||
<Button
|
||||
@ -117,6 +117,7 @@ export default function AccountList(props: Props) {
|
||||
onClick={() => {
|
||||
useStore.setState({ withdrawModal: true })
|
||||
}}
|
||||
disabled={positionBalance <= 0}
|
||||
/>
|
||||
<Button
|
||||
className='w-full'
|
||||
@ -145,7 +146,7 @@ export default function AccountList(props: Props) {
|
||||
</>
|
||||
) : (
|
||||
<div className='w-full p-4'>
|
||||
<AccountStats balance={positionBalance} risk={60} health={0.5} />
|
||||
<AccountStats balance={positionBalance} risk={60} health={50} />
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
|
@ -10,7 +10,7 @@ import FundAccount from 'components/Account/FundAccount'
|
||||
import { Button } from 'components/Button'
|
||||
import { CircularProgress } from 'components/CircularProgress'
|
||||
import { Account, Plus, PlusCircled } from 'components/Icons'
|
||||
import Overlay from 'components/Overlay/Overlay'
|
||||
import Overlay from 'components/Overlay'
|
||||
import Text from 'components/Text'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
@ -54,8 +54,6 @@ export default function AccountMenuContent(props: Props) {
|
||||
|
||||
if (!params.address) return null
|
||||
|
||||
useStore.setState({ accounts: props.accounts })
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
<Button
|
||||
|
@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
import DisplayCurrency from 'components/DisplayCurrency'
|
||||
import { Heart, Shield } from 'components/Icons'
|
||||
import Text from 'components/Text'
|
||||
import useStore from 'store'
|
||||
|
||||
import AccountHealth from './AccountHealth'
|
||||
|
||||
interface Props {
|
||||
balance: number
|
||||
risk: number
|
||||
@ -11,8 +11,6 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function AccountStats(props: Props) {
|
||||
const enableAnimations = useStore((s) => s.enableAnimations)
|
||||
const healthBarWidth = 53 * props.health
|
||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||
|
||||
return (
|
||||
@ -22,49 +20,7 @@ export default function AccountStats(props: Props) {
|
||||
className='w-full text-xl'
|
||||
/>
|
||||
<div className='mt-1 flex w-full items-center'>
|
||||
<Text size='xs' className='flex items-center'>
|
||||
<Shield className='mr-1.5 h-3' />
|
||||
<span className='text-white/70'>{`Risk score: ${props.risk}/100`}</span>
|
||||
</Text>
|
||||
<Text size='2xs' className='mx-2 -mt-1'>
|
||||
•
|
||||
</Text>
|
||||
<Text size='xs' className='flex items-center'>
|
||||
<Heart className='mr-1.5 h-3' />
|
||||
<span className='mr-2 text-white/70'>Health</span>
|
||||
<svg
|
||||
width='53'
|
||||
height='4'
|
||||
viewBox='0 0 53 4'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<rect width='53' height='4' rx='2' fill='white' fillOpacity='0.1' />
|
||||
<rect
|
||||
width={healthBarWidth}
|
||||
height='4'
|
||||
rx='2'
|
||||
fill='url(#bar)'
|
||||
style={{
|
||||
transition: enableAnimations ? 'width 1s ease' : 'none',
|
||||
}}
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id='bar'
|
||||
x1={healthBarWidth}
|
||||
y1='0'
|
||||
x2='0.208'
|
||||
y2='0'
|
||||
gradientUnits='userSpaceOnUse'
|
||||
>
|
||||
<stop stopColor='#FF645F' />
|
||||
<stop offset='0.489583' stopColor='#FFB1AE' />
|
||||
<stop offset='1' stopColor='#FFD5D3' />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</Text>
|
||||
<AccountHealth health={props.health} classNames='w-[140px]' hasLabel />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Accordion from 'components/Accordion'
|
||||
import AccountHealth from 'components/Account/AccountHealth'
|
||||
import Card from 'components/Card'
|
||||
import { ArrowChartLineUp, Shield } from 'components/Icons'
|
||||
import { ArrowChartLineUp } from 'components/Icons'
|
||||
import Text from 'components/Text'
|
||||
import useParams from 'utils/route'
|
||||
|
||||
@ -20,14 +21,7 @@ export default function AccountSummary() {
|
||||
<Text size='sm'>4.5x</Text>
|
||||
</Item>
|
||||
<Item>
|
||||
<span className='h-3 w-3'>
|
||||
<Shield />
|
||||
</span>
|
||||
</Item>
|
||||
<Item style={{ border: 'none' }}>
|
||||
<span className='h-3 w-3'>
|
||||
<Shield />
|
||||
</span>
|
||||
<AccountHealth health={80} />
|
||||
</Item>
|
||||
</Card>
|
||||
<Accordion
|
||||
|
@ -43,7 +43,11 @@ export const BorrowTable = (props: Props) => {
|
||||
return (
|
||||
<div className='flex flex-1 items-center gap-3'>
|
||||
<Image src={asset.logo} alt='token' width={32} height={32} />
|
||||
<TitleAndSubCell title={asset.symbol} sub={asset.name} className='min-w-15' />
|
||||
<TitleAndSubCell
|
||||
title={asset.symbol}
|
||||
sub={asset.name}
|
||||
className='min-w-15 text-left'
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
@ -58,7 +62,7 @@ export const BorrowTable = (props: Props) => {
|
||||
|
||||
return (
|
||||
<Text className='justify-end' size='sm'>
|
||||
{formatPercent(row.original.borrowRate)}
|
||||
{formatPercent(row.original.borrowRate, 2)}
|
||||
</Text>
|
||||
)
|
||||
},
|
||||
|
@ -9,6 +9,7 @@ interface Props {
|
||||
contentClassName?: string
|
||||
title?: string | ReactElement
|
||||
id?: string
|
||||
onClick?: (e: React.MouseEvent) => void
|
||||
}
|
||||
|
||||
export default function Card(props: Props) {
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Coin } from '@cosmjs/stargate'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
import { FormattedNumber } from 'components/FormattedNumber'
|
||||
import useStore from 'store'
|
||||
import { getMarketAssets } from 'utils/assets'
|
||||
import { BN } from 'utils/helpers'
|
||||
import { FormattedNumber } from 'components/FormattedNumber'
|
||||
|
||||
interface Props {
|
||||
coin: Coin
|
||||
@ -19,15 +18,14 @@ export default function DisplayCurrency(props: Props) {
|
||||
function convertToDisplayAmount(coin: Coin) {
|
||||
const price = prices.find((price) => price.denom === coin.denom)
|
||||
const asset = getMarketAssets().find((asset) => asset.denom === coin.denom)
|
||||
|
||||
const displayPrice = prices.find((price) => price.denom === displayCurrency.denom)
|
||||
|
||||
if (!price || !asset || !displayPrice) return '0'
|
||||
|
||||
return BN(coin.amount)
|
||||
.shiftedBy(-1 * asset.decimals)
|
||||
.times(price.amount)
|
||||
.div(displayPrice.amount)
|
||||
.integerValue(BigNumber.ROUND_HALF_DOWN)
|
||||
.toNumber()
|
||||
}
|
||||
|
||||
@ -39,7 +37,6 @@ export default function DisplayCurrency(props: Props) {
|
||||
minDecimals: 0,
|
||||
maxDecimals: 2,
|
||||
abbreviated: true,
|
||||
decimals: displayCurrency.decimals,
|
||||
prefix: `${props.isApproximation ? '~ ' : ''}${
|
||||
displayCurrency.prefix ? displayCurrency.prefix : ''
|
||||
}`,
|
||||
|
@ -3,7 +3,8 @@ import { Suspense } from 'react'
|
||||
import Card from 'components/Card'
|
||||
import { VaultTable } from 'components/Earn/vault/VaultTable'
|
||||
import Text from 'components/Text'
|
||||
import { VAULTS } from 'constants/vaults'
|
||||
import { IS_TESTNET } from 'constants/env'
|
||||
import { TESTNET_VAULTS, VAULTS } from 'constants/vaults'
|
||||
import { getVaults } from 'utils/api'
|
||||
|
||||
async function Content() {
|
||||
@ -27,9 +28,10 @@ export default function AvailableVaults() {
|
||||
|
||||
function Fallback() {
|
||||
// TODO: Replace with loading state of vaulttable
|
||||
const vaults = IS_TESTNET ? TESTNET_VAULTS : VAULTS
|
||||
return (
|
||||
<>
|
||||
{VAULTS.map((vault) => (
|
||||
{vaults.map((vault) => (
|
||||
<Text key={vault.address}>{vault.name}</Text>
|
||||
))}
|
||||
</>
|
||||
|
@ -4,6 +4,7 @@ import { Button } from 'components/Button'
|
||||
import VaultLogo from 'components/Earn/vault/VaultLogo'
|
||||
import Text from 'components/Text'
|
||||
import TitleAndSubCell from 'components/TitleAndSubCell'
|
||||
import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||
import useStore from 'store'
|
||||
import { getAssetByDenom } from 'utils/assets'
|
||||
import { formatPercent, formatValue } from 'utils/formatters'
|
||||
@ -17,6 +18,8 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function VaultCard(props: Props) {
|
||||
const currentAccount = useCurrentAccount()
|
||||
|
||||
function openVaultModal() {
|
||||
useStore.setState({ vaultModal: { vault: props.vault } })
|
||||
}
|
||||
@ -42,7 +45,7 @@ export default function VaultCard(props: Props) {
|
||||
<div className='mb-6 flex justify-between'>
|
||||
<TitleAndSubCell
|
||||
className='text-xs'
|
||||
title={props.vault.apy ? formatPercent(props.vault.apy) : '-'}
|
||||
title={props.vault.apy ? formatPercent(props.vault.apy, 2) : '-'}
|
||||
sub={'APY'}
|
||||
/>
|
||||
<TitleAndSubCell
|
||||
@ -67,8 +70,13 @@ export default function VaultCard(props: Props) {
|
||||
sub={'Depo. Cap'}
|
||||
/>
|
||||
</div>
|
||||
<Button color='secondary' onClick={openVaultModal} className='w-full'>
|
||||
Deposit
|
||||
<Button
|
||||
color='secondary'
|
||||
onClick={openVaultModal}
|
||||
className='w-full'
|
||||
disabled={!currentAccount}
|
||||
>
|
||||
{currentAccount ? 'Deposit' : 'Select Account'}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
|
@ -41,7 +41,9 @@ export const VaultTable = (props: Props) => {
|
||||
accessorKey: 'apy',
|
||||
header: 'APY',
|
||||
cell: ({ row }) => {
|
||||
return <Text size='xs'>{row.original.apy ? formatPercent(row.original.apy) : '-'}</Text>
|
||||
return (
|
||||
<Text size='xs'>{row.original.apy ? formatPercent(row.original.apy, 2) : '-'}</Text>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -77,7 +79,7 @@ export const VaultTable = (props: Props) => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'cap',
|
||||
accessorKey: 'details',
|
||||
enableSorting: false,
|
||||
header: 'Details',
|
||||
cell: ({ row }) => (
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import classNames from 'classnames'
|
||||
import { ReactNode } from 'react'
|
||||
import { ReactNode, useEffect, useRef } from 'react'
|
||||
|
||||
import { Button } from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
@ -13,43 +15,62 @@ interface Props {
|
||||
className?: string
|
||||
contentClassName?: string
|
||||
open: boolean
|
||||
setOpen?: (open: boolean) => void
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export const Modal = (props: Props) => {
|
||||
const onClickAway = () => {
|
||||
if (props.setOpen) props.setOpen(false)
|
||||
export default function Modal(props: Props) {
|
||||
const ref: any = useRef(null)
|
||||
|
||||
function onClose() {
|
||||
ref.current?.close()
|
||||
props.onClose()
|
||||
}
|
||||
|
||||
return props.open ? (
|
||||
<div className='fixed inset-0 z-40 h-screen w-screen'>
|
||||
<div className='relative flex h-full w-full items-center justify-center'>
|
||||
<Card
|
||||
className={classNames(
|
||||
'relative z-40 w-[895px] max-w-full bg-white/5 backdrop-blur-3xl',
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<div className={classNames('flex justify-between', props.headerClassName)}>
|
||||
{props.header}
|
||||
<Button
|
||||
onClick={onClickAway}
|
||||
leftIcon={<Cross />}
|
||||
className='h-8 w-8'
|
||||
iconClassName='h-2 w-2'
|
||||
color='tertiary'
|
||||
/>
|
||||
</div>
|
||||
<div className={classNames(props.contentClassName, 'flex-grow')}>
|
||||
{props.children ? props.children : props.content}
|
||||
</div>
|
||||
</Card>
|
||||
<div
|
||||
className='fixed inset-0 z-30 block h-full w-full bg-black/50 backdrop-blur-sm hover:cursor-pointer'
|
||||
onClick={onClickAway}
|
||||
role='button'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
useEffect(() => {
|
||||
if (props.open) {
|
||||
ref.current?.showModal()
|
||||
} else {
|
||||
ref.current?.close()
|
||||
}
|
||||
}, [props.open])
|
||||
|
||||
// close dialog on unmount
|
||||
useEffect(() => {
|
||||
const dialog = ref.current
|
||||
dialog?.removeAttribute('open')
|
||||
return () => dialog.close()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<dialog
|
||||
ref={ref}
|
||||
onCancel={onClose}
|
||||
className={classNames(
|
||||
'w-[895px] border-none bg-transparent text-white',
|
||||
'focus-visible:outline-none',
|
||||
'backdrop:bg-black/50 backdrop:backdrop-blur-sm',
|
||||
)}
|
||||
>
|
||||
<Card
|
||||
className={classNames(
|
||||
'relative w-full max-w-full bg-white/5 backdrop-blur-3xl',
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<div className={classNames('flex justify-between', props.headerClassName)}>
|
||||
{props.header}
|
||||
<Button
|
||||
onClick={onClose}
|
||||
leftIcon={<Cross />}
|
||||
className='h-8 w-8'
|
||||
iconClassName='h-2 w-2'
|
||||
color='tertiary'
|
||||
/>
|
||||
</div>
|
||||
<div className={classNames(props.contentClassName, 'flex-grow')}>
|
||||
{props.children ? props.children : props.content}
|
||||
</div>
|
||||
</Card>
|
||||
</dialog>
|
||||
)
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import BorrowModal from 'components/BorrowModal'
|
||||
import VaultModal from 'components/Earn/vault/VaultModal'
|
||||
|
||||
export const Modals = () => (
|
||||
<>
|
||||
<BorrowModal />
|
||||
<VaultModal />
|
||||
</>
|
||||
)
|
@ -1,21 +1,31 @@
|
||||
import Image from 'next/image'
|
||||
import { useState } from 'react'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
import AccountSummary from 'components/Account/AccountSummary'
|
||||
import { Button } from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
import Divider from 'components/Divider'
|
||||
import { ArrowRight } from 'components/Icons'
|
||||
import { Modal } from 'components/Modal'
|
||||
import Modal from 'components/Modal'
|
||||
import Text from 'components/Text'
|
||||
import TitleAndSubCell from 'components/TitleAndSubCell'
|
||||
import TokenInputWithSlider from 'components/TokenInputWithSlider'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import useStore from 'store'
|
||||
import { hardcodedFee } from 'utils/contants'
|
||||
import { formatPercent, formatValue } from 'utils/formatters'
|
||||
import useParams from 'utils/route'
|
||||
import { BN } from 'utils/helpers'
|
||||
import useParams from 'utils/route'
|
||||
|
||||
function getDebtAmount(modal: BorrowModal | null) {
|
||||
if (!(modal?.marketData as BorrowAssetActive)?.debt) return '0'
|
||||
return BN((modal?.marketData as BorrowAssetActive).debt).toString()
|
||||
}
|
||||
|
||||
function getAssetLogo(modal: BorrowModal | null) {
|
||||
if (!modal?.asset) return null
|
||||
return <Image src={modal.asset.logo} alt={modal.asset.symbol} width={24} height={24} />
|
||||
}
|
||||
|
||||
export default function BorrowModal() {
|
||||
const params = useParams()
|
||||
@ -25,6 +35,7 @@ export default function BorrowModal() {
|
||||
const modal = useStore((s) => s.borrowModal)
|
||||
const borrow = useStore((s) => s.borrow)
|
||||
const repay = useStore((s) => s.repay)
|
||||
const asset = modal?.asset ?? ASSETS[0]
|
||||
const accounts = useStore((s) => s.accounts)?.map((account) => {
|
||||
return account.id
|
||||
})
|
||||
@ -33,12 +44,6 @@ export default function BorrowModal() {
|
||||
setSelectedAccount(accountId)
|
||||
}
|
||||
|
||||
function setOpen(isOpen: boolean) {
|
||||
useStore.setState({ borrowModal: null })
|
||||
setAmount(BN(0))
|
||||
setPercentage(0)
|
||||
}
|
||||
|
||||
function onConfirmClick() {
|
||||
if (!modal?.asset) return
|
||||
if (modal.isRepay) {
|
||||
@ -58,36 +63,33 @@ export default function BorrowModal() {
|
||||
})
|
||||
}
|
||||
|
||||
if (!modal) return null
|
||||
function onClose() {
|
||||
useStore.setState({ borrowModal: null })
|
||||
setAmount(BN(0))
|
||||
setPercentage(0)
|
||||
}
|
||||
|
||||
const liquidityAmount = Number(modal.marketData.liquidity?.amount || 0)
|
||||
const liquidityAmountString: string = formatValue(liquidityAmount, {
|
||||
const liquidityAmountString = formatValue(modal?.marketData?.liquidity?.amount || 0, {
|
||||
abbreviated: true,
|
||||
decimals: 6,
|
||||
})
|
||||
|
||||
const liquidityValue = Number(modal.marketData.liquidity?.value || 0)
|
||||
const liquidityValueString: string = formatValue(liquidityValue, {
|
||||
const liquidityValueString = formatValue(modal?.marketData?.liquidity?.value || 0, {
|
||||
abbreviated: true,
|
||||
decimals: 6,
|
||||
})
|
||||
|
||||
let debtAmount = 0
|
||||
|
||||
if ((modal.marketData as BorrowAssetActive)?.debt)
|
||||
debtAmount = Number((modal.marketData as BorrowAssetActive).debt)
|
||||
|
||||
const max = BN(modal.isRepay ? debtAmount : liquidityAmount)
|
||||
const max = BN(modal?.isRepay ? getDebtAmount(modal) : liquidityAmountString)
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={true}
|
||||
setOpen={setOpen}
|
||||
open={!!modal}
|
||||
onClose={onClose}
|
||||
header={
|
||||
<span className='flex items-center gap-4 px-4'>
|
||||
<Image src={modal?.asset.logo} alt='token' width={24} height={24} />
|
||||
{getAssetLogo(modal)}
|
||||
<Text>
|
||||
{modal.isRepay ? 'Repay' : 'Borrow'} {modal.asset.symbol}
|
||||
{modal?.isRepay ? 'Repay' : 'Borrow'} {asset.symbol}
|
||||
</Text>
|
||||
</span>
|
||||
}
|
||||
@ -96,12 +98,15 @@ export default function BorrowModal() {
|
||||
>
|
||||
<div className='flex gap-3 border-b border-b-white/5 px-6 py-4 gradient-header'>
|
||||
<TitleAndSubCell
|
||||
title={formatPercent(modal.marketData.borrowRate || '0')}
|
||||
title={formatPercent(modal?.marketData.borrowRate || '0')}
|
||||
sub={'Borrow rate'}
|
||||
/>
|
||||
<div className='h-100 w-[1px] bg-white/10'></div>
|
||||
<TitleAndSubCell
|
||||
title={formatValue(debtAmount, { abbreviated: true, decimals: modal.asset.decimals })}
|
||||
title={formatValue(getDebtAmount(modal), {
|
||||
abbreviated: true,
|
||||
decimals: asset.decimals,
|
||||
})}
|
||||
sub={'Borrowed'}
|
||||
/>
|
||||
<div className='h-100 w-[1px] bg-white/10'></div>
|
||||
@ -116,16 +121,15 @@ export default function BorrowModal() {
|
||||
contentClassName='gap-6 flex flex-col justify-between h-full'
|
||||
>
|
||||
<TokenInputWithSlider
|
||||
asset={modal.asset}
|
||||
asset={asset}
|
||||
onChange={(val) => {
|
||||
console.log('new value received', val)
|
||||
setAmount(val)
|
||||
}}
|
||||
amount={amount}
|
||||
max={max}
|
||||
/>
|
||||
<Divider />
|
||||
<Text size='lg'>{modal.isRepay ? 'Repay for' : 'Borrow to'}</Text>
|
||||
<Text size='lg'>{modal?.isRepay ? 'Repay for' : 'Borrow to'}</Text>
|
||||
<select
|
||||
name='account'
|
||||
value={selectedAccount}
|
||||
@ -141,7 +145,7 @@ export default function BorrowModal() {
|
||||
<Button
|
||||
onClick={onConfirmClick}
|
||||
className='w-full'
|
||||
text={modal.isRepay ? 'Repay' : 'Borrow'}
|
||||
text={modal?.isRepay ? 'Repay' : 'Borrow'}
|
||||
rightIcon={<ArrowRight />}
|
||||
/>
|
||||
</Card>
|
15
src/components/Modals/ModalsContainer.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import WithdrawModal from 'components/Modals//WithdrawModal'
|
||||
import BorrowModal from 'components/Modals/BorrowModal'
|
||||
import VaultModal from 'components/Modals/VaultModal'
|
||||
|
||||
export default function ModalsContainer() {
|
||||
return (
|
||||
<>
|
||||
<BorrowModal />
|
||||
<WithdrawModal />
|
||||
<VaultModal />
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { useState } from 'react'
|
||||
|
||||
import AccountSummary from 'components/Account/AccountSummary'
|
||||
@ -8,59 +8,64 @@ import Divider from 'components/Divider'
|
||||
import VaultLogo from 'components/Earn/vault/VaultLogo'
|
||||
import { FormattedNumber } from 'components/FormattedNumber'
|
||||
import { ArrowRight } from 'components/Icons'
|
||||
import { Modal } from 'components/Modal'
|
||||
import Modal from 'components/Modal'
|
||||
import Slider from 'components/Slider'
|
||||
import Switch from 'components/Switch'
|
||||
import Text from 'components/Text'
|
||||
import TitleAndSubCell from 'components/TitleAndSubCell'
|
||||
import TokenInput from 'components/TokenInput'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||
import useStore from 'store'
|
||||
import { getAmount } from 'utils/accounts'
|
||||
import { formatValue } from 'utils/formatters'
|
||||
import { BN } from 'utils/helpers'
|
||||
import useParams from 'utils/route'
|
||||
|
||||
export default function VaultModal() {
|
||||
const modal = useStore((s) => s.vaultModal)
|
||||
const accounts = useStore((s) => s.accounts)
|
||||
const params = useParams()
|
||||
const [amount, setAmount] = useState(BN(0))
|
||||
const [percentage, setPercentage] = useState(0)
|
||||
const [isCustomAmount, setIsCustomAmount] = useState(false)
|
||||
const currentAccount = accounts?.find((account) => account.id === params.accountId)
|
||||
const currentAccount = useCurrentAccount()
|
||||
|
||||
function handleSwitch() {
|
||||
setIsCustomAmount(() => !isCustomAmount)
|
||||
}
|
||||
|
||||
function setOpen(isOpen: boolean) {
|
||||
function onClose() {
|
||||
useStore.setState({ vaultModal: null })
|
||||
setAmount(BN(0))
|
||||
setPercentage(0)
|
||||
}
|
||||
|
||||
function onChangeSlider(value: number) {}
|
||||
function onChangePrimary(value: BigNumber) {}
|
||||
function onChangeSecondary(value: BigNumber) {}
|
||||
|
||||
if (!modal || !currentAccount) return null
|
||||
const primaryAsset =
|
||||
ASSETS.find((asset) => asset.denom === modal?.vault.denoms.primary) ?? ASSETS[0]
|
||||
const secondaryAsset =
|
||||
ASSETS.find((asset) => asset.denom === modal?.vault.denoms.secondary) ?? ASSETS[0]
|
||||
|
||||
const primaryAsset = ASSETS.find((asset) => asset.denom === modal.vault.denoms.primary)
|
||||
const secondaryAsset = ASSETS.find((asset) => asset.denom === modal.vault.denoms.secondary)
|
||||
|
||||
if (!primaryAsset || !secondaryAsset) return null
|
||||
|
||||
const primaryMaxAmount = getAmount(primaryAsset.denom, currentAccount.deposits)
|
||||
const secondaryMaxAmount = getAmount(secondaryAsset.denom, currentAccount.deposits)
|
||||
const hasValidData = primaryAsset && currentAccount && secondaryAsset
|
||||
const maxPrimaryAmount = hasValidData
|
||||
? getAmount(primaryAsset.denom, currentAccount.deposits)
|
||||
: BN(0)
|
||||
const maxSecondaryAmount = hasValidData
|
||||
? getAmount(secondaryAsset.denom, currentAccount.deposits)
|
||||
: BN(0)
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={true}
|
||||
setOpen={setOpen}
|
||||
open={!!(modal && hasValidData)}
|
||||
onClose={onClose}
|
||||
header={
|
||||
<span className='flex items-center gap-4 px-4'>
|
||||
<VaultLogo vault={modal.vault} />
|
||||
<Text>{`${modal.vault.symbols.primary} - ${modal.vault.symbols.secondary}`}</Text>
|
||||
</span>
|
||||
modal && (
|
||||
<span className='flex items-center gap-4 px-4'>
|
||||
<VaultLogo vault={modal.vault} />
|
||||
<Text>{`${modal.vault.symbols.primary} - ${modal.vault.symbols.secondary}`}</Text>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
|
||||
contentClassName='flex flex-col'
|
||||
@ -81,14 +86,14 @@ export default function VaultModal() {
|
||||
<TokenInput
|
||||
onChange={onChangePrimary}
|
||||
amount={amount}
|
||||
max={primaryMaxAmount}
|
||||
max={maxPrimaryAmount}
|
||||
asset={primaryAsset}
|
||||
/>
|
||||
<Slider value={percentage} onChange={onChangeSlider} />
|
||||
<TokenInput
|
||||
onChange={onChangeSecondary}
|
||||
amount={amount}
|
||||
max={secondaryMaxAmount}
|
||||
max={maxSecondaryAmount}
|
||||
asset={secondaryAsset}
|
||||
/>
|
||||
<Divider />
|
||||
@ -97,7 +102,7 @@ export default function VaultModal() {
|
||||
<Switch checked={isCustomAmount} onChange={handleSwitch} name='customAmount' />
|
||||
</div>
|
||||
<div className='flex justify-between'>
|
||||
<Text className='text-white/50'>{`${modal.vault.symbols.primary}-${modal.vault.symbols.secondary} Position Value`}</Text>
|
||||
<Text className='text-white/50'>{`${primaryAsset.symbol}-${secondaryAsset.symbol} Position Value`}</Text>
|
||||
<FormattedNumber amount={0} options={{ prefix: '$' }} />
|
||||
</div>
|
||||
<Button
|
96
src/components/Modals/WithdrawModal.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
import AccountSummary from 'components/Account/AccountSummary'
|
||||
import { Button } from 'components/Button'
|
||||
import Card from 'components/Card'
|
||||
import Divider from 'components/Divider'
|
||||
import { ArrowRight } from 'components/Icons'
|
||||
import Modal from 'components/Modal'
|
||||
import Text from 'components/Text'
|
||||
import TokenInputWithSlider from 'components/TokenInputWithSlider'
|
||||
import useCurrentAccount from 'hooks/useCurrentAccount'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
import { getAmount } from 'utils/accounts'
|
||||
import { hardcodedFee } from 'utils/contants'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export default function WithdrawModal() {
|
||||
const currentAccount = useCurrentAccount()
|
||||
const modal = useStore((s) => s.withdrawModal)
|
||||
const baseCurrency = useStore((s) => s.baseCurrency)
|
||||
const withdraw = useStore((s) => s.withdraw)
|
||||
const [amount, setAmount] = useState(BN(0))
|
||||
const [currentAsset, setCurrentAsset] = useState(baseCurrency)
|
||||
const [isWithdrawing, setIsWithdrawing] = useToggle()
|
||||
|
||||
function onClose() {
|
||||
useStore.setState({ withdrawModal: false })
|
||||
setAmount(BN(0))
|
||||
}
|
||||
|
||||
async function onWithdraw() {
|
||||
if (!currentAccount) return
|
||||
setIsWithdrawing(true)
|
||||
const result = await withdraw({
|
||||
fee: hardcodedFee,
|
||||
accountId: currentAccount.id,
|
||||
coin: {
|
||||
denom: currentAsset.denom,
|
||||
amount: amount.toString(),
|
||||
},
|
||||
})
|
||||
setIsWithdrawing(false)
|
||||
if (result) {
|
||||
useStore.setState({ withdrawModal: false })
|
||||
}
|
||||
}
|
||||
|
||||
const maxWithdraw = currentAccount
|
||||
? getAmount(currentAsset.denom, currentAccount.deposits)
|
||||
: BN(0)
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={modal}
|
||||
onClose={onClose}
|
||||
header={
|
||||
<span className='flex items-center gap-4 px-4'>
|
||||
<Text>{`Withdraw from Account ${currentAccount?.id ?? '0'}`}</Text>
|
||||
</span>
|
||||
}
|
||||
headerClassName='gradient-header pl-2 pr-2.5 py-2.5 border-b-white/5 border-b'
|
||||
contentClassName='flex flex-col min-h-[400px]'
|
||||
>
|
||||
<div className='flex flex-grow items-start gap-6 p-6'>
|
||||
<Card
|
||||
className='w-full bg-white/5 p-4'
|
||||
contentClassName='gap-6 flex flex-col justify-between h-full'
|
||||
>
|
||||
<TokenInputWithSlider
|
||||
asset={currentAsset}
|
||||
onChange={(val) => {
|
||||
setAmount(val)
|
||||
}}
|
||||
onChangeAsset={(asset) => {
|
||||
setCurrentAsset(asset)
|
||||
}}
|
||||
amount={amount}
|
||||
max={maxWithdraw}
|
||||
hasSelect
|
||||
currentAccount={currentAccount}
|
||||
/>
|
||||
<Divider />
|
||||
<Button
|
||||
onClick={onWithdraw}
|
||||
showProgressIndicator={isWithdrawing}
|
||||
className='w-full'
|
||||
text='Withdraw'
|
||||
rightIcon={<ArrowRight />}
|
||||
/>
|
||||
</Card>
|
||||
<AccountSummary />
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
@ -4,7 +4,7 @@ import BigNumber from 'bignumber.js'
|
||||
import classNames from 'classnames'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import { formatValue } from 'utils/formatters'
|
||||
import { demagnify, formatValue, magnify } from 'utils/formatters'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
interface Props {
|
||||
@ -62,8 +62,8 @@ export default function NumberInput(props: Props) {
|
||||
cursorRef.current = inputRef.current?.selectionEnd || 0
|
||||
}
|
||||
setFormattedAmount(formatted)
|
||||
console.log(props.amount.toNumber(), amount.toNumber())
|
||||
if (props.amount.isEqualTo(amount)) {
|
||||
|
||||
if (!props.amount.isEqualTo(amount)) {
|
||||
props.onChange(amount)
|
||||
}
|
||||
}
|
||||
@ -90,8 +90,10 @@ export default function NumberInput(props: Props) {
|
||||
const hasMultipleDots = (formattedAmount.match(/[.,]/g)?.length || 0) > 1
|
||||
const isSeparator = lastChar === '.' || lastChar === ','
|
||||
const isNegative = formattedAmount.indexOf('-') > -1
|
||||
const isLowerThanMinimum = props.min !== undefined && props.min.isGreaterThan(formattedAmount)
|
||||
const isHigherThanMaximum = props.max !== undefined && props.max.isLessThan(formattedAmount)
|
||||
const isLowerThanMinimum =
|
||||
props.min !== undefined && props.min.isGreaterThan(magnify(formattedAmount, props.asset))
|
||||
const isHigherThanMaximum =
|
||||
props.max !== undefined && props.max.isLessThan(magnify(formattedAmount, props.asset))
|
||||
const isTooLong = props.maxLength !== undefined && numberCount > props.maxLength
|
||||
const exceedsMaxDecimals = props.maxDecimals !== undefined && decimals > props.maxDecimals
|
||||
|
||||
@ -116,12 +118,12 @@ export default function NumberInput(props: Props) {
|
||||
if (isTooLong) return
|
||||
|
||||
if (isLowerThanMinimum && props.min) {
|
||||
updateValues(String(props.min), props.min)
|
||||
updateValues(String(demagnify(props.min, props.asset)), props.min)
|
||||
return
|
||||
}
|
||||
|
||||
if (isHigherThanMaximum && props.max) {
|
||||
updateValues(String(props.max), props.max)
|
||||
updateValues(String(demagnify(props.max, props.asset)), props.max)
|
||||
return
|
||||
}
|
||||
|
||||
@ -133,12 +135,7 @@ export default function NumberInput(props: Props) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!formattedAmount) {
|
||||
updateValues(formattedAmount, BN(0))
|
||||
return
|
||||
}
|
||||
|
||||
updateValues(formattedAmount, amount)
|
||||
updateValues(amount.shiftedBy(-1 * props.asset.decimals).toString(), amount)
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -2,6 +2,7 @@ import classNames from 'classnames'
|
||||
import Image from 'next/image'
|
||||
|
||||
import DisplayCurrency from 'components/DisplayCurrency'
|
||||
import { ChevronDown } from 'components/Icons'
|
||||
import Text from 'components/Text'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import { formatValue } from 'utils/formatters'
|
||||
@ -9,6 +10,7 @@ import { formatValue } from 'utils/formatters'
|
||||
interface Props extends Option {
|
||||
isSelected?: boolean
|
||||
isDisplay?: boolean
|
||||
isClicked?: boolean
|
||||
onClick?: (value: string) => void
|
||||
}
|
||||
|
||||
@ -25,7 +27,20 @@ export default function Option(props: Props) {
|
||||
|
||||
if (props.isDisplay) {
|
||||
return (
|
||||
<div className={classNames('block bg-white/10 p-3 hover:cursor-pointer')}>{symbol}</div>
|
||||
<div
|
||||
className={classNames('flex items-center gap-2 bg-white/10 p-3', 'hover:cursor-pointer')}
|
||||
>
|
||||
<Image src={logo} alt={`${symbol} token logo`} width={20} height={20} />
|
||||
<span>{symbol}</span>
|
||||
<span
|
||||
className={classNames(
|
||||
'inline-block w-2.5 transition-transform',
|
||||
props.isClicked ? 'rotate-0' : '-rotate-90',
|
||||
)}
|
||||
>
|
||||
<ChevronDown />
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -35,7 +50,7 @@ export default function Option(props: Props) {
|
||||
'grid grid-flow-row grid-cols-5 grid-rows-2 py-3.5 pr-4',
|
||||
'border-b border-b-white/20 last:border-none',
|
||||
'hover:cursor-pointer hover:bg-white/20',
|
||||
props.isSelected && 'bg-white/10',
|
||||
!props.isSelected ? 'bg-white/10' : 'pointer-events-none',
|
||||
)}
|
||||
onClick={() => props?.onClick && props.onClick(denom)}
|
||||
>
|
||||
|
@ -3,7 +3,8 @@
|
||||
import classNames from 'classnames'
|
||||
import { useState } from 'react'
|
||||
|
||||
import Overlay from 'components/Overlay/Overlay'
|
||||
import { ChevronDown } from 'components/Icons'
|
||||
import Overlay from 'components/Overlay'
|
||||
import Option from 'components/Select/Option'
|
||||
import Text from 'components/Text'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
@ -34,8 +35,6 @@ export default function Select(props: Props) {
|
||||
props.onChange(optionValue)
|
||||
}
|
||||
|
||||
console.log(selected)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
@ -47,9 +46,21 @@ export default function Select(props: Props) {
|
||||
onClick={() => setShowDropdown(!showDropdown)}
|
||||
>
|
||||
{selectedOption ? (
|
||||
<Option {...selectedOption} isDisplay />
|
||||
<Option {...selectedOption} isClicked={showDropdown} isDisplay />
|
||||
) : (
|
||||
<Text className='w-full opacity-50 hover:cursor-pointer'>Select</Text>
|
||||
<div
|
||||
className={classNames('flex items-center gap-2 bg-white/10 p-3', 'hover:cursor-pointer')}
|
||||
>
|
||||
<Text className='w-full opacity-50 hover:cursor-pointer'>Select</Text>
|
||||
<span
|
||||
className={classNames(
|
||||
'inline-block w-2.5 transition-transform',
|
||||
showDropdown ? 'rotate-0' : '-rotate-90',
|
||||
)}
|
||||
>
|
||||
<ChevronDown />
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<Overlay
|
||||
show={showDropdown}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import { Button } from 'components/Button'
|
||||
import { Gear } from 'components/Icons'
|
||||
import Overlay from 'components/Overlay/Overlay'
|
||||
import Overlay from 'components/Overlay'
|
||||
import Switch from 'components/Switch'
|
||||
import Text from 'components/Text'
|
||||
import { Tooltip } from 'components/Tooltip'
|
||||
|
@ -73,6 +73,10 @@ export default function Slider(props: Props) {
|
||||
setShowTooltip(false)
|
||||
}
|
||||
|
||||
// draggable workaround - to solve node compatibility issues
|
||||
// TODO: find a replacement for react-draggable
|
||||
const DraggableElement: any = Draggable
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
@ -90,7 +94,7 @@ export default function Slider(props: Props) {
|
||||
onMouseDown={handleShowTooltip}
|
||||
className='absolute z-2 w-full cursor-pointer appearance-none bg-transparent [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:appearance-none'
|
||||
/>
|
||||
<div className='absolute flex w-full items-center gap-1'>
|
||||
<div className='absolute flex w-full items-center gap-1'>
|
||||
<Mark onClick={props.onChange} value={0} sliderValue={props.value} />
|
||||
<Track maxValue={23} sliderValue={props.value} />
|
||||
<Mark onClick={props.onChange} value={25} sliderValue={props.value} />
|
||||
@ -102,7 +106,7 @@ export default function Slider(props: Props) {
|
||||
<Mark onClick={props.onChange} value={100} sliderValue={props.value} />
|
||||
</div>
|
||||
<div onMouseEnter={handleShowTooltip} onMouseLeave={handleHideTooltip}>
|
||||
<Draggable
|
||||
<DraggableElement
|
||||
nodeRef={nodeRef}
|
||||
axis='x'
|
||||
grid={[sliderRect.width / 100, 0]}
|
||||
@ -125,7 +129,7 @@ export default function Slider(props: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Draggable>
|
||||
</DraggableElement>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,3 +1,5 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import Text from 'components/Text'
|
||||
|
||||
interface Props {
|
||||
@ -9,10 +11,10 @@ interface Props {
|
||||
export default function TitleAndSubCell(props: Props) {
|
||||
return (
|
||||
<div className='flex flex-col gap-[0.5]'>
|
||||
<Text className={props.className} size='sm'>
|
||||
<Text size='sm' className={props.className}>
|
||||
{props.title}
|
||||
</Text>
|
||||
<Text size='sm' className={'text-white/50 ' + props.className}>
|
||||
<Text size='sm' className={classNames('text-white/50', props.className)}>
|
||||
{props.sub}
|
||||
</Text>
|
||||
</div>
|
||||
|
@ -19,6 +19,7 @@ interface Props {
|
||||
onChange: (amount: BigNumber) => void
|
||||
className?: string
|
||||
disabled?: boolean
|
||||
currentAccount?: Account
|
||||
}
|
||||
|
||||
interface SingleProps extends Props {
|
||||
@ -44,22 +45,26 @@ export default function TokenInput(props: SingleProps | SelectProps) {
|
||||
amount: '0',
|
||||
})
|
||||
|
||||
const selectableBalances = props.currentAccount?.deposits ?? balances
|
||||
|
||||
const selectedAssetDenom = props.asset ? props.asset.denom : baseCurrency.denom
|
||||
|
||||
const updateAsset = useCallback(
|
||||
(coinDenom: string) => {
|
||||
const newAsset = ASSETS.find((asset) => asset.denom === coinDenom) ?? baseCurrency
|
||||
const newCoin = balances?.find((coin) => coin.denom === coinDenom)
|
||||
const newCoin = selectableBalances?.find((coin) => coin.denom === coinDenom)
|
||||
setAsset(newAsset)
|
||||
setCoin(newCoin ?? { denom: coinDenom, amount: '0' })
|
||||
},
|
||||
[balances, baseCurrency],
|
||||
[selectableBalances, baseCurrency],
|
||||
)
|
||||
|
||||
function setDefaultAsset() {
|
||||
if (!balances || balances?.length === 0) return setAsset(baseCurrency)
|
||||
if (balances.length === 1)
|
||||
return setAsset(ASSETS.find((asset) => asset.denom === balances[0].denom) ?? baseCurrency)
|
||||
if (!selectableBalances || selectableBalances?.length === 0) return setAsset(baseCurrency)
|
||||
if (selectableBalances.length === 1)
|
||||
return setAsset(
|
||||
ASSETS.find((asset) => asset.denom === selectableBalances[0].denom) ?? baseCurrency,
|
||||
)
|
||||
return setAsset(ASSETS.find((asset) => asset.denom === selectedAssetDenom) ?? baseCurrency)
|
||||
}
|
||||
|
||||
@ -85,14 +90,14 @@ export default function TokenInput(props: SingleProps | SelectProps) {
|
||||
props.disabled && 'pointer-events-none opacity-50',
|
||||
)}
|
||||
>
|
||||
<div className='relative isolate z-40 box-content flex h-11 w-full rounded-sm border border-white/20 bg-white/5'>
|
||||
{props.hasSelect && balances ? (
|
||||
<div className='relative isolate z-40 box-content flex h-11 w-full rounded-sm border border-white/20 bg-white/5'>
|
||||
{props.hasSelect && selectableBalances ? (
|
||||
<Select
|
||||
options={balances}
|
||||
options={selectableBalances}
|
||||
defaultValue={coin.denom}
|
||||
onChange={(value) => updateAsset(value)}
|
||||
title='Your Wallet'
|
||||
className=' border-r border-white/20 bg-white/5'
|
||||
title={props.currentAccount ? `Account ${props.currentAccount.id}` : 'Your Wallet'}
|
||||
className='border-r border-white/20 bg-white/5'
|
||||
/>
|
||||
) : (
|
||||
<div className='flex min-w-fit items-center gap-2 border-r border-white/20 bg-white/5 p-3'>
|
||||
@ -118,7 +123,7 @@ export default function TokenInput(props: SingleProps | SelectProps) {
|
||||
</Text>
|
||||
<DisplayCurrency
|
||||
className='inline pl-0.5 text-xs text-white/50'
|
||||
coin={{ denom: asset.denom, amount: String(magnify(1, asset)) }}
|
||||
coin={{ denom: asset.denom, amount: magnify(1, asset).toString() }}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex'>
|
||||
|
@ -1,16 +1,17 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
import { BN } from 'utils/helpers'
|
||||
import Slider from 'components/Slider'
|
||||
import TokenInput from 'components/TokenInput'
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
interface Props {
|
||||
amount: BigNumber
|
||||
onChange: (amount: BigNumber) => void
|
||||
className?: string
|
||||
disabled?: boolean
|
||||
currentAccount?: Account
|
||||
}
|
||||
|
||||
interface SingleProps extends Props {
|
||||
@ -34,22 +35,22 @@ export default function TokenInputWithSlider(props: SingleProps | SelectProps) {
|
||||
const [max, setMax] = useState<BigNumber>(props.max ? props.max : BN(0))
|
||||
|
||||
const onSliderChange = useCallback(
|
||||
(percentage: number, liquidityAmount: BigNumber) => {
|
||||
const newAmount = BN(percentage).div(100).times(liquidityAmount)
|
||||
(percentage: number) => {
|
||||
const newAmount = BN(percentage).div(100).times(max)
|
||||
setPercentage(percentage)
|
||||
setAmount(newAmount)
|
||||
props.onChange(newAmount)
|
||||
},
|
||||
[props],
|
||||
[props, max],
|
||||
)
|
||||
|
||||
const onInputChange = useCallback(
|
||||
(newAmount: BigNumber, liquidityAmount: BigNumber) => {
|
||||
(newAmount: BigNumber) => {
|
||||
setAmount(newAmount)
|
||||
setPercentage(BN(newAmount).div(liquidityAmount).times(100).toNumber())
|
||||
setPercentage(BN(newAmount).div(max).times(100).toNumber())
|
||||
props.onChange(newAmount)
|
||||
},
|
||||
[props],
|
||||
[props, max],
|
||||
)
|
||||
|
||||
const onAssetChange = useCallback(
|
||||
@ -67,17 +68,18 @@ export default function TokenInputWithSlider(props: SingleProps | SelectProps) {
|
||||
<div className={props.className}>
|
||||
<TokenInput
|
||||
asset={asset}
|
||||
onChange={(amount) => onInputChange(amount, max)}
|
||||
onChange={(amount) => onInputChange(amount)}
|
||||
onChangeAsset={(asset: Asset, max: BigNumber) => onAssetChange(asset, max)}
|
||||
amount={amount}
|
||||
max={max}
|
||||
className='mb-4'
|
||||
disabled={props.disabled}
|
||||
hasSelect
|
||||
hasSelect={props.hasSelect}
|
||||
currentAccount={props.currentAccount}
|
||||
/>
|
||||
<Slider
|
||||
value={percentage}
|
||||
onChange={(value) => onSliderChange(value, max)}
|
||||
onChange={(value) => onSliderChange(value)}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
</div>
|
||||
|
@ -16,8 +16,9 @@ import { Button } from 'components/Button'
|
||||
import { CircularProgress } from 'components/CircularProgress'
|
||||
import { FormattedNumber } from 'components/FormattedNumber'
|
||||
import { Check, Copy, ExternalLink, Osmo } from 'components/Icons'
|
||||
import Overlay from 'components/Overlay/Overlay'
|
||||
import Overlay from 'components/Overlay'
|
||||
import Text from 'components/Text'
|
||||
import { IS_TESTNET } from 'constants/env'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
import { Endpoints, getEndpoint, getWalletBalancesSWR } from 'utils/api'
|
||||
@ -79,7 +80,7 @@ export default function ConnectedButton() {
|
||||
|
||||
return (
|
||||
<div className={'relative'}>
|
||||
{network?.chainId !== ChainInfoID.Osmosis1 && (
|
||||
{IS_TESTNET && (
|
||||
<Text
|
||||
className='absolute -right-2 -top-2.5 z-10 rounded-sm p-0.5 px-2 gradient-primary-to-secondary'
|
||||
size='3xs'
|
||||
@ -136,10 +137,10 @@ export default function ConnectedButton() {
|
||||
{'Your Address'}
|
||||
</Text>
|
||||
|
||||
<Text size='sm' className='mb-1 hidden break-all font-bold md:block'>
|
||||
<Text size='sm' className={classNames('mb-1 hidden break-all font-bold', 'md:block')}>
|
||||
{address}
|
||||
</Text>
|
||||
<Text size='sm' className='mb-1 break-all font-bold md:hidden'>
|
||||
<Text size='sm' className={classNames('mb-1 break-all font-bold', 'md:hidden')}>
|
||||
{truncate(address, [14, 14])}
|
||||
</Text>
|
||||
<div className='flex w-full pt-1'>
|
||||
|
@ -34,7 +34,7 @@ export const WalletConnectProvider: FC<Props> = ({ children }) => {
|
||||
persistent
|
||||
classNames={{
|
||||
modalContent:
|
||||
'relative z-50 w-[460px] max-w-full rounded-base border border-white/20 bg-white/5 p-6 pb-4 backdrop-blur-3xl flex flex-wrap',
|
||||
'relative z-50 w-[460px] max-w-full rounded-base border border-white/20 bg-white/5 p-6 pb-4 backdrop-blur-3xl flex flex-wrap focus-visible:outline-none',
|
||||
modalOverlay:
|
||||
'fixed inset-0 bg-black/60 w-full h-full z-40 flex items-center justify-center cursor-pointer m-0 backdrop-blur-sm',
|
||||
modalHeader: 'text-lg text-white mb-4 flex-grow',
|
||||
|
@ -8,7 +8,7 @@ interface Props {
|
||||
|
||||
export default function Tradepage(props: Props) {
|
||||
return (
|
||||
<div className='grid grid-flow-row grid-cols-3 grid-rows-2 gap-4'>
|
||||
<div className='grid w-full grid-flow-row grid-cols-3 grid-rows-2 gap-4'>
|
||||
<TradingView params={props.params} />
|
||||
<Trade params={props.params} />
|
||||
<OrderBook params={props.params} />
|
||||
|
@ -4,6 +4,7 @@ export const ASSETS: Asset[] = [
|
||||
{
|
||||
symbol: 'OSMO',
|
||||
name: 'Osmosis',
|
||||
id: 'OSMO',
|
||||
denom: 'uosmo',
|
||||
color: '#9f1ab9',
|
||||
decimals: 6,
|
||||
@ -16,31 +17,63 @@ export const ASSETS: Asset[] = [
|
||||
{
|
||||
symbol: 'ATOM',
|
||||
name: 'Atom',
|
||||
denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
id: 'ATOM',
|
||||
denom: IS_TESTNET
|
||||
? 'ibc/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477'
|
||||
: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
||||
color: '#6f7390',
|
||||
logo: '/tokens/atom.svg',
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: IS_TESTNET ? true : false,
|
||||
isEnabled: true,
|
||||
isMarket: true,
|
||||
isDisplayCurrency: true,
|
||||
},
|
||||
{
|
||||
symbol: 'CRO',
|
||||
name: 'Cronos',
|
||||
denom: 'ibc/E6931F78057F7CC5DA0FD6CEF82FF39373A6E0452BF1FD76910B93292CF356C1',
|
||||
color: '#002D74',
|
||||
logo: '/tokens/cro.svg',
|
||||
symbol: 'stATOM',
|
||||
name: 'Stride Atom',
|
||||
id: 'stATOM',
|
||||
denom: 'ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901',
|
||||
color: '#9f1ab9',
|
||||
logo: '/tokens/statom.svg',
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: !IS_TESTNET,
|
||||
isMarket: !IS_TESTNET,
|
||||
isDisplayCurrency: !IS_TESTNET,
|
||||
},
|
||||
{
|
||||
symbol: 'WBTC.axl',
|
||||
id: 'axlWBTC',
|
||||
name: 'Axelar Wrapped Bitcoin',
|
||||
denom: 'ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F',
|
||||
color: '#f09242',
|
||||
logo: '/tokens/axlwbtc.svg',
|
||||
decimals: 8,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: false,
|
||||
isMarket: true,
|
||||
isEnabled: !IS_TESTNET,
|
||||
isMarket: !IS_TESTNET,
|
||||
isDisplayCurrency: !IS_TESTNET,
|
||||
},
|
||||
{
|
||||
symbol: 'WETH.axl',
|
||||
id: 'axlWETH',
|
||||
name: 'Axelar Wrapped Ethereum',
|
||||
denom: 'ibc/EA1D43981D5C9A1C4AAEA9C23BB1D4FA126BA9BC7020A25E0AE4AA841EA25DC5',
|
||||
color: '#343434',
|
||||
logo: '/tokens/axlweth.svg',
|
||||
decimals: 18,
|
||||
hasOraclePrice: true,
|
||||
isEnabled: !IS_TESTNET,
|
||||
isMarket: !IS_TESTNET,
|
||||
isDisplayCurrency: !IS_TESTNET,
|
||||
},
|
||||
{
|
||||
symbol: 'MARS',
|
||||
name: 'Mars',
|
||||
id: 'MARS',
|
||||
denom: IS_TESTNET
|
||||
? 'ibc/ACA4C8A815A053CC027DB90D15915ADA31939FA331CE745862CDD00A2904FA17'
|
||||
? 'ibc/DB9D326CF53EA07610C394D714D78F8BB4DC7E312D4213193791A9046BF45E20'
|
||||
: 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580',
|
||||
color: '#dd5b65',
|
||||
logo: '/tokens/mars.svg',
|
||||
@ -51,15 +84,33 @@ export const ASSETS: Asset[] = [
|
||||
isEnabled: true,
|
||||
},
|
||||
{
|
||||
symbol: 'JUNO',
|
||||
name: 'Juno',
|
||||
denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
||||
color: 'black',
|
||||
logo: '/tokens/juno.svg',
|
||||
symbol: 'USDC.axl',
|
||||
name: 'Axelar USDC',
|
||||
id: 'axlUSDC',
|
||||
denom: IS_TESTNET
|
||||
? 'ibc/6F34E1BD664C36CE49ACC28E60D62559A5F96C4F9A6CCE4FC5A67B2852E24CFE'
|
||||
: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858',
|
||||
color: '#478edc',
|
||||
logo: '/tokens/axlusdc.svg',
|
||||
decimals: 6,
|
||||
hasOraclePrice: true,
|
||||
isMarket: IS_TESTNET,
|
||||
isEnabled: true,
|
||||
isMarket: true,
|
||||
isDisplayCurrency: true,
|
||||
},
|
||||
{
|
||||
symbol: 'USDC.n',
|
||||
name: 'Noble USDC',
|
||||
id: 'nUSDC',
|
||||
denom: IS_TESTNET
|
||||
? 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4'
|
||||
: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
|
||||
color: '#478edc',
|
||||
logo: '/tokens/nusdc.svg',
|
||||
decimals: 6,
|
||||
hasOraclePrice: IS_TESTNET,
|
||||
isEnabled: IS_TESTNET,
|
||||
isMarket: IS_TESTNET,
|
||||
isDisplayCurrency: IS_TESTNET,
|
||||
},
|
||||
]
|
||||
|
@ -1,12 +1,73 @@
|
||||
export const VAULT_DEPOSIT_BUFFER = 0.999
|
||||
|
||||
export const VAULTS: VaultMetaData[] = [
|
||||
export const TESTNET_VAULTS: VaultMetaData[] = [
|
||||
{
|
||||
address: 'osmo108q2krqr0y9g0rtesenvsw68sap2xefelwwjs0wedyvdl0cmrntqvllfjk',
|
||||
address: 'osmo1q40xvrzpldwq5he4ftsf7zm2jf80tj373qaven38yqrvhex8r9rs8n94kv',
|
||||
name: 'OSMO-USDC.n',
|
||||
lockup: {
|
||||
duration: 1,
|
||||
timeframe: 'day',
|
||||
},
|
||||
provider: 'Apollo',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
|
||||
lp: 'gamm/pool/6',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'OSMO-USDC.n',
|
||||
},
|
||||
isFeatured: true,
|
||||
},
|
||||
{
|
||||
address: 'osmo14lu7m4ganxs20258dazafrjfaulmfxruq9n0r0th90gs46jk3tuqwfkqwn',
|
||||
name: 'OSMO-USDC.n',
|
||||
lockup: {
|
||||
duration: 7,
|
||||
timeframe: 'days',
|
||||
},
|
||||
provider: 'Apollo',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
|
||||
lp: 'gamm/pool/6',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'OSMO-USDC.n',
|
||||
},
|
||||
isFeatured: true,
|
||||
},
|
||||
{
|
||||
address: 'osmo1fmq9hw224fgz8lk48wyd0gfg028kvvzggt6c3zvnaqkw23x68cws5nd5em',
|
||||
name: 'OSMO-USDC.n',
|
||||
lockup: {
|
||||
duration: 14,
|
||||
timeframe: 'days',
|
||||
},
|
||||
provider: 'Apollo',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/B3504E092456BA618CC28AC671A71FB08C6CA0FD0BE7C8A5B5A3E2DD933CC9E4',
|
||||
lp: 'gamm/pool/6',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'OSMO-USDC.n',
|
||||
},
|
||||
isFeatured: true,
|
||||
},
|
||||
]
|
||||
|
||||
export const VAULTS: VaultMetaData[] = [
|
||||
// Mainnet Vaults
|
||||
{
|
||||
address: 'osmo1g3kmqpp8608szfp0pdag3r6z85npph7wmccat8lgl3mp407kv73qlj7qwp',
|
||||
name: 'OSMO-ATOM',
|
||||
lockup: {
|
||||
duration: 14,
|
||||
timeframe: 'day',
|
||||
timeframe: 'days',
|
||||
},
|
||||
provider: 'Apollo',
|
||||
denoms: {
|
||||
@ -20,22 +81,4 @@ export const VAULTS: VaultMetaData[] = [
|
||||
},
|
||||
isFeatured: true,
|
||||
},
|
||||
{
|
||||
address: 'osmo1g5hryv0gp9dzlchkp3yxk8fmcf5asjun6cxkvyffetqzkwmvy75qfmeq3f',
|
||||
name: 'OSMO - JUNO',
|
||||
lockup: {
|
||||
duration: 14,
|
||||
timeframe: 'day',
|
||||
},
|
||||
provider: 'Apollo',
|
||||
denoms: {
|
||||
primary: 'uosmo',
|
||||
secondary: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
||||
lp: 'gamm/pool/497',
|
||||
},
|
||||
symbols: {
|
||||
primary: 'OSMO',
|
||||
secondary: 'JUNO',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
8
src/hooks/useCurrentAccount.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import useStore from 'store'
|
||||
import useParams from 'utils/route'
|
||||
|
||||
export default function useCurrentAccount(): Account | undefined {
|
||||
const params = useParams()
|
||||
const accounts = useStore((s) => s.accounts)
|
||||
return accounts?.find((account) => account.id === params.accountId)
|
||||
}
|
@ -19,7 +19,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
(market: Market) => market.borrowEnabled,
|
||||
)
|
||||
const prices: Coin[] = await $prices.json()
|
||||
|
||||
return borrowEnabledMarkets.map((market) => {
|
||||
const price = prices.find((coin) => coin.denom === market.denom)?.amount ?? '1'
|
||||
const amount = liquidity.find((coin) => coin.denom === market.denom)?.amount ?? '0'
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { ENV, ENV_MISSING_MESSAGE, VERCEL_BYPASS } from 'constants/env'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!ENV.URL_API) {
|
||||
@ -21,7 +22,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
if (debt) {
|
||||
return {
|
||||
denom: deposit.denom,
|
||||
amount: (Number(deposit.amount) - Number(debt.amount)).toString(),
|
||||
amount: BN(deposit.amount).minus(debt.amount).toString(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { gql, request as gqlRequest } from 'graphql-request'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { ASSETS } from 'constants/assets'
|
||||
import { ENV, ENV_MISSING_MESSAGE } from 'constants/env'
|
||||
import { getMarketAssets } from 'utils/assets'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!ENV.URL_GQL || !ENV.ADDRESS_ORACLE) {
|
||||
@ -10,6 +12,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
}
|
||||
|
||||
const marketAssets = getMarketAssets()
|
||||
const baseCurrency = ASSETS[0]
|
||||
|
||||
const result = await gqlRequest<TokenPricesResult>(
|
||||
ENV.URL_GQL,
|
||||
@ -17,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
query PriceOracle {
|
||||
prices: wasm {
|
||||
${marketAssets.map((asset) => {
|
||||
return `${asset.symbol}: contractQuery(
|
||||
return `${asset.id}: contractQuery(
|
||||
contractAddress: "${ENV.ADDRESS_ORACLE}"
|
||||
query: {
|
||||
price: {
|
||||
@ -32,7 +35,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
)
|
||||
|
||||
const data: Coin[] = Object.values(result?.prices).reduce((acc: Coin[], curr) => {
|
||||
return [...acc, { denom: curr.denom, amount: curr.price }] as Coin[]
|
||||
const asset = marketAssets.find((asset) => asset.denom === curr.denom)
|
||||
const additionalDecimals = asset
|
||||
? asset.decimals > baseCurrency.decimals
|
||||
? asset.decimals - baseCurrency.decimals
|
||||
: 0
|
||||
: 0
|
||||
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
denom: curr.denom,
|
||||
amount: BN(curr.price).shiftedBy(additionalDecimals).toString(),
|
||||
},
|
||||
] as Coin[]
|
||||
}, [])
|
||||
|
||||
return res.status(200).json(data)
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { ENV, ENV_MISSING_MESSAGE } from 'constants/env'
|
||||
import { ENV, ENV_MISSING_MESSAGE, IS_TESTNET } from 'constants/env'
|
||||
import { TESTNET_VAULTS, VAULTS } from 'constants/vaults'
|
||||
import {
|
||||
ArrayOfVaultInfoResponse,
|
||||
VaultBaseForString,
|
||||
} from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||
import { VAULTS } from 'constants/vaults'
|
||||
import { convertAprToApy } from 'utils/parsers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
@ -45,7 +45,6 @@ async function getVaultConfigs(client: CosmWasmClient, startAfter?: VaultBaseFor
|
||||
|
||||
const getBatch = async (startAfter?: VaultBaseForString) => {
|
||||
if (!ENV.ADDRESS_CREDIT_MANAGER) return
|
||||
|
||||
const batch: ArrayOfVaultInfoResponse = await client.queryContractSmart(
|
||||
ENV.ADDRESS_CREDIT_MANAGER,
|
||||
{
|
||||
@ -78,8 +77,9 @@ async function getVaultConfigs(client: CosmWasmClient, startAfter?: VaultBaseFor
|
||||
}
|
||||
|
||||
await getBatch()
|
||||
const vaults = IS_TESTNET ? TESTNET_VAULTS : VAULTS
|
||||
|
||||
return VAULTS.map((vaultMetaData) => {
|
||||
return vaults.map((vaultMetaData) => {
|
||||
const vaultInfo = data.find((vault) => vault.address === vaultMetaData.address)
|
||||
|
||||
return {
|
||||
@ -104,7 +104,7 @@ interface NestedApr {
|
||||
}
|
||||
|
||||
async function getAprs() {
|
||||
const APOLLO_URL = 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-4'
|
||||
const APOLLO_URL = 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-5'
|
||||
|
||||
try {
|
||||
const response = await fetch(APOLLO_URL)
|
||||
|
@ -1,10 +1,10 @@
|
||||
import create, { GetState, SetState, StoreApi, UseBoundStore } from 'zustand'
|
||||
import { devtools } from 'zustand/middleware'
|
||||
|
||||
import { BroadcastSlice, createBroadcastSlice } from 'store/slices/broadcast'
|
||||
import { CommonSlice, createCommonSlice } from 'store/slices/common'
|
||||
import { createCurrencySlice, CurrencySlice } from 'store/slices/currency'
|
||||
import { createModalSlice, ModalSlice } from 'store/slices/modal'
|
||||
import createBroadcastSlice from 'store/slices/broadcast'
|
||||
import createCommonSlice from 'store/slices/common'
|
||||
import createCurrencySlice from 'store/slices/currency'
|
||||
import createModalSlice from 'store/slices/modal'
|
||||
|
||||
export interface Store extends CommonSlice, BroadcastSlice, CurrencySlice, ModalSlice {}
|
||||
|
||||
|
@ -9,31 +9,10 @@ import { getMarketAssets } from 'utils/assets'
|
||||
import { getSingleValueFromBroadcastResult } from 'utils/broadcast'
|
||||
import { formatAmountWithSymbol } from 'utils/formatters'
|
||||
|
||||
interface BroadcastResult {
|
||||
result?: TxBroadcastResult
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface BroadcastSlice {
|
||||
toast: { message: string; isError?: boolean } | null
|
||||
executeMsg: (options: {
|
||||
msg: Record<string, unknown>
|
||||
fee: StdFee
|
||||
funds?: Coin[]
|
||||
}) => Promise<BroadcastResult>
|
||||
borrow: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<void>
|
||||
createAccount: (options: { fee: StdFee }) => Promise<string | null>
|
||||
deleteAccount: (options: { fee: StdFee; accountId: string }) => Promise<boolean>
|
||||
deposit: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
repay: (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
coin: Coin
|
||||
accountBalance?: boolean
|
||||
}) => Promise<boolean>
|
||||
}
|
||||
|
||||
export function createBroadcastSlice(set: SetState<Store>, get: GetState<Store>): BroadcastSlice {
|
||||
export default function createBroadcastSlice(
|
||||
set: SetState<Store>,
|
||||
get: GetState<Store>,
|
||||
): BroadcastSlice {
|
||||
const marketAssets = getMarketAssets()
|
||||
return {
|
||||
toast: null,
|
||||
@ -141,6 +120,37 @@ export function createBroadcastSlice(set: SetState<Store>, get: GetState<Store>)
|
||||
}
|
||||
return !!response.result
|
||||
},
|
||||
withdraw: async (options: { fee: StdFee; accountId: string; coin: Coin }) => {
|
||||
const msg = {
|
||||
update_credit_account: {
|
||||
account_id: options.accountId,
|
||||
actions: [
|
||||
{
|
||||
withdraw: options.coin,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const response = await get().executeMsg({ msg, fee: options.fee })
|
||||
if (response.result) {
|
||||
set({
|
||||
toast: {
|
||||
message: `Withdrew ${formatAmountWithSymbol(options.coin)} from Account ${
|
||||
options.accountId
|
||||
}`,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
set({
|
||||
toast: {
|
||||
message: response.error ?? `Transaction failed: ${response.error}`,
|
||||
isError: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
return !!response.result
|
||||
},
|
||||
executeMsg: async (options: {
|
||||
fee: StdFee
|
||||
msg: Record<string, unknown>
|
||||
|
@ -1,18 +1,7 @@
|
||||
import { WalletClient, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||
import { WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||
import { GetState, SetState } from 'zustand'
|
||||
|
||||
export interface CommonSlice {
|
||||
accounts: Account[] | null
|
||||
address?: string
|
||||
enableAnimations: boolean
|
||||
isOpen: boolean
|
||||
balances: Coin[] | null
|
||||
selectedAccount: string | null
|
||||
client?: WalletClient
|
||||
status: WalletConnectionStatus
|
||||
}
|
||||
|
||||
export function createCommonSlice(set: SetState<CommonSlice>, get: GetState<CommonSlice>) {
|
||||
export default function createCommonSlice(set: SetState<CommonSlice>, get: GetState<CommonSlice>) {
|
||||
return {
|
||||
accounts: null,
|
||||
balances: null,
|
||||
|
@ -1,15 +1,11 @@
|
||||
import { Coin } from '@cosmjs/stargate'
|
||||
import { GetState, SetState } from 'zustand'
|
||||
|
||||
import { ASSETS } from 'constants/assets'
|
||||
|
||||
export interface CurrencySlice {
|
||||
baseCurrency: Asset
|
||||
displayCurrency: Asset
|
||||
prices: Coin[]
|
||||
}
|
||||
|
||||
export function createCurrencySlice(set: SetState<CurrencySlice>, get: GetState<CurrencySlice>) {
|
||||
export default function createCurrencySlice(
|
||||
set: SetState<CurrencySlice>,
|
||||
get: GetState<CurrencySlice>,
|
||||
) {
|
||||
return {
|
||||
baseCurrency: ASSETS[0],
|
||||
displayCurrency: ASSETS.find((asset) => asset.denom === ASSETS[0].denom)!,
|
||||
|
@ -1,21 +1,6 @@
|
||||
import { GetState, SetState } from 'zustand'
|
||||
|
||||
export interface ModalSlice {
|
||||
borrowModal: {
|
||||
asset: Asset
|
||||
marketData: BorrowAsset | BorrowAssetActive
|
||||
isRepay?: boolean
|
||||
} | null
|
||||
createAccountModal: boolean
|
||||
deleteAccountModal: boolean
|
||||
fundAccountModal: boolean
|
||||
withdrawModal: boolean
|
||||
vaultModal: {
|
||||
vault: Vault
|
||||
} | null
|
||||
}
|
||||
|
||||
export function createModalSlice(set: SetState<ModalSlice>, get: GetState<ModalSlice>) {
|
||||
export default function createModalSlice(set: SetState<ModalSlice>, get: GetState<ModalSlice>) {
|
||||
return {
|
||||
borrowModal: null,
|
||||
createAccountModal: false,
|
||||
|
3
src/types/interfaces/asset.d.ts
vendored
@ -2,7 +2,8 @@ interface Asset {
|
||||
color: string
|
||||
name: string
|
||||
denom: string
|
||||
symbol: 'OSMO' | 'ATOM' | 'CRO' | 'MARS' | 'JUNO'
|
||||
symbol: 'OSMO' | 'ATOM' | 'MARS' | 'stATOM' | 'USDC.axl' | 'USDC.n' | 'WBTC.axl' | 'WETH.axl'
|
||||
id: 'OSMO' | 'ATOM' | 'MARS' | 'stATOM' | 'axlUSDC' | 'axlWBTC' | 'axlWETH' | 'nUSDC'
|
||||
prefix?: string
|
||||
contract_addr?: string
|
||||
logo: string
|
||||
|
6
src/types/interfaces/market.d.ts
vendored
@ -1,9 +1,9 @@
|
||||
interface Market {
|
||||
denom: string
|
||||
borrowRate: number
|
||||
debtTotalScaled: number
|
||||
collateralTotalScaled: number
|
||||
debtTotalScaled: string
|
||||
collateralTotalScaled: string
|
||||
depositEnabled: boolean
|
||||
borrowEnabled: boolean
|
||||
depositCap: number
|
||||
depositCap: string
|
||||
}
|
||||
|
24
src/types/interfaces/store/broadcast.d.ts
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
interface BroadcastResult {
|
||||
result?: import('@marsprotocol/wallet-connector').TxBroadcastResult
|
||||
error?: string
|
||||
}
|
||||
|
||||
interface BroadcastSlice {
|
||||
toast: { message: string; isError?: boolean } | null
|
||||
executeMsg: (options: {
|
||||
msg: Record<string, unknown>
|
||||
fee: StdFee
|
||||
funds?: Coin[]
|
||||
}) => Promise<BroadcastResult>
|
||||
borrow: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<void>
|
||||
createAccount: (options: { fee: StdFee }) => Promise<string | null>
|
||||
deleteAccount: (options: { fee: StdFee; accountId: string }) => Promise<boolean>
|
||||
deposit: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
withdraw: (options: { fee: StdFee; accountId: string; coin: Coin }) => Promise<boolean>
|
||||
repay: (options: {
|
||||
fee: StdFee
|
||||
accountId: string
|
||||
coin: Coin
|
||||
accountBalance?: boolean
|
||||
}) => Promise<boolean>
|
||||
}
|
10
src/types/interfaces/store/comon.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
interface CommonSlice {
|
||||
accounts: Account[] | null
|
||||
address?: string
|
||||
enableAnimations: boolean
|
||||
isOpen: boolean
|
||||
balances: Coin[] | null
|
||||
selectedAccount: string | null
|
||||
client?: import('@marsprotocol/wallet-connector').WalletClient
|
||||
status: import('@marsprotocol/wallet-connector').WalletConnectionStatus
|
||||
}
|
5
src/types/interfaces/store/currency.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
interface CurrencySlice {
|
||||
baseCurrency: Asset
|
||||
displayCurrency: Asset
|
||||
prices: Coin[]
|
||||
}
|
16
src/types/interfaces/store/modals.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
interface ModalSlice {
|
||||
borrowModal: BorrowModal | null
|
||||
createAccountModal: boolean
|
||||
deleteAccountModal: boolean
|
||||
fundAccountModal: boolean
|
||||
withdrawModal: boolean
|
||||
vaultModal: {
|
||||
vault: Vault
|
||||
} | null
|
||||
}
|
||||
|
||||
interface BorrowModal {
|
||||
asset: Asset
|
||||
marketData: BorrowAsset | BorrowAssetActive
|
||||
isRepay?: boolean
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
import { BN } from './helpers'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export const calculateAccountBalance = (account: Account, prices: Coin[]) => {
|
||||
const totalDepositValue = account.deposits.reduce((acc, deposit) => {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { getMarketAssets } from './assets'
|
||||
import { BN } from './helpers'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
import { getMarketAssets } from 'utils/assets'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export function truncate(text = '', [h, t]: [number, number] = [6, 6]): string {
|
||||
const head = text.slice(0, h)
|
||||
@ -116,9 +118,9 @@ export function formatLeverage(leverage: number) {
|
||||
})
|
||||
}
|
||||
|
||||
export function formatPercent(percent: number | string) {
|
||||
export function formatPercent(percent: number | string, minDecimals?: number) {
|
||||
return formatValue(+percent * 100, {
|
||||
minDecimals: 0,
|
||||
minDecimals: minDecimals ?? 0,
|
||||
suffix: '%',
|
||||
})
|
||||
}
|
||||
@ -143,14 +145,12 @@ export const convertPercentage = (percent: number) => {
|
||||
return Number(formatValue(percentage, { minDecimals: 0, maxDecimals: 0 }))
|
||||
}
|
||||
|
||||
export function magnify(value: number, asset: Asset) {
|
||||
return value === 0 ? 0 : BN(value).shiftedBy(asset.decimals).toNumber()
|
||||
export function magnify(value: number | string, asset: Asset) {
|
||||
const amount = BN(value)
|
||||
return amount.isZero() ? amount : BN(value).shiftedBy(asset.decimals)
|
||||
}
|
||||
|
||||
export function demagnify(amount: number, asset: Asset) {
|
||||
return amount === 0
|
||||
? 0
|
||||
: BN(amount)
|
||||
.shiftedBy(-1 * asset.decimals)
|
||||
.toNumber()
|
||||
export function demagnify(amount: number | string | BigNumber, asset: Asset) {
|
||||
const value = BN(amount)
|
||||
return value.isZero() ? 0 : value.shiftedBy(-1 * asset.decimals).toNumber()
|
||||
}
|
||||
|
@ -16,10 +16,10 @@ export function resolveMarketResponses(responses: MarketResponse[]): Market[] {
|
||||
return responses.map((response) => ({
|
||||
denom: response.denom,
|
||||
borrowRate: Number(response.borrow_rate),
|
||||
debtTotalScaled: Number(response.debt_total_scaled),
|
||||
collateralTotalScaled: Number(response.collateral_total_scaled),
|
||||
debtTotalScaled: response.debt_total_scaled,
|
||||
collateralTotalScaled: response.collateral_total_scaled,
|
||||
depositEnabled: response.deposit_enabled,
|
||||
borrowEnabled: response.borrow_enabled,
|
||||
depositCap: Number(response.deposit_cap),
|
||||
depositCap: response.deposit_cap,
|
||||
}))
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { VAULTS } from 'constants/vaults'
|
||||
import { IS_TESTNET } from 'constants/env'
|
||||
import { TESTNET_VAULTS, VAULTS } from 'constants/vaults'
|
||||
|
||||
export function getVaultMetaData(address: string) {
|
||||
return VAULTS.find((vault) => vault.address === address)
|
||||
const vaults = IS_TESTNET ? TESTNET_VAULTS : VAULTS
|
||||
return vaults.find((vault) => vault.address === address)
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
@ -27,14 +23,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"src/types/custom.d.ts",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "src/types/**.d.ts", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|