From 2fac2c91d39b6ee5f4e69fece7eb6cf497773b60 Mon Sep 17 00:00:00 2001 From: Adeyemi Gbenga Date: Sun, 8 Dec 2024 21:37:04 +0100 Subject: [PATCH] fix: added env.example and updated consts and pixel placer timer --- apps/mobile/.env.example | 13 ++ apps/pwa/.env.example | 10 ++ packages/pixel_ui/src/App.tsx | 61 ++++++-- .../pixel_ui/src/canvas/CanvasContainer.js | 67 ++------- packages/pixel_ui/src/footer/PixelSelector.js | 11 +- .../pixel_ui/src/tabs/account/Account.tsx | 2 - packages/pixel_ui/src/utils/Consts.js | 135 +++++++++--------- 7 files changed, 161 insertions(+), 138 deletions(-) diff --git a/apps/mobile/.env.example b/apps/mobile/.env.example index 1df15137..ce922a47 100644 --- a/apps/mobile/.env.example +++ b/apps/mobile/.env.example @@ -17,6 +17,19 @@ REACT_APP_CANVAS_NFT_CONTRACT_ADDRESS= REACT_APP_USERNAME_STORE_CONTRACT_ADDRESS= REACT_APP_NODE_ENV= +# PWA Pixel UI package +NEXT_PUBLIC_CANVAS_STARKNET_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +NEXT_PUBLIC_USERNAME_STORE_CONTRACT_ADDRESS= +NEXT_PUBLIC_CANVAS_NFT_CONTRACT_ADDRESS= +NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS= +NEXT_PUBLIC_PROVIDER_URL= +NEXT_PUBLIC_ARGENT_WEBWALLET_URL= +NEXT_PUBLIC_ARGENT_SESSION_SERVICE_BASE_URL= +NEXT_PUBLIC_CHAIN_ID= +NEXT_PUBLIC_STARKNET_CHAIN_ID= +NEXT_PUBLIC_PROVIDER_URL="https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/api_key" +NEXT_PUBLIC_BACKEND_URL= + EXPO_PUBLIC_DYNAMIC_API_KEY="DYNAMIC_API_KEY" EXPO_PUBLIC_LAYERSWAP_CLIENT_ID="" diff --git a/apps/pwa/.env.example b/apps/pwa/.env.example index 690d4798..e3ad5b1f 100644 --- a/apps/pwa/.env.example +++ b/apps/pwa/.env.example @@ -15,9 +15,19 @@ REACT_APP_USERNAME_STORE_CONTRACT_ADDRESS= REACT_APP_NODE_ENV= NEXT_PUBLIC_GOOGLE_ANALYTICS= +# PWA Pixel UI package NEXT_PUBLIC_CANVAS_STARKNET_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e NEXT_PUBLIC_USERNAME_STORE_CONTRACT_ADDRESS= NEXT_PUBLIC_CANVAS_NFT_CONTRACT_ADDRESS= +NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS= +NEXT_PUBLIC_PROVIDER_URL= +NEXT_PUBLIC_ARGENT_WEBWALLET_URL= +NEXT_PUBLIC_ARGENT_SESSION_SERVICE_BASE_URL= +NEXT_PUBLIC_CHAIN_ID= +NEXT_PUBLIC_STARKNET_CHAIN_ID= +NEXT_PUBLIC_PROVIDER_URL= +NEXT_PUBLIC_BACKEND_URL= + NEXT_PUBLIC_DYNAMIC_API_KEY="dynamic env id" NEXT_PUBLIC_DYNAMIC_ENV_ID="dynamic env id" diff --git a/packages/pixel_ui/src/App.tsx b/packages/pixel_ui/src/App.tsx index 043af09f..e45050a4 100644 --- a/packages/pixel_ui/src/App.tsx +++ b/packages/pixel_ui/src/App.tsx @@ -22,7 +22,7 @@ import ModalPanel from './ui/ModalPanel.js'; import { connect as nextConnect } from 'starknetkit-next'; import useMediaQuery from './hooks/useMediaQuery'; import { buildSessionAccount, createSessionRequest, openSession } from '@argent/x-sessions'; -import { stark } from 'starknet'; +import { Contract, stark } from 'starknet'; const logoUrl = './resources/logo.png' const HamburgerUrl = './resources/icons/Hamburger.png'; @@ -272,6 +272,25 @@ function App({ contractAddress, usernameAddress, nftCanvasAddress }: IApp) { } }; + //CallData + const estimateInvokeFee = async ({ + contractAddress, + entrypoint, + calldata + }) => { + try { + const { suggestedMaxFee } = await account.estimateInvokeFee({ + contractAddress: contractAddress, + entrypoint: entrypoint, + calldata: calldata + }); + return { suggestedMaxFee }; + } catch (error) { + console.error(error); + return { suggestedMaxFee: BigInt(1000000000000000) }; + } + }; + // Pixel selection data const [selectedColorId, setSelectedColorId] = useState(-1); const [pixelSelectedMode, setPixelSelectedMode] = useState(false); @@ -322,6 +341,7 @@ function App({ contractAddress, usernameAddress, nftCanvasAddress }: IApp) { const updateBasePixelTimer = () => { let timeSinceLastPlacement = Date.now() - lastPlacedTime; let basePixelAvailable = timeSinceLastPlacement > timeBetweenPlacements; + if (basePixelAvailable) { setBasePixelUp(true); setBasePixelTimer('00:00'); @@ -330,18 +350,22 @@ function App({ contractAddress, usernameAddress, nftCanvasAddress }: IApp) { let secondsTillPlacement = Math.floor( (timeBetweenPlacements - timeSinceLastPlacement) / 1000 ); - setBasePixelTimer( - `${Math.floor(secondsTillPlacement / 60)}:${secondsTillPlacement % 60 < 10 ? '0' : ''}${secondsTillPlacement % 60}` - ); + let minutes = Math.floor(secondsTillPlacement / 60); + let seconds = secondsTillPlacement % 60; + setBasePixelTimer(`${minutes}:${seconds.toString().padStart(2, '0')}`); setBasePixelUp(false); } }; + const interval = setInterval(() => { updateBasePixelTimer(); }, updateInterval); - updateBasePixelTimer(); + + updateBasePixelTimer(); // Call immediately + return () => clearInterval(interval); - }, [lastPlacedTime]); + }, [lastPlacedTime, timeBetweenPlacements]); + const [chainFactionPixelTimers, setChainFactionPixelTimers] = useState([]); useEffect(() => { @@ -513,6 +537,11 @@ function App({ contractAddress, usernameAddress, nftCanvasAddress }: IApp) { }; + const clearAll = () => { + clearExtraPixels(); + setSelectedColorId(-1); + }; + const clearExtraPixels = useCallback(() => { setAvailablePixelsUsed(0); setExtraPixelsData([]); @@ -657,16 +686,18 @@ function App({ contractAddress, usernameAddress, nftCanvasAddress }: IApp) { setConnected(true); return; } + const { wallet, connectorData, connector } = await nextConnect({ modalMode: 'alwaysAsk', - webWalletUrl: process.env.REACT_APP_ARGENT_WEBWALLET_URL, + webWalletUrl: process.env.NEXT_PUBLIC_ARGENT_WEBWALLET_URL, argentMobileOptions: { - dappName: 'AFK/Lfg', + dappName: 'Afk/lfg', url: window.location.hostname, chainId: CHAIN_ID, icons: [] } }); + if (wallet && connectorData && connector) { setWallet(wallet); setConnectorData(connectorData); @@ -760,17 +791,23 @@ const startSession = async () => { publicDappKey: dappKey.publicKey }; let chainId = await provider.getChainId(); + + console.log("chain", chainId) const accountSessionSignature = await openSession({ wallet: wallet, sessionParams: sessionParams as any, chainId: chainId }); + + const sessionRequest = createSessionRequest( allowedMethods, expiry as any, metaData(false), dappKey.publicKey ); + + if (!accountSessionSignature || !sessionRequest) { console.error('Session request failed'); return; @@ -789,7 +826,7 @@ const startSession = async () => { address: address, dappKey: dappKey, argentSessionServiceBaseUrl: - process.env.REACT_APP_ARGENT_SESSION_SERVICE_BASE_URL + process.env.NEXT_PUBLIC_ARGENT_SESSION_SERVICE_BASE_URL }); if (!sessionAccount) { console.error('Session account failed'); @@ -808,8 +845,10 @@ const startSession = async () => { /> {modal && } { queryAddress={queryAddress} account={account} chain={chain} + clearAll={clearAll} setConnected={setConnected} artPeaceContract={artPeaceContract} usernameContract={usernameContract} @@ -962,7 +1002,7 @@ const startSession = async () => { startSession={startSession} isSessionable={isSessionable} disconnectWallet={disconnectWallet} - + estimateInvokeFee={estimateInvokeFee} /> @@ -997,6 +1037,7 @@ const startSession = async () => { setIsEraseMode={setIsEraserMode} isPortrait={isPortrait} isMobile={isMobile} + clearAll={clearAll} /> )} diff --git a/packages/pixel_ui/src/canvas/CanvasContainer.js b/packages/pixel_ui/src/canvas/CanvasContainer.js index b6f6ccf6..73554de9 100644 --- a/packages/pixel_ui/src/canvas/CanvasContainer.js +++ b/packages/pixel_ui/src/canvas/CanvasContainer.js @@ -1,22 +1,16 @@ import './CanvasContainer.css'; -import { useAccount, useContractWrite } from '@starknet-react/core'; import React, { useEffect, useRef, useState } from 'react'; - import canvasConfig from '../configs/canvas.config.json'; import { fetchWrapper } from '../services/apiService.js'; -import { devnetMode } from '../utils/Consts.js'; import Canvas from './Canvas'; import ExtraPixelsCanvas from './ExtraPixelsCanvas.js'; import NFTSelector from './NFTSelector.js'; import TemplateCreationOverlay from './TemplateCreationOverlay.js'; import TemplateOverlay from './TemplateOverlay.js'; -import { ART_PEACE_ADDRESS } from "common" -import { CallData } from 'starknet'; const CanvasContainer = (props) => { - const { account, address } = useAccount() // TODO: Handle window resize const width = canvasConfig.canvas.width; const height = canvasConfig.canvas.height; @@ -235,55 +229,24 @@ const CanvasContainer = (props) => { props.setPixelPlacedBy(getPixelInfoEndpoint.data); }; - const [calls, setCalls] = useState([]); const placePixelCall = async (position, color, now) => { - // if (devnetMode) return; - console.log("props artpeaceCOntract", props?.artPeaceContract) - // if (!props.address || !props.artPeaceContract) return; - if (!props.artPeaceContract) { - console.log('user connected', account?.address); - - const pixelCalldata = { - contractAddress: ART_PEACE_ADDRESS?.['0x534e5f5345504f4c4941'], - entrypoint: "place_pixel", - calldata: CallData.compile({ - position: position, - color, - now - }) - - } - console.log("pixelCAlldata",pixelCalldata) - const tx = await account.execute([pixelCalldata]) - - console.log('tx hash', tx.transaction_hash); - - const wait_tx = await account?.waitForTransaction(tx?.transaction_hash); - - - } else { - // TODO: Check valid inputs - setCalls(props.artPeaceContract.populateTransaction['place_pixel'](position, color, now)); - - } - }; - - useEffect(() => { - const placePixel = async () => { // if (devnetMode) return; - console.log('Place Pixel calls:', calls); + console.log("props artpeaceCOntract", props?.artPeaceContract, "contrr",) + // if (!props.address || !props.artPeaceContract) return; + if (!props.address || !props.artPeaceContract || !props.account) return; + + console.log('user connected', props.account?.address); + const pixelCalldata = props.artPeaceContract.populate('place_pixel', { + pos: position, + color: color, + now: now + }); - if (calls.length === 0) return; - await writeAsync(); - console.log('Place Pixel successful:', data, isPending); - // TODO: Update the UI with the new state - }; - placePixel(); - }, [calls]); + console.log(pixelCalldata,"pixel") + const result = await props.account.execute([pixelCalldata]); + console.log(result,"res") + }; - const { writeAsync, data, isPending } = useContractWrite({ - calls, - }); const pixelClicked = async (e) => { if (props.nftMintingMode || props.templateCreationMode) { @@ -338,7 +301,7 @@ const CanvasContainer = (props) => { // if (!devnetMode) { props.setSelectedColorId(-1); props.colorPixel(position, colorId); - placePixelCall(position, colorId, timestamp); + await placePixelCall(position, colorId, timestamp); props.clearPixelSelection(); props.setLastPlacedTime(timestamp * 1000); // return; diff --git a/packages/pixel_ui/src/footer/PixelSelector.js b/packages/pixel_ui/src/footer/PixelSelector.js index 217c50f7..fe3f1680 100644 --- a/packages/pixel_ui/src/footer/PixelSelector.js +++ b/packages/pixel_ui/src/footer/PixelSelector.js @@ -11,7 +11,6 @@ const PixelSelector = (props) => { const [placementTimer, setPlacementTimer] = useState('XX:XX'); const [placementMode, setPlacementMode] = useState(false); const [ended, setEnded] = useState(false); - useEffect(() => { if (props.queryAddress === '0') { setPlacementTimer('Login to Play'); @@ -32,7 +31,7 @@ const PixelSelector = (props) => { } else { // TODO: Use lowest timer out of base, chain, faction, ... setPlacementTimer(props.basePixelTimer); - + props.clearAll(); } if ( placementTimer === '0:00' && @@ -44,7 +43,7 @@ const PixelSelector = (props) => { } else { setEnded(false); } - }, [props.availablePixels, props.availablePixelsUsed, props.basePixelTimer, props.queryAddress, placementTimer, placementMode, props.query]); + }, [props.availablePixels, props.availablePixelsUsed, props.basePixelTimer, props.queryAddress, placementTimer, placementMode, props]); const toSelectorMode = (event) => { event.preventDefault(); @@ -61,7 +60,7 @@ const PixelSelector = (props) => { if (props.availablePixels > props.availablePixelsUsed) { props.setSelectorMode(true); props.setIsEraserMode(false); - // setPlacementMode(true); + setPlacementMode(true); } }; @@ -74,8 +73,8 @@ const PixelSelector = (props) => { props.setSelectedColorId(-1); props.setSelectorMode(false); props.setIsEraserMode(false); - // setPlacementMode(false); - // setEnded(false); + setPlacementMode(false); + setEnded(false); }; return ( diff --git a/packages/pixel_ui/src/tabs/account/Account.tsx b/packages/pixel_ui/src/tabs/account/Account.tsx index 9d36b5a4..2a7e6b9b 100644 --- a/packages/pixel_ui/src/tabs/account/Account.tsx +++ b/packages/pixel_ui/src/tabs/account/Account.tsx @@ -26,8 +26,6 @@ const Account = (props) => { const {isSessionable, usingSessionKeys} = props!; - console.log(isSessionable, usingSessionKeys,"keys") - const [usernameSaved, setUsernameSaved] = useState(false); const [isEditing, setIsEditing] = useState(false); diff --git a/packages/pixel_ui/src/utils/Consts.js b/packages/pixel_ui/src/utils/Consts.js index 3ead2902..6df63480 100644 --- a/packages/pixel_ui/src/utils/Consts.js +++ b/packages/pixel_ui/src/utils/Consts.js @@ -45,90 +45,89 @@ export const convertUrl = (url) => { }; export const CHAIN_ID = - process.env.REACT_APP_CHAIN_ID === constants.NetworkName.SN_MAIN + process.env.NEXT_PUBLIC_CHAIN_ID === constants.NetworkName.SN_MAIN ? constants.NetworkName.SN_MAIN : constants.NetworkName.SN_SEPOLIA; export const getProvider = (chainId) => { const provider = new RpcProvider({ nodeUrl: process.env.NEXT_PUBLIC_PROVIDER_URL, - chainId: chainId ?? constants.StarknetChainId.SN_SEPOLIA + chainId: chainId || constants.StarknetChainId.SN_SEPOLIA }); return provider } export const provider = new RpcProvider({ - nodeUrl: process.env.PROVIDER_URL, - chainId: process.env.STARKNET_CHAIN_ID ?? constants.StarknetChainId.SN_SEPOLIA + nodeUrl: process.env.NEXT_PUBLIC_PROVIDER_URL, + chainId: process.env.NEXT_PUBLIC_STARKNET_CHAIN_ID || constants.StarknetChainId.SN_SEPOLIA }); -//Change the commented section to NEXTJS ENVS since we are deploying to next environment export const allowedMethods = [ - { + { 'Contract Address': process.env.NEXT_PUBLIC_CANVAS_STARKNET_CONTRACT_ADDRESS || "", selector: 'place_extra_pixels', - } - // { - // 'Contract Address': process.env.REACT_APP_USERNAME_STORE_CONTRACT_ADDRESS, - // selector: 'claim_username' - // }, - // { - // 'Contract Address': process.env.REACT_APP_USERNAME_STORE_CONTRACT_ADDRESS, - // selector: 'change_username' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'claim_today_quest' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'claim_main_quest' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'vote_color' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'place_extra_pixels' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'add_faction_template' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'join_faction' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'join_chain_faction' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'add_chain_faction_template' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'mint_nft' - // }, - // { - // 'Contract Address': process.env.REACT_APP_CANVAS_NFT_CONTRACT_ADDRESS, - // selector: 'like_nft' - // }, - // { - // 'Contract Address': process.env.REACT_APP_CANVAS_NFT_CONTRACT_ADDRESS, - // selector: 'unlike_nft' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'increase_day_index' - // }, - // { - // 'Contract Address': process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS, - // selector: 'place_pixel' - // } + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_USERNAME_STORE_CONTRACT_ADDRESS || "", + selector: 'claim_username' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_USERNAME_STORE_CONTRACT_ADDRESS || "", + selector: 'change_username' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'claim_today_quest' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'claim_main_quest' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'vote_color' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'place_extra_pixels' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'add_faction_template' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'join_faction' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'join_chain_faction' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'add_chain_faction_template' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'mint_nft' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_CANVAS_NFT_CONTRACT_ADDRESS || "", + selector: 'like_nft' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_CANVAS_NFT_CONTRACT_ADDRESS || "", + selector: 'unlike_nft' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'increase_day_index' + }, + { + 'Contract Address': process.env.NEXT_PUBLIC_STARKNET_CONTRACT_ADDRESS || "", + selector: 'place_pixel' + } ]; export const expiry = Math.floor((Date.now() + 1000 * 60 * 60 * 24) / 1000); @@ -168,7 +167,7 @@ export const parseUnits = (value, decimals) => { // TODO: Allow STRK fee tokens export const metaData = (isStarkFeeToken) => ({ - projectID: 'art-peace', + projectID: 'afk', txFees: isStarkFeeToken ? [] : ETHFees });