Skip to content

Commit

Permalink
Merge pull request #42 from jdaly13/mySql
Browse files Browse the repository at this point in the history
My sql
  • Loading branch information
jdaly13 authored Sep 25, 2024
2 parents 7bd164a + 3d27085 commit 932edf4
Show file tree
Hide file tree
Showing 46 changed files with 1,676 additions and 1,016 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"strings": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"editor.tabSize": 2,
"css.customData": [".vscode/css_custom_data.json"],
Expand Down
102 changes: 7 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
# Remix Indie Stack
# YELLOWINGREEN -

![The Remix Indie Stack](https://repository-images.githubusercontent.com/465928257/a241fa49-bd4d-485a-a2a5-5cb8e4ee0abf)
![ORIGINALLY SCAFFOLDED FROM REMIX INDIE STACK](https://repository-images.githubusercontent.com/465928257/a241fa49-bd4d-485a-a2a5-5cb8e4ee0abf)

Learn more about [Remix Stacks](https://remix.run/stacks).

```
npx create-remix@latest --template remix-run/indie-stack
```
````
## What's in the stack
- [Fly app deployment](https://fly.io) with [Docker](https://www.docker.com/)
- Production-ready [SQLite Database](https://sqlite.org)
- Healthcheck endpoint for [Fly backups region fallbacks](https://fly.io/docs/reference/configuration/#services-http_checks)
- [GitHub Actions](https://github.com/features/actions) for deploy on merge to production and staging environments
- Email/Password Authentication with [cookie-based sessions](https://remix.run/docs/en/v1/api/remix#createcookiesessionstorage)
- Deployment via Google Cloud Build and Run
- Production-ready MySQL database
- Database ORM with [Prisma](https://prisma.io)
- Styling with [Tailwind](https://tailwindcss.com/)
- End-to-end testing with [Cypress](https://cypress.io)
- Local third party request mocking with [MSW](https://mswjs.io)
- Unit testing with [Vitest](https://vitest.dev) and [Testing Library](https://testing-library.com)
- Code formatting with [Prettier](https://prettier.io)
- Linting with [ESLint](https://eslint.org)
Expand All @@ -32,20 +22,9 @@ Not a fan of bits of the stack? Fork it, change it, and use `npx create-remix --
- This step only applies if you've opted out of having the CLI install dependencies for you:
```sh
npx remix init
```

- Initial setup: _If you just generated this project, this step has been done for you._

```sh
npm run setup
```

- Start dev server:

```sh
npm i
npm run dev
```
````

This starts your app in development mode, rebuilding assets on file changes.

Expand All @@ -57,79 +36,12 @@ NEEDS TO BE UPDATED!!!!!!

## Deployment

This Remix Stack comes with two GitHub Actions that handle automatically deploying your app to production and staging environments.

Prior to your first deployment, you'll need to do a few things:

- [Install Fly](https://fly.io/docs/getting-started/installing-flyctl/)

- Sign up and log in to Fly

```sh
fly auth signup
```

> **Note:** If you have more than one Fly account, ensure that you are signed into the same account in the Fly CLI as you are in the browser. In your terminal, run `fly auth whoami` and ensure the email matches the Fly account signed into the browser.
- Create two apps on Fly, one for staging and one for production:

```sh
fly apps create trivia-new-76c5
fly apps create trivia-new-76c5-staging
```

> **Note:** Make sure this name matches the `app` set in your `fly.toml` file. Otherwise, you will not be able to deploy.
- Initialize Git.

```sh
git init
```

- Create a new [GitHub Repository](https://repo.new), and then add it as the remote for your project. **Do not push your app yet!**

```sh
git remote add origin <ORIGIN_URL>
```

- Add a `FLY_API_TOKEN` to your GitHub repo. To do this, go to your user settings on Fly and create a new [token](https://web.fly.io/user/personal_access_tokens/new), then add it to [your repo secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) with the name `FLY_API_TOKEN`.

- Add a `SESSION_SECRET` to your fly app secrets, to do this you can run the following commands:

```sh
fly secrets set SESSION_SECRET=$(openssl rand -hex 32) --app trivia-new-76c5
fly secrets set SESSION_SECRET=$(openssl rand -hex 32) --app trivia-new-76c5-staging
```

If you don't have openssl installed, you can also use [1password](https://1password.com/password-generator/) to generate a random secret, just replace `$(openssl rand -hex 32)` with the generated secret.

- Create a persistent volume for the sqlite database for both your staging and production environments. Run the following:

```sh
fly volumes create data --size 1 --app trivia-new-76c5
fly volumes create data --size 1 --app trivia-new-76c5-staging
```

Now that everything is set up you can commit and push your changes to your repo. Every commit to your `main` branch will trigger a deployment to your production environment, and every commit to your `dev` branch will trigger a deployment to your staging environment.

### Connecting to your database

The sqlite database lives at `/data/sqlite.db` in your deployed application. You can connect to the live database by running `fly ssh console -C database-cli`.

### Getting Help with Deployment

If you run into any issues deploying to Fly, make sure you've followed all of the steps above and if you have, then post as many details about your deployment (including your app name) to [the Fly support community](https://community.fly.io). They're normally pretty responsive over there and hopefully can help resolve any of your deployment issues and questions.

## GitHub Actions

We use GitHub Actions for continuous integration and deployment. Anything that gets into the `main` branch will be deployed to production after running tests/build/etc. Anything in the `dev` branch will be deployed to staging.

## Testing

### Vitest

For lower level tests of utilities and individual components, we use `vitest`. We have DOM-specific assertion helpers via [`@testing-library/jest-dom`](https://testing-library.com/jest-dom).

### Linting

This project uses ESLint for linting. That is configured in `.eslintrc.js`.
Expand Down
16 changes: 11 additions & 5 deletions app/components/BalanceInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function BalanceInfo({
}) {
const [poolButton, setPoolButton] = useState(false);
const [prizeAmount, setPrizeAmount] = useState(null);
const { contracts, game } = useContext(ContractContext);
const { contracts, game, network } = useContext(ContractContext);
console.log({ game });

const { data } = useContractRead({
Expand Down Expand Up @@ -59,13 +59,11 @@ export default function BalanceInfo({
useEffect(() => {
if (activePlayer?.data && utils.formatEther(activePlayer.data) < 1) {
setPoolButton(true);
setDeposit(false);
}
if (activePlayer?.data && utils.formatEther(activePlayer.data) >= 1) {
setDeposit(true);
}
if (activePlayer?.data && utils.formatEther(activePlayer.data) < 1) {
setDeposit(false);
}
}, [activePlayer, deposit, setDeposit]);

// TODO REFACTOR
Expand All @@ -90,7 +88,15 @@ export default function BalanceInfo({
)}
{prizeAmount && game?.current && (
<p className="text-center font-bold lg:text-left">
Prize amount: {prizeAmount} TRIVIA Tokens
Prize includes:{" "}
{game.nativePayoutAmount && (
<span>
{network !== "polygon"
? `${game.nativePayoutAmount} ${network} Ethereum,`
: `${game.nativePayoutAmount} Polygon Matic, `}
</span>
)}{" "}
{prizeAmount} TRIVIA Tokens, 1 Trophy NFT
</p>
)}
{game?.user?.length > 3 && game?.current && (
Expand Down
4 changes: 1 addition & 3 deletions app/components/Wrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ export default function Wrapper({ children }) {
const { chain, chains } = useNetwork();
const [tokenData, setTokenData] = useState(null);
const [deposit, setDeposit] = useState(false);
if (!window.Buffer) {
window.Buffer = Buffer;
}

return (
<div className="container mx-auto max-w-screen-lg">
<Header
Expand Down
39 changes: 27 additions & 12 deletions app/models/game.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export async function getSpecificGame(id) {
include: {
questions: true,
user: true,
winner: true,
},
});
}
Expand Down Expand Up @@ -186,7 +187,10 @@ export async function checkWinner(userId, game) {
},
});
if (gameWithQuestions.questions.length === user.submissions.length) {
return true;
return {
nativePayout: gameWithQuestions?.nativePayoutAmount,
confirmed: true,
};
}
return false;
}
Expand All @@ -199,16 +203,25 @@ export async function declareWinner(game, userId) {
});

console.log(user);
let winnerUpdate;

try {
winnerUpdate = await prisma.game.update({
where: {
id: game,
winnerId: null,
},
data: {
winnerId: user.address,
current: false,
},
});
} catch (error) {
return {
winnerUpdate: null,
};
}

const winnerUpdate = await prisma.game.update({
where: {
id: game,
},
data: {
winnerId: user.address,
current: false,
},
});
try {
await sendEmail({ gameId: game, winnerId: user.address });
} catch (error) {
Expand Down Expand Up @@ -243,7 +256,8 @@ export async function checkAndDeclareWinner(id, game, submission) {
return json(winnerUpdate);
} else {
return json({
error: "questions and submissions matched up but not declared winner",
error:
"questions and submissions matched up but winner already declared",
});
}
} else {
Expand All @@ -257,12 +271,13 @@ export async function checkAndDeclareWinner(id, game, submission) {
}
}

export async function createGame(game, makeActive) {
export async function createGame(game, makeActive, nativeAmount) {
const active = makeActive === "true" ? true : false;
return prisma.game.create({
data: {
name: game,
current: active,
nativePayoutAmount: nativeAmount,
},
});
}
Expand Down
16 changes: 16 additions & 0 deletions app/models/mixpanel.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getClientIPAddress } from "remix-utils";
const Mixpanel = require("mixpanel");
const mixPanelAccount = process.env.MIXPANEL;
export async function mixPanelPageView(request, obj = {}) {
console.log({ getClientIPAddress });
let ipAddress = getClientIPAddress(request);
console.log({ ipAddress });
if (process.env.NODE_ENV === "production") {
const mixpanel = Mixpanel.init(mixPanelAccount, { track_pageview: true });
mixpanel.track("page_viewed", {
game: obj.currentGame || "no current game",
page: request.url,
ip: ipAddress,
});
}
}
35 changes: 31 additions & 4 deletions app/models/payout.server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { ethers } = require("ethers");
const { ethers, utils } = require("ethers");
require("dotenv").config();

let provider;
Expand Down Expand Up @@ -48,18 +48,45 @@ export async function makePayment(address, gameId) {
gasLimit: gasLimit,
});

const receipt = await tx.wait();
console.log("receipt", receipt);
console.log("withdrawtoken", tx);

// const receipt = await tx.wait();
// console.log("receipt", receipt);

return {
success: true,
receipt,
tx,
};
} catch (e) {
console.log("error", e);
return {
success: false,
tx: "error",
e,
};
}
}

export async function makeNativePayment(address, gameId, payoutAmount) {
try {
const gas = await provider.getGasPrice();
const gasLimit = 2200000;
const txParameters = {
to: address,
value: utils.parseEther(payoutAmount),
gasPrice: gas,
gasLimit,
};
const tx = await signer.sendTransaction(txParameters);
console.log({ tx });
// https://github.com/ethers-io/ethers.js/issues/444
// need to manually set this as transactions
await new Promise((resolve) => setTimeout(resolve, 1500));
// const nativetxwait = await tx.wait();
// console.log({ nativetxwait });
return tx;
} catch (e) {
console.log({ e });
return e;
}
}
24 changes: 24 additions & 0 deletions app/models/winner.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { prisma } from "~/db.server";
require("dotenv").config();
export async function updateTxInGame(receipt, nativePayoutTx, gameId, address) {
return prisma.winner.create({
data: {
triviaTransaction: receipt?.hash || "",
nativeTransaction: nativePayoutTx?.hash || "",
gameId,
network: process.env.NETWORK,
id: address,
},
});
}

export async function updateWinnerWithNftTransaction(winnerAddress, nftTx) {
return prisma.winner.update({
where: {
id: winnerAddress,
},
data: {
nftTransaction: nftTx,
},
});
}
Loading

0 comments on commit 932edf4

Please sign in to comment.