├── app
├── env.d.ts
├── public
│ └── favicon.ico
├── .vscode
│ ├── extensions.json
│ └── settings.json
├── src
│ ├── axios.ts
│ ├── quasar-variables.sass
│ ├── pages
│ │ ├── LoginPage.vue
│ │ └── IndexPage.vue
│ ├── App.vue
│ ├── assets
│ │ ├── logo.svg
│ │ ├── main.css
│ │ └── base.css
│ ├── components
│ │ ├── icons
│ │ │ ├── IconSupport.vue
│ │ │ ├── IconTooling.vue
│ │ │ ├── IconCommunity.vue
│ │ │ ├── IconDocumentation.vue
│ │ │ └── IconEcosystem.vue
│ │ ├── NearLogin.vue
│ │ ├── LeaderBoard.vue
│ │ └── PlayGame.vue
│ ├── main.ts
│ ├── auth.ts
│ ├── router
│ │ └── index.ts
│ ├── ws.js
│ ├── crypto.ts
│ └── game.ts
├── .prettierrc.json
├── tsconfig.json
├── index.html
├── .eslintrc.cjs
├── tsconfig.app.json
├── tsconfig.node.json
├── vite.config.ts
├── README.md
└── package.json
├── logic
├── leaderboard
│ ├── res
│ │ └── leaderboard.wasm
│ ├── relayer
│ │ ├── package.json
│ │ ├── mock-ws-server.js
│ │ ├── ws.js
│ │ ├── relayer.js
│ │ └── yarn.lock
│ ├── build.sh
│ ├── Cargo.toml
│ ├── tests
│ │ └── sandbox.rs
│ └── src
│ │ └── lib.rs
└── rock-paper-scissors
│ ├── res
│ └── rock_paper_scissors.wasm
│ ├── build.sh
│ ├── Cargo.toml
│ ├── src
│ ├── errors.rs
│ ├── player_idx.rs
│ ├── commitment.rs
│ ├── choice.rs
│ ├── key.rs
│ ├── repr.rs
│ └── lib.rs
│ └── Cargo.lock
├── .gitignore
├── .github
└── workflows
│ └── deploy-vue.yml
└── README.md
/app/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calimero-network/rock-paper-scissors/HEAD/app/public/favicon.ico
--------------------------------------------------------------------------------
/logic/leaderboard/res/leaderboard.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calimero-network/rock-paper-scissors/HEAD/logic/leaderboard/res/leaderboard.wasm
--------------------------------------------------------------------------------
/app/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "Vue.volar",
4 | "dbaeumer.vscode-eslint",
5 | "esbenp.prettier-vscode"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/axios.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | const nearApi = axios.create({ baseURL: 'https://rpc.testnet.near.org/' })
4 |
5 | export { axios, nearApi }
6 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/res/rock_paper_scissors.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calimero-network/rock-paper-scissors/HEAD/logic/rock-paper-scissors/res/rock_paper_scissors.wasm
--------------------------------------------------------------------------------
/app/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/prettierrc",
3 | "semi": false,
4 | "tabWidth": 2,
5 | "singleQuote": true,
6 | "printWidth": 100,
7 | "trailingComma": "none"
8 | }
--------------------------------------------------------------------------------
/app/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll": "explicit"
4 | },
5 | "editor.formatOnSave": true,
6 | "editor.defaultFormatter": "esbenp.prettier-vscode"
7 | }
8 |
--------------------------------------------------------------------------------
/app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | {
5 | "path": "./tsconfig.node.json"
6 | },
7 | {
8 | "path": "./tsconfig.app.json"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/quasar-variables.sass:
--------------------------------------------------------------------------------
1 | $primary : #1976D2
2 | $secondary : #26A69A
3 | $accent : #9C27B0
4 |
5 | $dark : #1D1D1D
6 |
7 | $positive : #21BA45
8 | $negative : #C10015
9 | $info : #31CCEC
10 | $warning : #F2C037
--------------------------------------------------------------------------------
/app/src/pages/LoginPage.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/logic/leaderboard/relayer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "relayer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "Saeed",
6 | "license": "MIT",
7 | "dependencies": {
8 | "command-line-args": "^5.2.1",
9 | "near-api-js": "^4.0.1",
10 | "prompt-sync": "^4.2.0",
11 | "ws": "^8.17.1"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/components/icons/IconSupport.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | require('@rushstack/eslint-patch/modern-module-resolution')
3 |
4 | module.exports = {
5 | root: true,
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended',
9 | '@vue/eslint-config-typescript',
10 | '@vue/eslint-config-prettier/skip-formatting'
11 | ],
12 | parserOptions: {
13 | ecmaVersion: 'latest'
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4 | "exclude": ["src/**/__tests__/*"],
5 | "compilerOptions": {
6 | "composite": true,
7 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
8 |
9 | "baseUrl": ".",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main.ts:
--------------------------------------------------------------------------------
1 | import './assets/main.css'
2 |
3 | import { createApp } from 'vue'
4 | import App from './App.vue'
5 | import router from './router'
6 | import { Quasar } from 'quasar'
7 | import '@quasar/extras/material-icons/material-icons.css'
8 | import 'quasar/src/css/index.sass'
9 |
10 | const app = createApp(App)
11 |
12 | app.use(router)
13 | app.use(Quasar, {
14 | plugins: {} // import Quasar plugins and add here
15 | })
16 |
17 | app.mount('#app')
18 |
--------------------------------------------------------------------------------
/app/src/auth.ts:
--------------------------------------------------------------------------------
1 | import { LocalStorage } from 'quasar'
2 |
3 | export interface ClientKey {
4 | privateKey: string
5 | publicKey: string
6 | }
7 |
8 | export const isAuthenticated = () => {
9 | return LocalStorage.hasItem('client-key')
10 | }
11 |
12 | export const getClientKey = (): ClientKey | null => {
13 | const keyStr: string | null = LocalStorage.getItem('client-key')
14 | if (keyStr) {
15 | return JSON.parse(keyStr)
16 | }
17 | return null
18 | }
19 |
--------------------------------------------------------------------------------
/logic/leaderboard/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | rustup target add wasm32-unknown-unknown
3 | set -e
4 |
5 | cd "$(dirname $0)"
6 |
7 | TARGET="${CARGO_TARGET_DIR:-target}"
8 |
9 | cargo build --target wasm32-unknown-unknown --profile app-release
10 |
11 | mkdir -p res
12 |
13 | cp $TARGET/wasm32-unknown-unknown/app-release/leaderboard.wasm ./res/
14 |
15 | if command -v wasm-opt > /dev/null; then
16 | wasm-opt -Oz ./res/leaderboard.wasm -o ./res/leaderboard.wasm
17 | fi
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
30 | *.tsbuildinfo
31 |
32 | .idea/
33 | data/
34 | target/
35 |
--------------------------------------------------------------------------------
/app/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/node20/tsconfig.json",
3 | "include": [
4 | "vite.config.*",
5 | "vitest.config.*",
6 | "cypress.config.*",
7 | "nightwatch.conf.*",
8 | "playwright.config.*"
9 | ],
10 | "compilerOptions": {
11 | "composite": true,
12 | "noEmit": true,
13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
14 |
15 | "module": "ESNext",
16 | "moduleResolution": "Bundler",
17 | "types": ["node"]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | cd "$(dirname $0)"
5 |
6 | TARGET="${CARGO_TARGET_DIR:-target}"
7 |
8 | rustup target add wasm32-unknown-unknown
9 |
10 | cargo build --target wasm32-unknown-unknown --profile app-release
11 |
12 | mkdir -p res
13 |
14 | cp $TARGET/wasm32-unknown-unknown/app-release/rock_paper_scissors.wasm ./res/
15 |
16 | if command -v wasm-opt > /dev/null; then
17 | wasm-opt -Oz ./res/rock_paper_scissors.wasm -o ./res/rock_paper_scissors.wasm
18 | fi
19 |
--------------------------------------------------------------------------------
/app/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHistory } from 'vue-router'
2 | import IndexPage from '../pages/IndexPage.vue'
3 | import NearLoginPage from '../pages/LoginPage.vue'
4 |
5 | const router = createRouter({
6 | history: createWebHistory(import.meta.env.BASE_URL),
7 | routes: [
8 | {
9 | path: '/',
10 | name: 'home',
11 | component: IndexPage
12 | },
13 | {
14 | path: '/login',
15 | name: 'login',
16 | component: NearLoginPage
17 | }
18 | ]
19 | })
20 |
21 | export default router
22 |
--------------------------------------------------------------------------------
/logic/leaderboard/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "leaderboard"
3 | description = "leaderboard"
4 | version = "0.1.0"
5 | edition = "2021"
6 |
7 | [lib]
8 | crate-type = ["cdylib", "rlib"]
9 |
10 | [dependencies]
11 | near-sdk = "5.5.0"
12 |
13 | [dev-dependencies]
14 | near-sdk = { version = "5.5.0", features = ["unit-testing"] }
15 | tokio = "1.35.1"
16 | near-workspaces = "0.15.0"
17 | serde_json = "1.0.113"
18 |
19 | [profile.app-release]
20 | inherits = "release"
21 | codegen-units = 1
22 | opt-level = "z"
23 | lto = true
24 | debug = false
25 | panic = "abort"
26 | overflow-checks = true
--------------------------------------------------------------------------------
/app/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app {
4 | max-width: 1280px;
5 | margin: 0 auto;
6 | padding: 2rem;
7 | font-weight: normal;
8 | }
9 |
10 | a,
11 | .green {
12 | text-decoration: none;
13 | color: hsla(160, 100%, 37%, 1);
14 | transition: 0.4s;
15 | padding: 3px;
16 | }
17 |
18 | @media (hover: hover) {
19 | a:hover {
20 | background-color: hsla(160, 100%, 37%, 0.2);
21 | }
22 | }
23 |
24 | @media (min-width: 1024px) {
25 | body {
26 | display: flex;
27 | place-items: center;
28 | }
29 |
30 | #app {
31 | display: grid;
32 | padding: 0 2rem;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/pages/IndexPage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rock-paper-scissors"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib"]
8 |
9 | [dependencies]
10 | bs58 = "0.5.0"
11 | calimero-sdk = { git = "https://github.com/calimero-network/core", branch = "master" }
12 | calimero-storage = { git = "https://github.com/calimero-network/core", branch = "master" }
13 | ed25519-dalek = {version = "2.1.1",features = ["rand_core"]}
14 | rand_chacha = "0.3.1"
15 | sha3 = "0.10.8"
16 |
17 | [profile.app-release]
18 | inherits = "release"
19 | codegen-units = 1
20 | opt-level = "z"
21 | lto = true
22 | debug = false
23 | panic = "abort"
24 | overflow-checks = true
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/errors.rs:
--------------------------------------------------------------------------------
1 | use calimero_sdk::serde::Serialize;
2 |
3 | #[derive(Debug, Serialize)]
4 | #[serde(crate = "calimero_sdk::serde")]
5 | pub enum JoinError {
6 | GameFull,
7 | }
8 |
9 | #[derive(Debug, Serialize)]
10 | #[serde(crate = "calimero_sdk::serde")]
11 | pub enum CommitError {
12 | NotReady,
13 | AlreadyCommitted,
14 | InvalidSignature,
15 | }
16 |
17 | #[derive(Debug, Serialize)]
18 | #[serde(crate = "calimero_sdk::serde")]
19 | pub enum RevealError {
20 | NotReady,
21 | NotCommitted,
22 | InvalidNonce,
23 | }
24 |
25 | #[derive(Debug, Serialize)]
26 | #[serde(crate = "calimero_sdk::serde")]
27 | pub enum ResetError {
28 | NotReady,
29 | InvalidSignature,
30 | }
31 |
--------------------------------------------------------------------------------
/app/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 | import { nodePolyfills } from 'vite-plugin-node-polyfills'
6 | import { quasar, transformAssetUrls } from '@quasar/vite-plugin'
7 |
8 | // https://vitejs.dev/config/
9 | export default defineConfig({
10 | plugins: [
11 | vue({
12 | template: { transformAssetUrls }
13 | }),
14 | nodePolyfills(),
15 | quasar({
16 | sassVariables: 'src/quasar-variables.sass'
17 | })
18 | ],
19 | resolve: {
20 | alias: {
21 | '@': fileURLToPath(new URL('./src', import.meta.url))
22 | }
23 | },
24 | base: process.env.NODE_ENV === 'production' ? '/rock-paper-scissors/' : '/'
25 | })
26 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/player_idx.rs:
--------------------------------------------------------------------------------
1 | use calimero_sdk::serde::{Deserialize, Deserializer, Serialize};
2 |
3 | #[derive(Copy, Clone, Serialize)]
4 | #[serde(crate = "calimero_sdk::serde")]
5 | pub struct PlayerIdx(pub usize);
6 |
7 | impl PlayerIdx {
8 | pub fn other(&self) -> PlayerIdx {
9 | PlayerIdx(1 - self.0)
10 | }
11 |
12 | pub fn is_first(&self) -> bool {
13 | self.0 == 0
14 | }
15 | }
16 |
17 | impl<'de> Deserialize<'de> for PlayerIdx {
18 | fn deserialize(deserializer: D) -> Result
19 | where
20 | D: Deserializer<'de>,
21 | {
22 | let value = Deserialize::deserialize(deserializer)?;
23 | match value {
24 | 0 | 1 => Ok(PlayerIdx(value)),
25 | _ => Err(calimero_sdk::serde::de::Error::custom(
26 | "Player index must be 0 or 1",
27 | )),
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/commitment.rs:
--------------------------------------------------------------------------------
1 | use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
2 | use sha3::{Digest, Sha3_256};
3 |
4 | use crate::Choice;
5 |
6 | #[derive(Eq, Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
7 | #[borsh(crate = "calimero_sdk::borsh")]
8 | pub struct Commitment([u8; 32]);
9 |
10 | pub type Nonce = [u8; 32];
11 |
12 | impl Commitment {
13 | pub fn of(choice: Choice, nonce: &Nonce) -> Self {
14 | let mut hasher = Sha3_256::new();
15 |
16 | hasher.update(&[choice as u8]);
17 | hasher.update(nonce);
18 |
19 | Commitment(hasher.finalize().into())
20 | }
21 |
22 | pub const fn from_bytes(bytes: &[u8; 32]) -> Self {
23 | Commitment(*bytes)
24 | }
25 |
26 | pub const fn to_bytes(&self) -> [u8; 32] {
27 | self.0
28 | }
29 | }
30 |
31 | impl AsRef<[u8]> for Commitment {
32 | fn as_ref(&self) -> &[u8] {
33 | &self.0
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/components/icons/IconTooling.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/components/icons/IconCommunity.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/README.md:
--------------------------------------------------------------------------------
1 | # Rock, paper and scissors UI
2 |
3 | This template should help get you started developing with Vue 3 in Vite.
4 |
5 | ## Recommended IDE Setup
6 |
7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8 |
9 | ## Type Support for `.vue` Imports in TS
10 |
11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
12 |
13 | ## Customize configuration
14 |
15 | See [Vite Configuration Reference](https://vitejs.dev/config/).
16 |
17 | ## Project Setup
18 |
19 | ```sh
20 | npm install
21 | ```
22 |
23 | ### Compile and Hot-Reload for Development
24 |
25 | ```sh
26 | npm run dev
27 | ```
28 |
29 | ### Type-Check, Compile and Minify for Production
30 |
31 | ```sh
32 | npm run build
33 | ```
34 |
35 | ### Lint with [ESLint](https://eslint.org/)
36 |
37 | ```sh
38 | npm run lint
39 | ```
40 |
--------------------------------------------------------------------------------
/app/src/components/icons/IconDocumentation.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/ws.js:
--------------------------------------------------------------------------------
1 |
2 | // Listen for messages
3 |
4 | export default class GameEventListener {
5 | constructor(nodeUrl, applicationId) {
6 | this.ws = new WebSocket(`${nodeUrl}/ws`);
7 | this.ws.addEventListener("open", () => {
8 | console.log('here')
9 | const request = {
10 | id: this.getRandomRequestId(),
11 | method: "subscribe",
12 | params: {
13 | applicationIds: [applicationId],
14 | },
15 | };
16 | this.ws.send(JSON.stringify(request));
17 | });
18 |
19 | this.events = {};
20 | this.ws.addEventListener("message", (event) => {
21 | this.parseMessage(event.data)
22 | });
23 | }
24 |
25 | on(event, func) {
26 | this.events[event] = func;
27 | }
28 |
29 | parseMessage(msg) {
30 | const event = JSON.parse(msg);
31 | const events = event.result.data?.events;
32 | if (events) {
33 | events.forEach(e => {
34 | if (e.kind in this.events) {
35 | let bytes = new Int8Array(e.data);
36 | let str = new TextDecoder().decode(bytes);
37 | this.events[e.kind](JSON.parse(str))
38 | }
39 | })
40 | }
41 | }
42 |
43 | getRandomRequestId() {
44 | return Math.floor(Math.random() * Math.pow(2, 32));
45 | };
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/logic/leaderboard/relayer/mock-ws-server.js:
--------------------------------------------------------------------------------
1 | const { WebSocketServer } = require('ws');
2 | const prompt = require('prompt-sync')({ sigint: true });
3 |
4 | const wss = new WebSocketServer({ port: 8080 });
5 |
6 | console.log('Waiting for a new connection...');
7 |
8 | wss.on('connection', function connection(ws) {
9 | let keepAsking = true;
10 | ws.on('error', () => keepAsking = false);
11 |
12 | ws.on('message', function message(data) {
13 | console.log('received: %s', data);
14 | });
15 |
16 | while (keepAsking) {
17 | console.log('-'.repeat(process.stdout.columns));
18 | const action = prompt('What to do? add-score/get-score: ');
19 | if (action === 'add-score') {
20 | const account = prompt('Account: ');
21 | const app = prompt('Application: ');
22 | const score = parseInt(prompt('score: '));
23 | ws.send(JSON.stringify({
24 | action: 'add-score',
25 | app,
26 | account,
27 | score
28 | }));
29 | } else if (action === 'get-score') {
30 | const account = prompt('Account: ');
31 | const app = prompt('Application: ');
32 | ws.send(JSON.stringify({
33 | action: 'get-score',
34 | app,
35 | account,
36 | }));
37 | } else {
38 | ws.close();
39 | }
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/choice.rs:
--------------------------------------------------------------------------------
1 | use std::cmp::Ordering;
2 |
3 | use crate::commitment::Commitment;
4 | use crate::commitment::Nonce;
5 | use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
6 | use calimero_sdk::serde::{Deserialize, Serialize};
7 |
8 | #[derive(
9 | Eq, Copy, Clone, Debug, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
10 | )]
11 | #[borsh(crate = "calimero_sdk::borsh")]
12 | #[serde(crate = "calimero_sdk::serde")]
13 | #[repr(u8)]
14 | pub enum Choice {
15 | Rock,
16 | Paper,
17 | Scissors,
18 | }
19 |
20 | use Choice::*;
21 |
22 | impl Choice {
23 | pub fn determine(commitment: &Commitment, nonce: &Nonce) -> Option {
24 | let choices = [Rock, Paper, Scissors];
25 |
26 | for choice in choices {
27 | if *commitment == Commitment::of(choice, nonce) {
28 | return Some(choice);
29 | }
30 | }
31 |
32 | None
33 | }
34 | }
35 |
36 | impl PartialOrd for Choice {
37 | fn partial_cmp(&self, other: &Self) -> Option {
38 | match (self, other) {
39 | (Rock, Scissors) | (Scissors, Paper) | (Paper, Rock) => Some(Ordering::Greater),
40 | (Scissors, Rock) | (Paper, Scissors) | (Rock, Paper) => Some(Ordering::Less),
41 | _ => Some(Ordering::Equal),
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/components/NearLogin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
53 |
--------------------------------------------------------------------------------
/logic/leaderboard/relayer/ws.js:
--------------------------------------------------------------------------------
1 |
2 | // Listen for messages
3 | const WebSocket = require('ws');
4 |
5 | module.exports = class GameEventListener {
6 | constructor(nodeUrl, applicationId) {
7 | this.ws = new WebSocket(`${nodeUrl}/ws`);
8 | this.ws.on('open', () => {
9 | const request = {
10 | id: this.getRandomRequestId(),
11 | method: 'subscribe',
12 | params: {
13 | applicationIds: [applicationId],
14 | },
15 | };
16 | this.ws.send(JSON.stringify(request));
17 | });
18 |
19 | this.events = {};
20 | this.ws.on('message', async (event) => {
21 | const utf8Decoder = new TextDecoder('UTF-8');
22 | const data = utf8Decoder.decode(event);
23 | await this.parseMessage(data);
24 | });
25 | }
26 |
27 | on(event, func) {
28 | this.events[event] = func;
29 | }
30 |
31 | parseMessage(msg) {
32 | try {
33 | const event = JSON.parse(msg);
34 | for (const e of event.result.data.events) {
35 | if (e.kind in this.events) {
36 | let bytes = new Int8Array(e.data);
37 | let str = new TextDecoder().decode(bytes);
38 | this.events[e.kind](JSON.parse(str));
39 | }
40 | }
41 | } catch (e) {
42 | console.error(`Failed to parse the json: ${e}`);
43 | }
44 | }
45 |
46 | getRandomRequestId() {
47 | return Math.floor(Math.random() * Math.pow(2, 32));
48 | }
49 | };
50 |
51 |
--------------------------------------------------------------------------------
/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rock-paper-scissors",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "run-p type-check \"build-only {@}\" --",
9 | "preview": "vite preview",
10 | "build-only": "vite build",
11 | "type-check": "vue-tsc --build --force",
12 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
13 | "format": "prettier --write src/"
14 | },
15 | "dependencies": {
16 | "@calimero-is-near/calimero-p2p-sdk": "^0.0.13",
17 | "@quasar/extras": "^1.16.11",
18 | "quasar": "^2.16.4",
19 | "react-dom": "^18.3.1",
20 | "veaury": "^2.4.0",
21 | "vite-plugin-node-polyfills": "^0.22.0",
22 | "vue": "^3.4.21",
23 | "vue-router": "^4.3.0"
24 | },
25 | "devDependencies": {
26 | "@quasar/vite-plugin": "^1.7.0",
27 | "@rushstack/eslint-patch": "^1.8.0",
28 | "@tsconfig/node20": "^20.1.4",
29 | "@types/node": "^20.12.5",
30 | "@vitejs/plugin-vue": "^5.0.4",
31 | "@vue/eslint-config-prettier": "^9.0.0",
32 | "sass": "^1.33.0",
33 | "@vue/eslint-config-typescript": "^13.0.0",
34 | "@vue/tsconfig": "^0.5.1",
35 | "eslint": "^8.57.0",
36 | "eslint-plugin-vue": "^9.23.0",
37 | "npm-run-all2": "^6.1.2",
38 | "prettier": "^3.2.5",
39 | "typescript": "~5.4.0",
40 | "vite": "^5.2.8",
41 | "vue-tsc": "^2.0.11"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/crypto.ts:
--------------------------------------------------------------------------------
1 | import { unmarshalPrivateKey } from '@libp2p/crypto/keys'
2 | import type { PrivateKey } from '@libp2p/interface'
3 | import bs58 from 'bs58'
4 | import { getClientKey, type ClientKey } from './auth'
5 |
6 | export enum WalletType {
7 | NEAR = 'NEAR',
8 | ETH = 'ETH'
9 | }
10 |
11 | export interface AxiosHeader {
12 | [key: string]: string
13 | }
14 |
15 | export async function createAuthHeader(payload: string): Promise {
16 | const privateKey: PrivateKey | null = await getPrivateKey()
17 |
18 | if (!privateKey) {
19 | return null
20 | }
21 |
22 | const encoder = new TextEncoder()
23 | const contentBuff = encoder.encode(payload)
24 |
25 | const signing_key = bs58.encode(privateKey.public.bytes)
26 |
27 | const hashBuffer = await crypto.subtle.digest('SHA-256', contentBuff)
28 | const hashArray = new Uint8Array(hashBuffer)
29 |
30 | const signature = await privateKey.sign(hashArray)
31 | const signatureBase58 = bs58.encode(signature)
32 | const contentBase58 = bs58.encode(hashArray)
33 |
34 | const headers: AxiosHeader = {
35 | wallet_type: WalletType.NEAR,
36 | signing_key: signing_key,
37 | signature: signatureBase58,
38 | challenge: contentBase58
39 | }
40 |
41 | return headers
42 | }
43 |
44 | export async function getPrivateKey(): Promise {
45 | try {
46 | const clientKey: ClientKey | null = getClientKey()
47 | console.log(clientKey)
48 | if (!clientKey) {
49 | return null
50 | }
51 | return await unmarshalPrivateKey(bs58.decode(clientKey.privateKey))
52 | } catch (error) {
53 | console.error('Error extracting private key:', error)
54 | return null
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-vue.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | deploy:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v4
17 |
18 | - name: Setup Node.js
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: "18"
22 |
23 | - name: Install dependencies
24 | working-directory: ./app
25 | run: yarn install
26 |
27 | - name: Build
28 | working-directory: ./app
29 | run: yarn build-only
30 |
31 | - name: Deploy
32 | uses: peaceiris/actions-gh-pages@v4
33 | with:
34 | github_token: ${{ secrets.GITHUB_TOKEN }}
35 | publish_dir: ./app/dist
36 |
37 | notify-on-failure:
38 | runs-on: ubuntu-latest
39 | needs: [deploy]
40 | if: failure()
41 | steps:
42 | - name: Notify failure
43 | uses: "ravsamhq/notify-slack-action@2.5.0"
44 | with:
45 | status: failure
46 | notification_title: "Deploy failed on ${{ github.ref_name }} - <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Failure>"
47 | message_format: ":fire: *Deploy Rock-paper-scissors site to Pages* in <${{ github.server_url }}/${{ github.repository }}/${{ github.ref_name }}|${{ github.repository }}>"
48 | footer: "Linked Repo <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}> | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Failure>"
49 | env:
50 | SLACK_WEBHOOK_URL: ${{ secrets.DEPLOY_FAIL_SLACK }}
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Rock Paper Scissors Game with Calimero SDK and Vue.js
2 |
3 | This repository contains the implementation of the classic game Rock Paper Scissors, built using the Calimero Application SDK and a user interface (UI) implemented in Vue.js.
4 |
5 | ## Project Structure
6 |
7 | The project is structured into two main parts:
8 |
9 | 1. **Logic Folder:** This folder contains the contract for the game, implemented using the Calimero SDK. It also includes a build script to compile the contract into a WebAssembly (WASM) file.
10 |
11 | 2. **Vue.js UI:** The user interface for the game is implemented using Vue.js. It interacts with the deployed contract to facilitate the gameplay.
12 |
13 | ## Getting Started
14 |
15 | Follow these steps to get the project up and running:
16 |
17 | ### Running local nodes
18 | You need to run Calimero nodes on your machine to get started. Follow the [Getting started](https://calimero-network.github.io/getting-started/setup) documentation.
19 |
20 | ### Building the Contract
21 |
22 | 1. Navigate to the `logic/rock-paper-scissors` folder.
23 | 2. Run the build script to compile the contract into a WASM file.
24 |
25 | ### Deploying the Contract
26 |
27 | Follow the deployment instructions provided in the [Calimero documentation](https://calimero-network.github.io/build/publish-app). You need to deploy the game on at least two nodes to play the game.
28 |
29 | ### Building the UI
30 |
31 | 1. Ensure you have `yarn` installed. If not, you can install it using `npm install -g yarn`.
32 | 2. Run `yarn dev` in the `app` folder, to start the development server for the Vue.js application.
33 | 3. Enter the calimero node URL you got from the first step and click `Connect`
34 | 4. Run another instance of the UI and connect to another node.
35 | 5. Now you have two players that can start playing the game!
36 |
37 |
--------------------------------------------------------------------------------
/app/src/components/LeaderBoard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
72 |
--------------------------------------------------------------------------------
/app/src/components/icons/IconEcosystem.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/logic/leaderboard/tests/sandbox.rs:
--------------------------------------------------------------------------------
1 | use near_sdk::json_types::U128;
2 | use near_sdk::NearToken;
3 | use serde_json::json;
4 |
5 | #[tokio::test]
6 | async fn test_score_board_contract() -> Result<(), Box> {
7 | let sandbox = near_workspaces::sandbox().await?;
8 | let wasm = tokio::fs::read("res/leaderboard.wasm").await?;
9 |
10 | let contract = sandbox.dev_deploy(&wasm).await?;
11 |
12 | let alice_account = sandbox.dev_create_account().await?;
13 | let bob_account = sandbox.dev_create_account().await?;
14 |
15 | let alice_outcome = alice_account
16 | .call(contract.id(), "add_score")
17 | .args_json(json!({"app_name": "test_app", "account_id": alice_account.id(), "score": "10"}))
18 | .deposit(NearToken::from_near(0))
19 | .transact()
20 | .await?;
21 |
22 | assert!(alice_outcome.is_success());
23 |
24 | let score: Option = contract
25 | .view("get_score")
26 | .args_json(json!({"app_name": "test_app", "account_id": alice_account.id()}))
27 | .await?
28 | .json()?;
29 |
30 | assert_eq!(score, Some(U128(10)));
31 |
32 | let score: Option = contract
33 | .view("get_score")
34 | .args_json(json!({"app_name": "test_app", "account_id": bob_account.id()}))
35 | .await?
36 | .json()?;
37 |
38 | assert_eq!(score, None);
39 |
40 | let alice_outcome = alice_account
41 | .call(contract.id(), "add_score")
42 | .args_json(
43 | json!({"app_name": "test_app_2", "account_id": alice_account.id(), "score": "100"}),
44 | )
45 | .deposit(NearToken::from_near(0))
46 | .transact()
47 | .await?;
48 |
49 | assert!(alice_outcome.is_success());
50 |
51 | let score: Option = contract
52 | .view("get_score")
53 | .args_json(json!({"app_name": "test_app", "account_id": alice_account.id()}))
54 | .await?
55 | .json()?;
56 | assert_eq!(score, Some(U128(10)));
57 |
58 | let score: Option = contract
59 | .view("get_score")
60 | .args_json(json!({"app_name": "test_app_2", "account_id": alice_account.id()}))
61 | .await?
62 | .json()?;
63 | assert_eq!(score, Some(U128(100)));
64 |
65 | Ok(())
66 | }
67 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/key.rs:
--------------------------------------------------------------------------------
1 | use calimero_sdk::serde::{Deserialize, Serialize};
2 | use ed25519_dalek::{Signature, SigningKey, VerifyingKey};
3 |
4 | use crate::repr::{Repr, ReprBytes};
5 | use crate::Commitment;
6 |
7 | #[derive(Debug, Serialize, Deserialize)]
8 | #[serde(crate = "calimero_sdk::serde")]
9 | pub struct KeyComponents {
10 | pub pk: Repr,
11 | pub sk: Repr,
12 | }
13 |
14 | impl ReprBytes for VerifyingKey {
15 | type Bytes = [u8; 32];
16 |
17 | fn to_bytes(&self) -> Self::Bytes {
18 | self.to_bytes()
19 | }
20 |
21 | fn from_bytes(f: F) -> Option>
22 | where
23 | F: FnOnce(&mut Self::Bytes) -> Option,
24 | {
25 | let mut bytes = [0; 32];
26 | if let Some(err) = f(&mut bytes) {
27 | return Some(Err(err));
28 | }
29 | Some(Ok(VerifyingKey::from_bytes(&bytes).ok()?))
30 | }
31 | }
32 |
33 | impl ReprBytes for SigningKey {
34 | type Bytes = [u8; 32];
35 |
36 | fn to_bytes(&self) -> Self::Bytes {
37 | self.to_bytes()
38 | }
39 |
40 | fn from_bytes(f: F) -> Option>
41 | where
42 | F: FnOnce(&mut Self::Bytes) -> Option,
43 | {
44 | let mut bytes = [0; 32];
45 |
46 | Some(f(&mut bytes).map_or_else(|| Ok(SigningKey::from_bytes(&bytes)), Err))
47 | }
48 | }
49 |
50 | impl ReprBytes for Signature {
51 | type Bytes = [u8; 64];
52 |
53 | fn to_bytes(&self) -> Self::Bytes {
54 | self.to_bytes()
55 | }
56 |
57 | fn from_bytes(f: F) -> Option>
58 | where
59 | F: FnOnce(&mut Self::Bytes) -> Option,
60 | {
61 | let mut bytes = [0; 64];
62 |
63 | Some(f(&mut bytes).map_or_else(|| Ok(Signature::from_bytes(&bytes)), Err))
64 | }
65 | }
66 |
67 | impl ReprBytes for Commitment {
68 | type Bytes = [u8; 32];
69 |
70 | fn to_bytes(&self) -> Self::Bytes {
71 | self.to_bytes()
72 | }
73 |
74 | fn from_bytes(f: F) -> Option>
75 | where
76 | F: FnOnce(&mut Self::Bytes) -> Option,
77 | {
78 | let mut bytes = [0; 32];
79 |
80 | Some(f(&mut bytes).map_or_else(|| Ok(Commitment::from_bytes(&bytes)), Err))
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/assets/base.css:
--------------------------------------------------------------------------------
1 | /* color palette from */
2 | :root {
3 | --vt-c-white: #ffffff;
4 | --vt-c-white-soft: #f8f8f8;
5 | --vt-c-white-mute: #f2f2f2;
6 |
7 | --vt-c-black: #181818;
8 | --vt-c-black-soft: #222222;
9 | --vt-c-black-mute: #282828;
10 |
11 | --vt-c-indigo: #2c3e50;
12 |
13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17 |
18 | --vt-c-text-light-1: var(--vt-c-indigo);
19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20 | --vt-c-text-dark-1: var(--vt-c-white);
21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22 | }
23 |
24 | /* semantic color variables for this project */
25 | :root {
26 | --color-background: var(--vt-c-white);
27 | --color-background-soft: var(--vt-c-white-soft);
28 | --color-background-mute: var(--vt-c-white-mute);
29 |
30 | --color-border: var(--vt-c-divider-light-2);
31 | --color-border-hover: var(--vt-c-divider-light-1);
32 |
33 | --color-heading: var(--vt-c-text-light-1);
34 | --color-text: var(--vt-c-text-light-1);
35 |
36 | --section-gap: 160px;
37 | }
38 |
39 | @media (prefers-color-scheme: dark) {
40 | :root {
41 | --color-background: var(--vt-c-black);
42 | --color-background-soft: var(--vt-c-black-soft);
43 | --color-background-mute: var(--vt-c-black-mute);
44 |
45 | --color-border: var(--vt-c-divider-dark-2);
46 | --color-border-hover: var(--vt-c-divider-dark-1);
47 |
48 | --color-heading: var(--vt-c-text-dark-1);
49 | --color-text: var(--vt-c-text-dark-2);
50 | }
51 | }
52 |
53 | *,
54 | *::before,
55 | *::after {
56 | box-sizing: border-box;
57 | margin: 0;
58 | font-weight: normal;
59 | }
60 |
61 | body {
62 | min-height: 100vh;
63 | color: var(--color-text);
64 | background: var(--color-background);
65 | transition:
66 | color 0.5s,
67 | background-color 0.5s;
68 | line-height: 1.6;
69 | font-family:
70 | Inter,
71 | -apple-system,
72 | BlinkMacSystemFont,
73 | 'Segoe UI',
74 | Roboto,
75 | Oxygen,
76 | Ubuntu,
77 | Cantarell,
78 | 'Fira Sans',
79 | 'Droid Sans',
80 | 'Helvetica Neue',
81 | sans-serif;
82 | font-size: 15px;
83 | text-rendering: optimizeLegibility;
84 | -webkit-font-smoothing: antialiased;
85 | -moz-osx-font-smoothing: grayscale;
86 | }
87 |
--------------------------------------------------------------------------------
/logic/leaderboard/src/lib.rs:
--------------------------------------------------------------------------------
1 | use std::collections::BTreeMap;
2 |
3 | use near_sdk::json_types::U128;
4 | use near_sdk::near;
5 | use near_sdk::store::{LookupMap, UnorderedMap};
6 |
7 | type UserName = String;
8 |
9 | #[near(contract_state)]
10 | pub struct LeaderBoard {
11 | scores: LookupMap>, // Key is app name, value is the leaderboard itself
12 | }
13 |
14 | impl Default for LeaderBoard {
15 | fn default() -> Self {
16 | Self {
17 | scores: LookupMap::new(b"m"),
18 | }
19 | }
20 | }
21 |
22 | #[near]
23 | impl LeaderBoard {
24 | pub fn add_score(&mut self, app_name: String, account_id: UserName, score: U128) {
25 | let app_leaderboard = self
26 | .scores
27 | .entry(app_name.clone())
28 | .or_insert_with(|| UnorderedMap::new(app_name.as_bytes()));
29 |
30 | let new_score = app_leaderboard.entry(account_id.clone()).or_default().0 + score.0;
31 | app_leaderboard.insert(account_id, U128(new_score));
32 | }
33 |
34 | pub fn get_score(&self, app_name: String, account_id: UserName) -> Option {
35 | self.scores
36 | .get(&app_name)?
37 | .get(&account_id)
38 | .map(|score| score.clone())
39 | }
40 |
41 | pub fn get_scores(&self, app_name: String) -> Option> {
42 | let mut map = BTreeMap::new();
43 | for (k, v) in self.scores.get(&app_name)? {
44 | map.insert(k.to_string(), v.0);
45 | }
46 | Some(map)
47 | }
48 | }
49 |
50 | #[cfg(test)]
51 | mod tests {
52 | use super::*;
53 |
54 | #[test]
55 | fn add_score() {
56 | let mut leader_board = LeaderBoard::default();
57 | let account = "alice.testnet".to_string();
58 | leader_board.add_score("test_app".to_string(), account.clone(), U128(10));
59 |
60 | let score = leader_board.get_score("test_app".to_string(), account);
61 | assert_eq!(score, Some(U128(10)));
62 | }
63 |
64 | #[test]
65 | fn get_score_of_absent_account() {
66 | let mut leader_board = LeaderBoard::default();
67 | let account = "alice.testnet".to_string();
68 | leader_board.add_score("test_app".to_string(), account.clone(), U128(10));
69 |
70 | let bob_account = "bob.testnet".to_string();
71 |
72 | let score = leader_board.get_score("test_app".to_string(), bob_account);
73 | assert_eq!(score, None);
74 | }
75 |
76 | #[test]
77 | fn get_score_of_absent_app() {
78 | let mut leader_board = LeaderBoard::default();
79 | let account = "alice.testnet".to_string();
80 | leader_board.add_score("test_app".to_string(), account.clone(), U128(10));
81 |
82 | let score = leader_board.get_score("test_app_2".to_string(), account);
83 | assert_eq!(score, None);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/repr.rs:
--------------------------------------------------------------------------------
1 | use std::marker::PhantomData;
2 | use std::ops::Deref;
3 | use std::{fmt, io};
4 |
5 | use bs58::decode::DecodeTarget;
6 | use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
7 | use calimero_sdk::serde::{de, ser, Deserialize, Serialize};
8 |
9 | #[derive(Eq, Copy, Clone, PartialEq)]
10 | pub enum Bs58 {}
11 |
12 | #[derive(Eq, Copy, Clone, PartialEq)]
13 | pub enum Raw {}
14 |
15 | mod private {
16 | pub trait Sealed {}
17 | }
18 |
19 | pub trait ReprFormat: private::Sealed {}
20 |
21 | impl private::Sealed for Bs58 {}
22 | impl ReprFormat for Bs58 {}
23 |
24 | impl private::Sealed for Raw {}
25 | impl ReprFormat for Raw {}
26 |
27 | #[derive(Eq, Copy, Clone, PartialEq)]
28 | pub struct Repr {
29 | data: T,
30 | _phantom: PhantomData,
31 | }
32 |
33 | pub trait ReprBytes {
34 | type Bytes: AsRef<[u8]>;
35 |
36 | fn to_bytes(&self) -> Self::Bytes;
37 | fn from_bytes(f: F) -> Option>
38 | where
39 | F: FnOnce(&mut Self::Bytes) -> Option,
40 | Self: Sized;
41 | }
42 |
43 | impl From for Repr {
44 | fn from(data: T) -> Self {
45 | Repr {
46 | data,
47 | _phantom: PhantomData,
48 | }
49 | }
50 | }
51 |
52 | impl From> for Repr {
53 | fn from(repr: Repr) -> Self {
54 | Repr {
55 | data: repr.data,
56 | _phantom: PhantomData,
57 | }
58 | }
59 | }
60 |
61 | impl Deref for Repr {
62 | type Target = T;
63 |
64 | fn deref(&self) -> &Self::Target {
65 | &self.data
66 | }
67 | }
68 |
69 | impl Default for Repr {
70 | fn default() -> Self {
71 | Repr::from(T::default())
72 | }
73 | }
74 |
75 | impl fmt::Debug for Repr {
76 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 | self.data.fmt(f)
78 | }
79 | }
80 |
81 | impl Serialize for Repr {
82 | fn serialize(&self, serializer: S) -> Result
83 | where
84 | S: ser::Serializer,
85 | {
86 | let bytes = self.data.to_bytes();
87 | let encoded = bs58::encode(bytes).into_string();
88 | serializer.serialize_str(&encoded)
89 | }
90 | }
91 |
92 | impl<'de, T: ReprBytes> Deserialize<'de> for Repr
93 | where
94 | T::Bytes: DecodeTarget,
95 | {
96 | fn deserialize(deserializer: D) -> Result
97 | where
98 | D: de::Deserializer<'de>,
99 | {
100 | let encoded = ::deserialize(deserializer)?;
101 |
102 | let data = match T::from_bytes(|bytes| bs58::decode(&encoded).onto(bytes).err()) {
103 | Some(data) => data.map_err(de::Error::custom)?,
104 | None => return Err(de::Error::custom("Invalid key")),
105 | };
106 |
107 | Ok(Repr::from(data))
108 | }
109 | }
110 |
111 | impl BorshSerialize for Repr
112 | where
113 | T::Bytes: BorshSerialize,
114 | {
115 | fn serialize(&self, writer: &mut W) -> Result<(), io::Error> {
116 | self.data.to_bytes().serialize(writer)
117 | }
118 | }
119 |
120 | impl BorshDeserialize for Repr
121 | where
122 | T::Bytes: BorshDeserialize,
123 | {
124 | fn deserialize_reader(reader: &mut R) -> io::Result {
125 | let bytes = T::Bytes::deserialize_reader(reader)?;
126 |
127 | let data = match T::from_bytes(|data| {
128 | *data = bytes;
129 |
130 | None::<()>
131 | }) {
132 | Some(data) => unsafe { data.unwrap_unchecked() },
133 | None => return Err(io::ErrorKind::InvalidData.into()),
134 | };
135 |
136 | Ok(Repr::from(data))
137 | }
138 | }
139 |
140 | impl BorshSerialize for Repr {
141 | fn serialize(&self, writer: &mut W) -> Result<(), io::Error> {
142 | self.data.serialize(writer)
143 | }
144 | }
145 |
146 | impl BorshDeserialize for Repr {
147 | fn deserialize_reader(reader: &mut R) -> io::Result {
148 | let data = T::deserialize_reader(reader)?;
149 |
150 | Ok(Repr::from(data))
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/logic/leaderboard/relayer/relayer.js:
--------------------------------------------------------------------------------
1 | const nearAPI = require('near-api-js');
2 | const fs = require('fs');
3 | const commandLineArgs = require('command-line-args');
4 | const GameEventListener = require('./ws');
5 |
6 | const { Contract } = nearAPI;
7 |
8 | const createKeyStore = async () => {
9 | const { KeyPair, keyStores } = nearAPI;
10 |
11 | const ACCOUNT_ID = 'highfalutin-act.testnet';
12 | const NETWORK_ID = 'testnet';
13 | const KEY_PATH =
14 | '/home/saeed/.near-credentials/testnet/highfalutin-act.testnet.json';
15 |
16 | const credentials = JSON.parse(fs.readFileSync(KEY_PATH));
17 | const myKeyStore = new keyStores.InMemoryKeyStore();
18 | myKeyStore.setKey(
19 | NETWORK_ID,
20 | ACCOUNT_ID,
21 | KeyPair.fromString(credentials.private_key)
22 | );
23 |
24 | return myKeyStore;
25 | };
26 |
27 | let keyStore;
28 | const connectToNear = async () => {
29 | keyStore = await createKeyStore();
30 | const connectionConfig = {
31 | networkId: 'testnet',
32 | keyStore,
33 | nodeUrl: 'https://rpc.testnet.near.org',
34 | walletUrl: 'https://testnet.mynearwallet.com/',
35 | helperUrl: 'https://helper.testnet.near.org',
36 | explorerUrl: 'https://testnet.nearblocks.io',
37 | };
38 | const { connect } = nearAPI;
39 | const nearConnection = await connect(connectionConfig);
40 | return nearConnection;
41 | };
42 |
43 | const addScore = async (account_id, app_name, score) => {
44 | if (contract === null) {
45 | throw new Error('Contract is not initialized');
46 | }
47 |
48 | const account = await near.account('highfalutin-act.testnet');
49 | await contract.add_score({
50 | signerAccount: account,
51 | args: {
52 | app_name,
53 | account_id,
54 | score,
55 | },
56 | });
57 | };
58 |
59 | const getScore = async (account_id, app_name) => {
60 | if (contract === null) {
61 | throw new Error('Contract is not initialized');
62 | }
63 |
64 | return await contract.get_score({
65 | app_name,
66 | account_id,
67 | });
68 | };
69 |
70 | const getScores = async (app_name) => {
71 | if (contract === null) {
72 | throw new Error('Contract is not initialized');
73 | }
74 |
75 | return await contract.get_scores({
76 | app_name,
77 | });
78 | };
79 |
80 | let contract = null;
81 | let near = null;
82 |
83 | async function main() {
84 | const optionDefinitions = [
85 | { name: 'subscribe', type: Boolean },
86 | { name: 'add-score', type: Boolean },
87 | { name: 'get-score', type: Boolean },
88 | { name: 'get-scores', type: Boolean },
89 | { name: 'account', type: String },
90 | { name: 'score', type: Number },
91 | { name: 'app', type: String },
92 | { name: 'applicationId', type: String },
93 | { name: 'nodeUrl', type: String },
94 | ];
95 |
96 | const options = commandLineArgs(optionDefinitions);
97 |
98 | const nearConnection = await connectToNear();
99 | near = nearConnection;
100 | contract = new Contract(
101 | nearConnection.connection,
102 | 'highfalutin-act.testnet',
103 | {
104 | changeMethods: ['add_score'],
105 | viewMethods: ['get_version', 'get_score', 'get_scores'],
106 | }
107 | );
108 | if (options.subscribe) {
109 | const { applicationId, nodeUrl } = options;
110 | console.log(`Subscribed for the events of ${applicationId}`);
111 | subscribe(applicationId, nodeUrl);
112 | } else if (options['add-score']) {
113 | const { account, app, score } = options;
114 | await addScore(account, app, score);
115 | console.log(
116 | `Score added for account: ${account}, app: ${app}, score: ${score}`
117 | );
118 | } else if (options['get-score']) {
119 | const { account, app } = options;
120 | const score = await getScore(account, app);
121 | console.log(`${account} score is: ${score}`);
122 | } else if (options['get-scores']) {
123 | const { app } = options;
124 | const scores = await getScores(app);
125 | console.log(`Scores for ${app}: ${JSON.stringify(scores)}`);
126 | }
127 | }
128 |
129 | let eventListener;
130 | let players = {};
131 | const subscribe = (applicationId, nodeUrl) => {
132 | eventListener = new GameEventListener(nodeUrl, applicationId);
133 | eventListener.on('NewPlayer', (player) => {
134 | players[player.id] = player.name;
135 | });
136 |
137 | eventListener.on('GameOver', (winner) => {
138 | addScore(players[winner.winner], 'rsp', 1000).then(() =>
139 | console.log(`Score added for ${players[winner.winner]}`)
140 | ).catch(e => {
141 | console.error(`Failed to add the score. ${e}`);
142 | });
143 | });
144 | };
145 |
146 | main().catch((error) => {
147 | console.error(error);
148 | process.exitCode = 1;
149 | });
150 |
--------------------------------------------------------------------------------
/app/src/game.ts:
--------------------------------------------------------------------------------
1 | import {
2 | JsonRpcClient,
3 | type RequestConfig,
4 | type RpcQueryResponse,
5 | type RpcResult
6 | } from '@calimero-is-near/calimero-p2p-sdk/lib'
7 | import { createAuthHeader, type AxiosHeader } from './crypto'
8 |
9 | interface VersionRequest {
10 | // ignore
11 | }
12 |
13 | interface CreateKeyPairRequest {
14 | seed: number[]
15 | }
16 |
17 | interface KeyComponents {
18 | pk: string
19 | sk: string
20 | }
21 |
22 | interface PrepareRequest {
23 | signing_key: string
24 | choice: string
25 | nonce: number[]
26 | }
27 |
28 | interface JoinRequest {
29 | player_name: string
30 | public_key: string
31 | }
32 |
33 | interface CommitRequest {
34 | player_idx: number
35 | commitment: string
36 | signature: string
37 | }
38 |
39 | interface ResetRequest {
40 | player_idx: number
41 | commitment: string
42 | signature: string
43 | }
44 |
45 | export class Game {
46 | constructor(nodeUrl: string, applicationId: string) {
47 | this.applicationId = applicationId
48 | this.seed = new Uint8Array(32)
49 | crypto.getRandomValues(this.seed)
50 | this.nonce = new Uint8Array(32)
51 | crypto.getRandomValues(this.nonce)
52 | this.jsonRpcClient = new JsonRpcClient(nodeUrl, '/jsonrpc')
53 | }
54 |
55 | async query(
56 | method: string,
57 | params: Args
58 | ): Promise>> {
59 | const authHeaders: AxiosHeader | null = await createAuthHeader(JSON.stringify(params))
60 | if (authHeaders === null) {
61 | throw new Error('Failed to getVersion')
62 | }
63 | console.log('*****************************')
64 | console.log(authHeaders)
65 | console.log('*****************************')
66 | const config: RequestConfig = {
67 | headers: authHeaders,
68 | timeout: 10000
69 | }
70 | return this.jsonRpcClient.query(
71 | {
72 | method,
73 | applicationId: this.applicationId,
74 | argsJson: params
75 | },
76 | config
77 | )
78 | }
79 |
80 | async mutate(
81 | method: string,
82 | params: Args
83 | ): Promise>> {
84 | const authHeaders: AxiosHeader | null = await createAuthHeader(JSON.stringify(params))
85 | if (authHeaders === null) {
86 | throw new Error('Failed to getVersion')
87 | }
88 | const config: RequestConfig = {
89 | headers: authHeaders,
90 | timeout: 10000
91 | }
92 | return this.jsonRpcClient.mutate(
93 | {
94 | method,
95 | applicationId: this.applicationId,
96 | argsJson: params
97 | },
98 | config
99 | )
100 | }
101 |
102 | async getVersion(): Promise {
103 | const params: VersionRequest = {}
104 | const response = await this.query('version', params)
105 | return response.result?.output
106 | }
107 |
108 | async reset() {
109 | if (!(this.playerIdx && this.commitment && this.signature)) {
110 | throw new Error('Unable to call reset.')
111 | }
112 |
113 | await this.mutate('reset', {
114 | player_idx: this.playerIdx,
115 | commitment: this.commitment,
116 | signature: this.signature
117 | })
118 | }
119 |
120 | async join(playerName: string): Promise {
121 | const params: CreateKeyPairRequest = {
122 | seed: Array.from(this.seed)
123 | }
124 | const keysResponse = await this.query(
125 | 'create_keypair',
126 | params
127 | )
128 |
129 | const keys = keysResponse.result?.output
130 | this.keys = keys
131 |
132 | const joinParams: JoinRequest = {
133 | player_name: playerName,
134 | public_key: keys!.pk
135 | }
136 | const joinResponse = await this.mutate('join', joinParams)
137 |
138 | this.playerIdx = joinResponse.result?.output
139 | return this.playerIdx
140 | }
141 |
142 | async submit(choice: string) {
143 | const params: PrepareRequest = {
144 | signing_key: this.keys!.sk,
145 | choice,
146 | nonce: Array.from(this.nonce)
147 | }
148 | const prepareResponse = await this.query('prepare', params)
149 |
150 | this.commitment = prepareResponse.result?.output![0]
151 | this.signature = prepareResponse.result?.output![1]
152 | await this.mutate('commit', {
153 | player_idx: this.playerIdx!,
154 | commitment: this.commitment!,
155 | signature: this.signature!
156 | })
157 | }
158 |
159 | async reveal() {
160 | await this.mutate('reveal', {
161 | player_idx: this.playerIdx,
162 | nonce: Array.from(this.nonce)
163 | })
164 | }
165 |
166 | async hardReset() {
167 | await this.mutate('reset_state', {})
168 | }
169 |
170 | applicationId: string
171 | seed: Uint8Array
172 | nonce: Uint8Array
173 | jsonRpcClient: JsonRpcClient
174 | keys: KeyComponents | undefined
175 | commitment: string | undefined
176 | signature: string | undefined
177 | playerIdx: number | undefined
178 | }
179 |
--------------------------------------------------------------------------------
/app/src/components/PlayGame.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 | Connect
21 | Login
24 |
25 |
26 |
27 |
Game Version:
28 |
{{ gameVersion }}
29 |
30 |
31 |
32 | Join
35 | Reset
36 |
37 |
38 |
Player ID:
39 |
{{ playerId }}
40 |
41 |
42 |
Opponent:
43 |
44 | Not joined
45 | {{ players[1 - playerId] }}
46 |
50 | Not commited!
51 |
52 | Commited
53 |
57 | Not Revealed!
58 |
59 | Revealed
60 |
61 |
62 |
63 |
75 |
76 | Commit
77 | Reset
78 |
79 |
80 | You won the game 🎉🎊
81 | You lost the game 🥲
82 |
83 |
84 |
85 |
86 |
201 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/src/lib.rs:
--------------------------------------------------------------------------------
1 | use std::cmp::Ordering;
2 |
3 | use calimero_sdk::app;
4 | use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
5 | use calimero_sdk::serde::{Deserialize, Serialize};
6 | use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
7 | use rand_chacha::rand_core::SeedableRng;
8 | use rand_chacha::ChaCha20Rng;
9 |
10 | mod choice;
11 | mod commitment;
12 | mod errors;
13 | mod key;
14 | mod player_idx;
15 | mod repr;
16 |
17 | use crate::commitment::Commitment;
18 | use crate::commitment::Nonce;
19 |
20 | use choice::Choice;
21 | use errors::{CommitError, JoinError, ResetError, RevealError};
22 | use key::KeyComponents;
23 | use player_idx::PlayerIdx;
24 | use repr::Repr;
25 |
26 | #[app::state(emits = for<'a> Event<'a>)]
27 | #[derive(Default, Debug, BorshSerialize, BorshDeserialize)]
28 | #[borsh(crate = "calimero_sdk::borsh")]
29 | struct Game {
30 | players: [Option; 2],
31 | }
32 |
33 | #[derive(Default, Debug, BorshSerialize, BorshDeserialize)]
34 | #[borsh(crate = "calimero_sdk::borsh")]
35 | struct Player {
36 | state: Option,
37 | public_key: Repr,
38 | name: String,
39 | }
40 |
41 | #[derive(Debug, Clone, PartialEq, BorshSerialize, BorshDeserialize, Deserialize, Serialize)]
42 | #[borsh(crate = "calimero_sdk::borsh")]
43 | #[serde(crate = "calimero_sdk::serde")]
44 | enum State {
45 | Committed(Repr),
46 | Revealed(Choice),
47 | }
48 |
49 | #[app::event]
50 | pub enum Event<'a> {
51 | PlayerCommited { id: PlayerIdx },
52 | NewPlayer { id: PlayerIdx, name: &'a str },
53 | PlayerRevealed { id: PlayerIdx, reveal: &'a Choice },
54 | GameOver { winner: Option },
55 | StateDumped,
56 | }
57 |
58 | pub type Seed = [u8; 32];
59 |
60 | #[app::logic]
61 | impl Game {
62 | #[app::init]
63 | pub fn init() -> Game {
64 | Game::default()
65 | }
66 |
67 | pub fn create_keypair(seed: Seed) -> KeyComponents {
68 | let mut csprng = ChaCha20Rng::from_seed(seed);
69 |
70 | let keypair = SigningKey::generate(&mut csprng);
71 |
72 | KeyComponents {
73 | pk: Repr::from(keypair.verifying_key()),
74 | sk: Repr::from(keypair),
75 | }
76 | }
77 |
78 | pub fn join(
79 | &mut self,
80 | player_name: String,
81 | public_key: Repr,
82 | ) -> Result {
83 | let Some((index, player)) = self
84 | .players
85 | .iter_mut()
86 | .enumerate()
87 | .find(|(_, player)| player.is_none())
88 | else {
89 | return Err(JoinError::GameFull);
90 | };
91 |
92 | app::emit!(Event::NewPlayer {
93 | id: PlayerIdx(index),
94 | name: &player_name
95 | });
96 |
97 | *player = Some(Player {
98 | state: None,
99 | public_key: Repr::from(public_key),
100 | name: player_name,
101 | });
102 |
103 | Ok(index)
104 | }
105 |
106 | pub fn state(&self) -> [Option<(&str, &State)>; 2] {
107 | let mut states = [None, None];
108 |
109 | for (i, player) in self.players.iter().enumerate() {
110 | if let Some(Player {
111 | state: Some(state),
112 | name,
113 | ..
114 | }) = player
115 | {
116 | states[i] = Some((name.as_str(), state));
117 | }
118 | }
119 |
120 | states
121 | }
122 |
123 | pub fn prepare(
124 | signing_key: Repr,
125 | choice: Choice,
126 | nonce: Nonce,
127 | ) -> (Repr, Repr) {
128 | let commitment = Commitment::of(choice, &nonce);
129 |
130 | let signature = signing_key.sign(commitment.as_ref());
131 |
132 | (Repr::from(commitment), Repr::from(signature))
133 | }
134 |
135 | fn players(&mut self, my_idx: PlayerIdx) -> (Option<&mut Player>, Option<&mut Player>) {
136 | let [a, b] = self.players.each_mut();
137 | if my_idx.is_first() {
138 | return (a.as_mut(), b.as_mut());
139 | }
140 | (b.as_mut(), a.as_mut())
141 | }
142 |
143 | pub fn commit_result(
144 | &mut self,
145 | player_idx: PlayerIdx,
146 | commitment: Repr,
147 | signature: Repr,
148 | ) -> Result<(), CommitError> {
149 | let (Some(player), Some(_)) = self.players(player_idx) else {
150 | return Err(CommitError::NotReady);
151 | };
152 |
153 | if player.state.is_some() {
154 | return Err(CommitError::AlreadyCommitted);
155 | }
156 |
157 | player
158 | .public_key
159 | .verify(commitment.as_ref(), &signature)
160 | .map_err(|_| CommitError::InvalidSignature)?;
161 |
162 | app::emit!(Event::PlayerCommited { id: player_idx });
163 |
164 | player.state = Some(State::Committed(commitment));
165 |
166 | Ok(())
167 | }
168 |
169 | pub fn reveal(&mut self, player_idx: PlayerIdx, nonce: Nonce) -> Result<(), RevealError> {
170 | let (Some(player), Some(other_player)) = self.players(player_idx) else {
171 | return Err(RevealError::NotReady);
172 | };
173 |
174 | let Some(State::Committed(commitment)) = &player.state else {
175 | return Err(RevealError::NotCommitted);
176 | };
177 |
178 | let choice = Choice::determine(commitment, &nonce).ok_or(RevealError::InvalidNonce)?;
179 |
180 | app::emit!(Event::PlayerRevealed {
181 | id: player_idx,
182 | reveal: &choice
183 | });
184 |
185 | player.state = Some(State::Revealed(choice));
186 |
187 | if let Some(State::Revealed(other)) = &other_player.state {
188 | match choice.partial_cmp(other) {
189 | Some(Ordering::Less) => app::emit!(Event::GameOver {
190 | winner: Some(player_idx.other())
191 | }),
192 | Some(Ordering::Equal) => app::emit!(Event::GameOver { winner: None }),
193 | Some(Ordering::Greater) => app::emit!(Event::GameOver {
194 | winner: Some(player_idx)
195 | }),
196 | None => {}
197 | }
198 | }
199 |
200 | Ok(())
201 | }
202 |
203 | pub fn reset(
204 | &mut self,
205 | player_idx: PlayerIdx,
206 | commitment: Repr,
207 | signature: Repr,
208 | ) -> Result<(), ResetError> {
209 | let (Some(player), _) = self.players(player_idx) else {
210 | return Err(ResetError::NotReady);
211 | };
212 |
213 | player
214 | .public_key
215 | .verify(commitment.as_ref(), &signature)
216 | .map_err(|_| ResetError::InvalidSignature)?;
217 |
218 | self.players = Default::default();
219 |
220 | app::emit!(Event::StateDumped);
221 |
222 | Ok(())
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/logic/leaderboard/relayer/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@near-js/accounts@1.2.0":
6 | version "1.2.0"
7 | resolved "https://registry.yarnpkg.com/@near-js/accounts/-/accounts-1.2.0.tgz#d0ffe0ddd976c04b0f27122d4bd737202fb82747"
8 | integrity sha512-0D/Tl7i2rqqVydGwu9zWBFOk6P7t4Zs2Gfo7l+8jNjOoioYsH/YCWaOheoH7SVu4wQ3xP9YEyjvZ8JL6xzYyHA==
9 | dependencies:
10 | "@near-js/crypto" "1.2.3"
11 | "@near-js/providers" "0.2.1"
12 | "@near-js/signers" "0.1.3"
13 | "@near-js/transactions" "1.2.1"
14 | "@near-js/types" "0.2.0"
15 | "@near-js/utils" "0.2.1"
16 | borsh "1.0.0"
17 | depd "2.0.0"
18 | is-my-json-valid "^2.20.6"
19 | lru_map "0.4.1"
20 | near-abi "0.1.1"
21 |
22 | "@near-js/crypto@1.2.3":
23 | version "1.2.3"
24 | resolved "https://registry.yarnpkg.com/@near-js/crypto/-/crypto-1.2.3.tgz#ba318d77b9eed79ef92a86f7a2c84562cb2f6b9d"
25 | integrity sha512-BuNE+tdcxwImxktFtuAxLiVejFDtn1X92kejcDcYc6f7e0ku9yMntdw98LMb+5ls+xlRuF1UDoi/hUF1LPVpyQ==
26 | dependencies:
27 | "@near-js/types" "0.2.0"
28 | "@near-js/utils" "0.2.1"
29 | "@noble/curves" "1.2.0"
30 | borsh "1.0.0"
31 | randombytes "2.1.0"
32 |
33 | "@near-js/keystores-browser@0.0.11":
34 | version "0.0.11"
35 | resolved "https://registry.yarnpkg.com/@near-js/keystores-browser/-/keystores-browser-0.0.11.tgz#dc0dab662fb2045f978fe1c725f03f0fd11f8267"
36 | integrity sha512-AQ86ST+keKjM5iektKLXu3q94lN8pG6R/LXVoIgm5/hi63n2QzhAd0XlUj9fcyPrfoGOckwUu6pFtXPbveBypw==
37 | dependencies:
38 | "@near-js/crypto" "1.2.3"
39 | "@near-js/keystores" "0.0.11"
40 |
41 | "@near-js/keystores-node@0.0.11":
42 | version "0.0.11"
43 | resolved "https://registry.yarnpkg.com/@near-js/keystores-node/-/keystores-node-0.0.11.tgz#b711c6fc0451d4115936734690e08de51e440ef4"
44 | integrity sha512-KeBl7oL8AwUwTilYPV3apEcL1P+UMAGJQvmkEFl9lyK7mftyjogehdqjqFREAdQpR+4jX5NXvU8ZJIShebK3ZA==
45 | dependencies:
46 | "@near-js/crypto" "1.2.3"
47 | "@near-js/keystores" "0.0.11"
48 |
49 | "@near-js/keystores@0.0.11":
50 | version "0.0.11"
51 | resolved "https://registry.yarnpkg.com/@near-js/keystores/-/keystores-0.0.11.tgz#570c70c4c5bb6ba64a94b8bff4cc71cc23265aec"
52 | integrity sha512-B/VkSNIT8vxMozDbK9O54YQGa4JT/rFnB0W+0cN3na38sQHdvzK015X2RHK8mfS0isP/iIT9QzIQtYZcI3M83Q==
53 | dependencies:
54 | "@near-js/crypto" "1.2.3"
55 | "@near-js/types" "0.2.0"
56 |
57 | "@near-js/providers@0.2.1":
58 | version "0.2.1"
59 | resolved "https://registry.yarnpkg.com/@near-js/providers/-/providers-0.2.1.tgz#1d195638b07fd542e202a61dd8c571034ec7cd62"
60 | integrity sha512-F5ZVlXynGopg3BjK3ihyA28tnOk/cM7kUhc/bw5aJg+m+oa1yuBkaAp9JbihagbLZpWOZiDJmkrdkpvTvQlHag==
61 | dependencies:
62 | "@near-js/transactions" "1.2.1"
63 | "@near-js/types" "0.2.0"
64 | "@near-js/utils" "0.2.1"
65 | borsh "1.0.0"
66 | http-errors "1.7.2"
67 | optionalDependencies:
68 | node-fetch "2.6.7"
69 |
70 | "@near-js/signers@0.1.3":
71 | version "0.1.3"
72 | resolved "https://registry.yarnpkg.com/@near-js/signers/-/signers-0.1.3.tgz#7ac9c630536457c3cd94c4faf901b7033a76b6bc"
73 | integrity sha512-Eim6ZsQUgsaSzi+oyR9cQesOO2QcZmhK+tawZan1vni8y+JvKnSH6r3krzbtvKWqIlx/kJ+PsIV74YIxPY5Uhw==
74 | dependencies:
75 | "@near-js/crypto" "1.2.3"
76 | "@near-js/keystores" "0.0.11"
77 | "@noble/hashes" "1.3.3"
78 |
79 | "@near-js/transactions@1.2.1":
80 | version "1.2.1"
81 | resolved "https://registry.yarnpkg.com/@near-js/transactions/-/transactions-1.2.1.tgz#f9a304cd2a35f292557c3764473127b231c06892"
82 | integrity sha512-w2EXgTRXJ+Zxqh8lVnQuRnpCEm6Cq7NxqAcfH6x0BPuSXye5kR9d0n2ut8AGkSXWeooKKEUnDhi6UcXadfoerg==
83 | dependencies:
84 | "@near-js/crypto" "1.2.3"
85 | "@near-js/signers" "0.1.3"
86 | "@near-js/types" "0.2.0"
87 | "@near-js/utils" "0.2.1"
88 | "@noble/hashes" "1.3.3"
89 | borsh "1.0.0"
90 |
91 | "@near-js/types@0.2.0":
92 | version "0.2.0"
93 | resolved "https://registry.yarnpkg.com/@near-js/types/-/types-0.2.0.tgz#5370c3e9230103222b2827dbd6370f03c4e996d1"
94 | integrity sha512-pTahjni0+PzStseFtnnI9nqmh+ZrHqBqeERo3B3OCXUC/qEie0ZSBMSMt80SgqnaGAy5/CqkCLO9zOx1gA8Cwg==
95 |
96 | "@near-js/utils@0.2.1":
97 | version "0.2.1"
98 | resolved "https://registry.yarnpkg.com/@near-js/utils/-/utils-0.2.1.tgz#6798cf8c3a6ed8057da002401e24409c49454a82"
99 | integrity sha512-u7yR1fmxIcYoiITR1spTvqciXbMXNvlrmRcneNt9DWeQP7yPdbCQtRB7lMN2KI7ONkUf3U7xiheQDDmk2vFI0w==
100 | dependencies:
101 | "@near-js/types" "0.2.0"
102 | bs58 "4.0.0"
103 | depd "2.0.0"
104 | mustache "4.0.0"
105 |
106 | "@near-js/wallet-account@1.2.1":
107 | version "1.2.1"
108 | resolved "https://registry.yarnpkg.com/@near-js/wallet-account/-/wallet-account-1.2.1.tgz#f94ebd9c0e58e437045e17467c283d692c3ad6e4"
109 | integrity sha512-T1k15LN9YIgz1Ca3u76GFxtyDSSKNeBTqEKOJZiOMPse9HjXeiI/ycrOVzmEG/a+ZJ5tipQwcDDChUsY4nTQ1w==
110 | dependencies:
111 | "@near-js/accounts" "1.2.0"
112 | "@near-js/crypto" "1.2.3"
113 | "@near-js/keystores" "0.0.11"
114 | "@near-js/providers" "0.2.1"
115 | "@near-js/signers" "0.1.3"
116 | "@near-js/transactions" "1.2.1"
117 | "@near-js/types" "0.2.0"
118 | "@near-js/utils" "0.2.1"
119 | borsh "1.0.0"
120 |
121 | "@noble/curves@1.2.0":
122 | version "1.2.0"
123 | resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35"
124 | integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==
125 | dependencies:
126 | "@noble/hashes" "1.3.2"
127 |
128 | "@noble/hashes@1.3.2":
129 | version "1.3.2"
130 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
131 | integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
132 |
133 | "@noble/hashes@1.3.3":
134 | version "1.3.3"
135 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699"
136 | integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==
137 |
138 | "@types/json-schema@^7.0.11":
139 | version "7.0.15"
140 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
141 | integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
142 |
143 | ansi-regex@^4.1.0:
144 | version "4.1.1"
145 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
146 | integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
147 |
148 | array-back@^3.0.1, array-back@^3.1.0:
149 | version "3.1.0"
150 | resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0"
151 | integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==
152 |
153 | base-x@^2.0.1:
154 | version "2.0.6"
155 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-2.0.6.tgz#4582a91ebcec99ee06f4e4032030b0cf1c2941d8"
156 | integrity sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g==
157 | dependencies:
158 | safe-buffer "^5.0.1"
159 |
160 | borsh@1.0.0:
161 | version "1.0.0"
162 | resolved "https://registry.yarnpkg.com/borsh/-/borsh-1.0.0.tgz#b564c8cc8f7a91e3772b9aef9e07f62b84213c1f"
163 | integrity sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ==
164 |
165 | bs58@4.0.0:
166 | version "4.0.0"
167 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.0.tgz#65f5deaf6d74e6135a99f763ca6209ab424b9172"
168 | integrity sha512-/jcGuUuSebyxwLLfKrbKnCJttxRf9PM51EnHTwmFKBxl4z1SGkoAhrfd6uZKE0dcjQTfm6XzTP8DPr1tzE4KIw==
169 | dependencies:
170 | base-x "^2.0.1"
171 |
172 | command-line-args@^5.2.1:
173 | version "5.2.1"
174 | resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e"
175 | integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==
176 | dependencies:
177 | array-back "^3.1.0"
178 | find-replace "^3.0.0"
179 | lodash.camelcase "^4.3.0"
180 | typical "^4.0.0"
181 |
182 | depd@2.0.0:
183 | version "2.0.0"
184 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
185 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
186 |
187 | depd@~1.1.2:
188 | version "1.1.2"
189 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
190 | integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
191 |
192 | find-replace@^3.0.0:
193 | version "3.0.0"
194 | resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38"
195 | integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==
196 | dependencies:
197 | array-back "^3.0.1"
198 |
199 | generate-function@^2.0.0:
200 | version "2.3.1"
201 | resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f"
202 | integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
203 | dependencies:
204 | is-property "^1.0.2"
205 |
206 | generate-object-property@^1.1.0:
207 | version "1.2.0"
208 | resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
209 | integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==
210 | dependencies:
211 | is-property "^1.0.0"
212 |
213 | http-errors@1.7.2:
214 | version "1.7.2"
215 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
216 | integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
217 | dependencies:
218 | depd "~1.1.2"
219 | inherits "2.0.3"
220 | setprototypeof "1.1.1"
221 | statuses ">= 1.5.0 < 2"
222 | toidentifier "1.0.0"
223 |
224 | inherits@2.0.3:
225 | version "2.0.3"
226 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
227 | integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
228 |
229 | is-my-ip-valid@^1.0.0:
230 | version "1.0.1"
231 | resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442"
232 | integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==
233 |
234 | is-my-json-valid@^2.20.6:
235 | version "2.20.6"
236 | resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387"
237 | integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==
238 | dependencies:
239 | generate-function "^2.0.0"
240 | generate-object-property "^1.1.0"
241 | is-my-ip-valid "^1.0.0"
242 | jsonpointer "^5.0.0"
243 | xtend "^4.0.0"
244 |
245 | is-property@^1.0.0, is-property@^1.0.2:
246 | version "1.0.2"
247 | resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
248 | integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==
249 |
250 | jsonpointer@^5.0.0:
251 | version "5.0.1"
252 | resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559"
253 | integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==
254 |
255 | lodash.camelcase@^4.3.0:
256 | version "4.3.0"
257 | resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
258 | integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
259 |
260 | lru_map@0.4.1:
261 | version "0.4.1"
262 | resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.4.1.tgz#f7b4046283c79fb7370c36f8fca6aee4324b0a98"
263 | integrity sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==
264 |
265 | mustache@4.0.0:
266 | version "4.0.0"
267 | resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.0.0.tgz#7f02465dbb5b435859d154831c032acdfbbefb31"
268 | integrity sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA==
269 |
270 | near-abi@0.1.1:
271 | version "0.1.1"
272 | resolved "https://registry.yarnpkg.com/near-abi/-/near-abi-0.1.1.tgz#b7ead408ca4ad11de4fe3e595d30a7a8bc5307e0"
273 | integrity sha512-RVDI8O+KVxRpC3KycJ1bpfVj9Zv+xvq9PlW1yIFl46GhrnLw83/72HqHGjGDjQ8DtltkcpSjY9X3YIGZ+1QyzQ==
274 | dependencies:
275 | "@types/json-schema" "^7.0.11"
276 |
277 | near-api-js@^4.0.1:
278 | version "4.0.1"
279 | resolved "https://registry.yarnpkg.com/near-api-js/-/near-api-js-4.0.1.tgz#ac99ef0fc11f24a733ba9c93bd7f094311f891dd"
280 | integrity sha512-lBLgxhXhY7M05UI0ppBOzfArkMCXRvtKiHVgpxrSqN/mp3WCcWV5C+Y/dwx9U6JtaNG8UWxrvB8kHqKyWGeisw==
281 | dependencies:
282 | "@near-js/accounts" "1.2.0"
283 | "@near-js/crypto" "1.2.3"
284 | "@near-js/keystores" "0.0.11"
285 | "@near-js/keystores-browser" "0.0.11"
286 | "@near-js/keystores-node" "0.0.11"
287 | "@near-js/providers" "0.2.1"
288 | "@near-js/signers" "0.1.3"
289 | "@near-js/transactions" "1.2.1"
290 | "@near-js/types" "0.2.0"
291 | "@near-js/utils" "0.2.1"
292 | "@near-js/wallet-account" "1.2.1"
293 | "@noble/curves" "1.2.0"
294 | borsh "1.0.0"
295 | depd "2.0.0"
296 | http-errors "1.7.2"
297 | near-abi "0.1.1"
298 | node-fetch "2.6.7"
299 |
300 | node-fetch@2.6.7:
301 | version "2.6.7"
302 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
303 | integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
304 | dependencies:
305 | whatwg-url "^5.0.0"
306 |
307 | prompt-sync@^4.2.0:
308 | version "4.2.0"
309 | resolved "https://registry.yarnpkg.com/prompt-sync/-/prompt-sync-4.2.0.tgz#0198f73c5b70e3b03e4b9033a50540a7c9a1d7f4"
310 | integrity sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==
311 | dependencies:
312 | strip-ansi "^5.0.0"
313 |
314 | randombytes@2.1.0:
315 | version "2.1.0"
316 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
317 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
318 | dependencies:
319 | safe-buffer "^5.1.0"
320 |
321 | safe-buffer@^5.0.1, safe-buffer@^5.1.0:
322 | version "5.2.1"
323 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
324 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
325 |
326 | setprototypeof@1.1.1:
327 | version "1.1.1"
328 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
329 | integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
330 |
331 | "statuses@>= 1.5.0 < 2":
332 | version "1.5.0"
333 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
334 | integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
335 |
336 | strip-ansi@^5.0.0:
337 | version "5.2.0"
338 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
339 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
340 | dependencies:
341 | ansi-regex "^4.1.0"
342 |
343 | toidentifier@1.0.0:
344 | version "1.0.0"
345 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
346 | integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
347 |
348 | tr46@~0.0.3:
349 | version "0.0.3"
350 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
351 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
352 |
353 | typical@^4.0.0:
354 | version "4.0.0"
355 | resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
356 | integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==
357 |
358 | webidl-conversions@^3.0.0:
359 | version "3.0.1"
360 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
361 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
362 |
363 | whatwg-url@^5.0.0:
364 | version "5.0.0"
365 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
366 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
367 | dependencies:
368 | tr46 "~0.0.3"
369 | webidl-conversions "^3.0.0"
370 |
371 | ws@^8.17.1:
372 | version "8.17.1"
373 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
374 | integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
375 |
376 | xtend@^4.0.0:
377 | version "4.0.2"
378 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
379 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
380 |
--------------------------------------------------------------------------------
/logic/rock-paper-scissors/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 4
4 |
5 | [[package]]
6 | name = "base64ct"
7 | version = "1.6.0"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
10 |
11 | [[package]]
12 | name = "block-buffer"
13 | version = "0.10.4"
14 | source = "registry+https://github.com/rust-lang/crates.io-index"
15 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
16 | dependencies = [
17 | "generic-array",
18 | ]
19 |
20 | [[package]]
21 | name = "borsh"
22 | version = "1.5.3"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03"
25 | dependencies = [
26 | "borsh-derive",
27 | "cfg_aliases",
28 | ]
29 |
30 | [[package]]
31 | name = "borsh-derive"
32 | version = "1.5.3"
33 | source = "registry+https://github.com/rust-lang/crates.io-index"
34 | checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244"
35 | dependencies = [
36 | "once_cell",
37 | "proc-macro-crate",
38 | "proc-macro2",
39 | "quote",
40 | "syn",
41 | ]
42 |
43 | [[package]]
44 | name = "bs58"
45 | version = "0.5.1"
46 | source = "registry+https://github.com/rust-lang/crates.io-index"
47 | checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
48 | dependencies = [
49 | "tinyvec",
50 | ]
51 |
52 | [[package]]
53 | name = "byteorder"
54 | version = "1.5.0"
55 | source = "registry+https://github.com/rust-lang/crates.io-index"
56 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
57 |
58 | [[package]]
59 | name = "calimero-sdk"
60 | version = "0.1.0"
61 | source = "git+https://github.com/calimero-network/core?branch=master#f6ccc8196aea1e501fbcc6294870682ea12df614"
62 | dependencies = [
63 | "borsh",
64 | "bs58",
65 | "calimero-sdk-macros",
66 | "cfg-if",
67 | "serde",
68 | "serde_json",
69 | ]
70 |
71 | [[package]]
72 | name = "calimero-sdk-macros"
73 | version = "0.1.0"
74 | source = "git+https://github.com/calimero-network/core?branch=master#f6ccc8196aea1e501fbcc6294870682ea12df614"
75 | dependencies = [
76 | "prettyplease",
77 | "proc-macro2",
78 | "quote",
79 | "syn",
80 | "thiserror",
81 | ]
82 |
83 | [[package]]
84 | name = "calimero-storage"
85 | version = "0.1.0"
86 | source = "git+https://github.com/calimero-network/core?branch=master#f6ccc8196aea1e501fbcc6294870682ea12df614"
87 | dependencies = [
88 | "borsh",
89 | "calimero-sdk",
90 | "calimero-storage-macros",
91 | "eyre",
92 | "fixedstr",
93 | "hex",
94 | "indexmap",
95 | "rand",
96 | "serde",
97 | "sha2",
98 | "thiserror",
99 | ]
100 |
101 | [[package]]
102 | name = "calimero-storage-macros"
103 | version = "0.1.0"
104 | source = "git+https://github.com/calimero-network/core?branch=master#f6ccc8196aea1e501fbcc6294870682ea12df614"
105 | dependencies = [
106 | "borsh",
107 | "quote",
108 | "syn",
109 | ]
110 |
111 | [[package]]
112 | name = "cfg-if"
113 | version = "1.0.0"
114 | source = "registry+https://github.com/rust-lang/crates.io-index"
115 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
116 |
117 | [[package]]
118 | name = "cfg_aliases"
119 | version = "0.2.1"
120 | source = "registry+https://github.com/rust-lang/crates.io-index"
121 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
122 |
123 | [[package]]
124 | name = "const-oid"
125 | version = "0.9.6"
126 | source = "registry+https://github.com/rust-lang/crates.io-index"
127 | checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
128 |
129 | [[package]]
130 | name = "cpufeatures"
131 | version = "0.2.16"
132 | source = "registry+https://github.com/rust-lang/crates.io-index"
133 | checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
134 | dependencies = [
135 | "libc",
136 | ]
137 |
138 | [[package]]
139 | name = "crypto-common"
140 | version = "0.1.6"
141 | source = "registry+https://github.com/rust-lang/crates.io-index"
142 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
143 | dependencies = [
144 | "generic-array",
145 | "typenum",
146 | ]
147 |
148 | [[package]]
149 | name = "curve25519-dalek"
150 | version = "4.1.3"
151 | source = "registry+https://github.com/rust-lang/crates.io-index"
152 | checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
153 | dependencies = [
154 | "cfg-if",
155 | "cpufeatures",
156 | "curve25519-dalek-derive",
157 | "digest",
158 | "fiat-crypto",
159 | "rustc_version",
160 | "subtle",
161 | "zeroize",
162 | ]
163 |
164 | [[package]]
165 | name = "curve25519-dalek-derive"
166 | version = "0.1.1"
167 | source = "registry+https://github.com/rust-lang/crates.io-index"
168 | checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
169 | dependencies = [
170 | "proc-macro2",
171 | "quote",
172 | "syn",
173 | ]
174 |
175 | [[package]]
176 | name = "der"
177 | version = "0.7.9"
178 | source = "registry+https://github.com/rust-lang/crates.io-index"
179 | checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
180 | dependencies = [
181 | "const-oid",
182 | "zeroize",
183 | ]
184 |
185 | [[package]]
186 | name = "digest"
187 | version = "0.10.7"
188 | source = "registry+https://github.com/rust-lang/crates.io-index"
189 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
190 | dependencies = [
191 | "block-buffer",
192 | "crypto-common",
193 | ]
194 |
195 | [[package]]
196 | name = "ed25519"
197 | version = "2.2.3"
198 | source = "registry+https://github.com/rust-lang/crates.io-index"
199 | checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
200 | dependencies = [
201 | "pkcs8",
202 | "signature",
203 | ]
204 |
205 | [[package]]
206 | name = "ed25519-dalek"
207 | version = "2.1.1"
208 | source = "registry+https://github.com/rust-lang/crates.io-index"
209 | checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
210 | dependencies = [
211 | "curve25519-dalek",
212 | "ed25519",
213 | "rand_core",
214 | "serde",
215 | "sha2",
216 | "subtle",
217 | "zeroize",
218 | ]
219 |
220 | [[package]]
221 | name = "equivalent"
222 | version = "1.0.1"
223 | source = "registry+https://github.com/rust-lang/crates.io-index"
224 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
225 |
226 | [[package]]
227 | name = "eyre"
228 | version = "0.6.12"
229 | source = "registry+https://github.com/rust-lang/crates.io-index"
230 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
231 | dependencies = [
232 | "indenter",
233 | "once_cell",
234 | ]
235 |
236 | [[package]]
237 | name = "fiat-crypto"
238 | version = "0.2.9"
239 | source = "registry+https://github.com/rust-lang/crates.io-index"
240 | checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
241 |
242 | [[package]]
243 | name = "fixedstr"
244 | version = "0.5.8"
245 | source = "registry+https://github.com/rust-lang/crates.io-index"
246 | checksum = "60aba7afd9b1b9e1950c2b7e8bcac3cc44a273c62a02717dedca2d0a1aee694d"
247 | dependencies = [
248 | "serde",
249 | ]
250 |
251 | [[package]]
252 | name = "generic-array"
253 | version = "0.14.7"
254 | source = "registry+https://github.com/rust-lang/crates.io-index"
255 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
256 | dependencies = [
257 | "typenum",
258 | "version_check",
259 | ]
260 |
261 | [[package]]
262 | name = "getrandom"
263 | version = "0.2.15"
264 | source = "registry+https://github.com/rust-lang/crates.io-index"
265 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
266 | dependencies = [
267 | "cfg-if",
268 | "libc",
269 | "wasi",
270 | ]
271 |
272 | [[package]]
273 | name = "hashbrown"
274 | version = "0.15.2"
275 | source = "registry+https://github.com/rust-lang/crates.io-index"
276 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
277 |
278 | [[package]]
279 | name = "hex"
280 | version = "0.4.3"
281 | source = "registry+https://github.com/rust-lang/crates.io-index"
282 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
283 |
284 | [[package]]
285 | name = "indenter"
286 | version = "0.3.3"
287 | source = "registry+https://github.com/rust-lang/crates.io-index"
288 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
289 |
290 | [[package]]
291 | name = "indexmap"
292 | version = "2.7.0"
293 | source = "registry+https://github.com/rust-lang/crates.io-index"
294 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
295 | dependencies = [
296 | "equivalent",
297 | "hashbrown",
298 | ]
299 |
300 | [[package]]
301 | name = "itoa"
302 | version = "1.0.14"
303 | source = "registry+https://github.com/rust-lang/crates.io-index"
304 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
305 |
306 | [[package]]
307 | name = "keccak"
308 | version = "0.1.5"
309 | source = "registry+https://github.com/rust-lang/crates.io-index"
310 | checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
311 | dependencies = [
312 | "cpufeatures",
313 | ]
314 |
315 | [[package]]
316 | name = "libc"
317 | version = "0.2.169"
318 | source = "registry+https://github.com/rust-lang/crates.io-index"
319 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
320 |
321 | [[package]]
322 | name = "memchr"
323 | version = "2.7.4"
324 | source = "registry+https://github.com/rust-lang/crates.io-index"
325 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
326 |
327 | [[package]]
328 | name = "once_cell"
329 | version = "1.20.2"
330 | source = "registry+https://github.com/rust-lang/crates.io-index"
331 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
332 |
333 | [[package]]
334 | name = "pkcs8"
335 | version = "0.10.2"
336 | source = "registry+https://github.com/rust-lang/crates.io-index"
337 | checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
338 | dependencies = [
339 | "der",
340 | "spki",
341 | ]
342 |
343 | [[package]]
344 | name = "ppv-lite86"
345 | version = "0.2.20"
346 | source = "registry+https://github.com/rust-lang/crates.io-index"
347 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
348 | dependencies = [
349 | "zerocopy",
350 | ]
351 |
352 | [[package]]
353 | name = "prettyplease"
354 | version = "0.2.25"
355 | source = "registry+https://github.com/rust-lang/crates.io-index"
356 | checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
357 | dependencies = [
358 | "proc-macro2",
359 | "syn",
360 | ]
361 |
362 | [[package]]
363 | name = "proc-macro-crate"
364 | version = "3.2.0"
365 | source = "registry+https://github.com/rust-lang/crates.io-index"
366 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
367 | dependencies = [
368 | "toml_edit",
369 | ]
370 |
371 | [[package]]
372 | name = "proc-macro2"
373 | version = "1.0.92"
374 | source = "registry+https://github.com/rust-lang/crates.io-index"
375 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
376 | dependencies = [
377 | "unicode-ident",
378 | ]
379 |
380 | [[package]]
381 | name = "quote"
382 | version = "1.0.37"
383 | source = "registry+https://github.com/rust-lang/crates.io-index"
384 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
385 | dependencies = [
386 | "proc-macro2",
387 | ]
388 |
389 | [[package]]
390 | name = "rand"
391 | version = "0.8.5"
392 | source = "registry+https://github.com/rust-lang/crates.io-index"
393 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
394 | dependencies = [
395 | "libc",
396 | "rand_chacha",
397 | "rand_core",
398 | ]
399 |
400 | [[package]]
401 | name = "rand_chacha"
402 | version = "0.3.1"
403 | source = "registry+https://github.com/rust-lang/crates.io-index"
404 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
405 | dependencies = [
406 | "ppv-lite86",
407 | "rand_core",
408 | ]
409 |
410 | [[package]]
411 | name = "rand_core"
412 | version = "0.6.4"
413 | source = "registry+https://github.com/rust-lang/crates.io-index"
414 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
415 | dependencies = [
416 | "getrandom",
417 | ]
418 |
419 | [[package]]
420 | name = "rock-paper-scissors"
421 | version = "0.1.0"
422 | dependencies = [
423 | "bs58",
424 | "calimero-sdk",
425 | "calimero-storage",
426 | "ed25519-dalek",
427 | "rand_chacha",
428 | "sha3",
429 | ]
430 |
431 | [[package]]
432 | name = "rustc_version"
433 | version = "0.4.1"
434 | source = "registry+https://github.com/rust-lang/crates.io-index"
435 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
436 | dependencies = [
437 | "semver",
438 | ]
439 |
440 | [[package]]
441 | name = "ryu"
442 | version = "1.0.18"
443 | source = "registry+https://github.com/rust-lang/crates.io-index"
444 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
445 |
446 | [[package]]
447 | name = "semver"
448 | version = "1.0.24"
449 | source = "registry+https://github.com/rust-lang/crates.io-index"
450 | checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
451 |
452 | [[package]]
453 | name = "serde"
454 | version = "1.0.216"
455 | source = "registry+https://github.com/rust-lang/crates.io-index"
456 | checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
457 | dependencies = [
458 | "serde_derive",
459 | ]
460 |
461 | [[package]]
462 | name = "serde_derive"
463 | version = "1.0.216"
464 | source = "registry+https://github.com/rust-lang/crates.io-index"
465 | checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
466 | dependencies = [
467 | "proc-macro2",
468 | "quote",
469 | "syn",
470 | ]
471 |
472 | [[package]]
473 | name = "serde_json"
474 | version = "1.0.134"
475 | source = "registry+https://github.com/rust-lang/crates.io-index"
476 | checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
477 | dependencies = [
478 | "itoa",
479 | "memchr",
480 | "ryu",
481 | "serde",
482 | ]
483 |
484 | [[package]]
485 | name = "sha2"
486 | version = "0.10.8"
487 | source = "registry+https://github.com/rust-lang/crates.io-index"
488 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
489 | dependencies = [
490 | "cfg-if",
491 | "cpufeatures",
492 | "digest",
493 | ]
494 |
495 | [[package]]
496 | name = "sha3"
497 | version = "0.10.8"
498 | source = "registry+https://github.com/rust-lang/crates.io-index"
499 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
500 | dependencies = [
501 | "digest",
502 | "keccak",
503 | ]
504 |
505 | [[package]]
506 | name = "signature"
507 | version = "2.2.0"
508 | source = "registry+https://github.com/rust-lang/crates.io-index"
509 | checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
510 | dependencies = [
511 | "rand_core",
512 | ]
513 |
514 | [[package]]
515 | name = "spki"
516 | version = "0.7.3"
517 | source = "registry+https://github.com/rust-lang/crates.io-index"
518 | checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
519 | dependencies = [
520 | "base64ct",
521 | "der",
522 | ]
523 |
524 | [[package]]
525 | name = "subtle"
526 | version = "2.6.1"
527 | source = "registry+https://github.com/rust-lang/crates.io-index"
528 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
529 |
530 | [[package]]
531 | name = "syn"
532 | version = "2.0.91"
533 | source = "registry+https://github.com/rust-lang/crates.io-index"
534 | checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035"
535 | dependencies = [
536 | "proc-macro2",
537 | "quote",
538 | "unicode-ident",
539 | ]
540 |
541 | [[package]]
542 | name = "thiserror"
543 | version = "1.0.69"
544 | source = "registry+https://github.com/rust-lang/crates.io-index"
545 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
546 | dependencies = [
547 | "thiserror-impl",
548 | ]
549 |
550 | [[package]]
551 | name = "thiserror-impl"
552 | version = "1.0.69"
553 | source = "registry+https://github.com/rust-lang/crates.io-index"
554 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
555 | dependencies = [
556 | "proc-macro2",
557 | "quote",
558 | "syn",
559 | ]
560 |
561 | [[package]]
562 | name = "tinyvec"
563 | version = "1.8.1"
564 | source = "registry+https://github.com/rust-lang/crates.io-index"
565 | checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
566 | dependencies = [
567 | "tinyvec_macros",
568 | ]
569 |
570 | [[package]]
571 | name = "tinyvec_macros"
572 | version = "0.1.1"
573 | source = "registry+https://github.com/rust-lang/crates.io-index"
574 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
575 |
576 | [[package]]
577 | name = "toml_datetime"
578 | version = "0.6.8"
579 | source = "registry+https://github.com/rust-lang/crates.io-index"
580 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
581 |
582 | [[package]]
583 | name = "toml_edit"
584 | version = "0.22.22"
585 | source = "registry+https://github.com/rust-lang/crates.io-index"
586 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
587 | dependencies = [
588 | "indexmap",
589 | "toml_datetime",
590 | "winnow",
591 | ]
592 |
593 | [[package]]
594 | name = "typenum"
595 | version = "1.17.0"
596 | source = "registry+https://github.com/rust-lang/crates.io-index"
597 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
598 |
599 | [[package]]
600 | name = "unicode-ident"
601 | version = "1.0.14"
602 | source = "registry+https://github.com/rust-lang/crates.io-index"
603 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
604 |
605 | [[package]]
606 | name = "version_check"
607 | version = "0.9.5"
608 | source = "registry+https://github.com/rust-lang/crates.io-index"
609 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
610 |
611 | [[package]]
612 | name = "wasi"
613 | version = "0.11.0+wasi-snapshot-preview1"
614 | source = "registry+https://github.com/rust-lang/crates.io-index"
615 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
616 |
617 | [[package]]
618 | name = "winnow"
619 | version = "0.6.20"
620 | source = "registry+https://github.com/rust-lang/crates.io-index"
621 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
622 | dependencies = [
623 | "memchr",
624 | ]
625 |
626 | [[package]]
627 | name = "zerocopy"
628 | version = "0.7.35"
629 | source = "registry+https://github.com/rust-lang/crates.io-index"
630 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
631 | dependencies = [
632 | "byteorder",
633 | "zerocopy-derive",
634 | ]
635 |
636 | [[package]]
637 | name = "zerocopy-derive"
638 | version = "0.7.35"
639 | source = "registry+https://github.com/rust-lang/crates.io-index"
640 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
641 | dependencies = [
642 | "proc-macro2",
643 | "quote",
644 | "syn",
645 | ]
646 |
647 | [[package]]
648 | name = "zeroize"
649 | version = "1.8.1"
650 | source = "registry+https://github.com/rust-lang/crates.io-index"
651 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
652 |
--------------------------------------------------------------------------------