diff --git a/backend/.gitignore b/backend/.gitignore index 4c49bd78f..f66989b51 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1 +1,5 @@ .env + + +/indexer/indexer.env +/indexer/.env \ No newline at end of file diff --git a/backend/indexer/.env.example b/backend/indexer/.env.example new file mode 100644 index 000000000..dfccb9e7d --- /dev/null +++ b/backend/indexer/.env.example @@ -0,0 +1,7 @@ +ART_PEACE_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +APIBARA_STREAM_URL=http://localhost:7171 +CONSUMER_TARGET_URL=http://localhost:8082/consume-indexer-msg + +NFT_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +NFT_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +USERNAME_STORE_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e \ No newline at end of file diff --git a/backend/indexer/Dockerfile b/backend/indexer/Dockerfile index e67f2cecf..5c5a18766 100644 --- a/backend/indexer/Dockerfile +++ b/backend/indexer/Dockerfile @@ -1,6 +1,28 @@ FROM quay.io/apibara/sink-webhook:0.6.0 as sink-webhook WORKDIR /indexer -COPY ./indexer/script.js . +COPY ./script.js . -CMD ["run", "script.js", "--allow-env", "/configs/configs.env", "--allow-env-from-env", "CONSUMER_TARGET_URL,APIBARA_STREAM_URL,PERSIST_TO_REDIS,INDEXER_ID", "--allow-net", "--sink-id", "art-peace-sink-id"] + +ARG ART_PEACE_CONTRACT_ADDRESS + +ENV ART_PEACE_CONTRACT_ADDRESS=${ART_PEACE_CONTRACT_ADDRESS} + + +ARG PERSIST_TO_REDIS + +ENV PERSIST_TO_REDIS=${PERSIST_TO_REDIS} + +ARG APIBARA_STREAM_URL + +ENV APIBARA_STREAM_URL=${APIBARA_STREAM_URL} + +ARG CONSUMER_TARGET_URL + +ENV CONSUMER_TARGET_URL=${CONSUMER_TARGET_URL} + +ARG INDEXER_ID + +ENV INDEXER_ID=${INDEXER_ID} + +CMD ["run", "script.js", "--allow-env", "./.env", "--allow-env-from-env", "CONSUMER_TARGET_URL,APIBARA_STREAM_URL,PERSIST_TO_REDIS,INDEXER_ID, ART_PEACE_CONTRACT_ADDRESS", "--allow-net", "--sink-id", "art-peace-sink-id"] diff --git a/backend/indexer/Dockerfile.prod b/backend/indexer/Dockerfile.prod index fe9b376d7..bafb369d8 100644 --- a/backend/indexer/Dockerfile.prod +++ b/backend/indexer/Dockerfile.prod @@ -3,5 +3,27 @@ FROM quay.io/apibara/sink-webhook:0.6.0 as sink-webhook WORKDIR /indexer COPY ./indexer/prod-script.js . + + +ARG ART_PEACE_CONTRACT_ADDRESS + +ENV ART_PEACE_CONTRACT_ADDRESS=${ART_PEACE_CONTRACT_ADDRESS} + +ARG PERSIST_TO_REDIS + +ENV PERSIST_TO_REDIS=${PERSIST_TO_REDIS} + +ARG APIBARA_STREAM_URL + +ENV APIBARA_STREAM_URL=${APIBARA_STREAM_URL} + +ARG CONSUMER_TARGET_URL + +ENV CONSUMER_TARGET_URL=${CONSUMER_TARGET_URL} + +ARG INDEXER_ID + +ENV INDEXER_ID=${INDEXER_ID} + # TODO: Allow net only on the required domains CMD ["run", "prod-script.js", "--allow-env-from-env", "CONSUMER_TARGET_URL,APIBARA_STREAM_URL,PERSIST_TO_REDIS,INDEXER_ID,ART_PEACE_CONTRACT_ADDRESS,NFT_CONTRACT_ADDRESS,USERNAME_STORE_ADDRESS", "--allow-net", "--sink-id", "art-peace-sink-id"] diff --git a/backend/indexer/README.md b/backend/indexer/README.md index 1885ddf39..f11932e71 100644 --- a/backend/indexer/README.md +++ b/backend/indexer/README.md @@ -6,7 +6,7 @@ This directory contains the Apibara indexer setup for `art/peace`, which indexes ``` # Setup Indexer/DNA w/ docker compose or other options -# Create an indexer.env file with the following : +# Create an .env file with the following : # ART_PEACE_CONTRACT_ADDRESS=... # Example: 0x78223f7ab13216727ed426380079c169578cafad83a3178c7b33ba7ca307713 # APIBARA_STREAM_URL=... # Example: http://localhost:7171 # CONSUMER_TARGET_URL=... # Example: http://localhost:8081/consume-indexer-msg diff --git a/backend/indexer/indexer.env.example b/backend/indexer/indexer.env.example new file mode 100644 index 000000000..dfccb9e7d --- /dev/null +++ b/backend/indexer/indexer.env.example @@ -0,0 +1,7 @@ +ART_PEACE_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +APIBARA_STREAM_URL=http://localhost:7171 +CONSUMER_TARGET_URL=http://localhost:8082/consume-indexer-msg + +NFT_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +NFT_CONTRACT_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e +USERNAME_STORE_ADDRESS=0x1c3e2cae24f0f167fb389a7e4c797002c4f0465db29ecf1753ed944c6ae746e \ No newline at end of file diff --git a/packages/pixel_ui/src/App.tsx b/packages/pixel_ui/src/App.tsx index 24f9a7faa..dd719d3e9 100644 --- a/packages/pixel_ui/src/App.tsx +++ b/packages/pixel_ui/src/App.tsx @@ -23,6 +23,8 @@ import NotificationPanel from './tabs/NotificationPanel.js'; import ModalPanel from './ui/ModalPanel.js'; import Hamburger from './resources/icons/Hamburger.png'; import useMediaQuery from './hooks/useMediaQuery'; +const logoUrl = './resources/logo.png' +const HamburgerUrl = './resources/icons/Hamburger.png'; interface IApp { contractAddress?: string; @@ -163,7 +165,7 @@ function App({ contractAddress }: IApp) { // Colors const staticColors = canvasConfig.colors; - const [colors, setColors] = useState([]); + const [colors, setColors] = useState([]); const [notificationMessage, setNotificationMessage] = useState(''); @@ -217,18 +219,22 @@ function App({ contractAddress }: IApp) { const width = canvasConfig.canvas.width; const height = canvasConfig.canvas.height; - const canvasRef = useRef(null); - const extraPixelsCanvasRef = useRef(null); + const canvasRef = useRef(null); + const extraPixelsCanvasRef = useRef(null); const colorPixel = (position, color) => { const canvas = canvasRef.current; - const context = canvas.getContext('2d'); - const x = position % width; - const y = Math.floor(position / width); - const colorIdx = color; - const colorHex = `#${colors[colorIdx]}FF`; - context.fillStyle = colorHex; - context.fillRect(x, y, 1, 1); + if (canvas && canvasRef?.current) { + const context = canvas?.getContext('2d'); + if (context) { + const x = position % width; + const y = Math.floor(position / width); + const colorIdx = color; + const colorHex = `#${colors[colorIdx]}FF`; + context.fillStyle = colorHex; + context.fillRect(x, y, 1, 1); + } + } }; // Pixel selection data @@ -240,14 +246,14 @@ function App({ contractAddress }: IApp) { const [lastPlacedTime, setLastPlacedTime] = useState(0); const [basePixelUp, setBasePixelUp] = useState(false); - const [chainFactionPixelsData, setChainFactionPixelsData] = useState([]); - const [chainFactionPixels, setChainFactionPixels] = useState([]); - const [factionPixelsData, setFactionPixelsData] = useState([]); - const [factionPixels, setFactionPixels] = useState([]); + const [chainFactionPixelsData, setChainFactionPixelsData] = useState([]); + const [chainFactionPixels, setChainFactionPixels] = useState([]); + const [factionPixelsData, setFactionPixelsData] = useState([]); + const [factionPixels, setFactionPixels] = useState([]); const [extraPixels, setExtraPixels] = useState(0); const [availablePixels, setAvailablePixels] = useState(0); const [availablePixelsUsed, setAvailablePixelsUsed] = useState(0); - const [extraPixelsData, setExtraPixelsData] = useState([]); + const [extraPixelsData, setExtraPixelsData] = useState([]); const [selectorMode, setSelectorMode] = useState(false); @@ -298,11 +304,11 @@ function App({ contractAddress }: IApp) { return () => clearInterval(interval); }, [lastPlacedTime]); - const [chainFactionPixelTimers, setChainFactionPixelTimers] = useState([]); + const [chainFactionPixelTimers, setChainFactionPixelTimers] = useState([]); useEffect(() => { const updateChainFactionPixelTimers = () => { - let newChainFactionPixelTimers = []; - let newChainFactionPixels = []; + let newChainFactionPixelTimers: string[] = []; + let newChainFactionPixels: any[] = []; for (let i = 0; i < chainFactionPixelsData.length; i++) { let memberPixels = chainFactionPixelsData[i].memberPixels; if (memberPixels !== 0) { @@ -337,11 +343,11 @@ function App({ contractAddress }: IApp) { return () => clearInterval(interval); }, [chainFactionPixelsData]); - const [factionPixelTimers, setFactionPixelTimers] = useState([]); + const [factionPixelTimers, setFactionPixelTimers] = useState([]); useEffect(() => { const updateFactionPixelTimers = () => { - let newFactionPixelTimers = []; - let newFactionPixels = []; + let newFactionPixelTimers: any[] = []; + let newFactionPixels: any[] = []; for (let i = 0; i < factionPixelsData.length; i++) { let memberPixels = factionPixelsData[i].memberPixels; if (memberPixels !== 0) { @@ -451,8 +457,13 @@ function App({ contractAddress }: IApp) { setExtraPixelsData([]); const canvas = extraPixelsCanvasRef.current; - const context = canvas.getContext('2d'); - context.clearRect(0, 0, width, height); + if (canvas && canvasRef?.current) { + const context = canvas.getContext('2d'); + if (context) { + context.clearRect(0, 0, width, height); + } + } + }, [width, height]); const clearExtraPixel = useCallback( @@ -460,11 +471,17 @@ function App({ contractAddress }: IApp) { setAvailablePixelsUsed(availablePixelsUsed - 1); setExtraPixelsData(extraPixelsData.filter((_, i) => i !== index)); const canvas = extraPixelsCanvasRef.current; - const context = canvas.getContext('2d'); - const pixel = extraPixelsData[index]; - const x = pixel.x; - const y = pixel.y; - context.clearRect(x, y, 1, 1); + if (canvas) { + const context = canvas.getContext('2d'); + if (context) { + const pixel = extraPixelsData[index]; + const x = pixel.x; + const y = pixel.y; + context.clearRect(x, y, 1, 1); + } + + } + }, [extraPixelsData, availablePixelsUsed] ); @@ -661,7 +678,7 @@ function App({ contractAddress }: IApp) { setLastPlacedTime={setLastPlacedTime} /> {(!isMobile || activeTab === tabs[0]) && ( - logo + logo )}
- Tabs + Tabs
)} {isFooterSplit && footerExpanded && ( diff --git a/packages/pixel_ui/src/footer/PixelSelector.js b/packages/pixel_ui/src/footer/PixelSelector.js index b34b1a38a..ecd25874f 100644 --- a/packages/pixel_ui/src/footer/PixelSelector.js +++ b/packages/pixel_ui/src/footer/PixelSelector.js @@ -12,7 +12,6 @@ const PixelSelector = (props) => { const [placementTimer, setPlacementTimer] = useState('XX:XX'); const {address} = useAccount() - console.log("Pixel selector address",address) useEffect(() => { if (!address) { setPlacementTimer('Login to Play'); diff --git a/packages/pixel_ui/src/utils/Consts.js b/packages/pixel_ui/src/utils/Consts.js index 7c0b9a707..f081bae66 100644 --- a/packages/pixel_ui/src/utils/Consts.js +++ b/packages/pixel_ui/src/utils/Consts.js @@ -6,17 +6,8 @@ const isProduction = process.env.NEXT_PUBLIC_NODE_ENV == "true" ? true : false /** TODO fix url */ const backendConfig = isProduction ? backendConfigProd : backendConfigDev -// const backendConfig = backendConfigProd -// const backendConfig = backendConfigDev -// TODO used REACT_APP_NODE_ENV -// const isProduction = true -// export const backendUrl = 'https://' + backendConfig.host; console.log("isProduction", isProduction) -// export const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL ?? backendConfig.host; - -// export const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL ? 'https://' + process.env.NEXT_PUBLIC_BACKEND_URL : 'https://' + backendConfig.host + ':' + backendConfig.port; -// console.log("backendUrl", backendUrl) export const backendUrl = isProduction ? 'https://' + typeof process.env.NEXT_PUBLIC_BACKEND_URL !== "undefined" ? process.env.NEXT_PUBLIC_BACKEND_URL : backendConfig.host @@ -24,7 +15,8 @@ export const backendUrl = isProduction console.log("backendUrl", backendUrl) export const wsUrl = isProduction - ? 'wss://' + backendConfig.host + '/ws' + // ? 'wss://' + backendConfig.host + '/ws' + ? 'wss://' + typeof process.env.NEXT_PUBLIC_BACKEND_URL !== "undefined" ? process.env.NEXT_PUBLIC_BACKEND_URL + "/ws": backendConfig.host + "/ws" : 'ws://' + backendConfig.host + ':' + backendConfig.consumer_port + '/ws'; console.log("wsUrl", wsUrl) @@ -40,22 +32,8 @@ export const templateUrl = isProduction console.log("templateUrl", templateUrl) -// export const wsUrl = backendConfig.production -// ? 'wss://' + backendConfig.host + '/ws' -// : 'ws://' + backendConfig.host + ':' + backendConfig.consumer_port + '/ws'; -// console.log("wsUrl", wsUrl) - -// export const nftUrl = backendConfig.production -// ? 'https://' + typeof process.env.NEXT_PUBLIC_BACKEND_URL !== "undefined" ? process.env.NEXT_PUBLIC_BACKEND_URL : backendConfig.host -// : 'http://' + backendConfig.host + ':' + backendConfig.consumer_port; - console.log("nftUrl", nftUrl) -// export const templateUrl = backendConfig.production -// ? 'https://' + typeof process.env.NEXT_PUBLIC_BACKEND_URL !== "undefined" ? process.env.NEXT_PUBLIC_BACKEND_URL : backendConfig.host -// : 'http://' + typeof process.env.NEXT_PUBLIC_BACKEND_URL !== "undefined" ? process.env.NEXT_PUBLIC_BACKEND_URL : backendConfig.host + ':' + backendConfig.port; - -// TODO used REACT_APP_NODE_ENV export const devnetMode = backendConfig.production === false; // export const devnetMode = backendConfig.production === false; export const convertUrl = (url) => {