mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
Reformat all existing code
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { ApolloProvider } from '@apollo/react-hooks';
|
||||
import { CssBaseline } from '@material-ui/core';
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
|
||||
import { createApolloClient } from './apollo';
|
||||
|
||||
@@ -16,10 +16,10 @@ function App() {
|
||||
return (
|
||||
<ApolloProvider client={apolloClient}>
|
||||
<Web3ContextProvider>
|
||||
<CssBaseline/>
|
||||
<CssBaseline />
|
||||
<Router>
|
||||
<Header/>
|
||||
<Routes/>
|
||||
<Header />
|
||||
<Routes />
|
||||
</Router>
|
||||
</Web3ContextProvider>
|
||||
</ApolloProvider>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Switch, Route, Redirect } from "react-router-dom";
|
||||
import { Switch, Route, Redirect } from 'react-router-dom';
|
||||
|
||||
import { Home } from './containers/Home';
|
||||
import { Player } from './containers/Player';
|
||||
@@ -13,7 +13,7 @@ export default function Routes() {
|
||||
<Route path="/player/:playerId">
|
||||
<Player />
|
||||
</Route>
|
||||
<Redirect to="/"/>
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,12 +29,13 @@ export async function login(client, token, ethAddress) {
|
||||
authToken: token,
|
||||
},
|
||||
});
|
||||
return client.query({
|
||||
query: queries.get_MyAccount,
|
||||
variables: { eth_address: ethAddress }
|
||||
})
|
||||
.then(async res => {
|
||||
if(res.data.Account.length === 0) {
|
||||
return client
|
||||
.query({
|
||||
query: queries.get_MyAccount,
|
||||
variables: { eth_address: ethAddress },
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (res.data.Account.length === 0) {
|
||||
throw new Error('Impossible to fetch player, not found.');
|
||||
}
|
||||
client.writeData({
|
||||
@@ -45,7 +46,7 @@ export async function login(client, token, ethAddress) {
|
||||
});
|
||||
setTokenInStore(token);
|
||||
})
|
||||
.catch(async error => {
|
||||
.catch(async (error) => {
|
||||
logout(client);
|
||||
throw error;
|
||||
});
|
||||
|
||||
@@ -17,22 +17,27 @@ export function createApolloClient() {
|
||||
async function authMiddleware(operation) {
|
||||
const queryLogin = client.readQuery({ query: localQueries.get_authState });
|
||||
|
||||
if(queryLogin.authToken) {
|
||||
if (queryLogin.authToken) {
|
||||
operation.setContext({
|
||||
headers: {
|
||||
'authorization': `Bearer ${queryLogin.authToken}`,
|
||||
authorization: `Bearer ${queryLogin.authToken}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onErrorMiddleware({ networkError = {}, graphQLErrors = {}, operation }) {
|
||||
if (networkError.statusCode === 401 || graphQLErrors[0]?.extensions?.code === 'invalid-jwt') {
|
||||
function onErrorMiddleware({
|
||||
networkError = {},
|
||||
graphQLErrors = {},
|
||||
operation,
|
||||
}) {
|
||||
if (
|
||||
networkError.statusCode === 401 ||
|
||||
graphQLErrors[0]?.extensions?.code === 'invalid-jwt'
|
||||
) {
|
||||
console.error('Authentication error, login out');
|
||||
logout(client);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.error('GraphQL request error:', networkError);
|
||||
}
|
||||
}
|
||||
@@ -48,9 +53,8 @@ export function createApolloClient() {
|
||||
});
|
||||
|
||||
client.onResetStore(() => {
|
||||
client.writeData({ data: defaultClientState })
|
||||
client.writeData({ data: defaultClientState });
|
||||
});
|
||||
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { createApolloClient } from './client';
|
||||
import * as localQueries from './localQueries';
|
||||
|
||||
export {
|
||||
localQueries, createApolloClient,
|
||||
};
|
||||
export { localQueries, createApolloClient };
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { gql } from 'apollo-boost';
|
||||
|
||||
export const get_authState = gql`
|
||||
query AuthState {
|
||||
authState @client
|
||||
authToken @client
|
||||
playerId @client
|
||||
}
|
||||
query AuthState {
|
||||
authState @client
|
||||
authToken @client
|
||||
playerId @client
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -3,13 +3,15 @@ import { Link } from 'react-router-dom';
|
||||
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
import {Login} from "../containers/Login";
|
||||
import { Login } from '../containers/Login';
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<Box>
|
||||
<Link to={`/`}><button>Home</button></Link>
|
||||
<Login/>
|
||||
<Link to={`/`}>
|
||||
<button>Home</button>
|
||||
</Link>
|
||||
<Login />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import {useMutation} from "@apollo/react-hooks";
|
||||
import { useMutation } from '@apollo/react-hooks';
|
||||
|
||||
import ThreeBox from '3box';
|
||||
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
import {useMyPlayer} from "../graphql/hooks";
|
||||
import {getPlayerETHAddress} from "../utils/players";
|
||||
import { useMyPlayer } from '../graphql/hooks';
|
||||
import { getPlayerETHAddress } from '../utils/players';
|
||||
import mutations from '../graphql/mutations';
|
||||
|
||||
function getProfilePicture(boxProfile: any) {
|
||||
const imageHash = boxProfile && boxProfile.image && boxProfile.image[0] && boxProfile.image[0].contentUrl && boxProfile.image[0].contentUrl['/'];
|
||||
if(imageHash) {
|
||||
const imageHash =
|
||||
boxProfile &&
|
||||
boxProfile.image &&
|
||||
boxProfile.image[0] &&
|
||||
boxProfile.image[0].contentUrl &&
|
||||
boxProfile.image[0].contentUrl['/'];
|
||||
if (imageHash) {
|
||||
return `https://ipfs.infura.io/ipfs/${imageHash}`;
|
||||
} else {
|
||||
return 'https://i.imgur.com/RXJO8FD.png';
|
||||
@@ -30,31 +35,30 @@ export default function PlayerDetails({ player }: { player: any }) {
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
|
||||
const boxProfile = await ThreeBox.getProfile(ethAddress);
|
||||
setBoxProfile(boxProfile);
|
||||
|
||||
})();
|
||||
}, [ethAddress]);
|
||||
|
||||
const goToEditBoxProfile = useCallback(() => {
|
||||
window.open(`https://3box.io/${ethAddress}/edit`)
|
||||
window.open(`https://3box.io/${ethAddress}/edit`);
|
||||
}, [ethAddress]);
|
||||
|
||||
const editUserName = useCallback(() => {
|
||||
// TODO Apollo does not updates caches as it expects that the mutation returns an object with id, but hasura returns { returning: [{id}] }
|
||||
updateUsername({
|
||||
variables: {
|
||||
username: usernameInput
|
||||
}
|
||||
}).then(res =>
|
||||
console.log('updated username', res.data)
|
||||
);
|
||||
username: usernameInput,
|
||||
},
|
||||
}).then((res) => console.log('updated username', res.data));
|
||||
}, [usernameInput, updateUsername]);
|
||||
|
||||
const updateAccounts = useCallback(() => {
|
||||
updateBoxProfiles().then(res =>
|
||||
console.log('updated verified profiles', res.data.updateBoxProfile.updatedProfiles)
|
||||
updateBoxProfiles().then((res) =>
|
||||
console.log(
|
||||
'updated verified profiles',
|
||||
res.data.updateBoxProfile.updatedProfiles,
|
||||
),
|
||||
);
|
||||
}, [updateBoxProfiles]);
|
||||
|
||||
@@ -63,28 +67,41 @@ export default function PlayerDetails({ player }: { player: any }) {
|
||||
<h3>{player.username}</h3>
|
||||
<h4>{player.id}</h4>
|
||||
{isMyPlayer && <button onClick={goToEditBoxProfile}>Edit profile</button>}
|
||||
{isMyPlayer && <div>
|
||||
<input value={usernameInput} onChange={e => setUsernameInput(e.target.value)} />
|
||||
<button onClick={editUserName}>Change username</button>
|
||||
</div>}
|
||||
{boxProfile ?
|
||||
{isMyPlayer && (
|
||||
<div>
|
||||
<p><b>Name:</b> {boxProfile.name}</p>
|
||||
<p><b>Description:</b> {boxProfile.description}</p>
|
||||
<img src={getProfilePicture(boxProfile)} width={100} alt="profile"/>
|
||||
<input
|
||||
value={usernameInput}
|
||||
onChange={(e) => setUsernameInput(e.target.value)}
|
||||
/>
|
||||
<button onClick={editUserName}>Change username</button>
|
||||
</div>
|
||||
:
|
||||
)}
|
||||
{boxProfile ? (
|
||||
<div>
|
||||
<p>
|
||||
<b>Name:</b> {boxProfile.name}
|
||||
</p>
|
||||
<p>
|
||||
<b>Description:</b> {boxProfile.description}
|
||||
</p>
|
||||
<img src={getProfilePicture(boxProfile)} width={100} alt="profile" />
|
||||
</div>
|
||||
) : (
|
||||
<p>Loading box profile</p>
|
||||
}
|
||||
)}
|
||||
<div>
|
||||
<h4>External accounts</h4>
|
||||
<ul>
|
||||
{player.Accounts.map((account: any) =>
|
||||
<li key={account.type}><b>{account.type}</b>: {account.identifier}</li>
|
||||
)}
|
||||
{player.Accounts.map((account: any) => (
|
||||
<li key={account.type}>
|
||||
<b>{account.type}</b>: {account.identifier}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{isMyPlayer && <button onClick={updateAccounts}>Update accounts</button>}
|
||||
{isMyPlayer && (
|
||||
<button onClick={updateAccounts}>Update accounts</button>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ export default function PlayerListItem({ player }: { player: any }) {
|
||||
return (
|
||||
<Box>
|
||||
{player.username}
|
||||
<Link to={`/player/${player.id}`}><button>View player</button></Link>
|
||||
<Link to={`/player/${player.id}`}>
|
||||
<button>View player</button>
|
||||
</Link>
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export default {
|
||||
graphqlURL: process.env.REACT_APP_GRAPHQL_URL || 'http://localhost:8080/v1/graphql',
|
||||
infuraId: process.env.REACT_APP_INFURA_ID || '781d8466252d47508e177b8637b1c2fd',
|
||||
graphqlURL:
|
||||
process.env.REACT_APP_GRAPHQL_URL || 'http://localhost:8080/v1/graphql',
|
||||
infuraId:
|
||||
process.env.REACT_APP_INFURA_ID || '781d8466252d47508e177b8637b1c2fd',
|
||||
};
|
||||
|
||||
@@ -7,8 +7,7 @@ import PlayerList from './PlayerList';
|
||||
export const Home: React.FC = () => {
|
||||
return (
|
||||
<Box>
|
||||
<PlayerList/>
|
||||
<PlayerList />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React, {useContext, useCallback} from 'react';
|
||||
import React, { useContext, useCallback } from 'react';
|
||||
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
import { Web3Context } from '../contexts/Web3';
|
||||
import {localQueries} from "../apollo";
|
||||
import { localQueries } from '../apollo';
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import {Link} from "react-router-dom";
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const Login: React.FC = () => {
|
||||
const { data, loading } = useQuery(localQueries.get_authState);
|
||||
@@ -16,18 +16,16 @@ export const Login: React.FC = () => {
|
||||
connectWeb3().catch(console.error);
|
||||
}, [connectWeb3]);
|
||||
|
||||
if(loading || data?.authState === 'loading') {
|
||||
return (
|
||||
<Box>
|
||||
Connecting...
|
||||
</Box>
|
||||
);
|
||||
} else if(data?.authState === 'logged') {
|
||||
if (loading || data?.authState === 'loading') {
|
||||
return <Box>Connecting...</Box>;
|
||||
} else if (data?.authState === 'logged') {
|
||||
const { playerId } = data;
|
||||
return (
|
||||
<Box>
|
||||
Connected
|
||||
<Link to={`/player/${playerId}`}><button>View my player</button></Link>
|
||||
<Link to={`/player/${playerId}`}>
|
||||
<button>View my player</button>
|
||||
</Link>
|
||||
<button onClick={disconnect}>Logout</button>
|
||||
</Box>
|
||||
);
|
||||
@@ -36,6 +34,6 @@ export const Login: React.FC = () => {
|
||||
<Box>
|
||||
<button onClick={connect}>Connect</button>
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import React from 'react';
|
||||
import {useQuery} from "@apollo/react-hooks";
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
import PlayerDetails from '../components/PlayerDetails';
|
||||
|
||||
import queries from "../graphql/queries";
|
||||
import queries from '../graphql/queries';
|
||||
|
||||
export const Player: React.FC = () => {
|
||||
const { playerId } = useParams();
|
||||
const { data, loading, error } = useQuery(queries.get_Player, {
|
||||
variables: {
|
||||
player_id: playerId,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if(error) {
|
||||
return <div>error</div>
|
||||
if (error) {
|
||||
return <div>error</div>;
|
||||
}
|
||||
if(loading) {
|
||||
return <div>loading</div>
|
||||
if (loading) {
|
||||
return <div>loading</div>;
|
||||
}
|
||||
|
||||
const myPlayer = data.Player[0];
|
||||
@@ -28,6 +28,5 @@ export const Player: React.FC = () => {
|
||||
<h4>Player</h4>
|
||||
<PlayerDetails player={myPlayer} />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
import {useQuery} from '@apollo/react-hooks';
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
|
||||
import queries from '../graphql/queries';
|
||||
|
||||
@@ -11,19 +11,19 @@ import PlayerListItem from '../components/PlayerListItem';
|
||||
export default function PlayerList() {
|
||||
const { data, loading, error } = useQuery(queries.get_Player);
|
||||
|
||||
if(error) {
|
||||
return <div>error: {error.message}</div>
|
||||
if (error) {
|
||||
return <div>error: {error.message}</div>;
|
||||
}
|
||||
if(loading) {
|
||||
return <div>loading</div>
|
||||
if (loading) {
|
||||
return <div>loading</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<h4>Player list</h4>
|
||||
{data.Player.map((player: any) =>
|
||||
{data.Player.map((player: any) => (
|
||||
<PlayerListItem key={player.id} player={player} />
|
||||
)}
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import React, {createContext, useCallback, useEffect, useState} from 'react';
|
||||
import React, { createContext, useCallback, useEffect, useState } from 'react';
|
||||
import WalletConnectProvider from '@walletconnect/web3-provider';
|
||||
import Web3Modal from 'web3modal';
|
||||
import Web3 from 'web3';
|
||||
import { ethers } from 'ethers';
|
||||
import { AsyncSendable, Web3Provider } from 'ethers/providers';
|
||||
import {useApolloClient} from '@apollo/react-hooks';
|
||||
import { useApolloClient } from '@apollo/react-hooks';
|
||||
|
||||
import config from '../config';
|
||||
import { did } from '@metafam/utils';
|
||||
import {loginLoading, login, logout, getTokenFromStore} from '../apollo/auth';
|
||||
import { loginLoading, login, logout, getTokenFromStore } from '../apollo/auth';
|
||||
|
||||
type Web3ContextType = {
|
||||
ethersProvider: Web3Provider | null,
|
||||
ethersProvider: Web3Provider | null;
|
||||
connectWeb3: () => Promise<void>;
|
||||
disconnect: () => void,
|
||||
}
|
||||
disconnect: () => void;
|
||||
};
|
||||
|
||||
export const Web3Context = createContext<Web3ContextType>({
|
||||
ethersProvider: null,
|
||||
@@ -27,8 +27,8 @@ const providerOptions = {
|
||||
package: WalletConnectProvider,
|
||||
options: {
|
||||
infuraId: config.infuraId,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const web3Modal = new Web3Modal({
|
||||
@@ -37,41 +37,42 @@ const web3Modal = new Web3Modal({
|
||||
providerOptions,
|
||||
});
|
||||
|
||||
|
||||
const Web3ContextProvider: React.FC = props => {
|
||||
|
||||
const Web3ContextProvider: React.FC = (props) => {
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const [ethersProvider, setEthersProvider] = useState<Web3Provider | null>(null);
|
||||
const [ethersProvider, setEthersProvider] = useState<Web3Provider | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
const connectDID = useCallback(async (ethersProvider: Web3Provider) => {
|
||||
const connectDID = useCallback(
|
||||
async (ethersProvider: Web3Provider) => {
|
||||
let token = getTokenFromStore();
|
||||
|
||||
let token = getTokenFromStore();
|
||||
if (!token) {
|
||||
token = await did.createToken(ethersProvider);
|
||||
}
|
||||
|
||||
if(!token) {
|
||||
token = await did.createToken(ethersProvider);
|
||||
}
|
||||
|
||||
const signer = ethersProvider.getSigner();
|
||||
const address = await signer.getAddress();
|
||||
await login(apolloClient, token, address);
|
||||
|
||||
}, [apolloClient]);
|
||||
const signer = ethersProvider.getSigner();
|
||||
const address = await signer.getAddress();
|
||||
await login(apolloClient, token, address);
|
||||
},
|
||||
[apolloClient],
|
||||
);
|
||||
|
||||
const connectWeb3 = useCallback(async () => {
|
||||
try {
|
||||
|
||||
loginLoading(apolloClient);
|
||||
|
||||
const provider = await web3Modal.connect();
|
||||
|
||||
const web3Provider = new Web3(provider);
|
||||
const ethersProvider = new ethers.providers.Web3Provider(web3Provider.currentProvider as AsyncSendable);
|
||||
const ethersProvider = new ethers.providers.Web3Provider(
|
||||
web3Provider.currentProvider as AsyncSendable,
|
||||
);
|
||||
await connectDID(ethersProvider);
|
||||
|
||||
setEthersProvider(ethersProvider);
|
||||
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
loginLoading(apolloClient, false);
|
||||
throw e;
|
||||
}
|
||||
@@ -83,7 +84,7 @@ const Web3ContextProvider: React.FC = props => {
|
||||
}, [apolloClient]);
|
||||
|
||||
useEffect(() => {
|
||||
if(web3Modal.cachedProvider) {
|
||||
if (web3Modal.cachedProvider) {
|
||||
connectWeb3().catch(console.error);
|
||||
}
|
||||
}, [connectWeb3]);
|
||||
|
||||
@@ -12,7 +12,7 @@ export function useMyPlayer() {
|
||||
const playerId = authStateQuery.data?.playerId;
|
||||
|
||||
useEffect(() => {
|
||||
if(playerId) {
|
||||
if (playerId) {
|
||||
getMyPlayer({
|
||||
variables: {
|
||||
player_id: playerId,
|
||||
|
||||
@@ -3,29 +3,24 @@ import gql from 'graphql-tag';
|
||||
const mutations: any = {};
|
||||
|
||||
mutations.UpdateBoxProfiles = gql`
|
||||
mutation UpdateBoxProfiles {
|
||||
updateBoxProfile {
|
||||
success
|
||||
updatedProfiles
|
||||
mutation UpdateBoxProfiles {
|
||||
updateBoxProfile {
|
||||
success
|
||||
updatedProfiles
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
mutations.UpdateUsername = gql`
|
||||
mutation UpdateUsername($username: String!) {
|
||||
update_Player(
|
||||
where: {},
|
||||
_set: {
|
||||
username: $username
|
||||
}
|
||||
) {
|
||||
affected_rows
|
||||
returning {
|
||||
id
|
||||
username
|
||||
mutation UpdateUsername($username: String!) {
|
||||
update_Player(where: {}, _set: { username: $username }) {
|
||||
affected_rows
|
||||
returning {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default mutations;
|
||||
|
||||
@@ -5,36 +5,31 @@ import fragments from './fragments';
|
||||
const queries: any = {};
|
||||
|
||||
queries.get_Player = gql`
|
||||
query GetPlayer($player_id: uuid) {
|
||||
Player(
|
||||
where: { id: { _eq: $player_id } }
|
||||
) {
|
||||
...PlayerFragment
|
||||
Accounts {
|
||||
...AccountFragment
|
||||
query GetPlayer($player_id: uuid) {
|
||||
Player(where: { id: { _eq: $player_id } }) {
|
||||
...PlayerFragment
|
||||
Accounts {
|
||||
...AccountFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${fragments.PlayerFragment}
|
||||
${fragments.AccountFragment}
|
||||
${fragments.PlayerFragment}
|
||||
${fragments.AccountFragment}
|
||||
`;
|
||||
|
||||
queries.get_MyAccount = gql`
|
||||
query GetMyAccount($eth_address: String) {
|
||||
Account(
|
||||
where: {
|
||||
identifier: { _eq: $eth_address },
|
||||
type: { _eq: "ETHEREUM" }
|
||||
}
|
||||
) {
|
||||
...AccountFragment
|
||||
Player {
|
||||
...PlayerFragment
|
||||
query GetMyAccount($eth_address: String) {
|
||||
Account(
|
||||
where: { identifier: { _eq: $eth_address }, type: { _eq: "ETHEREUM" } }
|
||||
) {
|
||||
...AccountFragment
|
||||
Player {
|
||||
...PlayerFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${fragments.PlayerFragment}
|
||||
${fragments.AccountFragment}
|
||||
${fragments.PlayerFragment}
|
||||
${fragments.AccountFragment}
|
||||
`;
|
||||
|
||||
export default queries;
|
||||
|
||||
@@ -3,9 +3,6 @@ import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('root')
|
||||
);
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
|
||||
serviceWorker.unregister();
|
||||
|
||||
@@ -16,8 +16,8 @@ const isLocalhost = Boolean(
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
|
||||
),
|
||||
);
|
||||
|
||||
type Config = {
|
||||
@@ -30,7 +30,7 @@ export function register(config?: Config) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(
|
||||
process.env.PUBLIC_URL || '',
|
||||
window.location.href
|
||||
window.location.href,
|
||||
);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
@@ -51,7 +51,7 @@ export function register(config?: Config) {
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA',
|
||||
);
|
||||
});
|
||||
} else {
|
||||
@@ -65,7 +65,7 @@ export function register(config?: Config) {
|
||||
function registerValidSW(swUrl: string, config?: Config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
@@ -79,7 +79,7 @@ function registerValidSW(swUrl: string, config?: Config) {
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.',
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
@@ -101,7 +101,7 @@ function registerValidSW(swUrl: string, config?: Config) {
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
@@ -109,9 +109,9 @@ function registerValidSW(swUrl: string, config?: Config) {
|
||||
function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' }
|
||||
headers: { 'Service-Worker': 'script' },
|
||||
})
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
@@ -119,7 +119,7 @@ function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
@@ -131,7 +131,7 @@ function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
'No internet connection found. App is running in offline mode.',
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -139,10 +139,10 @@ function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then(registration => {
|
||||
.then((registration) => {
|
||||
registration.unregister();
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
console.error(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export function getPlayerETHAddress(player: any) {
|
||||
return player.Accounts.find((a: any) => a.type === "ETHEREUM").identifier;
|
||||
return player.Accounts.find((a: any) => a.type === 'ETHEREUM').identifier;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
@@ -18,11 +14,7 @@
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react",
|
||||
"typeRoots": [
|
||||
"../@types", "../../node_modules/@types"]
|
||||
"typeRoots": ["../@types", "../../node_modules/@types"]
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"./@types"
|
||||
]
|
||||
"include": ["src", "./@types"]
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
type Maybe<T> = T | null
|
||||
|
||||
|
||||
|
||||
|
||||
type Maybe<T> = T | null;
|
||||
|
||||
type UpdateBoxProfileResponse = {
|
||||
success: boolean
|
||||
updatedProfiles: Array<string>
|
||||
}
|
||||
success: boolean;
|
||||
updatedProfiles: Array<string>;
|
||||
};
|
||||
|
||||
type Mutation = {
|
||||
updateBoxProfile?: Maybe<UpdateBoxProfileResponse>
|
||||
}
|
||||
updateBoxProfile?: Maybe<UpdateBoxProfileResponse>;
|
||||
};
|
||||
|
||||
type updateBoxProfileArgs = {
|
||||
|
||||
}
|
||||
type updateBoxProfileArgs = {};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Request, Response } from 'express';
|
||||
import {hasuraQuery} from "../../../lib/hasuraHelpers";
|
||||
import {getPlayerETHAddress} from "../../../lib/playerHelpers";
|
||||
import { hasuraQuery } from '../../../lib/hasuraHelpers';
|
||||
import { getPlayerETHAddress } from '../../../lib/playerHelpers';
|
||||
import Box from '3box';
|
||||
|
||||
const getPlayerQuery = `
|
||||
@@ -34,12 +34,11 @@ mutation upsert_Account($objects: [Account_insert_input!]!) {
|
||||
`;
|
||||
|
||||
const handler = async (req: Request, res: Response) => {
|
||||
|
||||
const { session_variables } = req.body;
|
||||
const role = session_variables['x-hasura-role'];
|
||||
const playerId = session_variables['x-hasura-user-id'];
|
||||
|
||||
if(role !== 'player') {
|
||||
if (role !== 'player') {
|
||||
throw new Error('expected role player');
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ const handler = async (req: Request, res: Response) => {
|
||||
});
|
||||
|
||||
const player = data.Player[0];
|
||||
if(!player) {
|
||||
if (!player) {
|
||||
throw new Error('unknown-player');
|
||||
}
|
||||
|
||||
@@ -58,13 +57,15 @@ const handler = async (req: Request, res: Response) => {
|
||||
const result = await updateVerifiedProfiles(playerId, verifiedProfile);
|
||||
|
||||
res.json(result);
|
||||
|
||||
};
|
||||
|
||||
async function updateVerifiedProfiles(playerId: string, verifiedProfiles: any): Promise<UpdateBoxProfileResponse> {
|
||||
async function updateVerifiedProfiles(
|
||||
playerId: string,
|
||||
verifiedProfiles: any,
|
||||
): Promise<UpdateBoxProfileResponse> {
|
||||
const updatedProfiles: string[] = [];
|
||||
|
||||
if(verifiedProfiles.github) {
|
||||
if (verifiedProfiles.github) {
|
||||
const result = await hasuraQuery(upsertAccount, {
|
||||
objects: [
|
||||
{
|
||||
@@ -72,16 +73,16 @@ async function updateVerifiedProfiles(playerId: string, verifiedProfiles: any):
|
||||
type: 'GITHUB',
|
||||
identifier: verifiedProfiles.github.username,
|
||||
linkToProof: verifiedProfiles.github.proof,
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
if(result.affected_rows === 0) {
|
||||
if (result.affected_rows === 0) {
|
||||
throw new Error('Error while upserting github profile');
|
||||
}
|
||||
updatedProfiles.push('github');
|
||||
}
|
||||
|
||||
if(verifiedProfiles.twitter) {
|
||||
if (verifiedProfiles.twitter) {
|
||||
const result = await hasuraQuery(upsertAccount, {
|
||||
objects: [
|
||||
{
|
||||
@@ -89,10 +90,10 @@ async function updateVerifiedProfiles(playerId: string, verifiedProfiles: any):
|
||||
type: 'TWITTER',
|
||||
identifier: verifiedProfiles.twitter.username,
|
||||
linkToProof: verifiedProfiles.twitter.proof,
|
||||
}
|
||||
},
|
||||
],
|
||||
});
|
||||
if(result.affected_rows === 0) {
|
||||
if (result.affected_rows === 0) {
|
||||
throw new Error('Error while upserting github profile');
|
||||
}
|
||||
updatedProfiles.push('twitter');
|
||||
|
||||
@@ -8,24 +8,21 @@ const unauthorizedVariables = {
|
||||
|
||||
function getHeaderToken(req: Request): string | null {
|
||||
const authHeader = req.headers['authorization'];
|
||||
if(!authHeader) return null;
|
||||
if (!authHeader) return null;
|
||||
const token = authHeader.replace('Bearer ', '');
|
||||
if(token.length === 0) return null;
|
||||
if (token.length === 0) return null;
|
||||
return token;
|
||||
}
|
||||
|
||||
const handler = async (req: Request, res: Response) => {
|
||||
|
||||
const token = getHeaderToken(req);
|
||||
|
||||
if(!token) {
|
||||
if (!token) {
|
||||
res.json(unauthorizedVariables);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
const claim = did.verifyToken(token);
|
||||
if(!claim) {
|
||||
if (!claim) {
|
||||
res.status(401).send();
|
||||
return;
|
||||
}
|
||||
@@ -38,9 +35,7 @@ const handler = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
res.json(hasuraVariables);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
||||
@@ -38,7 +38,7 @@ mutation CreateAccountFromETH ($eth_address: String!, $username: String!) {
|
||||
}
|
||||
`;
|
||||
interface IPlayer {
|
||||
id: string
|
||||
id: string;
|
||||
}
|
||||
|
||||
export async function createPlayer(ethAddress: string): Promise<IPlayer> {
|
||||
@@ -46,7 +46,7 @@ export async function createPlayer(ethAddress: string): Promise<IPlayer> {
|
||||
eth_address: ethAddress,
|
||||
username: ethAddress,
|
||||
});
|
||||
if(resProfile.insert_Account.affected_rows !== 2) {
|
||||
if (resProfile.insert_Account.affected_rows !== 2) {
|
||||
throw new Error('error while creating profile');
|
||||
}
|
||||
return resProfile.insert_Account.returning[0].Player;
|
||||
@@ -59,7 +59,7 @@ export async function getPlayer(ethAddress: string): Promise<IPlayer> {
|
||||
|
||||
let player = res.Account[0]?.Player;
|
||||
|
||||
if(!player) {
|
||||
if (!player) {
|
||||
player = await createPlayer(ethAddress);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import authHandler from './auth-webhook/handler';
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', function (_, res) {
|
||||
res.send('pong')
|
||||
res.send('pong');
|
||||
});
|
||||
|
||||
router.get('/auth-webhook', asyncHandlerWrapper(authHandler));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import express from 'express';
|
||||
import bodyParser from 'body-parser';
|
||||
import bodyParser from 'body-parser';
|
||||
|
||||
import config from './config';
|
||||
import config from './config';
|
||||
|
||||
import routes from './handlers/routes';
|
||||
import { errorMiddleware } from './lib/apiHelpers';
|
||||
@@ -15,5 +15,5 @@ app.use(routes);
|
||||
app.use(errorMiddleware);
|
||||
|
||||
app.listen(config.port, function () {
|
||||
console.log(`Listening on port ${config.port}`)
|
||||
console.log(`Listening on port ${config.port}`);
|
||||
});
|
||||
|
||||
@@ -2,11 +2,20 @@ import { Request, Response, NextFunction } from 'express';
|
||||
|
||||
export function asyncHandlerWrapper(middleware: any) {
|
||||
if (middleware.length === 4) {
|
||||
return function wrappedHandler(error: Error, req: Request, res: Response, next: NextFunction) {
|
||||
return function wrappedHandler(
|
||||
error: Error,
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) {
|
||||
middleware(error, req, res, next).catch(next);
|
||||
};
|
||||
}
|
||||
return function wrappedHandler(req: Request, res: Response, next: NextFunction) {
|
||||
return function wrappedHandler(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
) {
|
||||
middleware(req, res, next).catch(next);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export async function hasuraQuery(query: string, qv: any = {}) {
|
||||
|
||||
const { errors, data } = await result.json();
|
||||
|
||||
if(errors) {
|
||||
if (errors) {
|
||||
throw new Error(JSON.stringify(errors));
|
||||
}
|
||||
return data;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export function getPlayerETHAddress(player: any) {
|
||||
return player.Accounts.find((a: any) => a.type === "ETHEREUM").identifier;
|
||||
return player.Accounts.find((a: any) => a.type === 'ETHEREUM').identifier;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"typeRoots": [
|
||||
"../@types", "../../node_modules/@types"]
|
||||
"typeRoots": ["../@types", "../../node_modules/@types"]
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ overwrite: true
|
||||
config:
|
||||
scalars:
|
||||
DateTime: Date
|
||||
JSON: "{ [key: string]: any }"
|
||||
JSON: '{ [key: string]: any }'
|
||||
generates:
|
||||
./autogen/hasura/gql.ts:
|
||||
plugins:
|
||||
|
||||
@@ -4,7 +4,7 @@ overwrite: true
|
||||
config:
|
||||
scalars:
|
||||
DateTime: Date
|
||||
JSON: "{ [key: string]: any }"
|
||||
JSON: '{ [key: string]: any }'
|
||||
generates:
|
||||
./autogen/index.tsx:
|
||||
documents:
|
||||
@@ -28,7 +28,7 @@ generates:
|
||||
- graphql-codegen-hasura-typescript
|
||||
config:
|
||||
reactApolloVersion: 3
|
||||
typescriptCodegenOutputPath: "../"
|
||||
typescriptCodegenOutputPath: '../'
|
||||
trimString:
|
||||
withClientAndCacheHelpers: true
|
||||
withQueries: true
|
||||
@@ -43,7 +43,7 @@ generates:
|
||||
- graphql-codegen-hasura-react
|
||||
config:
|
||||
reactApolloVersion: 3
|
||||
typescriptCodegenOutputPath: "../"
|
||||
typescriptCodegenOutputPath: '../'
|
||||
trimString:
|
||||
withQueries: true
|
||||
withSubscriptions: true
|
||||
@@ -57,7 +57,7 @@ generates:
|
||||
- graphql-codegen-hasura-client-config
|
||||
config:
|
||||
reactApolloVersion: 3
|
||||
typescriptCodegenOutputPath: "../"
|
||||
typescriptCodegenOutputPath: '../'
|
||||
trimString:
|
||||
withTypePolicies: true
|
||||
withResolverTypes: true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ethers } from "ethers";
|
||||
import { Web3Provider } from "ethers/providers";
|
||||
import { ethers } from 'ethers';
|
||||
import { Web3Provider } from 'ethers/providers';
|
||||
import { Base64 } from 'js-base64';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@@ -27,7 +27,6 @@ export async function createToken(provider: Web3Provider) {
|
||||
return DIDToken;
|
||||
}
|
||||
|
||||
|
||||
export function getSignerAddress(token: string): any {
|
||||
try {
|
||||
const rawToken = Base64.decode(token);
|
||||
@@ -47,7 +46,7 @@ export function verifyToken(token: string): any {
|
||||
const claim = JSON.parse(rawClaim);
|
||||
|
||||
const signerAddress = ethers.utils.verifyMessage(rawClaim, proof);
|
||||
if(signerAddress !== claim.iss) {
|
||||
if (signerAddress !== claim.iss) {
|
||||
return null;
|
||||
}
|
||||
return claim;
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "./dist",
|
||||
"typeRoots": [
|
||||
"../@types", "../../node_modules/@types"]
|
||||
"typeRoots": ["../@types", "../../node_modules/@types"]
|
||||
},
|
||||
"include": [
|
||||
"./src"
|
||||
]
|
||||
"include": ["./src"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user