From a2cff4f9b0e4310105f6638eb0caa017e4f30496 Mon Sep 17 00:00:00 2001 From: Lana Ivina Date: Tue, 31 Dec 2024 03:16:41 +0100 Subject: [PATCH] Text and small PNG image request works onchain, Xverse address fetched --- apps/web/src/App.tsx | 57 +++++++++---- apps/web/src/components/inscription/Form.tsx | 90 ++++++++++++++++---- apps/web/src/pages/Home.tsx | 32 +++++-- 3 files changed, 144 insertions(+), 35 deletions(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 6477c3b..e8ced4c 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -88,13 +88,24 @@ function App() { setIsStarknetConnected(false) } - // Bitcoin Wallet Connect + const [taprootAddress, setTaprootAddress] = useState(null) + const connectBitcoinWalletHandler = async () => { const addresses = await connectBitcoinWallet() - setBitcoinWallet(addresses) + // TODO: replace with the Ordinals address. + // Currently the sats connect lib fetches + // only the Payments address from Xverse. + if (addresses.paymentAddress) { + setTaprootAddress(addresses.paymentAddress) + setBitcoinWallet((prev) => ({ + ...prev, + paymentAddress: addresses.paymentAddress, + })) + } else { + console.error('Ordinals address not found in wallet connection') + } } - - // Bitcoin Wallet Disconnect + const disconnectBitcoinWallet = () => { setBitcoinWallet({ paymentAddress: null, ordinalsAddress: null, stacksAddress: null }) } @@ -113,21 +124,23 @@ function App() { }); const [calls, setCalls] = useState([] as any[]) - const requestInscriptionCall = async () => { + + const requestInscriptionCall = async (dataToInscribe: string, taprootAddress: string) => { if (!address || !orderbookContract) { return } + const calldata = CallData.compile([ - byteArray.byteArrayFromString("message:Hello, Starknet!"), - byteArray.byteArrayFromString("tb1234567890123456789012345678901234567890"), - Number(100), + byteArray.byteArrayFromString(dataToInscribe), + byteArray.byteArrayFromString(taprootAddress), + Number(100), // TODO remove when contract is re-deployed toHex("STRK"), - uint256.bnToUint256(2000) - ]); - setCalls( - [orderbookContract.populate('request_inscription', calldata)] - ) + uint256.bnToUint256(2000), + ]) + + setCalls([await orderbookContract.populate('request_inscription', calldata)]) } + const { send, data, isPending } = useSendTransaction({ calls }); @@ -174,14 +187,28 @@ function App() { connectWallet: connectBitcoinWalletHandler, disconnectWallet: disconnectBitcoinWallet }} - />
+ /> +
{tabs.map((tab) => ( - } /> + + } + /> ))} } /> } /> +
) } diff --git a/apps/web/src/components/inscription/Form.tsx b/apps/web/src/components/inscription/Form.tsx index 0ea4f44..9a0355c 100644 --- a/apps/web/src/components/inscription/Form.tsx +++ b/apps/web/src/components/inscription/Form.tsx @@ -10,14 +10,44 @@ function InscriptionForm(props: any) { const handleSubmit = async (e: any) => { e.preventDefault(); - if (!uploadedImage) { - setErrorMessage("Please upload an image"); + + let dataToInscribe = ""; + + if (selectedOption === "Image") { + if (!uploadedImage) { + setErrorMessage("Please upload an image"); + return; + } + const response = await fetch(uploadedImage); + const blob = await response.blob(); + const base64Image = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result as string); + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + dataToInscribe = base64Image; + } else if (selectedOption === "Message") { + const textAreaElement = document.querySelector(".Form__textarea"); + dataToInscribe = textAreaElement?.value || ""; + if (!dataToInscribe) { + setErrorMessage("Please enter a message to inscribe"); + return; + } + } + + const taprootAddress = props.taprootAddress; + if (!taprootAddress) { + setErrorMessage("Taproot address not found. Please connect Bitcoin wallet."); return; } - await props.requestInscriptionCall(); + + setErrorMessage(""); + + await props.requestInscriptionCall(dataToInscribe, taprootAddress); props.setIsInscribing(true); - }; - + } + const handleImageUpload = (e: any) => { e.preventDefault(); if (e.target.files && e.target.files[0]) { @@ -39,28 +69,58 @@ function InscriptionForm(props: any) {
{selectedOption === "Image" ? (
-
) : ( -