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: starknet wallet interact #27

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Needed to run Indexer
APIBARA_AUTH_TOKEN=dna_xxx

# Only needed to deploy the contract
STARKNET_KEYSTORE=$HOME/.starkli-sepolia/starkli-keystore.json
STARKNET_ACCOUNT=$HOME/.starkli-sepolia/starkli-account.json
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div align="center">
<img src="apps/web/public/images/logo.png" alt="broly-logo" height="220"/>
<img src="apps/web/public/images/logo-high.png" alt="broly-logo" height="220"/>

# B.R.O.L.Y.
***Bitcoin Registry Orchestrates Like Yesterday***
Expand Down Expand Up @@ -100,6 +100,7 @@ broly/
├── packages/
│ ├── inscribor/ # Bitcoin inscription service
│ ├── onchain/ # Starknet smart contracts
│ ├── scripts/ # Deployment & Testing scripts
│ └── indexer/ # Starknet contract indexing
├── package.json
└── turbo.json
Expand Down
6 changes: 5 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
"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"
"react-router": "^7.0.1",
"starknet": "^6.11.0",
"starknetkit": "^2.6.1"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
Expand Down
Binary file added apps/web/public/images/logo-high.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/web/public/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
132 changes: 126 additions & 6 deletions apps/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { useState } from 'react'
import { useState, useEffect } from 'react'
import { Routes, Route } from 'react-router'
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';

import Home from './pages/Home'
import Inscriptions from './pages/Inscriptions'
Expand All @@ -10,25 +14,141 @@ import Info from './pages/Info'
import Inscription from './pages/Inscription'
import Request from './pages/Request'

export const NODE_URL = 'https://starknet-sepolia.public.blastapi.io/rpc/v0_7';
export const STARKNET_CHAIN_ID = constants.StarknetChainId.SN_SEPOLIA;

//export const provider = new RpcProvider([NODE_URL], STARKNET_CHAIN_ID);
export const provider = new RpcProvider({
nodeUrl: NODE_URL,
chainId: STARKNET_CHAIN_ID
});

function App() {
// TODO: Move to seperate module ( starknet stuff )
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 { connector } = await starknetkitConnectModal()
if (!connector) {
return
}
connect({ connector })
setConnector(connector)
}

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])

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

const toHex = (str: string) => {
let hex = '0x';
for (let i = 0; i < str.length; i++) {
hex += '' + str.charCodeAt(i).toString(16);
}
return hex;
};

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 (!address || !orderbookContract) {
return
}
const calldata = CallData.compile([
byteArray.byteArrayFromString("message:Hello, Starknet!"),
byteArray.byteArrayFromString("tb1234567890123456789012345678901234567890"),
Number(100),
toHex("STRK"),
uint256.bnToUint256(2000)
]);
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
}

const [tabs, _setTabs] = useState([
{ name: 'Home', path: '/', component: Home },
{ name: 'Home', path: '/', component: Home as any },
{ name: 'Inscriptions', path: '/inscriptions', component: Inscriptions },
{ name: 'Collection', path: '/collection', component: Collection },
{ name: 'Info', path: '/info', component: Info },
])
const tabProps = {
requestInscriptionCall,
cancelInscriptionCall,
orderbookContract
}

// TODO: <Route path="*" element={<NotFound />} />
return (
<div className="h-screen relative">
<Header tabs={tabs} />
<Header tabs={tabs} connectWallet={connectWallet} isConnected={isConnected} disconnectWallet={disconnectWallet} />
<div className="h-[4.5rem]" />
<Routes>
{tabs.map((tab) => (
<Route key={tab.path} path={tab.path} element={<tab.component />} />
<Route key={tab.path} path={tab.path} element={<tab.component {...tabProps} />} />
))}
<Route path="/inscription/:id" element={<Inscription />} />
<Route path="/request/:id" element={<Request />} />
<Route path="/inscription/:id" element={<Inscription {...tabProps} />} />
<Route path="/request/:id" element={<Request {...tabProps} />} />
</Routes>
</div>
)
Expand Down
Loading
Loading