From 541a27bab3578b9d0970a3beac5aa696f32e7b36 Mon Sep 17 00:00:00 2001 From: chrisjgf Date: Tue, 2 Feb 2021 16:01:34 +0000 Subject: [PATCH 01/18] renbtc attempt --- package.json | 5 +- .../pages/Mint/curvedMasset/index.tsx | 82 +++++++++++++++++++ .../pages/Mint/curvedMasset/ren.tsx | 22 +++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/components/pages/Mint/curvedMasset/index.tsx create mode 100644 src/components/pages/Mint/curvedMasset/ren.tsx diff --git a/package.json b/package.json index 3b22c2a13..89bd871a8 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ "@apollo/react-common": "^3.2.0-beta.1", "@apollo/react-hooks": "^3.2.0-beta.1", "@habx/apollo-multi-endpoint-link": "^1.1.0", + "@renproject/chains": "^2.0.8", + "@renproject/interfaces": "^2.1.0", + "@renproject/ren": "^2.0.9", "@sentry/react": "^5.19.0", "@testing-library/jest-dom": "^5.7.0", "@testing-library/react": "^10.0.4", @@ -70,9 +73,9 @@ "styled-components": "^5.1.0", "styled-reset": "^4.1.4", "ts-pipe-compose": "^0.2.0", - "use-resize-observer": "^7.0.0", "use-clipboard-copy": "^0.1.2", "use-onclickoutside": "^0.3.1", + "use-resize-observer": "^7.0.0", "utility-types": "^3.10.0", "web3-utils": "^1.2.6" }, diff --git a/src/components/pages/Mint/curvedMasset/index.tsx b/src/components/pages/Mint/curvedMasset/index.tsx new file mode 100644 index 000000000..c2d16bb0d --- /dev/null +++ b/src/components/pages/Mint/curvedMasset/index.tsx @@ -0,0 +1,82 @@ +import React, { FC, useMemo, useState } from 'react'; +import RenJS from '@renproject/ren'; + +import { Bitcoin } from '@renproject/chains'; +import { RenNetwork } from '@renproject/interfaces'; +import { useSelectedMassetState } from '../../../../context/DataProvider/DataProvider'; +import { + useSigner, + useWalletAddress, +} from '../../../../context/OnboardProvider'; +import { MultiAssetExchange } from '../../../forms/MultiAssetExchange'; +import { Asset, getEthChainObject } from './ren'; +import { Button } from '../../../core/Button'; + +export const Mint: FC = () => { + const massetState = useSelectedMassetState(); + + // RenJS + const renJS = useMemo(() => new RenJS(RenNetwork.Testnet, {}), []); + const recipientAddress = useWalletAddress(); + const [depositAddress, setDepositAddress] = useState< + string | { address: string; params?: string; memo?: string } | null + >(null); + const signer = useSigner(); + const provider = (signer?.provider as any)?._web3Provider; + + const inputAssets = useMemo( + () => + Object.fromEntries( + Object.entries(massetState?.bAssets ?? {}).map( + ([ + address, + { + token: { decimals, balance, symbol }, + }, + ]) => [address, { decimals, balance, symbol }], + ), + ), + [massetState], + ); + + const outputAssets = useMemo(() => { + if (!massetState) return {}; + const { address, decimals, symbol } = massetState.token; + return { [address]: { decimals, symbol } }; + }, [massetState]); + + const mintBTC = async (): Promise => { + const asset = Asset.BTC; + const from = Bitcoin(); + const to = getEthChainObject(provider, recipientAddress); + + if (!recipientAddress) return; + + const lockAndMint = await renJS?.lockAndMint({ + asset, + from, + to, + }); + + if (lockAndMint?.gatewayAddress) { + setDepositAddress(lockAndMint.gatewayAddress); + } + + lockAndMint.on('deposit', async deposit => { + const txHash = await deposit.txHash(); + console.log('TX', txHash); + }); + }; + + return ( +
+ + +

{depositAddress}

+
+ ); +}; diff --git a/src/components/pages/Mint/curvedMasset/ren.tsx b/src/components/pages/Mint/curvedMasset/ren.tsx new file mode 100644 index 000000000..4413a02fe --- /dev/null +++ b/src/components/pages/Mint/curvedMasset/ren.tsx @@ -0,0 +1,22 @@ +import { EthereumClass, Ethereum } from '@renproject/chains'; +import { getRenNetworkDetails, RenNetwork } from '@renproject/interfaces'; + +export const NETWORK = getRenNetworkDetails(RenNetwork.Testnet); + +export enum Asset { + BTC = 'BTC', +} + +export const getEthChainObject = ( + provider: any, + recipientAddress?: string, + amount?: string, +): EthereumClass => { + const eth = Ethereum(provider, NETWORK); + return recipientAddress + ? eth.Account({ + address: recipientAddress, + value: amount, + }) + : eth; +}; From 2357f059d6a209cd1356b64c9727129ed7991a10 Mon Sep 17 00:00:00 2001 From: chrisjgf Date: Wed, 10 Feb 2021 11:43:25 +0000 Subject: [PATCH 02/18] Begin stubbing out ren/mint --- src/components/pages/Mint/ren/index.tsx | 90 +++++++++++++++++++++++++ src/index.tsx | 2 + 2 files changed, 92 insertions(+) create mode 100644 src/components/pages/Mint/ren/index.tsx diff --git a/src/components/pages/Mint/ren/index.tsx b/src/components/pages/Mint/ren/index.tsx new file mode 100644 index 000000000..7f3027ae3 --- /dev/null +++ b/src/components/pages/Mint/ren/index.tsx @@ -0,0 +1,90 @@ +import React, { FC, useMemo } from 'react'; +import styled from 'styled-components'; + +import { AssetExchange } from '../../../forms/AssetExchange'; +import { CollapseBox } from '../../../forms/CollapseBox'; +import { PageAction, PageHeader } from '../../PageHeader'; +import { useSelectedMassetState } from '../../../../context/DataProvider/DataProvider'; + +// To index address with +const BTC_ADDRESS = 'BTC_ADDRESS_1'; + +const List = styled.ol` + list-style: circle; + padding: 0.75rem 1.25rem 0.25rem; + border-top: 1px solid ${({ theme }) => theme.color.accent}; +`; + +const Exchange = styled.div` + width: 50%; + margin-top: 1rem; +`; + +export const RenMint: FC = () => { + // const [outputAddress, handleSetAddress] = useState(); + + const massetState = useSelectedMassetState(); + const { address: massetAddress } = massetState ?? {}; + + const outputAddressOptions = useMemo(() => { + return [{ address: massetAddress }]; + }, [massetAddress]); + + // const [ + // inputAmount, + // inputFormValue, + // setInputFormValue, + // setInputAmount, + // ] = useBigDecimalInput(); + + // const inputAddressOptions = useMemo(() => { + // return [{ address: saveAddress as string }]; + // }, [saveAddress]); + + return ( +
+ + + +
  • + BTC will be deposited to the RenJS BTC gateway (this step can take + up to 24 hours) +
  • +
  • Ren will lock this BTC and mint renBTC.
  • +
  • + You will then need to finalize the transaction with an Ethereum + transaction. +
  • +
  • You will receive mBTC
  • +
    +
    + + { + // if (inputToken) { + // setInputFormValue(inputToken.balance.string); + // } + // }} + outputAddress={outputAddressOptions[0].address} + // error={error} + inputAddressDisabled + /> + +
    + ); +}; diff --git a/src/index.tsx b/src/index.tsx index 2cf19fa90..f416383cb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -13,6 +13,7 @@ import { Layout } from './components/layout/Layout'; import { Home } from './components/pages'; import { Swap } from './components/pages/Swap'; import { Mint } from './components/pages/Mint'; +import { RenMint } from './components/pages/Mint/ren'; import { Earn } from './components/pages/Earn'; import { Save } from './components/pages/Save'; import { Redeem } from './components/pages/Redeem'; @@ -59,6 +60,7 @@ const Routes: FC = () => { + From ddbf47bb9684bf060c26aba05b9457c8b06d764e Mon Sep 17 00:00:00 2001 From: chrisjgf Date: Wed, 10 Feb 2021 16:38:03 +0000 Subject: [PATCH 03/18] First 2 states for UI --- src/components/core/Arrow.tsx | 14 +- src/components/core/Dropdown.tsx | 8 +- src/components/forms/AssetExchange.tsx | 5 +- src/components/icons/TokenIcon.tsx | 3 + src/components/icons/tokens/BTC.svg | 1 + .../pages/Mint/ren/RenMintOnboard.tsx | 204 ++++++++++++++++++ src/components/pages/Mint/ren/index.tsx | 112 ++++++---- 7 files changed, 304 insertions(+), 43 deletions(-) create mode 100644 src/components/icons/tokens/BTC.svg create mode 100644 src/components/pages/Mint/ren/RenMintOnboard.tsx diff --git a/src/components/core/Arrow.tsx b/src/components/core/Arrow.tsx index 6c4cc6049..8ae9054af 100644 --- a/src/components/core/Arrow.tsx +++ b/src/components/core/Arrow.tsx @@ -1,6 +1,8 @@ import React, { FC } from 'react'; import styled from 'styled-components'; +type Direction = 'up' | 'down' | 'left' | 'right'; + export const Container = styled.div` align-items: center; display: flex; @@ -11,9 +13,15 @@ export const Container = styled.div` user-select: none; `; -export const Arrow: FC<{ direction?: 'up' | 'down' }> = ({ +const ArrowIcon: Record = { + up: '↑', + down: '↓', + left: '←', + right: '→', +}; + +export const Arrow: FC<{ direction?: Direction }> = ({ direction = 'down', }) => { - const arrowIcon = direction === 'up' ? '↑' : '↓'; - return {arrowIcon}; + return {ArrowIcon[direction]}; }; diff --git a/src/components/core/Dropdown.tsx b/src/components/core/Dropdown.tsx index dc2f323e0..9692dcd97 100644 --- a/src/components/core/Dropdown.tsx +++ b/src/components/core/Dropdown.tsx @@ -14,6 +14,7 @@ interface Props { options?: TransactionOption[]; onChange?(address?: string): void; disabled?: boolean; + className?: string; } const ChevronContainer = styled.span<{ selected?: boolean; active?: boolean }>` @@ -161,6 +162,7 @@ export const Dropdown: FC = ({ options, onChange, disabled, + className, }) => { const [show, toggleShow] = useToggle(false); @@ -185,7 +187,11 @@ export const Dropdown: FC = ({ const isDropdown = (options?.length ?? 0) > 1; return ( - +