From c106de9412d7b707dc0bf88d9b2f1773cf8fdb00 Mon Sep 17 00:00:00 2001 From: Nadai <112663528+Nadai2010@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:27:42 +0100 Subject: [PATCH] Update ch-2: cyberpunk theme and scaffold-stark new features (#89) Co-authored-by: Gabriela del Pilar Rojas <77763655+GabrielaDelPilarR@users.noreply.github.com> Co-authored-by: gianmalarcon Co-authored-by: Gabriela del Pilar Rojas --- .github/workflows/demo.yaml | 63 ++++++++ .github/workflows/release-create-stark.yaml | 114 +++++++++++++ README.md | 4 +- .../app/debug/_components/DebugContracts.tsx | 4 +- .../contract/ContractReadMethods.tsx | 3 - .../debug/_components/contract/ContractUI.tsx | 34 ++-- .../contract/ContractVariables.tsx | 3 - .../_components/contract/DisplayVariable.tsx | 9 +- .../contract/ReadOnlyFunctionForm.tsx | 8 +- .../debug/_components/contract/TxReceipt.tsx | 10 +- .../contract/WriteOnlyFunctionForm.tsx | 13 +- packages/nextjs/app/debug/page.tsx | 10 -- packages/nextjs/app/token-vendor/page.tsx | 150 ++++++++++-------- packages/nextjs/components/FaucetMenu.tsx | 3 - packages/nextjs/components/Footer.tsx | 45 +----- packages/nextjs/components/Header.tsx | 80 ++++++++-- .../ScaffoldStarkAppWithProviders.tsx | 47 +++--- packages/nextjs/components/SwitchTheme.tsx | 10 +- .../components/assets/BuidlGuidlLogo.tsx | 18 --- .../AddressInfoDropdown.tsx | 52 +++--- .../CustomConnectButton/ConnectModal.tsx | 128 +++++---------- .../CustomConnectButton/GenericModal.tsx | 12 +- .../CustomConnectButton/Wallet.tsx | 7 +- .../CustomConnectButton/index.tsx | 9 +- .../components/scaffold-stark/Faucet.tsx | 6 +- .../scaffold-stark/Input/AddressInput.tsx | 1 - .../scaffold-stark/Input/InputBase.tsx | 6 +- .../scaffold-stark/Input/IntegerInput.tsx | 2 +- .../nextjs/contracts/deployedContracts.ts | 20 +-- packages/nextjs/public/ch2-Events.png | Bin 0 -> 423879 bytes .../nextjs/public/ch2-TokenVendorBalance.png | Bin 1989301 -> 478680 bytes packages/nextjs/public/ch2-VendorBuySell.png | Bin 1666770 -> 80264 bytes packages/nextjs/public/ch2-YourToken.png | Bin 3002158 -> 526580 bytes packages/nextjs/public/debug-icon.svg | 9 ++ packages/nextjs/public/explorer-icon.svg | 27 ++++ packages/nextjs/public/gradient-s.svg | 9 ++ packages/nextjs/services/web3/connectors.tsx | 19 +++ packages/nextjs/styles/globals.css | 99 +++++++++++- packages/nextjs/tailwind.config.ts | 114 +++++++++++-- .../nextjs/utils/scaffold-stark/networks.ts | 3 - packages/snfoundry/contracts/src/Vendor.cairo | 6 - packages/snfoundry/localhost.accounts.json | 12 -- packages/snfoundry/package.json | 4 +- .../snfoundry/scripts-ts/deploy-contract.ts | 10 ++ packages/snfoundry/scripts-ts/deploy.ts | 2 +- .../snfoundry/scripts-ts/helpers/networks.ts | 15 -- packages/snfoundry/scripts-ts/types.ts | 5 +- yarn.lock | 50 +++++- 48 files changed, 801 insertions(+), 454 deletions(-) create mode 100644 .github/workflows/demo.yaml create mode 100644 .github/workflows/release-create-stark.yaml delete mode 100644 packages/nextjs/components/assets/BuidlGuidlLogo.tsx create mode 100644 packages/nextjs/public/ch2-Events.png create mode 100644 packages/nextjs/public/debug-icon.svg create mode 100644 packages/nextjs/public/explorer-icon.svg create mode 100644 packages/nextjs/public/gradient-s.svg delete mode 100644 packages/snfoundry/localhost.accounts.json diff --git a/.github/workflows/demo.yaml b/.github/workflows/demo.yaml new file mode 100644 index 000000000..7451bda5e --- /dev/null +++ b/.github/workflows/demo.yaml @@ -0,0 +1,63 @@ +name: scaffold-stark-demo workflow + +on: + pull_request: + types: [closed] + branches: [main] + paths: + - 'packages/nextjs/**' + +jobs: + version-bump-nextjs: + runs-on: ubuntu-22.04 + steps: + + - name: Checkout Source Repository + uses: actions/checkout@v4 + with: + repository: Quantum3-Labs/scaffold-stark-2 + token: ${{ secrets.ORG_GITHUB_TOKEN }} + path: source_repo + + - name: Modify scaffoldConfig in Source Repository + run: | + cd source_repo + sed -i 's/targetNetworks: \[chains.devnet\]/targetNetworks: \[chains.sepolia\]/' packages/nextjs/scaffold.config.ts + cat packages/nextjs/scaffold.config.ts + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 20 + registry-url: 'https://registry.yarnpkg.com' + + - name: Deploy to vercel + if: success() + id: deploy + env: + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + run: | + cd source_repo + yarn install + vercel link --yes --project $VERCEL_PROJECT_ID --token $VERCEL_TOKEN --scope $VERCEL_ORG_ID + vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true --prod --token $VERCEL_TOKEN --scope $VERCEL_ORG_ID + + - name: Notify Slack on Success + if: success() + uses: slackapi/slack-github-action@v1.26.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + slack-message: "GitHub deployed to vercel result: ${{ job.status }}\nRepository Name: ${{ github.repository }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + + - name: Notify Slack on Failure + if: failure() + uses: slackapi/slack-github-action@v1.26.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + slack-message: "GitHub deployed to vercel result: ${{ job.status }}\nRepository Name: ${{ github.repository }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/release-create-stark.yaml b/.github/workflows/release-create-stark.yaml new file mode 100644 index 000000000..7bda6f8bc --- /dev/null +++ b/.github/workflows/release-create-stark.yaml @@ -0,0 +1,114 @@ +name: Version Bump and Notify + +on: + pull_request: + types: [closed] + branches: [main] + +jobs: + version-bump: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout Source Repository + uses: actions/checkout@v4 + with: + repository: Quantum3-Labs/scaffold-stark-2 + token: ${{ secrets.ORG_GITHUB_TOKEN }} + path: source_repo + + - name: Checkout Destination Repository + uses: actions/checkout@v4 + with: + repository: Quantum3-Labs/create-stark + token: ${{ secrets.ORG_GITHUB_TOKEN }} + path: destination_repo + + - name: Determine version bump type + id: version + run: | + cd source_repo + commit_message=$(git log -1 --pretty=%B) + if [[ "$commit_message" == *"[major]"* ]]; then + echo "type=major" >> "$GITHUB_ENV" + elif [[ "$commit_message" == *"[minor]"* ]]; then + echo "type=minor" >> "$GITHUB_ENV" + else + echo "type=patch" >> "$GITHUB_ENV" + fi + + - name: Bump version in Source Repository + id: bump-version-source + run: | + cd source_repo + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + new_version=$(npm version ${{ env.type }} -m "chore(release): %s [skip ci]") + echo "NEW_VERSION=${new_version}" >> "$GITHUB_ENV" + git push origin main --follow-tags + + - name: Copy Files to Destination Repository + run: | + rsync -av --delete --exclude='.git' source_repo/ destination_repo/templates/base + cd destination_repo + git add . + git commit -m "chore: sync files from scaffold-stark-2 [skip ci]" + + - name: Format .gitignore files + run: | + find destination_repo/templates/base -type f -name ".gitignore" | while read -r gitignore_file; do + mjs_file="${gitignore_file%/*}/.gitignore.template.mjs" + gitignore_content=$(cat "$gitignore_file") + cat > "$mjs_file" <<-EOF + const contents = () => + \`${gitignore_content}\` + + export default contents; + EOF + rm "$gitignore_file" + done + cd destination_repo + git add . + git commit -m "Processed $gitignore_file into $mjs_file" + + - name: Bump version in Destination Repository + id: bump-version-destination + run: | + cd destination_repo + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + new_version=$(npm version ${{ env.type }} -m "chore(release): %s [skip ci]") + git push origin main --follow-tags + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '16' + registry-url: 'https://registry.npmjs.org/' + + - name: Publish release + if: success() + id: publish-release + run: | + cd destination_repo + npm install && npm run build && npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Notify Slack on Success + if: success() + uses: slackapi/slack-github-action@v1.26.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + slack-message: "GitHub Action succeeded for version bump to ${{ env.NEW_VERSION }}." + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + + - name: Notify Slack on Failure + if: failure() + uses: slackapi/slack-github-action@v1.26.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + slack-message: "GitHub Action failed for version bump." + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index a20ff2180..23c0790f0 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ yarn start > 👩‍💻 Edit `YourToken.cairo` to reuse the **ERC20** token standard from OpenZeppelin. To accomplish this, you can use [`Cairo Components`](https://book.cairo-lang.org/ch16-02-00-composability-and-components.html) to embed the `ERC20` logic inside your contract. -> Mint **2000** (\* 10 \*\* 18) to your frontend address using the `constructor()`. In devnet, by default we choose the first pre-deployed account: `0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691`, to deploy the contracts. In order to complete this checkpoint, you need to connect to devnet using the same address. In testnet, you can use your own address to deploy the contracts. Edi the .env file in the `snfoundry` package to set the `ACCOUNT_ADDRESS_SEPOLIA` to your own address. +> Mint **2000** (\* 10 \*\* 18) to your frontend address using the `constructor()`. In devnet, by default we choose the first pre-deployed account: `0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691`, to deploy the contracts. In order to complete this checkpoint, you need to connect to devnet using the same address. In testnet, you can use your own address to deploy the contracts. Edit the .env file in the `snfoundry` package to set the `ACCOUNT_ADDRESS_SEPOLIA` to your own address. (Your frontend address is the address in the top right of ) @@ -225,7 +225,7 @@ In `Vendor.cairo` you will need to add one more input parameter to setup the `ow `SellTokens {seller: ContractAddress, tokens_amount: u256, eth_amount: u256}` and `emit` it in your `Vendor.cairo` and uncomment `SellTokens Events` section in your `packages/nextjs/app/events/page.tsx` to update your frontend. - ![Events](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/2812ab21de5d261ef670b0ef5a211fdfbae3b8d8/packages/nextjs/public/events.png) + ![Events](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/token-vendor/nextjs/public/Events.png) ### ⚠️ Test it diff --git a/packages/nextjs/app/debug/_components/DebugContracts.tsx b/packages/nextjs/app/debug/_components/DebugContracts.tsx index 70a2a6386..d7b19e932 100644 --- a/packages/nextjs/app/debug/_components/DebugContracts.tsx +++ b/packages/nextjs/app/debug/_components/DebugContracts.tsx @@ -35,8 +35,8 @@ export function DebugContracts() { - */} - - {/* Buy Tokens */} - {/*
+ {/* Buy Tokens */} + {/*
Buy tokens
{Number(tokensPerEth)} tokens per ETH
-
{ disableMultiplyBy1e18 />
- -
*/} - - {/* Sell Tokens */} - - {/*
-
Sell tokens
-
{Number(tokensPerEth)} tokens per ETH
-
- setTokensToSell(value as string)} - disabled={isApproved} - disableMultiplyBy1e18 - /> -
- -
+
*/} + + {!!yourTokenBalance && ( +
+
Transfer tokens
+
+ setToAddress(value)} + /> + setTokensToSend(value as string)} + disableMultiplyBy1e18 + /> +
-
*/} + )} + + {/* Sell Tokens */} + {/* {!!yourTokenBalance && ( +
+
Sell tokens
+
{Number(tokensPerEth)} tokens per ETH
+
+ setTokensToSell(value as string)} + disabled={isApproved} + disableMultiplyBy1e18 + /> +
+ +
+ +
+
+ )}*/}
); diff --git a/packages/nextjs/components/FaucetMenu.tsx b/packages/nextjs/components/FaucetMenu.tsx index afab5db88..7a1a59368 100644 --- a/packages/nextjs/components/FaucetMenu.tsx +++ b/packages/nextjs/components/FaucetMenu.tsx @@ -11,9 +11,6 @@ export default function FaucetMenu() { - - Goerli - Sepolia diff --git a/packages/nextjs/components/Footer.tsx b/packages/nextjs/components/Footer.tsx index 651e7fadd..31f75fea3 100644 --- a/packages/nextjs/components/Footer.tsx +++ b/packages/nextjs/components/Footer.tsx @@ -5,9 +5,6 @@ import { CurrencyDollarIcon, MagnifyingGlassIcon, } from "@heroicons/react/24/outline"; -import { HeartIcon } from "@heroicons/react/24/outline"; -import { SwitchTheme } from "~~/components/SwitchTheme"; -import { BuidlGuidlLogo } from "~~/components/assets/BuidlGuidlLogo"; import { useTargetNetwork } from "~~/hooks/scaffold-stark/useTargetNetwork"; import { useGlobalState } from "~~/services/store/store"; import { devnet } from "@starknet-react/chains"; @@ -25,14 +22,14 @@ export const Footer = () => { const isLocalNetwork = targetNetwork.id === devnet.id; return ( -
+
{nativeCurrencyPrice > 0 && (
-
- +
+ {nativeCurrencyPrice}
@@ -45,19 +42,14 @@ export const Footer = () => { target={"_blank"} rel={"noopener noreferrer"} passHref - className="btn btn-primary btn-sm font-normal gap-1 text-base-100 border-base-100 " + className="btn btn-sm font-normal gap-1 border border-[#32BAC4] shadow-none" > - + Block Explorer )}
-
@@ -74,32 +66,7 @@ export const Footer = () => {
· -
-

- Built with by -

- - - Q3 Labs - -

at

- - - BuidlGuidl - -
- · -
+
{ const pathname = usePathname(); + const { theme } = useTheme(); + const [isDark, setIsDark] = useState(false); + + useEffect(() => { + setIsDark(theme === "dark"); + }, [theme]); return ( <> - {menuLinks.map((link) => { - const isActive = pathname === link.href; - return ; + {menuLinks.map(({ label, href, icon }) => { + const isActive = pathname === href; + return ( +
  • + + {icon} + {label} + +
  • + ); })} ); @@ -67,13 +91,28 @@ export const Header = () => { burgerMenuRef, useCallback(() => setIsDrawerOpen(false), []), ); + const { targetNetwork } = useTargetNetwork(); + const isLocalNetwork = targetNetwork.id === devnet.id; + const { provider } = useProvider(); + const { address, status } = useAccount(); + const [isDeployed, setIsDeployed] = useState(true); - const toggleDrawer = () => { - setIsDrawerOpen((prevIsOpenState) => !prevIsOpenState); - }; + useEffect(() => { + if (status === "connected" && address) { + provider + .getContractVersion(address) + .then((v) => { + if (v) setIsDeployed(true); + }) + .catch((e) => { + console.log(e); + setIsDeployed(false); + }); + } + }, [status, address, provider]); return ( -
    +
    {isDrawerOpen && (
      { setIsDrawerOpen(false); }} @@ -119,9 +160,18 @@ export const Header = () => {
    -
    +
    + {status === "connected" && !isDeployed ? ( + + Wallet Not Deployed + + ) : null} - +
    ); diff --git a/packages/nextjs/components/ScaffoldStarkAppWithProviders.tsx b/packages/nextjs/components/ScaffoldStarkAppWithProviders.tsx index b3a25db2a..72bb7b179 100644 --- a/packages/nextjs/components/ScaffoldStarkAppWithProviders.tsx +++ b/packages/nextjs/components/ScaffoldStarkAppWithProviders.tsx @@ -1,62 +1,55 @@ "use client"; -import React from "react"; -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { useTheme } from "next-themes"; import { Toaster } from "react-hot-toast"; -import { - StarknetConfig, - argent, - braavos, - useInjectedConnectors, - starkscan, -} from "@starknet-react/core"; +import { StarknetConfig, starkscan } from "@starknet-react/core"; import { Header } from "~~/components/Header"; import { Footer } from "~~/components/Footer"; import { ProgressBar } from "~~/components/scaffold-stark/ProgressBar"; -import { appChains } from "~~/services/web3/connectors"; -import { BurnerConnector } from "~~/services/web3/stark-burner/BurnerConnector"; +import { appChains, connectors } from "~~/services/web3/connectors"; import provider from "~~/services/web3/provider"; import { useNativeCurrencyPrice } from "~~/hooks/scaffold-stark/useNativeCurrencyPrice"; -// import { Space_Grotesk } from "@next/font/google"; -// import scaffoldConfig from "~~/scaffold.config"; - -// const spaceGrotesk = Space_Grotesk({ -// subsets: ["latin"], -// }); const ScaffoldStarkApp = ({ children }: { children: React.ReactNode }) => { useNativeCurrencyPrice(); - + const { resolvedTheme } = useTheme(); + const isDarkMode = resolvedTheme === "dark"; return ( <> -
    +
    + {isDarkMode ? ( + <> +
    +
    + + ) : ( + <> +
    +
    + + )}
    -
    {children}
    +
    {children}
    ); }; + export const ScaffoldStarkAppWithProviders = ({ children, }: { children: React.ReactNode; }) => { - const { resolvedTheme } = useTheme(); - const isDarkMode = resolvedTheme === "dark"; const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); - const { connectors } = useInjectedConnectors({ - // Show these connectors if the user has no connector installed. - recommended: [argent(), braavos(), new BurnerConnector()], - order: "random", - }); + if (!mounted) return null; return ( { return (
    - {
    {getStarknetPFPIfExists(profile?.profilePicture) ? ( //eslint-disable-next-line @next/next/no-img-element @@ -97,7 +97,7 @@ export const AddressInfoDropdown = ({ ) : ( )} - + {isENS(displayName) ? displayName : profile?.name || @@ -107,7 +107,7 @@ export const AddressInfoDropdown = ({