diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42e90ca..bd7e82d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,7 +64,7 @@ All new repositories in the haste ecosystem should contain the following: 4. All top level `package.json` should have the following scripts: `test`, `lint`, `build`, `pretty`, `clean`, `prepare`. 5. `.gitignore` 6. Top level `package.json` should use the haste-sdk as a template for how to structure the `package.json`. -7. If using Lerna, you must include a `README` at the top level and in each package. +7. You must include a `README` at the top level and in each package if using a monorepo. #### Coding Style diff --git a/LICENSE b/LICENSE index 89902a0..46c73f4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 playhaste +Copyright (c) 2021 hastearcade Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index cf27d32..3fddf40 100644 --- a/README.md +++ b/README.md @@ -2,44 +2,236 @@ ## Overview -A monorepo that contains the tooling required to create games quickly and easily for the [Haste Arcade](https://playhaste.com/). Additionally it includes a sample game to provide a comprehensive example of how the Haste SDK can be used. +The haste-sdk is not ready for production use yet. This document is subject to change. -Initially, TypeScript and JavaScript will be the only supported SDKs, but long term Haste will build SDKs for other technology stacks and will help support community driven SDKs. Haste plans to keep client SDKs open source to ensure a good developer experience and will make available documented APIs. +This readme is intended for developers looking to utilize the Haste ecosystem to build a game on the Haste Arcade. If you are a developer looking to contribute to the Haste ecosystem please see [Contributing](#contributing). - +The haste-sdk repository is a monorepo that contains the tooling required to create games quickly and easily for the [Haste Arcade](https://hastearcade.com/). Additionally it includes a sample game to provide a comprehensive example of how the Haste SDK can be used to apply the concept of Instant Leaderboard Payout (ILP). + +Initially, TypeScript and JavaScript will be the only supported SDKs, but long term Haste will build SDKs for other technology stacks and will help support community driven SDKs. Haste plans to keep client SDKs open source to ensure a good developer experience and will make available documented APIs for developers that do not wish to utilize Typescript or Javascript. ## Table of Contents +- [Quickstart](#quickstart) + - [Server](#server) + - [Web](#web) - [Background and Use Case](#background) - [Packages](#packages) -- [Setup](#setup) +- [Documentation](#documentation) +- [License](#license) +- [Contributing](#contributing) +- [Contriubtor Setup](#setup) - [Prerequisites](#prerequisites) - [Installation](#installation) - [Environment Variables](#environment-variables) -- [Usage](#usage) - - [Lerna Monorepo](#lerna-monorepo) +- [Contributor Usage](#usage) + - [Monorepo](#monorepo) + - [Branching & Versioning](#branching-&-versioning) - [Developer Tooling](#developer-tooling) - [Deploy](#deploy) -- [Documentation](#documentation) -- [License](#license) -- [Contributing](#contributing) - [Authors](#authors) +## Quickstart + +This quick start guide will demonstrate the use of the haste-sdk in a server side node environment and a browser based environment. To build a game for the haste arcade you will need both if you are building a web based game. If you are building a desktop or mobile game please see our advanced documentation [here](https://haste-arcade.stoplight.io/). + +To start you need to register your game with Haste through the developer [portal](https://developerportal.hastearcade.com). Once you login, you can create a game to generate a set of access keys to be used by the SDK. + +### Server + +The `@hastearcade/server` package is the primary entry point to the Haste ecosystem. The sdk is a wrapper for the Haste API and allows developers to ILP enable a game. The Haste ecosystem provides tools to handle the following components of ILP: + +1. Authentication +2. Leaderboard management +3. Payouts to the leaderboard +4. Play & Score submission + +#### Initialize Haste + +To initialize the Haste sdk for use in your server, you need to perform the following: + +```typescript +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +/// Now do things with the haste object like submit a play or a score. +``` + +The client id and secret are defined in the developer portal on your game page. See image below for reference: + +![](docs\assets\gameserverkeys.png) + +NOTE: It is recommneded to create an abstraction (service, lib, etc) around the haste-sdk in your codebase. This will allow you to initialize one haste object. + +#### Authentication + +Integrating the Haste authentication system into your server is one of the first steps needed. This step is important because it allows players in the arcade to receive payment for their skill. If the user is not logged in, then they can not submit and score, and ultimately can not be paid for placing on a leaderboard. The game client (using `@hastearcade/web`) will send the token to the server with each request. The server can use the following code to validate the token: + +```typescript +import { Haste } from '@hastearcade/server'; +const token = receiveTokenFromRequest(); +try { + const playerId = await Haste.validatePlayerAccess(token); + console.log(`The player authenticated has an id of ${playerId}`); +} catch (err) { + console.error(`An error occurred while validating the player's token.`); +} +``` + +Note: the above code does not use the haste object created from `build`. `build` and `validatePlayerAccess` are both static async functions. All other functions (get leaderboards, submit score, etc should utilize the haste object created from `build`) + +#### Leaderboard management + +The Haste ecosystem currently has multiple leaderboards that can be played for every game. Each tier requires additional funds to play the game (i.e. paying a penny vs paying a quarter). Every game in the arcade must support this concept in game. Thus, most games will display a dropdown UI to allow the player to select what leaderboard they wish to participate in. In order to retrieve the list of leaderboards to show in your dropdown you can use the following: + +```typescript +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +const leaderBoards = haste.game.leaderboards(); +console.log(leaderBoards); + +/* +output: + +[{ + id: "guid", + name: "Beginner", + cost: 2000, // cost to play in this leaderboard in satoshis. +}] +``` + +#### Submit Play & Score + +When playing a game in an arcade, in order to play you must first insert your quarter. The `@hastearcade/server` sdk requires a similar flow. Once a player has selected their leaderboard, the developer will need to submit a "play" to the Haste api via the sdk. The following code shows a demonstration of this concept: + +```typescript +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +const play = await haste.game.play(new Player(playerId), new Leaderboard(leaderboardId)); +console.log(play); + +/* +output: + +{ + id: "guid", + gameId: "your game guid", + playerId: "player guid", + leaderboard: { + id: "guid", + name: "Beginner", + cost: 2000, // cost to play in this leaderboard in satoshis. + } +} +``` + +Once the play submission is you completed you should allow the user the play your game. + +_Always maintain the business logic and scoring logic server side for security reasons in your game. Do not keep score or make any important game state decisions on the client._ + +Upon hitting an end state for your game (i.e. the player gets hit by a bomb and dies) it is time to submit your score. To submit a score, you'll need the original play object. The play object can be maintained however you choose (memory, database, cache, etc). The score sdk method takes the current Play object, the Leaderboard the score is being submitted against, and the score. + +```typescript +await haste.game.score(currentPlay, leaderboard, score); +``` + +#### Payouts + +All payouts are handled internal to the Haste ecosystem and do not require any additional code for the game developer. + +### Web + +While the primary work of integrating with Haste is performed in the server (where all game logic and score state should be maintained), Haste does provide a web based sdk to assist in the authentication process. In order for a player to play your game, they will need to authenticate with the Haste Arcade. + +Your client side game will need to handle the following scenarios: + +1. Login button with a click event +2. Handle redirect from Authentication system +3. Determine if player is authenticated +4. Get authentication token +5. Logout button with a redirect + +Similar to the server side SDK, `@hastearcade/web` starts by initializing a Haste object. In this case, the name of the object is `HasteClient` and the object should be maintained via an abstraction so it only need to be initialized one time. + +```typescript +const hasteClient = await HasteClient.build(process.env.HASTE_GAME_CLIENT_ID); +``` + +The client id used here can be found in the developer portal and will be for your game _not your server_. See image below for a reference point: + +![](docs\assets\gameclientkeys.png) + +#### Login + +Once you have built your `HasteClient` object you may begin using it in your game. At the appropriate time in your game's flow, you will need to present them with a login button. The login button's click event should perform the following: + +```typescript +await hasteClient.loginWithRedirect(); +``` + +This code will redirect your user to Haste's authentication system for the player to login with their Haste credentials + +Once the user authenticates, the authentication system will redirect the user back to your game's url. Additional code will be needed in your implementation to handle this redirect. + +```typescript +await hasteClient.handleRedirect(async () => { + /// perform any code necessary to initialize your game with + /// the player ready to initiate a start action like a start + /// button + this.update(); +}); +``` + +#### Check Authenticated status + +To check if the current user is authenticated please utilize the following method: + +```typescript +const isAuth = await hasteClient.isAuthenticated(); +``` + +#### Logout + +To allow a user to log out of your game you can utilize the following code: + +```typescript +hasteClient.logout(); /// does not need to be awaited +``` + +Note: Logout does not need to be awaited, but it is best practice to redirect your user back to your game's sign in page or state. In addition, it is best practice to submit the user's current score upon logout. + ## Background -Welcome to the world’s first ILP Arcade. Haste Arcade is a platform filled with ILP Games -built by developers all around the world. Unlike traditional online games, ILP Games found on the Haste Arcade platform adhere to an exciting new real-time "Instant Leaderboard Payout" structure that was invented and made popular by Haste’s founding team members. Imagine going to your local arcade, inserting 25 cents into the gaming console, posting a high score on Pac-Man, and then getting paid 2.5 cents every time subsequent players play the game but fail to beat your score. Now consider holding the top score in a global online arcade where millions of daily players are playing the game but failing to beat your score, and earning 2.5 cents per play. This is a "game changer". This is Haste Arcade. +Welcome to the world’s first ILP Arcade. Haste Arcade is a platform filled with ILP Games built by developers all around the world. Unlike traditional online games, ILP Games found on the Haste Arcade platform adhere to an exciting new real-time "Instant Leaderboard Payout" structure that was invented and made popular by Haste’s founding team members. + +Imagine going to your local arcade, inserting 25 cents into the gaming console, posting a high score on Pac-Man, and then getting paid 2.5 cents every time subsequent players play the game but fail to beat your score. Now consider holding the top score in a global online arcade where millions of daily players are playing the game but failing to beat your score, and earning 2.5 cents per play. This is a "game changer". This is Haste Arcade. ## Packages -- `domain` - shared domain models and services for the SDK -- `sdk` - The primary package. `sdk` provides a simple wrapper around the Haste API and makes it easy to configure integration with Haste. +The following lists the packages contained in the haste-sdk monorepo: + +- `models` - shared domain models and services for the server and web SDK. +- `server` - The primary package for server side integration with Haste. `server` provides a simple wrapper around the Haste API and makes it easy to configure integration with Haste. +- `web` - The primary package for client side integration with Haste. The web SDK is used to integrate with the Haste authentication system. - `haste-game-domain` - A base package that allows sharing types between the sample game server and sample game client - `haste-game-server` - An example [authoritative server](https://www.gabrielgambetta.com/client-server-game-architecture.html) leveraging [matter-js](https://brm.io/matter-js/) for game physics - `haste-game-client` - An example game client integrated with the game server. Leverages [phaser3](https://phaser.io/phaser3) for rendering the game levels and game state. +## Documentation + +This `README` and each package's `README` provides high-level documentation. Additionally the code has been reviewed and comments provided to aid future developers in understanding why certain decisions were made. + +More comprehensive documentation can be found [here](https://haste-arcade.stoplight.io/). + +## License + +The haste-sdk repository along with the corresponding npm packages are currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) + +## Contributing + +If you are a developer looking to contribute to the Haste ecosystem please review our +[Contributing Readme](https://github.com/playhaste/haste-sdk/blob/main/ContributingReadme.md) and our [Contributing Guidelines](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md) + ## Setup +The follow sections detail how to contribute to this repository and the Haste ecosystem. + ### Prerequisites haste-sdk is built using the node.js and typescript ecosystem. In order to develop haste-sdk you will need to install [Node.js](https://nodejs.org/en/). haste-sdk was primarily developed on Ubuntu 20 via Windows WSL, but this is not a requirement to develop haste-sdk. @@ -50,17 +242,13 @@ In addition, you will need [NVM](https://github.com/nvm-sh/nvm) installed. NVM i Once you have Node.js and NVM installed you can run the following commands to test haste-sdk. -`npm install commitizen -D -g` - `git clone git@github.com:playhaste/haste-sdk.git` `cd haste-sdk` `nvm use` -`npm i -g lerna` - -`npm run boostrap` +`npm install commitizen -D -g` `npm run build` @@ -71,52 +259,45 @@ It is strongly recommended to develop haste-sdk using an editing ecosystem that 1. VSCode ESLint [link](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 2. VSCode Prettier [link](https://marketplace.visualstudio.com/items?itemName=SimonSiefke.prettier-vscode) +All pull requests will be reviewed for linting and styling to ensure a conssitent codebase. Please ensure that you run lint and prettier before submitting a pull request. + ### Environment Variables -Within this monorepository, developers can see that `haste-game-client` and `haste-game-server` use [dotenv](https://github.com/motdotla/dotenv) and `.env` files. Their specifications are outlined in their corresponding `README`. The `sdk` does not require environment variables. +Within this monorepository, developers can see that `haste-game-client` and `haste-game-server` use [dotenv](https://github.com/motdotla/dotenv) and `.env` files. Their specifications are outlined in their corresponding `README`. + +The `server`, `web`, `models`, and `haste-game-domain` pakcages do not require environment variables. ## Usage The follow section describes the haste-sdk development experience. -### Lerna Monorepo - -haste-sdk utilizes a monorepo via Lerna to manage dependencies between the packages that comprise the haste arcade sdk. If you are not familiar with Lerna, please see their [website](https://lerna.js.org/) for additional information. - -haste-sdk is currently using a shared versioning strategy for all packages. This means that all packages' version numbers will remain in sync and will be released together. +### Monorepo -Typically, you will not need to interact with Lerna directly as standard tooling commands will be run via `npm`. +haste-sdk utilizes npm 7 and npm's workspaces to manage dependencies between the packages that comprise the haste arcade sdk. If you are not familiar with NPM 7 workspaces, please see their [website](https://docs.npmjs.com/cli/v7/using-npm/workspaces) for additional information. -### Changesets +haste-sdk is currently using a distinct semantic versioning strategy for each published package (server, web, and models). -haste-sdk utilizes [changesets](https://github.com/atlassian/changesets) to manage versioning and publishing of the packages in the PNPM monorepo. Atlassion developed changesets to solve the following problem: +Typically, you will not need to interact with workspaces directly as standard tooling commands will be run via `npm`. -> The changesets workflow is designed to help when people are making changes, all the way through to publishing. It lets contributors declare how their changes should be released, then we automate updating package versions, and changelogs, and publishing new versions of packages based on the provided information. +### Branching & Versioning -Developers making modifications to any package in the haste-sdk should create a changeset. The developer flow will be: +The stable branch used by haste-sdk is the `main` branch. All stable npm package releases will be performed from the main branch. Any beta releases will be performed from the `next` branch and will use a `beta` npm distribution tag. -1. Identify change needed to the repository -2. Create feature branch off of development. -3. Implement changes -4. Create changeset by running `pnpm changeset` at the root directory. -5. Select which packages have been modified by using the spacebar key. -6. Give a description of the change. This description will flow through to the changelog of the package so please review the [contribution guide](./CONTRIBUTING.md). -7. Push code to feature branch -8. Submit PR to development and ask for review. +haste-sdk utilizes [semantic-release](https://github.com/semantic-release/semantic-release) to automatically manage versions of each npm package. Upon any merge to the main branch, a Github Action will run the release process to update npm repository. ### Developer Tooling haste-sdk uses the following tools to ensure a consistent, standard development environment: 1. Typescript -2. Lerna +2. NPM 7 Workspaces 3. Prettier 4. ESLint 5. Husky with lint-staged 6. Jest 7. Commitizen -_Through the use of npm package scripts and lerna, all commands can be run from the root directory of haste-sdk._ +_Through the use of npm package scripts and workspaces, all commands can be run from the root directory of haste-sdk._ #### Linting and Formatting @@ -132,26 +313,10 @@ haste-sdk utilizes Jest for running tests. To run all tests in the monorepo use ## Deploy -No deploy process is utilized at this time. - -## Documentation - -This `README` and each package's `README` provides high-level documentation. Additionally the code has been reviewed and comments provided to aid future developers in understanding why certain decisions were made. In the future the Haste team will be providing links here to the Haste API documentation and any quick start documentation. - -## License - -haste-sdk is currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) - -## Contributing - -Please read our contribution [policy](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md). +Github Actions is used to deploy the server, web, and models npm packages. ## Authors - Keith LaForce ([rallieon](https://github.com/rallieon/)) - Eric LaForce ([foundrium](https://github.com/foundrium/)) - Dan Wagner ([danwag06](https://github.com/danwag06)) - -``` - -``` diff --git a/docs/assets/gameclientkeys.png b/docs/assets/gameclientkeys.png new file mode 100644 index 0000000..d4b7b0c Binary files /dev/null and b/docs/assets/gameclientkeys.png differ diff --git a/docs/assets/gameserverkeys.png b/docs/assets/gameserverkeys.png new file mode 100644 index 0000000..9a4b07a Binary files /dev/null and b/docs/assets/gameserverkeys.png differ diff --git a/packages/haste-game-server/README.md b/packages/haste-game-server/README.md index 307509d..3453a08 100644 --- a/packages/haste-game-server/README.md +++ b/packages/haste-game-server/README.md @@ -6,7 +6,7 @@ The haste game server is an example an ILP based game server. It leverages [matt All game logic and scoring occurs within the haste-game-server. The client is used only to render the latest game state. No logic or scoring should occur on the client. -The haste-game-server also leverages the @hastearcade/haste to integrate with the Haste API. This supports authz, submitting scores, and retrieving information about the latest leaderboard. +The haste-game-server also leverages the `@hastearcade/server` to integrate with the Haste API. This supports authz, submitting scores, and retrieving information about the latest leaderboard. Information is transferred between the client and server using socket.io. diff --git a/packages/models/README.md b/packages/models/README.md index 5fdeda3..85937af 100644 --- a/packages/models/README.md +++ b/packages/models/README.md @@ -1,19 +1,17 @@ # @hastearcade/models +[![npm version](https://badge.fury.io/js/%40hastearcade%2Fmodels.svg)](https://badge.fury.io/js/%40hastearcade%2Fmodels) + ## Overview -The @hastearcade/models package includes common domain models and services used in the SDK. Eventually it will also be used to support tooling such as a CLI tool. +The `@hastearcade/models` package includes common domain models and services used in the SDK. Eventually it will also be used to support tooling such as a CLI tool. At the current time this package should not be used on its own. Please use the `@hastearcade/server` and `@hastearcade/web` packages. See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md) for an overview of the haste-sdk repository. - - ## Table of Contents - [Background and Use Case](#background) - [Setup](#setup) -- [Usage](#usage) -- [Deploy](#deploy) - [Documentation](#documentation) - [License](#license) - [Contributing](#contributing) @@ -27,27 +25,20 @@ See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Background See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Setup) for a detailed setup guide. -## Usage - -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Usage) for a detailed usage guide. - -### Testing - -@hastearcade/models utilizes Jest for running tests. To run all tests in the domain package use the following command - -`pnpm run test` - ## Documentation -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Documentation) for more documentation. +This `README` and each package's `README` provides high-level documentation. Additionally the code has been reviewed and comments provided to aid future developers in understanding why certain decisions were made. + +More comprehensive documentation can be found [here](https://haste-arcade.stoplight.io/). ## License -haste-sdk is currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) +The haste-sdk repository along with the corresponding npm packages are currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) ## Contributing -Please read our contribution [policy](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md). +If you are a developer looking to contribute to the Haste ecosystem please review our +[Contributing Readme](https://github.com/playhaste/haste-sdk/blob/main/ContributingReadme.md) and our [Contributing Guidelines](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md) ## Authors diff --git a/packages/server/README.md b/packages/server/README.md index 42edbf3..9d9ca87 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -1,132 +1,150 @@ -# haste-sdk +# @hastearcade/server -## Overview - -The SDK to be used to empower developers to leverage the Haste Arcade. The SDK is intended to be used only on the server side. The SDK current supports +[![npm version](https://badge.fury.io/js/%40hastearcade%2Fserver.svg)](https://badge.fury.io/js/%40hastearcade%2Fserver) -- Authz -- Submitting Scores - -On the roadmap the Haste team plans to provide +## Overview -- [ ] Real time leaderboard updates -- [ ] Simpler authentication setup and support -- [ ] Access to player information -- [ ] Player cards +The `@hastearcade/server` sdk empowers developers to leverage the Haste Arcade ecosystem to build Instant Leaderboard Payout (ILP) based games. The SDK is intended to be used only on the server side, but it is required to be used in conjunction with `@hastearcade/web`. See details [here](https://github.com/playhaste/haste-sdk/blob/main/packages/web/README.md). See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md) for an overview of the haste-sdk repository. - - ## Table of Contents +- [Quickstart](#quickstart) - [Background and Use Case](#background) - [Setup](#setup) -- [Usage](#usage) -- [Deploy](#deploy) +- [Testing](#testing) - [Documentation](#documentation) - [License](#license) - [Contributing](#contributing) - [Authors](#authors) -## Background +## Quickstart -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Background) for a detailed background. +The `@hastearcade/server` package is the primary entry point to the Haste ecosystem. The sdk is a wrapper for the Haste API and allows developers to ILP enable a game. The Haste ecosystem provides tools to handle the following components of ILP: -## Setup +1. Authentication +2. Leaderboard management +3. Payouts to the leaderboard +4. Play & Score submission -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Setup) for a detailed setup guide. +#### Initialize Haste + +To initialize the Haste sdk for use in your server, you need to perform the following: + +```typescript +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +/// Now do things with the haste object like submit a play or a score. +``` + +The client id and secret are defined in the developer portal on your game page. See image below for reference: + +![](docs\assets\gameserverkeys.png) + +NOTE: It is recommneded to create an abstraction (service, lib, etc) around the haste-sdk in your codebase. This will allow you to initialize one haste object. -## Quick Start +#### Authentication -### Initialize the Haste SDK +Integrating the Haste authentication system into your server is one of the first steps needed. This step is important because it allows players in the arcade to receive payment for their skill. If the user is not logged in, then they can not submit and score, and ultimately can not be paid for placing on a leaderboard. The game client (using `@hastearcade/web`) will send the token to the server with each request. The server can use the following code to validate the token: -A game developer can access their game's client id and client secret through the developer portal. +```typescript +import { Haste } from '@hastearcade/server'; +const token = receiveTokenFromRequest(); +try { + const playerId = await Haste.validatePlayerAccess(token); + console.log(`The player authenticated has an id of ${playerId}`); +} catch (err) { + console.error(`An error occurred while validating the player's token.`); +} +``` + +Note: the above code does not use the haste object created from `build`. `build` and `validatePlayerAccess` are both static async functions. All other functions (get leaderboards, submit score, etc should utilize the haste object created from `build`) + +#### Leaderboard management + +The Haste ecosystem currently has multiple leaderboards that can be played for every game. Each tier requires additional funds to play the game (i.e. paying a penny vs paying a quarter). Every game in the arcade must support this concept in game. Thus, most games will display a dropdown UI to allow the player to select what leaderboard they wish to participate in. In order to retrieve the list of leaderboards to show in your dropdown you can use the following: ```typescript -const haste = await Haste.build(process.env.HASTE_CLIENT_ID, process.env.HASTE_CLIENT_SECRET, { - hostProtocol: process.env.HASTE_API_PROTOCOL, - host: process.env.HASTE_API_HOST, - port: parseInt(process.env.HASTE_API_PORT, 10), -}); +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +const leaderBoards = haste.game.leaderboards(); +console.log(leaderBoards); + +/* +output: + +[{ + id: "guid", + name: "Beginner", + cost: 2000, // cost to play in this leaderboard in satoshis. +}] ``` -### Authenticate a user +#### Submit Play & Score -The example game server and client use socket.io so here is the necessary code to authenticate the user and setup the Haste SDK. +When playing a game in an arcade, in order to play you must first insert your quarter. The `@hastearcade/server` sdk requires a similar flow. Once a player has selected their leaderboard, the developer will need to submit a "play" to the Haste api via the sdk. The following code shows a demonstration of this concept: ```typescript -this.io = new Server(server, { - cors: { - origin: process.env.CORS_URL, - methods: ['GET', 'POST'], - }, -}); - -this.jwtClient = new JwksClient({ - jwksUri: 'https://playhaste.us.auth0.com/.well-known/jwks.json', -}); - -this.io.use(this.jwtMiddleware); - -private getKey = (header: JwtHeader, callback: SigningKeyCallback) => { - this.jwtClient.getSigningKey(header.kid, (err: Error, key: SigningKey) => { - const signingKey = key.getPublicKey(); - callback(err, signingKey); - }); -}; - -private jwtMiddleware = (socket: Socket, next: (err?: ExtendedError) => void) => { - if (socket.handshake.auth && socket.handshake.auth.token) { - jwt.verify(socket.handshake.auth.token as string, this.getKey, {}, (err, decoded) => { - if (err) return next(new Error('Authentication error')); - if (decoded.iss === process.env.AUTH0_ISSUER && decoded.exp > new Date().getTime() / 1000) { - socket.data = decoded; - return next(); - } else { - return next(new Error('Authentication error')); - } - }); - } else { - next(new Error('Authentication error')); +const haste = await Haste.build(process.env.HASTE_SERVER_CLIENT_ID, process.env.HASTE_SERVER_CLIENT_SECRET); +const play = await haste.game.play(new Player(playerId), new Leaderboard(leaderboardId)); +console.log(play); + +/* +output: + +{ + id: "guid", + gameId: "your game guid", + playerId: "player guid", + leaderboard: { + id: "guid", + name: "Beginner", + cost: 2000, // cost to play in this leaderboard in satoshis. } -}; - +} ``` -### Submit a score +Once the play submission is you completed you should allow the user the play your game. -This assumes a user is already logged in and the developer has access to the JWT. +_Always maintain the business logic and scoring logic server side for security reasons in your game. Do not keep score or make any important game state decisions on the client._ + +Upon hitting an end state for your game (i.e. the player gets hit by a bomb and dies) it is time to submit your score. To submit a score, you'll need the original play object. The play object can be maintained however you choose (memory, database, cache, etc). The score sdk method takes the current Play object, the Leaderboard the score is being submitted against, and the score. ```typescript -const metadata = jwt['http://haste/metadata'].playerId; -const player = new Player(metadata.playerId); -const score = 1; -const play = await haste.game.play(player); -await haste.game.score(play, score); +await haste.game.score(currentPlay, leaderboard, score); ``` -## Usage +#### Payouts + +All payouts are handled internal to the Haste ecosystem and do not require any additional code for the game developer. -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Usage) for a detailed usage guide. +## Background + +See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Background) for a detailed background. + +## Setup + +See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Setup) for a detailed setup guide. ### Testing -@hastearcade/haste utilizes Jest for running tests. To run all tests in the server package use the following command +`@hastearcade/server` utilizes Jest for running tests. To run all tests in the server package use the following command `npm run test` ## Documentation -Currently there is no further documentation setup, but please check back in the future. +This `README` and each package's `README` provides high-level documentation. Additionally the code has been reviewed and comments provided to aid future developers in understanding why certain decisions were made. + +More comprehensive documentation can be found [here](https://haste-arcade.stoplight.io/). ## License -haste-sdk is currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) +The haste-sdk repository along with the corresponding npm packages are currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) ## Contributing -Please read our contribution [policy](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md). +If you are a developer looking to contribute to the Haste ecosystem please review our +[Contributing Readme](https://github.com/playhaste/haste-sdk/blob/main/ContributingReadme.md) and our [Contributing Guidelines](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md) ## Authors diff --git a/packages/web/README.md b/packages/web/README.md index 5abe1a3..cfa8ed7 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -1,132 +1,113 @@ -# haste-sdk +# @hastearcade/web -## Overview - -The SDK to be used to empower developers to leverage the Haste Arcade. The SDK is intended to be used only on the server side. The SDK current supports +[![npm version](https://badge.fury.io/js/%40hastearcade%2Fweb.svg)](https://badge.fury.io/js/%40hastearcade%2Fweb) -- Authz -- Submitting Scores - -On the roadmap the Haste team plans to provide +## Overview -- [ ] Real time leaderboard updates -- [ ] Simpler authentication setup and support -- [ ] Access to player information -- [ ] Player cards +The `@hastearcade/web` SDK empowers developers to incoroporate the Haste authentication system into their web based game. The SDK is intended to be used only on the client side, but it is required to be used in conjunction with `@hastearcade/server`. See details [here](https://github.com/playhaste/haste-sdk/blob/main/packages/server/README.md). See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md) for an overview of the haste-sdk repository. - - ## Table of Contents +- [Quickstart](#quickstart) - [Background and Use Case](#background) - [Setup](#setup) -- [Usage](#usage) -- [Deploy](#deploy) +- [Testing](#testing) - [Documentation](#documentation) - [License](#license) - [Contributing](#contributing) - [Authors](#authors) -## Background +## Quickstart -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Background) for a detailed background. +While the primary work of integrating with Haste is performed in the server (where all game logic and score state should be maintained), Haste does provide a web based sdk to assist in the authentication process. In order for a player to play your game, they will need to authenticate with the Haste Arcade. -## Setup +Your client side game will need to handle the following scenarios: -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Setup) for a detailed setup guide. +1. Login button with a click event +2. Handle redirect from Authentication system +3. Determine if player is authenticated +4. Get authentication token +5. Logout button with a redirect + +Similar to the server side SDK, `@hastearcade/web` starts by initializing a Haste object. In this case, the name of the object is `HasteClient` and the object should be maintained via an abstraction so it only need to be initialized one time. + +```typescript +const hasteClient = await HasteClient.build(process.env.HASTE_GAME_CLIENT_ID); +``` -## Quick Start +The client id used here can be found in the developer portal and will be for your game _not your server_. See image below for a reference point: -### Initialize the Haste SDK +![](docs\assets\gameclientkeys.png) -A game developer can access their game's client id and client secret through the developer portal. +#### Login + +Once you have built your `HasteClient` object you may begin using it in your game. At the appropriate time in your game's flow, you will need to present them with a login button. The login button's click event should perform the following: ```typescript -const haste = await Haste.build(process.env.HASTE_CLIENT_ID, process.env.HASTE_CLIENT_SECRET, { - hostProtocol: process.env.HASTE_API_PROTOCOL, - host: process.env.HASTE_API_HOST, - port: parseInt(process.env.HASTE_API_PORT, 10), -}); +await hasteClient.loginWithRedirect(); ``` -### Authenticate a user +This code will redirect your user to Haste's authentication system for the player to login with their Haste credentials -The example game server and client use socket.io so here is the necessary code to authenticate the user and setup the Haste SDK. +Once the user authenticates, the authentication system will redirect the user back to your game's url. Additional code will be needed in your implementation to handle this redirect. ```typescript -this.io = new Server(server, { - cors: { - origin: process.env.CORS_URL, - methods: ['GET', 'POST'], - }, +await hasteClient.handleRedirect(async () => { + /// perform any code necessary to initialize your game with + /// the player ready to initiate a start action like a start + /// button + this.update(); }); +``` -this.jwtClient = new JwksClient({ - jwksUri: 'https://playhaste.us.auth0.com/.well-known/jwks.json', -}); +#### Check Authenticated status -this.io.use(this.jwtMiddleware); - -private getKey = (header: JwtHeader, callback: SigningKeyCallback) => { - this.jwtClient.getSigningKey(header.kid, (err: Error, key: SigningKey) => { - const signingKey = key.getPublicKey(); - callback(err, signingKey); - }); -}; - -private jwtMiddleware = (socket: Socket, next: (err?: ExtendedError) => void) => { - if (socket.handshake.auth && socket.handshake.auth.token) { - jwt.verify(socket.handshake.auth.token as string, this.getKey, {}, (err, decoded) => { - if (err) return next(new Error('Authentication error')); - if (decoded.iss === process.env.AUTH0_ISSUER && decoded.exp > new Date().getTime() / 1000) { - socket.data = decoded; - return next(); - } else { - return next(new Error('Authentication error')); - } - }); - } else { - next(new Error('Authentication error')); - } -}; +To check if the current user is authenticated please utilize the following method: +```typescript +const isAuth = await hasteClient.isAuthenticated(); ``` -### Submit a score +#### Logout -This assumes a user is already logged in and the developer has access to the JWT. +To allow a user to log out of your game you can utilize the following code: ```typescript -const metadata = jwt['http://haste/metadata'].playerId; -const player = new Player(metadata.playerId); -const score = 1; -const play = await haste.game.play(player); -await haste.game.score(play, score); +hasteClient.logout(); /// does not need to be awaited ``` -## Usage +Note: Logout does not need to be awaited, but it is best practice to redirect your user back to your game's sign in page or state. In addition, it is best practice to submit the user's current score upon logout. -See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Usage) for a detailed usage guide. +## Background + +See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Background) for a detailed background. + +## Setup + +See [here](https://github.com/playhaste/haste-sdk/blob/main/README.md#Setup) for a detailed setup guide. ### Testing -@hastearcade/haste utilizes Jest for running tests. To run all tests in the server package use the following command +`@hastearcade/web` utilizes Jest for running tests. To run all tests in the server package use the following command `npm run test` ## Documentation -Currently there is no further documentation setup, but please check back in the future. +This `README` and each package's `README` provides high-level documentation. Additionally the code has been reviewed and comments provided to aid future developers in understanding why certain decisions were made. + +More comprehensive documentation can be found [here](https://haste-arcade.stoplight.io/). ## License -haste is currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) +The haste-sdk repository along with the corresponding npm packages are currently licensed under [MIT](https://github.com/playhaste/haste-sdk/blob/main/LICENSE) ## Contributing -Please read our contribution [policy](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md). +If you are a developer looking to contribute to the Haste ecosystem please review our +[Contributing Readme](https://github.com/playhaste/haste-sdk/blob/main/ContributingReadme.md) and our [Contributing Guidelines](https://github.com/playhaste/haste-sdk/blob/main/CONTRIBUTING.md) ## Authors