Skip to content

Commit

Permalink
Merge pull request #6 from calimero-network/fix/restructure
Browse files Browse the repository at this point in the history
Restructure the project to meet the template
  • Loading branch information
its-saeed authored Jun 21, 2024
2 parents ed04c5c + 0ca88a4 commit 17abead
Show file tree
Hide file tree
Showing 57 changed files with 1,449 additions and 2 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/deploy-vue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
node-version: "18"

- name: Install dependencies
working-directory: ./app
run: yarn install

- name: Build
working-directory: ./app
run: yarn build-only

- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
publish_dir: ./app/dist

notify-on-failure:
runs-on: ubuntu-latest
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions logic/leaderboard/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "leaderboard"
description = "leaderboard"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
repository.workspace = true
license.workspace = true

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
near-sdk.workspace = true

[dev-dependencies]
near-sdk = { workspace = true, features = ["unit-testing"] }
tokio.workspace = true
near-workspaces.workspace = true
serde_json.workspace = true
17 changes: 17 additions & 0 deletions logic/leaderboard/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh
rustup target add wasm32-unknown-unknown
set -e

cd "$(dirname $0)"

TARGET="${CARGO_TARGET_DIR:-../../target}"

cargo build --target wasm32-unknown-unknown --profile app-release

mkdir -p res

cp $TARGET/wasm32-unknown-unknown/app-release/leaderboard.wasm ./res/

if command -v wasm-opt > /dev/null; then
wasm-opt -Oz ./res/leaderboard.wasm -o ./res/leaderboard.wasm
fi
41 changes: 41 additions & 0 deletions logic/leaderboard/relayer/mock-ws-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { WebSocketServer } = require('ws');
const prompt = require('prompt-sync')({ sigint: true });

const wss = new WebSocketServer({ port: 8080 });

console.log('Waiting for a new connection...');

wss.on('connection', function connection(ws) {
let keepAsking = true;
ws.on('error', () => keepAsking = false);

ws.on('message', function message(data) {
console.log('received: %s', data);
});

while (keepAsking) {
console.log('-'.repeat(process.stdout.columns));
const action = prompt('What to do? add-score/get-score: ');
if (action === 'add-score') {
const account = prompt('Account: ');
const app = prompt('Application: ');
const score = parseInt(prompt('score: '));
ws.send(JSON.stringify({
action: 'add-score',
app,
account,
score
}));
} else if (action === 'get-score') {
const account = prompt('Account: ');
const app = prompt('Application: ');
ws.send(JSON.stringify({
action: 'get-score',
app,
account,
}));
} else {
ws.close();
}
}
});
13 changes: 13 additions & 0 deletions logic/leaderboard/relayer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "relayer",
"version": "1.0.0",
"main": "index.js",
"author": "Saeed",
"license": "MIT",
"dependencies": {
"command-line-args": "^5.2.1",
"near-api-js": "^4.0.1",
"prompt-sync": "^4.2.0",
"ws": "^8.17.0"
}
}
149 changes: 149 additions & 0 deletions logic/leaderboard/relayer/relayer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
const nearAPI = require('near-api-js');
const fs = require('fs');
const commandLineArgs = require('command-line-args');
const GameEventListener = require('./ws');

const { Contract } = nearAPI;

const createKeyStore = async () => {
const { KeyPair, keyStores } = nearAPI;

const ACCOUNT_ID = 'highfalutin-act.testnet';
const NETWORK_ID = 'testnet';
const KEY_PATH =
'/home/saeed/.near-credentials/testnet/highfalutin-act.testnet.json';

const credentials = JSON.parse(fs.readFileSync(KEY_PATH));
const myKeyStore = new keyStores.InMemoryKeyStore();
myKeyStore.setKey(
NETWORK_ID,
ACCOUNT_ID,
KeyPair.fromString(credentials.private_key)
);

return myKeyStore;
};

let keyStore;
const connectToNear = async () => {
keyStore = await createKeyStore();
const connectionConfig = {
networkId: 'testnet',
keyStore,
nodeUrl: 'https://rpc.testnet.near.org',
walletUrl: 'https://testnet.mynearwallet.com/',
helperUrl: 'https://helper.testnet.near.org',
explorerUrl: 'https://testnet.nearblocks.io',
};
const { connect } = nearAPI;
const nearConnection = await connect(connectionConfig);
return nearConnection;
};

const addScore = async (account_id, app_name, score) => {
if (contract === null) {
throw new Error('Contract is not initialized');
}

const account = await near.account('highfalutin-act.testnet');
await contract.add_score({
signerAccount: account,
args: {
app_name,
account_id,
score,
},
});
};

const getScore = async (account_id, app_name) => {
if (contract === null) {
throw new Error('Contract is not initialized');
}

return await contract.get_score({
app_name,
account_id,
});
};

const getScores = async (app_name) => {
if (contract === null) {
throw new Error('Contract is not initialized');
}

return await contract.get_scores({
app_name,
});
};

let contract = null;
let near = null;

async function main() {
const optionDefinitions = [
{ name: 'subscribe', type: Boolean },
{ name: 'add-score', type: Boolean },
{ name: 'get-score', type: Boolean },
{ name: 'get-scores', type: Boolean },
{ name: 'account', type: String },
{ name: 'score', type: Number },
{ name: 'app', type: String },
{ name: 'applicationId', type: String },
{ name: 'nodeUrl', type: String },
];

const options = commandLineArgs(optionDefinitions);

const nearConnection = await connectToNear();
near = nearConnection;
contract = new Contract(
nearConnection.connection,
'highfalutin-act.testnet',
{
changeMethods: ['add_score'],
viewMethods: ['get_version', 'get_score', 'get_scores'],
}
);
if (options.subscribe) {
const { applicationId, nodeUrl } = options;
console.log(`Subscribed for the events of ${applicationId}`);
subscribe(applicationId, nodeUrl);
} else if (options['add-score']) {
const { account, app, score } = options;
await addScore(account, app, score);
console.log(
`Score added for account: ${account}, app: ${app}, score: ${score}`
);
} else if (options['get-score']) {
const { account, app } = options;
const score = await getScore(account, app);
console.log(`${account} score is: ${score}`);
} else if (options['get-scores']) {
const { app } = options;
const scores = await getScores(app);
console.log(`Scores for ${app}: ${JSON.stringify(scores)}`);
}
}

let eventListener;
let players = {};
const subscribe = (applicationId, nodeUrl) => {
eventListener = new GameEventListener(nodeUrl, applicationId);
eventListener.on('NewPlayer', (player) => {
players[player.id] = player.name;
});

eventListener.on('GameOver', (winner) => {
addScore(players[winner.winner], 'rsp', 1000).then(() =>
console.log(`Score added for ${players[winner.winner]}`)
).catch(e => {
console.error(`Failed to add the score. ${e}`);
});
});
};

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
50 changes: 50 additions & 0 deletions logic/leaderboard/relayer/ws.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

// Listen for messages
const WebSocket = require('ws');

module.exports = class GameEventListener {
constructor(nodeUrl, applicationId) {
this.ws = new WebSocket(`${nodeUrl}/ws`);
this.ws.on('open', () => {
const request = {
id: this.getRandomRequestId(),
method: 'subscribe',
params: {
applicationIds: [applicationId],
},
};
this.ws.send(JSON.stringify(request));
});

this.events = {};
this.ws.on('message', async (event) => {
const utf8Decoder = new TextDecoder('UTF-8');
const data = utf8Decoder.decode(event);
await this.parseMessage(data);
});
}

on(event, func) {
this.events[event] = func;
}

parseMessage(msg) {
try {
const event = JSON.parse(msg);
for (const e of event.result.data.events) {
if (e.kind in this.events) {
let bytes = new Int8Array(e.data);
let str = new TextDecoder().decode(bytes);
this.events[e.kind](JSON.parse(str));
}
}
} catch (e) {
console.error(`Failed to parse the json: ${e}`);
}
}

getRandomRequestId() {
return Math.floor(Math.random() * Math.pow(2, 32));
}
};

Loading

0 comments on commit 17abead

Please sign in to comment.