From 391f680a4f228b843c7e5947b001b6864886e390 Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Thu, 3 Oct 2024 13:29:19 +0300 Subject: [PATCH 01/14] fix(energy): init --- src/pages/Energy/Energy.module.scss | 0 src/pages/Energy/Energy.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/pages/Energy/Energy.module.scss create mode 100644 src/pages/Energy/Energy.tsx diff --git a/src/pages/Energy/Energy.module.scss b/src/pages/Energy/Energy.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/Energy/Energy.tsx b/src/pages/Energy/Energy.tsx new file mode 100644 index 000000000..e69de29bb From a8e91c3c84709882da90df24bfdbdf035f817058 Mon Sep 17 00:00:00 2001 From: OggyKUN Date: Mon, 14 Oct 2024 05:19:30 +0300 Subject: [PATCH 02/14] feat(portal): add packages front --- src/pages/Portal/Buy/Buy.module.scss | 123 ++++++++++++++++++++ src/pages/Portal/Buy/Buy.tsx | 91 +++++++++++++++ src/pages/Portal/Buy/PlanDisplay.tsx | 135 ++++++++++++++++++++++ src/pages/Portal/Buy/images/checkmark.svg | 5 + src/pages/Portal/Buy/images/genius.png | Bin 0 -> 27836 bytes src/pages/Portal/Buy/images/ghost.png | Bin 0 -> 25162 bytes src/pages/Portal/Buy/images/prodigy.png | Bin 0 -> 24195 bytes src/pages/Portal/Buy/images/smart.png | Bin 0 -> 25943 bytes src/pages/Portal/Buy/type.ts | 86 ++++++++++++++ src/router.tsx | 2 + src/routes.ts | 3 + src/utils/appsMenu/appsMenu.ts | 5 + 12 files changed, 450 insertions(+) create mode 100644 src/pages/Portal/Buy/Buy.module.scss create mode 100644 src/pages/Portal/Buy/Buy.tsx create mode 100644 src/pages/Portal/Buy/PlanDisplay.tsx create mode 100644 src/pages/Portal/Buy/images/checkmark.svg create mode 100644 src/pages/Portal/Buy/images/genius.png create mode 100644 src/pages/Portal/Buy/images/ghost.png create mode 100644 src/pages/Portal/Buy/images/prodigy.png create mode 100644 src/pages/Portal/Buy/images/smart.png create mode 100644 src/pages/Portal/Buy/type.ts diff --git a/src/pages/Portal/Buy/Buy.module.scss b/src/pages/Portal/Buy/Buy.module.scss new file mode 100644 index 000000000..38453d9f8 --- /dev/null +++ b/src/pages/Portal/Buy/Buy.module.scss @@ -0,0 +1,123 @@ +.buyContainer { + display: grid; + grid-template-columns: repeat(5, 200px); + justify-content: center; + padding: 1rem; +} + +.labelsColumn { + padding: 75px 10px 50px; + z-index: 1; +} + +.planContent { + display: flex; + flex-direction: column; +} + +%flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +%row-common { + @extend %flex-center; + height: 45px; + width: 100%; + text-align: center; + padding: 7px 0; +} + +.row, .uploads, .symbols, .influence, .price, .included, .excluded, .fuel, .energy { + @extend %row-common; +} + +.labelGroup { + display: flex; + flex-direction: column; + align-items: flex-start; + width: 100%; +} + +.label, .subLabel { + text-align: center; +} + +.label { + font-size: 16px; + color: var(--grayscale-primary); +} + +.subLabel { + font-size: 14px; + color: var(--grayscale-disabled); +} + +.included { + color: var(--green-light); + + .checkmark { + width: 31px; + height: 31px; + fill: var(--green-light); + } +} + +.excluded { + color: var(--red); +} + +.symbols, .fuel, .energy, .influence, .uploads, .planName { + font-size: 20px; +} + +.price { + font-size: 30px; +} + +.symbolsDigit { + color: var(--grayscale-primary); + margin-right: 2px; +} + +.symbolsText { + color: var(--grayscale-disabled); +} + +.fuelIcon, .energyIcon { + margin-left: 3px; +} + +.white { color: var(--grayscale-primary); } +.green { color: var(--primary-color); } +.blue { color: var(--blue-light); } +.purple { color: var(--pink); } +.gray { color: var(--grayscale-disabled); } + +.displayWrapper { + position: relative; +} + +.planTitleWrapper { + @extend %flex-center; + } + +.planIcon { + width: 65px; + height: 65px; + object-fit: contain; +} + +.planButton { + background: none; + border: none; + cursor: pointer; + padding: 0; + + &:focus { + outline: none; + } +} + + diff --git a/src/pages/Portal/Buy/Buy.tsx b/src/pages/Portal/Buy/Buy.tsx new file mode 100644 index 000000000..f03853ebd --- /dev/null +++ b/src/pages/Portal/Buy/Buy.tsx @@ -0,0 +1,91 @@ +import { useState } from 'react'; +import styles from './Buy.module.scss'; +import portal from 'images/space-pussy.svg'; +import oracle from 'src/image/new_icons/oracle.svg'; +import docs from 'src/image/new_icons/docs.svg'; +import sphere from 'src/image/new_icons/sphere.svg'; +import hfr from 'src/image/new_icons/hfr.svg'; +import teleport from 'src/image/new_icons/teleport.svg'; +/* import studio from './images/studio.png'; */ +import robot from 'src/image/new_icons/robot.svg'; +import { MoonAnimation } from 'src/containers/portal/components'; +import { features, plans } from './type'; +import { Stars } from 'src/containers/portal/components'; +import { ActionBar, Button } from 'src/components'; +import PlanDisplay from './PlanDisplay'; + + +function Buy() { + const [selectedPlan, setSelectedPlan] = useState(null); + const [hoveredPlan, setHoveredPlan] = useState(null); + + + const renderFeatureContent = (feature: typeof features[0]) => { + if (feature.label === '3 free to use aips') { + return ( +
+ portal + oracle + docs +
+ ); + } + if (feature.label === 'all powered aips') { + return ( +
+ sphere + hfr + teleport + robot +
+ ); + } + return null; + }; + + return ( + <> + + +
+
+
+ {features.map((feature, index) => ( +
+
+
{feature.label}
+ {feature.subLabel && ( +
{feature.subLabel}
+ )} + {renderFeatureContent(feature)} +
+
+ ))} +
+
+ {plans.map((plan, index) => ( + setSelectedPlan(plan.name)} + onHover={() => setHoveredPlan(plan.name)} + onLeave={() => setHoveredPlan(null)} + /> + + ))} +
+ {selectedPlan && ( + + + + )} + + ); +}; + +export default Buy; diff --git a/src/pages/Portal/Buy/PlanDisplay.tsx b/src/pages/Portal/Buy/PlanDisplay.tsx new file mode 100644 index 000000000..bcec4ffc4 --- /dev/null +++ b/src/pages/Portal/Buy/PlanDisplay.tsx @@ -0,0 +1,135 @@ +import styles from './Buy.module.scss'; +import Display from '../../../components/containerGradient/Display/Display'; +import checkmark from './images/checkmark.svg'; +import { features, plans } from './type'; +import IconsNumber from 'src/components/IconsNumber/IconsNumber'; +import AdviserHoverWrapper from 'src/features/adviser/AdviserHoverWrapper/AdviserHoverWrapper'; + +interface PlanDisplayProps { + plan: typeof plans[0]; + index: number; + isSelected: boolean; + isHovered: boolean; + onSelect: () => void; + onHover: () => void; + onLeave: () => void; +} + +function PlanDisplay({ + plan, + index, + isSelected, + isHovered, + onSelect, + onHover, + onLeave, +}: PlanDisplayProps) { + const renderPlanFeature = (featureIndex: number) => { + const featureRenderers = { + default: () => ( +
+ {plan.features[featureIndex] ? ( + checkmark + ) : '❌'} +
+ ), + 2: () => plan.uploads > 0 ? ( +
~ {plan.uploads}
+ ) : ( +
+ ), + 3: () => ( +
+ + {'>'}{plan.symbols} + {'symbols'} + +
+ ), + 4: () => plan.fuel > 0 ? ( +
+ +
+ ) : ( +
+ ), + 5: () => plan.energy > 0 ? ( +
+ + + +
+ ) : ( +
+ ), + 6: () => plan.influence > 0 ? ( +
+ {plan.influence}{' '} +
+ ) : ( +
+ ), + }; + + const renderer = featureRenderers[featureIndex as keyof typeof featureRenderers] || featureRenderers.default; + return renderer(); + }; + + return ( + + + ); +}; + +export default PlanDisplay; \ No newline at end of file diff --git a/src/pages/Portal/Buy/images/checkmark.svg b/src/pages/Portal/Buy/images/checkmark.svg new file mode 100644 index 000000000..caed443a4 --- /dev/null +++ b/src/pages/Portal/Buy/images/checkmark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/pages/Portal/Buy/images/genius.png b/src/pages/Portal/Buy/images/genius.png new file mode 100644 index 0000000000000000000000000000000000000000..611370b152d0f741d5a628bd0a2ea1ecd8f0c447 GIT binary patch literal 27836 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 fefaR=h5Kh-G--00000NkvXXu0mjfx-U^} literal 0 HcmV?d00001 diff --git a/src/pages/Portal/Buy/images/ghost.png b/src/pages/Portal/Buy/images/ghost.png new file mode 100644 index 0000000000000000000000000000000000000000..d111f5fb085082159a905fd1b011de1b95682130 GIT binary patch literal 25162 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 JPDHLkV1mNkPpkj{ literal 0 HcmV?d00001 diff --git a/src/pages/Portal/Buy/images/prodigy.png b/src/pages/Portal/Buy/images/prodigy.png new file mode 100644 index 0000000000000000000000000000000000000000..b250b516e34bbb0fb675d84163334e034e033155 GIT binary patch literal 24195 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 e{h57p+W!ZtL%y1!#`H`80000iRoX+u@0 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

iyZ`;*kivN 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 KMNUMnLSTYihLT+X literal 0 HcmV?d00001 diff --git a/src/pages/Portal/Buy/type.ts b/src/pages/Portal/Buy/type.ts new file mode 100644 index 000000000..7abd31c77 --- /dev/null +++ b/src/pages/Portal/Buy/type.ts @@ -0,0 +1,86 @@ +import { Colors } from '../../../components/containerGradient/types'; +import ghostIcon from './images/ghost.png'; +import smartIcon from './images/smart.png'; +import prodigyIcon from './images/prodigy.png'; +import geniusIcon from './images/genius.png'; + +export interface Feature { + label: string; + subLabel: string; +} + +export interface Plan { + name: string; + color: Colors; + price: string; + icon: string; + features: boolean[]; + symbols: string; + uploads: number; + fuel: number; + energy: number; + influence: number; +} + +export const features: Feature[] = [ + { label: 'brain surf', subLabel: 'search for free' }, + { label: 'private pins', subLabel: 'unlimited' }, + { label: 'public upload', subLabel: 'cyberlinks daily' }, + { label: '.moon citizenship', subLabel: 'afford cool short name' }, + { label: 'fuel', subLabel: 'main token, liquid' }, + { label: 'energy', subLabel: 'your power, A x V = kW' }, + { label: 'influence', subLabel: 'your content visibility' }, + { label: '3 free to use aips', subLabel: '' }, + { label: 'all powered aips', subLabel: '' }, +]; + +export const plans: Plan[] = [ + { + name: 'ghost', + color: Colors.WHITE, + price: 'free', + icon: ghostIcon, + features: [true, true, false, false, false, false, false, true, false], + symbols: ' 8 ', + uploads: 0, + fuel: 0, + energy: 0, + influence: 0, + }, + { + name: 'smart', + color: Colors.GREEN, + price: '10$', + icon: smartIcon, + features: [true, true, true, true, true, true, true, true, false], + symbols: ' 5 ', + uploads: 80, + fuel: 2, + energy: 4, + influence: 1, + }, + { + name: 'prodigy', + color: Colors.BLUE, + price: '100$', + icon: prodigyIcon, + features: [true, true, true, true, true, true, true, true, true], + symbols: ' 4 ', + uploads: 800, + fuel: 20, + energy: 1, + influence: 7, + }, + { + name: 'genius', + color: Colors.PURPLE, + price: '1000$', + icon: geniusIcon, + features: [true, true, true, true, true, true, true, true, true], + symbols: ' 3 ', + uploads: 8000, + fuel: 200, + energy: 11, + influence: 19, + }, +]; diff --git a/src/router.tsx b/src/router.tsx index c7d6cc238..4a25eaf54 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -59,6 +59,7 @@ import BrainRoutes from './routing/Brain'; import Settings from './pages/Settings/Settings'; import GovernanceRoutes from './containers/governance/GovernanceRoutes'; import StudioWrapper from './features/studio/StudioWrapper'; +import Buy from './pages/Portal/Buy/Buy'; type WrappedRouterProps = { children: React.ReactNode; @@ -191,6 +192,7 @@ function AppRouter() { } /> } /> } /> + } /> {/* wasm */} } /> diff --git a/src/routes.ts b/src/routes.ts index e123755b9..d497c82ca 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -30,6 +30,9 @@ export const routes = { gift: { path: '/gift', }, + buy: { + path: '/buy', + }, ipfs: { path: '/ipfs', getLink: (param: string) => `/ipfs/${param}`, diff --git a/src/utils/appsMenu/appsMenu.ts b/src/utils/appsMenu/appsMenu.ts index af2bb338d..e576198de 100644 --- a/src/utils/appsMenu/appsMenu.ts +++ b/src/utils/appsMenu/appsMenu.ts @@ -275,6 +275,11 @@ const getMenuItems = () => { to: '/genesis', icon: require('./images/aos.png'), }, + { + name: 'Buy', + to: '/buy', + icon: '🤑', + }, // { name: 'Release', to: '/release' }, ], }); From 8044330e489d91a0586812b3a58f6bf33c62b74d Mon Sep 17 00:00:00 2001 From: OggyKUN Date: Mon, 14 Oct 2024 18:26:03 +0300 Subject: [PATCH 03/14] fix(portal/buy): fixes and improvements --- src/pages/Portal/Buy/Buy.module.scss | 90 +++++++----- src/pages/Portal/Buy/Buy.tsx | 32 ++--- src/pages/Portal/Buy/PlanDisplay.tsx | 196 +++++++++++++-------------- 3 files changed, 169 insertions(+), 149 deletions(-) diff --git a/src/pages/Portal/Buy/Buy.module.scss b/src/pages/Portal/Buy/Buy.module.scss index 38453d9f8..76bb876c0 100644 --- a/src/pages/Portal/Buy/Buy.module.scss +++ b/src/pages/Portal/Buy/Buy.module.scss @@ -6,13 +6,29 @@ } .labelsColumn { - padding: 75px 10px 50px; + padding: 65px 10px 0px 30px; z-index: 1; } .planContent { display: flex; flex-direction: column; + width: 100%; + padding: 10px 5px; + cursor: pointer; + transition: all 0.3s ease; + + &.active { + background-color: rgb(54, 214, 174, 0.1); + } +} + +.planWrapper { + &:hover { + .planContent:not(.active) { + background-color: rgba(255, 255, 255, 0.1); + } + } } %flex-center { @@ -29,7 +45,14 @@ padding: 7px 0; } -.row, .uploads, .symbols, .influence, .price, .included, .excluded, .fuel, .energy { +.row, +.uploads, +.symbols, +.influence, +.price, +.excluded, +.fuel, +.energy { @extend %row-common; } @@ -40,7 +63,8 @@ width: 100%; } -.label, .subLabel { +.label, +.subLabel { text-align: center; } @@ -54,26 +78,28 @@ color: var(--grayscale-disabled); } -.included { - color: var(--green-light); - - .checkmark { - width: 31px; - height: 31px; - fill: var(--green-light); - } +.checkmark { + width: 31px; + height: 31px; + fill: var(--green-light); } .excluded { color: var(--red); } -.symbols, .fuel, .energy, .influence, .uploads, .planName { +.symbols, +.fuel, +.energy, +.influence, +.uploads, +.planName { font-size: 20px; } .price { font-size: 30px; + margin-top: 10px; } .symbolsDigit { @@ -85,15 +111,26 @@ color: var(--grayscale-disabled); } -.fuelIcon, .energyIcon { +.fuelIcon, +.energyIcon { margin-left: 3px; } -.white { color: var(--grayscale-primary); } -.green { color: var(--primary-color); } -.blue { color: var(--blue-light); } -.purple { color: var(--pink); } -.gray { color: var(--grayscale-disabled); } +.white { + color: var(--grayscale-primary); +} +.green { + color: var(--primary-color); +} +.blue { + color: var(--blue-light); +} +.purple { + color: var(--pink); +} +.gray { + color: var(--grayscale-disabled); +} .displayWrapper { position: relative; @@ -101,23 +138,10 @@ .planTitleWrapper { @extend %flex-center; - } +} .planIcon { width: 65px; height: 65px; - object-fit: contain; -} - -.planButton { - background: none; - border: none; - cursor: pointer; - padding: 0; - - &:focus { - outline: none; - } + object-fit: fill; } - - diff --git a/src/pages/Portal/Buy/Buy.tsx b/src/pages/Portal/Buy/Buy.tsx index f03853ebd..fd958078a 100644 --- a/src/pages/Portal/Buy/Buy.tsx +++ b/src/pages/Portal/Buy/Buy.tsx @@ -14,13 +14,10 @@ import { Stars } from 'src/containers/portal/components'; import { ActionBar, Button } from 'src/components'; import PlanDisplay from './PlanDisplay'; - function Buy() { const [selectedPlan, setSelectedPlan] = useState(null); - const [hoveredPlan, setHoveredPlan] = useState(null); - - const renderFeatureContent = (feature: typeof features[0]) => { + const renderFeatureContent = (feature: (typeof features)[0]) => { if (feature.label === '3 free to use aips') { return (

@@ -64,28 +61,31 @@ function Buy() {
{plans.map((plan, index) => ( - setSelectedPlan(plan.name)} - onHover={() => setHoveredPlan(plan.name)} - onLeave={() => setHoveredPlan(null)} - /> - + onClick={() => setSelectedPlan(plan.name)} + className={styles.planWrapper} + > + + ))} {selectedPlan && ( - )} ); -}; +} export default Buy; diff --git a/src/pages/Portal/Buy/PlanDisplay.tsx b/src/pages/Portal/Buy/PlanDisplay.tsx index bcec4ffc4..cbb63e676 100644 --- a/src/pages/Portal/Buy/PlanDisplay.tsx +++ b/src/pages/Portal/Buy/PlanDisplay.tsx @@ -3,133 +3,129 @@ import Display from '../../../components/containerGradient/Display/Display'; import checkmark from './images/checkmark.svg'; import { features, plans } from './type'; import IconsNumber from 'src/components/IconsNumber/IconsNumber'; -import AdviserHoverWrapper from 'src/features/adviser/AdviserHoverWrapper/AdviserHoverWrapper'; interface PlanDisplayProps { - plan: typeof plans[0]; + plan: (typeof plans)[0]; index: number; isSelected: boolean; - isHovered: boolean; - onSelect: () => void; - onHover: () => void; - onLeave: () => void; } -function PlanDisplay({ - plan, - index, - isSelected, - isHovered, - onSelect, - onHover, - onLeave, -}: PlanDisplayProps) { +function PlanDisplay({ plan, index, isSelected }: PlanDisplayProps) { const renderPlanFeature = (featureIndex: number) => { const featureRenderers = { default: () => ( -
+
{plan.features[featureIndex] ? ( checkmark - ) : '❌'} + ) : ( + '❌' + )}
), - 2: () => plan.uploads > 0 ? ( -
~ {plan.uploads}
- ) : ( -
- ), + 2: () => + plan.uploads > 0 ? ( +
~ {plan.uploads}
+ ) : ( +
+ ), 3: () => (
- {'>'}{plan.symbols} + {'>'} + {plan.symbols} {'symbols'}
), - 4: () => plan.fuel > 0 ? ( -
- -
- ) : ( -
- ), - 5: () => plan.energy > 0 ? ( -
- - - -
- ) : ( -
- ), - 6: () => plan.influence > 0 ? ( -
- {plan.influence}{' '} -
- ) : ( -
- ), + 4: () => + plan.fuel > 0 ? ( +
+ +
+ ) : ( +
+ ), + 5: () => + plan.energy > 0 ? ( +
+ + + +
+ ) : ( +
+ ), + 6: () => + plan.influence > 0 ? ( +
+ {plan.influence} +
+ ) : ( +
+ ), }; - const renderer = featureRenderers[featureIndex as keyof typeof featureRenderers] || featureRenderers.default; + const renderer = + featureRenderers[featureIndex as keyof typeof featureRenderers] || + featureRenderers.default; return renderer(); }; return ( - -
+ } + noPaddingY + noPaddingX > -
- - {`${plan.name} - {plan.name} -
- } - /* noPaddingY */ - > -
- {features.map((_, index) => ( -
- {renderPlanFeature(index)} -
- ))} -
-
- {plan.price} -
-
+
+ {features.map((_, index) => ( +
+ {renderPlanFeature(index)} +
+ ))} +
+
+ {plan.price}
- +
- - ); -}; + +
+ ); +} -export default PlanDisplay; \ No newline at end of file +export default PlanDisplay; From 2a8bb6e8a98449e512b35c5c8ee999d493b9755c Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Tue, 15 Oct 2024 04:31:01 +0300 Subject: [PATCH 04/14] feat(energy): back-end energy pages - select package - swap - send ibc tx to bostrom - ping status --- package.json | 5 + src/features/ibc-history/historyContext.tsx | 29 +- src/features/ibc-history/useGetStatus.tsx | 9 +- src/features/ibc-history/utils.ts | 93 +++--- src/pages/Energy/Energy.tsx | 33 ++ src/pages/Energy/constants.ts | 11 + src/pages/Energy/context/Energy.context.tsx | 53 ++++ .../Energy/context/OsmosisRpcProvider.tsx | 42 +++ .../Energy/context/OsmosisSignerProvider.tsx | 78 +++++ src/pages/Energy/hooks/txs/useBuyPackage.ts | 9 + src/pages/Energy/hooks/txs/useIbc.ts | 0 src/pages/Energy/hooks/useBalances.ts | 32 ++ src/pages/Energy/hooks/usePools.ts | 41 +++ src/pages/Energy/hooks/usePrices.ts | 38 +++ src/pages/Energy/hooks/useQueryHooks.ts | 5 + src/pages/Energy/hooks/useSwap.ts | 80 +++++ src/pages/Energy/hooks/useTx.ts | 75 +++++ src/pages/Energy/redux/energy.redux.ts | 96 ++++++ src/pages/Energy/redux/utils.ts | 6 + src/pages/Energy/types/EnergyPackages.ts | 11 + src/pages/Energy/types/swap.ts | 17 + src/pages/Energy/types/token.ts | 21 ++ src/pages/Energy/ui/Layout/Layout.tsx | 20 ++ .../Energy/ui/pages/BuyPackages/ActionBar.tsx | 225 ++++++++++++++ .../ui/pages/BuyPackages/BuyPackages.tsx | 113 +++++++ .../components/StatusIbc/StatusIbc.tsx | 58 ++++ src/pages/Energy/ui/pages/Main/Main.tsx | 78 +++++ .../ui/pages/SelectPackages/SelectPackages.ts | 0 src/pages/Energy/utils/assets.ts | 60 ++++ src/pages/Energy/utils/pool.ts | 52 ++++ src/pages/Energy/utils/swap.ts | 156 ++++++++++ src/pages/Energy/utils/tokenBuy.ts | 10 + src/pages/Energy/utils/utils.ts | 45 +++ src/redux/reducers/index.ts | 2 + src/router.tsx | 3 + src/utils/networkListIbc.ts | 32 +- yarn.lock | 292 +++++++++++++++--- 37 files changed, 1822 insertions(+), 108 deletions(-) create mode 100644 src/pages/Energy/constants.ts create mode 100644 src/pages/Energy/context/Energy.context.tsx create mode 100644 src/pages/Energy/context/OsmosisRpcProvider.tsx create mode 100644 src/pages/Energy/context/OsmosisSignerProvider.tsx create mode 100644 src/pages/Energy/hooks/txs/useBuyPackage.ts create mode 100644 src/pages/Energy/hooks/txs/useIbc.ts create mode 100644 src/pages/Energy/hooks/useBalances.ts create mode 100644 src/pages/Energy/hooks/usePools.ts create mode 100644 src/pages/Energy/hooks/usePrices.ts create mode 100644 src/pages/Energy/hooks/useQueryHooks.ts create mode 100644 src/pages/Energy/hooks/useSwap.ts create mode 100644 src/pages/Energy/hooks/useTx.ts create mode 100644 src/pages/Energy/redux/energy.redux.ts create mode 100644 src/pages/Energy/redux/utils.ts create mode 100644 src/pages/Energy/types/EnergyPackages.ts create mode 100644 src/pages/Energy/types/swap.ts create mode 100644 src/pages/Energy/types/token.ts create mode 100644 src/pages/Energy/ui/Layout/Layout.tsx create mode 100644 src/pages/Energy/ui/pages/BuyPackages/ActionBar.tsx create mode 100644 src/pages/Energy/ui/pages/BuyPackages/BuyPackages.tsx create mode 100644 src/pages/Energy/ui/pages/BuyPackages/components/StatusIbc/StatusIbc.tsx create mode 100644 src/pages/Energy/ui/pages/Main/Main.tsx create mode 100644 src/pages/Energy/ui/pages/SelectPackages/SelectPackages.ts create mode 100644 src/pages/Energy/utils/assets.ts create mode 100644 src/pages/Energy/utils/pool.ts create mode 100644 src/pages/Energy/utils/swap.ts create mode 100644 src/pages/Energy/utils/tokenBuy.ts create mode 100644 src/pages/Energy/utils/utils.ts diff --git a/package.json b/package.json index 549b4be36..031153fac 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@babel/preset-env": "7.20.2", "@babel/preset-react": "7.18.6", "@babel/preset-typescript": "^7.21.0", + "@chain-registry/osmosis": "^1.63.9", "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", "@graphql-codegen/cli": "^5.0.2", @@ -43,6 +44,8 @@ "@graphql-codegen/typescript-react-apollo": "^4.3.0", "@keplr-wallet/types": "^0.11.52", "@milkdown/kit": "^7.5.0", + "@osmonauts/math": "^1.7.0", + "@osmonauts/utils": "^1.17.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@rjsf/core": "^3.2.1", "@storybook/addon-essentials": "^7.2.3", @@ -68,6 +71,7 @@ "babel-loader": "9.1.2", "babel-plugin-root-import": "^6.6.0", "browserify-zlib": "^0.2.0", + "chain-registry": "^1.67.0", "clean-webpack-plugin": "^4.0.0", "compression-webpack-plugin": "^6.1.1", "constants-browserify": "^1.0.0", @@ -99,6 +103,7 @@ "mini-css-extract-plugin": "^2.6.1", "ncp": "^2.0.0", "os-browserify": "^0.3.0", + "osmojs": "^16.14.0", "path-browserify": "^1.0.1", "postcss-loader": "^7.0.2", "postcss-media-minmax": "^5.0.0", diff --git a/src/features/ibc-history/historyContext.tsx b/src/features/ibc-history/historyContext.tsx index 2c50aeb9a..48e91a39c 100644 --- a/src/features/ibc-history/historyContext.tsx +++ b/src/features/ibc-history/historyContext.tsx @@ -34,6 +34,7 @@ type HistoryContext = { ) => void; useGetHistoriesItems: () => Option>; updateStatusByTxHash: (txHash: string, status: StatusTx) => void; + getItemByTxHash: (txHash: string) => Promise; traceHistoryStatus: (item: HistoriesItem) => Promise; }; @@ -45,6 +46,7 @@ const valueContext = { useGetHistoriesItems: () => {}, updateStatusByTxHash: () => {}, traceHistoryStatus: () => {}, + getItemByTxHash: () => {}, }; export const HistoryContext = React.createContext(valueContext); @@ -55,15 +57,6 @@ export const useIbcHistory = () => { return context; }; -const historiesItemsByAddress = (addressActive: AccountValue | null) => { - if (addressActive) { - return dbIbcHistory.historiesItems - .where({ address: addressActive.bech32 }) - .toArray(); - } - return []; -}; - type UncommitedTx = { txHash: string; address: string; @@ -82,7 +75,7 @@ function HistoryContextProvider({ children }: { children: React.ReactNode }) { useState>(undefined); const { defaultAccount } = useAppSelector((state: RootState) => state.pocket); const [update, setUpdate] = useState(0); - const addressActive = defaultAccount.account?.cyber || undefined; + const addressActive = defaultAccount.account?.cyber || undefined; function getBlockSubscriber(chainId: string): PollingStatusSubscription { if (!blockSubscriberMap.has(chainId)) { @@ -198,7 +191,7 @@ function HistoryContextProvider({ children }: { children: React.ReactNode }) { timeoutUnsubscriber(); } - txTracer.close(); + txTracer.close(); if (result) { return StatusTx.COMPLETE; @@ -234,15 +227,22 @@ function HistoryContextProvider({ children }: { children: React.ReactNode }) { getItem(); }, [addressActive, update]); + const getItemByTxHash = async (txHash: string) => { + return dbIbcHistory.historiesItems + .where({ + txHash, + }) + .toArray(); + }; + const pingTxsIbc = async ( cliet: SigningStargateClient | SigningCyberClient, uncommitedTx: UncommitedTx ) => { const ping = async () => { const response = await cliet.getTx(uncommitedTx.txHash); - if (response) { - const result = parseRawLog(response.rawLog); - const dataFromEvent = parseEvents(result); + if (response && response.events) { + const dataFromEvent = parseEvents(response.events); if (dataFromEvent) { const itemHistories = { ...uncommitedTx, ...dataFromEvent }; addHistoriesItem({ @@ -285,6 +285,7 @@ function HistoryContextProvider({ children }: { children: React.ReactNode }) { useGetHistoriesItems, updateStatusByTxHash, traceHistoryStatus, + getItemByTxHash, }} > {children} diff --git a/src/features/ibc-history/useGetStatus.tsx b/src/features/ibc-history/useGetStatus.tsx index 7ab3d860f..01d4532e7 100644 --- a/src/features/ibc-history/useGetStatus.tsx +++ b/src/features/ibc-history/useGetStatus.tsx @@ -6,10 +6,12 @@ function* toGenerator(p: Promise) { return (yield p) as R; } -function useGetStatus(item: HistoriesItem) { +function useGetStatus(item?: HistoriesItem) { const { traceHistoryStatus, updateStatusByTxHash } = useIbcHistory(); - const [status, setStatus] = useState(item.status); + const [status, setStatus] = useState( + item ? item.status : StatusTx.PENDING + ); // eslint-disable-next-line react-hooks/exhaustive-deps function* tryUpdateHistoryStatus(item: HistoriesItem) { @@ -27,6 +29,9 @@ function useGetStatus(item: HistoriesItem) { } useEffect(() => { + if (!item) { + return; + } const getValue = async () => { const gen = await helper(tryUpdateHistoryStatus(item)); diff --git a/src/features/ibc-history/utils.ts b/src/features/ibc-history/utils.ts index d19f6bf6c..21d4d675d 100644 --- a/src/features/ibc-history/utils.ts +++ b/src/features/ibc-history/utils.ts @@ -1,54 +1,53 @@ -const parseEvents = (rawLog: readonly Log[]) => { +import { Event } from '@cosmjs/stargate'; + +const parseEvents = (events: readonly Event[]) => { try { - if (rawLog && Object.keys(rawLog).length > 0) { - const { events } = rawLog[0]; - if (events) { - // eslint-disable-next-line no-restricted-syntax - for (const event of events) { - if (event.type === 'send_packet') { - const { attributes } = event; - const sourceChannelAttr = attributes.find( - (attr) => attr.key === 'packet_src_channel' - ); - const sourceChannelValue = sourceChannelAttr - ? sourceChannelAttr.value - : undefined; - const destChannelAttr = attributes.find( - (attr) => attr.key === 'packet_dst_channel' - ); - const destChannelValue = destChannelAttr - ? destChannelAttr.value - : undefined; - const sequenceAttr = attributes.find( - (attr) => attr.key === 'packet_sequence' - ); - const sequence = sequenceAttr ? sequenceAttr.value : undefined; - const timeoutHeightAttr = attributes.find( - (attr) => attr.key === 'packet_timeout_height' - ); - const timeoutHeight = timeoutHeightAttr - ? timeoutHeightAttr.value - : undefined; - const timeoutTimestampAttr = attributes.find( - (attr) => attr.key === 'packet_timeout_timestamp' - ); - const timeoutTimestamp = timeoutTimestampAttr - ? timeoutTimestampAttr.value - : undefined; - if (sequence && destChannelValue && sourceChannelValue) { - return { - destChannelId: destChannelValue, - sourceChannelId: sourceChannelValue, - sequence, - timeoutHeight, - timeoutTimestamp, - }; - } - } + if (events && !events.length) { + return undefined; + } + // eslint-disable-next-line no-restricted-syntax + for (const event of events) { + if (event.type === 'send_packet') { + const { attributes } = event; + const sourceChannelAttr = attributes.find( + (attr) => attr.key === 'packet_src_channel' + ); + const sourceChannelValue = sourceChannelAttr + ? sourceChannelAttr.value + : undefined; + const destChannelAttr = attributes.find( + (attr) => attr.key === 'packet_dst_channel' + ); + const destChannelValue = destChannelAttr + ? destChannelAttr.value + : undefined; + const sequenceAttr = attributes.find( + (attr) => attr.key === 'packet_sequence' + ); + const sequence = sequenceAttr ? sequenceAttr.value : undefined; + const timeoutHeightAttr = attributes.find( + (attr) => attr.key === 'packet_timeout_height' + ); + const timeoutHeight = timeoutHeightAttr + ? timeoutHeightAttr.value + : undefined; + const timeoutTimestampAttr = attributes.find( + (attr) => attr.key === 'packet_timeout_timestamp' + ); + const timeoutTimestamp = timeoutTimestampAttr + ? timeoutTimestampAttr.value + : undefined; + if (sequence && destChannelValue && sourceChannelValue) { + return { + destChannelId: destChannelValue, + sourceChannelId: sourceChannelValue, + sequence, + timeoutHeight, + timeoutTimestamp, + }; } } } - return null; } catch (e) { console.debug('error parseLog', e); return null; diff --git a/src/pages/Energy/Energy.tsx b/src/pages/Energy/Energy.tsx index e69de29bb..a5a751080 100644 --- a/src/pages/Energy/Energy.tsx +++ b/src/pages/Energy/Energy.tsx @@ -0,0 +1,33 @@ +import { Route, Routes } from 'react-router-dom'; +import HistoryContextProvider from 'src/features/ibc-history/historyContext'; +import EnergyMain from './ui/pages/Main/Main'; +import OsmosisRpcProvider from './context/OsmosisRpcProvider'; +import EnergyProvider from './context/Energy.context'; +import OsmosisSignerProvider from './context/OsmosisSignerProvider'; +import Layout from './ui/Layout/Layout'; + +function EnergyRouter() { + return ( + + }> + } /> + + + ); +} + +function Energy() { + return ( + + + + + + + + + + ); +} + +export default Energy; diff --git a/src/pages/Energy/constants.ts b/src/pages/Energy/constants.ts new file mode 100644 index 000000000..710bdfa2d --- /dev/null +++ b/src/pages/Energy/constants.ts @@ -0,0 +1,11 @@ +import networkList from 'src/utils/networkListIbc'; + +export const Slippages = [1, 2.5, 3, 5]; + +export const EnergyPackages = ['1', '100', '1000']; + +export const sellTokensSymbol = ['OSMO', 'ATOM']; + +export const CHAIN_ID_OSMO = networkList['osmosis-1'].chainId; + +export const RPC_OSMO = networkList['osmosis-1'].rpc; diff --git a/src/pages/Energy/context/Energy.context.tsx b/src/pages/Energy/context/Energy.context.tsx new file mode 100644 index 000000000..01f182001 --- /dev/null +++ b/src/pages/Energy/context/Energy.context.tsx @@ -0,0 +1,53 @@ +import React, { useCallback, useContext, useMemo } from 'react'; +import { CoinDenom, PriceHash } from '@osmonauts/math/types'; +import { Coin } from '@cosmjs/stargate'; +import useBalances from '../hooks/useBalances'; +import useSwap from '../hooks/useSwap'; +import { EnergyPackageSwapRoutes } from '../types/EnergyPackages'; +import { useOsmosisSign } from './OsmosisSignerProvider'; + +const EnergyContext = React.createContext<{ + prices: PriceHash; + balances: { + assets: Coin[]; + hash: Record; + }; + energyPackageSwapRoutes?: EnergyPackageSwapRoutes[]; + refetch: () => void; +}>({ + prices: {}, + balances: { assets: [], hash: {} }, + energyPackageSwapRoutes: [], + refetch: () => {}, +}); + +export function useEnergy() { + return useContext(EnergyContext); +} + +function EnergyProvider({ children }: { children: React.ReactNode }) { + const { address } = useOsmosisSign(); + const { assets, hash, refetch: refetchBal } = useBalances(address); + const { energyPackageSwapRoutes, refetchSwapRoute, prices } = useSwap(); + + const refetchFnc = useCallback(() => { + refetchBal(); + refetchSwapRoute(); + }, [refetchBal, refetchSwapRoute]); + + const value = useMemo( + () => ({ + prices, + balances: { assets, hash }, + energyPackageSwapRoutes, + refetch: refetchFnc, + }), + [prices, assets, hash, energyPackageSwapRoutes, refetchFnc] + ); + + return ( + {children} + ); +} + +export default EnergyProvider; diff --git a/src/pages/Energy/context/OsmosisRpcProvider.tsx b/src/pages/Energy/context/OsmosisRpcProvider.tsx new file mode 100644 index 000000000..7999c787b --- /dev/null +++ b/src/pages/Energy/context/OsmosisRpcProvider.tsx @@ -0,0 +1,42 @@ +import React, { useContext } from 'react'; +import { osmosis } from 'osmojs'; +import { useQuery } from '@tanstack/react-query'; +import { Option } from 'src/types'; +import { CHAIN_ID_OSMO, RPC_OSMO } from '../constants'; + +const { createRPCQueryClient } = osmosis.ClientFactory; + +type Client = Awaited>; + +const QueryClientContext = React.createContext>(undefined); + +export function useOsmosisRpc() { + return useContext(QueryClientContext); +} + +function OsmosisRpcProvider({ children }: { children: React.ReactNode }) { + const { data, error, isFetching } = useQuery({ + queryKey: [CHAIN_ID_OSMO, 'connect'], + queryFn: async () => { + return createRPCQueryClient({ + rpcEndpoint: RPC_OSMO, + }); + }, + }); + + if (isFetching) { + return null; + } + + if (error) { + console.error('Error queryClient connect: ', error.message); + } + + return ( + + {children} + + ); +} + +export default OsmosisRpcProvider; diff --git a/src/pages/Energy/context/OsmosisSignerProvider.tsx b/src/pages/Energy/context/OsmosisSignerProvider.tsx new file mode 100644 index 000000000..08d0ce00c --- /dev/null +++ b/src/pages/Energy/context/OsmosisSignerProvider.tsx @@ -0,0 +1,78 @@ +import { SigningStargateClient } from '@cosmjs/stargate'; +import React, { useContext, useEffect, useMemo, useState } from 'react'; +import { getKeplr } from 'src/utils/keplrUtils'; +import { OfflineSigner } from '@cosmjs/proto-signing'; +import { getSigningOsmosisClient } from 'osmojs'; +import { Option } from 'src/types'; +import { useAppSelector } from 'src/redux/hooks'; +import { CHAIN_ID_OSMO, RPC_OSMO } from '../constants'; + +const OsmosisSignerContext = React.createContext<{ + address?: string; + signingClient?: SigningStargateClient; +}>({ + address: undefined, + signingClient: undefined, +}); + +export function useOsmosisSign() { + const signingClient = useContext(OsmosisSignerContext); + return signingClient; +} + +function OsmosisSignerProvider({ children }: { children: React.ReactNode }) { + const { defaultAccount } = useAppSelector((state) => state.pocket); + const [address, setAddress] = useState>(undefined); + const [signingClient, setSigningClient] = + useState>(undefined); + + async function initSigner() { + const windowKeplr = await getKeplr(); + + if (!windowKeplr) { + return; + } + + await windowKeplr.enable(CHAIN_ID_OSMO); + + const offlineSigner: OfflineSigner = await windowKeplr.getOfflineSignerAuto( + CHAIN_ID_OSMO + ); + + const [{ address }] = await offlineSigner.getAccounts(); + + setAddress(address); + + const stargateClient = await getSigningOsmosisClient({ + rpcEndpoint: RPC_OSMO, + signer: offlineSigner, + }); + + setSigningClient(stargateClient); + } + + useEffect(() => { + (async () => { + const windowKeplr = await getKeplr(); + if (windowKeplr) { + initSigner(); + } + })(); + }, [defaultAccount]); + + const value = useMemo( + () => ({ + address, + signingClient, + }), + [address, signingClient] + ); + + return ( + + {children} + + ); +} + +export default OsmosisSignerProvider; diff --git a/src/pages/Energy/hooks/txs/useBuyPackage.ts b/src/pages/Energy/hooks/txs/useBuyPackage.ts new file mode 100644 index 000000000..e63d16ec2 --- /dev/null +++ b/src/pages/Energy/hooks/txs/useBuyPackage.ts @@ -0,0 +1,9 @@ +import useTx from '../useTx'; + +function useBuyPackage() { + const { tx } = useTx(); + + return null; +} + +export default useBuyPackage; diff --git a/src/pages/Energy/hooks/txs/useIbc.ts b/src/pages/Energy/hooks/txs/useIbc.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/Energy/hooks/useBalances.ts b/src/pages/Energy/hooks/useBalances.ts new file mode 100644 index 000000000..46264b3fa --- /dev/null +++ b/src/pages/Energy/hooks/useBalances.ts @@ -0,0 +1,32 @@ +import { useQuery } from '@tanstack/react-query'; +import { Coin } from '@cosmjs/stargate'; +import { useOsmosisRpc } from '../context/OsmosisRpcProvider'; + +function useBalances(address?: string) { + const rpc = useOsmosisRpc(); + + const { data, refetch } = useQuery( + ['osmosis', 'allBalances', address], + async () => { + if (!address) { + return undefined; + } + return rpc?.cosmos.bank.v1beta1.allBalances({ + address, + }); + }, + { enabled: Boolean(rpc && address) } + ); + + const all = data?.balances || []; + const hash = (all.reduce( + (acc, coin) => ({ ...acc, [coin.denom]: coin }), + {} + ) || {}) as Record; + const pools = all.filter((coin) => coin.denom.startsWith('gamm')) || []; + const assets = all.filter((coin) => !coin.denom.startsWith('gamm')) || []; + + return { all, hash, pools, assets, refetch }; +} + +export default useBalances; diff --git a/src/pages/Energy/hooks/usePools.ts b/src/pages/Energy/hooks/usePools.ts new file mode 100644 index 000000000..8b69c2c31 --- /dev/null +++ b/src/pages/Energy/hooks/usePools.ts @@ -0,0 +1,41 @@ +import { useQuery } from '@tanstack/react-query'; +import { Pool } from 'osmojs/osmosis/gamm/v1beta1/balancerPool'; +import { useOsmosisRpc } from '../context/OsmosisRpcProvider'; +import { paginate } from '../utils/utils'; +import { Osmosis } from '../utils/assets'; + +export type PoolList = Pool[] & { + priced: Pool[]; +}; + +function usePools() { + const rpc = useOsmosisRpc(); + const { data, refetch } = useQuery( + ['osmosis', 'pools'], + async () => { + return rpc?.osmosis.poolmanager.v1beta1.allPools({ + pagination: paginate(5000n), + }); + }, + { enabled: Boolean(rpc) } + ); + + // rpc?.osmosis.poolmanager.v1beta1.estimateSinglePoolSwapExactAmountIn(); + + const all: Pool[] = data?.pools || []; + const map = all.reduce( + (map, pool) => map.set(pool.id, pool), + new Map() + ); + const freefloat = (all.filter(({ $typeUrl }) => + $typeUrl?.includes('/osmosis.gamm.v1beta1.Pool') + ) || []) as PoolList; + + freefloat.priced = freefloat.filter(({ poolAssets }) => + poolAssets.every(({ token }) => Osmosis.CoinDenomToAsset[token.denom]) + ); + + return { all, map, freefloat: freefloat.priced, refetch }; +} + +export default usePools; diff --git a/src/pages/Energy/hooks/usePrices.ts b/src/pages/Energy/hooks/usePrices.ts new file mode 100644 index 000000000..b8e86bfc0 --- /dev/null +++ b/src/pages/Energy/hooks/usePrices.ts @@ -0,0 +1,38 @@ +import { PriceHash } from '@osmonauts/math/types'; +import { useQuery } from '@tanstack/react-query'; + +const getPriceHash = async () => { + let prices = []; + + try { + const response = await fetch( + 'https://api-osmosis.imperator.co/tokens/v2/all' + ); + if (!response.ok) { + throw Error('Get price error'); + } + prices = await response.json(); + } catch (err) { + console.error(err); + } + + const priceHash = prices.reduce( + (prev: any, cur: { denom: any; price: any }) => ({ + ...prev, + [cur.denom]: cur.price, + }), + {} + ); + + return priceHash; +}; + +function usePrices() { + const { data, refetch } = useQuery(['osmosis', 'priceHash'], async () => { + return getPriceHash() as Promise; + }); + + return { data: data || {}, refetch }; +} + +export default usePrices; diff --git a/src/pages/Energy/hooks/useQueryHooks.ts b/src/pages/Energy/hooks/useQueryHooks.ts new file mode 100644 index 000000000..92f769885 --- /dev/null +++ b/src/pages/Energy/hooks/useQueryHooks.ts @@ -0,0 +1,5 @@ +function useQueryHooks() { + return null; +} + +export default useQueryHooks; diff --git a/src/pages/Energy/hooks/useSwap.ts b/src/pages/Energy/hooks/useSwap.ts new file mode 100644 index 000000000..872e29389 --- /dev/null +++ b/src/pages/Energy/hooks/useSwap.ts @@ -0,0 +1,80 @@ +import { useMemo } from 'react'; +import BigNumber from 'bignumber.js'; +import { useAppSelector } from 'src/redux/hooks'; +import { newCoin, newToken, newTokensRoutes } from '../utils/swap'; +import { + getOsmoAssetByDenom, + isEmptyArray, + symbolToOsmoDenom, +} from '../utils/utils'; +import { EnergyPackages } from '../constants'; +import usePrices from './usePrices'; +import usePools from './usePools'; +import { makePoolPairs } from '../utils/pool'; +import { EnergyPackageSwapRoutes } from '../types/EnergyPackages'; + +function useSwap() { + const { freefloat: pools, refetch: refetchPools } = usePools(); + const { data: prices, refetch: refetchPrice } = usePrices(); + const { tokenSell } = useAppSelector((state) => state.energy); + + const findTokenDenom = getOsmoAssetByDenom( + symbolToOsmoDenom(tokenSell) || '' + ); + + const fromToken = newToken(findTokenDenom); + + const pricesSelectedDenom = prices[fromToken.denom] || 0; + + const energyPackagesByDenom: { [key: string]: string } = + EnergyPackages.reduce( + (acc, item) => ({ + ...acc, + [item]: new BigNumber(item) + .multipliedBy(pricesSelectedDenom) + .toString(), + }), + {} + ); + + const pairs = useMemo(() => { + if (isEmptyArray(pools)) { + return []; + } + + return makePoolPairs(pools, prices, 200); + }, [pools, prices]); + + const energyPackageSwapRoutes = useMemo(() => { + if (!pricesSelectedDenom || isEmptyArray(pairs) || isEmptyArray(pools)) { + return undefined; + } + + const result: EnergyPackageSwapRoutes[] = []; + + Object.keys(energyPackagesByDenom).forEach((key) => { + const item = energyPackagesByDenom[key]; + const swapRoute = newTokensRoutes(item, fromToken, { pairs, pools }); + if (swapRoute) { + result.push({ + keyPackage: key, + tokenIn: newCoin({ denom: fromToken.denom, amount: item }), + swapInfo: swapRoute, + }); + } + }); + + return result; + }, [pricesSelectedDenom, pairs, pools, energyPackagesByDenom, fromToken]); + + const refetchSwapRoute = () => { + refetchPools(); + refetchPrice(); + }; + + console.log('energyPackageSwapRoutes', energyPackageSwapRoutes); + + return { energyPackageSwapRoutes, prices, refetchSwapRoute }; +} + +export default useSwap; diff --git a/src/pages/Energy/hooks/useTx.ts b/src/pages/Energy/hooks/useTx.ts new file mode 100644 index 000000000..9da865580 --- /dev/null +++ b/src/pages/Energy/hooks/useTx.ts @@ -0,0 +1,75 @@ +// eslint-disable-next-line max-classes-per-file +import { estimateOsmoFee } from '@osmonauts/utils'; +import { isDeliverTxSuccess } from '@cosmjs/stargate'; +import { cosmos, DeliverTxResponse } from 'osmojs'; +import { useOsmosisSign } from '../context/OsmosisSignerProvider'; + +type Msg = { + typeUrl: string; + value: { [key: string]: any }; +}; + +class TxError extends Error { + constructor(message = 'Tx Error', options?: ErrorOptions) { + super(message, options); + this.name = 'TxError'; + } +} + +class TxResult { + error?: TxError; + + response?: DeliverTxResponse; + + constructor({ error, response }: Pick) { + this.error = error; + this.response = response; + } + + get errorMsg() { + return this.isOutOfGas + ? `Out of gas. gasWanted: ${this.response?.gasWanted} gasUsed: ${this.response?.gasUsed}` + : this.error?.message || 'Swap Failed'; + } + + get isSuccess() { + return this.response && isDeliverTxSuccess(this.response); + } + + get isOutOfGas() { + return this.response && this.response.gasUsed > this.response.gasWanted; + } +} + +function useTx() { + const { address, signingClient } = useOsmosisSign(); + + async function tx(msgs: Msg[]) { + if (!address || !signingClient) { + return new TxResult({ error: new TxError('Wallet not connected') }); + } + + try { + const txRaw = cosmos.tx.v1beta1.TxRaw; + const fee = await estimateOsmoFee(signingClient, address, [...msgs], ''); + const signed = await signingClient.sign(address, [...msgs], fee, ''); + + if (!signed) { + return new TxResult({ error: new TxError('Invalid transaction') }); + } + + const response: any = await signingClient.broadcastTx( + Uint8Array.from(txRaw.encode(signed).finish()) + ); + return isDeliverTxSuccess(response) + ? new TxResult({ response }) + : new TxResult({ response, error: new TxError(response.rawLog) }); + } catch (e: any) { + return new TxResult({ error: new TxError(e.message || 'Tx Error') }); + } + } + + return { tx }; +} + +export default useTx; diff --git a/src/pages/Energy/redux/energy.redux.ts b/src/pages/Energy/redux/energy.redux.ts new file mode 100644 index 000000000..61e53d181 --- /dev/null +++ b/src/pages/Energy/redux/energy.redux.ts @@ -0,0 +1,96 @@ +import { PayloadAction, createSlice } from '@reduxjs/toolkit'; +import { Coin } from '@cosmjs/stargate'; +import { StatusTx } from 'src/features/ibc-history/HistoriesItem'; +import { StatusOrder } from './utils'; + +type SliceState = { + statusOrder: StatusOrder; + selectPlan?: { keyPackage: string; tokenIn: Coin }; + tokenSell: 'OSMO' | 'ATOM'; + swapResult?: { + swapTx: string; + tokens: Coin[]; + }; + ibcResult?: { + ibcHash: string; + status: StatusTx; + }; +}; + +const initStateTokenSell = 'OSMO'; + +const keyEnergyStateApp = 'energy-state-app'; + +const stateGetItem = localStorage.getItem(keyEnergyStateApp); + +const poolsInitState = stateGetItem + ? (JSON.parse(stateGetItem) as SliceState) + : undefined; + +const initialState: SliceState = { + statusOrder: poolsInitState + ? poolsInitState.statusOrder + : StatusOrder.SELECT_PACK, + selectPlan: poolsInitState?.selectPlan, + tokenSell: poolsInitState ? poolsInitState.tokenSell : initStateTokenSell, + swapResult: poolsInitState?.swapResult, + ibcResult: poolsInitState?.ibcResult, +}; + +function saveToLocalStorage(state: SliceState) { + localStorage.setItem(keyEnergyStateApp, JSON.stringify(state)); +} + +const slice = createSlice({ + name: 'energyPackages', + initialState, + reducers: { + setStatusOrder: (state, { payload }: PayloadAction) => { + state.statusOrder = payload; + saveToLocalStorage(state); + }, + setSelectPlan: ( + state, + { payload }: PayloadAction + ) => { + state.selectPlan = payload; + saveToLocalStorage(state); + }, + setTokenSell: ( + state, + { payload }: PayloadAction + ) => { + state.tokenSell = payload; + saveToLocalStorage(state); + }, + setSwapResult: ( + state, + { payload }: PayloadAction + ) => { + state.swapResult = payload; + saveToLocalStorage(state); + }, + setIbcResult: ( + state, + { payload }: PayloadAction + ) => { + state.ibcResult = payload; + saveToLocalStorage(state); + }, + resetEnergy() { + localStorage.removeItem(keyEnergyStateApp); + return initialState; + }, + }, +}); + +export const { + setStatusOrder, + setSelectPlan, + setSwapResult, + setTokenSell, + setIbcResult, + resetEnergy, +} = slice.actions; + +export default slice.reducer; diff --git a/src/pages/Energy/redux/utils.ts b/src/pages/Energy/redux/utils.ts new file mode 100644 index 000000000..25865933f --- /dev/null +++ b/src/pages/Energy/redux/utils.ts @@ -0,0 +1,6 @@ +export enum StatusOrder { + SELECT_PACK = 'select_pack', + SWAP = 'swap', + SEND_IBC = 'send_ibc', + STATUS_IBC = 'status_ibc', +} diff --git a/src/pages/Energy/types/EnergyPackages.ts b/src/pages/Energy/types/EnergyPackages.ts new file mode 100644 index 000000000..f47d6ddc2 --- /dev/null +++ b/src/pages/Energy/types/EnergyPackages.ts @@ -0,0 +1,11 @@ +import { Coin } from '@cosmjs/stargate'; +import { SwapTokensWithRoutes } from './swap'; + +// eslint-disable-next-line import/no-unused-modules, import/prefer-default-export +export type EnergyPackagesKey = '10' | '100' | '1000'; + +export type EnergyPackageSwapRoutes = { + keyPackage: string; + tokenIn: Coin; + swapInfo: SwapTokensWithRoutes[]; +}; diff --git a/src/pages/Energy/types/swap.ts b/src/pages/Energy/types/swap.ts new file mode 100644 index 000000000..642320cf3 --- /dev/null +++ b/src/pages/Energy/types/swap.ts @@ -0,0 +1,17 @@ +import { Coin } from '@cosmjs/stargate'; +import { SwapAmountInRoute } from 'osmojs/osmosis/poolmanager/v1beta1/swap_route'; +import { Token } from './token'; + +export type Swap = { + to: Token; + from: Token; + slippage: number; +}; + +export type SwapTokensWithRoutes = { + swap: { + tokenIn: Coin; + tokenOut: Coin; + }; + routes: SwapAmountInRoute[]; +}; diff --git a/src/pages/Energy/types/token.ts b/src/pages/Energy/types/token.ts new file mode 100644 index 000000000..e0fa53a2e --- /dev/null +++ b/src/pages/Energy/types/token.ts @@ -0,0 +1,21 @@ +import { Coin } from '@cosmjs/stargate'; +import { CoinDenom } from '@osmonauts/math/types'; +import { Asset, Chain } from '@chain-registry/types'; + +export type Token = { + logo?: string; + denom: string; + asset?: Asset; + chain?: Chain; + price?: number; + symbol?: string; + amount?: string; + value?: string; + $value?: string; + balance?: Coin; +}; + +export type TokenList = Token[] & { + rest: Token[]; + hash: Record; +}; diff --git a/src/pages/Energy/ui/Layout/Layout.tsx b/src/pages/Energy/ui/Layout/Layout.tsx new file mode 100644 index 000000000..a11415798 --- /dev/null +++ b/src/pages/Energy/ui/Layout/Layout.tsx @@ -0,0 +1,20 @@ +import { Outlet } from 'react-router-dom'; +import { Helmet } from 'react-helmet'; +import { MainContainer } from 'src/components'; +// import styles from './Layout.module.scss'; + +function Layout() { + return ( + +
+ + energy | cyb + + + +
+
+ ); +} + +export default Layout; diff --git a/src/pages/Energy/ui/pages/BuyPackages/ActionBar.tsx b/src/pages/Energy/ui/pages/BuyPackages/ActionBar.tsx new file mode 100644 index 000000000..e114251dc --- /dev/null +++ b/src/pages/Energy/ui/pages/BuyPackages/ActionBar.tsx @@ -0,0 +1,225 @@ +import { Coin, coin } from '@cosmjs/stargate'; +import { DeliverTxResponse, ibc } from 'osmojs'; +import { useState } from 'react'; +import { ActionBar, Button } from 'src/components'; +import { useEnergy } from 'src/pages/Energy/context/Energy.context'; +import { useOsmosisSign } from 'src/pages/Energy/context/OsmosisSignerProvider'; +import useTx from 'src/pages/Energy/hooks/useTx'; +import { newSwapMessage } from 'src/pages/Energy/utils/swap'; +import { fromBech32 } from 'src/utils/utils'; +import defaultNetworks from 'src/constants/defaultNetworks'; +import { useHub } from 'src/contexts/hub'; +import { CHAIN_ID_OSMO } from 'src/pages/Energy/constants'; +import BigNumber from 'bignumber.js'; +import { useIbcHistory } from 'src/features/ibc-history/historyContext'; +import { getNowUtcNumber } from 'src/utils/date'; +import { + resetEnergy, + setIbcResult, + setStatusOrder, + setSwapResult, +} from 'src/pages/Energy/redux/energy.redux'; +import { StatusOrder } from 'src/pages/Energy/redux/utils'; +import { useAppDispatch, useAppSelector } from 'src/redux/hooks'; +import { StatusTx } from 'src/features/ibc-history/HistoriesItem'; +import { getOsmoAssetByDenom } from 'src/pages/Energy/utils/utils'; + +const coinFunc = (amount: string, denom: string): Coin => { + return { denom, amount: new BigNumber(amount).toString(10) }; +}; + +function newTokenSwapped(res: DeliverTxResponse) { + const tokenSwapped = res.events.find((item) => item.type === 'token_swapped'); + + const tokensOut = tokenSwapped?.attributes.find( + (item) => item.key === 'tokens_out' + ); + + if (!tokensOut) { + return undefined; + } + + const value = tokensOut.value.split('ibc/'); + + return coin(value[0], `ibc/${value[1]}`); +} + +function ActionBarContainer() { + const { refetch, energyPackageSwapRoutes } = useEnergy(); + const { address, signingClient } = useOsmosisSign(); + const { pingTxsIbc } = useIbcHistory(); + const { channels } = useHub(); + const dispatch = useAppDispatch(); + const { swapResult, selectPlan, statusOrder, ibcResult } = useAppSelector( + (state) => state.energy + ); + + const findChannels = channels && channels[CHAIN_ID_OSMO]; + + const selectPackage = energyPackageSwapRoutes?.find( + (item) => item.keyPackage === selectPlan?.keyPackage + ); + + const { tx } = useTx(); + + const [isSwapping, setIsSwapping] = useState(false); + const [isIbcSending, setIsIbcSending] = useState(false); + + const onIbcTxs = async () => { + if (!address || !signingClient || !findChannels) { + return; + } + + if (!swapResult) { + return; + } + + setIsIbcSending(true); + + const { transfer } = + ibc.applications.transfer.v1.MessageComposer.withTypeUrl; + + const stamp = Date.now(); + const timeoutInNanos = (stamp + 1.2e6) * 1e6; + const counterpartyAccount = fromBech32( + address, + defaultNetworks.bostrom.BECH32_PREFIX + ); + + const ibcMsg = swapResult.tokens.map((item) => { + return transfer({ + sourcePort: 'transfer', + sourceChannel: findChannels.destination_channel_id, + sender: address, + token: item, + receiver: counterpartyAccount, + timeoutTimestamp: BigInt(timeoutInNanos), + timeoutHeight: undefined, + memo: '', + }); + }); + + console.log('ibcMsg', ibcMsg); + + const res = await tx([...ibcMsg]); + + setIsIbcSending(false); + + console.log('res', res); + + if (res.error) { + console.log('{res.errorMsg}', res.errorMsg); + } else if (res.isSuccess) { + // ibcMsg.forEach((item) => { + const { denom, amount } = swapResult.tokens[0]; + const { transactionHash } = res.response; + const tokenSelect = getOsmoAssetByDenom(denom); + const aliases = tokenSelect?.denom_units[0].aliases; + const transferData = { + txHash: transactionHash, + address: counterpartyAccount, + sourceChainId: findChannels.destination_chain_id, + destChainId: findChannels.source_chain_id, + sender: address, + recipient: counterpartyAccount, + createdAt: getNowUtcNumber(), + amount: coinFunc(amount, aliases ? aliases[0] : denom), + }; + + pingTxsIbc(signingClient, transferData); + + dispatch( + setIbcResult({ ibcHash: transactionHash, status: StatusTx.PENDING }) + ); + + dispatch(setStatusOrder(StatusOrder.STATUS_IBC)); + // }); + + console.log('IBC Send successful'); + + refetch(); + } + }; + + const onBuyPackage = async () => { + if (!address || !signingClient) { + console.error('stargateClient undefined or address undefined.'); + return; + } + + if (!selectPackage) { + console.log('energyPackageSwapRoutes undefined'); + return; + } + console.log('address', address); + + setIsSwapping(true); + + const msgIn = newSwapMessage(selectPackage.swapInfo, address); + console.log('msgIn', msgIn); + + const res = await tx([...msgIn]); + setIsSwapping(false); + + console.log('res', res); + + if (res.error) { + console.log('{res.errorMsg}', res.errorMsg); + } else if (res.isSuccess) { + console.log('Swap successful'); + if (res.response) { + const tokenSwapped = newTokenSwapped(res.response); + console.log('tokenSwapped', tokenSwapped); + + if (!tokenSwapped) { + return; + } + dispatch( + setSwapResult({ + swapTx: res.response.transactionHash, + tokens: [tokenSwapped], + }) + ); + dispatch(setStatusOrder(StatusOrder.SEND_IBC)); + } + refetch(); + } + }; + + console.log('ibcResult', ibcResult); + + return ( + + {(statusOrder === StatusOrder.SELECT_PACK || + statusOrder === StatusOrder.SWAP) && ( +