├── src ├── styles.scss ├── assets │ ├── .gitkeep │ ├── images │ │ ├── bnb.png │ │ ├── eth.png │ │ ├── usdt.png │ │ ├── empty-token.png │ │ ├── wallet_link.png │ │ ├── image-missing.png │ │ ├── reef │ │ │ ├── reef-card.jpg │ │ │ ├── reef-token.jpg │ │ │ ├── reef-token.png │ │ │ └── HeroSectionBG.png │ │ ├── tokens │ │ │ ├── dai.svg │ │ │ ├── usdt.svg │ │ │ ├── bal.svg │ │ │ ├── comp.svg │ │ │ ├── yfi.svg │ │ │ └── usdc.svg │ │ └── binance_icon_logo.svg │ ├── icons │ │ ├── favicon-32x32.png │ │ ├── cryptocoins │ │ │ └── fonts │ │ │ │ ├── cryptocoins.ttf │ │ │ │ ├── cryptocoins.woff │ │ │ │ └── cryptocoins.woff2 │ │ ├── line-awesome │ │ │ └── fonts │ │ │ │ ├── la-brands-400.eot │ │ │ │ ├── la-brands-400.ttf │ │ │ │ ├── la-solid-900.eot │ │ │ │ ├── la-solid-900.ttf │ │ │ │ ├── la-solid-900.woff │ │ │ │ ├── line-awesome.eot │ │ │ │ ├── line-awesome.ttf │ │ │ │ ├── line-awesome.woff │ │ │ │ ├── la-brands-400.woff │ │ │ │ ├── la-brands-400.woff2 │ │ │ │ ├── la-regular-400.eot │ │ │ │ ├── la-regular-400.ttf │ │ │ │ ├── la-regular-400.woff │ │ │ │ ├── la-solid-900.woff2 │ │ │ │ ├── line-awesome.woff2 │ │ │ │ └── la-regular-400.woff2 │ │ ├── font-awesome │ │ │ └── fonts │ │ │ │ ├── fontawesome-webfont3e6e.eot │ │ │ │ ├── fontawesome-webfont3e6e.ttf │ │ │ │ ├── fontawesome-webfontd41d.eot │ │ │ │ ├── fontawesome-webfont3e6e.woff │ │ │ │ └── fontawesome-webfont3e6e.woff2 │ │ └── material-design-iconic-font │ │ │ └── fonts │ │ │ ├── materialdesignicons-webfont.eot │ │ │ ├── materialdesignicons-webfont.ttf │ │ │ ├── materialdesignicons-webfont.woff │ │ │ └── materialdesignicons-webfont.woff2 │ ├── scripts │ │ ├── casino_hand-webfont.eot │ │ ├── casino_hand-webfont.ttf │ │ └── casino_hand-webfont.woff │ ├── scss │ │ ├── _base.scss │ │ └── partials │ │ │ └── _variables.scss │ └── providers.ts ├── app │ ├── modules │ │ ├── reef │ │ │ ├── pages │ │ │ │ ├── bond │ │ │ │ │ └── bond.page.scss │ │ │ │ ├── bonds │ │ │ │ │ ├── bonds.page.scss │ │ │ │ │ └── bonds.page.ts │ │ │ │ ├── farms │ │ │ │ │ ├── farms.page.scss │ │ │ │ │ └── farms.page.spec.ts │ │ │ │ ├── pools │ │ │ │ │ ├── pools.page.scss │ │ │ │ │ ├── pools.page.spec.ts │ │ │ │ │ └── pools.page.ts │ │ │ │ ├── reef │ │ │ │ │ ├── reef.page.scss │ │ │ │ │ ├── reef.page.spec.ts │ │ │ │ │ └── reef.page.html │ │ │ │ ├── reef-menu │ │ │ │ │ ├── reef-menu.page.scss │ │ │ │ │ ├── reef-menu.page.spec.ts │ │ │ │ │ └── reef-menu.page.ts │ │ │ │ ├── farm │ │ │ │ │ ├── farm.page.scss │ │ │ │ │ └── farm.page.spec.ts │ │ │ │ ├── pool │ │ │ │ │ ├── pool.page.scss │ │ │ │ │ └── pool.page.spec.ts │ │ │ │ ├── card │ │ │ │ │ └── card.page.scss │ │ │ │ └── about │ │ │ │ │ ├── about.page.ts │ │ │ │ │ └── about.page.scss │ │ │ ├── components │ │ │ │ ├── stake-reef │ │ │ │ │ ├── stake-reef.component.scss │ │ │ │ │ ├── stake-reef.component.ts │ │ │ │ │ ├── stake-reef.component.spec.ts │ │ │ │ │ └── stake-reef.component.html │ │ │ │ ├── reef-historic-price │ │ │ │ │ ├── reef-historic-price.component.scss │ │ │ │ │ ├── reef-historic-price.component.spec.ts │ │ │ │ │ ├── reef-historic-price.component.ts │ │ │ │ │ └── reef-historic-price.component.html │ │ │ │ └── buy-reef │ │ │ │ │ ├── buy-reef.component.scss │ │ │ │ │ └── buy-reef.component.spec.ts │ │ │ ├── reef.service.ts │ │ │ └── reef.service.spec.ts │ │ ├── vaults │ │ │ ├── pages │ │ │ │ └── vaults │ │ │ │ │ ├── vaults.page.scss │ │ │ │ │ ├── vaults.page.spec.ts │ │ │ │ │ └── vaults.page.html │ │ │ ├── components │ │ │ │ ├── vaults-list │ │ │ │ │ ├── vaults-list.component.scss │ │ │ │ │ ├── vaults-list.component.ts │ │ │ │ │ ├── vaults-list.component.spec.ts │ │ │ │ │ └── vaults-list.component.html │ │ │ │ ├── diversify-vaults │ │ │ │ │ ├── diversify-vaults.component.scss │ │ │ │ │ ├── diversify-vaults.component.spec.ts │ │ │ │ │ └── diversify-vaults.component.ts │ │ │ │ └── vaults-roi-chart │ │ │ │ │ ├── vaults-roi-chart.component.scss │ │ │ │ │ ├── vaults-roi-chart.component.spec.ts │ │ │ │ │ ├── vaults-roi-chart.component.ts │ │ │ │ │ └── vaults-roi-chart.component.html │ │ │ ├── vaults-routing.module.ts │ │ │ └── vaults.module.ts │ │ ├── baskets │ │ │ ├── pages │ │ │ │ ├── baskets │ │ │ │ │ ├── baskets.page.scss │ │ │ │ │ └── baskets.page.spec.ts │ │ │ │ ├── basket-types │ │ │ │ │ ├── basket-types.page.scss │ │ │ │ │ ├── basket-types.page.ts │ │ │ │ │ └── basket-types.page.spec.ts │ │ │ │ ├── custom-basket │ │ │ │ │ ├── custom-basket.page.scss │ │ │ │ │ └── custom-basket.page.spec.ts │ │ │ │ └── create-basket │ │ │ │ │ ├── create-basket.page.scss │ │ │ │ │ ├── create-basket.page.spec.ts │ │ │ │ │ └── create-basket.page.html │ │ │ ├── components │ │ │ │ ├── basket-roi │ │ │ │ │ ├── basket-roi.component.scss │ │ │ │ │ ├── basket-roi.component.spec.ts │ │ │ │ │ ├── basket-roi.component.ts │ │ │ │ │ └── basket-roi.component.html │ │ │ │ ├── create-basket │ │ │ │ │ ├── create-basket.component.scss │ │ │ │ │ ├── create-basket.component.spec.ts │ │ │ │ │ └── create-basket.component.ts │ │ │ │ ├── liquidate-modal │ │ │ │ │ ├── liquidate-modal.component.scss │ │ │ │ │ ├── liquidate-modal.component.html │ │ │ │ │ ├── liquidate-modal.component.spec.ts │ │ │ │ │ └── liquidate-modal.component.ts │ │ │ │ ├── basket-composition │ │ │ │ │ ├── basket-composition.component.scss │ │ │ │ │ ├── basket-composition.component.spec.ts │ │ │ │ │ └── basket-composition.component.ts │ │ │ │ ├── vaults-composition │ │ │ │ │ ├── vaults-composition.component.scss │ │ │ │ │ ├── vaults-composition.component.ts │ │ │ │ │ ├── vaults-composition.component.spec.ts │ │ │ │ │ └── vaults-composition.component.html │ │ │ │ ├── custom-invest-modal │ │ │ │ │ ├── custom-invest-modal.component.scss │ │ │ │ │ ├── custom-invest-modal.component.spec.ts │ │ │ │ │ ├── custom-invest-modal.component.ts │ │ │ │ │ └── custom-invest-modal.component.html │ │ │ │ ├── vault │ │ │ │ │ ├── vault.component.scss │ │ │ │ │ └── vault.component.spec.ts │ │ │ │ ├── basket │ │ │ │ │ ├── basket.component.scss │ │ │ │ │ └── basket.component.spec.ts │ │ │ │ ├── custom-basket-pools │ │ │ │ │ ├── custom-basket-pools.component.scss │ │ │ │ │ └── custom-basket-pools.component.spec.ts │ │ │ │ └── custom-basket-composition │ │ │ │ │ ├── custom-basket-composition.component.spec.ts │ │ │ │ │ ├── custom-basket-composition.component.scss │ │ │ │ │ └── custom-basket-composition.component.ts │ │ │ ├── baskets.service.ts │ │ │ ├── baskets.service.spec.ts │ │ │ └── baskets-routing.module.ts │ │ ├── binance │ │ │ ├── pages │ │ │ │ └── buy-crypto │ │ │ │ │ ├── buy-crypto.page.scss │ │ │ │ │ └── buy-crypto.page.spec.ts │ │ │ ├── components │ │ │ │ └── binance-register-modal │ │ │ │ │ ├── binance-register-modal.component.scss │ │ │ │ │ ├── binance-register-modal.component.ts │ │ │ │ │ ├── binance-register-modal.component.spec.ts │ │ │ │ │ └── binance-register-modal.component.html │ │ │ ├── binance-routing.module.ts │ │ │ └── binance.module.ts │ │ ├── dashboard │ │ │ ├── components │ │ │ │ ├── asset-distribution-chart │ │ │ │ │ ├── asset-distribution-chart.component.scss │ │ │ │ │ ├── asset-distribution-chart.component.html │ │ │ │ │ ├── asset-distribution-chart.component.ts │ │ │ │ │ └── asset-distribution-chart.component.spec.ts │ │ │ │ ├── holdings-table │ │ │ │ │ ├── portfolio-positions │ │ │ │ │ │ ├── portfolio-positions.component.scss │ │ │ │ │ │ └── portfolio-positions.component.ts │ │ │ │ │ ├── holdings-table.component.spec.ts │ │ │ │ │ ├── holdings-table.component.scss │ │ │ │ │ └── holdings-table.component.ts │ │ │ │ └── price-not-supported-dialog │ │ │ │ │ ├── price-not-supported-dialog.component.ts │ │ │ │ │ └── price-not-supported-dialog.component.html │ │ │ ├── pages │ │ │ │ ├── settings │ │ │ │ │ ├── settings.page.scss │ │ │ │ │ ├── settings.page.spec.ts │ │ │ │ │ └── settings.page.ts │ │ │ │ └── dashboard │ │ │ │ │ ├── dashboard.page.spec.ts │ │ │ │ │ └── dashboard.page.scss │ │ │ ├── dashboard-routing.module.ts │ │ │ └── dashboard.module.ts │ │ └── home │ │ │ ├── home.service.ts │ │ │ ├── home-routing.module.ts │ │ │ ├── home.service.spec.ts │ │ │ ├── components │ │ │ └── disclaimer-modal │ │ │ │ ├── disclaimer-modal.component.ts │ │ │ │ ├── disclaimer-modal.component.scss │ │ │ │ └── disclaimer-modal.component.spec.ts │ │ │ ├── pages │ │ │ └── home │ │ │ │ ├── home.page.spec.ts │ │ │ │ ├── home.page.scss │ │ │ │ └── home.page.html │ │ │ └── home.module.ts │ ├── shared │ │ ├── service │ │ │ ├── token-price.service.ts │ │ │ ├── fb-pixel.service.ts │ │ │ └── google-analytics.service.ts │ │ ├── components │ │ │ ├── button │ │ │ │ ├── button.component.scss │ │ │ │ ├── button.component.html │ │ │ │ ├── button.component.ts │ │ │ │ └── button.component.spec.ts │ │ │ ├── svg-icon │ │ │ │ ├── svg-icon.component.scss │ │ │ │ ├── svg-icon.component.ts │ │ │ │ └── svg-icon.component.spec.ts │ │ │ ├── info-modal │ │ │ │ ├── info-modal.component.scss │ │ │ │ ├── info-modal.component.ts │ │ │ │ └── info-modal.component.html │ │ │ ├── page-title │ │ │ │ ├── page-title.component.scss │ │ │ │ ├── page-title.component.ts │ │ │ │ └── page-title.component.spec.ts │ │ │ ├── notification │ │ │ │ ├── notification.component.scss │ │ │ │ ├── notification.component.ts │ │ │ │ ├── notification.component.spec.ts │ │ │ │ └── notification.component.html │ │ │ ├── countdown-timer │ │ │ │ ├── countdown-timer.component.scss │ │ │ │ ├── countdown-timer.component.html │ │ │ │ └── countdown-timer.component.ts │ │ │ ├── number-counter │ │ │ │ ├── number-counter.component.scss │ │ │ │ ├── number-counter.component.html │ │ │ │ └── number-counter.component.spec.ts │ │ │ ├── address-shortener │ │ │ │ ├── address-shortener.component.scss │ │ │ │ ├── address-shortener.component.ts │ │ │ │ ├── address-shortener.component.html │ │ │ │ └── address-shortener.component.spec.ts │ │ │ ├── percentage-buttons │ │ │ │ ├── percentage-buttons.component.scss │ │ │ │ ├── percentage-buttons.component.html │ │ │ │ ├── percentage-buttons.component.spec.ts │ │ │ │ └── percentage-buttons.component.ts │ │ │ ├── provider-loading │ │ │ │ ├── provider-loading.component.scss │ │ │ │ ├── provider-loading.component.html │ │ │ │ ├── provider-loading.component.ts │ │ │ │ └── provider-loading.component.spec.ts │ │ │ ├── skeleton-loading │ │ │ │ ├── skeleton-loading.component.scss │ │ │ │ ├── skeleton-loading.component.html │ │ │ │ ├── skeleton-loading.component.spec.ts │ │ │ │ └── skeleton-loading.component.ts │ │ │ ├── exceeded-balance-msg │ │ │ │ ├── exceeded-balance-msg.component.scss │ │ │ │ ├── exceeded-balance-msg.component.html │ │ │ │ └── exceeded-balance-msg.component.ts │ │ │ ├── pending-transaction-msg │ │ │ │ ├── pending-transaction-msg.component.scss │ │ │ │ ├── pending-transaction-msg.component.ts │ │ │ │ ├── pending-transaction-msg.component.spec.ts │ │ │ │ └── pending-transaction-msg.component.html │ │ │ ├── set-input-relative-amount │ │ │ │ ├── set-input-relative-amount.component.scss │ │ │ │ └── set-input-relative-amount.component.ts │ │ │ ├── transaction-confirmation │ │ │ │ ├── transaction-confirmation.component.scss │ │ │ │ ├── transaction-confirmation.component.html │ │ │ │ ├── transaction-confirmation.component.ts │ │ │ │ └── transaction-confirmation.component.spec.ts │ │ │ ├── unsupported-chain-msg │ │ │ │ ├── unsupported-chain-msg.component.scss │ │ │ │ ├── unsupported-chain-msg.component.ts │ │ │ │ └── unsupported-chain-msg.component.html │ │ │ ├── footer │ │ │ │ ├── footer.component.html │ │ │ │ ├── footer.component.ts │ │ │ │ ├── footer.component.scss │ │ │ │ └── footer.component.spec.ts │ │ │ ├── loading │ │ │ │ ├── loading.component.html │ │ │ │ ├── loading.component.ts │ │ │ │ ├── loading.component.scss │ │ │ │ └── loading.component.spec.ts │ │ │ ├── content-box │ │ │ │ ├── content-box.component.html │ │ │ │ ├── content-box.component.ts │ │ │ │ ├── content-box.component.scss │ │ │ │ └── content-box.component.spec.ts │ │ │ ├── header │ │ │ │ ├── header.component.scss │ │ │ │ ├── header.component.spec.ts │ │ │ │ ├── header.component.html │ │ │ │ └── header.component.ts │ │ │ ├── empty-state │ │ │ │ ├── empty-state.component.scss │ │ │ │ ├── empty-state.component.html │ │ │ │ ├── empty-state.component.ts │ │ │ │ └── empty-state.component.spec.ts │ │ │ └── sidebar │ │ │ │ ├── sidebar.component.spec.ts │ │ │ │ └── sidebar.component.scss │ │ ├── utils │ │ │ ├── dev-util-log-level.ts │ │ │ ├── dev-util.ts │ │ │ ├── date-time.util.ts │ │ │ ├── http-util.ts │ │ │ ├── provider.util.ts │ │ │ └── ui.utils.ts │ │ ├── ng-destroyable-component.ts │ │ ├── pipes │ │ │ ├── filter.pipe.spec.ts │ │ │ ├── filter.pipe.ts │ │ │ ├── categorize.pipe.ts │ │ │ └── decimal.pipe.ts │ │ ├── data │ │ │ └── walkthrough_steps.ts │ │ └── directives │ │ │ └── numbers-only-input.directive.ts │ ├── core │ │ ├── utils │ │ │ ├── math-utils.ts │ │ │ └── provider-name.ts │ │ ├── guards │ │ │ ├── wallet.guard.spec.ts │ │ │ ├── covalent-auth.interceptor.spec.ts │ │ │ ├── covalent-auth.interceptor.ts │ │ │ └── wallet.guard.ts │ │ ├── services │ │ │ ├── api.service.spec.ts │ │ │ ├── pool.service.spec.ts │ │ │ ├── charts.service.spec.ts │ │ │ ├── events.service.spec.ts │ │ │ ├── vaults.service.spec.ts │ │ │ ├── uniswap.service.spec.ts │ │ │ ├── contract.service.spec.ts │ │ │ ├── connector.service.spec.ts │ │ │ ├── notification.service.spec.ts │ │ │ ├── transactions.service.spec.ts │ │ │ ├── notification.service.ts │ │ │ └── pool.service.ts │ │ └── models │ │ │ └── pool-queries.ts │ ├── app.component.scss │ ├── app.module.ts │ ├── app.component.spec.ts │ ├── app.component.html │ └── app-routing.module.ts ├── favicon.ico ├── proxy.conf.json ├── main.ts ├── test.ts └── environments │ └── environment.prod.ts ├── trigger.txt ├── .prettierignore ├── .prettierrc ├── nginx.conf ├── .editorconfig ├── e2e ├── src │ ├── app.po.ts │ └── app.e2e-spec.ts ├── tsconfig.json └── protractor.conf.js ├── tsconfig.app.json ├── tsconfig.spec.json ├── tsconfig.json ├── Dockerfile ├── .gitignore ├── .browserslistrc ├── README.md ├── patch.js └── karma.conf.js /src/styles.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /trigger.txt: -------------------------------------------------------------------------------- 1 | rebuild 3 2 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/bond/bond.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/bonds/bonds.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/farms/farms.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/pools/pools.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef/reef.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/service/token-price.service.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/vaults/pages/vaults/vaults.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/baskets/baskets.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef-menu/reef-menu.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/button/button.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/svg-icon/svg-icon.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/binance/pages/buy-crypto/buy-crypto.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/info-modal/info-modal.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/page-title/page-title.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/basket-types/basket-types.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/custom-basket/custom-basket.page.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/stake-reef/stake-reef.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/notification/notification.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-roi/basket-roi.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-list/vaults-list.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/countdown-timer/countdown-timer.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/number-counter/number-counter.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/create-basket/create-basket.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/address-shortener/address-shortener.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/percentage-buttons/percentage-buttons.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/provider-loading/provider-loading.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/skeleton-loading/skeleton-loading.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/liquidate-modal/liquidate-modal.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/diversify-vaults/diversify-vaults.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-roi-chart/vaults-roi-chart.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/exceeded-balance-msg/exceeded-balance-msg.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore: 2 | build 3 | dist 4 | node_modules 5 | coverage 6 | e2e 7 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-composition/basket-composition.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vaults-composition/vaults-composition.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/reef-historic-price/reef-historic-price.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/pending-transaction-msg/pending-transaction-msg.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-invest-modal/custom-invest-modal.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/number-counter/number-counter.component.html: -------------------------------------------------------------------------------- 1 | {{ end | number }} 2 | -------------------------------------------------------------------------------- /src/app/shared/components/set-input-relative-amount/set-input-relative-amount.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/transaction-confirmation/transaction-confirmation.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/binance/components/binance-register-modal/binance-register-modal.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/farm/farm.page.scss: -------------------------------------------------------------------------------- 1 | .small-line-h { 2 | line-height: 0.8em; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/asset-distribution-chart/asset-distribution-chart.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/holdings-table/portfolio-positions/portfolio-positions.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/bnb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/bnb.png -------------------------------------------------------------------------------- /src/assets/images/eth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/eth.png -------------------------------------------------------------------------------- /src/app/modules/reef/components/buy-reef/buy-reef.component.scss: -------------------------------------------------------------------------------- 1 | .reef__wrapper { 2 | padding: 50px; 3 | } 4 | -------------------------------------------------------------------------------- /src/assets/images/usdt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/usdt.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/images/empty-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/empty-token.png -------------------------------------------------------------------------------- /src/assets/images/wallet_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/wallet_link.png -------------------------------------------------------------------------------- /src/app/shared/utils/dev-util-log-level.ts: -------------------------------------------------------------------------------- 1 | export enum LogLevel { 2 | ERROR = -1, 3 | WARNING = 0, 4 | STD = 1, 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/images/image-missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/image-missing.png -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vault/vault.component.scss: -------------------------------------------------------------------------------- 1 | .roi__percent { 2 | color: #887ef2; 3 | font-size: 25px; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/reef/reef-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/reef/reef-card.jpg -------------------------------------------------------------------------------- /src/assets/images/reef/reef-token.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/reef/reef-token.jpg -------------------------------------------------------------------------------- /src/assets/images/reef/reef-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/reef/reef-token.png -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket/basket.component.scss: -------------------------------------------------------------------------------- 1 | .roi__percent { 2 | color: #887ef2; 3 | font-size: 25px; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/reef/HeroSectionBG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/images/reef/HeroSectionBG.png -------------------------------------------------------------------------------- /src/app/modules/reef/pages/pool/pool.page.scss: -------------------------------------------------------------------------------- 1 | .fixed-w-20 { 2 | display: inline-block; 3 | width: 20px; 4 | overflow: visible; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/shared/components/unsupported-chain-msg/unsupported-chain-msg.component.scss: -------------------------------------------------------------------------------- 1 | .alert-white { 2 | background-color: white; 3 | } 4 | -------------------------------------------------------------------------------- /src/assets/scripts/casino_hand-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/scripts/casino_hand-webfont.eot -------------------------------------------------------------------------------- /src/assets/scripts/casino_hand-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/scripts/casino_hand-webfont.ttf -------------------------------------------------------------------------------- /src/assets/scripts/casino_hand-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/scripts/casino_hand-webfont.woff -------------------------------------------------------------------------------- /src/assets/icons/cryptocoins/fonts/cryptocoins.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/cryptocoins/fonts/cryptocoins.ttf -------------------------------------------------------------------------------- /src/assets/icons/cryptocoins/fonts/cryptocoins.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/cryptocoins/fonts/cryptocoins.woff -------------------------------------------------------------------------------- /src/assets/icons/cryptocoins/fonts/cryptocoins.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/cryptocoins/fonts/cryptocoins.woff2 -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-brands-400.eot -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-brands-400.ttf -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-solid-900.eot -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-solid-900.ttf -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-solid-900.woff -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/line-awesome.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/line-awesome.eot -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/line-awesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/line-awesome.ttf -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/line-awesome.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/line-awesome.woff -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-brands-400.woff -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-brands-400.woff2 -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-regular-400.eot -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-regular-400.ttf -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-regular-400.woff -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-solid-900.woff2 -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/line-awesome.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/line-awesome.woff2 -------------------------------------------------------------------------------- /src/assets/icons/line-awesome/fonts/la-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/line-awesome/fonts/la-regular-400.woff2 -------------------------------------------------------------------------------- /src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.eot -------------------------------------------------------------------------------- /src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.ttf -------------------------------------------------------------------------------- /src/assets/icons/font-awesome/fonts/fontawesome-webfontd41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/font-awesome/fonts/fontawesome-webfontd41d.eot -------------------------------------------------------------------------------- /src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.woff -------------------------------------------------------------------------------- /src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/font-awesome/fonts/fontawesome-webfont3e6e.woff2 -------------------------------------------------------------------------------- /src/app/core/utils/math-utils.ts: -------------------------------------------------------------------------------- 1 | export const roundDownTo = (base: number, precision: number) => { 2 | const m = Math.pow(10, precision); 3 | return Math.floor(base * m) / m; 4 | }; 5 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/create-basket/create-basket.page.scss: -------------------------------------------------------------------------------- 1 | .parameters__wrapper { 2 | -webkit-border-radius: 7px; 3 | -moz-border-radius: 7px; 4 | border-radius: 7px; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/modules/home/home.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class HomeService { 7 | constructor() {} 8 | } 9 | -------------------------------------------------------------------------------- /src/app/modules/reef/reef.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class ReefService { 7 | constructor() {} 8 | } 9 | -------------------------------------------------------------------------------- /src/app/shared/components/button/button.component.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/app/modules/baskets/baskets.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class BasketsService { 7 | constructor() {} 8 | } 9 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/card/card.page.scss: -------------------------------------------------------------------------------- 1 | .reef-card-img { 2 | min-width: 0; 3 | max-width: 400px; 4 | height: auto; 5 | width: 100%; 6 | border: solid 1px #707070; 7 | border-radius: 0.5em; 8 | } 9 | -------------------------------------------------------------------------------- /src/assets/scss/_base.scss: -------------------------------------------------------------------------------- 1 | @import './partials/variables'; 2 | @import './partials/buttons'; 3 | @import './partials/containers'; 4 | @import './partials/typography'; 5 | @import './partials/material-overrides'; 6 | -------------------------------------------------------------------------------- /src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.eot -------------------------------------------------------------------------------- /src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff -------------------------------------------------------------------------------- /src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reef-defi/reef-client/HEAD/src/assets/icons/material-design-iconic-font/fonts/materialdesignicons-webfont.woff2 -------------------------------------------------------------------------------- /src/proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api": { 3 | "target": "https://baskets.reef.finance/v1", 4 | "secure": true, 5 | "changeOrigin": true, 6 | "pathRewrite": { 7 | "^/api": "" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/transaction-confirmation/transaction-confirmation.component.html: -------------------------------------------------------------------------------- 1 |
2 |
Please confirm the transaction
3 | 4 |
5 | -------------------------------------------------------------------------------- /src/app/shared/ng-destroyable-component.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from 'rxjs'; 2 | 3 | export class NgDestroyableComponent { 4 | onDestroyed$ = new Subject(); 5 | 6 | onDestroy() { 7 | this.onDestroyed$.next(null); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | 4 | location / { 5 | root /usr/share/nginx/html; 6 | index index.html index.htm; 7 | try_files $uri $uri/ /index.html =404; 8 | } 9 | 10 | include /etc/nginx/extra-conf.d/*.conf; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/shared/components/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/shared/pipes/filter.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { FilterPipe } from './filter.pipe'; 2 | 3 | describe('FilterPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new FilterPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-basket-pools/custom-basket-pools.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/partials/variables'; 2 | 3 | .app-custom-basket-pools .mat-slider-track-background { 4 | background: map-get($theme-colors, dark) !important; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/shared/components/loading/loading.component.html: -------------------------------------------------------------------------------- 1 |
7 | 8 |
9 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/pages/settings/settings.page.scss: -------------------------------------------------------------------------------- 1 | .gas-price__item { 2 | &:hover { 3 | background-color: #6f42c1; 4 | color: white; 5 | } 6 | cursor: pointer; 7 | } 8 | 9 | .gas-price__item--selected { 10 | background-color: #6f42c1; 11 | color: white; 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/skeleton-loading/skeleton-loading.component.html: -------------------------------------------------------------------------------- 1 |
2 | 8 | 9 |
10 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/about/about.page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-about-page', 5 | templateUrl: './about.page.html', 6 | styleUrls: ['./about.page.scss'], 7 | }) 8 | export class AboutPage { 9 | constructor() {} 10 | } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/content-box/content-box.component.html: -------------------------------------------------------------------------------- 1 |
11 | 12 |
13 | -------------------------------------------------------------------------------- /src/app/shared/components/header/header.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/partials/variables'; 2 | 3 | .header { 4 | display: flex; 5 | justify-content: space-between; 6 | flex-direction: row-reverse; 7 | z-index: 998; 8 | border-radius: 8px; 9 | box-shadow: 0 0 8px #00000024; 10 | padding: 10px; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/shared/service/fb-pixel.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | declare let fbq: Function; 4 | 5 | @Injectable({ providedIn: 'root' }) 6 | export class FbPixelService { 7 | static readonly LEAD_TYPE = 'Lead'; 8 | 9 | track(type: string): void { 10 | fbq('track', type); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-state/empty-state.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/partials/variables'; 2 | $mid: 50%; 3 | .center { 4 | position: absolute; 5 | top: 45%; 6 | left: calc(#{$mid} + #{$sidebar-width - 100px}); 7 | margin-right: calc(-#{$mid} + #{$sidebar-width}); 8 | transform: translate(-50%, -50%); 9 | } 10 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/asset-distribution-chart/asset-distribution-chart.component.html: -------------------------------------------------------------------------------- 1 |
2 | 8 |
9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../out-tsc/e2e", 6 | "module": "commonjs", 7 | "target": "es2018", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/shared/components/content-box/content-box.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-content-box', 5 | templateUrl: './content-box.component.html', 6 | styleUrls: ['./content-box.component.scss'], 7 | }) 8 | export class ContentBoxComponent { 9 | @Input() isAddress: boolean | undefined; 10 | constructor() {} 11 | } 12 | -------------------------------------------------------------------------------- /src/app/shared/components/percentage-buttons/percentage-buttons.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 10 |
11 |
12 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [], 7 | "resolveJsonModule": true 8 | }, 9 | "files": [ 10 | "src/main.ts", 11 | "src/polyfills.ts" 12 | ], 13 | "include": [ 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/components/svg-icon/svg-icon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-svg-icon', 5 | templateUrl: './svg-icon.component.html', 6 | styleUrls: ['./svg-icon.component.scss'], 7 | }) 8 | export class SvgIconComponent implements OnInit { 9 | @Input() icon: string; 10 | constructor() {} 11 | 12 | ngOnInit(): void {} 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/components/provider-loading/provider-loading.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/app/shared/components/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | templateUrl: './footer.component.html', 6 | styleUrls: ['./footer.component.scss'], 7 | }) 8 | export class FooterComponent implements OnInit { 9 | readonly currentYear = new Date().getFullYear(); 10 | 11 | constructor() {} 12 | 13 | ngOnInit(): void {} 14 | } 15 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/app/core/guards/wallet.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { WalletGuard } from './wallet.guard'; 4 | 5 | describe('WalletGuard', () => { 6 | let guard: WalletGuard; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | guard = TestBed.inject(WalletGuard); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(guard).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/shared/components/footer/footer.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | 3 | .footer { 4 | position: sticky; 5 | bottom: 0; 6 | padding: 1px 10px; 7 | width: 100%; 8 | color: map-get($theme-colors, dark); 9 | background: map-get($theme-colors, light); 10 | } 11 | 12 | .footer__company { 13 | font-weight: 300; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: map-get($theme-colors, dark); 19 | } 20 | -------------------------------------------------------------------------------- /src/app/core/services/api.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ApiService } from './api.service'; 4 | 5 | describe('ApiService', () => { 6 | let service: ApiService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(ApiService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/pool.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { PoolService } from './pool.service'; 4 | 5 | describe('PoolService', () => { 6 | let service: PoolService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(PoolService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/home/home-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { HomePage } from './pages/home/home.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: HomePage, 9 | }, 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule], 15 | }) 16 | export class HomeRoutingModule {} 17 | -------------------------------------------------------------------------------- /src/app/modules/home/home.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { HomeService } from './home.service'; 4 | 5 | describe('HomeService', () => { 6 | let service: HomeService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(HomeService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/reef/reef.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ReefService } from './reef.service'; 4 | 5 | describe('ReefService', () => { 6 | let service: ReefService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(ReefService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/charts.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ChartsService } from './charts.service'; 4 | 5 | describe('ChartsService', () => { 6 | let service: ChartsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(ChartsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/events.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { EventsService } from './events.service'; 4 | 5 | describe('EventsService', () => { 6 | let service: EventsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(EventsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/vaults.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultsService } from './vaults.service'; 4 | 5 | describe('VaultsService', () => { 6 | let service: VaultsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(VaultsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/uniswap.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { UniswapService } from './uniswap.service'; 4 | 5 | describe('UniswapService', () => { 6 | let service: UniswapService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(UniswapService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/baskets/baskets.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketsService } from './baskets.service'; 4 | 5 | describe('ApiService', () => { 6 | let service: BasketsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(BasketsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/vaults/vaults-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { VaultsPage } from './pages/vaults/vaults.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: VaultsPage, 9 | }, 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule], 15 | }) 16 | export class VaultsRoutingModule {} 17 | -------------------------------------------------------------------------------- /src/app/shared/components/transaction-confirmation/transaction-confirmation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-transaction-confirmation', 5 | templateUrl: './transaction-confirmation.component.html', 6 | styleUrls: ['./transaction-confirmation.component.scss'], 7 | }) 8 | export class TransactionConfirmationComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit(): void {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/core/services/contract.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ContractService } from './contract.service'; 4 | 5 | describe('ContractService', () => { 6 | let service: ContractService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(ContractService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/connector.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ConnectorService } from './connector.service'; 4 | 5 | describe('ConnectorService', () => { 6 | let service: ConnectorService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(ConnectorService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/binance/binance-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { BuyCryptoPage } from './pages/buy-crypto/buy-crypto.page'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: BuyCryptoPage, 9 | }, 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule], 15 | }) 16 | export class BinanceRoutingModule {} 17 | -------------------------------------------------------------------------------- /src/app/shared/components/page-title/page-title.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-page-title', 5 | templateUrl: './page-title.component.html', 6 | styleUrls: ['./page-title.component.scss'], 7 | changeDetection: ChangeDetectionStrategy.OnPush, 8 | }) 9 | export class PageTitleComponent { 10 | @Input() title: string | undefined; 11 | @Input() subtitle: string | undefined; 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/address-shortener/address-shortener.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-address-shortener', 5 | templateUrl: './address-shortener.component.html', 6 | styleUrls: ['./address-shortener.component.scss'], 7 | }) 8 | export class AddressShortenerComponent { 9 | @Input() address: string | null; 10 | @Input() standalone = true; 11 | @Input() showCopy = true; 12 | constructor() {} 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/components/button/button.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-button', 5 | templateUrl: './button.component.html', 6 | styleUrls: ['./button.component.scss'], 7 | }) 8 | export class ButtonComponent { 9 | @Input() text: string; 10 | @Input() inverse = false; 11 | @Output() click = new EventEmitter(); 12 | 13 | onClick(): void { 14 | this.click.emit(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/app/core/services/notification.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { NotificationService } from './notification.service'; 4 | 5 | describe('NotificationService', () => { 6 | let service: NotificationService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(NotificationService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/core/services/transactions.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { TransactionsService } from './transactions.service'; 4 | 5 | describe('TransactionsService', () => { 6 | let service: TransactionsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(TransactionsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/stake-reef/stake-reef.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-stake-reef', 5 | templateUrl: './stake-reef.component.html', 6 | styleUrls: ['./stake-reef.component.scss'], 7 | }) 8 | export class StakeReefComponent { 9 | @Output() stake = new EventEmitter(); 10 | constructor() {} 11 | 12 | onStake(amount: number): void { 13 | this.stake.emit(amount); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | 3 | .main { 4 | padding-top: 10px; 5 | padding-bottom: 10px; 6 | } 7 | 8 | .main__active { 9 | padding-left: $sidebar-width + 15px; 10 | margin-bottom: -40px; 11 | @include media-breakpoint-down(sm) { 12 | padding-left: $mobile-sidebar-width + 15px; 13 | padding-top: 50px; 14 | } 15 | } 16 | 17 | .dark { 18 | background: map-get($theme-colors, dark); 19 | } 20 | 21 | .light { 22 | background: map-get($theme-colors, light); 23 | } 24 | -------------------------------------------------------------------------------- /src/app/shared/components/exceeded-balance-msg/exceeded-balance-msg.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | Not enough {{ tokenBalance.contract_ticker_symbol }} in your 6 | account. 8 | 11 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /src/app/shared/components/content-box/content-box.component.scss: -------------------------------------------------------------------------------- 1 | @import '../../../../assets/scss/partials/variables'; 2 | 3 | .content-box { 4 | height: 45px; 5 | padding: 4px 17px; 6 | margin: 0 5px; 7 | -webkit-border-radius: 10px; 8 | -moz-border-radius: 10px; 9 | border-radius: 10px; 10 | background-color: map_get($theme-colors, light); 11 | font-weight: 500; 12 | } 13 | 14 | .address { 15 | background: #eae8fd; 16 | letter-spacing: 0; 17 | -webkit-border-radius: 0; 18 | -moz-border-radius: 0; 19 | border-radius: 0; 20 | } 21 | -------------------------------------------------------------------------------- /src/app/shared/components/loading/loading.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | import { ThemePalette } from '@angular/material/core'; 3 | 4 | @Component({ 5 | selector: 'app-loading', 6 | templateUrl: './loading.component.html', 7 | styleUrls: ['./loading.component.scss'], 8 | }) 9 | export class LoadingComponent implements OnInit { 10 | @Input() color: ThemePalette = 'primary'; 11 | @Input() diameter = 50; 12 | @Input() isWholePage = false; 13 | constructor() {} 14 | 15 | ngOnInit(): void {} 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/pipes/filter.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'filter', 5 | }) 6 | export class FilterPipe implements PipeTransform { 7 | transform(value: any[], filterBy: string, searchString): any[] { 8 | if (!value) { 9 | return []; 10 | } 11 | if (!filterBy) { 12 | return value; 13 | } 14 | return value.filter((val: any) => 15 | val[filterBy] 16 | .toLocaleLowerCase() 17 | .includes(searchString.toLocaleLowerCase()) 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/modules/binance/components/binance-register-modal/binance-register-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { MAT_DIALOG_DATA } from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'app-binance-register-modal', 6 | templateUrl: './binance-register-modal.component.html', 7 | styleUrls: ['./binance-register-modal.component.scss'], 8 | }) 9 | export class BinanceRegisterModalComponent { 10 | public email: string | undefined; 11 | constructor(@Inject(MAT_DIALOG_DATA) public data: any) {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/address-shortener/address-shortener.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {{ address.slice(0, 4) }}...{{ 5 | address.slice(address.length - 4, address.length) 6 | }} 7 |
8 |
9 |
10 | 11 | content_copy 12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /src/app/shared/components/loading/loading.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | $mid: 50%; 3 | 4 | .center-loader { 5 | position: absolute; 6 | transform: translate(-50%, -50%); 7 | @include media-breakpoint-down(md) { 8 | top: 50%; 9 | left: 50%; 10 | margin-right: calc(-#{$mid} + #{$mobile-sidebar-width}); 11 | } 12 | @include media-breakpoint-up(md) { 13 | top: calc(#{$mid} + #{$header-height - 50px}); 14 | left: calc(#{$mid} + #{$sidebar-width - 100px}); 15 | margin-right: calc(-#{$mid} + #{$sidebar-width}); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/modules/home/components/disclaimer-modal/disclaimer-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { MatDialogRef } from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'app-disclaimer-modal', 6 | templateUrl: './disclaimer-modal.component.html', 7 | styleUrls: ['./disclaimer-modal.component.scss'], 8 | }) 9 | export class DisclaimerModalComponent { 10 | constructor(public dialogRef: MatDialogRef) {} 11 | 12 | action(state: boolean): void { 13 | this.dialogRef.close(state); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-state/empty-state.component.html: -------------------------------------------------------------------------------- 1 |
2 | Empty State 9 |
{{ title }}
10 |
{{ subtitle }}
11 |
12 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /src/app/core/guards/covalent-auth.interceptor.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { CovalentAuthInterceptor } from './covalent-auth.interceptor'; 4 | 5 | describe('CovalentAuthInterceptor', () => { 6 | beforeEach(() => 7 | TestBed.configureTestingModule({ 8 | providers: [CovalentAuthInterceptor], 9 | }) 10 | ); 11 | 12 | it('should be created', () => { 13 | const interceptor: CovalentAuthInterceptor = TestBed.inject( 14 | CovalentAuthInterceptor 15 | ); 16 | expect(interceptor).toBeTruthy(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/about/about.page.scss: -------------------------------------------------------------------------------- 1 | .reef-bg { 2 | background-color: #f2f3f4; 3 | background-image: url('/assets/images/reef/HeroSectionBG.png'); 4 | background-size: cover; 5 | background-repeat: no-repeat; 6 | background-position-x: 54%; 7 | } 8 | @media (max-width: 467px) { 9 | /* Target devices narrower than 768px. */ 10 | .reef-bg { 11 | padding-bottom: 10em; 12 | } 13 | } 14 | 15 | .card-body { 16 | padding-bottom: 12em !important; 17 | } 18 | 19 | .bottom-logo { 20 | width: 60px; 21 | } 22 | 23 | .social-box { 24 | min-width: 60px; 25 | } 26 | -------------------------------------------------------------------------------- /src/app/shared/components/pending-transaction-msg/pending-transaction-msg.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { 3 | PendingTransaction, 4 | TransactionType, 5 | } from '../../../core/models/types'; 6 | 7 | @Component({ 8 | selector: 'app-pending-transaction-msg', 9 | templateUrl: './pending-transaction-msg.component.html', 10 | styleUrls: ['./pending-transaction-msg.component.scss'], 11 | }) 12 | export class PendingTransactionMsgComponent { 13 | TransactionType = TransactionType; 14 | @Input() transaction: PendingTransaction | undefined; 15 | } 16 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { DashboardPage } from './pages/dashboard/dashboard.page'; 4 | import { SettingsPage } from './pages/settings/settings.page'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: DashboardPage, 10 | }, 11 | { 12 | path: 'settings', 13 | component: SettingsPage, 14 | }, 15 | ]; 16 | 17 | @NgModule({ 18 | imports: [RouterModule.forChild(routes)], 19 | exports: [RouterModule], 20 | }) 21 | export class DashboardRoutingModule {} 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "experimentalDecorators": true, 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "module": "es2020", 15 | "resolveJsonModule": true, 16 | "lib": [ 17 | "es2018", 18 | "dom" 19 | ], 20 | "allowSyntheticDefaultImports": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/shared/components/notification/notification.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, OnInit } from '@angular/core'; 2 | import { 3 | MAT_SNACK_BAR_DATA, 4 | MatSnackBarRef, 5 | } from '@angular/material/snack-bar'; 6 | 7 | @Component({ 8 | selector: 'app-notification', 9 | templateUrl: './notification.component.html', 10 | styleUrls: ['./notification.component.scss'], 11 | }) 12 | export class NotificationComponent implements OnInit { 13 | constructor( 14 | @Inject(MAT_SNACK_BAR_DATA) public data: any, 15 | public snackBarRef: MatSnackBarRef 16 | ) {} 17 | 18 | ngOnInit(): void {} 19 | } 20 | -------------------------------------------------------------------------------- /src/app/shared/components/provider-loading/provider-loading.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-provider-loading', 5 | templateUrl: './provider-loading.component.html', 6 | styleUrls: ['./provider-loading.component.scss'], 7 | }) 8 | export class ProviderLoadingComponent implements OnInit { 9 | ngOnInit() { 10 | const span = document.querySelector('.dots'); 11 | setInterval(() => { 12 | if (span.innerHTML.length > 2) { 13 | span.innerHTML = ''; 14 | } else { 15 | span.innerHTML += '.'; 16 | } 17 | }, 500); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/holdings-table/portfolio-positions/portfolio-positions.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output } from '@angular/core'; 2 | import { EventEmitter } from '@angular/core'; 3 | import { ChainId } from '../../../../../core/models/types'; 4 | 5 | @Component({ 6 | selector: 'app-portfolio-positions', 7 | templateUrl: './portfolio-positions.component.html', 8 | styleUrls: ['./portfolio-positions.component.scss'], 9 | }) 10 | export class PortfolioPositionsComponent { 11 | @Input() 12 | positions: any; 13 | @Input() 14 | title: string; 15 | @Output() 16 | refresh = new EventEmitter(); 17 | } 18 | -------------------------------------------------------------------------------- /src/assets/images/tokens/dai.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/price-not-supported-dialog/price-not-supported-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'app-price-not-supported-dialog', 6 | templateUrl: './price-not-supported-dialog.component.html', 7 | }) 8 | export class PriceNotSupportedDialogComponent { 9 | constructor( 10 | private dialogRef: MatDialogRef, 11 | @Inject(MAT_DIALOG_DATA) public data: any 12 | ) {} 13 | 14 | onClose(): void { 15 | this.dialogRef.close(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-list/vaults-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import { IVault } from '../../../../core/models/types'; 3 | 4 | @Component({ 5 | selector: 'app-vaults-list', 6 | templateUrl: './vaults-list.component.html', 7 | styleUrls: ['./vaults-list.component.scss'], 8 | }) 9 | export class VaultsListComponent { 10 | Object = Object; 11 | @Input() vaults: IVault | undefined; 12 | @Output() vaultAllocChanged = new EventEmitter(); 13 | 14 | onVaultAllocChanged(percentage, name): void { 15 | this.vaultAllocChanged.emit([name, percentage]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/assets/images/tokens/usdt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-state/empty-state.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-empty-state', 5 | templateUrl: './empty-state.component.html', 6 | styleUrls: ['./empty-state.component.scss'], 7 | }) 8 | export class EmptyStateComponent { 9 | @Input() title: string | undefined; 10 | @Input() subtitle: string | undefined; 11 | @Input() showCtaButton: boolean | undefined; 12 | @Input() ctaButtonText: string | undefined; 13 | @Output() cta = new EventEmitter(); 14 | constructor() {} 15 | 16 | onCta(): void { 17 | this.cta.emit(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/shared/components/info-modal/info-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'app-info-modal', 6 | templateUrl: './info-modal.component.html', 7 | styleUrls: ['./info-modal.component.scss'], 8 | }) 9 | export class InfoModalComponent { 10 | title: any; 11 | message: any; 12 | 13 | constructor( 14 | public dialogRef: MatDialogRef, 15 | @Inject(MAT_DIALOG_DATA) public data: any 16 | ) {} 17 | 18 | action(state: boolean): void { 19 | this.dialogRef.close(state); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14 as builder 2 | 3 | ADD . /app 4 | WORKDIR /app 5 | RUN rm -rf node_modules 6 | 7 | RUN npm install --loglevel=error 8 | RUN npm install -g @angular/cli@10.1.7 --loglevel=error 9 | 10 | RUN npm run ng -- build --prod --aot --outputHashing=all 11 | 12 | ENV PATH /app/node_modules/.bin:$PATH 13 | 14 | FROM nginx:alpine 15 | 16 | #!/bin/sh 17 | 18 | 19 | ## Remove default nginx index page 20 | RUN rm -rf /usr/share/nginx/html/* 21 | 22 | COPY --from=builder /app/dist/reef-app-v2 /usr/share/nginx/html 23 | COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf 24 | 25 | EXPOSE 4200 80 26 | 27 | ENTRYPOINT ["nginx", "-g", "daemon off;"] 28 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/price-not-supported-dialog/price-not-supported-dialog.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 |

6 | Currently we can not display prices for some tokens on selected 7 | blockchain. 8 |

9 |
10 |
11 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /src/app/shared/components/countdown-timer/countdown-timer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | {{ time.days }} days 7 | 8 | 9 | {{ time.hours }} 10 | 11 | hours {{ time.minutes }} minutes 12 | {{ time.seconds }} seconds. 13 |
14 |
15 | This bond sale closed. 16 | -------------------------------------------------------------------------------- /src/app/shared/utils/dev-util.ts: -------------------------------------------------------------------------------- 1 | import { environment } from '../../../environments/environment'; 2 | import { LogLevel } from './dev-util-log-level'; 3 | 4 | export class DevUtil { 5 | static devLog( 6 | msg: string, 7 | value?: any, 8 | logLevel: LogLevel = LogLevel.STD 9 | ): void { 10 | const minLogLevel = environment.logLevel; 11 | if (minLogLevel >= logLevel) { 12 | if (logLevel > LogLevel.WARNING) { 13 | console.log(msg, value); 14 | } else if (logLevel === LogLevel.WARNING) { 15 | console.warn(msg, value); 16 | } else if (logLevel === LogLevel.ERROR) { 17 | console.error(msg, value); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/assets/images/binance_icon_logo.svg: -------------------------------------------------------------------------------- 1 | bi 2 | -------------------------------------------------------------------------------- /src/app/modules/home/components/disclaimer-modal/disclaimer-modal.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | 3 | .dialog__footer { 4 | display: flex !important; 5 | @include media-breakpoint-up(md) { 6 | flex-direction: row; 7 | justify-content: space-between; 8 | } 9 | @include media-breakpoint-down(md) { 10 | flex-direction: column-reverse; 11 | align-items: center; 12 | justify-content: space-around; 13 | div:nth-child(2) { 14 | margin-bottom: 1rem; 15 | } 16 | } 17 | } 18 | 19 | ::ng-deep.cdk-global-overlay-wrapper { 20 | display: flex; 21 | position: absolute; 22 | z-index: 1000; 23 | overflow: auto; 24 | pointer-events: auto; 25 | } 26 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/farm/farm.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FarmPage } from './farm.page'; 4 | 5 | describe('FarmPage', () => { 6 | let component: FarmPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [FarmPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(FarmPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/pool/pool.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PoolPage } from './pool.page'; 4 | 5 | describe('PoolPage', () => { 6 | let component: PoolPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PoolPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PoolPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef/reef.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ReefPage } from './reef.page'; 4 | 5 | describe('ReefPage', () => { 6 | let component: ReefPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ReefPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ReefPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/assets/scss/partials/_variables.scss: -------------------------------------------------------------------------------- 1 | $dark-primary: #10163A; 2 | $sidebar-width: 220px; 3 | $mobile-sidebar-width: 0px; 4 | $primary-gradient: -webkit-linear-gradient(#A80DE6, #F37C8E); 5 | $header-height: 95px; 6 | $sidebar-primary: #887EF2; 7 | $theme-colors: ( 8 | "primary": #6610f2, 9 | "secondary": #6c757d, 10 | "success": #007bff, 11 | "info": #17a2b8, 12 | "light": #f2f3f4, 13 | "lighter": #F3F3F3, 14 | "dark": #343a40, 15 | "danger": #dc3545, 16 | "lightest": #FFFFFF, 17 | ); 18 | 19 | $font-colors: ( 20 | "primary": #393939, 21 | "light": #848484, 22 | "lightest": #FFFFFF, 23 | "danger": #F64E60, 24 | "success": #69DC9E, 25 | ) 26 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/liquidate-modal/liquidate-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 |
Claim REEF
3 |
4 | 5 |
Stake or re-invest into REEF-ETH pool.
6 |
7 |
8 |
9 | 12 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /src/app/modules/home/pages/home/home.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HomePage } from './home.page'; 4 | 5 | describe('HomeComponent', () => { 6 | let component: HomePage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [HomePage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(HomePage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/farms/farms.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FarmsPage } from './farms.page'; 4 | 5 | describe('FarmsPage', () => { 6 | let component: FarmsPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [FarmsPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(FarmsPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/pools/pools.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PoolsPage } from './pools.page'; 4 | 5 | describe('PoolsPage', () => { 6 | let component: PoolsPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PoolsPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PoolsPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/basket-types/basket-types.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ConnectorService } from '../../../../core/services/connector.service'; 3 | import { TransactionType } from '../../../../core/models/types'; 4 | 5 | @Component({ 6 | selector: 'app-basket-types', 7 | templateUrl: './basket-types.page.html', 8 | styleUrls: ['./basket-types.page.scss'], 9 | }) 10 | export class BasketTypesPage implements OnInit { 11 | public stableCoins = ['dai', 'usdc', 'usdt']; 12 | public erc20Coins = ['bal', 'comp', 'uni']; 13 | TransactionType = TransactionType; 14 | constructor(public readonly connectorService: ConnectorService) {} 15 | 16 | ngOnInit(): void {} 17 | } 18 | -------------------------------------------------------------------------------- /src/app/modules/binance/binance.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { BinanceRoutingModule } from './binance-routing.module'; 5 | import { BuyCryptoPage } from './pages/buy-crypto/buy-crypto.page'; 6 | import { SharedModule } from '../../shared/shared.module'; 7 | import { BinanceRegisterModalComponent } from './components/binance-register-modal/binance-register-modal.component'; 8 | 9 | const pages = [BuyCryptoPage]; 10 | const components = [BinanceRegisterModalComponent]; 11 | 12 | @NgModule({ 13 | declarations: [...pages, ...components], 14 | imports: [CommonModule, BinanceRoutingModule, SharedModule], 15 | }) 16 | export class BinanceModule {} 17 | -------------------------------------------------------------------------------- /src/app/modules/vaults/pages/vaults/vaults.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultsPage } from './vaults.page'; 4 | 5 | describe('VaultsPage', () => { 6 | let component: VaultsPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [VaultsPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(VaultsPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/service/google-analytics.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | declare let gtag: Function; 4 | 5 | @Injectable({ providedIn: 'root' }) 6 | export class GoogleAnalyticsService { 7 | pageView(uri: string) { 8 | gtag('config', 'G-G1W8EPNCTC', { 9 | page_path: uri, 10 | }); 11 | } 12 | 13 | eventEmitter( 14 | eventName: string, 15 | eventCategory: string, 16 | eventAction: string, 17 | eventLabel: string = null, 18 | eventValue: number = null 19 | ) { 20 | gtag('event', eventName, { 21 | eventCategory: eventCategory, 22 | eventLabel: eventLabel, 23 | eventAction: eventAction, 24 | eventValue: eventValue, 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/baskets/baskets.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketsPage } from './baskets.page'; 4 | 5 | describe('BasketsPage', () => { 6 | let component: BasketsPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BasketsPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BasketsPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/home/home.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { HomeRoutingModule } from './home-routing.module'; 5 | import { HomePage } from './pages/home/home.page'; 6 | import { DisclaimerModalComponent } from './components/disclaimer-modal/disclaimer-modal.component'; 7 | import { SharedModule } from '../../shared/shared.module'; 8 | import { MatRippleModule } from '@angular/material/core'; 9 | 10 | const components = [DisclaimerModalComponent]; 11 | const pages = [HomePage]; 12 | 13 | @NgModule({ 14 | declarations: [...pages, ...components], 15 | imports: [CommonModule, HomeRoutingModule, SharedModule, MatRippleModule], 16 | }) 17 | export class HomeModule {} 18 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('reef-app-v2 app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef-menu/reef-menu.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ReefMenuPage } from './reef-menu.page'; 4 | 5 | describe('ReefMenuPage', () => { 6 | let component: ReefMenuPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ReefMenuPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ReefMenuPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/pages/settings/settings.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SettingsPage } from './settings.page'; 4 | 5 | describe('SettingsComponent', () => { 6 | let component: SettingsPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [SettingsPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(SettingsPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/assets/images/tokens/bal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/binance/pages/buy-crypto/buy-crypto.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BuyCryptoPage } from './buy-crypto.page'; 4 | 5 | describe('BuyCryptoPage', () => { 6 | let component: BuyCryptoPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BuyCryptoPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BuyCryptoPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/pages/dashboard/dashboard.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DashboardPage } from './dashboard.page'; 4 | 5 | describe('DashboardPage', () => { 6 | let component: DashboardPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [DashboardPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(DashboardPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/assets/providers.ts: -------------------------------------------------------------------------------- 1 | import {ProviderName} from '../app/core/models/types'; 2 | import {environment} from '../environments/environment'; 3 | 4 | export const provider = { 5 | [ProviderName.INFURA]: { 6 | url: 'https://mainnet.infura.io/v3/' + environment.infuraApiKey, 7 | apiKey: environment.infuraApiKey, 8 | chainId: 1 9 | }, 10 | [ProviderName.ALCHEMY]: { 11 | url: 'https://eth-mainnet.alchemyapi.io/v2/' + environment.alchemyApiKey, 12 | apiKey: environment.alchemyApiKey, 13 | chainId: 1 14 | }, 15 | [ProviderName.LOCAL_FORK]: { 16 | url: 'https://localhost:8545', 17 | apiKey: '', 18 | chainId: 1337 19 | }, 20 | }; 21 | 22 | // 944e0650418142c4a352e7e802e71ee1 DEV 23 | 24 | // 395d6f5d9a324c799a3becf85449122a PROD 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vault/vault.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultComponent } from './vault.component'; 4 | 5 | describe('VaultComponent', () => { 6 | let component: VaultComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [VaultComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(VaultComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/button/button.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ButtonComponent } from './button.component'; 4 | 5 | describe('ButtonComponent', () => { 6 | let component: ButtonComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ButtonComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ButtonComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/footer/footer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FooterComponent } from './footer.component'; 4 | 5 | describe('FooterComponent', () => { 6 | let component: FooterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [FooterComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(FooterComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeaderComponent } from './header.component'; 4 | 5 | describe('HeaderComponent', () => { 6 | let component: HeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [HeaderComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(HeaderComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vaults-composition/vaults-composition.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { IVaultInfo } from '../../../../core/models/types'; 3 | import { ThemePalette } from '@angular/material/core'; 4 | 5 | @Component({ 6 | selector: 'app-vaults-composition', 7 | templateUrl: './vaults-composition.component.html', 8 | styleUrls: ['./vaults-composition.component.scss'], 9 | }) 10 | export class VaultsCompositionComponent { 11 | private mColors: ThemePalette[] = ['primary', 'accent', 'warn']; 12 | @Input() vaults: IVaultInfo | undefined; 13 | @Input() isList: boolean | undefined; 14 | 15 | get colors(): ThemePalette[] { 16 | return [...this.mColors, ...this.mColors, ...this.mColors]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket/basket.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketComponent } from './basket.component'; 4 | 5 | describe('BasketComponent', () => { 6 | let component: BasketComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BasketComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BasketComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/loading/loading.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LoadingComponent } from './loading.component'; 4 | 5 | describe('LoadingComponent', () => { 6 | let component: LoadingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [LoadingComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(LoadingComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/sidebar/sidebar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SidebarComponent } from './sidebar.component'; 4 | 5 | describe('SidebarComponent', () => { 6 | let component: SidebarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [SidebarComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(SidebarComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/basket-types/basket-types.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketTypesPage } from './basket-types.page'; 4 | 5 | describe('BasketTypesPage', () => { 6 | let component: BasketTypesPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BasketTypesPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BasketTypesPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/svg-icon/svg-icon.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SvgIconComponent } from './svg-icon.component'; 4 | 5 | describe('SvgIconComponent', () => { 6 | let component: SvgIconComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [SvgIconComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(SvgIconComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/pages/dashboard/dashboard.page.scss: -------------------------------------------------------------------------------- 1 | $min-width: 500px; 2 | 3 | .gas-price__item { 4 | &:hover { 5 | background-color: #6f42c1; 6 | color: white; 7 | } 8 | 9 | cursor: pointer; 10 | } 11 | 12 | .gas-price__item--selected { 13 | background-color: #6f42c1; 14 | color: white; 15 | } 16 | 17 | .min-height-100px { 18 | min-height: 100px; 19 | } 20 | 21 | .ellipsis { 22 | overflow-x: hidden; 23 | text-overflow: ellipsis; 24 | white-space: nowrap; 25 | } 26 | 27 | @media (max-width: 768px) { 28 | .transactions { 29 | overflow-x: auto; 30 | } 31 | 32 | .transaction-header, 33 | .transaction-item { 34 | min-width: $min-width; 35 | } 36 | 37 | .mat-divider { 38 | min-width: calc(#{$min-width} - 1.25rem); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/buy-reef/buy-reef.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BuyReefComponent } from './buy-reef.component'; 4 | 5 | describe('BuyReefComponent', () => { 6 | let component: BuyReefComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BuyReefComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BuyReefComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/create-basket/create-basket.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CreateBasketPage } from './create-basket.page'; 4 | 5 | describe('CreateBasketPage', () => { 6 | let component: CreateBasketPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CreateBasketPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CreateBasketPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/custom-basket/custom-basket.page.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CustomBasketPage } from './custom-basket.page'; 4 | 5 | describe('CustomBasketPage', () => { 6 | let component: CustomBasketPage; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CustomBasketPage], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CustomBasketPage); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/stake-reef/stake-reef.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StakeReefComponent } from './stake-reef.component'; 4 | 5 | describe('PoolsPage', () => { 6 | let component: StakeReefComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [StakeReefComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(StakeReefComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/page-title/page-title.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PageTitleComponent } from './page-title.component'; 4 | 5 | describe('PageTitleComponent', () => { 6 | let component: PageTitleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PageTitleComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PageTitleComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/assets/images/tokens/comp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/core/guards/covalent-auth.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | HttpRequest, 4 | HttpHandler, 5 | HttpEvent, 6 | HttpInterceptor, 7 | } from '@angular/common/http'; 8 | import { Observable } from 'rxjs'; 9 | 10 | const apk = 'ckey_02c001945c67428eaff497033d2'; 11 | 12 | @Injectable() 13 | export class CovalentAuthInterceptor implements HttpInterceptor { 14 | constructor() {} 15 | 16 | intercept( 17 | request: HttpRequest, 18 | next: HttpHandler 19 | ): Observable> { 20 | if (request.url.includes('covalent')) { 21 | request = request.clone({ 22 | setHeaders: { 23 | Authorization: `Basic ${apk}`, 24 | }, 25 | }); 26 | } 27 | return next.handle(request); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-roi/basket-roi.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketRoiComponent } from './basket-roi.component'; 4 | 5 | describe('BasketRoiComponent', () => { 6 | let component: BasketRoiComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BasketRoiComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BasketRoiComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/content-box/content-box.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContentBoxComponent } from './content-box.component'; 4 | 5 | describe('ContentBoxComponent', () => { 6 | let component: ContentBoxComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ContentBoxComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ContentBoxComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/empty-state/empty-state.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { EmptyStateComponent } from './empty-state.component'; 4 | 5 | describe('EmptyStateComponent', () => { 6 | let component: EmptyStateComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [EmptyStateComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(EmptyStateComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/core/models/pool-queries.ts: -------------------------------------------------------------------------------- 1 | export const balancerPoolQuery = ` 2 | { 3 | pools(first: 250, orderBy: liquidity, orderDirection: desc, where: {publicSwap: true}) { 4 | id 5 | totalWeight 6 | tokensList 7 | totalShares 8 | swapsCount 9 | liquidity 10 | tokens { 11 | id 12 | address 13 | balance 14 | symbol 15 | denormWeight 16 | } 17 | } 18 | }`; 19 | 20 | export const uniswapPoolQuery = ` 21 | { 22 | pairs(first: 250, orderBy: trackedReserveETH, orderDirection: desc) { 23 | id, 24 | reserve0, 25 | reserve1, 26 | totalSupply, 27 | trackedReserveETH, 28 | token0 { 29 | id, 30 | symbol, 31 | decimals 32 | }, 33 | token1 { 34 | id, 35 | symbol, 36 | decimals 37 | } 38 | } 39 | }`; 40 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-list/vaults-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultsListComponent } from './vaults-list.component'; 4 | 5 | describe('VaultsListComponent', () => { 6 | let component: VaultsListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [VaultsListComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(VaultsListComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/notification/notification.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NotificationComponent } from './notification.component'; 4 | 5 | describe('NotificationComponent', () => { 6 | let component: NotificationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [NotificationComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(NotificationComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/pipes/categorize.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'categorize', 5 | }) 6 | export class CategorizePipe implements PipeTransform { 7 | constructor(@Inject(LOCALE_ID) private locale: string) {} 8 | 9 | transform(items, category): unknown { 10 | return items.filter((item) => { 11 | let name = item.contract_ticker_symbol || item.contract_name; 12 | if (!name) return true; 13 | if (category == 'token') { 14 | return ( 15 | name.indexOf('LP Token') == -1 || 16 | (name.length > 4 && name.indexOf('LP') == -1) 17 | ); 18 | } else if (category == 'defi') { 19 | //Assumes non-LP 20 | return name.indexOf('LP Token') != -1; 21 | } 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/create-basket/create-basket.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CreateBasketComponent } from './create-basket.component'; 4 | 5 | describe('CreateBasketComponent', () => { 6 | let component: CreateBasketComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CreateBasketComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CreateBasketComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/number-counter/number-counter.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NumberCounterComponent } from './number-counter.component'; 4 | 5 | describe('NumberCounterComponent', () => { 6 | let component: NumberCounterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [NumberCounterComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(NumberCounterComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/exceeded-balance-msg/exceeded-balance-msg.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Token, TokenSymbol } from '../../../core/models/types'; 3 | 4 | @Component({ 5 | selector: 'app-exceeded-balance-msg', 6 | templateUrl: './exceeded-balance-msg.component.html', 7 | styleUrls: ['./exceeded-balance-msg.component.scss'], 8 | }) 9 | export class ExceededBalanceMsgComponent { 10 | @Input() 11 | tokenAmount: number; 12 | @Input() 13 | selectedSymbol: TokenSymbol; 14 | @Input() 15 | tokenBalance: Token; 16 | 17 | hasBalanceForPayment( 18 | paymentValue: number, 19 | selectedToken: TokenSymbol, 20 | token: Token 21 | ): boolean { 22 | if (token.balance > 0) { 23 | return token.balance >= paymentValue; 24 | } 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/core/services/notification.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { MatSnackBar } from '@angular/material/snack-bar'; 3 | import { NotificationComponent } from '../../shared/components/notification/notification.component'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class NotificationService { 9 | constructor(private readonly snackBar: MatSnackBar) {} 10 | 11 | public showNotification( 12 | message: string, 13 | buttonText: string, 14 | type: 'error' | 'success' | 'info' 15 | ): void { 16 | this.snackBar.openFromComponent( 17 | NotificationComponent, 18 | { 19 | data: { 20 | message, 21 | buttonText, 22 | type, 23 | }, 24 | panelClass: type, 25 | } 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/holdings-table/holdings-table.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HoldingsTableComponent } from './holdings-table.component'; 4 | 5 | describe('HoldingsTableComponent', () => { 6 | let component: HoldingsTableComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [HoldingsTableComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(HoldingsTableComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | *.iml 48 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/liquidate-modal/liquidate-modal.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LiquidateModalComponent } from './liquidate-modal.component'; 4 | 5 | describe('LiquidateModalComponent', () => { 6 | let component: LiquidateModalComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [LiquidateModalComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(LiquidateModalComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/asset-distribution-chart/asset-distribution-chart.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 | import * as Highcharts from 'highcharts'; 3 | 4 | @Component({ 5 | selector: 'app-asset-distribution-chart', 6 | templateUrl: './asset-distribution-chart.component.html', 7 | styleUrls: ['./asset-distribution-chart.component.scss'], 8 | }) 9 | export class AssetDistributionChartComponent { 10 | HighCharts: typeof Highcharts = Highcharts; 11 | public options: Highcharts.Options | any = {}; 12 | public updateFlag: boolean; 13 | @Input() set chartData(val: number[][]) { 14 | if (val) { 15 | this.options = val; 16 | this.updateFlag = true; 17 | } 18 | } 19 | @Input() isList = false; 20 | @Output() dateSpanChange = new EventEmitter(); 21 | } 22 | -------------------------------------------------------------------------------- /src/app/shared/components/provider-loading/provider-loading.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ProviderLoadingComponent } from './provider-loading.component'; 4 | 5 | describe('ProviderLoadingComponent', () => { 6 | let component: ProviderLoadingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ProviderLoadingComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ProviderLoadingComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/skeleton-loading/skeleton-loading.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SkeletonLoadingComponent } from './skeleton-loading.component'; 4 | 5 | describe('SkeletonLoadingComponent', () => { 6 | let component: SkeletonLoadingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [SkeletonLoadingComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(SkeletonLoadingComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/home/components/disclaimer-modal/disclaimer-modal.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DisclaimerModalComponent } from './disclaimer-modal.component'; 4 | 5 | describe('DisclaimerModalComponent', () => { 6 | let component: DisclaimerModalComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [DisclaimerModalComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(DisclaimerModalComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-roi-chart/vaults-roi-chart.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultsRoiChartComponent } from './vaults-roi-chart.component'; 4 | 5 | describe('VaultsRoiChartComponent', () => { 6 | let component: VaultsRoiChartComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [VaultsRoiChartComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(VaultsRoiChartComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/sidebar/sidebar.component.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: 100vh; 5 | background: white; 6 | position: fixed; 7 | z-index: 999; 8 | width: 220px; 9 | } 10 | 11 | //.sidebar__label { 12 | // @include media-breakpoint-down(md) { 13 | // display: none; 14 | // } 15 | //} 16 | // 17 | //.sidebar__icon { 18 | // margin-left: 1rem; 19 | // @include media-breakpoint-down(md) { 20 | // margin: 0 5px; 21 | // } 22 | //} 23 | 24 | .sidebar__divider { 25 | background: black; 26 | opacity: 0.4; 27 | width: 90%; 28 | } 29 | 30 | .icon-container { 31 | display: flex; 32 | flex-direction: column; 33 | justify-content: center; 34 | align-items: center; 35 | } 36 | 37 | .menu-item { 38 | transition: 0.3s; 39 | &:hover { 40 | cursor: pointer; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/diversify-vaults/diversify-vaults.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DiversifyVaultsComponent } from './diversify-vaults.component'; 4 | 5 | describe('DiversifyVaultsComponent', () => { 6 | let component: DiversifyVaultsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [DiversifyVaultsComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(DiversifyVaultsComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/address-shortener/address-shortener.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AddressShortenerComponent } from './address-shortener.component'; 4 | 5 | describe('AddressShortenerComponent', () => { 6 | let component: AddressShortenerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [AddressShortenerComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(AddressShortenerComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /src/app/shared/components/percentage-buttons/percentage-buttons.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PercentageButtonsComponent } from './percentage-buttons.component'; 4 | 5 | describe('PercentageButtonsComponent', () => { 6 | let component: PercentageButtonsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PercentageButtonsComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PercentageButtonsComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-composition/basket-composition.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BasketCompositionComponent } from './basket-composition.component'; 4 | 5 | describe('BasketCompositionComponent', () => { 6 | let component: BasketCompositionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BasketCompositionComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BasketCompositionComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-basket-pools/custom-basket-pools.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CustomBasketPoolsComponent } from './custom-basket-pools.component'; 4 | 5 | describe('CustomBasketPoolsComponent', () => { 6 | let component: CustomBasketPoolsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CustomBasketPoolsComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CustomBasketPoolsComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-invest-modal/custom-invest-modal.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CustomInvestModalComponent } from './custom-invest-modal.component'; 4 | 5 | describe('CustomInvestModalComponent', () => { 6 | let component: CustomInvestModalComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CustomInvestModalComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CustomInvestModalComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vaults-composition/vaults-composition.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VaultsCompositionComponent } from './vaults-composition.component'; 4 | 5 | describe('VaultsCompositionComponent', () => { 6 | let component: VaultsCompositionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [VaultsCompositionComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(VaultsCompositionComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/reef-historic-price/reef-historic-price.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ReefHistoricPriceComponent } from './reef-historic-price.component'; 4 | 5 | describe('ReefHistoricPriceComponent', () => { 6 | let component: ReefHistoricPriceComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ReefHistoricPriceComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(ReefHistoricPriceComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/percentage-buttons/percentage-buttons.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import { roundDownTo } from '../../../core/utils/math-utils'; 3 | 4 | @Component({ 5 | selector: 'app-percentage-buttons', 6 | templateUrl: './percentage-buttons.component.html', 7 | styleUrls: ['./percentage-buttons.component.scss'], 8 | }) 9 | export class PercentageButtonsComponent { 10 | /** 11 | * The options that the user would have 12 | * to instantly add coins 13 | */ 14 | public readonly percentages = [0.1, 0.25, 0.5, 0.9]; 15 | @Input() value: number | undefined; 16 | @Output() selectPercentage = new EventEmitter(); 17 | 18 | onSelectPercentage(percentage: number): void { 19 | const val = roundDownTo(this.value * percentage, 3); 20 | this.selectPercentage.emit(val); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/bonds/bonds.page.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component } from '@angular/core'; 2 | import { BondsService } from '../../../../core/services/bonds.service'; 3 | import { UiUtils } from '../../../../shared/utils/ui.utils'; 4 | import { BondSaleStatus, TransactionType } from '../../../../core/models/types'; 5 | import { ConnectorService } from '../../../../core/services/connector.service'; 6 | 7 | @Component({ 8 | selector: 'app-bonds', 9 | templateUrl: './bonds.page.html', 10 | styleUrls: ['./bonds.page.scss'], 11 | changeDetection: ChangeDetectionStrategy.OnPush, 12 | }) 13 | export class BondsPage { 14 | UiUtils = UiUtils; 15 | BondSaleStatus = BondSaleStatus; 16 | TransactionType = TransactionType; 17 | 18 | constructor( 19 | public bondsService: BondsService, 20 | public readonly connectorService: ConnectorService 21 | ) {} 22 | } 23 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-composition/basket-composition.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { 3 | IGenerateBasketResponse, 4 | PoolsChartOptions, 5 | } from '../../../../core/models/types'; 6 | import { ThemePalette } from '@angular/material/core'; 7 | 8 | @Component({ 9 | selector: 'app-basket-composition', 10 | templateUrl: './basket-composition.component.html', 11 | styleUrls: ['./basket-composition.component.scss'], 12 | }) 13 | export class BasketCompositionComponent { 14 | Object = Object; 15 | private mColors: ThemePalette[] = ['primary', 'accent', 'warn']; 16 | @Input() basket: IGenerateBasketResponse | undefined; 17 | @Input() isList = false; 18 | @Input() canCustomize = true; 19 | constructor() {} 20 | 21 | get colors(): ThemePalette[] { 22 | return [...this.mColors, ...this.mColors, ...this.mColors]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/modules/binance/components/binance-register-modal/binance-register-modal.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BinanceRegisterModalComponent } from './binance-register-modal.component'; 4 | 5 | describe('BinanceRegisterModalComponent', () => { 6 | let component: BinanceRegisterModalComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [BinanceRegisterModalComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(BinanceRegisterModalComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/shared/components/pending-transaction-msg/pending-transaction-msg.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PendingTransactionMsgComponent } from './pending-transaction-msg.component'; 4 | 5 | describe('PendingTransactionMsgComponent', () => { 6 | let component: PendingTransactionMsgComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PendingTransactionMsgComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PendingTransactionMsgComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/liquidate-modal/liquidate-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; 3 | import { FormControl } from '@angular/forms'; 4 | 5 | @Component({ 6 | selector: 'app-liquidate-modal', 7 | templateUrl: './liquidate-modal.component.html', 8 | styleUrls: ['./liquidate-modal.component.scss'], 9 | }) 10 | export class LiquidateModalComponent { 11 | public percentage = new FormControl(0); 12 | public isReefStake = new FormControl(false); 13 | constructor( 14 | public dialogRef: MatDialogRef, 15 | @Inject(MAT_DIALOG_DATA) public data: any 16 | ) {} 17 | 18 | onClose(): void { 19 | this.dialogRef.close(); 20 | } 21 | 22 | onLiquidate(): any { 23 | return [...this.data.data, this.percentage.value, this.isReefStake.value]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | import { SharedModule } from './shared/shared.module'; 7 | import { HttpClientModule } from '@angular/common/http'; 8 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 9 | import { CommonModule } from '@angular/common'; 10 | 11 | @NgModule({ 12 | declarations: [AppComponent], 13 | imports: [ 14 | BrowserModule, 15 | AppRoutingModule, 16 | HttpClientModule, 17 | SharedModule, 18 | BrowserAnimationsModule, 19 | CommonModule, 20 | ], 21 | providers: [ 22 | // { provide: HTTP_INTERCEPTORS, useClass: CovalentAuthInterceptor, multi: true }, 23 | ], 24 | bootstrap: [AppComponent], 25 | }) 26 | export class AppModule {} 27 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-roi-chart/vaults-roi-chart.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import * as Highcharts from 'highcharts'; 3 | 4 | @Component({ 5 | selector: 'app-vaults-roi-chart', 6 | templateUrl: './vaults-roi-chart.component.html', 7 | styleUrls: ['./vaults-roi-chart.component.scss'], 8 | }) 9 | export class VaultsRoiChartComponent { 10 | HighCharts: typeof Highcharts = Highcharts; 11 | public options: Highcharts.Options | any = {}; 12 | public updateFlag: boolean; 13 | @Input() set roiChartData(val: number[][]) { 14 | if (val) { 15 | this.options = val; 16 | this.updateFlag = true; 17 | } 18 | } 19 | @Input() isList = false; 20 | @Output() dateSpanChange = new EventEmitter(); 21 | 22 | onDateChange(val: number): void { 23 | this.updateFlag = false; 24 | this.dateSpanChange.emit(val); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/app/shared/components/transaction-confirmation/transaction-confirmation.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TransactionConfirmationComponent } from './transaction-confirmation.component'; 4 | 5 | describe('TransactionConfirmationComponent', () => { 6 | let component: TransactionConfirmationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [TransactionConfirmationComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(TransactionConfirmationComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. 18 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 19 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/asset-distribution-chart/asset-distribution-chart.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AssetDistributionChartComponent } from './asset-distribution-chart.component'; 4 | 5 | describe('AssetDistributionChartComponent', () => { 6 | let component: AssetDistributionChartComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [AssetDistributionChartComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(AssetDistributionChartComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/assets/images/tokens/yfi.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-basket-composition/custom-basket-composition.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CustomBasketCompositionComponent } from './custom-basket-composition.component'; 4 | 5 | describe('CustomBasketCompositionComponent', () => { 6 | let component: CustomBasketCompositionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [CustomBasketCompositionComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(CustomBasketCompositionComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reef Client 2 | 3 | The **official repository** for the Reef Client. 4 | 5 | ## Introduction 6 | 7 | The Reef Client is the software that connects our smart contracts with the browser, and allows communicating via our protocols. It is written in **Angular 10**. 8 | 9 | ## Related Efforts 10 | 11 | - [Reef Protocol](https://github.com/reef-defi/reef-protocol) 12 | - [Reef Baskets API](https://github.com/reef-defi/reef-baskets) 13 | 14 | ## Usage 15 | 16 | To run this project locally, you need to: 17 | 18 | 1. `git clone https://github.com/reef-defi/reef-client.git && cd reef-client` 19 | 2. `npm install` 20 | 3. `ng serve` 21 | 22 | ## Contributing 23 | **Code contributions are welcome!** 24 | To contribute to our project, fork the repo, add a PR and wait for someone from our team to review it. If you encounter some unexpected behavior, open an issue. 25 | 26 | For more info, check out our Telegram group: https://t.me/reefdefi. 27 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/reef-historic-price/reef-historic-price.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import * as Highcharts from 'highcharts'; 3 | 4 | @Component({ 5 | selector: 'app-reef-historic-price', 6 | templateUrl: './reef-historic-price.component.html', 7 | styleUrls: ['./reef-historic-price.component.scss'], 8 | }) 9 | export class ReefHistoricPriceComponent { 10 | HighCharts: typeof Highcharts = Highcharts; 11 | public options: Highcharts.Options | any = {}; 12 | public updateFlag: boolean; 13 | @Input() set chartData(val: number[][]) { 14 | if (val) { 15 | this.options = val; 16 | this.updateFlag = true; 17 | } 18 | } 19 | @Input() priceError: boolean; 20 | @Output() dateSpanChange = new EventEmitter(); 21 | 22 | onDateChange(val: number): void { 23 | this.updateFlag = false; 24 | this.dateSpanChange.emit(val); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/app/modules/vaults/pages/vaults/vaults.page.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 10 |
11 |
12 | 16 |
17 |
18 |
19 |
20 | 24 |
25 |
26 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/holdings-table/holdings-table.component.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | 3 | .table-min-w-up-to-lg { 4 | min-width: 100%; 5 | border-top: solid 1px #ccc; 6 | margin-top: 0.5em; 7 | } 8 | 9 | .hide-lg { 10 | display: none; 11 | } 12 | 13 | // used same as .table-responsive-lg 14 | @media (max-width: 991.98px) { 15 | .table-min-w-up-to-lg { 16 | min-width: 650px; 17 | } 18 | .hide-lg { 19 | display: block; 20 | } 21 | } 22 | 23 | .x-wide-cell { 24 | min-width: 210px; 25 | } 26 | 27 | .m-wide-cell { 28 | min-width: 60px; 29 | } 30 | 31 | .align-to-icon { 32 | margin-left: 0.2em; 33 | position: relative; 34 | bottom: 0.5em; 35 | } 36 | 37 | .asset-icon { 38 | margin-right: 0.3em; 39 | } 40 | 41 | .asset-row { 42 | border-bottom: #efefef 1px solid; 43 | padding: 0.5em; 44 | margin-bottom: 0.2em; 45 | } 46 | 47 | .no-price-icon { 48 | font-size: 1.4em; 49 | } 50 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-roi/basket-roi.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import * as Highcharts from 'highcharts'; 3 | 4 | @Component({ 5 | selector: 'app-basket-roi', 6 | templateUrl: './basket-roi.component.html', 7 | styleUrls: ['./basket-roi.component.scss'], 8 | }) 9 | export class BasketRoiComponent { 10 | HighCharts: typeof Highcharts = Highcharts; 11 | public updateFlag: boolean; 12 | public options: Highcharts.Options | any = {}; 13 | @Input() set roiData(val: number[][]) { 14 | if (val) { 15 | this.options = val; 16 | this.updateFlag = true; 17 | } 18 | } 19 | @Input() activeTimeSpan = 1; 20 | @Input() isList = false; 21 | @Output() dateSpanChange = new EventEmitter(); 22 | 23 | constructor() {} 24 | 25 | onDateSpanChange(val: number): void { 26 | this.updateFlag = false; 27 | this.dateSpanChange.emit(val); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/modules/baskets/baskets-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { CreateBasketPage } from './pages/create-basket/create-basket.page'; 4 | import { CustomBasketPage } from './pages/custom-basket/custom-basket.page'; 5 | import { BasketsPage } from './pages/baskets/baskets.page'; 6 | import { BasketTypesPage } from './pages/basket-types/basket-types.page'; 7 | 8 | const routes: Routes = [ 9 | { 10 | path: '', 11 | component: BasketsPage, 12 | }, 13 | { 14 | path: 'create-basket', 15 | component: CreateBasketPage, 16 | }, 17 | { 18 | path: 'custom-basket', 19 | component: CustomBasketPage, 20 | }, 21 | { 22 | path: 'basket-types', 23 | component: BasketTypesPage, 24 | }, 25 | ]; 26 | 27 | @NgModule({ 28 | imports: [RouterModule.forChild(routes)], 29 | exports: [RouterModule], 30 | }) 31 | export class BasketsRoutingModule {} 32 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async () => { 7 | await TestBed.configureTestingModule({ 8 | imports: [RouterTestingModule], 9 | declarations: [AppComponent], 10 | }).compileComponents(); 11 | }); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it('should render title', () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | fixture.detectChanges(); 22 | const compiled = fixture.nativeElement; 23 | expect(compiled.querySelector('.content span').textContent).toContain( 24 | 'reef-app-v2 app is running!' 25 | ); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/diversify-vaults/diversify-vaults.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-diversify-vaults', 6 | templateUrl: './diversify-vaults.component.html', 7 | styleUrls: ['./diversify-vaults.component.scss'], 8 | }) 9 | export class DiversifyVaultsComponent { 10 | @Input() ethAmount: FormControl | undefined; 11 | @Input() ethBalance: string | undefined; 12 | @Output() invest = new EventEmitter(); 13 | @Output() diversifyChange = new EventEmitter(); 14 | @Output() percentageChange = new EventEmitter(); 15 | 16 | onInvest(): void { 17 | this.invest.emit(); 18 | } 19 | 20 | onDiversifyChange(amount: number): void { 21 | this.diversifyChange.emit(amount); 22 | } 23 | 24 | onPercentageChange(amount: number): void { 25 | this.percentageChange.emit(amount); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /patch.js: -------------------------------------------------------------------------------- 1 | // Angular >= 11 2 | /*const fs = require('fs') 3 | const f = 'node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js' 4 | 5 | fs.readFile(f, 'utf8', function(err, data) { 6 | if (err) { 7 | return console.log(err) 8 | } 9 | var result = data.replace(/node: false/g, 'node: {crypto: true, stream: true, fs: "empty"}') 10 | 11 | fs.writeFile(f, result, 'utf8', function(err) { 12 | if (err) return console.log(err) 13 | }) 14 | });*/ 15 | // ---- 16 | 17 | // For Angular <11 18 | const fs = require('fs'); 19 | const f = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js'; 20 | 21 | fs.readFile(f, 'utf8', function (err,data) { 22 | if (err) { 23 | return console.log(err); 24 | } 25 | var result = data.replace(/node: false/g, 'node: {crypto: true, stream: true}'); 26 | 27 | fs.writeFile(f, result, 'utf8', function (err) { 28 | if (err) return console.log(err); 29 | }); 30 | }); 31 | // ---- 32 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-basket-composition/custom-basket-composition.component.scss: -------------------------------------------------------------------------------- 1 | .slider { 2 | margin-top: -25px; 3 | } 4 | 5 | .position-warning-icon { 6 | font-size: 1.8em; 7 | } 8 | 9 | ::ng-deep { 10 | .mat-slider { 11 | padding: 0px !important; 12 | } 13 | 14 | .mat-slider.mat-slider-horizontal .mat-slider-track-wrapper { 15 | height: 3px; 16 | border-radius: 3px; 17 | } 18 | 19 | .mat-slider.mat-slider-horizontal .mat-slider-track-background, 20 | .mat-slider.mat-slider-horizontal .mat-slider-track-fill { 21 | height: 25px; 22 | } 23 | 24 | .mat-accent .mat-slider-thumb { 25 | height: 20px; 26 | width: 20px; 27 | background-color: #6610f2 !important; 28 | bottom: -10px; 29 | right: -9px; 30 | } 31 | 32 | .mat-slider.mat-slider-horizontal .mat-slider-track-fill { 33 | background-color: #6610f2; 34 | } 35 | 36 | .mat-slider-track-background { 37 | background: #f3f3f3 !important; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/pages/settings/settings.page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ConnectorService } from '../../../../core/services/connector.service'; 3 | import { ApiService } from '../../../../core/services/api.service'; 4 | import { UniswapService } from '../../../../core/services/uniswap.service'; 5 | 6 | @Component({ 7 | selector: 'app-settings', 8 | templateUrl: './settings.page.html', 9 | styleUrls: ['./settings.page.scss'], 10 | }) 11 | export class SettingsPage { 12 | Object = Object; 13 | readonly selectedGas$ = this.connectorService.selectedGasPrice$; 14 | readonly gasPrices$ = this.apiService.getGasPrices(); 15 | 16 | constructor( 17 | readonly uniswapService: UniswapService, 18 | private readonly connectorService: ConnectorService, 19 | private readonly apiService: ApiService 20 | ) {} 21 | 22 | public setGas(type: string, price: number): void { 23 | this.connectorService.setSelectedGas(type, price); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app/modules/vaults/vaults.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { VaultsRoutingModule } from './vaults-routing.module'; 5 | import { VaultsPage } from './pages/vaults/vaults.page'; 6 | import { SharedModule } from '../../shared/shared.module'; 7 | import { DiversifyVaultsComponent } from './components/diversify-vaults/diversify-vaults.component'; 8 | import { VaultsListComponent } from './components/vaults-list/vaults-list.component'; 9 | import { VaultsRoiChartComponent } from './components/vaults-roi-chart/vaults-roi-chart.component'; 10 | 11 | const pages = [VaultsPage]; 12 | const components = [ 13 | DiversifyVaultsComponent, 14 | VaultsListComponent, 15 | VaultsRoiChartComponent, 16 | ]; 17 | 18 | @NgModule({ 19 | declarations: [...pages, ...components], 20 | exports: [VaultsRoiChartComponent], 21 | imports: [CommonModule, VaultsRoutingModule, SharedModule], 22 | }) 23 | export class VaultsModule {} 24 | -------------------------------------------------------------------------------- /src/app/shared/components/unsupported-chain-msg/unsupported-chain-msg.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; 2 | import { ChainId, TransactionType } from '../../../core/models/types'; 3 | import { getChainData } from '../../../core/utils/chains'; 4 | import { TransactionsService } from '../../../core/services/transactions.service'; 5 | 6 | @Component({ 7 | selector: 'app-unsupported-chain-msg', 8 | templateUrl: './unsupported-chain-msg.component.html', 9 | styleUrls: ['./unsupported-chain-msg.component.scss'], 10 | changeDetection: ChangeDetectionStrategy.OnPush, 11 | }) 12 | export class UnsupportedChainMsgComponent { 13 | @Input() transactionType: TransactionType | undefined; 14 | @Input() chainId: ChainId | undefined; 15 | @Input() displayUnsupportedChainIdMessage: boolean; 16 | TransactionsService = TransactionsService; 17 | ChainId = ChainId; 18 | 19 | public getChainName(chainId: number): string { 20 | return getChainData(chainId).name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ 31 | spec: { 32 | displayStacktrace: StacktraceOption.PRETTY 33 | } 34 | })); 35 | } 36 | }; -------------------------------------------------------------------------------- /src/app/core/utils/provider-name.ts: -------------------------------------------------------------------------------- 1 | export const getProviderName = (web3: any, provider: any): string => { 2 | if (!web3) { 3 | return 'unknown'; 4 | } 5 | if (web3.currentProvider.isMetaMask) { 6 | return 'MetaMask'; 7 | } 8 | 9 | if (web3.currentProvider.isTrust) { 10 | return 'Trust'; 11 | } 12 | 13 | if (web3.currentProvider.isGoWallet) { 14 | return 'Go Wallet'; 15 | } 16 | 17 | if (web3.currentProvider.isAlphaWallet) { 18 | return 'Alpha Wallet'; 19 | } 20 | 21 | if (web3.currentProvider.isStatus) { 22 | return 'Status'; 23 | } 24 | 25 | if (web3.currentProvider.isToshi) { 26 | return 'Coinbase'; 27 | } 28 | 29 | if (web3.currentProvider.isTorus) { 30 | return 'Torus'; 31 | } 32 | 33 | if (web3.currentProvider.constructor.name === 'WalletConnectProvider') { 34 | return 'Wallet Connect'; 35 | } 36 | 37 | if ( 38 | provider.bridge && 39 | provider.bridge === 'https://bridge.walletconnect.org' 40 | ) { 41 | return 'Wallet Connect'; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /src/app/shared/components/header/header.component.html: -------------------------------------------------------------------------------- 1 |
2 | 27 |
28 | -------------------------------------------------------------------------------- /src/app/shared/components/unsupported-chain-msg/unsupported-chain-msg.component.html: -------------------------------------------------------------------------------- 1 |
13 |
14 | 15 | 16 |
17 | This functionality is currently not supported on 18 | {{ getChainName(chainId) }}. 20 | 21 | You can find {{ getChainName(chainId) }} 22 | bonds here. 23 | 24 |
25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assets/images/tokens/usdc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/set-input-relative-amount/set-input-relative-amount.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import { TokenSymbol } from '../../../core/models/types'; 3 | import { TokenUtil } from '../../utils/token.util'; 4 | 5 | @Component({ 6 | selector: 'app-set-input-relative-amount', 7 | templateUrl: './set-input-relative-amount.component.html', 8 | styleUrls: ['./set-input-relative-amount.component.scss'], 9 | }) 10 | export class SetInputRelativeAmountComponent { 11 | private _tokenSymbol: TokenSymbol | string; 12 | @Input() 13 | value: number; 14 | 15 | @Input() set tokenSymbol(val: TokenSymbol | string) { 16 | this._tokenSymbol = TokenUtil.parseLPTokenName(val); 17 | } 18 | 19 | get tokenSymbol(): TokenSymbol | string { 20 | return this._tokenSymbol; 21 | } 22 | 23 | @Output() 24 | valueChange = new EventEmitter(); 25 | 26 | @Output() 27 | refreshBalance = new EventEmitter(); 28 | 29 | TokenSymbol = TokenSymbol; 30 | TokenUtil = TokenUtil; 31 | } 32 | -------------------------------------------------------------------------------- /src/app/shared/components/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | EventEmitter, 4 | HostListener, 5 | Input, 6 | OnInit, 7 | Output, 8 | } from '@angular/core'; 9 | import { EthPrice, IProviderUserInfo } from '../../../core/models/types'; 10 | 11 | @Component({ 12 | selector: 'app-header', 13 | templateUrl: './header.component.html', 14 | styleUrls: ['./header.component.scss'], 15 | }) 16 | export class HeaderComponent implements OnInit { 17 | public isMobileLayout: boolean; 18 | @HostListener('window:resize', []) 19 | onResize(): void { 20 | this.isMobileLayout = window.innerWidth < 992; 21 | } 22 | @Input() version: string | undefined; 23 | @Input() providerName: string | undefined; 24 | @Input() providerUserInfo: IProviderUserInfo | undefined; 25 | @Input() ethPrice: EthPrice | undefined; 26 | @Output() signOut = new EventEmitter(); 27 | 28 | constructor() {} 29 | 30 | ngOnInit(): void { 31 | this.isMobileLayout = window.innerWidth < 992; 32 | } 33 | 34 | onSignOut(): void { 35 | this.signOut.emit(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-invest-modal/custom-invest-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; 3 | import { FormControl } from '@angular/forms'; 4 | 5 | @Component({ 6 | selector: 'app-custom-invest-modal', 7 | templateUrl: './custom-invest-modal.component.html', 8 | styleUrls: ['./custom-invest-modal.component.scss'], 9 | }) 10 | export class CustomInvestModalComponent { 11 | public ethAmount = new FormControl(0); 12 | 13 | constructor( 14 | public dialogRef: MatDialogRef, 15 | @Inject(MAT_DIALOG_DATA) public data: any 16 | ) {} 17 | 18 | onClose(): void { 19 | this.dialogRef.close(); 20 | } 21 | 22 | onInvest(): number { 23 | return this.ethAmount.value; 24 | } 25 | 26 | onNumberInput() { 27 | if (this.ethAmount.value > 100) { 28 | this.ethAmount.patchValue(100); 29 | } 30 | if (this.ethAmount.value && this.ethAmount.value < 1) { 31 | this.ethAmount.patchValue(1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/modules/binance/components/binance-register-modal/binance-register-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ data.action === 'register' ? 'Register with ' : 'Bind account using ' }} 4 |
5 | binance logo 11 |
12 |
13 |
Enter your email
14 | 22 |
23 |
24 | 25 | 32 |
33 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 9 |
10 |
11 | 18 |
23 | 24 |
25 | 26 |
27 |
28 | 29 | Connecting to Wallet 30 | 31 |
32 | -------------------------------------------------------------------------------- /src/app/shared/components/info-modal/info-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 | 16 |
17 |
{{ data?.title }}
18 |

19 | {{ data?.message }} 20 |

21 |
22 | 35 |
36 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | import {LogLevel} from '../app/shared/utils/dev-util-log-level'; 2 | 3 | export const environment = { 4 | production: true, 5 | logLevel: LogLevel.WARNING, 6 | reefApiUrl: 'https://baskets.reef.finance/v1', 7 | reefBinanceApiUrl: 'http://localhost:3000/v1', 8 | balancerPoolUrl: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer', 9 | ethPriceUrl: 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd', 10 | curvePoolUrl: 'https://www.curve.fi/raw-stats/apys.json', 11 | uniswapPoolUrl: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2', 12 | gasPriceUrl: 'https://www.etherchain.org/api/gasPriceOracle', 13 | cmcReefPriceUrl: 'https://web-api.coinmarketcap.com/v1/cryptocurrency/market-pairs/latest?slug=reef&start=1&limit=6&convert=USD', 14 | reefNodeApiUrl: 'https://node-api.reef.finance/api', 15 | // reefNodeApiUrl: 'https://reef-node-api-jfwccyl2mq-nw.a.run.app/api', 16 | infuraApiKey: '395d6f5d9a324c799a3becf85449122a', 17 | alchemyApiKey: 'yxcjm59ypt3tMf4SBUa8-wbrMtgrtesF', 18 | coinGeckoApiUrl: 'https://api.coingecko.com/api/v3', 19 | }; 20 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/reef-app-v2'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-invest-modal/custom-invest-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 |
Satisfied with your basket?
3 | 6 |
7 | 18 | 19 |
20 |
21 | 22 | Minimum 1 ETH, up to 100ETH. 23 | 24 |
25 |
26 | 27 | 30 |
31 |
32 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/create-basket/create-basket.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-create-basket', 6 | templateUrl: './create-basket.component.html', 7 | styleUrls: ['./create-basket.component.scss'], 8 | }) 9 | export class CreateBasketComponent { 10 | @Input() ethAmount: FormControl | undefined; 11 | @Input() riskAmount: FormControl | undefined; 12 | @Input() ethBalance: string; 13 | @Input() minimalInvestment: string | undefined; 14 | @Input() maximumInvestment: string | undefined; 15 | @Output() invest = new EventEmitter(); 16 | @Output() selectPercentage = new EventEmitter(); 17 | 18 | onInvest(): void { 19 | this.invest.emit(); 20 | } 21 | 22 | onPercentageChange(val: number): void { 23 | this.selectPercentage.emit(val); 24 | } 25 | 26 | onNumberInput() { 27 | if (this.ethAmount.value > 100) { 28 | this.ethAmount.patchValue(100); 29 | } 30 | if (this.ethAmount.value && this.ethAmount.value < 1) { 31 | this.ethAmount.patchValue(1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/custom-basket-composition/custom-basket-composition.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 | import { IGenerateBasketResponse } from '../../../../core/models/types'; 3 | import { ThemePalette } from '@angular/material/core'; 4 | 5 | @Component({ 6 | selector: 'app-custom-basket-composition', 7 | templateUrl: './custom-basket-composition.component.html', 8 | styleUrls: ['./custom-basket-composition.component.scss'], 9 | }) 10 | export class CustomBasketCompositionComponent { 11 | Object = Object; 12 | @Input() basket: IGenerateBasketResponse | undefined; 13 | @Input() disabledSlider: boolean | undefined; 14 | @Input() errorSymbol: string; 15 | @Output() removePool = new EventEmitter(); 16 | @Output() invest = new EventEmitter(); 17 | @Output() changeAllocation = new EventEmitter(); 18 | 19 | onRemovePool(symbol: string): void { 20 | this.removePool.emit(symbol); 21 | } 22 | 23 | onInvest(): void { 24 | this.invest.emit(); 25 | } 26 | 27 | onAllocChange(symbol: string, event: any): void { 28 | this.changeAllocation.emit([symbol, event]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/shared/pipes/decimal.pipe.ts: -------------------------------------------------------------------------------- 1 | import { formatNumber } from '@angular/common'; 2 | import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'; 3 | import { TokenSymbol } from '../../core/models/types'; 4 | 5 | @Pipe({ 6 | name: 'decimal', 7 | }) 8 | export class DecimalNumberPipe implements PipeTransform { 9 | constructor(@Inject(LOCALE_ID) private locale: string) {} 10 | 11 | transform(amount: number, price: number, token?: TokenSymbol): string { 12 | if (token && token === TokenSymbol.ETH) { 13 | return formatNumber(amount, this.locale, `1.0-5`); 14 | } 15 | if (amount * price < 1) { 16 | return formatNumber(amount, this.locale, `1.0-5`); 17 | } 18 | if (price < 1) { 19 | return formatNumber(amount, this.locale, `1.0-5`); 20 | } 21 | if (price < 10) { 22 | return formatNumber(amount, this.locale, `1.0-2`); 23 | } 24 | if (price > 100 && price < 1000) { 25 | return formatNumber(amount, this.locale, `1.0-2`); 26 | } 27 | if (price > 1000 || amount > 1000) { 28 | return formatNumber(amount, this.locale, `1.0-0`); 29 | } 30 | return formatNumber(amount, this.locale, `1.0-5`); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/app/shared/components/notification/notification.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{ data.message }} 4 |
5 |
6 | 13 |
14 |
15 | 16 | 17 |
Success
18 |
19 | {{ data.message }} 20 |
21 |
22 | 25 |
26 |
27 | 28 | 29 |
30 | {{ data.message }} 31 |
32 |
33 | 36 |
37 |
38 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { DashboardRoutingModule } from './dashboard-routing.module'; 5 | import { DashboardPage } from './pages/dashboard/dashboard.page'; 6 | import { SharedModule } from '../../shared/shared.module'; 7 | import { SettingsPage } from './pages/settings/settings.page'; 8 | import { AssetDistributionChartComponent } from './components/asset-distribution-chart/asset-distribution-chart.component'; 9 | import { HoldingsTableComponent } from './components/holdings-table/holdings-table.component'; 10 | import { PortfolioPositionsComponent } from './components/holdings-table/portfolio-positions/portfolio-positions.component'; 11 | import { PriceNotSupportedDialogComponent } from './components/price-not-supported-dialog/price-not-supported-dialog.component'; 12 | 13 | @NgModule({ 14 | declarations: [ 15 | DashboardPage, 16 | SettingsPage, 17 | AssetDistributionChartComponent, 18 | HoldingsTableComponent, 19 | PortfolioPositionsComponent, 20 | PriceNotSupportedDialogComponent, 21 | ], 22 | imports: [CommonModule, DashboardRoutingModule, SharedModule], 23 | }) 24 | export class DashboardModule {} 25 | -------------------------------------------------------------------------------- /src/app/shared/utils/date-time.util.ts: -------------------------------------------------------------------------------- 1 | import { Duration, intervalToDuration, isAfter } from 'date-fns'; 2 | 3 | export class DateTimeUtil { 4 | public static getPositiveTimeDiff( 5 | startDate: Date | string | number, 6 | endDate: Date | string | number 7 | ): Duration { 8 | startDate = DateTimeUtil.toDate(startDate); 9 | endDate = DateTimeUtil.toDate(endDate); 10 | 11 | if (!isAfter(endDate, startDate)) { 12 | return null; 13 | } 14 | return intervalToDuration({ start: startDate, end: endDate }); 15 | } 16 | 17 | static toDate(dateVal: number | string | Date): Date { 18 | if (dateVal instanceof Date) { 19 | return dateVal; 20 | } 21 | 22 | if ( 23 | typeof dateVal === 'string' && 24 | dateVal.indexOf(':') < 0 && 25 | !isNaN(parseInt(dateVal, 10)) 26 | ) { 27 | dateVal = parseInt(dateVal, 10); 28 | } 29 | return new Date(dateVal); 30 | } 31 | 32 | static toJSTimestamp(blockchainTimestamp: number) { 33 | return blockchainTimestamp * 1000; 34 | } 35 | 36 | static isInFuture(time: number): boolean { 37 | const now = new Date(); 38 | const compareTo = DateTimeUtil.toDate(time); 39 | return compareTo.getTime() > now.getTime(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-roi-chart/vaults-roi-chart.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
VAULTS HISTORIC SIMULATED PERFORMANCE
4 |
5 |
6 |
7 | 8 | 13 | Last {{ time }} month(s) 14 | 15 | 16 |
17 |
18 |
19 | 25 |
26 |
27 |
28 |
29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/app/shared/components/countdown-timer/countdown-timer.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; 2 | import { Observable, ReplaySubject, timer } from 'rxjs'; 3 | import { map, shareReplay, withLatestFrom } from 'rxjs/operators'; 4 | import { DateTimeUtil } from '../../utils/date-time.util'; 5 | 6 | @Component({ 7 | selector: 'app-countdown-timer', 8 | templateUrl: './countdown-timer.component.html', 9 | styleUrls: ['./countdown-timer.component.scss'], 10 | changeDetection: ChangeDetectionStrategy.OnPush, 11 | }) 12 | export class CountdownTimerComponent { 13 | expiredDateSub = new ReplaySubject(); 14 | 15 | @Input() 16 | set expiresDate(val: Date | string) { 17 | this.expiredDateSub.next(DateTimeUtil.toDate(val)); 18 | } 19 | 20 | @Input() 21 | accentColor: boolean; 22 | 23 | expiresCountdownTime$ = timer(0, 1000).pipe( 24 | map((_) => new Date()), 25 | withLatestFrom(this.expiredDateSub), 26 | map(([currTime, expiresDate]: [Date, Date]) => { 27 | return DateTimeUtil.getPositiveTimeDiff(currTime, expiresDate); 28 | }), 29 | shareReplay(1) 30 | ) as Observable<{ 31 | days: number; 32 | hours: number; 33 | minutes: number; 34 | seconds: number; 35 | }>; 36 | } 37 | -------------------------------------------------------------------------------- /src/app/core/services/pool.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { environment } from '../../../environments/environment'; 4 | import { balancerPoolQuery, uniswapPoolQuery } from '../models/pool-queries'; 5 | import { combineLatest, Observable, timer } from 'rxjs'; 6 | import { shareReplay, switchMap } from 'rxjs/operators'; 7 | 8 | @Injectable({ 9 | providedIn: 'root', 10 | }) 11 | export class PoolService { 12 | private static ETH_PRICE_REFRESH_INTERVAL = 60000; 13 | 14 | ethPrice$: Observable = timer( 15 | 0, 16 | PoolService.ETH_PRICE_REFRESH_INTERVAL 17 | ).pipe( 18 | switchMap(() => this.http.get(environment.ethPriceUrl)), 19 | shareReplay(1) 20 | ); 21 | 22 | constructor(private readonly http: HttpClient) {} 23 | 24 | getAllPools(): Observable { 25 | return combineLatest(this.getUniPool(), this.getBalancerPool()); 26 | } 27 | 28 | getUniPool(): Observable { 29 | const query = uniswapPoolQuery; 30 | return this.http.post(environment.uniswapPoolUrl, { query }); 31 | } 32 | 33 | getBalancerPool(): Observable { 34 | const query = balancerPoolQuery; 35 | return this.http.post(environment.balancerPoolUrl, { query }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app/shared/utils/http-util.ts: -------------------------------------------------------------------------------- 1 | import { filter, map } from 'rxjs/operators'; 2 | import { HttpEventType, HttpResponse } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | export class HttpUtil { 6 | static REQ_LOADING_EVENT_OPTIONS = { 7 | reportProgress: true, 8 | observe: 'events', 9 | }; 10 | 11 | static withInitLoadingRequestValue( 12 | httpRequestObservable: Observable, 13 | initLoadingValue: any = null 14 | ): Observable { 15 | return httpRequestObservable.pipe( 16 | filter((v) => { 17 | return !( 18 | v.type === HttpEventType.ResponseHeader || 19 | v.type === HttpEventType.DownloadProgress || 20 | v.type === HttpEventType.UploadProgress || 21 | v.type === HttpEventType.User 22 | ); 23 | }), 24 | map((v: HttpResponse) => { 25 | // @ts-ignore 26 | if (v.type === HttpEventType.Sent) { 27 | return initLoadingValue; 28 | } 29 | if (v.type === HttpEventType.Response) { 30 | if (v.status >= 200 && v.status < 300) { 31 | return v.body; 32 | } else { 33 | throw new Error('Request error ' + v.status); 34 | } 35 | } 36 | return null; 37 | }) 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/app/shared/utils/provider.util.ts: -------------------------------------------------------------------------------- 1 | import { ProviderName } from '../../core/models/types'; 2 | import { provider } from '../../../assets/providers'; 3 | 4 | // TODO currently the provider params are defined 5 | // before metamask connects - if there is a way to set provider 6 | // from metamask values in connector.service use these methods to get provider based on chainId 7 | export class ProviderUtil { 8 | static getProviderApiKey(providerName: ProviderName): string { 9 | const apiKey = provider[providerName].apiKey; 10 | if (!apiKey) { 11 | throw new Error( 12 | 'No provider apiKey defined for providerName=' + providerName 13 | ); 14 | } 15 | return apiKey; 16 | } 17 | 18 | static getProviderUrl(providerName: ProviderName): string { 19 | const url = provider[providerName].url; 20 | if (!url) { 21 | throw new Error( 22 | 'No provider url defined for providerName=' + providerName 23 | ); 24 | } 25 | return url; 26 | } 27 | 28 | static getProviderChainId(providerName: ProviderName): number { 29 | const chainId = provider[providerName].chainId; 30 | if (!chainId) { 31 | throw new Error( 32 | 'No provider chainId defined for providerName=' + providerName 33 | ); 34 | } 35 | return chainId; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/app/core/guards/wallet.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | ActivatedRouteSnapshot, 4 | CanActivate, 5 | Router, 6 | RouterStateSnapshot, 7 | UrlTree, 8 | } from '@angular/router'; 9 | import { Observable } from 'rxjs'; 10 | import { ConnectorService } from '../services/connector.service'; 11 | import { NotificationService } from '../services/notification.service'; 12 | 13 | @Injectable({ 14 | providedIn: 'root', 15 | }) 16 | export class WalletGuard implements CanActivate { 17 | constructor( 18 | public readonly connectorService: ConnectorService, 19 | private readonly notificationService: NotificationService, 20 | private readonly router: Router 21 | ) {} 22 | 23 | canActivate( 24 | route: ActivatedRouteSnapshot, 25 | state: RouterStateSnapshot 26 | ): 27 | | Observable 28 | | Promise 29 | | boolean 30 | | UrlTree { 31 | if (!this.connectorService.currentProviderName$.value) { 32 | this.notificationService.showNotification( 33 | 'Connect your wallet to proceed', 34 | 'Okay', 35 | 'info' 36 | ); 37 | setTimeout(() => { 38 | this.router.navigate(['/']); 39 | }, 1000); 40 | return false; 41 | } 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/components/holdings-table/holdings-table.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { 4 | ChainId, 5 | ExchangeId, 6 | IChainData, 7 | IPortfolio, 8 | IProviderUserInfo, 9 | TokenSymbol, 10 | } from '../../../../core/models/types'; 11 | import { MatDialog } from '@angular/material/dialog'; 12 | import { PriceNotSupportedDialogComponent } from '../price-not-supported-dialog/price-not-supported-dialog.component'; 13 | 14 | @Component({ 15 | selector: 'app-holdings-table', 16 | templateUrl: './holdings-table.component.html', 17 | styleUrls: ['./holdings-table.component.scss'], 18 | }) 19 | export class HoldingsTableComponent { 20 | ChainId = ChainId; 21 | TokenSymbol = TokenSymbol; 22 | ExchangeId = ExchangeId; 23 | @Input() chainInfo: IChainData | undefined; 24 | @Input() portfolio: IPortfolio; 25 | 26 | constructor(private readonly router: Router, private dialog: MatDialog) {} 27 | 28 | goToReef() { 29 | this.router.navigate(['/reef/buy']); 30 | } 31 | 32 | isPriceSupported(chainId: ChainId) { 33 | return this.chainInfo.chain_id === ChainId.MAINNET; 34 | } 35 | 36 | noPriceDialog() { 37 | const dialogRef = this.dialog.open(PriceNotSupportedDialogComponent); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/shared/data/walkthrough_steps.ts: -------------------------------------------------------------------------------- 1 | export const hintSteps = [ 2 | { 3 | 'next #dashboardBtn': `Analyze your portfolio, view transactions and much more.`, 4 | nextButton: { className: 'regular', text: 'Next' }, 5 | showNext: true, 6 | showSkip: false, 7 | showPrev: false, 8 | }, 9 | { 10 | 'next #buyReef': `Buy REEF via REEF/ETH & REEF/USDT pools using our Uniswap Integration`, 11 | nextButton: { className: 'regular', text: 'Next' }, 12 | showNext: true, 13 | showSkip: false, 14 | showPrev: false, 15 | }, 16 | { 17 | 'next #reefLiquidity': `Provide liquidity to REEF's USDT & ETH Pools`, 18 | nextButton: { className: 'regular', text: 'Next' }, 19 | showNext: true, 20 | showSkip: false, 21 | showPrev: false, 22 | }, 23 | { 24 | 'next #bonds': `Lock your tokens for a defined time, gaining some sweet APY.`, 25 | nextButton: { className: 'regular', text: 'Next' }, 26 | showNext: false, 27 | showSkip: false, 28 | showPrev: false, 29 | }, 30 | { 31 | 'next #reefCard': `Interested in spending your REEF through our VISA REEF card? Express it here.`, 32 | nextButton: { className: 'regular', text: 'Next' }, 33 | skipButton: { className: 'danger', text: 'Done' }, 34 | showNext: false, 35 | showSkip: true, 36 | showPrev: false, 37 | }, 38 | ]; 39 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/stake-reef/stake-reef.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
Stake Reef and EARN Interest
5 |
Enter your amount
6 |
7 | 13 | eth-logo 19 |
20 |
21 |
22 |
Yield
23 |
24 | 25 |
Pool APY
26 |
13%
27 |
28 |
29 |
30 |
31 | 38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef-menu/reef-menu.page.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ConnectorService } from '../../../../core/services/connector.service'; 3 | import { ApiService } from '../../../../core/services/api.service'; 4 | import { first } from 'rxjs/internal/operators/first'; 5 | import { Token, TokenSymbol } from '../../../../core/models/types'; 6 | import { Observable } from 'rxjs'; 7 | import { TokenBalanceService } from '../../../../shared/service/token-balance.service'; 8 | 9 | @Component({ 10 | selector: 'app-reef-menu', 11 | templateUrl: './reef-menu.page.html', 12 | styleUrls: ['./reef-menu.page.scss'], 13 | }) 14 | export class ReefMenuPage implements OnInit { 15 | readonly providerUserInfo$ = this.connectorService.providerUserInfo$; 16 | reefBalance$: Observable; 17 | 18 | constructor( 19 | private readonly connectorService: ConnectorService, 20 | private readonly apiService: ApiService, 21 | private readonly tokenBalanceService: TokenBalanceService 22 | ) {} 23 | 24 | ngOnInit(): void { 25 | this.connectorService.providerUserInfo$ 26 | .pipe(first((ev) => !!ev)) 27 | .subscribe(({ address }) => { 28 | this.reefBalance$ = this.tokenBalanceService.getTokenBalance$( 29 | address, 30 | TokenSymbol.REEF 31 | ); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/shared/components/skeleton-loading/skeleton-loading.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | type LoaderType = 4 | | 'composition' 5 | | 'vault' 6 | | 'transaction' 7 | | 'chart' 8 | | 'basket' 9 | | 'circle'; 10 | 11 | @Component({ 12 | selector: 'app-skeleton-loading', 13 | templateUrl: './skeleton-loading.component.html', 14 | styleUrls: ['./skeleton-loading.component.scss'], 15 | }) 16 | export class SkeletonLoadingComponent implements OnInit { 17 | @Input() type: LoaderType; 18 | @Input() count = 1; 19 | @Input() animation = 'progress'; 20 | @Input() appearance = ''; 21 | public styles: { [key: string]: { [key: string]: string } } = { 22 | composition: { 23 | height: '30px', 24 | }, 25 | vault: { 26 | height: '30px', 27 | 'background-color': 'rgb(124, 181, 236, 0.2)', 28 | }, 29 | chart: { 30 | 'margin-top': '0', 31 | 'border-top': '1px white', 32 | height: '50px', 33 | 'background-color': 'rgb(124, 181, 236, 0.2)', 34 | }, 35 | transactions: { 36 | height: '15px', 37 | 'background-color': 'rgb(132, 132, 132, 0.1)', 38 | }, 39 | basket: { 40 | height: '300px', 41 | }, 42 | circle: { 43 | height: '65px', 44 | width: '65px', 45 | }, 46 | }; 47 | 48 | constructor() {} 49 | 50 | ngOnInit(): void {} 51 | } 52 | -------------------------------------------------------------------------------- /src/app/modules/baskets/pages/create-basket/create-basket.page.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Be advised that this is the very first version of our baskets engine, thus 4 | there are some programmatic limits to it. We recommend investing smaller 5 | amounts. 6 |
7 |
8 |
9 |
16 | 25 | 26 |
27 |
28 | 29 |
30 |
31 |
32 |
33 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/reef/reef.page.html: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | 10 |
11 |
12 | 13 |
14 |
15 | 20 | 27 | 28 |
29 | 35 |
36 |
37 |
38 |
39 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/basket-roi/basket-roi.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
HISTORIC SIMULATED PERFORMANCE
4 |
5 |
6 |
17 | 18 | 23 | Last {{ time }} month(s) 24 | 25 | 26 |
27 |
28 |
29 | 35 |
36 |
37 |
38 |
39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/app/modules/home/pages/home/home.page.scss: -------------------------------------------------------------------------------- 1 | @import '~src/assets/scss/styles'; 2 | $mid: 50%; 3 | 4 | #particles { 5 | position: fixed; 6 | width: 100%; 7 | height: 100%; 8 | background-color: map-get($theme-colors, light); 9 | background-size: cover; 10 | background-position: 50% 50%; 11 | } 12 | 13 | .center { 14 | @include media-breakpoint-up(md) { 15 | position: fixed; 16 | top: 45%; 17 | left: calc(#{$mid} + #{$sidebar-width - 150px}); 18 | margin-right: calc(-#{$mid} + #{$sidebar-width}); 19 | transform: translate(-50%, -50%); 20 | } 21 | } 22 | 23 | .connected__separator { 24 | left: calc(#{$mid} + #{$sidebar-width}); 25 | } 26 | 27 | .heading__container { 28 | @include media-breakpoint-up(md) { 29 | height: 100%; 30 | } 31 | @include media-breakpoint-down(md) { 32 | margin-top: 2rem; 33 | } 34 | } 35 | 36 | .heading__title { 37 | display: flex; 38 | align-items: center; 39 | @include media-breakpoint-up(md) { 40 | flex-direction: row; 41 | margin-bottom: 1rem; 42 | } 43 | @include media-breakpoint-down(md) { 44 | flex-direction: column; 45 | align-items: center; 46 | margin-bottom: 2rem; 47 | } 48 | } 49 | 50 | .heading__title--welcome { 51 | @include media-breakpoint-up(md) { 52 | margin-bottom: 0; 53 | } 54 | @include media-breakpoint-down(md) { 55 | margin-bottom: 0.5rem; 56 | } 57 | } 58 | 59 | .wallet__wrapper { 60 | padding: 50px 25px; 61 | } 62 | -------------------------------------------------------------------------------- /src/app/shared/directives/numbers-only-input.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostListener, Input } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appNumbersOnlyInput]', 5 | }) 6 | export class NumbersOnlyInputDirective { 7 | @Input() 8 | appNumbersOnlyInputNoDecimal: any; 9 | 10 | @HostListener('keydown', ['$event']) onKeyDown(event): any { 11 | let e = event; 12 | const allowedDecimalSign = !!this.appNumbersOnlyInputNoDecimal ? '' : '.'; 13 | if ( 14 | [ 15 | 'Delete', 16 | 'Backspace', 17 | 'Tab', 18 | 'Escape', 19 | 'Enter', 20 | 'NumLock', 21 | 'ArrowLeft', 22 | 'ArrowRight', 23 | 'End', 24 | 'Home', 25 | allowedDecimalSign, 26 | ].indexOf(e.key) !== -1 || 27 | // Allow: Ctrl+A 28 | (e.key === 'a' && (e.ctrlKey || e.metaKey)) || 29 | // Allow: Ctrl+C 30 | (e.key === 'c' && (e.ctrlKey || e.metaKey)) || 31 | // Allow: Ctrl+V 32 | (e.key === 'v' && (e.ctrlKey || e.metaKey)) || 33 | // Allow: Ctrl+X 34 | (e.key === 'x' && (e.ctrlKey || e.metaKey)) 35 | ) { 36 | // let it happen, don't do anything 37 | return; 38 | } 39 | // Ensure that it is a number and stop the keypress 40 | if ( 41 | e.shiftKey || 42 | ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].indexOf(e.key) === -1 43 | ) { 44 | e.preventDefault(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/shared/components/pending-transaction-msg/pending-transaction-msg.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | You have a pending transaction for 5 | 6 | purchasing REEF. 7 | 8 | adding liquidity to the REEF/ETH pool. 9 | 10 | 11 | adding liquidity to the REEF/USDT pool. 12 | 13 | 14 | using the REEF/ETH farm. 15 | 16 | 17 | using the REEF/USDT farm. 18 | 19 | 20 | using the REEF farm. 21 | 22 | 23 | approving a token. 24 | 25 | 26 | 27 | Check it out on 28 | Etherscan 34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /src/app/modules/vaults/components/vaults-list/vaults-list.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Vaults
4 |
5 | You can modify the allocated amount using the sliders 6 |
7 |
8 |
9 |
{{ key }}
10 |
20 |
21 | APY: {{ vaults[key].APY | number }}% 22 |
23 |
24 | {{ vaults[key].percentage }}% 25 |
26 |
27 | 36 |
37 |
38 |
39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/app/shared/utils/ui.utils.ts: -------------------------------------------------------------------------------- 1 | import { DateTimeUtil } from './date-time.util'; 2 | 3 | export class UiUtils { 4 | static keydownPreventDecimal($event: any): void { 5 | if ($event.key === '.' || $event.key === ',') { 6 | $event.preventDefault(); 7 | } 8 | } 9 | 10 | static toMinTimespanText( 11 | startDate: Date | string | number, 12 | endDate: Date | string | number 13 | ): string { 14 | let returnStr = ''; 15 | 16 | const diff = DateTimeUtil.getPositiveTimeDiff(startDate, endDate); 17 | 18 | if (diff) { 19 | if (diff.months > 0 && diff.days === 30) { 20 | diff.months = diff.months + 1; 21 | diff.days = 0; 22 | diff.hours = 0; 23 | diff.minutes = 0; 24 | diff.seconds = 0; 25 | } 26 | if (!!diff.years) { 27 | returnStr += diff.years + `${diff.years === 1 ? ' year' : ' years'}`; 28 | } 29 | if (!!diff.months) { 30 | returnStr += 31 | ' ' + diff.months + `${diff.months === 1 ? ' month' : ' months'}`; 32 | } 33 | if (!!diff.weeks) { 34 | returnStr += 35 | ' ' + diff.weeks + `${diff.weeks === 1 ? ' week' : ' weeks'}`; 36 | } 37 | if (!!diff.days) { 38 | returnStr += ' ' + diff.days + `${diff.days === 1 ? ' day' : ' days'}`; 39 | } 40 | if (!!diff.hours) { 41 | returnStr += 42 | ' ' + diff.hours + `${diff.hours === 1 ? ' hour' : ' hours'}`; 43 | } 44 | } 45 | return returnStr; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/modules/reef/pages/pools/pools.page.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ConnectorService } from '../../../../core/services/connector.service'; 3 | import { first } from 'rxjs/internal/operators/first'; 4 | import { Observable } from 'rxjs'; 5 | import { 6 | IProviderUserInfo, 7 | TransactionType, 8 | } from '../../../../core/models/types'; 9 | import { TransactionsService } from 'src/app/core/services/transactions.service'; 10 | 11 | @Component({ 12 | selector: 'app-stake-reef-page', 13 | templateUrl: './pools.page.html', 14 | styleUrls: ['./pools.page.scss'], 15 | }) 16 | export class PoolsPage { 17 | TransactionType = TransactionType; 18 | constructor(public readonly connectorService: ConnectorService) {} 19 | pools = [ 20 | { 21 | name: 'ETH & REEF', 22 | description: ` 23 | Provide ETH and REEF into this pool to get 24 | ETH-REEF 25 | LP Tokens`, 26 | link: 'ETH', 27 | btnLabel: 'Provide Liquidity into ETH/REEF', 28 | imgs: ['eth.png', 'reef/reef-token.svg'], 29 | }, 30 | { 31 | name: 'USDT & REEF', 32 | description: ` 33 | Invest USDT and REEF into this pool to get 34 | USDT-REEF 35 | LP Tokens`, 36 | link: 'USDT', 37 | btnLabel: 'Provide Liquidity into USDT/REEF', 38 | imgs: ['usdt.png', 'reef/reef-token.svg'], 39 | }, 40 | ]; 41 | TransactionsService = TransactionsService; 42 | } 43 | -------------------------------------------------------------------------------- /src/app/modules/reef/components/reef-historic-price/reef-historic-price.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
REEF Price
4 |
5 | 18 | 19 |
20 | 26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 |
34 | Something went wrong while calculating the REEF Historical Price. 36 | 37 |
38 |
39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { WalletGuard } from './core/guards/wallet.guard'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | loadChildren: () => 9 | import('./modules/home/home.module').then((m) => m.HomeModule), 10 | }, 11 | { 12 | path: 'reef', 13 | loadChildren: () => 14 | import('./modules/reef/reef.module').then((m) => m.ReefModule), 15 | canActivate: [WalletGuard], 16 | }, 17 | { 18 | path: 'dashboard', 19 | loadChildren: () => 20 | import('./modules/dashboard/dashboard.module').then( 21 | (m) => m.DashboardModule 22 | ), 23 | canActivate: [WalletGuard], 24 | }, 25 | { 26 | path: 'baskets', 27 | loadChildren: () => 28 | import('./modules/baskets/baskets.module').then((m) => m.BasketsModule), 29 | canActivate: [WalletGuard], 30 | }, 31 | // { 32 | // path: 'vaults', 33 | // loadChildren: () => 34 | // import('./modules/vaults/vaults.module').then((m) => m.VaultsModule), 35 | // canActivate: [WalletGuard], 36 | // }, 37 | // { 38 | // path: 'binance', 39 | // loadChildren: () => import('./modules/binance/binance.module').then(m => m.BinanceModule), 40 | // canActivate: [WalletGuard], 41 | // }, 42 | { 43 | path: '**', 44 | redirectTo: '/', 45 | }, 46 | ]; 47 | 48 | @NgModule({ 49 | imports: [RouterModule.forRoot(routes)], 50 | exports: [RouterModule], 51 | }) 52 | export class AppRoutingModule {} 53 | -------------------------------------------------------------------------------- /src/app/modules/baskets/components/vaults-composition/vaults-composition.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
COMPOSITION
4 |
10 |
11 |
{{ vault.name }}
12 |
13 | {{ vaults.weights[i] | number: '1.1-2' }}% 14 |
15 | 20 |
21 |
22 |
23 |
24 | 25 | 26 |
27 |
28 |
{{ vault.name }}
29 |
30 | {{ vaults.weights[i] | number: '1.1-2' }}% 31 |
32 | 37 |
38 |
39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/app/modules/home/pages/home/home.page.html: -------------------------------------------------------------------------------- 1 |
5 |
6 | 13 |
14 |
15 |
27 | 32 |
33 |
Welcome to Reef Finance!
34 |
35 |

36 | Making DeFi Easy for Everyone 37 |

38 |
39 |

40 | Reef Finance provides the gateway to the DeFi landscape through 41 | Liquidity and Protocol Aggregation, Proprietary Analytics, 42 | Personalized Recommendations and Multi-Chain Accessibility. 43 |

44 |
45 |
46 |
47 |
48 | --------------------------------------------------------------------------------