Skip to content

Commit

Permalink
feat: Add NEAR API with login and logout button
Browse files Browse the repository at this point in the history
  • Loading branch information
johnedvard committed Aug 17, 2022
1 parent 54f50cb commit 369619f
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
<meta charset="utf-8" />
<title>Skeleton rope</title>
<link rel="stylesheet" href="styles.css" />
<script
type="module"
src="https://js13kgames.com/src/near-api-js.js"
></script>
<script type="module" src="index.js"></script>
</head>
<body>
<button id="loginout"></button>
<canvas width="800px" height="800px"></canvas>
</body>
</html>
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Game } from './Game';
import { NearConnection } from './near/nearConnection';
import { initLoginLogout } from './near/nearLogin';
const init = () => {
new Game();
const nearConnection = new NearConnection();
nearConnection.initContract().then((res) => {
initLoginLogout(nearConnection);
});
};

init();
63 changes: 63 additions & 0 deletions src/near/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const CONTRACT_NAME = 'dev-1618829854588-2430734';

function getConfig(env) {
switch (env) {
// case 'production':
// case 'mainnet':
// return {
// networkId: 'mainnet',
// nodeUrl: 'https://rpc.mainnet.near.org',
// contractName: CONTRACT_NAME,
// walletUrl: 'https://wallet.near.org',
// helperUrl: 'https://helper.mainnet.near.org',
// explorerUrl: 'https://explorer.mainnet.near.org',
// };
case 'development':
case 'testnet':
return {
networkId: 'testnet',
nodeUrl: 'https://rpc.testnet.near.org',
contractName: CONTRACT_NAME,
walletUrl: 'https://wallet.testnet.near.org',
helperUrl: 'https://helper.testnet.near.org',
explorerUrl: 'https://explorer.testnet.near.org',
};
// case 'betanet':
// return {
// networkId: 'betanet',
// nodeUrl: 'https://rpc.betanet.near.org',
// contractName: CONTRACT_NAME,
// walletUrl: 'https://wallet.betanet.near.org',
// helperUrl: 'https://helper.betanet.near.org',
// explorerUrl: 'https://explorer.betanet.near.org',
// };
// case 'local':
// return {
// networkId: 'local',
// nodeUrl: 'http://localhost:3030',
// keyPath: `${process.env.HOME}/.near/validator_key.json`,
// walletUrl: 'http://localhost:4000/wallet',
// contractName: CONTRACT_NAME,
// };
// case 'test':
// case 'ci':
// return {
// networkId: 'shared-test',
// nodeUrl: 'https://rpc.ci-testnet.near.org',
// contractName: CONTRACT_NAME,
// masterAccount: 'test.near',
// };
// case 'ci-betanet':
// return {
// networkId: 'shared-test-staging',
// nodeUrl: 'https://rpc.ci-betanet.near.org',
// contractName: CONTRACT_NAME,
// masterAccount: 'test.near',
// };
// default:
// throw Error(
// `Unconfigured environment '${env}'. Can be configured in src/config.js.`
// );
}
}
module.exports = getConfig;
110 changes: 110 additions & 0 deletions src/near/nearConnection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import getConfig from './config';

export class NearConnection {
walletConnection;
contract;
accountId;
userName;
ready; //promise
nearConfig = getConfig('development');
resolveContract;
constructor() {
this.ready = new Promise((resolve, reject) => {
this.resolveContract = resolve;
});
}

// Initialize contract & set global variables
async initContract() {
// Initialize connection to the NEAR testnet
const keyStore = new window.nearApi.keyStores.BrowserLocalStorageKeyStore();
const near = await window.nearApi.connect({ ...this.nearConfig, keyStore });

// Initializing Wallet based Account. It can work with NEAR testnet wallet that
// is hosted at https://wallet.testnet.near.org
this.walletConnection = new window.nearApi.WalletConnection(near, null);

// Getting the Account ID. If still unauthorized, it's just empty string
this.accountId = this.walletConnection.getAccountId();

// Initializing our contract APIs by contract name and configuration
this.contract = await new window.nearApi.Contract(
this.walletConnection.account(),
this.nearConfig.contractName,
{
// View methods are read only. They don't modify the state, but usually return some value.
viewMethods: ['getScores', 'getScore', 'getName'],
// Change methods can modify the state. But you don't receive the returned value when called.
changeMethods: ['setGreeting', 'setScore', 'setName'],
}
);
this.resolveContract();

return this.walletConnection;
}

logout() {
this.walletConnection.signOut();
// reload page
}
login() {
// Allow the current app to make calls to the specified contract on the
// user's behalf.
// This works by creating a new access key for the user's account and storing
// the private key in localStorage.
this.walletConnection.requestSignIn(this.nearConfig.contractName);
}

setScore(levelName, score, name) {
const json = JSON.stringify({ score, name });
return this.contract.setScore({
levelName,
json,
});
}

getScores(levelName) {
const scoreBoard = this.contract.getScores({ levelName });
return scoreBoard;
}

getScore(levelName) {
const accountId = this.accountId;
return this.contract.getScore({ levelName, accountId });
}

setName(name) {
if (
name &&
name != this.userName &&
this.walletConnection &&
this.walletConnection.isSignedIn()
) {
this.userName = name;
return this.contract.setName({ name });
}
return Promise.resolve();
}

async getName() {
if (this.userName) {
return Promise.resolve(this.userName);
}
const accountId = this.accountId;
return new Promise((resolve, reject) => {
this.contract
.getName({ accountId })
.then((res) => {
if (res && res.match(/[ `!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/g)) {
this.userName = 'Invalid username';
} else {
this.userName = res;
}
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
}
29 changes: 29 additions & 0 deletions src/near/nearLogin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const loginout = (loginoutEl, nearConnection) => {
if (!nearConnection) return;
if (nearConnection.walletConnection.isSignedIn()) {
nearConnection.logout();
loginoutEl.innerHTML = 'Login to NEAR wallet';
} else {
nearConnection.login();
loginoutEl.innerHTML = 'Logout from NEAR wallet';
}
};

export const initLoginLogout = (nearConnection) => {
const loginoutEl = document.getElementById('loginout');
if (
nearConnection &&
nearConnection.walletConnection &&
nearConnection.walletConnection.isSignedIn()
) {
loginoutEl.innerHTML = 'Logout from NEAR wallet';
nearConnection.getName().then((res) => {
loginoutEl.innerHTML = `Logout from NEAR wallet`;
});
} else {
loginoutEl.innerHTML = 'Login to NEAR wallet';
}
loginoutEl.addEventListener('click', () =>
loginout(loginoutEl, nearConnection)
);
};
9 changes: 5 additions & 4 deletions src/styles.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
display: flex;
align-items: center;
align-content: center;
flex-flow: column;
justify-content: center;
height: 100vh;
width: 100vw;
align-items: center;
overflow: hidden;
}
canvas {
background-color: gray;
Expand Down

0 comments on commit 369619f

Please sign in to comment.