README.md
as-pect.config.js
asconfig.json
package.json
scripts
    1.deploy.sh
    10.get_all_rooms.sh
    2.create_room.sh
    3.request_to_join_room.sh
    4.join_room.sh
    5.create_game.sh
    6.play.sh
    7.approve_member.sh
    8.stake.sh
    9.payout.sh
    README.md
src
    as-pect.d.ts
    as_types.d.ts
    rock-paper-scissor
        README.md
        __test__
            README.md
            index.unit.spec.ts
        asconfig.json
        assembly
            index.ts
            model.ts
        utils.ts
    tsconfig.json

## Deploying contract through your terminal

The `deploy.sh` file within the scripts folder demonstrates a simple way of deploying a smart contract to the testnet.

```sh
[ -z "$CONTRACT" ] && echo "Missing \$CONTRACT environment variable"
[ -z "$OWNER" ] && echo "Missing \$OWNER environment variable"
```
The above commands searches the environment variables for `$CONTRACT` and `$OWNER` variables.

```sh
echo "deleting $CONTRACT and setting $OWNER as beneficiary"
echo
near delete $CONTRACT $OWNER
```
These commands deletes the two environment variable , `$CONTRACT` and `$OWNER` if any is found in the codebase, resolving the conflict of having two set of `$CONTRACT` and `$OWNER` variables.

```sh
echo --------------------------------------------
echo
echo "cleaning up the /neardev folder"
echo
rm -rf ./neardev
```
The above shell commands deletes the `./neardev` folder. This folder contains details about the smart contract once deploy, expample is the `CONTRACT_NAME` found in the `dev-account.env` file. This way we can always generate a new `./neardev` folder on every deploy.

```sh
echo --------------------------------------------
echo
echo "rebuilding the contract (release build)"
echo
yarn build:release
```
These commands compiles/builds the AssemlyScript code down to WebAssembly code. This action generates a file with `.wasm` extension that contains the WebAssembly code.

```sh
echo --------------------------------------------
echo
echo "redeploying the contract"
echo
near dev-deploy ../build/release/block-dice.wasm
```
These commands deploys/redeploys the resulting WebAssembly file from the previous action, `yarn build:release`. This file is deployed to the Near blockchain.

```sh
echo --------------------------------------------
echo run the following commands
echo
echo 'export CONTRACT=__new_contract_account_id__'
echo
echo
```

These final commands prompts the developer to export the exported interfaces, making it available for consumption on the local machine.
## Deploying contract through your terminal

The `deploy.sh` file within the scripts folder demonstrates a simple way of deploying a smart contract to the testnet.

```sh
[ -z "$CONTRACT" ] && echo "Missing \$CONTRACT environment variable"
[ -z "$OWNER" ] && echo "Missing \$OWNER environment variable"
```
The above commands searches the environment variables for `$CONTRACT` and `$OWNER` variables.

```sh
echo "deleting $CONTRACT and setting $OWNER as beneficiary"
echo
near delete $CONTRACT $OWNER
```
These commands deletes the two environment variable , `$CONTRACT` and `$OWNER` if any is found in the codebase, resolving the conflict of having two set of `$CONTRACT` and `$OWNER` variables.

```sh
echo --------------------------------------------
echo
echo "cleaning up the /neardev folder"
echo
rm -rf ./neardev
```
The above shell commands deletes the `./neardev` folder. This folder contains details about the smart contract once deploy, expample is the `CONTRACT_NAME` found in the `dev-account.env` file. This way we can always generate a new `./neardev` folder on every deploy.

```sh
echo --------------------------------------------
echo
echo "rebuilding the contract (release build)"
echo
yarn build:release
```
These commands compiles/builds the AssemlyScript code down to WebAssembly code. This action generates a file with `.wasm` extension that contains the WebAssembly code.

```sh
echo --------------------------------------------
echo
echo "redeploying the contract"
echo
near dev-deploy ../build/release/block-dice.wasm
```
These commands deploys/redeploys the resulting WebAssembly file from the previous action, `yarn build:release`. This file is deployed to the Near blockchain.

```sh
echo --------------------------------------------
echo run the following commands
echo
echo 'export CONTRACT=__new_contract_account_id__'
echo
echo
```

These final commands prompts the developer to export the exported interfaces, making it available for consumption on the local machine.
![Near, Inc. logo](https://near.org/wp-content/themes/near-19/assets/img/logo.svg?t=1553011311)

## Design

### Interface

#### Core functions

```ts
function createRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieve a boolean value (false for private room, true for public room)
- Creates a new room and update the rooms data structure with the created room.
- Returns a success message.

```ts
function joinPublicRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId, "_isVisible": boolean}'` parameters
- Allows the account initiating the contract call to join the room that's public
- This invokes a `addNewMember` method on the `Room` data type.
- Returns a success message.

```ts
function requestToJoinPrivateRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Allows the account initiating the contract call to request to join a private room
- This invokes a `addNewRequest` method on the `Room` data type.
- Returns a success message.

```ts
function responseToRequest
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId, "acct": AccountId, "acceptance": boolean}'` as parameter
- This invokes the `addNewMember` and the `acceptRequests` methods on the `Room` data type if `acceptance` is `true` while it invoking the `rejectRequest` method if `acceptance` is `false`.
- Returns a success message.

```ts
function createGame
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Allows the account initiating the contract call to create a new game within a room
- This updates the `games` data structure with the new game.
- Returns a success message.

```ts
function play
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- This invokes the `addNewPlayer` method on the `Game` data type.
- Smart contract panics if maximum players reached.
- Returns a success message.

```ts
function stake
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{_gameId: GameId, stakeOn: AccountId}'` as parameter
- This invokes the `addNewStaker` method on the `Game` data type.
- Returns a success message.

```ts
function payout
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Smart contract panics if game is still active.
- Returns boolean

#### Game Reporting Functions

```ts
function getRooms
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"isJoined": boolean}'` as parameter
- Returns rooms that a player is a member ofor rooms a player is not a member of depending on the parameter passed.

```ts
function getRoomMembers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Returns an array of members of a room.

```ts
function getRoomRequests
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Returns an array of requests within a private room.

```ts
function getRoomGames
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Returns an array of games within the room; either created or active or completed games.

```ts
function getRoom
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{_roomId: RoomId}'` as parameter
- Returns a room with its details.

```ts
function getGame
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{_gameId: GameId}'` as parameter
- Returns a game with its details.

```ts
function getProfile
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{acct: AccountId}'` as parameter
- Returns a all the rooms that an accountId is a member of.

```ts
function getGamePlayers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns an array of players participating in a game.

```ts
function getGameStakers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns an array of stakers participating in a game.

```ts
function getWinner
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns an array of winners for a game.

### Helper Functions

```ts
function verifyMembership
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{_roomId: RoomId, acct: AccountId}'` as parameter
- Verifies that an AccountId is a member of a room.

```ts
function verifyRequest
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{_roomId: RoomId, acct: AccountId}'` as parameter
- Verifies that a request tied to an AccountId exists within a room's requests.

```ts
function verifyRoom
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{_roomId: RoomId}'` as parameter
- Verifies that a room exists within the rooms array.

```ts
function verifyGame
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{_gameId: GameId}'` as parameter
- Verifies that a game exist within the games array.

```ts
function verifyTxFee
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{deposit: u128, Fee: u128}'` as parameter
- Verifies that a particular deposit was made to the smart contract.

```ts
function generateId
```
- Non-exported function (ie. a function that can be acessed outside the contract)
- Recieves a `'{prefix: string}'` as parameter
- Generates and returns a unique ID
## Rock-Paper-Scissor Game
This repository includes a complete Smart Contract for a rock-paper-scissor game built on the NEAR blockchain. This smart contract has flaws that would fixed in the second version or in a branch within the repo.

The flaws fixed within this smart contract are:
- A player can play twice within a game. 
  - solution: restrict the first player from also being the second player through assertion.
- Anyone can create a game or play a game even if not a member of the room.
  - solution: restrict a non-member from creating or playing a game within a room.
- Without making a request, a player can be added to a private room.
  - solution: check if a join-room request exists before approving a request/member
- Added more enumeration functions to easily return necessary data to the frontend

Check out these additional video content for more informtion on this rock-paper-scissor smart contract methods:
https://loom.com/share/folder/39accbd082e44ddf99805235b2d6f4b1
https://www.loom.com/share/folder/7d02b7d00fdd40d6a77d55d5d60c8363

This is a smart contract written in the simple format. This smart contract introduces game development on the NEAR blockchain using assembly script:
- How to use Data types and the data structures within AssemblyScript based smart contract. How state management across a DApp works, and as well, how to implement restrictions on your smart contracts 
- How to implement random number generation and id checks on the NEAR block chain

## Usage

### Getting started

1. clone this repo to a local folder
2. run `yarn`
3. run `yarn test:unit`

### Top-level `yarn` commands

- run `yarn test` to run all tests
  - (!) be sure to run `yarn build:release` at least once before:
    - run `yarn test:unit` to run only unit tests
- run `yarn build` to quickly verify build status
- run `yarn clean` to clean up build folder

> Check the `./scripts` folder for the integration tests.

### Other documentation

- NEAR-rock-paper-scissor contract and test documentation
  - see `/src/rock-paper-scissor/README` for contract interface
  - see `/src/rock-paper-scissor/__tests__/README` for Sample unit testing details
## Unit tests

Unit tests can be run from the top level folder using the following command:

```
yarn test:unit
```

### Tests for Contract in `index.unit.spec.ts`

```
[Describe]: Creating a room

 [Success]: ✔ creates a new room
 [Success]: ✔ creates a new private room
 [Success]: ✔ throws an error with zero deposit

[Describe]: Joining a created room

 [Success]: ✔ create a public room
 [Success]: ✔ Accept request to join private room
 [Success]: ✔ Reject request to join private room

[Describe]: Creating a game within a room

 [Success]: ✔ Create a game within a room
 [Success]: ✔ throws an error with zero deposit

[Describe]: Playing a created game within a room

 [Success]: ✔ member gets added as a player and plays
 [Success]: ✔ throws error with zero deposit

[Describe]: Staking on players within a game

 [Success]: ✔ stake on a player
 [Success]: ✔ throws error with zero deposit

[Describe]: Winning a game as a player

 [Success]: ✔ Winner of the game
 [Success]: ✔ Payout of pool

    [File]: src/rock-paper-scissor/__test__/index.unit.spec.ts
  [Groups]: 7 pass, 7 total
  [Result]: ✔ PASS
[Snapshot]: 0 total, 0 added, 0 removed, 0 different
 [Summary]: 14 pass,  0 fail, 14 total
    [Time]: 169.011ms

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  [Result]: ✔ PASS
   [Files]: 1 total
  [Groups]: 7 count, 7 pass
   [Tests]: 14 pass, 0 fail, 14 total
    [Time]: 9047.68ms
✨  Done in 9.90s.
![Near, Inc. logo](https://near.org/wp-content/themes/near-19/assets/img/logo.svg?t=1553011311)

## Design

### Interface

#### Core functions

```ts
function createRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieve a boolean value (false for private room, true for public room)
- Creates a new room and update the rooms data structure with the created room.

```ts
function joinPublicRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId, "_isVisible": boolean}'` parameters
- Allows the account initiating the contract call to join the room that's public
- This invokes a `addNewMember` method on the `Room` data type.

```ts
function requestToJoinPrivateRoom
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Allows the account initiating the contract call to request to join a private room
- This invokes a `addNewRequest` method on the `Room` data type.

```ts
function approveMember
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId, "acct": AccountId, "_isVisible": boolean}'` as parameter
- This invokes the `addNewMember` and the `updateRequests` methods on the `Room` data type.

```ts
function createGame
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Allows the account initiating the contract call to create a new game within a room
- This updates the `games` data structure with the new game.

```ts
function play
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- This invokes the `addNewPlayer` method on the `Game` data type.
- Smart contract panics if maximum players reached.

```ts
function stake
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- This invokes the `addNewStaker` method on the `Game` data type.

```ts
function payout
```
- "Change" function (ie. a function that alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Smart contract panics if game is still active.

#### Game Reporting Functions

```ts
function getRooms
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"isJoined": boolean}'` as parameter
- Returns rooms that a player is a member ofor rooms a player is not a member of depending on the parameter passed.

```ts
function getRoomMembers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Returns an array of members of a room.

```ts
function getRoomRequests
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId}'` as parameter
- Returns an array of requests within a private room.

```ts
function getAllGames
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_roomId": RoomId, "gameStatus": Status}'` as parameter
- Returns an array of games with the same status; either created or active or completed games.

```ts
function getGamePlayers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns an array of players participating in a game.

```ts
function getGameStakers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns an array of stakers participating in a game.

```ts
function getGameStakers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns the winner of a game.

```ts
function getGameStakers
```
- "View" function (ie. a function that does not alters contract state)
- Recieves a `'{"_gameId": GameId}'` as parameter
- Returns the winner of a game.
## Unit tests

Unit tests can be run from the top level folder using the following command:

```
yarn test:unit
```

### Tests for Contract in `index.unit.spec.ts`

```
[Describe]: Creating a room

 [Success]: ✔ creates a new room
 [Success]: ✔ creates a new private room
 [Success]: ✔ throws an error with zero deposit

[Describe]: Joining a created room

 [Success]: ✔ Join a public room
 [Success]: ✔ Join a private room

[Describe]: Creating a game within a room

 [Success]: ✔ Create a game within a room
 [Success]: ✔ throws an error with zero deposit

[Describe]: Playing a created game within a room

 [Success]: ✔ member gets added as a player and plays
 [Success]: ✔ throws error with zero deposit

[Describe]: Staking on players within a game

 [Success]: ✔ stake on a player
 [Success]: ✔ throws error with zero deposit

[Describe]: Winning a game as a player

 [Success]: ✔ Winner of the game
 [Success]: ✔ Payout of pool

    [File]: src/rock-paper-scissor/__test__/index.unit.spec.ts
  [Groups]: 7 pass, 7 total
  [Result]: ✔ PASS
[Snapshot]: 0 total, 0 added, 0 removed, 0 different
 [Summary]: 13 pass,  0 fail, 13 total
    [Time]: 147.669ms

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  [Result]: ✔ PASS
   [Files]: 1 total
  [Groups]: 7 count, 7 pass
   [Tests]: 13 pass, 0 fail, 13 total
    [Time]: 8593.509ms
✨  Done in 10.24s.
```
## Rock-Paper-Scissor Game
This repository includes a complete Smart Contract for a rock-paper-scissor game built on the NEAR blockchain. This smart contract has flaws that would fixed in the second version or in a branch within the repo.

The flaws within the smart contract are:
- A player can play twice within a game. 
  - solution: restrict the first player from also being the second player through assertion.
- Anyone can create a game or play a game even if not a member of the room.
  - solution: restrict a non-member from creating or playing a game within a room.
- Without making a request, a player can be added to a private room.
  - check if a join-room request exists before approving a request/member

Check out these additional video content for more informtion on this rock-paper-scissor smart contract methods:
https://loom.com/share/folder/39accbd082e44ddf99805235b2d6f4b1
https://www.loom.com/share/folder/7d02b7d00fdd40d6a77d55d5d60c8363

This is a smart contract written in the simple format. This smart contract introduces game development on the NEAR blockchain using assembly script:
- How to use Data types and the data structures within AssemblyScript based smart contract. How state management across a DApp works, and as well, how to implement restrictions on your smart contracts 
- How to implement random number generation and id checks on the NEAR block chain

## Usage

### Getting started

1. clone this repo to a local folder
2. run `yarn`
3. run `yarn test:unit`

### Top-level `yarn` commands

- run `yarn test` to run all tests
  - (!) be sure to run `yarn build:release` at least once before:
    - run `yarn test:unit` to run only unit tests
- run `yarn build` to quickly verify build status
- run `yarn clean` to clean up build folder

> Check the `./scripts` folder for the integration tests.

### Other documentation

- NEAR-rock-paper-scissor contract and test documentation
  - see `/src/rock-paper-scissor/README` for contract interface
  - see `/src/rock-paper-scissor/__tests__/README` for Sample unit testing details
