Skip to content

Commit

Permalink
Info screen, responsive, and add starknet-react
Browse files Browse the repository at this point in the history
  • Loading branch information
b-j-roberts committed Dec 19, 2024
1 parent a2219d3 commit bcf7204
Show file tree
Hide file tree
Showing 20 changed files with 507 additions and 123 deletions.
2 changes: 2 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"preview": "vite preview"
},
"dependencies": {
"@starknet-react/chains": "^3.1.1",
"@starknet-react/core": "^3.6.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router": "^7.0.1",
Expand Down
159 changes: 68 additions & 91 deletions apps/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState, useEffect } from 'react'
import { Routes, Route } from 'react-router'
import { connect, disconnect } from "starknetkit";
import { CallData, Contract, RpcProvider, constants, byteArray } from 'starknet';
import { CallData, RpcProvider, constants, byteArray, uint256 } from 'starknet';
import { useConnect, useDisconnect, useAccount, useContract, useSendTransaction } from '@starknet-react/core'
import { useStarknetkitConnectModal, StarknetkitConnector } from "starknetkit";
import './App.css'
import Header from './components/Header'
import orderbook_abi from './abi/orderbook.abi.json';
Expand All @@ -24,40 +25,59 @@ export const provider = new RpcProvider({

function App() {
// TODO: Move to seperate module ( starknet stuff )
const [starkWallet, setWallet] = useState(null as any)
const [starkConnector, setConnector] = useState(null as any)
const [starkConnectorData, setConnectorData] = useState(null as any)
const [starkAddress, setAddress] = useState(null as any)
const [starkAccount, setStarkAccount] = useState(null as any)
const { connect, connectors } = useConnect()
const { disconnect, error } = useDisconnect()
const { address, status } = useAccount()
const { starknetkitConnectModal } = useStarknetkitConnectModal({
connectors: connectors as StarknetkitConnector[]
})
const [isConnected, setIsConnected] = useState(false)
const [connector, setConnector] = useState(null as StarknetkitConnector | null)

const connectWallet = async () => {
// TODO: If no wallet/connectors?
// TODO: Auto-reconnect on page refresh?
const { wallet, connector, connectorData } = await connect({
modalMode: "alwaysAsk",
modalTheme: "dark"
})
if (!wallet || !connector || !connectorData) {
const { connector } = await starknetkitConnectModal()
if (!connector) {
return
}

setWallet(wallet)
connect({ connector })
setConnector(connector)
setConnectorData(connectorData)
setAddress(connectorData.account)
let new_account = await connector.account(provider);
setStarkAccount(new_account);
}

const disconnectWallet = async () => {
if (starkConnector) {
await disconnect()
useEffect(() => {
if (!connectors) return;
if (connectors.length === 0) return;
if (isConnected) return;

const connectIfReady = async () => {
for (let i = 0; i < connectors.length; i++) {
let ready = await connectors[i].ready();
if (ready) {
connect({ connector: connectors[i] })
//setConnector(connectors[i])
break;
}
}
};
connectIfReady();
}, [connectors]);

useEffect(() => {
if (status === 'connected') {
setIsConnected(true)
} else if (status === 'disconnected') {
setIsConnected(false)
}
}, [address, status])

setWallet(null)
const disconnectWallet = async () => {
if (!isConnected || !connector) {
return
}
disconnect()
setConnector(null)
setConnectorData(null)
setAddress(null)
setIsConnected(false)
}

const toHex = (str: string) => {
Expand All @@ -68,81 +88,39 @@ function App() {
return hex;
};

const estimateInvokeFee = async ({
contractAddress,
entrypoint,
calldata
}: {
contractAddress: any;
entrypoint: any;
calldata: any;
}) => {
try {
const { suggestedMaxFee } = await starkAccount.estimateInvokeFee({
contractAddress: contractAddress,
entrypoint: entrypoint,
calldata: calldata
});
return { suggestedMaxFee };
} catch (error) {
console.error(error);
return { suggestedMaxFee: BigInt(1000000000000000) };
}
};

const [orderbookContract, setOrderbookContract] = useState(null as any)
useEffect(() => {
if (!starkConnector || !starkAccount) {
return
}

const newOrderbookContract = new Contract(
orderbook_abi,
import.meta.env.VITE_ORDERBOOK_CONTRACT_ADDRESS,
starkAccount
)

setOrderbookContract(newOrderbookContract)
}, [starkConnector, starkAccount])
const { contract: orderbookContract } = useContract({
address: import.meta.env.VITE_BROLY_CONTRACT_ADDRESS,
abi: orderbook_abi as any
});

const [calls, setCalls] = useState([] as any[])
const requestInscriptionCall = async () => {
if (!starkAddress || !orderbookContract) {
if (!address || !orderbookContract) {
return
}
const calldata = CallData.compile([
byteArray.byteArrayFromString("message:Hello, Starknet!"),
byteArray.byteArrayFromString("tb1234567890123456789012345678901234567890"),
Number(100),
toHex("STRK"),
Number(2000)
uint256.bnToUint256(2000)
]);
console.log(calldata);
const requestCalldata = orderbookContract.populate(
"request_inscription",
calldata,
//{
// inscription_data: byteArray.byteArrayFromString("message:Hello, Starknet!"),
// receiving_address: toHex("tb1234567890123456789012345678901234567890"),
// satoshi: Number(100),
// currency_fee: toHex("STRK"),
// submitter_fee: Number(2000),
//}
);
const { suggestedMaxFee } = await estimateInvokeFee({
contractAddress: orderbookContract.address,
entrypoint: "request_inscription",
calldata: requestCalldata.calldata
});
/* global BigInt */
const maxFee = (suggestedMaxFee * BigInt(15)) / BigInt(10);
const result = await orderbookContract.request_inscription(
requestCalldata.calldata,
{
maxFee
}
);
console.log(result);
setCalls(
[orderbookContract.populate('request_inscription', calldata)]
)
}
const { send, data, isPending } = useSendTransaction({
calls
});
useEffect(() => {
const requestCall = async () => {
if (calls.length === 0) return;
send();
console.log('Call successful:', data, isPending);
// TODO: Update the UI with the new vote count
};
requestCall();
}, [calls]);

const cancelInscriptionCall = async () => {
// TODO
Expand All @@ -157,14 +135,13 @@ function App() {
const tabProps = {
requestInscriptionCall,
cancelInscriptionCall,
orderbookContract,
starkAddress
orderbookContract
}

// TODO: <Route path="*" element={<NotFound />} />
return (
<div className="h-screen relative">
<Header tabs={tabs} connectWallet={connectWallet} address={starkAddress} disconnectWallet={disconnectWallet} />
<Header tabs={tabs} connectWallet={connectWallet} isConnected={isConnected} disconnectWallet={disconnectWallet} />
<div className="h-[4.5rem]" />
<Routes>
{tabs.map((tab) => (
Expand Down
6 changes: 6 additions & 0 deletions apps/web/src/assets/argent-x.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions apps/web/src/assets/argentmobile.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/web/src/assets/braavos.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/web/src/assets/webwallet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions apps/web/src/components/Header.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
.tab__nav {
font-size: 1.2rem;
font-weight: 500;
color: #fff;
padding: 0.5rem 1rem;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
cursor: pointer;
transition: all 0.2s;
Expand Down
13 changes: 7 additions & 6 deletions apps/web/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { NavLink } from "react-router";
import { useAccount } from "@starknet-react/core";
import "./Header.css";

function Header(props: any) {
return (
<header className="heading__color--primary text-center flex flex-row justify-between items-center px-4 py-1 m-0 fixed w-full z-10">
<header className="heading__color--primary text-center flex flex-row justify-between items-center px-1 sm:px-3 md:px-4 py-1 m-0 fixed w-full z-10">
<div className="flex flex-row items-center">
<NavLink to={props.tabs[0].path} className="flex flex-row items-center">
<img src="/images/logo.png" alt="B.R.O.L.Y. Logo" className="m-2 w-12 h-12 border-[1px] border-[var(--color-secondary)] rounded-full bg-[#a8c8a808]"/>
<h1 className="text-4xl font-bold pl-1">B.R.O.L.Y.</h1>
<img src="/images/logo.png" alt="B.R.O.L.Y. Logo" className="m-1 sm:m-2 w-10 h-10 sm:w-12 sm:h-12 border-[1px] border-[var(--color-secondary)] rounded-full bg-[#a8c8a808]"/>
<h1 className="text-2xl sm:text-4xl font-bold sm:pl-1">B.R.O.L.Y.</h1>
</NavLink>
</div>
<nav className="flex justify-center flex-row items-center">
<nav className="flex justify-center flex-row items-center gap-3 sm:gap-4 md:gap-6">
{props.tabs.slice(1).map((tab: any, index: number) => (
<NavLink key={index} to={tab.path} className="tab__nav">
<NavLink key={index} to={tab.path} className="tab__nav text-md sm:text-lg md:text-xl">
{tab.name}
</NavLink>
))}
{props.address ? (
{props.isConnected ? (
<button className="button--gradient button__primary" onClick={props.disconnectWallet}>
Logout
</button>
Expand Down
66 changes: 66 additions & 0 deletions apps/web/src/components/StarknetProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';

/*
import { sepolia, mainnet } from "@starknet-react/chains";
import {
StarknetConfig,
publicProvider,
voyager
} from "@starknet-react/core";
import { getL2Connections } from "../connections";
export function StarknetProvider({ children }: { children: React.ReactNode }) {
return (
<StarknetConfig
chains={[mainnet, sepolia]}
provider={publicProvider()}
connectors={getL2Connections() as any}
explorer={voyager}
>
{children}
</StarknetConfig>
);
}
*/

import { InjectedConnector } from "starknetkit/injected";
import { ArgentMobileConnector, isInArgentMobileAppBrowser } from "starknetkit/argentMobile";
import { WebWalletConnector } from "starknetkit/webwallet";
import { mainnet, sepolia } from "@starknet-react/chains";
import { StarknetConfig, publicProvider } from "@starknet-react/core";

export function StarknetProvider({ children }: { children: React.ReactNode }) {
const chains = [mainnet, sepolia]

const connectors = isInArgentMobileAppBrowser() ? [
ArgentMobileConnector.init({
options: {
dappName: "B.R.O.L.Y.",
projectId: "broly-id",
url: window.location.href,
},
inAppBrowserOptions: {},
})
] : [
new InjectedConnector({ options: { id: "braavos", name: "Braavos" }}),
new InjectedConnector({ options: { id: "argentX", name: "Argent X" }}),
new WebWalletConnector({ url: "https://web.argent.xyz" }),
ArgentMobileConnector.init({
options: {
dappName: "B.R.O.L.Y.",
projectId: "broly-id",
url: window.location.href,
}
})
]

return(
<StarknetConfig
chains={chains}
provider={publicProvider()}
connectors={connectors}
>
{children}
</StarknetConfig>
)
}
6 changes: 3 additions & 3 deletions apps/web/src/components/inscription/Form.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
height: 6rem;
background-color: var(--color-tertiary);
margin-right: 2rem;
border: 1px solid var(--color-primary-light);
border: 1px solid var(--color-primary-xlight);
border-radius: 1rem;
box-shadow: 0 0 0.5rem var(--color-tertiary-dark);
box-shadow: 0 0 0.5rem var(--color-tertiary-ldark);
position: relative;
}

Expand Down Expand Up @@ -41,7 +41,7 @@
height: 5.5rem;
border: 1px solid var(--color-primary-light);
border-radius: 1rem;
box-shadow: 0 0 2px var(--color-tertiary-dark);
box-shadow: 0 0 2px var(--color-tertiary-ldark);
background-color: var(--color-primary);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/inscription/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function InscriptionForm(props: any) {

// TODO: disabled button b4 input
return (
<form className="flex flex-row items-center w-[40%]" onSubmit={handleSubmit}>
<form className="flex flex-row items-center justify-center w-full md:w-[80%] lg:w-[60%] xl:w-[40%] px-8" onSubmit={handleSubmit}>
<div className="flex-grow Form__input">
{selectedOption === "Image" ? (
<div>
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/components/inscription/View.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
background-image: linear-gradient(
to bottom right,
var(--color-tertiary) 60%,
var(--color-tertiary-dark)
var(--color-tertiary-ldark)
);
box-shadow: 0 2px 4px var(--color-tertiary-dark);
overflow: hidden;
cursor: pointer;
transition: all 0.2s;
}
Expand Down
Loading

0 comments on commit bcf7204

Please sign in to comment.