Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] Bridging UI #1

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,4 @@

## Subgraphs

- Ethereum Mainnet
- Ethereum Rinkeby
- Boba Mainnet
- [EIP721](https://graph.mainnet.boba.network:8000/subgraphs/name/tapioca/eip721-subgraph-boba)
- Boba Rinkeby
- [EIP721](https://graph.rinkeby.boba.network:8000/subgraphs/name/tapioca/eip721-subgraph-boba)
- [ERC721ExchangeUpgradeable](https://graph.rinkeby.boba.network:8000/subgraphs/name/shibuidao/nft-exchange)
Information about our subgraph can be found [here](https://docs.shibuidao.com/nft/subgraph/Exchange.html).
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shibuidao/interface",
"version": "0.2.0-beta",
"version": "0.3.0-beta",
"private": true,
"scripts": {
"predev": "yarn meta:package",
Expand Down Expand Up @@ -67,7 +67,7 @@
"@sapphire/eslint-config": "4.0.8",
"@sapphire/prettier-config": "1.2.7",
"@sapphire/ts-config": "3.1.6",
"@shibuidao/boba-nft-bridge": "^1.1.0",
"@shibuidao/boba-nft-bridge": "^1.1.1",
"@shibuidao/exchange": "^1.6.0",
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-controls": "^6.4.19",
Expand Down
4 changes: 2 additions & 2 deletions src/components/Assets/DataAssetCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { selectAssetMetadata } from 'state/reducers/assets';
import { executeSellOrder, OrderDirection, selectSellOrder, setCurrentOrder, SimpleSellOrder } from 'state/reducers/orders';
import { executeSellOrderTxw, OrderDirection, selectSellOrder, setCurrentOrder, SimpleSellOrder } from 'state/reducers/orders';
import AssetCard from './AssetCard';

export interface DataAssetCardProps {
Expand Down Expand Up @@ -37,7 +37,7 @@ const DataAssetCard: React.FC<DataAssetCardProps> = ({ chainId, contract, identi
};
const exerciseFunction = (order: SimpleSellOrder, chainId_: SupportedChainId, library_: JsonRpcProvider, account_: string) => () => {
dispatch(
executeSellOrder({
executeSellOrderTxw({
chainId: chainId_,
library: library_,
data: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Assets/ERC721Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useProviders from 'hooks/useProviders';
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchAssetMetadata, selectAssetMetadata } from 'state/reducers/assets';
import { fetchAssetMetadataTxr, selectAssetMetadata } from 'state/reducers/assets';
import DataAssetCard from './DataAssetCard';

export interface ERC721AssetProps {
Expand All @@ -24,7 +24,7 @@ const ERC721Asset: React.FC<ERC721AssetProps> = ({ token, chainId }) => {
if (metadata !== undefined && metadata.owner === token.owner.id) return;

dispatch(
fetchAssetMetadata({
fetchAssetMetadataTxr({
token: {
owner: token.owner?.id,
identifier: token.identifier,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Collection/CollectionSpecificsInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useProviders from 'hooks/useProviders';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchCollectionInfo, selectCollectionInfo } from 'state/reducers/collections';
import { fetchCollectionInfoTxr, selectCollectionInfo } from 'state/reducers/collections';

export interface CollectionSpecificsInfoProps {
address: string;
Expand All @@ -20,7 +20,7 @@ const CollectionSpecificsInfo: React.FC<CollectionSpecificsInfoProps> = ({ addre
const info = useSelector(selectCollectionInfo(chainIdNormalised, address));
if (!info)
dispatch(
fetchCollectionInfo({
fetchCollectionInfoTxr({
address,
chainId: chainIdNormalised,
provider: account && library ? library : baseProvider,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Collection/DataCollectionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useProviders from 'hooks/useProviders';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchCollectionInfo, selectCollectionInfo } from 'state/reducers/collections';
import { fetchCollectionInfoTxr, selectCollectionInfo } from 'state/reducers/collections';
import CollectionCard from './CollectionCard';

export interface DataCollectionCardProps {
Expand All @@ -22,7 +22,7 @@ const DataCollectionCard: React.FC<DataCollectionCardProps> = ({ address }) => {
const info = useSelector(selectCollectionInfo(chainIdNormalised, address));
if (!info)
dispatch(
fetchCollectionInfo({
fetchCollectionInfoTxr({
address,
chainId: chainIdNormalised,
provider: account && library ? library : baseProvider,
Expand Down
4 changes: 2 additions & 2 deletions src/components/OrderManipulation/forms/SellForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Form, Formik } from 'formik';
import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import React from 'react';
import { useDispatch } from 'react-redux';
import { clearOrder, createSellOrder } from 'state/reducers/orders';
import { clearOrder, createSellOrderTxw } from 'state/reducers/orders';
import { SellFormSchema } from 'utils/schemas';

export interface SellFormFields {
Expand Down Expand Up @@ -35,7 +35,7 @@ const SellForm: React.FC<SellFormProps> = ({ contract, identifier }) => {
validationSchema={SellFormSchema}
onSubmit={(values: SellFormFields) => {
dispatch(
createSellOrder({
createSellOrderTxw({
chainId,
library,
data: {
Expand Down
9 changes: 6 additions & 3 deletions src/components/OrderManipulation/states/Approve.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useProviders from 'hooks/useProviders';
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchApprovalStatus, OrderDirection, selectOrderingStatus, setApprovalForAll, updateCurrentOrderDirection } from 'state/reducers/orders';
import { setApprovalForAllTxw } from 'state/reducers/approvals';
import { fetchCurrentOrderApprovalStatusTxr, OrderDirection, selectOrderingStatus, updateCurrentOrderDirection } from 'state/reducers/orders';

const Approve: React.FC = () => {
const { library, account, chainId } = useActiveWeb3React();
Expand All @@ -19,7 +20,7 @@ const Approve: React.FC = () => {
if (!library || !account) return;

dispatch(
fetchApprovalStatus({
fetchCurrentOrderApprovalStatusTxr({
contract: order.contract,
operator: ERC721_EXCHANGE[chainIdNormalised],
owner: account,
Expand All @@ -36,9 +37,11 @@ const Approve: React.FC = () => {
disabled={!library}
onClick={() => {
dispatch(
setApprovalForAll({
setApprovalForAllTxw({
contract: order.contract,
user: account!,
operator: ERC721_EXCHANGE[chainIdNormalised],
approval: true,
provider: library!
})
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/OrderManipulation/states/Cancel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useMounted from 'hooks/useMounted';
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { cancelSellOrder, clearOrder, OrderDirection, selectOrderingStatus } from 'state/reducers/orders';
import { cancelSellOrderTxw, clearOrder, OrderDirection, selectOrderingStatus } from 'state/reducers/orders';

const Cancel: React.FC = () => {
const { library, chainId } = useActiveWeb3React();
Expand All @@ -16,7 +16,7 @@ const Cancel: React.FC = () => {
if (!mounted || !chainId || !library) return;

dispatch(
cancelSellOrder({
cancelSellOrderTxw({
chainId,
library: library!,
data: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/OrderManipulation/states/Exercise.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useMounted from 'hooks/useMounted';
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { clearOrder, executeSellOrder, OrderDirection, selectOrderingStatus } from 'state/reducers/orders';
import { clearOrder, executeSellOrderTxw, OrderDirection, selectOrderingStatus } from 'state/reducers/orders';

const Exercise: React.FC = () => {
const { library, account, chainId } = useActiveWeb3React();
Expand All @@ -16,7 +16,7 @@ const Exercise: React.FC = () => {
if (!mounted || !chainId || !library) return;

dispatch(
executeSellOrder({
executeSellOrderTxw({
chainId,
library: library!,
data: {
Expand Down
16 changes: 12 additions & 4 deletions src/constants/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { SupportedChainId } from './chains';

const BOBA_MAINNET_ERC721_EXCHANGE = '0x02af48a420f0934ecfc1c34f6da83db1e3e56af7';
const BOBA_RINKEBY_ERC721_EXCHANGE = '0x34755A949E68b18F585eB91711351b697C1563d5';
const BOBA_MAINNET_ERC721_EXCHANGE = '0x02af48a420f0934ecfc1c34f6da83db1e3e56af7'; // Proxy
const BOBA_RINKEBY_ERC721_EXCHANGE = '0x34755A949E68b18F585eB91711351b697C1563d5'; // Proxy

export const ERC721_EXCHANGE: { [K in SupportedChainId]: `0x${string}` } = {
[SupportedChainId.BOBA]: BOBA_MAINNET_ERC721_EXCHANGE,
[SupportedChainId.BOBA_RINKEBY]: BOBA_RINKEBY_ERC721_EXCHANGE
};

const BOBA_MAINNET_L2_NFT_BRIDGE = '0xE791c5A8aC5299bb946226d6E4864022c982371b';
const BOBA_RINKEBY_L2_NFT_BRIDGE = '0x9b175c83d6238cB4a48E6f3C025D43E35b04391f';
const BOBA_MAINNET_L1_NFT_BRIDGE = '0xC891F466e53f40603250837282eAE4e22aD5b088'; // Proxy
const BOBA_RINKEBY_L1_NFT_BRIDGE = '0x01F5d5D6de3a8c7A157B22FD331A1F177b7bE043'; // Proxy

export const L1_NFT_BRIDGE: { [K in SupportedChainId]: `0x${string}` } = {
[SupportedChainId.BOBA]: BOBA_MAINNET_L1_NFT_BRIDGE,
[SupportedChainId.BOBA_RINKEBY]: BOBA_RINKEBY_L1_NFT_BRIDGE
};

const BOBA_MAINNET_L2_NFT_BRIDGE = '0xFB823b65D0Dc219fdC0d759172D1E098dA32f9eb'; // Proxy
const BOBA_RINKEBY_L2_NFT_BRIDGE = '0x5E368E9dce71B624D7DdB155f360E7A4969eB7aA'; // Proxy

export const L2_NFT_BRIDGE: { [K in SupportedChainId]: `0x${string}` } = {
[SupportedChainId.BOBA]: BOBA_MAINNET_L2_NFT_BRIDGE,
Expand Down
4 changes: 4 additions & 0 deletions src/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ module.exports = withPlausibleProxy()({
{
source: '/app',
destination: '/app/collections'
},
{
source: '/app/collections/index',
destination: '/app/collections'
}
];
},
Expand Down
141 changes: 141 additions & 0 deletions src/pages/app/bridge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* eslint-disable no-alert */
import { faArrowRightLong } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import FormFieldError from 'components/forms/FormFieldError';
import FormFieldInfo from 'components/forms/FormFieldInfo';
import Offset from 'components/Navbar/Offset';
import { SupportedChainId } from 'constants/chains';
import { DEFAULT_CHAIN } from 'constants/misc';
import { Form, Formik } from 'formik';
import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import useForceConnectMenu from 'hooks/useForceConnectMenu';
import useProviders from 'hooks/useProviders';
import { NextPage } from 'next';
import { NextSeo } from 'next-seo';
import React from 'react';
import { When } from 'react-if';
import { BridgeFormSchema } from 'utils/schemas';

const TestingMetadataPage: NextPage = () => {
useForceConnectMenu();
const { account, chainId, library } = useActiveWeb3React();

const chainIdNormalised: SupportedChainId = chainId || DEFAULT_CHAIN;
const fallbackProvider = useProviders()[chainIdNormalised];
const readonlyProvider = library || fallbackProvider;

return (
<>
<NextSeo title="Bridge" openGraph={{ title: 'ShibuiNFT Bridge' }} />
<Offset />
<div
style={{
backgroundImage: 'url(/assets/misc/background.svg)',
backgroundSize: 'cover'
}}
>
<div className="container">
<div className="flex min-h-[100vh] w-full flex-row items-center justify-center">
<div className="rounded-2xl border p-4 dark:border-lights-100 dark:bg-darks-400 dark:text-white">
<div className="p-4">
<div className="rounded-xl border p-4 font-bold dark:border-lights-300 dark:bg-lights-200 dark:text-black">
<div className="">
<div className="grid grid-cols-3 gap-8 text-center">
<div className="flex flex-row items-center justify-center">
<img className="inline h-10 object-contain" src="/assets/chains/boba.svg" alt="Boba L2 logo" />
<span className="pl-2">Boba</span>
</div>
<div className="flex flex-row items-center justify-center">
<FontAwesomeIcon icon={faArrowRightLong} />
</div>
<div className="flex flex-row items-center justify-center">
<img className="inline h-10 object-contain" src="/assets/chains/ethereum.svg" alt="Ethereum logo" />
<span className="pl-2">Ethereum</span>
</div>
</div>
</div>
</div>
<div className="pt-4">
<>
<Formik
initialValues={{
l2Contract: '',
tokenId: '',
l1Receiver: ''
}}
validationSchema={BridgeFormSchema(chainIdNormalised, readonlyProvider)}
onSubmit={(data) => alert(data)}
>
{(props) => (
<Form>
<>
<div>
<div className="py-2">
<label htmlFor="l2Contract" className="mb-2 text-lg font-bold text-white">
L2 NFT Contract Address
</label>
<FormFieldInfo message="Address of the collection on the Boba L2 network" />
<input
name="l2Contract"
type="text"
onChange={props.handleChange}
value={props.values.l2Contract}
className="border-element-secondary outline-none block w-full rounded-lg border-b border-dotted bg-darks-200 px-2 py-1 text-white"
/>
<FormFieldError message={props.errors.l2Contract} />
</div>
<div className="py-2">
<label htmlFor="tokenId" className="mb-2 text-lg font-bold text-white">
Token ID
</label>
<FormFieldInfo message="ID of the asset to bridge" />
<input
name="tokenId"
type="text"
onChange={props.handleChange}
value={props.values.tokenId}
className="border-element-secondary outline-none block w-full rounded-lg border-b border-dotted bg-darks-200 px-2 py-1 text-white"
/>
<FormFieldError message={props.errors.tokenId} />
</div>
<div className="py-2">
<label htmlFor="l1Receiver" className="mb-2 text-lg font-bold text-white">
L1 Receiver
</label>
<FormFieldInfo message="The address to which to bridge on L1" />
<input
name="l1Receiver"
type="text"
onChange={props.handleChange}
value={props.values.l1Receiver}
className="border-element-secondary outline-none block w-full rounded-lg border-b border-dotted bg-darks-200 px-2 py-1 text-white"
/>
<FormFieldError message={props.errors.l1Receiver} />
</div>
</div>
<div className="mt-4">
<When condition={Boolean(account)}>
<button
type="submit"
className="btn w-full bg-lights-300 text-black hover:bg-lights-400 hover:text-white"
>
Bridge
</button>
</When>
</div>
</>
</Form>
)}
</Formik>
</>
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
};

export default TestingMetadataPage;
2 changes: 2 additions & 0 deletions src/pages/app/testing/metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DEFAULT_CHAIN } from 'constants/misc';
import { Form, Formik } from 'formik';
import { useActiveWeb3React } from 'hooks/useActiveWeb3React';
import { NextPage } from 'next';
import { NextSeo } from 'next-seo';
import Highlight, { defaultProps } from 'prism-react-renderer';
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
Expand All @@ -21,6 +22,7 @@ const TestingMetadataPage: NextPage = () => {

return (
<>
<NextSeo title="Metadata Preview" openGraph={{ title: 'ShibuiNFT Metadata Preview' }} />
<Offset />
<div className="py-4">
<div className="flex w-full min-w-full justify-center">
Expand Down
Loading