├── .gitignore ├── CNAME ├── README.md ├── docs ├── CNAME ├── _config.yml ├── cli.md ├── index.md └── sdk │ ├── common_types.md │ ├── configuration.md │ ├── index.md │ ├── redux_integration.md │ └── state.md ├── index.js ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── cli │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── src │ │ ├── Main.tsx │ │ ├── bin.tsx │ │ ├── cli.ts │ │ ├── components │ │ │ ├── Form.tsx │ │ │ ├── QrCode.tsx │ │ │ ├── Spinner.tsx │ │ │ └── index.ts │ │ ├── constants.ts │ │ ├── containers │ │ │ ├── AuthAction.tsx │ │ │ ├── Completed.tsx │ │ │ ├── DeployAction.tsx │ │ │ ├── DevelopAction.tsx │ │ │ ├── Help.tsx │ │ │ ├── InitAction.tsx │ │ │ ├── Summary.tsx │ │ │ └── index.ts │ │ ├── context │ │ │ ├── ContextComponent.ts │ │ │ ├── context.ts │ │ │ ├── index.ts │ │ │ └── interfaces.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ └── services │ │ │ ├── SdkService.ts │ │ │ ├── ServerService.ts │ │ │ ├── StorageService.ts │ │ │ ├── TemplateService.ts │ │ │ └── index.ts │ ├── template │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── config.d.ts │ │ │ ├── config.js │ │ │ ├── handlers.d.ts │ │ │ ├── handlers.js │ │ │ ├── logger.d.ts │ │ │ ├── logger.js │ │ │ └── main.js │ ├── tsconfig.build.json │ └── tsconfig.json ├── sdk-playground │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ │ ├── favicon │ │ │ ├── apple-touch-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ └── favicon.ico │ │ └── index.html │ ├── scripts │ │ ├── build.sh │ │ └── deploy.sh │ ├── src │ │ ├── App.module.scss │ │ ├── App.tsx │ │ ├── components │ │ │ ├── Button.module.scss │ │ │ ├── Button.tsx │ │ │ ├── Code.module.scss │ │ │ ├── Code.tsx │ │ │ ├── Example.module.scss │ │ │ ├── Example.tsx │ │ │ ├── HelpTrigger.module.scss │ │ │ ├── HelpTrigger.tsx │ │ │ ├── InputCheckBox.module.scss │ │ │ ├── InputCheckBox.tsx │ │ │ ├── InputGasPriceStrategy.tsx │ │ │ ├── InputSelect.module.scss │ │ │ ├── InputSelect.tsx │ │ │ ├── InputText.module.scss │ │ │ ├── InputText.tsx │ │ │ ├── Menu.module.scss │ │ │ ├── Menu.tsx │ │ │ ├── MenuOption.module.scss │ │ │ ├── MenuOption.tsx │ │ │ ├── Screen.module.scss │ │ │ ├── Screen.tsx │ │ │ ├── Url.module.scss │ │ │ ├── Url.tsx │ │ │ └── index.ts │ │ ├── config.ts │ │ ├── configure.ts │ │ ├── containers │ │ │ ├── Console.module.scss │ │ │ ├── Console.tsx │ │ │ ├── Content.module.scss │ │ │ ├── Content.tsx │ │ │ ├── Help.module.scss │ │ │ ├── Help.tsx │ │ │ ├── Preloader.module.scss │ │ │ ├── Preloader.tsx │ │ │ ├── StatusBar.module.scss │ │ │ ├── StatusBar.tsx │ │ │ ├── account │ │ │ │ ├── ConnectAccount.tsx │ │ │ │ ├── CreateAccount.tsx │ │ │ │ ├── DeployAccount.tsx │ │ │ │ ├── DisconnectAccount.tsx │ │ │ │ ├── SearchAccount.tsx │ │ │ │ ├── UpdateAccount.tsx │ │ │ │ └── index.ts │ │ │ ├── accountDevice │ │ │ │ ├── CreateAccountDevice.tsx │ │ │ │ ├── DeployAccountDevice.tsx │ │ │ │ ├── GetAccountDevice.tsx │ │ │ │ ├── GetConnectedAccountDevice.tsx │ │ │ │ ├── GetConnectedAccountDevices.tsx │ │ │ │ ├── RemoveAccountDevice.tsx │ │ │ │ ├── UnDeployAccountDevice.tsx │ │ │ │ └── index.ts │ │ │ ├── accountFriendRecovery │ │ │ │ ├── AddAccountFriendRecoveryExtension.tsx │ │ │ │ ├── CancelAccountFriendRecovery.tsx │ │ │ │ ├── CollectAccountFriendSignature.tsx │ │ │ │ ├── GetAccountFriendRecovery.tsx │ │ │ │ ├── GetConnectedAccountFriendRecoveryExtension.tsx │ │ │ │ ├── SetupAccountFriendRecoveryExtension.tsx │ │ │ │ ├── SignAccountFriendRecovery.tsx │ │ │ │ ├── StartAccountFriendRecovery.tsx │ │ │ │ ├── SubmitAccountFriendRecovery.tsx │ │ │ │ └── index.ts │ │ │ ├── accountGame │ │ │ │ ├── CancelAccountGame.tsx │ │ │ │ ├── CreateAccountGame.tsx │ │ │ │ ├── GetAccountGame.tsx │ │ │ │ ├── GetConnectedAccountGames.tsx │ │ │ │ ├── JoinAccountGame.tsx │ │ │ │ ├── StartAccountGame.tsx │ │ │ │ ├── UpdateAccountGame.tsx │ │ │ │ └── index.ts │ │ │ ├── accountPayment │ │ │ │ ├── CancelAccountPayment.tsx │ │ │ │ ├── CreateAccountPayment.tsx │ │ │ │ ├── DepositAccountPayment.tsx │ │ │ │ ├── GetConnectedAccountPayment.tsx │ │ │ │ ├── GetConnectedAccountPayments.tsx │ │ │ │ ├── GrabAccountPayment.tsx │ │ │ │ ├── SignAccountPayment.tsx │ │ │ │ ├── WithdrawAccountPayment.tsx │ │ │ │ └── index.ts │ │ │ ├── accountTransaction │ │ │ │ ├── GetConnectedAccountTransaction.tsx │ │ │ │ ├── GetConnectedAccountTransactions.tsx │ │ │ │ ├── SendAccountTransaction.tsx │ │ │ │ └── index.ts │ │ │ ├── accountVirtualBalance │ │ │ │ ├── GetConnectedAccountVirtualBalance.tsx │ │ │ │ ├── GetConnectedAccountVirtualBalances.tsx │ │ │ │ ├── GetConnectedAccountVirtualPendingBalance.tsx │ │ │ │ ├── GetConnectedAccountVirtualPendingBalances.tsx │ │ │ │ ├── TopUpAccountVirtualBalance.tsx │ │ │ │ ├── WithdrawFromAccountVirtualBalance.tsx │ │ │ │ └── index.ts │ │ │ ├── action │ │ │ │ ├── AcceptIncomingAction.tsx │ │ │ │ ├── DismissIncomingAction.tsx │ │ │ │ └── index.ts │ │ │ ├── app │ │ │ │ ├── GetApp.tsx │ │ │ │ ├── GetAppOpenGames.tsx │ │ │ │ ├── GetApps.tsx │ │ │ │ └── index.ts │ │ │ ├── constants.ts │ │ │ ├── examples │ │ │ │ ├── MintToken.tsx │ │ │ │ ├── PlayTicTacToe.module.scss │ │ │ │ ├── PlayTicTacToe.tsx │ │ │ │ ├── index.ts │ │ │ │ └── ticTacToe │ │ │ │ │ ├── InputBoard.module.scss │ │ │ │ │ ├── InputBoard.tsx │ │ │ │ │ └── index.ts │ │ │ ├── global │ │ │ │ ├── Initialize.tsx │ │ │ │ ├── Reset.tsx │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── token │ │ │ │ ├── GetToken.tsx │ │ │ │ ├── GetTokenBalance.tsx │ │ │ │ ├── GetTokens.tsx │ │ │ │ └── index.ts │ │ │ ├── url │ │ │ │ ├── CreateRequestAddAccountDeviceUrl.tsx │ │ │ │ ├── CreateRequestSignSecureCodeUrl.tsx │ │ │ │ ├── ProcessIncomingUrl.tsx │ │ │ │ └── index.ts │ │ │ └── utils │ │ │ │ ├── GetTransactionDetails.tsx │ │ │ │ ├── RecoverAccountDeviceFromPersonalMessageSignature.tsx │ │ │ │ ├── SignPersonalMessage.tsx │ │ │ │ └── index.ts │ │ ├── help │ │ │ ├── index.ts │ │ │ ├── menu.ts │ │ │ └── statusBar.ts │ │ ├── index.scss │ │ ├── index.tsx │ │ ├── react-app-env.d.ts │ │ └── shared │ │ │ ├── ContextComponent.ts │ │ │ ├── context.ts │ │ │ ├── help.ts │ │ │ ├── index.ts │ │ │ ├── interfaces.ts │ │ │ ├── logger.ts │ │ │ └── utils.ts │ └── tsconfig.json └── sdk │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── src │ ├── Sdk.ts │ ├── SdkError.ts │ ├── constants.ts │ ├── environments │ │ ├── constants.ts │ │ ├── index.ts │ │ └── utils.ts │ ├── errors.ts │ ├── helpers.ts │ ├── index.ts │ ├── interfaces.ts │ ├── modules │ │ ├── AccountFriendRecovery.ts │ │ ├── AccountGame.ts │ │ ├── AccountPayment.ts │ │ ├── AccountTransaction.ts │ │ ├── Action.ts │ │ ├── Api.ts │ │ ├── ApiError.ts │ │ ├── ApiMethods.ts │ │ ├── Contract.ts │ │ ├── Device.ts │ │ ├── Ens.ts │ │ ├── Environment.ts │ │ ├── Eth.ts │ │ ├── EthError.ts │ │ ├── Session.ts │ │ ├── State.ts │ │ ├── Storage.ts │ │ ├── Url.ts │ │ └── index.ts │ ├── redux │ │ ├── actions.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ ├── middleware.ts │ │ └── reducers.ts │ └── types.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # node.js 2 | node_modules/ 3 | *.log 4 | build 5 | bak 6 | 7 | *. 8 | !.circleci 9 | !.gitignore 10 | /test.js 11 | 12 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | archanova.io 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Archanova monorepo 2 | 3 | [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/) 4 | 5 | Try Archanova SDK Playground at [https://playground.archanova.run](https://playground.archanova.run) 6 | 7 | ## Packages 8 | 9 | - [@archanova/cli](packages/cli) 10 | - [@archanova/sdk](packages/sdk) 11 | - [@archanova/sdk-playground](packages/sdk-playground) 12 | 13 | ## Docs 14 | 15 | - [CLI](docs/cli.md) 16 | - [SDK](docs/sdk/index.md) 17 | 18 | 19 | ## License 20 | 21 | The MIT License 22 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | archanova.io -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | title: Archanova 3 | description: CLI, SDK Docs 4 | -------------------------------------------------------------------------------- /docs/cli.md: -------------------------------------------------------------------------------- 1 | # CLI 2 | 3 | ## Installation 4 | 5 | ```bash 6 | $ npm i @archanova/cli -g 7 | ``` 8 | 9 | ## Usage 10 | 11 | ```bash 12 | $ archanova-cli [action] [options] [workingPath] 13 | ``` 14 | 15 | **Actions:** 16 | * `auth` - authentication 17 | * `init` - initialize application 18 | * `develop` - develop application 19 | * `deploy` - deploy application 20 | 21 | **Options:** 22 | * `--help, -h` - print help 23 | * `--global, -g` - use global storage 24 | * `--env, -e ` - environment [main,ropsten,rinkeby,kovan,sokol,xdai,local] (default: main) 25 | * `--local-env-host ` - local environment host 26 | * `--local-env-port ` - local environment port 27 | * `--private-key ` - device private key 28 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | ## Docs 2 | 3 | - [CLI](cli.md) 4 | - [SDK](sdk/index.md) 5 | -------------------------------------------------------------------------------- /docs/sdk/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | ## Setup SDK Environment 4 | 5 | ### Predefined Environments 6 | ```typescript 7 | import { SdkEnvironmentNames, getSdkEnvironment } from '@archanova/sdk'; 8 | 9 | const sdkEnv = getSdkEnvironment(SdkEnvironmentNames.Main); 10 | ``` 11 | 12 | ### Extending Environment 13 | 14 | ```typescript 15 | import { SdkEnvironmentNames, getSdkEnvironment } from '@archanova/sdk'; 16 | import Ws from 'ws'; 17 | 18 | const sdkEnv = getSdkEnvironment(SdkEnvironmentNames.Rinkeby) 19 | .setConfig('storageAdapter', sessionStorage) 20 | .setConfig('apiWebSocketConstructor', Ws) // for nodejs env 21 | .extendConfig('ensOptions', { 22 | supportedRootNames: ['smartsafe.test'], 23 | }); 24 | ``` 25 | 26 | ## Create SDK Instance 27 | 28 | ```typescript 29 | const sdk = createSdk(sdkEnv); 30 | ``` 31 | 32 | ## Initialize SDK Instance 33 | ```typescript 34 | await sdk.initialize(); 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/sdk/index.md: -------------------------------------------------------------------------------- 1 | # SDK 2 | 3 | ## Installation 4 | 5 | ```bash 6 | $ npm i @archanova/sdk -S 7 | ``` 8 | 9 | ## Usage 10 | 11 | - [Configuration](configuration.md) 12 | - [Common Types](common_types.md) 13 | - [State](state.md) 14 | - [Redux Integration](redux_integration.md) 15 | - [Api](https://playground.archanova.run/) 16 | -------------------------------------------------------------------------------- /docs/sdk/redux_integration.md: -------------------------------------------------------------------------------- 1 | # Redux Integration 2 | 3 | ## Actions 4 | ```typescript 5 | import { ReduxSdkActionTypes } from '@archanova/sdk'; 6 | 7 | interface ISdkReduxAction { 8 | type: ReduxSdkActionTypes; 9 | payload: T; 10 | } 11 | ``` 12 | 13 | ## Reducers 14 | 15 | ```typescript 16 | import { reduxSdkReducer } from '@archanova/sdk'; 17 | import { combineReducers } from 'redux'; 18 | 19 | export default combineReducers({ 20 | sdk: reduxSdkReducer, 21 | }); 22 | ``` 23 | 24 | ## Middleware 25 | 26 | ```typescript 27 | import { createReduxSdkMiddleware, ISdkReduxState } from '@archanova/sdk'; 28 | import { applyMiddleware, createStore } from 'redux'; 29 | import reducers from './reducers'; 30 | 31 | const sdk; // ... sdk object 32 | const store = createStore( 33 | reducers, 34 | {}, 35 | applyMiddleware( 36 | createReduxSdkMiddleware(sdk), 37 | ), 38 | ); 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/sdk/state.md: -------------------------------------------------------------------------------- 1 | # State 2 | 3 | Sdk `state` is available in `sdk.state`, it's a combination of `getters` and `rxjs` `Subjects`. 4 | 5 | ```typescript 6 | import { Subject } from 'rxjs'; 7 | import { sdkModules, sdkInterfaces } from '@archanova/sdk'; 8 | 9 | interface IState { 10 | initialized$: Subject; 11 | connected$: Subject; 12 | authenticated$: Subject; 13 | account$: Subject; 14 | accountDevice$: Subject; 15 | accountFriendRecovery$: Subject; 16 | device$: Subject; 17 | ens$: Subject; 18 | eth$: Subject; 19 | session$: Subject; 20 | incomingAction$: Subject; 21 | 22 | initialized: boolean; 23 | connected: boolean; 24 | authenticated: boolean; 25 | account: sdkInterfaces.IAccount; 26 | accountAddress: string; 27 | accountDevice: sdkInterfaces.IAccountDevice; 28 | accountFriendRecovery: sdkInterfaces.IAccountFriendRecovery; 29 | device: sdkInterfaces.IDevice; 30 | deviceAddress: string; 31 | ens: sdkModules.State.IEns; 32 | eth: sdkModules.State.IEth; 33 | session: sdkModules.State.ISession; 34 | sessionToken: string; 35 | incomingAction: sdkModules.Action.IAction; 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = null; 2 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "0.0.0", 4 | "packages": [ 5 | "packages/*" 6 | ], 7 | "npmClient": "npm", 8 | "command": { 9 | "publish": { 10 | "ignoreChanges": [ 11 | "ignored-file", 12 | "*.md" 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "archanova", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "Archanova monorepo", 6 | "license": "MIT", 7 | "main": "./index.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/netgum/archanova.git" 11 | }, 12 | "scripts": { 13 | "lint": "tslint --project ./tsconfig.json --exclude ./packages/**/*.d.ts ./packages/**/*.ts", 14 | "bootstrap": "lerna bootstrap -- --no-package-lock", 15 | "clean": "lerna clean --yes && lerna run clean --stream", 16 | "prebuild": "npm run bootstrap", 17 | "build": "lerna run --stream build --ignore \"@archanova/sdk-playground\"", 18 | "compile": "lerna run compile --stream", 19 | "precompile:watch": "npm run compile", 20 | "compile:watch": "lerna run compile:watch --parallel", 21 | "test": "npm run lint", 22 | "start:sdk:playground": "lerna run --stream --scope \"@archanova/sdk-playground\" start", 23 | "build:sdk:playground": "lerna run --stream --scope \"@archanova/sdk-playground\" build", 24 | "deploy:sdk:playground": "lerna run --stream --scope \"@archanova/sdk-playground\" deploy" 25 | }, 26 | "dependencies": { 27 | "cross-env": "^5.2.0", 28 | "lerna": "^3.15.0", 29 | "tslint": "^5.16.0", 30 | "tslint-config-airbnb": "^5.11.1", 31 | "tsutils": "^3.10.0", 32 | "typescript": "^3.4.5" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/cli/.gitignore: -------------------------------------------------------------------------------- 1 | example 2 | -------------------------------------------------------------------------------- /packages/cli/.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | .* 3 | !.npmignore 4 | /src 5 | tsconfig* 6 | -------------------------------------------------------------------------------- /packages/cli/README.md: -------------------------------------------------------------------------------- 1 | # Archanova CLI 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | 5 | ## Installation 6 | 7 | ```bash 8 | $ npm i @archanova/cli -g 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```bash 14 | $ archanova-cli [action] [options] [workingPath] 15 | ``` 16 | 17 | **Actions:** 18 | * `auth` - authentication 19 | * `init` - initialize application 20 | * `develop` - develop application 21 | * `deploy` - deploy application 22 | 23 | **Options:** 24 | * `--help, -h` - print help 25 | * `--global, -g` - use global storage 26 | * `--env, -e ` - environment [main,ropsten,rinkeby,kovan,sokol,xdai,local] (default: main) 27 | * `--local-env-host ` - local environment host 28 | * `--local-env-port ` - local environment port 29 | * `--private-key ` - device private key 30 | 31 | 32 | ## License 33 | 34 | The MIT License 35 | 36 | [npm-image]: https://badge.fury.io/js/%40archanova%2Fcli.svg 37 | [npm-url]: https://npmjs.org/package/@archanova/cli 38 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@archanova/cli", 3 | "version": "1.1.2", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/netgum/archanova.git" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/netgum/archanova/issues" 11 | }, 12 | "bin": { 13 | "archanova-cli": "./build/bin.js" 14 | }, 15 | "description": "Archanova CLI", 16 | "scripts": { 17 | "clean": "rimraf ./build", 18 | "compile": "tsc --project ./tsconfig.build.json --rootDir ./src", 19 | "compile:watch": "npm run compile -- --watch --preserveWatchOutput", 20 | "prebuild": "npm run clean", 21 | "build": "npm run compile" 22 | }, 23 | "dependencies": { 24 | "@archanova/sdk": "^1.1.2", 25 | "@netgum/types": "^0.1.8", 26 | "@netgum/utils": "^0.1.3", 27 | "@types/body-parser": "^1.17.0", 28 | "@types/chalk": "^2.2.0", 29 | "@types/node": "^12.0.10", 30 | "@types/express": "^4.17.0", 31 | "@types/fs-extra": "^8.0.0", 32 | "@types/react": "^16.8.22", 33 | "@types/webpack-env": "^1.13.9", 34 | "@types/ws": "^6.0.1", 35 | "body-parser": "^1.19.0", 36 | "bn.js": "^4.11.8", 37 | "chalk": "^2.4.2", 38 | "express": "^4.17.1", 39 | "fs-extra": "^8.0.1", 40 | "ink": "^2.3.0", 41 | "ink-box": "^1.0.0", 42 | "ink-link": "^1.0.0", 43 | "ink-spinner": "^3.0.1", 44 | "ink-text-input": "^3.1.1", 45 | "meow": "^5.0.0", 46 | "ngrok": "^3.2.1", 47 | "qrcode-terminal": "^0.12.0", 48 | "react": "^16.8.6", 49 | "react-dom": "^16.8.6", 50 | "rxjs": "6.4.0", 51 | "rxjs-addons": "^0.0.4", 52 | "ws": "^7.0.1" 53 | }, 54 | "devDependencies": { 55 | "rimraf": "^2.6.3" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/cli/src/bin.tsx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { createLocalSdkEnvironment, getSdkEnvironment, SdkEnvironmentNames, sdkModules } from '@archanova/sdk'; 4 | import { render } from 'ink'; 5 | import React from 'react'; 6 | import Ws from 'ws'; 7 | import { getCliConfig } from './cli'; 8 | import context from './context'; 9 | import { Main } from './Main'; 10 | import { SdkService, ServerService, StorageService, TemplateService } from './services'; 11 | 12 | const config = getCliConfig(); 13 | 14 | let sdkEnv: sdkModules.Environment; 15 | 16 | if (config.env === 'local') { 17 | sdkEnv = createLocalSdkEnvironment({ 18 | ...config.localEnv, 19 | }); 20 | } 21 | 22 | if (!sdkEnv) { 23 | sdkEnv = getSdkEnvironment(config.env as any) || getSdkEnvironment(SdkEnvironmentNames.Main); 24 | } 25 | 26 | const storageService = new StorageService({ 27 | scope: config.scope, 28 | workingPath: config.workingPath, 29 | }); 30 | 31 | storageService.setNamespace(sdkEnv.getConfig('storageOptions').namespace); 32 | 33 | const sdkService = new SdkService( 34 | sdkEnv 35 | .setConfig('storageAdapter', storageService.toSdkAdapter()) 36 | .setConfig('apiWebSocketConstructor', Ws), 37 | ); 38 | 39 | const serverService = new ServerService(config.workingPath); 40 | const templateService = new TemplateService(config.workingPath); 41 | 42 | render( 43 | 52 |
53 | , 54 | ); 55 | -------------------------------------------------------------------------------- /packages/cli/src/cli.ts: -------------------------------------------------------------------------------- 1 | import { SdkEnvironmentNames } from '@archanova/sdk'; 2 | import { anyToBuffer, verifyPrivateKey } from '@netgum/utils'; 3 | import meow from 'meow'; 4 | import { resolve } from 'path'; 5 | import { Actions, Scopes } from './constants'; 6 | import { IConfig } from './interfaces'; 7 | 8 | const { input: inputs, flags }: { 9 | input: string[]; 10 | flags: { 11 | env: SdkEnvironmentNames | 'local'; 12 | global: boolean; 13 | help: boolean; 14 | localEnvHost: string; 15 | localEnvPort: string; 16 | privateKey: string; 17 | }; 18 | } = meow({ 19 | booleanDefault: false, 20 | autoHelp: false, 21 | autoVersion: false, 22 | flags: { 23 | env: { 24 | type: 'string', 25 | alias: 'e', 26 | default: SdkEnvironmentNames.Main, 27 | }, 28 | global: { 29 | type: 'boolean', 30 | alias: 'g', 31 | }, 32 | help: { 33 | type: 'boolean', 34 | alias: 'h', 35 | }, 36 | localEnvHost: { 37 | type: 'string', 38 | default: null, 39 | }, 40 | localEnvPort: { 41 | type: 'string', 42 | default: null, 43 | }, 44 | privateKey: { 45 | type: 'string', 46 | default: null, 47 | }, 48 | }, 49 | }); 50 | 51 | const supportedEnvs = [...Object.values(SdkEnvironmentNames), 'local']; 52 | const supportedActions = Object.values(Actions); 53 | 54 | /** 55 | * gets cli config 56 | * @return IConfig 57 | */ 58 | export function getCliConfig(): IConfig { 59 | const privateKey: Buffer = anyToBuffer(flags.privateKey, { defaults: null }); 60 | let action: Actions = null; 61 | let workingPath = process.cwd(); 62 | 63 | for (const input of inputs) { 64 | if (supportedActions.includes(input)) { 65 | action = input as any; 66 | } else { 67 | if ( 68 | input.startsWith('/') || 69 | input.startsWith('.') 70 | ) { 71 | workingPath = resolve(input); 72 | } 73 | break; 74 | } 75 | } 76 | 77 | if (!supportedEnvs.includes(flags.env)) { 78 | throw new Error('Unsupported env'); // TODO: add error handler 79 | } 80 | 81 | if (privateKey && !verifyPrivateKey(privateKey)) { 82 | throw new Error('Invalid private key'); // TODO: add error handler 83 | } 84 | 85 | return { 86 | action, 87 | privateKey, 88 | workingPath, 89 | scope: flags.global ? Scopes.Global : Scopes.Local, 90 | env: flags.env, 91 | localEnv: { 92 | host: flags.localEnvHost, 93 | port: parseInt(flags.localEnvPort, 10) || null, 94 | }, 95 | showHelp: !action || flags.help, 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /packages/cli/src/components/QrCode.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box, BoxProps } from 'ink'; 3 | import { generate } from 'qrcode-terminal'; 4 | 5 | export interface IProps extends BoxProps { 6 | url: string; 7 | small?: boolean; 8 | } 9 | 10 | export interface IState { 11 | data: string; 12 | } 13 | 14 | export class QrCode extends React.Component { 15 | public static defaultProps: Partial = { 16 | small: false, 17 | }; 18 | 19 | public state = { 20 | data: '', 21 | }; 22 | 23 | public componentWillReceiveProps(nextProps: Readonly): void { 24 | this.generateFromProps(nextProps); 25 | } 26 | 27 | public componentWillMount(): void { 28 | this.generateFromProps(this.props); 29 | } 30 | 31 | public render(): any { 32 | const { data } = this.state; 33 | const { url, small, ...props } = this.props; 34 | 35 | return ( 36 | 37 | {data} 38 | 39 | ); 40 | } 41 | 42 | private generateFromProps({ url, small }: IProps): void { 43 | generate(url, { small }, (data) => { 44 | this.setState({ 45 | data, 46 | }); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/cli/src/components/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box, BoxProps, Color } from 'ink'; 3 | import InkSpinner from 'ink-spinner'; 4 | 5 | export interface IProps extends BoxProps { 6 | children: string; 7 | } 8 | 9 | export class Spinner extends React.Component { 10 | public render(): any { 11 | const { children, ...props } = this.props; 12 | 13 | return ( 14 | 15 | 16 | 17 | 18 | {` ${children.trim()}`} 19 | 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { Form } from './Form'; 2 | export { QrCode } from './QrCode'; 3 | export { Spinner } from './Spinner'; 4 | -------------------------------------------------------------------------------- /packages/cli/src/constants.ts: -------------------------------------------------------------------------------- 1 | export enum Actions { 2 | Auth = 'auth', 3 | Init = 'init', 4 | Develop = 'develop', 5 | Deploy = 'deploy', 6 | } 7 | 8 | export enum Scopes { 9 | Local = 'local', 10 | Global = 'global', 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/src/containers/AuthAction.tsx: -------------------------------------------------------------------------------- 1 | import { sdkInterfaces, sdkConstants } from '@archanova/sdk'; 2 | import React from 'react'; 3 | import { Box, Color } from 'ink'; 4 | import TextInput from 'ink-text-input'; 5 | import { QrCode } from '../components'; 6 | import { ContextComponent } from '../context'; 7 | 8 | interface IState { 9 | account: sdkInterfaces.IAccount; 10 | url: string; 11 | code: string; 12 | } 13 | 14 | export class AuthAction extends ContextComponent<{}, IState> { 15 | public state: IState = { 16 | account: null, 17 | url: null, 18 | code: '', 19 | }; 20 | 21 | public componentWillMount(): void { 22 | const { sdkService } = this.context; 23 | 24 | this.addSubscriptions( 25 | sdkService 26 | .state 27 | .account$ 28 | .subscribe(account => this.setState({ 29 | account, 30 | url: account ? null : sdkService.createRequestAddAccountDeviceUrl(), 31 | })), 32 | ); 33 | 34 | this.codeChanged = this.codeChanged.bind(this); 35 | this.codeSubmitted = this.codeSubmitted.bind(this); 36 | } 37 | 38 | public componentWillUnmount(): void { 39 | super.componentWillUnmount(); 40 | } 41 | 42 | public render(): any { 43 | let result: React.ReactNode = null; 44 | 45 | const { url, account, code } = this.state; 46 | 47 | if (account && account.type !== sdkConstants.AccountTypes.Developer) { 48 | result = ( 49 | 50 | 51 | Developer Program Invitation Code 52 | 53 | 58 | 59 | ); 60 | } else if (url) { 61 | result = ( 62 | 63 | 64 | 65 | ); 66 | } 67 | 68 | return result; 69 | } 70 | 71 | private codeChanged(code: string): void { 72 | this.setState({ 73 | code, 74 | }); 75 | } 76 | 77 | private codeSubmitted(): void { 78 | const { code } = this.state; 79 | const { sdkService } = this.context; 80 | 81 | if (!code) { 82 | return; 83 | } 84 | 85 | this.setState({ 86 | code: '', 87 | }, () => this.wrapAsync(async () => { 88 | await sdkService.becomeDeveloper(code); 89 | })); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /packages/cli/src/containers/Completed.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Color} from 'ink'; 3 | 4 | export class Completed extends React.Component { 5 | public componentDidMount(): void { 6 | setTimeout(() => { 7 | process.exit(); 8 | }, 500); 9 | } 10 | 11 | public render(): any { 12 | return ( 13 | 14 | Completed! 15 | 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/src/containers/DeployAction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { SdkError } from '@archanova/sdk'; 3 | import { Box } from 'ink'; 4 | import { Form } from '../components'; 5 | import { ContextComponent } from '../context'; 6 | import { SdkService } from '../services'; 7 | import { Completed } from './Completed'; 8 | 9 | interface IState { 10 | app: SdkService.IApp; 11 | errors: { [key: string]: any }; 12 | completed: boolean; 13 | } 14 | 15 | export class DeployAction extends ContextComponent<{}, IState> { 16 | public state: IState = { 17 | errors: {}, 18 | app: null, 19 | completed: false, 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.formSubmitted = this.formSubmitted.bind(this); 24 | 25 | const { sdkService: { state: { app } } } = this.context; 26 | 27 | this.setState({ 28 | app, 29 | }); 30 | } 31 | 32 | public render(): any { 33 | let result: React.ReactNode = null; 34 | const { app, completed, errors } = this.state; 35 | 36 | if (completed) { 37 | result = ( 38 | 39 | ); 40 | } else if (app) { 41 | result = ( 42 | 43 |
58 | 59 | ); 60 | } 61 | 62 | return result; 63 | } 64 | 65 | private formSubmitted(values: any): void { 66 | const { sdkService } = this.context; 67 | 68 | this.wrapAsync(async () => { 69 | try { 70 | const app = await sdkService.updateDeveloperApp(values); 71 | 72 | this.setState({ 73 | app, 74 | completed: true, 75 | }); 76 | } catch (err) { 77 | if ( 78 | SdkError.isSdkError(err) && 79 | err.type === SdkError.Types.Http && 80 | err.data 81 | ) { 82 | this.setState({ 83 | errors: err.data, 84 | }); 85 | } 86 | } 87 | }); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/cli/src/containers/DevelopAction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box, Color } from 'ink'; 3 | import { ContextComponent } from '../context'; 4 | import { Spinner } from '../components'; 5 | import { SdkService } from '../services'; 6 | import Link from 'ink-link'; 7 | 8 | interface IState { 9 | app: SdkService.IApp; 10 | oldCallbackUrl: string; 11 | } 12 | 13 | export class DevelopAction extends ContextComponent<{}, IState> { 14 | public state: IState = { 15 | app: null, 16 | oldCallbackUrl: null, 17 | }; 18 | 19 | public componentWillMount(): void { 20 | this.exitHandler = this.exitHandler.bind(this); 21 | 22 | const { sdkService, templateService, serverService } = this.context; 23 | let { app } = sdkService.state; 24 | const { callbackUrl: oldCallbackUrl } = app; 25 | 26 | this.wrapAsync(async () => { 27 | 28 | if (!await templateService.templateExists()) { 29 | await templateService.createTemplate(app); 30 | } 31 | 32 | const callbackUrl = await serverService.start(); 33 | 34 | app = await sdkService.updateDeveloperApp({ 35 | callbackUrl, 36 | }); 37 | 38 | this.setState({ 39 | app, 40 | oldCallbackUrl, 41 | }); 42 | 43 | process.on('SIGINT', this.exitHandler); 44 | }); 45 | } 46 | 47 | public componentWillUnmount(): void { 48 | process.removeListener('SIGINT', this.exitHandler); 49 | } 50 | 51 | public render(): any { 52 | const { app } = this.state; 53 | return app 54 | ? ( 55 | 56 | Temporary Callback URL 57 | {app.callbackUrl} 58 | 59 | ) 60 | : ( 61 | Starting Local Server... 62 | ); 63 | } 64 | 65 | private exitHandler(): void { 66 | const { sdkService, serverService } = this.context; 67 | const { oldCallbackUrl: callbackUrl } = this.state; 68 | 69 | this.wrapAsync(async () => { 70 | 71 | try { 72 | await sdkService.updateDeveloperApp({ 73 | callbackUrl, 74 | }); 75 | 76 | await serverService.stop(); 77 | } catch (err) { 78 | // 79 | } 80 | 81 | setTimeout(() => { 82 | process.exit(); 83 | }, 500); 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/cli/src/containers/Help.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Box } from 'ink'; 3 | import chalk from 'chalk'; 4 | import { ContextComponent } from '../context'; 5 | import { Actions } from '../constants'; 6 | 7 | const HELP_OPTIONS = chalk` 8 | {magenta Options} 9 | {cyan --help, -h } print help 10 | {cyan --global, -g } use global scope 11 | {cyan --env, -e } environment [main,ropsten,rinkeby,kovan,sokol,xdai,local] (default: main) 12 | {cyan --local-env-host } local environment host 13 | {cyan --local-env-port } local environment port 14 | {cyan --private-key } device private key`; 15 | 16 | const defaultHelp = chalk` 17 | {magenta Usage} {cyan archanova-cli} [action] [options] [workingPath] 18 | 19 | ${chalk.magenta('Actions')} 20 | {cyan ${Actions.Auth}} authentication 21 | {cyan ${Actions.Init}} initialize application 22 | {cyan ${Actions.Develop}} develop application 23 | {cyan ${Actions.Deploy}} deploy application 24 | ${HELP_OPTIONS} 25 | `; 26 | 27 | function buildActionHelp(action: Actions): string { 28 | return chalk` 29 | {magenta Usage} {cyan archanova-cli} {cyanBright ${action}} [options] [workingPath] 30 | ${HELP_OPTIONS} 31 | `; 32 | } 33 | 34 | export class Help extends ContextComponent { 35 | public render(): any { 36 | const { config: { action } } = this.context; 37 | let help: string = null; 38 | 39 | if (!action) { 40 | help = defaultHelp; 41 | } else { 42 | help = buildActionHelp(action); 43 | } 44 | 45 | return ( 46 | 47 | {help.trim()} 48 | 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/cli/src/containers/InitAction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { SdkError } from '@archanova/sdk'; 3 | import { Box } from 'ink'; 4 | import { Form } from '../components'; 5 | import { ContextComponent } from '../context'; 6 | 7 | interface IState { 8 | errors: { [key: string]: any }; 9 | } 10 | 11 | export class InitAction extends ContextComponent<{}, IState> { 12 | public state: IState = { 13 | errors: {}, 14 | }; 15 | 16 | public componentWillMount(): void { 17 | this.formSubmitted = this.formSubmitted.bind(this); 18 | } 19 | 20 | public componentWillUnmount(): void { 21 | // 22 | } 23 | 24 | public render(): any { 25 | const { errors } = this.state; 26 | 27 | return ( 28 | 29 | 41 | 42 | ); 43 | } 44 | 45 | private formSubmitted(values: any): void { 46 | const { sdkService, templateService } = this.context; 47 | 48 | this.wrapAsync(async () => { 49 | try { 50 | const app = await sdkService.createDeveloperApp(values); 51 | if (!await templateService.templateExists()) { 52 | await templateService.createTemplate(app); 53 | } 54 | } catch (err) { 55 | if ( 56 | SdkError.isSdkError(err) && 57 | err.type === SdkError.Types.Http && 58 | err.data 59 | ) { 60 | this.setState({ 61 | errors: err.data, 62 | }); 63 | } 64 | } 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/cli/src/containers/Summary.tsx: -------------------------------------------------------------------------------- 1 | import { sdkInterfaces, sdkConstants } from '@archanova/sdk'; 2 | import { Box, Color } from 'ink'; 3 | import React from 'react'; 4 | import { ContextComponent } from '../context'; 5 | import { SdkService } from '../services'; 6 | 7 | interface IState { 8 | account: sdkInterfaces.IAccount; 9 | app: SdkService.IApp; 10 | device: sdkInterfaces.IDevice; 11 | } 12 | 13 | export class Summary extends ContextComponent<{}, IState> { 14 | public state: IState = { 15 | account: null, 16 | app: null, 17 | device: null, 18 | }; 19 | 20 | public componentWillMount(): void { 21 | const { sdkService: { state: { app$, account$, device$ } } } = this.context; 22 | 23 | this.addSubscriptions( 24 | app$ 25 | .subscribe(app => this.setState({ 26 | app, 27 | })), 28 | account$ 29 | .subscribe(account => this.setState({ 30 | account, 31 | })), 32 | device$ 33 | .subscribe(device => this.setState({ 34 | device, 35 | })), 36 | ); 37 | } 38 | 39 | public componentWillUnmount(): void { 40 | super.componentWillUnmount(); 41 | } 42 | 43 | public render(): any { 44 | const { app, account, device } = this.state; 45 | 46 | return ( 47 | 48 | {!device ? null : ( 49 | 50 | 51 | {'Device '} 52 | 53 | {device.address} 54 | 55 | )} 56 | {!account ? null : ( 57 | 58 | 59 | {'Account '} 60 | 61 | {account.address} 62 | {account.type === sdkConstants.AccountTypes.Developer ? null : ( 63 | 64 | {' (Non-Developer)'} 65 | 66 | )} 67 | 68 | )} 69 | {!app ? null : ( 70 | 71 | 72 | {'Application '} 73 | 74 | {app.name} 75 | 76 | {` (${app.alias})`} 77 | 78 | 79 | )} 80 | 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/cli/src/containers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AuthAction'; 2 | export * from './InitAction'; 3 | export * from './DevelopAction'; 4 | export * from './DeployAction'; 5 | export * from './Summary'; 6 | export * from './Help'; 7 | export * from './Completed'; 8 | -------------------------------------------------------------------------------- /packages/cli/src/context/ContextComponent.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Subscription } from 'rxjs'; 3 | import { IContextProps } from './interfaces'; 4 | import { context } from './context'; 5 | 6 | export abstract class ContextComponent

extends React.Component { 7 | public static contextType = context; 8 | 9 | public context: IContextProps; 10 | private subscriptions: Subscription[] = []; 11 | 12 | public abstract render(): any; 13 | 14 | public componentWillUnmount(): void { 15 | for (const subscription of this.subscriptions) { 16 | subscription.unsubscribe(); 17 | } 18 | } 19 | 20 | protected wrapAsync(fun: () => Promise): void { 21 | fun().catch(err => console.error(err)); 22 | } 23 | 24 | protected addSubscriptions(...subscriptions: Subscription[]): void { 25 | this.subscriptions = [ 26 | ...this.subscriptions, 27 | ...subscriptions, 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/src/context/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { IContextProps } from './interfaces'; 3 | 4 | export const context = createContext(null); 5 | -------------------------------------------------------------------------------- /packages/cli/src/context/index.ts: -------------------------------------------------------------------------------- 1 | export { context as default } from './context'; 2 | export * from './interfaces'; 3 | export * from './ContextComponent'; 4 | -------------------------------------------------------------------------------- /packages/cli/src/context/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { IConfig } from '../interfaces'; 2 | import { 3 | SdkService, 4 | ServerService, 5 | StorageService, 6 | TemplateService, 7 | } from '../services'; 8 | 9 | export interface IContextProps { 10 | config: IConfig; 11 | serverService: ServerService; 12 | sdkService: SdkService; 13 | storageService: StorageService; 14 | templateService: TemplateService; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | -------------------------------------------------------------------------------- /packages/cli/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { SdkEnvironmentNames } from '@archanova/sdk'; 2 | import { Actions, Scopes } from './constants'; 3 | 4 | export interface IConfig { 5 | action?: Actions; 6 | scope: Scopes; 7 | env: SdkEnvironmentNames | 'local'; 8 | localEnv: { 9 | host: string; 10 | port: number; 11 | }; 12 | workingPath?: string; 13 | showHelp?: boolean; 14 | privateKey?: Buffer; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/services/TemplateService.ts: -------------------------------------------------------------------------------- 1 | import { resolve, join } from 'path'; 2 | import { readdir, readFile, writeFile, stat, ensureDir, pathExists } from 'fs-extra'; 3 | import { SdkService } from './SdkService'; 4 | 5 | export class TemplateService { 6 | private static SRC_DIR = resolve(__dirname, '../../template'); 7 | 8 | constructor(private workingPath: string) { 9 | // 10 | } 11 | 12 | public templateExists(): Promise { 13 | return pathExists( 14 | join(this.workingPath, 'package.json'), 15 | ); 16 | } 17 | 18 | public async createTemplate(app: SdkService.IApp): Promise { 19 | const fileNames = await readdir(TemplateService.SRC_DIR); 20 | const copyMap: { 21 | src: string; 22 | dest: string; 23 | }[] = []; 24 | 25 | for (const fileName of fileNames) { 26 | const filePath = join(TemplateService.SRC_DIR, fileName); 27 | const fileStat = await stat(filePath); 28 | 29 | if (fileStat.isDirectory()) { 30 | const subFileNames = await readdir(filePath); 31 | 32 | await ensureDir(join(this.workingPath, fileName)); 33 | 34 | for (const subFileName of subFileNames) { 35 | const subFilePath = join(filePath, subFileName); 36 | const subFileStat = await stat(subFilePath); 37 | 38 | if (!subFileStat.isDirectory()) { 39 | copyMap.push({ 40 | src: subFilePath, 41 | dest: join(this.workingPath, fileName, subFileName), 42 | }); 43 | } 44 | } 45 | } else { 46 | copyMap.push({ 47 | src: filePath, 48 | dest: join(this.workingPath, fileName), 49 | }); 50 | } 51 | } 52 | 53 | for (const { src, dest } of copyMap) { 54 | let content = await readFile(src, 'utf8'); 55 | 56 | if (app) { 57 | content = content.replace( 58 | new RegExp('\\$\\{([a-zA-Z\\.]+)\\}', 'ig'), 59 | (result: string, found: string) => { 60 | switch (found) { 61 | case 'app.name': 62 | result = app.name; 63 | break; 64 | 65 | case 'app.description': 66 | result = app.description || ''; 67 | break; 68 | 69 | case 'app.alias': 70 | result = app.alias; 71 | break; 72 | } 73 | 74 | return result; 75 | }, 76 | ); 77 | } 78 | 79 | await writeFile(dest, content, 'utf8'); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/cli/src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SdkService'; 2 | export * from './ServerService'; 3 | export * from './StorageService'; 4 | export * from './TemplateService'; 5 | -------------------------------------------------------------------------------- /packages/cli/template/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | WORKDIR /app 4 | 5 | COPY package.json . 6 | 7 | RUN npm i 8 | 9 | COPY src ./src 10 | 11 | CMD [ "npm", "start"] 12 | -------------------------------------------------------------------------------- /packages/cli/template/README.md: -------------------------------------------------------------------------------- 1 | # ${app.name} 2 | 3 | ${app.description} 4 | 5 | ## Usage 6 | 7 | ```bash 8 | $ npm start 9 | ``` 10 | -------------------------------------------------------------------------------- /packages/cli/template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "${app.alias}", 3 | "private": true, 4 | "description": "${app.description}", 5 | "version": "0.0.1", 6 | "main": "./src/main.js", 7 | "scripts": { 8 | "start": "node ." 9 | }, 10 | "dependencies": { 11 | "body-parser": "^1.19.0", 12 | "express": "^4.17.1" 13 | }, 14 | "devDependencies": { 15 | "@types/body-parser": "^1.17.0", 16 | "@types/node": "^12.0.10", 17 | "@types/express": "^4.17.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/template/src/config.d.ts: -------------------------------------------------------------------------------- 1 | export interface IConfig { 2 | server: { 3 | port: number; 4 | }; 5 | } 6 | 7 | const config: IConfig; 8 | 9 | export = config; 10 | -------------------------------------------------------------------------------- /packages/cli/template/src/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | server: { 3 | port: parseInt(process.env.PORT, 10) || 0, // 0 by default 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/cli/template/src/handlers.d.ts: -------------------------------------------------------------------------------- 1 | export interface IGetResponse { 2 | version: string; 3 | } 4 | 5 | export interface IPostBody { 6 | player?: 'Creator' | 'Opponent' | null; 7 | nextData: string; 8 | nextTime: number; 9 | previousData?: string | null; 10 | previousTime?: number | null; 11 | now?: number | null; 12 | } 13 | 14 | export interface IPostResponse { 15 | whoseTurn: 'Creator' | 'Opponent' | null; 16 | winner: 'Creator' | 'Opponent' | null; 17 | } 18 | 19 | export declare function get(): IGetResponse; 20 | 21 | export declare function post(body: IPostBody): Promise; 22 | -------------------------------------------------------------------------------- /packages/cli/template/src/handlers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * GET / 3 | * @returns {IGetResponse} 4 | */ 5 | function get() { 6 | return { 7 | name: '${app.name}', 8 | alias: '${app.alias}', 9 | version: '0.0.1', 10 | }; 11 | } 12 | 13 | /** 14 | * POST / 15 | * @param body IPostBody 16 | * @returns {Promise} 17 | */ 18 | async function post(body) { 19 | const { 20 | player, 21 | nextData, 22 | nextTime, 23 | previousData, 24 | previousTime, 25 | now, 26 | } = body; 27 | 28 | let whoseTurn = null; 29 | let winner = null; 30 | 31 | // initial move 32 | if (!player) { 33 | whoseTurn = 'Opponent'; 34 | } else { 35 | 36 | switch (player) { 37 | case 'Creator': 38 | if (nextData === '0x01') { 39 | winner = 'Creator'; 40 | } else { 41 | whoseTurn = 'Opponent'; 42 | } 43 | break; 44 | 45 | case 'Opponent': 46 | if (nextData === '0x01') { 47 | winner = 'Opponent'; 48 | } else { 49 | whoseTurn = 'Creator'; 50 | } 51 | break; 52 | } 53 | } 54 | 55 | return { 56 | whoseTurn, 57 | winner, 58 | }; 59 | } 60 | 61 | module.exports = { 62 | get, 63 | post, 64 | }; 65 | -------------------------------------------------------------------------------- /packages/cli/template/src/logger.d.ts: -------------------------------------------------------------------------------- 1 | export interface ILogger { 2 | info(name: string, ...args: any[]): void; 3 | 4 | error(name: string, err: any): void; 5 | } 6 | 7 | const logger: ILogger; 8 | 9 | export = logger; 10 | -------------------------------------------------------------------------------- /packages/cli/template/src/logger.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | info(name, ...args) { 3 | console.info(name, ...args); 4 | }, 5 | error(name, err) { 6 | console.error(name, err); 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/template/src/main.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('http'); 2 | const express = require('express'); 3 | const bodyParser = require('body-parser'); 4 | const config = require('./config'); 5 | const logger = require('./logger'); 6 | const { get, post } = require('./handlers'); 7 | 8 | const app = express(); 9 | const server = createServer(app); 10 | 11 | app.get('/', (req, res, next) => { 12 | try { 13 | const data = get(); 14 | res.send(data); 15 | } catch (err) { 16 | next(err); 17 | } 18 | }); 19 | app.post('/', bodyParser.json({}), (req, res, next) => { 20 | try { 21 | post(req.body) 22 | .then((data) => { 23 | if (!data) { 24 | res.status(400); 25 | res.send({ 26 | error: 'bad request', 27 | }); 28 | } else { 29 | res.send(data); 30 | } 31 | }) 32 | .catch(next); 33 | } catch (err) { 34 | next(err); 35 | } 36 | }); 37 | 38 | app.use((err, req, res, next) => { 39 | logger.error('request error', err); 40 | 41 | res.status(500); 42 | res.send({ 43 | error: 'internal server error', 44 | }); 45 | }); 46 | 47 | server.listen(config.server.port, (err) => { 48 | if (err) { 49 | logger.error('server error', err); 50 | } else { 51 | const { port } = server.address(); 52 | 53 | logger.info('listening on port:', port); 54 | } 55 | }); 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "outDir": "./build" 5 | }, 6 | "exclude": [ 7 | "./src/**/*.test.ts" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "compilerOptions": { 4 | "jsx": "react", 5 | "typeRoots": [ 6 | "./node_modules/@types", 7 | "./node_modules/@netgum/types/ink", 8 | "./node_modules/@netgum/types/node" 9 | ] 10 | }, 11 | "include": [ 12 | "./src/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/sdk-playground/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | /build* 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | .env 26 | -------------------------------------------------------------------------------- /packages/sdk-playground/README.md: -------------------------------------------------------------------------------- 1 | # Archanova SDK Playground 2 | 3 | ## Installation 4 | 5 | ```bash 6 | $ git clone https://github.com/netgum/archanova.git 7 | $ cd ./archanova 8 | $ npm i 9 | $ npm run bootstrap 10 | $ npm run compile 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```bash 16 | $ npm run start:sdk:playground 17 | ``` 18 | 19 | ## Configuration via `env` variables 20 | 21 | | Name | Default Value | Options | 22 | | --- | ---| ---| 23 | | `REACT_APP_ACTIVATE_HELP` | `0` | `0,1` | 24 | | `REACT_APP_ACTIVATE_MAIN_SDK_ENV` | `0` | `0,1` | 25 | | `REACT_APP_ACTIVATE_LOCAL_SDK_ENV` | `0` | `0,1` | 26 | | `REACT_APP_ACTIVATE_XDAI_SDK_ENV` | `0` | `0,1` | 27 | | `REACT_APP_LOCAL_SDK_ENV_PORT` | `8880` | `-` | 28 | | `REACT_APP_AUTO_INITIALIZE_SDK` | `1` | `0,1` | 29 | | `REACT_APP_AUTO_ACCEPT_SDK_ACTIONS` | `1` | `0,1` | 30 | 31 | ## License 32 | 33 | The MIT License 34 | -------------------------------------------------------------------------------- /packages/sdk-playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@archanova/sdk-playground", 3 | "version": "1.1.2", 4 | "private": true, 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/netgum/archanova.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/netgum/archanova/issues" 12 | }, 13 | "description": "Archanova Tutorial", 14 | "dependencies": { 15 | "@archanova/contracts": "^1.0.0", 16 | "@archanova/sdk": "^1.1.2", 17 | "@netgum/types": "^0.1.8", 18 | "@netgum/utils": "^0.1.3", 19 | "@types/react": "^16.8.17", 20 | "@types/react-dom": "^16.8.4", 21 | "@types/react-redux": "^7.0.9", 22 | "@types/markdown-it": "^0.0.7", 23 | "@types/node": "^12.0.0", 24 | "@types/webpack-env": "^1.13.9", 25 | "bn.js": "^4.11.8", 26 | "highlight.js": "^9.15.6", 27 | "markdown-it": "^8.4.2", 28 | "qrcode.react": "^0.9.3", 29 | "react": "^16.8.6", 30 | "react-dom": "^16.8.6", 31 | "react-highlight": "^0.12.0", 32 | "react-scripts": "3.0.1", 33 | "react-redux": "^7.0.3", 34 | "redux": "^4.0.1", 35 | "redux-devtools-extension": "^2.13.8", 36 | "react-inspector": "^3.0.2", 37 | "rxjs": "6.4.0", 38 | "node-sass": "^4.11.0", 39 | "normalize-scss": "^7.0.1", 40 | "webpack": "4.29.6" 41 | }, 42 | "scripts": { 43 | "start": "react-scripts start", 44 | "build": "./scripts/build.sh", 45 | "predeploy": "npm run build", 46 | "deploy": "./scripts/deploy.sh" 47 | }, 48 | "browserslist": { 49 | "production": [ 50 | ">0.2%", 51 | "not dead", 52 | "not op_mini all" 53 | ], 54 | "development": [ 55 | "last 1 chrome version", 56 | "last 1 firefox version", 57 | "last 1 safari version" 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/sdk-playground/public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netgum/archanova/cf72eb34db6fcdc6977d0b8ddab2171cda52c2bc/packages/sdk-playground/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /packages/sdk-playground/public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netgum/archanova/cf72eb34db6fcdc6977d0b8ddab2171cda52c2bc/packages/sdk-playground/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /packages/sdk-playground/public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netgum/archanova/cf72eb34db6fcdc6977d0b8ddab2171cda52c2bc/packages/sdk-playground/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /packages/sdk-playground/public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netgum/archanova/cf72eb34db6fcdc6977d0b8ddab2171cda52c2bc/packages/sdk-playground/public/favicon/favicon.ico -------------------------------------------------------------------------------- /packages/sdk-playground/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Archanova SDK Playground 13 | 18 | 19 | 20 | 21 |

22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/sdk-playground/scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ROOT_DIR=$(dirname $0) 4 | 5 | cd "${ROOT_DIR}/.." 6 | 7 | export REACT_APP_ACTIVATE_HELP=0 8 | export REACT_APP_ACTIVATE_MAIN_SDK_ENV=0 9 | export REACT_APP_ACTIVATE_LOCAL_SDK_ENV=0 10 | export REACT_APP_ACTIVATE_XDAI_SDK_ENV=0 11 | export REACT_APP_LOCAL_SDK_ENV_PORT=8880 12 | export REACT_APP_AUTO_INITIALIZE_SDK=1 13 | export REACT_APP_AUTO_ACCEPT_SDK_ACTIONS=1 14 | 15 | rm -r -f ./build 16 | ./node_modules/.bin/react-scripts build 17 | -------------------------------------------------------------------------------- /packages/sdk-playground/scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ROOT_DIR=$(dirname $0) 4 | 5 | cd "${ROOT_DIR}/.." 6 | 7 | aws s3 sync ./build s3://archanova-playground 8 | aws cloudfront create-invalidation --distribution-id E101MSN0MKTQD4 --paths "/*" 9 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/App.module.scss: -------------------------------------------------------------------------------- 1 | .ribbon { 2 | position: fixed; 3 | top: 0; 4 | right: 0; 5 | z-index: 1000; 6 | } 7 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Content, Console, StatusBar, Help, Preloader } from './containers'; 3 | import styles from './App.module.scss'; 4 | 5 | export default class App extends React.Component { 6 | 7 | public render() { 8 | return ( 9 | 10 | 11 | Fork me on GitHub 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Button.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 7px 20px; 3 | border-width: 0; 4 | background-color: #6024FC; 5 | color: white; 6 | font-weight: bold; 7 | &:disabled { 8 | opacity: 0.1; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './Button.module.scss'; 3 | 4 | interface IProps { 5 | onClick?: () => any; 6 | disabled?: boolean; 7 | } 8 | 9 | export class Button extends React.Component { 10 | public render(): any { 11 | const { children, disabled, onClick } = this.props; 12 | return ( 13 | 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Code.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | font-size: 12px; 3 | font-family: Menlo, sans-serif; 4 | padding: 2px; 5 | background-color: white; 6 | box-shadow: 10px 0 10px rgba(0, 0, 0, 0.2); 7 | code { 8 | font-family: Menlo, sans-serif; 9 | font-size: 11px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Code.tsx: -------------------------------------------------------------------------------- 1 | import 'highlight.js/styles/a11y-light.css'; 2 | import 'highlight.js/lib/languages/javascript'; 3 | import 'highlight.js/lib/languages/json'; 4 | 5 | import React from 'react'; 6 | import Highlight from 'react-highlight'; 7 | import styles from './Code.module.scss'; 8 | 9 | interface IProps { 10 | language: 'javascript' | 'json'; 11 | children: string; 12 | } 13 | 14 | export class Code extends React.Component { 15 | public render(): any { 16 | const { language, children } = this.props; 17 | 18 | let empty = false; 19 | const code = children 20 | .trim() 21 | .split('\n') 22 | .filter((line) => { 23 | let result = true; 24 | if (!line.trim()) { 25 | if (empty) { 26 | result = false; 27 | } else { 28 | empty = true; 29 | } 30 | } else { 31 | empty = false; 32 | } 33 | return result; 34 | }) 35 | .join('\n'); 36 | 37 | return ( 38 |
39 | 40 | {code} 41 | 42 |
43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Example.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 20px; 3 | h3 { 4 | text-transform: uppercase; 5 | font-weight: bolder; 6 | padding-bottom: 10px; 7 | } 8 | h5 { 9 | text-transform: uppercase; 10 | color: #6024FC; 11 | } 12 | > div { 13 | padding-top: 5px; 14 | padding-bottom: 10px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Example.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button } from './Button'; 3 | import { Code } from './Code'; 4 | import styles from './Example.module.scss'; 5 | 6 | interface IProps { 7 | title?: string; 8 | code: string; 9 | enabled: boolean; 10 | run: () => any; 11 | } 12 | 13 | export class Example extends React.Component { 14 | 15 | public render(): any { 16 | const { title, code, run, enabled, children } = this.props; 17 | return ( 18 |
19 | {!title ? null : ( 20 |

{title}

21 | )} 22 | {children ? ( 23 | 24 |
PARAMETERS
25 |
26 | {children} 27 |
28 |
29 | ) : null} 30 |
CODE
31 |
32 | 33 | {code} 34 | 35 | 36 |
37 |
38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/HelpTrigger.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: relative; 3 | & > .dot { 4 | position: absolute; 5 | } 6 | 7 | &.menu:hover > .dot { 8 | width: 40px; 9 | height: 1px; 10 | right: -15px; 11 | top: 0; 12 | border-top: 10px solid transparent; 13 | border-bottom: 10px solid transparent; 14 | border-right: 10px solid white; 15 | } 16 | 17 | &.statusBar:hover > .dot { 18 | bottom: -11px; 19 | left: 50%; 20 | margin-left: -10px; 21 | width: 1px; 22 | height: 40px; 23 | border-left: 10px solid transparent; 24 | border-right: 10px solid transparent; 25 | border-bottom: 10px solid white; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputCheckBox.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 5px; 3 | label { 4 | cursor: pointer; 5 | } 6 | 7 | span { 8 | padding-left: 7px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputCheckBox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './InputCheckBox.module.scss'; 3 | 4 | interface IProps { 5 | label: string; 6 | checked: boolean; 7 | onChange?: (checked: boolean) => any; 8 | } 9 | 10 | export class InputCheckBox extends React.Component { 11 | 12 | componentWillMount(): void { 13 | this.onChangeHandler = this.onChangeHandler.bind(this); 14 | } 15 | 16 | public render(): any { 17 | const { label, checked } = this.props; 18 | 19 | return ( 20 |
21 | 29 |
30 | ); 31 | } 32 | 33 | private onChangeHandler(event: React.SyntheticEvent): void { 34 | const { onChange } = this.props; 35 | 36 | if (onChange) { 37 | const { checked } = event.currentTarget; 38 | onChange(checked); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputGasPriceStrategy.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { sdkConstants } from '@archanova/sdk'; 3 | import { InputSelect } from './InputSelect'; 4 | 5 | interface IProps { 6 | selected: any; 7 | onChange?: (value: any) => any; 8 | } 9 | 10 | export class InputGasPriceStrategy extends React.Component { 11 | public static selectedToText(selected: any): string { 12 | let result: string = null; 13 | 14 | if (selected === sdkConstants.GasPriceStrategies.Fast) { 15 | result = 'sdkConstants.GasPriceStrategies.Fast'; 16 | } 17 | 18 | return result; 19 | } 20 | 21 | private static values: string[] = [ 22 | sdkConstants.GasPriceStrategies.Avg, 23 | sdkConstants.GasPriceStrategies.Fast, 24 | ]; 25 | 26 | public render(): any { 27 | const { selected, onChange } = this.props; 28 | 29 | return ( 30 | 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputSelect.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 5px; 3 | 4 | div { 5 | padding-bottom: 2px; 6 | } 7 | select { 8 | padding: 7px; 9 | border-width: 0; 10 | border-radius: 0; 11 | width: 414px; 12 | font-size: 12px; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputSelect.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './InputSelect.module.scss'; 3 | 4 | interface IProps { 5 | label: string; 6 | selected: string; 7 | values: string[]; 8 | onChange?: (value: any) => any; 9 | } 10 | 11 | export class InputSelect extends React.Component { 12 | componentWillMount(): void { 13 | this.onChangeHandler = this.onChangeHandler.bind(this); 14 | } 15 | 16 | public render(): any { 17 | const { label, values, selected } = this.props; 18 | 19 | return ( 20 |
21 |
{label}
22 | 35 |
36 | ); 37 | } 38 | 39 | private onChangeHandler(event: React.SyntheticEvent): void { 40 | const { onChange, values } = this.props; 41 | if (onChange) { 42 | const { selectedIndex } = event.currentTarget; 43 | if (values[selectedIndex]) { 44 | onChange(values[selectedIndex]); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputText.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 5px; 3 | 4 | div { 5 | padding-bottom: 4px; 6 | } 7 | input { 8 | padding: 7px; 9 | border-width: 0; 10 | } 11 | input[type="number"] { 12 | width: 100px; 13 | } 14 | input[type="text"] { 15 | width: 400px; 16 | } 17 | input[readonly] { 18 | color: #6c6c6c !important; 19 | background-color: #d9bc5e; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/InputText.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './InputText.module.scss'; 3 | import { Button } from './Button'; 4 | 5 | interface IProps { 6 | label: string; 7 | value: string; 8 | readOnly?: boolean; 9 | type?: 'text' | 'number'; 10 | decimal?: boolean; 11 | onChange?: (value: string, valueParsed: any) => any; 12 | onRandomClick?: () => any; 13 | } 14 | 15 | export class InputText extends React.Component { 16 | public static defaultProps: Partial = { 17 | type: 'text', 18 | }; 19 | 20 | componentWillMount(): void { 21 | this.onChangeHandler = this.onChangeHandler.bind(this); 22 | } 23 | 24 | public render(): any { 25 | const { label, value, type, readOnly, onRandomClick } = this.props; 26 | 27 | return ( 28 |
29 |
{label}
30 | 36 | {!onRandomClick ? null : ( 37 | 38 | )} 39 |
40 | ); 41 | } 42 | 43 | private onChangeHandler(event: React.SyntheticEvent): void { 44 | const { onChange, type, decimal } = this.props; 45 | 46 | if (onChange) { 47 | const { value } = event.currentTarget; 48 | let valueParsed: any = null; 49 | 50 | switch (type) { 51 | case 'number': 52 | if (decimal) { 53 | valueParsed = parseFloat(value) || 0; 54 | } else { 55 | valueParsed = parseInt(value, 10) || 0; 56 | } 57 | if (valueParsed < 0) { 58 | valueParsed = 0; 59 | } 60 | break; 61 | case 'text': 62 | valueParsed = value; 63 | break; 64 | } 65 | 66 | onChange( 67 | value || '', 68 | valueParsed, 69 | ); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/MenuOption.module.scss: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | $color: #cf9eff; 3 | height: 17px; 4 | display: block; 5 | position: relative; 6 | padding-top: 4px; 7 | padding-left: 27px; 8 | cursor: pointer; 9 | font-size: 11px; 10 | 11 | input { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | opacity: 0; 16 | } 17 | 18 | .overlay { 19 | position: absolute; 20 | top: 0; 21 | left: 0; 22 | height: 15px; 23 | width: 15px; 24 | background-color: transparent; 25 | border-radius: 3px; 26 | border: 2px solid $color; 27 | transform: rotate(-90deg); 28 | transition: all 0.3s; 29 | } 30 | 31 | .icon { 32 | color: white; 33 | display: none; 34 | } 35 | 36 | input:checked ~ .overlay { 37 | background-color: $color; 38 | border-radius: 3px; 39 | transform: rotate(0deg); 40 | opacity: 1; 41 | border: 2px solid $color; 42 | } 43 | 44 | input:checked ~ .overlay .icon { 45 | display: block; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/MenuOption.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './MenuOption.module.scss'; 3 | 4 | interface IProps { 5 | checked: boolean; 6 | onToggle: () => any; 7 | children: string; 8 | } 9 | 10 | export class MenuOption extends React.Component { 11 | public render() { 12 | const { checked, onToggle, children } = this.props; 13 | return ( 14 |
15 | 38 |
39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Screen.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: absolute; 3 | left: 250px; 4 | top: 50px; 5 | right: 0; 6 | bottom: 0; 7 | display: flex; 8 | flex: 1; 9 | flex-direction: column; 10 | overflow: auto; 11 | padding: 15px 0 250px 15px; 12 | } 13 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Screen.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './Screen.module.scss'; 3 | import { ContextComponent } from '../shared'; 4 | 5 | interface IProps { 6 | enabled: boolean; 7 | } 8 | 9 | export abstract class Screen extends ContextComponent { 10 | public render(): any { 11 | const content = this.renderContent(); 12 | return ( 13 |
14 | {content} 15 |
16 | ); 17 | } 18 | 19 | public abstract renderContent(): any; 20 | } 21 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Url.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 30px; 3 | h5 { 4 | padding-bottom: 10px; 5 | color: #6024FC; 6 | } 7 | > div { 8 | padding-top: 5px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/Url.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import QrCode from 'qrcode.react'; 3 | import { Button } from './Button'; 4 | import styles from './Url.module.scss'; 5 | 6 | interface IProps { 7 | mobile?: string; 8 | redirect?: string; 9 | } 10 | 11 | export class Url extends React.Component { 12 | public componentWillMount(): void { 13 | this.clickHandler = this.clickHandler.bind(this); 14 | } 15 | 16 | public render(): any { 17 | const { mobile, redirect } = this.props; 18 | return ( 19 |
20 |
21 |
SCAN USING SMARTSAFE APP
22 |
23 | 24 |
25 |
26 | {!redirect ? null : ( 27 |
28 | 29 |
30 | )} 31 |
32 | ); 33 | } 34 | 35 | private clickHandler(): void { 36 | const { redirect } = this.props; 37 | document.location = redirect as any; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Button'; 2 | export * from './Example'; 3 | export * from './HelpTrigger'; 4 | export * from './InputCheckBox'; 5 | export * from './InputSelect'; 6 | export * from './InputText'; 7 | export * from './InputGasPriceStrategy'; 8 | export * from './Menu'; 9 | export * from './Screen'; 10 | export * from './Url'; 11 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/configure.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createSdk, 3 | Sdk, 4 | reduxSdkReducer, 5 | createReduxSdkMiddleware, 6 | } from '@archanova/sdk'; 7 | import { applyMiddleware, createStore, Store, combineReducers } from 'redux'; 8 | import { composeWithDevTools } from 'redux-devtools-extension'; 9 | import { filter } from 'rxjs/operators'; 10 | import { ILogger, buildSdkEnv } from './shared'; 11 | import { config } from './config'; 12 | 13 | export function configureSdk(logger: ILogger): Sdk { 14 | const sdk = createSdk( 15 | buildSdkEnv(config.sdkEnv), 16 | ); 17 | 18 | sdk 19 | .event$ 20 | .pipe(filter(value => !!value)) 21 | .subscribe(event => console.log('sdk.event$', event)); 22 | 23 | sdk 24 | .error$ 25 | .pipe(filter(value => !!value)) 26 | .subscribe(err => console.error('sdk.error$', err)); 27 | 28 | if (config.autoInitializeSdk) { 29 | logger 30 | .wrapSync('sdk.initialize', async (console) => { 31 | await sdk.initialize(); 32 | console.log('initialized'); 33 | }); 34 | } 35 | 36 | return sdk; 37 | } 38 | 39 | export function configureStore(sdk: Sdk): Store { 40 | return createStore( 41 | combineReducers({ 42 | sdk: reduxSdkReducer, 43 | }), 44 | {}, 45 | composeWithDevTools(applyMiddleware( 46 | createReduxSdkMiddleware(sdk), 47 | )), 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Console.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: fixed; 3 | bottom: 0; 4 | left: 250px; 5 | right: 0; 6 | max-height: 250px; 7 | min-height: 70px; 8 | display: flex; 9 | flex-direction: column; 10 | background: white; 11 | padding: 10px 0; 12 | box-shadow: 10px 0 10px rgba(0, 0, 0, 0.2); 13 | } 14 | 15 | .tabs { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | height: 30px; 20 | display: flex; 21 | flex-direction: row; 22 | 23 | button { 24 | cursor: pointer; 25 | border-width: 0; 26 | padding: 0 15px; 27 | background-color: white; 28 | 29 | &.active { 30 | font-weight: bold; 31 | } 32 | } 33 | } 34 | 35 | .content { 36 | display: flex; 37 | flex-direction: column; 38 | flex: 1; 39 | overflow-y: auto; 40 | padding-top: 30px; 41 | 42 | > div { 43 | padding: 10px; 44 | border-bottom: 1px solid #E8E8E8; 45 | 46 | &:last-child { 47 | border-bottom: 0; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Content.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | min-width: 1200px; 8 | } 9 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Help.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: fixed; 3 | background-color: white; 4 | padding: 15px; 5 | z-index: 10; 6 | 7 | &.statusBar { 8 | left: 250px; 9 | top: 50px; 10 | right: 0; 11 | box-shadow: 0 10px 10px rgba(0, 0, 0, 0.2); 12 | } 13 | 14 | &.menu { 15 | left: 250px; 16 | top: 0; 17 | bottom: 0; 18 | min-width: 250px; 19 | box-shadow: 10px 0 10px rgba(0, 0, 0, 0.2); 20 | } 21 | 22 | h1 { 23 | font-size: 14px; 24 | color: #6024FC; 25 | } 26 | 27 | h1, h2, h3, h4 { 28 | padding-bottom: 10px; 29 | border-bottom: 1px solid #eeeeee; 30 | } 31 | 32 | ul, li { 33 | margin: 0; 34 | padding: 0; 35 | } 36 | 37 | li { 38 | padding: 5px; 39 | margin-left: 15px; 40 | list-style: disc; 41 | } 42 | 43 | code { 44 | background-color: rgba(27,31,35,.05); 45 | border-radius: 3px; 46 | font-size: 85%; 47 | margin: 0; 48 | padding: .2em .4em; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Help.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Subscription } from 'rxjs'; 3 | import MarkdownIt from 'markdown-it'; 4 | import { ContextComponent } from '../shared'; 5 | import styles from './Help.module.scss'; 6 | import help from '../help'; 7 | 8 | interface IState { 9 | alias: string; 10 | visible: boolean; 11 | } 12 | 13 | export default class Help extends ContextComponent<{}, IState> { 14 | public state = { 15 | alias: null, 16 | visible: false, 17 | }; 18 | 19 | private markdownIt: MarkdownIt = null; 20 | private subscriptions: Subscription[] = []; 21 | 22 | public componentWillMount(): void { 23 | this.markdownIt = new MarkdownIt(); 24 | this.subscriptions = [ 25 | this 26 | .config 27 | .showHelp$ 28 | .subscribe(visible => this.setState({ 29 | visible, 30 | })), 31 | this 32 | .help 33 | .stream$ 34 | .subscribe(alias => this.setState({ 35 | alias, 36 | })), 37 | ]; 38 | this.setState({ 39 | visible: this.context.config.showHelp, 40 | }); 41 | } 42 | 43 | public componentWillUnmount(): void { 44 | for (const subscription of this.subscriptions) { 45 | subscription.unsubscribe(); 46 | } 47 | } 48 | 49 | public render() { 50 | const { alias, visible } = this.state; 51 | 52 | if ( 53 | !visible || 54 | !alias || 55 | !help[alias] 56 | ) { 57 | return null; 58 | } 59 | 60 | const classNames: string[] = [ 61 | styles.content, 62 | ]; 63 | 64 | switch (this.prefix) { 65 | case 'menu': 66 | classNames.push(styles.menu); 67 | break; 68 | case 'statusBar': 69 | classNames.push(styles.statusBar); 70 | break; 71 | } 72 | 73 | const html = this.markdownIt.render(help[alias].trim()); 74 | 75 | return ( 76 |
80 | ); 81 | } 82 | 83 | private get prefix(): string { 84 | const { alias } = this.state; 85 | 86 | return alias 87 | ? alias.split('.')[0] 88 | : null; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Preloader.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | background-color: rgba(0, 0, 0, 0.2); 8 | z-index: 200; 9 | } 10 | 11 | .ring { 12 | display: inline-block; 13 | width: 64px; 14 | height: 64px; 15 | } 16 | 17 | .ring:after { 18 | position: absolute; 19 | top: 50%; 20 | left: 50%; 21 | margin: 1px; 22 | margin-left: -25px; 23 | content: " "; 24 | display: block; 25 | width: 50px; 26 | height: 50px; 27 | border-radius: 50%; 28 | border: 5px solid #F3CF48; 29 | border-color: #F3CF48 transparent #F3CF48 transparent; 30 | animation: ringKF 1.2s linear infinite; 31 | } 32 | 33 | @keyframes ringKF { 34 | 0% { 35 | transform: rotate(0deg); 36 | } 37 | 100% { 38 | transform: rotate(360deg); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/Preloader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Subscription } from 'rxjs'; 3 | import { ContextComponent } from '../shared'; 4 | import styles from './Preloader.module.scss'; 5 | 6 | interface IState { 7 | show: boolean; 8 | } 9 | 10 | export default class Preloader extends ContextComponent<{}, IState> { 11 | public state = { 12 | show: false, 13 | }; 14 | 15 | private subscription: Subscription = null; 16 | 17 | public componentWillMount(): void { 18 | this.subscription = this 19 | .logger 20 | .pending$ 21 | .subscribe(show => this.setState({ show })); 22 | } 23 | 24 | public componentWillUnmount(): void { 25 | this.subscription.unsubscribe(); 26 | } 27 | 28 | public render() { 29 | const { show } = this.state; 30 | 31 | return !show ? null : ( 32 |
33 |
34 |
35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/StatusBar.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | position: fixed; 3 | top: 0; 4 | left: 250px; 5 | right: 0; 6 | height: 50px; 7 | min-width: 1200px; 8 | font-size: 9px; 9 | padding: 0 15px; 10 | box-shadow: 10px 0 10px rgba(0, 0, 0, 0.2); 11 | color: white; 12 | display: flex; 13 | flex-direction: row; 14 | align-items: center; 15 | background-color: #6024FC; 16 | 17 | > div { 18 | flex-direction: column; 19 | margin-right: 20px; 20 | 21 | .label { 22 | font-weight: bold; 23 | color: #cd9eff; 24 | padding-bottom: 2px; 25 | text-transform: uppercase; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/StatusBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ISdkReduxState } from '@archanova/sdk'; 3 | import { connect } from 'react-redux'; 4 | import { HelpTrigger } from '../components'; 5 | import { formatBalance } from '../shared'; 6 | import styles from './StatusBar.module.scss'; 7 | 8 | interface IProps { 9 | sdk: ISdkReduxState; 10 | } 11 | 12 | class StatusBar extends React.Component { 13 | public render() { 14 | const { sdk: { account, accountDevice, device, eth } } = this.props; 15 | const network = eth && eth.networkName ? eth.networkName : 'Unknown'; 16 | 17 | return ( 18 |
19 | 20 |
Network
21 |
{network}
22 |
23 | {!account || !accountDevice ? null : ( 24 | 25 | 26 |
Account Address
27 |
{account ? account.address : 'Unknown'}
28 |
29 | 30 |
Account State
31 |
{account ? account.state : 'Unknown'}
32 |
33 | 34 |
Account Balance (real)
35 |
36 | {formatBalance(account && account.balance.real ? account.balance.real : null)} 37 |
38 |
39 | 40 |
Account Balance (virtual)
41 |
42 | {formatBalance(account && account.balance.virtual ? account.balance.virtual : null)} 43 |
44 |
45 | 46 |
Account Device State
47 |
{accountDevice ? accountDevice.state : 'None'}
48 |
49 |
50 | )} 51 | 52 |
Device Address
53 |
{device ? device.address : 'Unknown'}
54 |
55 |
56 | ); 57 | } 58 | } 59 | 60 | export default connect( 61 | state => state, 62 | )(StatusBar); 63 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/account/CreateAccount.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | import { generateRandomEnsLabel, mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (ensLabel: string) => ` 6 | ${ensLabel ? `const ensLabel = "${ensLabel}";` : ''} 7 | 8 | sdk 9 | .createAccount(${mergeMethodArgs(ensLabel && 'ensLabel')}) 10 | .then(account => console.log('account', account)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | ensLabel: string; 16 | } 17 | 18 | export class CreateAccount extends Screen { 19 | public state = { 20 | ensLabel: '', 21 | }; 22 | 23 | public componentWillMount(): void { 24 | this.run = this.run.bind(this); 25 | 26 | this.ensLabelChanged = this.ensLabelChanged.bind(this); 27 | this.generateEnsLabel = this.generateEnsLabel.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { ensLabel } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private ensLabelChanged(ensLabel: string): void { 53 | this.setState({ 54 | ensLabel, 55 | }); 56 | } 57 | 58 | private generateEnsLabel(): void { 59 | this.setState({ 60 | ensLabel: generateRandomEnsLabel(), 61 | }); 62 | } 63 | 64 | private run(): void { 65 | const { ensLabel } = this.state; 66 | this 67 | .logger 68 | .wrapSync('sdk.createAccount', async (console) => { 69 | console.log('account', await this.sdk.createAccount(ensLabel || null)); 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/account/DisconnectAccount.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .disconnectAccount() 7 | .then(() => console.log('disconnected')) 8 | .catch(console.error); 9 | `; 10 | 11 | export class DisconnectAccount extends Screen { 12 | 13 | public componentWillMount(): void { 14 | this.run = this.run.bind(this); 15 | } 16 | 17 | public renderContent(): any { 18 | const { enabled } = this.props; 19 | return ( 20 |
21 | 27 |
28 | ); 29 | } 30 | 31 | private run(): void { 32 | this 33 | .logger 34 | .wrapSync('sdk.disconnectAccount', async (console) => { 35 | await this.sdk.disconnectAccount(); 36 | console.log('disconnected'); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/account/SearchAccount.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (ensName: string, address: string) => ` 5 | const options = { 6 | ${address ? `address: "${address}"` : `ensName: ${ensName ? `"${ensName}"` : 'null'}`}, 7 | }; 8 | 9 | sdk 10 | .searchAccount(options) 11 | .then(account => console.log('account', account)) 12 | .catch(console.error); 13 | `; 14 | 15 | interface IState { 16 | ensName: string; 17 | address: string; 18 | } 19 | 20 | export class SearchAccount extends Screen { 21 | public state = { 22 | ensName: '', 23 | address: '', 24 | }; 25 | 26 | public componentWillMount(): void { 27 | this.run = this.run.bind(this); 28 | 29 | this.ensNameChanged = this.ensNameChanged.bind(this); 30 | this.addressChanged = this.addressChanged.bind(this); 31 | } 32 | 33 | public renderContent(): any { 34 | const { enabled } = this.props; 35 | const { ensName, address } = this.state; 36 | return ( 37 |
38 | 44 | 49 | 54 | 55 |
56 | ); 57 | } 58 | 59 | private ensNameChanged(ensName: string): void { 60 | this.setState({ 61 | ensName, 62 | }); 63 | } 64 | 65 | private addressChanged(address: string): void { 66 | this.setState({ 67 | address, 68 | }); 69 | } 70 | 71 | private run(): void { 72 | const { ensName, address } = this.state; 73 | this 74 | .logger 75 | .wrapSync('sdk.createAccount', async (console) => { 76 | console.log('account', await this.sdk.searchAccount({ 77 | ensName, 78 | address, 79 | })); 80 | }); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/account/UpdateAccount.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { generateRandomEnsLabel } from '../../shared'; 4 | 5 | const code = (ensLabel: string) => ` 6 | const ensLabel = ${ensLabel ? `"${ensLabel}"` : 'null'}; 7 | 8 | sdk 9 | .updateAccount(ensLabel) 10 | .then(account => console.log('account', account)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | ensLabel: string; 16 | } 17 | 18 | export class UpdateAccount extends Screen { 19 | public state = { 20 | ensLabel: generateRandomEnsLabel(), 21 | }; 22 | 23 | public componentWillMount(): void { 24 | this.run = this.run.bind(this); 25 | 26 | this.ensLabelChanged = this.ensLabelChanged.bind(this); 27 | this.generateEnsLabel = this.generateEnsLabel.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { ensLabel } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private ensLabelChanged(ensLabel: string): void { 53 | this.setState({ 54 | ensLabel, 55 | }); 56 | } 57 | 58 | private generateEnsLabel(): void { 59 | this.setState({ 60 | ensLabel: generateRandomEnsLabel(), 61 | }); 62 | } 63 | 64 | private run(): void { 65 | const { ensLabel } = this.state; 66 | this 67 | .logger 68 | .wrapSync('sdk.updateAccount', async (console) => { 69 | console.log('account', await this.sdk.updateAccount(ensLabel)); 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/account/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SearchAccount'; 2 | export * from './CreateAccount'; 3 | export * from './ConnectAccount'; 4 | export * from './UpdateAccount'; 5 | export * from './DisconnectAccount'; 6 | export * from './DeployAccount'; 7 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/CreateAccountDevice.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | import { generateRandomAddress } from '../../shared'; 4 | 5 | const code = (address: string) => ` 6 | const deviceAddress = ${address ? `"${address}"` : 'null'}; 7 | 8 | sdk 9 | .createAccountDevice(deviceAddress) 10 | .then(accountDevice => console.log('accountDevice', accountDevice)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | address: string; 16 | } 17 | 18 | export class CreateAccountDevice extends Screen { 19 | public state = { 20 | address: '', 21 | }; 22 | 23 | public componentWillMount(): void { 24 | this.run = this.run.bind(this); 25 | 26 | this.addressChanged = this.addressChanged.bind(this); 27 | this.generateAddress = this.generateAddress.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { address } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private addressChanged(address: string): void { 53 | this.setState({ 54 | address, 55 | }); 56 | } 57 | 58 | private generateAddress(): void { 59 | this.setState({ 60 | address: generateRandomAddress(), 61 | }); 62 | } 63 | 64 | private run(): void { 65 | const { address } = this.state; 66 | this 67 | .logger 68 | .wrapSync('sdk.createAccount', async (console) => { 69 | console.log('accountDevice', await this.sdk.createAccountDevice(address)); 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/GetAccountDevice.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (accountAddress: string, deviceAddress: string) => ` 5 | const accountAddress = ${accountAddress ? `"${accountAddress}"` : 'null'}; 6 | const deviceAddress = ${deviceAddress ? `"${deviceAddress}"` : 'null'}; 7 | 8 | sdk 9 | .getAccountDevice(accountAddress, deviceAddress) 10 | .then(accountDevice => console.log('accountDevice', accountDevice)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | accountAddress: string; 16 | deviceAddress: string; 17 | } 18 | 19 | export class GetAccountDevice extends Screen { 20 | public state = { 21 | accountAddress: '', 22 | deviceAddress: '', 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.accountAddressChanged = this.accountAddressChanged.bind(this); 29 | this.deviceAddressChanged = this.deviceAddressChanged.bind(this); 30 | } 31 | 32 | public renderContent(): any { 33 | const { enabled } = this.props; 34 | const { accountAddress, deviceAddress } = this.state; 35 | return ( 36 |
37 | 43 | 49 | 55 | 56 |
57 | ); 58 | } 59 | 60 | private accountAddressChanged(accountAddress: string): void { 61 | this.setState({ 62 | accountAddress, 63 | }); 64 | } 65 | private deviceAddressChanged(deviceAddress: string): void { 66 | this.setState({ 67 | deviceAddress, 68 | }); 69 | } 70 | 71 | private run(): void { 72 | const { accountAddress, deviceAddress } = this.state; 73 | this 74 | .logger 75 | .wrapSync('sdk.getAccountDevice', async (console) => { 76 | console.log('accountDevice', await this.sdk.getAccountDevice( 77 | accountAddress, 78 | deviceAddress, 79 | )); 80 | }); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/GetConnectedAccountDevice.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (address: string) => ` 5 | const address = ${address ? `"${address}"` : 'null'}; 6 | 7 | sdk 8 | .getConnectedAccountDevice(address) 9 | .then(accountDevice => console.log('accountDevice', accountDevice)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | address: string; 15 | } 16 | 17 | export class GetConnectedAccountDevice extends Screen { 18 | public state = { 19 | address: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.addressChanged = this.addressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { address } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private addressChanged(address: string): void { 51 | this.setState({ 52 | address, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { address } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getConnectedAccountDevice', async (console) => { 61 | console.log('accountDevice', await this.sdk.getConnectedAccountDevice(address)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/GetConnectedAccountDevices.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (page = 0) => ` 6 | ${page ? `const page = ${page};` : ''} 7 | 8 | sdk 9 | .getConnectedAccountDevices(${mergeMethodArgs(page && 'page')}) 10 | .then(accountDevices => console.log('accountDevices', accountDevices)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | page: string; 16 | pageParsed: number; 17 | } 18 | 19 | export class GetConnectedAccountDevices extends Screen { 20 | public state = { 21 | page: '0', 22 | pageParsed: 0, 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.pageChanged = this.pageChanged.bind(this); 29 | } 30 | 31 | public renderContent(): any { 32 | const { enabled } = this.props; 33 | const { page, pageParsed } = this.state; 34 | return ( 35 |
36 | 42 | 48 | 49 |
50 | ); 51 | } 52 | 53 | private pageChanged(page: string, pageParsed: number) { 54 | this.setState({ 55 | page, 56 | pageParsed, 57 | }); 58 | } 59 | 60 | private run(): void { 61 | const { pageParsed } = this.state; 62 | this 63 | .logger 64 | .wrapSync('sdk.getConnectedAccountDevices', async (console) => { 65 | console.log('accountDevices', await this.sdk.getConnectedAccountDevices(pageParsed)); 66 | }); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/RemoveAccountDevice.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (address: string) => ` 5 | const deviceAddress = ${address ? `"${address}"` : 'null'}; 6 | 7 | sdk 8 | .removeAccountDevice(deviceAddress) 9 | .then(success => console.log('success', success)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | address: string; 15 | } 16 | 17 | export class RemoveAccountDevice extends Screen { 18 | public state = { 19 | address: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.addressChanged = this.addressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { address } = this.state; 31 | return ( 32 |
33 | 39 | 44 | 45 |
46 | ); 47 | } 48 | 49 | private addressChanged(address: string): void { 50 | this.setState({ 51 | address, 52 | }); 53 | } 54 | 55 | private run(): void { 56 | const { address } = this.state; 57 | this 58 | .logger 59 | .wrapSync('sdk.removeAccountDevice', async (console) => { 60 | console.log('success', await this.sdk.removeAccountDevice(address)); 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountDevice/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetConnectedAccountDevices'; 2 | export * from './GetConnectedAccountDevice'; 3 | export * from './GetAccountDevice'; 4 | export * from './CreateAccountDevice'; 5 | export * from './RemoveAccountDevice'; 6 | export * from './DeployAccountDevice'; 7 | export * from './UnDeployAccountDevice'; 8 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/CancelAccountFriendRecovery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .cancelAccountFriendRecovery() 7 | .then(() => console.log('account friend recovery canceled')) 8 | .catch(console.error); 9 | `; 10 | 11 | export class CancelAccountFriendRecovery extends Screen { 12 | public componentWillMount(): void { 13 | this.run = this.run.bind(this); 14 | } 15 | 16 | public renderContent(): any { 17 | const { enabled } = this.props; 18 | return ( 19 |
20 | 26 |
27 | ); 28 | } 29 | 30 | private run(): void { 31 | this 32 | .logger 33 | .wrapSync('sdk.cancelAccountFriendRecovery', async (console) => { 34 | await this.sdk.cancelAccountFriendRecovery(); 35 | console.log('account friend recovery canceled'); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/CollectAccountFriendSignature.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (friendAddress: string, friendSignature: string) => ` 5 | const friendAddress = ${friendAddress ? `"${friendAddress}"` : 'null'}; 6 | const friendSignature = ${friendSignature ? `"${friendSignature}"` : 'null'}; 7 | 8 | sdk 9 | .collectAccountFriendSignature(friendAddress, friendSignature) 10 | .then(accountFriendRecovery => console.log('accountFriendRecovery', accountFriendRecovery)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | friendAddress: string; 16 | friendSignature: string; 17 | } 18 | 19 | export class CollectAccountFriendSignature extends Screen { 20 | public state = { 21 | friendAddress: '', 22 | friendSignature: '', 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.friendAddressChanged = this.friendAddressChanged.bind(this); 29 | this.friendSignatureChanged = this.friendSignatureChanged.bind(this); 30 | } 31 | 32 | public renderContent(): any { 33 | const { enabled } = this.props; 34 | const { friendAddress, friendSignature } = this.state; 35 | return ( 36 |
37 | 43 | 49 | 55 | 56 |
57 | ); 58 | } 59 | 60 | private friendAddressChanged(friendAddress: string): void { 61 | this.setState({ 62 | friendAddress, 63 | }); 64 | } 65 | 66 | private friendSignatureChanged(friendSignature: string): void { 67 | this.setState({ 68 | friendSignature, 69 | }); 70 | } 71 | 72 | private run(): void { 73 | const { friendAddress, friendSignature } = this.state; 74 | this 75 | .logger 76 | .wrapSync('sdk.collectAccountFriendSignature', async (console) => { 77 | console.log('accountFriendRecovery', await this.sdk.collectAccountFriendSignature( 78 | friendAddress, 79 | friendSignature, 80 | )); 81 | }); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/GetAccountFriendRecovery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (address: string) => ` 5 | const accountAddress = ${address ? `"${address}"` : 'null'}; 6 | 7 | sdk 8 | .getAccountFriendRecovery(accountAddress) 9 | .then(accountFriendRecovery => console.log('accountFriendRecovery', accountFriendRecovery)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | address: string; 15 | } 16 | 17 | export class GetAccountFriendRecovery extends Screen { 18 | public state = { 19 | address: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.addressChanged = this.addressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { address } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private addressChanged(address: string): void { 51 | this.setState({ 52 | address, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { address } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getAccountFriendRecovery', async (console) => { 61 | console.log('accountFriendRecovery', await this.sdk.getAccountFriendRecovery(address)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/GetConnectedAccountFriendRecoveryExtension.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .getConnectedAccountFriendRecoveryExtension() 7 | .then(extension => console.log('extension', extension)) 8 | .catch(console.error); 9 | `; 10 | 11 | export class GetConnectedAccountFriendRecoveryExtension extends Screen { 12 | public componentWillMount(): void { 13 | this.run = this.run.bind(this); 14 | } 15 | 16 | public renderContent(): any { 17 | const { enabled } = this.props; 18 | return ( 19 |
20 | 26 |
27 | ); 28 | } 29 | 30 | private run(): void { 31 | this 32 | .logger 33 | .wrapSync('sdk.getConnectedAccountFriendRecoveryExtension', async (console) => { 34 | console.log('extension', await this.sdk.getConnectedAccountFriendRecoveryExtension()); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/StartAccountFriendRecovery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (accountAddress: string) => ` 5 | const accountAddress = ${accountAddress ? `"${accountAddress}"` : 'null'}; 6 | 7 | sdk 8 | .startAccountFriendRecovery(accountAddress) 9 | .then(accountFriendRecovery => console.log('accountFriendRecovery', accountFriendRecovery)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | accountAddress: string; 15 | } 16 | 17 | export class StartAccountFriendRecovery extends Screen { 18 | public state = { 19 | accountAddress: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.accountAddressChanged = this.accountAddressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { accountAddress } = this.state; 31 | return ( 32 |
33 | 39 | 44 | 45 |
46 | ); 47 | } 48 | 49 | private accountAddressChanged(accountAddress: string): void { 50 | this.setState({ 51 | accountAddress, 52 | }); 53 | } 54 | 55 | private run(): void { 56 | const { accountAddress } = this.state; 57 | this 58 | .logger 59 | .wrapSync('sdk.startAccountFriendRecovery', async (console) => { 60 | console.log('accountFriendRecovery', await this.sdk.startAccountFriendRecovery(accountAddress)); 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/SubmitAccountFriendRecovery.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .submitAccountFriendRecovery() 7 | .then(hash => console.log('hash', hash)) 8 | .catch(console.error); 9 | `; 10 | 11 | export class SubmitAccountFriendRecovery extends Screen { 12 | public componentWillMount(): void { 13 | this.run = this.run.bind(this); 14 | } 15 | 16 | public renderContent(): any { 17 | const { enabled } = this.props; 18 | return ( 19 |
20 | 26 |
27 | ); 28 | } 29 | 30 | private run(): void { 31 | this 32 | .logger 33 | .wrapSync('sdk.submitAccountFriendRecovery', async (console) => { 34 | console.log('hash', await this.sdk.submitAccountFriendRecovery()); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountFriendRecovery/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AddAccountFriendRecoveryExtension'; 2 | export * from './SetupAccountFriendRecoveryExtension'; 3 | export * from './GetConnectedAccountFriendRecoveryExtension'; 4 | export * from './GetAccountFriendRecovery'; 5 | export * from './StartAccountFriendRecovery'; 6 | export * from './CancelAccountFriendRecovery'; 7 | export * from './CollectAccountFriendSignature'; 8 | export * from './SubmitAccountFriendRecovery'; 9 | export * from './SignAccountFriendRecovery'; 10 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/CancelAccountGame.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (id: number) => ` 5 | const gameId = ${id ? id : 'null'}; 6 | 7 | sdk 8 | .cancelAccountGame(gameId) 9 | .then(success => console.log('success', success)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | id: string; 15 | idParsed: number; 16 | } 17 | 18 | export class CancelAccountGame extends Screen { 19 | public state = { 20 | id: '0', 21 | idParsed: 0, 22 | }; 23 | 24 | public componentWillMount(): void { 25 | this.run = this.run.bind(this); 26 | 27 | this.idChanged = this.idChanged.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { id, idParsed } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private idChanged(id: string, idParsed: number): void { 53 | this.setState({ 54 | id, 55 | idParsed, 56 | }); 57 | } 58 | 59 | private run(): void { 60 | const { idParsed } = this.state; 61 | this 62 | .logger 63 | .wrapSync('sdk.cancelAccountGame', async (console) => { 64 | console.log('success', await this.sdk.cancelAccountGame(idParsed)); 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/GetAccountGame.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (id: number) => ` 5 | const gameId = ${id ? id : 'null'}; 6 | 7 | sdk 8 | .getAccountGame(gameId) 9 | .then(game => console.log('game', game)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | id: string; 15 | idParsed: number; 16 | } 17 | 18 | export class GetAccountGame extends Screen { 19 | public state = { 20 | id: '0', 21 | idParsed: 0, 22 | }; 23 | 24 | public componentWillMount(): void { 25 | this.run = this.run.bind(this); 26 | 27 | this.idChanged = this.idChanged.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { id, idParsed } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private idChanged(id: string, idParsed: number): void { 53 | this.setState({ 54 | id, 55 | idParsed, 56 | }); 57 | } 58 | 59 | private run(): void { 60 | const { idParsed } = this.state; 61 | this 62 | .logger 63 | .wrapSync('sdk.createAccountGame', async (console) => { 64 | console.log('game', await this.sdk.getAccountGame(idParsed)); 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/GetConnectedAccountGames.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (appAlias: string, page = 0) => ` 6 | const appAlias = ${appAlias ? `"${appAlias}"` : 'null'}; 7 | ${page ? `const page = ${page};` : ''} 8 | 9 | sdk 10 | .getConnectedAccountGames(${mergeMethodArgs('appAlias', page && 'page')}) 11 | .then(games => console.log('games', games)) 12 | .catch(console.error); 13 | `; 14 | 15 | interface IState { 16 | appAlias: string; 17 | page: string; 18 | pageParsed: number; 19 | } 20 | 21 | export class GetConnectedAccountGames extends Screen { 22 | public state = { 23 | appAlias: 'tictactoe', 24 | page: '0', 25 | pageParsed: 0, 26 | }; 27 | 28 | public componentWillMount(): void { 29 | this.run = this.run.bind(this); 30 | 31 | this.appAliasChanged = this.appAliasChanged.bind(this); 32 | this.pageChanged = this.pageChanged.bind(this); 33 | } 34 | 35 | public renderContent(): any { 36 | const { enabled } = this.props; 37 | const { appAlias, page, pageParsed } = this.state; 38 | return ( 39 |
40 | 46 | 52 | 58 | 59 |
60 | ); 61 | } 62 | 63 | private appAliasChanged(appAlias: string) { 64 | this.setState({ 65 | appAlias, 66 | }); 67 | } 68 | 69 | private pageChanged(page: string, pageParsed: number) { 70 | this.setState({ 71 | page, 72 | pageParsed, 73 | }); 74 | } 75 | 76 | private run(): void { 77 | const { appAlias, pageParsed } = this.state; 78 | this 79 | .logger 80 | .wrapSync('sdk.getConnectedAccountGames', async (console) => { 81 | console.log('games', await this.sdk.getConnectedAccountGames(appAlias, pageParsed)); 82 | }); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/JoinAccountGame.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (id: number) => ` 5 | const gameId = ${id ? id : 'null'}; 6 | 7 | sdk 8 | .joinAccountGame(gameId) 9 | .then(game => console.log('game', game)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | id: string; 15 | idParsed: number; 16 | } 17 | 18 | export class JoinAccountGame extends Screen { 19 | public state = { 20 | id: '0', 21 | idParsed: 0, 22 | }; 23 | 24 | public componentWillMount(): void { 25 | this.run = this.run.bind(this); 26 | 27 | this.idChanged = this.idChanged.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { id, idParsed } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private idChanged(id: string, idParsed: number): void { 53 | this.setState({ 54 | id, 55 | idParsed, 56 | }); 57 | } 58 | 59 | private run(): void { 60 | const { idParsed } = this.state; 61 | this 62 | .logger 63 | .wrapSync('sdk.joinAccountGame', async (console) => { 64 | console.log('game', await this.sdk.joinAccountGame(idParsed)); 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/StartAccountGame.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (id: number) => ` 5 | const gameId = ${id ? id : 'null'}; 6 | 7 | sdk 8 | .startAccountGame(gameId) 9 | .then(game => console.log('game', game)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | id: string; 15 | idParsed: number; 16 | } 17 | 18 | export class StartAccountGame extends Screen { 19 | public state = { 20 | id: '0', 21 | idParsed: 0, 22 | }; 23 | 24 | public componentWillMount(): void { 25 | this.run = this.run.bind(this); 26 | 27 | this.idChanged = this.idChanged.bind(this); 28 | } 29 | 30 | public renderContent(): any { 31 | const { enabled } = this.props; 32 | const { id, idParsed } = this.state; 33 | return ( 34 |
35 | 41 | 47 | 48 |
49 | ); 50 | } 51 | 52 | private idChanged(id: string, idParsed: number): void { 53 | this.setState({ 54 | id, 55 | idParsed, 56 | }); 57 | } 58 | 59 | private run(): void { 60 | const { idParsed } = this.state; 61 | this 62 | .logger 63 | .wrapSync('sdk.startAccountGame', async (console) => { 64 | console.log('game', await this.sdk.startAccountGame(idParsed)); 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/UpdateAccountGame.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (id: number, data: string) => ` 5 | const gameId = ${id ? id : 'null'}; 6 | const data = ${data ? `'${data}'` : 'null'}; 7 | 8 | sdk 9 | .updateAccountGame(gameId, data) 10 | .then(game => console.log('game', game)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | id: string; 16 | idParsed: number; 17 | data: string; 18 | } 19 | 20 | export class UpdateAccountGame extends Screen { 21 | public state = { 22 | id: '0', 23 | idParsed: 0, 24 | data: '', 25 | }; 26 | 27 | public componentWillMount(): void { 28 | this.run = this.run.bind(this); 29 | 30 | this.idChanged = this.idChanged.bind(this); 31 | this.dataChanged = this.dataChanged.bind(this); 32 | } 33 | 34 | public renderContent(): any { 35 | const { enabled } = this.props; 36 | const { id, idParsed, data } = this.state; 37 | return ( 38 |
39 | 45 | 51 | 56 | 57 |
58 | ); 59 | } 60 | 61 | private idChanged(id: string, idParsed: number): void { 62 | this.setState({ 63 | id, 64 | idParsed, 65 | }); 66 | } 67 | 68 | private dataChanged(data: string): void { 69 | this.setState({ 70 | data, 71 | }); 72 | } 73 | 74 | private run(): void { 75 | const { idParsed, data } = this.state; 76 | this 77 | .logger 78 | .wrapSync('sdk.updateAccountGame', async (console) => { 79 | console.log('game', await this.sdk.updateAccountGame(idParsed, data)); 80 | 81 | this.setState({ 82 | data: '', 83 | }); 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountGame/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetConnectedAccountGames'; 2 | export * from './GetAccountGame'; 3 | export * from './CreateAccountGame'; 4 | export * from './JoinAccountGame'; 5 | export * from './StartAccountGame'; 6 | export * from './UpdateAccountGame'; 7 | export * from './CancelAccountGame'; 8 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountPayment/CancelAccountPayment.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (hash: string) => ` 5 | const hash = ${hash ? `"${hash}"` : 'null'}; 6 | 7 | sdk 8 | .cancelAccountPayment(hash) 9 | .then(success => console.log('success', success)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | hash: string; 15 | } 16 | 17 | export class CancelAccountPayment extends Screen { 18 | public state = { 19 | hash: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.hashChanged = this.hashChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { hash } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private hashChanged(hash: string): void { 51 | this.setState({ 52 | hash, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { hash } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.cancelAccountPayment', async (console) => { 61 | console.log('success', await this.sdk.cancelAccountPayment(hash)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountPayment/GetConnectedAccountPayment.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (hash: string) => ` 5 | const hash = ${hash ? `"${hash}"` : 'null'}; 6 | 7 | sdk 8 | .getConnectedAccountPayment(hash) 9 | .then(accountPayment => console.log('accountPayment', accountPayment)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | hash: string; 15 | } 16 | 17 | export class GetConnectedAccountPayment extends Screen { 18 | public state = { 19 | hash: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.hashChanged = this.hashChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { hash } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private hashChanged(hash: string): void { 51 | this.setState({ 52 | hash, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { hash } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getConnectedAccountPayment', async (console) => { 61 | console.log('accountPayment', await this.sdk.getConnectedAccountPayment(hash)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountPayment/GrabAccountPayment.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | import { generateRandomAddress, mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (hash: string, recipient: string) => ` 6 | const hash = ${hash ? `"${hash}"` : 'null'}; 7 | ${recipient ? `const recipient = "${recipient}";` : ''} 8 | 9 | sdk 10 | .grabAccountPayment(${mergeMethodArgs('hash', recipient && 'recipient')}) 11 | .then(accountPayment => console.log('accountPayment', accountPayment)) 12 | .catch(console.error); 13 | `; 14 | 15 | interface IState { 16 | hash: string; 17 | recipient: string; 18 | } 19 | 20 | export class GrabAccountPayment extends Screen { 21 | public state = { 22 | hash: '', 23 | recipient: '', 24 | }; 25 | 26 | public componentWillMount(): void { 27 | this.run = this.run.bind(this); 28 | 29 | this.hashChanged = this.hashChanged.bind(this); 30 | this.recipientChanged = this.recipientChanged.bind(this); 31 | this.generateRecipient = this.generateRecipient.bind(this); 32 | } 33 | 34 | public renderContent(): any { 35 | const { enabled } = this.props; 36 | const { hash, recipient } = this.state; 37 | return ( 38 |
39 | 45 | 51 | 58 | 59 |
60 | ); 61 | } 62 | 63 | private hashChanged(hash: string): void { 64 | this.setState({ 65 | hash, 66 | }); 67 | } 68 | 69 | private recipientChanged(recipient: string): void { 70 | this.setState({ 71 | recipient, 72 | }); 73 | } 74 | 75 | private generateRecipient(): void { 76 | this.setState({ 77 | recipient: generateRandomAddress(), 78 | }); 79 | } 80 | 81 | private run(): void { 82 | const { hash, recipient } = this.state; 83 | this 84 | .logger 85 | .wrapSync('sdk.grabAccountPayment', async (console) => { 86 | console.log('accountPayment', await this.sdk.grabAccountPayment(hash, recipient || null)); 87 | }); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountPayment/SignAccountPayment.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (hash: string) => ` 5 | const hash = ${hash ? `"${hash}"` : 'null'}; 6 | 7 | sdk 8 | .signAccountPayment(hash) 9 | .then(accountPayment => console.log('accountPayment', accountPayment)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | hash: string; 15 | } 16 | 17 | export class SignAccountPayment extends Screen { 18 | public state = { 19 | hash: '', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.hashChanged = this.hashChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { hash } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private hashChanged(hash: string): void { 51 | this.setState({ 52 | hash, 53 | }); 54 | } 55 | 56 | 57 | private run(): void { 58 | const { hash } = this.state; 59 | this 60 | .logger 61 | .wrapSync('sdk.signAccountPayment', async (console) => { 62 | console.log('accountPayment', await this.sdk.signAccountPayment(hash)); 63 | }); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountPayment/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetConnectedAccountPayments'; 2 | export * from './GetConnectedAccountPayment'; 3 | export * from './CreateAccountPayment'; 4 | export * from './SignAccountPayment'; 5 | export * from './GrabAccountPayment'; 6 | export * from './DepositAccountPayment'; 7 | export * from './WithdrawAccountPayment'; 8 | export * from './CancelAccountPayment'; 9 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountTransaction/GetConnectedAccountTransaction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (hash: string, index = 0) => ` 6 | const hash = ${hash ? `"${hash}"` : 'null'}; 7 | ${index ? `const index = ${index};` : ''} 8 | 9 | sdk 10 | .getConnectedAccountTransaction(${mergeMethodArgs('hash', index && 'index')}) 11 | .then(accountTransaction => console.log('accountTransaction', accountTransaction)) 12 | .catch(console.error); 13 | `; 14 | 15 | interface IState { 16 | hash: string; 17 | index: string; 18 | indexParsed: number; 19 | } 20 | 21 | export class GetConnectedAccountTransaction extends Screen { 22 | public state = { 23 | hash: '', 24 | index: '0', 25 | indexParsed: 0, 26 | }; 27 | 28 | public componentWillMount(): void { 29 | this.run = this.run.bind(this); 30 | 31 | this.hashChanged = this.hashChanged.bind(this); 32 | this.indexChanged = this.indexChanged.bind(this); 33 | } 34 | 35 | public renderContent(): any { 36 | const { enabled } = this.props; 37 | const { hash, index, indexParsed } = this.state; 38 | return ( 39 |
40 | 46 | 52 | 58 | 59 |
60 | ); 61 | } 62 | 63 | private hashChanged(hash: string): void { 64 | this.setState({ 65 | hash, 66 | }); 67 | } 68 | private indexChanged(index: string, indexParsed: number) { 69 | this.setState({ 70 | index, 71 | indexParsed, 72 | }); 73 | } 74 | 75 | private run(): void { 76 | const { hash, indexParsed } = this.state; 77 | this 78 | .logger 79 | .wrapSync('sdk.getConnectedAccountTransaction', async (console) => { 80 | console.log('accountTransaction', await this.sdk.getConnectedAccountTransaction(hash, indexParsed)); 81 | }); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountTransaction/GetConnectedAccountTransactions.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (page = 0, hash: string) => ` 6 | const hash = ${hash ? `"${hash}"` : 'null'}; 7 | ${page ? `const page = ${page};` : ''} 8 | 9 | 10 | sdk 11 | .getConnectedAccountTransactions(${mergeMethodArgs('hash', page && 'page')}) 12 | .then(accountTransactions => console.log('accountTransactions', accountTransactions)) 13 | .catch(console.error); 14 | `; 15 | 16 | interface IState { 17 | page: string; 18 | pageParsed: number; 19 | hash: string; 20 | } 21 | 22 | export class GetConnectedAccountTransactions extends Screen { 23 | public state = { 24 | hash: '', 25 | page: '0', 26 | pageParsed: 0, 27 | }; 28 | 29 | public componentWillMount(): void { 30 | this.run = this.run.bind(this); 31 | 32 | this.hashChanged = this.hashChanged.bind(this); 33 | this.pageChanged = this.pageChanged.bind(this); 34 | } 35 | 36 | public renderContent(): any { 37 | const { enabled } = this.props; 38 | const { page, hash, pageParsed } = this.state; 39 | return ( 40 |
41 | 47 | 53 | 59 | 60 |
61 | ); 62 | } 63 | 64 | private hashChanged(hash: string): void { 65 | this.setState({ 66 | hash, 67 | }); 68 | } 69 | 70 | private pageChanged(page: string, pageParsed: number) { 71 | this.setState({ 72 | page, 73 | pageParsed, 74 | }); 75 | } 76 | 77 | private run(): void { 78 | const { hash, pageParsed } = this.state; 79 | this 80 | .logger 81 | .wrapSync('sdk.getConnectedAccountTransactions', async (console) => { 82 | console.log('accountTransactions', await this.sdk.getConnectedAccountTransactions(hash, pageParsed)); 83 | }); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountTransaction/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetConnectedAccountTransactions'; 2 | export * from './GetConnectedAccountTransaction'; 3 | export * from './SendAccountTransaction'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountVirtualBalance/GetConnectedAccountVirtualBalance.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (symbolOrAddress: string) => ` 5 | const symbolOrAddress = ${symbolOrAddress ? `"${symbolOrAddress}"` : 'null'}; 6 | 7 | sdk 8 | .getConnectedAccountVirtualBalance(symbolOrAddress) 9 | .then(accountVirtualBalance => console.log('accountVirtualBalance', accountVirtualBalance)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | symbolOrAddress: string; 15 | } 16 | 17 | export class GetConnectedAccountVirtualBalance extends Screen { 18 | public state = { 19 | symbolOrAddress: 'ETK', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.symbolOrAddressChanged = this.symbolOrAddressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { symbolOrAddress } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private symbolOrAddressChanged(symbolOrAddress: string): void { 51 | this.setState({ 52 | symbolOrAddress, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { symbolOrAddress } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getConnectedAccountVirtualBalance', async (console) => { 61 | console.log('accountVirtualBalance', await this.sdk.getConnectedAccountVirtualBalance(symbolOrAddress)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountVirtualBalance/GetConnectedAccountVirtualBalances.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (page = 0) => ` 6 | ${page ? `const page = ${page};` : ''} 7 | 8 | sdk 9 | .getConnectedAccountVirtualBalances(${mergeMethodArgs(page && 'page')}) 10 | .then(accountVirtualBalances => console.log('accountVirtualBalances', accountVirtualBalances)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | page: string; 16 | pageParsed: number; 17 | } 18 | 19 | export class GetConnectedAccountVirtualBalances extends Screen { 20 | public state = { 21 | page: '0', 22 | pageParsed: 0, 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.pageChanged = this.pageChanged.bind(this); 29 | } 30 | 31 | public renderContent(): any { 32 | const { enabled } = this.props; 33 | const { page, pageParsed } = this.state; 34 | return ( 35 |
36 | 42 | 48 | 49 |
50 | ); 51 | } 52 | 53 | private pageChanged(page: string, pageParsed: number) { 54 | this.setState({ 55 | page, 56 | pageParsed, 57 | }); 58 | } 59 | 60 | private run(): void { 61 | const { pageParsed } = this.state; 62 | this 63 | .logger 64 | .wrapSync('sdk.getConnectedAccountVirtualBalances', async (console) => { 65 | console.log('accountVirtualBalances', await this.sdk.getConnectedAccountVirtualBalances(pageParsed)); 66 | }); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountVirtualBalance/GetConnectedAccountVirtualPendingBalance.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (symbolOrAddress: string) => ` 5 | const symbolOrAddress = ${symbolOrAddress ? `"${symbolOrAddress}"` : 'null'}; 6 | 7 | sdk 8 | .getConnectedAccountVirtualPendingBalance(symbolOrAddress) 9 | .then(accountVirtualPendingBalance => console.log('accountVirtualPendingBalance', accountVirtualPendingBalance)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | symbolOrAddress: string; 15 | } 16 | 17 | export class GetConnectedAccountVirtualPendingBalance extends Screen { 18 | public state = { 19 | symbolOrAddress: 'ETK', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.symbolOrAddressChanged = this.symbolOrAddressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { symbolOrAddress } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private symbolOrAddressChanged(symbolOrAddress: string): void { 51 | this.setState({ 52 | symbolOrAddress, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { symbolOrAddress } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getConnectedAccountVirtualPendingBalance', async (console) => { 61 | console.log('accountVirtualPendingBalance', await this.sdk.getConnectedAccountVirtualPendingBalance(symbolOrAddress)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountVirtualBalance/GetConnectedAccountVirtualPendingBalances.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .getConnectedAccountVirtualPendingBalances() 7 | .then(accountVirtualPendingBalances => console.log('accountVirtualPendingBalances', accountVirtualPendingBalances)) 8 | .catch(console.error); 9 | `; 10 | 11 | interface IState { 12 | page: string; 13 | pageParsed: number; 14 | } 15 | 16 | export class GetConnectedAccountVirtualPendingBalances extends Screen { 17 | public state = { 18 | page: '0', 19 | pageParsed: 0, 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | } 25 | 26 | public renderContent(): any { 27 | const { enabled } = this.props; 28 | return ( 29 |
30 | 36 |
37 | ); 38 | } 39 | 40 | private run(): void { 41 | this 42 | .logger 43 | .wrapSync('sdk.getConnectedAccountVirtualPendingBalances', async (console) => { 44 | console.log('accountVirtualPendingBalances', await this.sdk.getConnectedAccountVirtualPendingBalances()); 45 | }); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/accountVirtualBalance/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TopUpAccountVirtualBalance'; 2 | export * from './WithdrawFromAccountVirtualBalance'; 3 | export * from './GetConnectedAccountVirtualBalances'; 4 | export * from './GetConnectedAccountVirtualBalance'; 5 | export * from './GetConnectedAccountVirtualPendingBalances'; 6 | export * from './GetConnectedAccountVirtualPendingBalance'; 7 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/action/AcceptIncomingAction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk.acceptIncomingAction(); 6 | 7 | console.log('action accepted'); 8 | `; 9 | 10 | export class AcceptIncomingAction extends Screen { 11 | public componentWillMount(): void { 12 | this.run = this.run.bind(this); 13 | } 14 | 15 | public renderContent(): any { 16 | const { enabled } = this.props; 17 | return ( 18 |
19 | 25 |
26 | ); 27 | } 28 | 29 | private run(): void { 30 | this 31 | .logger 32 | .wrapSync('sdk.acceptIncomingAction', async (console) => { 33 | this.sdk.acceptIncomingAction(); 34 | 35 | console.log('action accepted'); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/action/DismissIncomingAction.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk.dismissIncomingAction(); 6 | 7 | console.log('action dismissed'); 8 | `; 9 | 10 | export class DismissIncomingAction extends Screen { 11 | public componentWillMount(): void { 12 | this.run = this.run.bind(this); 13 | } 14 | 15 | public renderContent(): any { 16 | const { enabled } = this.props; 17 | return ( 18 |
19 | 25 |
26 | ); 27 | } 28 | 29 | private run(): void { 30 | this 31 | .logger 32 | .wrapSync('sdk.dismissIncomingAction', async (console) => { 33 | this.sdk.dismissIncomingAction(); 34 | console.log('action dismissed'); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/action/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AcceptIncomingAction'; 2 | export * from './DismissIncomingAction'; 3 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/app/GetApp.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (alias: string) => ` 5 | const alias = ${alias ? `"${alias}"` : 'null'}; 6 | 7 | sdk 8 | .getApp(alias) 9 | .then(app => console.log('app', alias)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | alias: string; 15 | } 16 | 17 | export class GetApp extends Screen { 18 | public state = { 19 | alias: 'tictactoe', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.aliasChanged = this.aliasChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { alias } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private aliasChanged(alias: string): void { 51 | this.setState({ 52 | alias, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { alias } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getApp', async (console) => { 61 | console.log('app', await this.sdk.getApp(alias)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/app/GetAppOpenGames.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (alias: string, page = 0) => ` 6 | const alias = ${alias ? `"${alias}"` : 'null'}; 7 | ${page ? `const page = ${page};` : ''} 8 | 9 | sdk 10 | .getAppOpenGames(${mergeMethodArgs('alias', page && 'page')}) 11 | .then(games => console.log('games', games)) 12 | .catch(console.error); 13 | `; 14 | 15 | interface IState { 16 | alias: string; 17 | page: string; 18 | pageParsed: number; 19 | } 20 | 21 | export class GetAppOpenGames extends Screen { 22 | public state = { 23 | alias: 'tictactoe', 24 | page: '0', 25 | pageParsed: 0, 26 | }; 27 | 28 | public componentWillMount(): void { 29 | this.run = this.run.bind(this); 30 | 31 | this.aliasChanged = this.aliasChanged.bind(this); 32 | this.pageChanged = this.pageChanged.bind(this); 33 | } 34 | 35 | public renderContent(): any { 36 | const { enabled } = this.props; 37 | const { alias, page, pageParsed } = this.state; 38 | return ( 39 |
40 | 46 | 52 | 58 | 59 |
60 | ); 61 | } 62 | 63 | private aliasChanged(alias: string) { 64 | this.setState({ 65 | alias, 66 | }); 67 | } 68 | 69 | private pageChanged(page: string, pageParsed: number) { 70 | this.setState({ 71 | page, 72 | pageParsed, 73 | }); 74 | } 75 | 76 | private run(): void { 77 | const { alias, pageParsed } = this.state; 78 | this 79 | .logger 80 | .wrapSync('sdk.getAppOpenGames', async (console) => { 81 | console.log('games', await this.sdk.getAppOpenGames(alias, pageParsed)); 82 | }); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/app/GetApps.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (page = 0) => ` 6 | ${page ? `const page = ${page};` : ''} 7 | 8 | sdk 9 | .getApps(${mergeMethodArgs(page && 'page')}) 10 | .then(apps => console.log('apps', apps)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | page: string; 16 | pageParsed: number; 17 | } 18 | 19 | export class GetApps extends Screen { 20 | public state = { 21 | page: '0', 22 | pageParsed: 0, 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.pageChanged = this.pageChanged.bind(this); 29 | } 30 | 31 | public renderContent(): any { 32 | const { enabled } = this.props; 33 | const { page, pageParsed } = this.state; 34 | return ( 35 |
36 | 42 | 48 | 49 |
50 | ); 51 | } 52 | 53 | private pageChanged(page: string, pageParsed: number) { 54 | this.setState({ 55 | page, 56 | pageParsed, 57 | }); 58 | } 59 | 60 | private run(): void { 61 | const { pageParsed } = this.state; 62 | this 63 | .logger 64 | .wrapSync('sdk.getApps', async (console) => { 65 | console.log('apps', await this.sdk.getApps(pageParsed)); 66 | }); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/app/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetApps'; 2 | export * from './GetApp'; 3 | export * from './GetAppOpenGames'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/examples/PlayTicTacToe.module.scss: -------------------------------------------------------------------------------- 1 | .tabs { 2 | button { 3 | border-width: 0; 4 | padding: 0; 5 | background-color: transparent; 6 | cursor: pointer; 7 | margin-right: 15px; 8 | font-weight: bolder; 9 | color: rgba(0, 0, 0, 0.6); 10 | text-transform: uppercase; 11 | font-size: 13px; 12 | &.active, 13 | &.active:hover { 14 | color: #6024FC; 15 | } 16 | &:hover { 17 | color: #000000; 18 | } 19 | &:disabled { 20 | color: rgba(0, 0, 0, 0.2) !important; 21 | } 22 | 23 | &:disabled, 24 | &.active { 25 | cursor: default; 26 | } 27 | } 28 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 29 | margin-bottom: 15px; 30 | padding-bottom: 15px; 31 | } 32 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/examples/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PlayTicTacToe'; 2 | export * from './MintToken'; 3 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/examples/ticTacToe/InputBoard.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | margin-bottom: 5px; 3 | 4 | div:first-child { 5 | padding-bottom: 2px; 6 | } 7 | 8 | div:last-child { 9 | width: 57px * 3; 10 | 11 | button { 12 | width: 56px; 13 | height: 56px; 14 | margin-right: 1px; 15 | margin-bottom: 1px; 16 | border-width: 0; 17 | background-color: white; 18 | cursor: pointer; 19 | font-size: 30px; 20 | line-height: 50px; 21 | &:disabled { 22 | background-color: rgba(255, 255, 255, 0.5); 23 | cursor: default; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/examples/ticTacToe/index.ts: -------------------------------------------------------------------------------- 1 | export * from './InputBoard'; 2 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/global/Reset.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputCheckBox } from '../../components'; 3 | 4 | const code1 = () => ` 5 | sdk 6 | .reset() 7 | .then(() => console.log('reseted')) 8 | .catch(console.error); 9 | `; 10 | 11 | const code2 = (device: boolean, session: boolean) => ` 12 | const options = { 13 | ${` 14 | ${device ? 'device: true,' : ''} 15 | ${session ? ' session: true,' : ''} 16 | `.trim()} 17 | }; 18 | 19 | sdk 20 | .reset(options) 21 | .then(() => console.log('reseted')) 22 | .catch(console.error); 23 | `; 24 | 25 | interface IState { 26 | device: boolean; 27 | session: boolean; 28 | } 29 | 30 | export class Reset extends Screen { 31 | public state = { 32 | device: false, 33 | session: false, 34 | }; 35 | 36 | public componentWillMount(): void { 37 | this.run = this.run.bind(this); 38 | 39 | this.deviceChanged = this.deviceChanged.bind(this); 40 | this.sessionChanged = this.sessionChanged.bind(this); 41 | } 42 | 43 | public renderContent(): any { 44 | const { enabled } = this.props; 45 | const { device, session } = this.state; 46 | return ( 47 |
48 | 57 | 62 | 67 | 68 |
69 | ); 70 | } 71 | 72 | private deviceChanged(device: boolean): void { 73 | this.setState({ 74 | device, 75 | }); 76 | } 77 | 78 | private sessionChanged(session: boolean): void { 79 | this.setState({ 80 | session, 81 | }); 82 | } 83 | 84 | private run(): void { 85 | const { device, session } = this.state; 86 | this 87 | .logger 88 | .wrapSync('sdk.reset', async (console) => { 89 | await this.sdk.reset({ 90 | device, 91 | session, 92 | }); 93 | 94 | console.log('reseted'); 95 | }); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/global/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Initialize'; 2 | export * from './Reset'; 3 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Content } from './Content'; 2 | export { default as Console } from './Console'; 3 | export { default as StatusBar } from './StatusBar'; 4 | export { default as Help } from './Help'; 5 | export { default as Preloader } from './Preloader'; 6 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/token/GetToken.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (symbolOrAddress: string) => ` 5 | const symbolOrAddress = ${symbolOrAddress ? `"${symbolOrAddress}"` : 'null'}; 6 | 7 | sdk 8 | .getToken(symbolOrAddress) 9 | .then(token => console.log('token', token)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | symbolOrAddress: string; 15 | } 16 | 17 | export class GetToken extends Screen { 18 | public state = { 19 | symbolOrAddress: 'ETK', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.symbolOrAddressChanged = this.symbolOrAddressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { symbolOrAddress } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private symbolOrAddressChanged(symbolOrAddress: string): void { 51 | this.setState({ 52 | symbolOrAddress, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { symbolOrAddress } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getToken', async (console) => { 61 | console.log('token', await this.sdk.getToken(symbolOrAddress)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/token/GetTokenBalance.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | 4 | const code = (symbolOrAddress: string) => ` 5 | const symbolOrAddress = ${symbolOrAddress ? `"${symbolOrAddress}"` : 'null'}; 6 | 7 | sdk 8 | .getTokenBalance(symbolOrAddress) 9 | .then(tokenBalance => console.log('tokenBalance', tokenBalance)) 10 | .catch(console.error); 11 | `; 12 | 13 | interface IState { 14 | symbolOrAddress: string; 15 | } 16 | 17 | export class GetTokenBalance extends Screen { 18 | public state = { 19 | symbolOrAddress: 'ETK', 20 | }; 21 | 22 | public componentWillMount(): void { 23 | this.run = this.run.bind(this); 24 | 25 | this.symbolOrAddressChanged = this.symbolOrAddressChanged.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { symbolOrAddress } = this.state; 31 | return ( 32 |
33 | 39 | 45 | 46 |
47 | ); 48 | } 49 | 50 | private symbolOrAddressChanged(symbolOrAddress: string): void { 51 | this.setState({ 52 | symbolOrAddress, 53 | }); 54 | } 55 | 56 | private run(): void { 57 | const { symbolOrAddress } = this.state; 58 | this 59 | .logger 60 | .wrapSync('sdk.getTokenBalance', async (console) => { 61 | console.log('tokenBalance', await this.sdk.getTokenBalance(symbolOrAddress)); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/token/GetTokens.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | import { mergeMethodArgs } from '../../shared'; 4 | 5 | const code = (page = 0) => ` 6 | ${page ? `const page = ${page};` : ''} 7 | 8 | sdk 9 | .getTokens(${mergeMethodArgs(page && 'page')}) 10 | .then(tokens => console.log('tokens', tokens)) 11 | .catch(console.error); 12 | `; 13 | 14 | interface IState { 15 | page: string; 16 | pageParsed: number; 17 | } 18 | 19 | export class GetTokens extends Screen { 20 | public state = { 21 | page: '0', 22 | pageParsed: 0, 23 | }; 24 | 25 | public componentWillMount(): void { 26 | this.run = this.run.bind(this); 27 | 28 | this.pageChanged = this.pageChanged.bind(this); 29 | } 30 | 31 | public renderContent(): any { 32 | const { enabled } = this.props; 33 | const { page, pageParsed } = this.state; 34 | return ( 35 |
36 | 42 | 48 | 49 |
50 | ); 51 | } 52 | 53 | private pageChanged(page: string, pageParsed: number) { 54 | this.setState({ 55 | page, 56 | pageParsed, 57 | }); 58 | } 59 | 60 | private run(): void { 61 | const { pageParsed } = this.state; 62 | this 63 | .logger 64 | .wrapSync('sdk.getTokens', async (console) => { 65 | console.log('tokens', await this.sdk.getTokens(pageParsed)); 66 | }); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/token/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GetTokens'; 2 | export * from './GetToken'; 3 | export * from './GetTokenBalance'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/url/CreateRequestSignSecureCodeUrl.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, Url } from '../../components'; 3 | 4 | const code = () => ` 5 | sdk 6 | .createRequestSignSecureCodeUrl() 7 | .then(mobileUrl => console.log('mobileUrl', mobileUrl)) 8 | .catch(console.error); 9 | `; 10 | 11 | interface IState { 12 | mobileUrl: string; 13 | } 14 | 15 | export class CreateRequestSignSecureCodeUrl extends Screen { 16 | public state = { 17 | mobileUrl: '', 18 | }; 19 | 20 | public componentWillMount(): void { 21 | this.run = this.run.bind(this); 22 | } 23 | 24 | public renderContent(): any { 25 | const { enabled } = this.props; 26 | const { mobileUrl } = this.state; 27 | return ( 28 |
29 | 35 | {enabled && mobileUrl && ( 36 | 37 | )} 38 |
39 | ); 40 | } 41 | 42 | private run(): void { 43 | this 44 | .logger 45 | .wrapSync('sdk.createRequestSignSecureCodeUrl', async (console) => { 46 | const mobileUrl = await this.sdk.createRequestSignSecureCodeUrl(); 47 | 48 | console.log('mobileUrl', mobileUrl); 49 | 50 | this.setState({ 51 | mobileUrl, 52 | }); 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/url/ProcessIncomingUrl.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, InputText, Screen } from '../../components'; 3 | 4 | const code = (url: string) => ` 5 | const url = ${url ? `"${url}"` : 'null'}; 6 | 7 | sdk.processIncomingUrl(url); 8 | `; 9 | 10 | interface IState { 11 | url: string; 12 | } 13 | 14 | export class ProcessIncomingUrl extends Screen { 15 | public state = { 16 | url: '', 17 | }; 18 | 19 | public componentWillMount(): void { 20 | this.run = this.run.bind(this); 21 | 22 | this.urlChanged = this.urlChanged.bind(this); 23 | } 24 | 25 | public renderContent(): any { 26 | const { enabled } = this.props; 27 | const { url } = this.state; 28 | return ( 29 |
30 | 36 | 42 | 43 |
44 | ); 45 | } 46 | 47 | private urlChanged(url: string): void { 48 | this.setState({ 49 | url, 50 | }); 51 | } 52 | 53 | private run(): void { 54 | const { url } = this.state; 55 | this 56 | .logger 57 | .wrapSync('sdk.processIncomingUrl', async () => { 58 | this.sdk.processIncomingUrl(url); 59 | this.setState({ 60 | url: '', 61 | }); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/url/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ProcessIncomingUrl'; 2 | export * from './CreateRequestAddAccountDeviceUrl'; 3 | export * from './CreateRequestSignSecureCodeUrl'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/utils/GetTransactionDetails.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Example, Screen, InputText } from '../../components'; 3 | const code = (hash: string) => ` 4 | const hash = ${hash ? `"${hash}"` : 'null'}; 5 | 6 | sdk 7 | .getTransactionDetails(hash) 8 | .then(transactionDetails => console.log('transactionDetails', transactionDetails)) 9 | .catch(console.error); 10 | `; 11 | 12 | interface IState { 13 | hash: string; 14 | } 15 | 16 | export class GetTransactionDetails extends Screen { 17 | public state = { 18 | hash: '', 19 | }; 20 | 21 | public componentWillMount(): void { 22 | this.run = this.run.bind(this); 23 | 24 | this.hashChanged = this.hashChanged.bind(this); 25 | } 26 | 27 | public renderContent(): any { 28 | const { enabled } = this.props; 29 | const { hash } = this.state; 30 | return ( 31 |
32 | 38 | 44 | 45 |
46 | ); 47 | } 48 | 49 | private hashChanged(hash: string): void { 50 | this.setState({ 51 | hash, 52 | }); 53 | } 54 | 55 | private run(): void { 56 | const { hash } = this.state; 57 | this 58 | .logger 59 | .wrapSync('sdk.getTransactionDetails', async (console) => { 60 | console.log('transactionDetails', await this.sdk.getTransactionDetails(hash)); 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/utils/SignPersonalMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { randomBytes } from 'crypto'; 3 | import { anyToHex } from '@netgum/utils'; 4 | import { Example, Screen, InputText } from '../../components'; 5 | 6 | const code = (message: string) => ` 7 | const message = ${message ? `"${message}"` : 'null'}; 8 | 9 | console.log('signature', sdk.signPersonalMessage(message)); 10 | `; 11 | 12 | interface IState { 13 | message: string; 14 | } 15 | 16 | export class SignPersonalMessage extends Screen { 17 | public state = { 18 | message: '', 19 | }; 20 | 21 | public componentWillMount(): void { 22 | this.run = this.run.bind(this); 23 | 24 | this.messageChanged = this.messageChanged.bind(this); 25 | this.generateMessage = this.generateMessage.bind(this); 26 | } 27 | 28 | public renderContent(): any { 29 | const { enabled } = this.props; 30 | const { message } = this.state; 31 | return ( 32 |
33 | 39 | 46 | 47 |
48 | ); 49 | } 50 | 51 | private messageChanged(message: string): void { 52 | this.setState({ 53 | message, 54 | }); 55 | } 56 | 57 | private generateMessage(): void { 58 | this.setState({ 59 | message: anyToHex(randomBytes(15), { add0x: true }), 60 | }); 61 | } 62 | 63 | private run(): void { 64 | const { message } = this.state; 65 | this 66 | .logger 67 | .wrapSync('sdk.signPersonalMessage', async (console) => { 68 | console.log('signature', this.sdk.signPersonalMessage(message)); 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/containers/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SignPersonalMessage'; 2 | export * from './RecoverAccountDeviceFromPersonalMessageSignature'; 3 | export * from './GetTransactionDetails'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/help/index.ts: -------------------------------------------------------------------------------- 1 | import * as menu from './menu'; 2 | import * as statusBar from './statusBar'; 3 | 4 | const help: { [key: string]: string } = {}; 5 | 6 | function buildHelp(prefix: string, data: object): void { 7 | const keys = Object.keys(data); 8 | 9 | for (const key of keys) { 10 | help[`${prefix}.${key}`] = data[key]; 11 | } 12 | } 13 | 14 | buildHelp('menu', menu); 15 | buildHelp('statusBar', statusBar); 16 | 17 | export default help; 18 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/help/statusBar.ts: -------------------------------------------------------------------------------- 1 | export const network = ''; // TODO 2 | 3 | export const accountAddress = ` 4 | # Account Address 5 | 6 | Address of account smart contract. 7 | `; 8 | 9 | export const accountState = ` 10 | # Account State 11 | 12 | * \`Created\` - account address is reserved 13 | * \`Deployed\` - account smart contract is deployed 14 | `; 15 | 16 | export const accountRealBalance = ` 17 | # Account Real Balance 18 | 19 | Account \`on-chain\` balance - used in account transactions. 20 | `; 21 | 22 | export const accountVirtualBalance = ` 23 | # Account Virtual Balance 24 | 25 | Account \`off-chain\` balance - used in account payments. 26 | `; 27 | 28 | export const accountDeviceState = ''; // TODO 29 | 30 | export const deviceAddress = ''; // TODO 31 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/index.scss: -------------------------------------------------------------------------------- 1 | @import "~normalize-scss/sass/normalize"; 2 | 3 | @include normalize(); 4 | 5 | body { 6 | color: black; 7 | background-color: #F3CF48; 8 | font-size: 12px; 9 | font-family: Roboto, sans-serif; 10 | font-weight: 400; 11 | line-height: 1.2em; 12 | } 13 | 14 | h1, h2, h3, h4, h5 { 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | 20 | button, 21 | input[type="text"], 22 | input[type="number"], 23 | select { 24 | font-size: 12px; 25 | appearance: none; 26 | } 27 | 28 | button:focus, 29 | input:focus, 30 | select:focus { 31 | outline: none; 32 | } 33 | 34 | pre { 35 | margin: 0; 36 | } 37 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/index.tsx: -------------------------------------------------------------------------------- 1 | import './index.scss'; 2 | 3 | import React from 'react'; 4 | import { render } from 'react-dom'; 5 | import { Provider } from 'react-redux'; 6 | import App from './App'; 7 | import { configureSdk, configureStore } from './configure'; 8 | import { logger, help, context } from './shared'; 9 | import { config } from './config'; 10 | 11 | const sdk = configureSdk(logger); 12 | const store = configureStore(sdk); 13 | 14 | render( 15 | 16 | 22 | 23 | 24 | , 25 | document.getElementById('root'), 26 | ); 27 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.scss'; 4 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/ContextComponent.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { IContextProps } from './interfaces'; 3 | import { context } from './context'; 4 | 5 | export abstract class ContextComponent

extends React.Component { 6 | public static contextType = context; 7 | 8 | public context: IContextProps; 9 | 10 | public get config(): IContextProps['config'] { 11 | return this.context ? 12 | this.context.config 13 | : null; 14 | } 15 | 16 | public get logger(): IContextProps['logger'] { 17 | return this.context ? 18 | this.context.logger 19 | : null; 20 | } 21 | 22 | public get sdk(): IContextProps['sdk'] { 23 | return this.context ? 24 | this.context.sdk 25 | : null; 26 | } 27 | 28 | public get help(): IContextProps['help'] { 29 | return this.context ? 30 | this.context.help 31 | : null; 32 | } 33 | 34 | public abstract render(): any; 35 | } 36 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { IContextProps } from './interfaces'; 3 | 4 | export const context = createContext(null); 5 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/help.ts: -------------------------------------------------------------------------------- 1 | import { IHelp } from './interfaces'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | 4 | const stream$ = new BehaviorSubject(null); 5 | 6 | function show(alias: string): void { 7 | stream$.next(alias); 8 | } 9 | 10 | function hide(): void { 11 | stream$.next(null); 12 | } 13 | 14 | export const help: IHelp = { 15 | stream$, 16 | show, 17 | hide, 18 | }; 19 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context'; 2 | export * from './ContextComponent'; 3 | export * from './help'; 4 | export * from './interfaces'; 5 | export * from './logger'; 6 | export * from './utils'; 7 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Sdk } from '@archanova/sdk'; 2 | import { BehaviorSubject, Subject } from 'rxjs'; 3 | import { config } from '../config'; 4 | 5 | export interface IContextProps { 6 | config: typeof config; 7 | sdk: Sdk; 8 | logger: ILogger; 9 | help: IHelp; 10 | } 11 | 12 | export interface IHelp { 13 | stream$: BehaviorSubject; 14 | 15 | show(alias: string): void; 16 | 17 | hide(): void; 18 | } 19 | 20 | export interface ILoggerConsole { 21 | log(key: string, data?: T): T; 22 | 23 | error(err: any): void; 24 | } 25 | 26 | export interface ILogger { 27 | stream$: Subject; 28 | pending$: Subject; 29 | 30 | wrapSync(label: string, fun: (console: ILoggerConsole) => Promise): void; 31 | } 32 | 33 | export interface ILoggerEvent { 34 | type: 'info' | 'error'; 35 | args: any[]; 36 | } 37 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/logger.ts: -------------------------------------------------------------------------------- 1 | import { BehaviorSubject } from 'rxjs'; 2 | import { ILogger, ILoggerConsole, ILoggerEvent } from './interfaces'; 3 | 4 | const pending$ = new BehaviorSubject(false); 5 | const stream$ = new BehaviorSubject(null); 6 | const wrappedConsole: Partial = { 7 | info(...args: any[]): void { 8 | console.log(...args); 9 | stream$.next({ 10 | args, 11 | type: 'info', 12 | }); 13 | }, 14 | error(...args: any[]): void { 15 | console.error(...args); 16 | stream$.next({ 17 | args, 18 | type: 'error', 19 | }); 20 | }, 21 | }; 22 | 23 | const wrapSync: ILogger['wrapSync'] = (label, fun) => { 24 | pending$.next(true); 25 | console.info(`// ${label}`); 26 | 27 | const log: ILoggerConsole['log'] = (key, data) => { 28 | if (data || data === null) { 29 | wrappedConsole.info(key, data); 30 | } else { 31 | wrappedConsole.info(key); 32 | } 33 | return data; 34 | }; 35 | 36 | const error: ILoggerConsole['error'] = (err) => { 37 | wrappedConsole.error(err); 38 | }; 39 | 40 | const wrapper = async () => { 41 | return Promise.resolve(fun({ 42 | log, 43 | error, 44 | })); 45 | }; 46 | 47 | wrapper() 48 | .finally(() => pending$.next(false)) 49 | .catch(error); 50 | }; 51 | 52 | export const logger: ILogger = { 53 | stream$, 54 | pending$, 55 | wrapSync, 56 | }; 57 | -------------------------------------------------------------------------------- /packages/sdk-playground/src/shared/utils.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | import { createLocalSdkEnvironment, getSdkEnvironment, SdkEnvironmentNames, sdkModules } from '@archanova/sdk'; 3 | import { anyToHex, generateRandomPrivateKey, privateKeyToAddress, weiToEth } from '@netgum/utils'; 4 | import { config } from '../config'; 5 | 6 | export function buildSdkEnv(name: string): sdkModules.Environment { 7 | let result: sdkModules.Environment; 8 | 9 | if (name === 'local') { 10 | result = createLocalSdkEnvironment({ 11 | port: config.localSdkEnvPort, 12 | }); 13 | } else { 14 | result = getSdkEnvironment(name as SdkEnvironmentNames); 15 | } 16 | 17 | return result 18 | .setConfig('storageAdapter', localStorage as sdkModules.Storage.IAdapter) 19 | .setConfig('urlAdapter', { 20 | open(url: string): any { 21 | document.location = url as any; 22 | }, 23 | addListener(listener: (url: string) => any): void { 24 | listener(document.location.toString()); 25 | }, 26 | }) 27 | .extendConfig('actionOptions', { 28 | autoAccept: config.autoAcceptSdkActions, 29 | }); 30 | } 31 | 32 | export function generateRandomAddress() { 33 | return privateKeyToAddress( 34 | generateRandomPrivateKey(), 35 | ); 36 | } 37 | 38 | export function generateRandomEnsLabel() { 39 | const hash1 = Date.now().toString(32); 40 | const hash2 = Math.floor(Math.random() * 100000).toString(32); 41 | return ( 42 | `playground${hash1}${hash2}` 43 | ); 44 | } 45 | 46 | export function getCurrentEndpoint() { 47 | return document.location.origin; 48 | } 49 | 50 | export function formatBalance(balance: BN): string { 51 | return balance 52 | ? `${weiToEth(balance).toFixed(6)} ETH` 53 | : '-'; 54 | } 55 | 56 | export function mergeMethodArgs(...args: any[]): string { 57 | return args 58 | .filter(arg => !!arg) 59 | .map(arg => `${arg}`) 60 | .join(', '); 61 | } 62 | 63 | function jsonReplacer(key: string, value: any): any { 64 | const data = this[key]; 65 | 66 | if ( 67 | Buffer.isBuffer(data) || 68 | BN.isBN(data) 69 | ) { 70 | const hash = anyToHex(data, { 71 | add0x: true, 72 | }); 73 | const label = Buffer.isBuffer(data) ? 'Buffer' : 'BN'; 74 | 75 | value = `${label}: ${hash}`; 76 | } 77 | 78 | return value; 79 | } 80 | 81 | export function toRawObject(data: any): any { 82 | return JSON.parse( 83 | JSON.stringify(data, jsonReplacer), 84 | ); 85 | } 86 | -------------------------------------------------------------------------------- /packages/sdk-playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "typeRoots": [ 6 | "./node_modules/@types", 7 | "./node_modules/@netgum/types/react", 8 | "./node_modules/@netgum/types/node" 9 | ], 10 | "allowJs": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "module": "esnext", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "declaration": false 18 | }, 19 | "include": [ 20 | "./src/**/*" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/sdk/.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.npmignore 3 | src 4 | tsconfig* 5 | -------------------------------------------------------------------------------- /packages/sdk/README.md: -------------------------------------------------------------------------------- 1 | # Archanova SDK 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | 5 | ## Installation 6 | 7 | ```bash 8 | $ npm i @archanova/sdk -S 9 | ``` 10 | 11 | ## License 12 | 13 | The MIT License 14 | 15 | [npm-image]: https://badge.fury.io/js/%40archanova%2Fsdk.svg 16 | [npm-url]: https://npmjs.org/package/@archanova/sdk 17 | -------------------------------------------------------------------------------- /packages/sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@archanova/sdk", 3 | "version": "1.1.2", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/netgum/archanova.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/netgum/archanova/issues" 13 | }, 14 | "description": "Archanova SDK", 15 | "scripts": { 16 | "clean": "rimraf ./build", 17 | "compile": "tsc --project ./tsconfig.build.json --rootDir ./src", 18 | "compile:watch": "npm run compile -- --watch --preserveWatchOutput", 19 | "prebuild": "npm run clean", 20 | "build": "npm run compile" 21 | }, 22 | "dependencies": { 23 | "@archanova/contracts": "^1.0.0", 24 | "@babel/runtime": "^7.4.4", 25 | "@netgum/types": "^0.1.8", 26 | "@netgum/utils": "^0.1.3", 27 | "@types/node": "^12.0.0", 28 | "@types/webpack-env": "^1.13.9", 29 | "bn.js": "^4.11.8", 30 | "cross-fetch": "^3.0.2", 31 | "deep-equal-extended": "^0.0.2", 32 | "ethjs": "^0.4.0", 33 | "ethjs-abi": "^0.2.1", 34 | "redux": "^4.0.1", 35 | "rxjs": "6.4.0", 36 | "rxjs-addons": "^0.0.4" 37 | }, 38 | "devDependencies": { 39 | "rimraf": "^2.6.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk/src/constants.ts: -------------------------------------------------------------------------------- 1 | export enum AccountStates { 2 | Created = 'Created', 3 | Deployed = 'Deployed', 4 | } 5 | 6 | export enum AccountTypes { 7 | Developer = 'Developer', 8 | Admin = 'Admin', 9 | } 10 | 11 | export enum AccountDeviceStates { 12 | Created = 'Created', 13 | Deployed = 'Deployed', 14 | } 15 | 16 | export enum AccountDeviceTypes { 17 | Owner = 'Owner', 18 | Delegate = 'Delegate', 19 | Extension = 'Extension', 20 | } 21 | 22 | export enum AccountGameStates { 23 | Open = 'Open', 24 | Opened = 'Opened', 25 | Started = 'Started', 26 | Finished = 'Finished', 27 | } 28 | 29 | export enum AccountGamePlayers { 30 | Creator = 'Creator', 31 | Opponent = 'Opponent', 32 | } 33 | 34 | export enum AccountTransactionTypes { 35 | CreateAccount = 'CreateAccount', 36 | AddDevice = 'AddDevice', 37 | RemoveDevice = 'RemoveDevice', 38 | ExecuteTransaction = 'ExecuteTransaction', 39 | } 40 | 41 | export enum AccountTransactionStates { 42 | Created = 'Created', 43 | Completed = 'Completed', 44 | } 45 | 46 | export enum AccountPaymentStates { 47 | Reserved = 'Reserved', 48 | Locked = 'Locked', 49 | Created = 'Created', 50 | Signed = 'Signed', 51 | Completed = 'Completed', 52 | Processed = 'Processed', 53 | } 54 | 55 | export enum AppStates { 56 | Accepted = 'Accepted', 57 | Rejected = 'Rejected', 58 | } 59 | 60 | export enum TokenTypes { 61 | ERC20 = 'ERC20', 62 | } 63 | 64 | export enum GasPriceStrategies { 65 | Avg = 'Avg', 66 | Fast = 'Fast', 67 | } 68 | -------------------------------------------------------------------------------- /packages/sdk/src/environments/index.ts: -------------------------------------------------------------------------------- 1 | export { SdkEnvironmentNames } from './constants'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/environments/utils.ts: -------------------------------------------------------------------------------- 1 | import { ContractNames } from '@archanova/contracts'; 2 | import { Environment } from '../modules'; 3 | import { 4 | SdkEnvironmentNames, 5 | main, 6 | ropsten, 7 | rinkeby, 8 | kovan, 9 | sokol, 10 | xdai, 11 | } from './constants'; 12 | 13 | /** 14 | * gets sdk environment by name 15 | * @param name 16 | */ 17 | export function getSdkEnvironment(name: SdkEnvironmentNames): Environment { 18 | let result: Environment = null; 19 | 20 | switch (name) { 21 | case SdkEnvironmentNames.Main: 22 | result = main; 23 | break; 24 | 25 | case SdkEnvironmentNames.Ropsten: 26 | result = ropsten; 27 | break; 28 | 29 | case SdkEnvironmentNames.Rinkeby: 30 | result = rinkeby; 31 | break; 32 | 33 | case SdkEnvironmentNames.Kovan: 34 | result = kovan; 35 | break; 36 | 37 | case SdkEnvironmentNames.Sokol: 38 | result = sokol; 39 | break; 40 | 41 | case SdkEnvironmentNames.Xdai: 42 | result = xdai; 43 | break; 44 | } 45 | 46 | return result; 47 | } 48 | 49 | /** 50 | * creates local sdk environment 51 | * @param options 52 | */ 53 | export function createLocalSdkEnvironment(options: { host?: string, port?: number } = {}): Environment { 54 | return new Environment({ 55 | apiOptions: { 56 | host: options.host || 'localhost', 57 | port: options.port || 8880, 58 | ssl: false, 59 | reconnectTimeout: 3000, 60 | }, 61 | ensOptions: { 62 | supportedRootNames: ['archanova.local'], 63 | }, 64 | ethOptions: { 65 | networkId: '65280', 66 | gasPrice: '0x77359400', 67 | contractAddresses: { 68 | [ContractNames.AccountProvider]: '0xf254E687aD631A681cC895Dbdca37230D4a6f06C', 69 | [ContractNames.AccountProxy]: '0x12939a4d566e460B7024d38b0A54535c8B282484', 70 | [ContractNames.AccountFriendRecovery]: '0x63636CABbabaDD86D2675110cD469e77Bc87B36A', 71 | [ContractNames.ENSRegistry]: '0xC5dFc16D722a4fa6afA59d94439c74537A4Ee70E', 72 | [ContractNames.VirtualPaymentManager]: '0x5E2355b6522F29D3f0096cA9F4343DB23c243586', 73 | }, 74 | }, 75 | apiWebSocketConstructor: null, 76 | storageOptions: { 77 | namespace: '@archanova:local', 78 | }, 79 | storageAdapter: null, 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /packages/sdk/src/errors.ts: -------------------------------------------------------------------------------- 1 | import { SdkError } from './SdkError'; 2 | 3 | export const ERR_SDK_NOT_INITIALIZED = SdkError.fromAny('sdk not initialized'); 4 | export const ERR_SDK_ALREADY_INITIALIZED = SdkError.fromAny('sdk already initialized'); 5 | export const ERR_ACCOUNT_DISCONNECTED = SdkError.fromAny('account disconnected'); 6 | export const ERR_ACCOUNT_ALREADY_CONNECTED = SdkError.fromAny('account already connected'); 7 | export const ERR_INVALID_ACCOUNT_STATE = SdkError.fromAny('invalid account state'); 8 | export const ERR_INVALID_ACCOUNT_DEVICE_STATE = SdkError.fromAny('invalid account device state'); 9 | export const ERR_INVALID_ACCOUNT_DEVICE_TYPE = SdkError.fromAny('invalid account device type'); 10 | export const ERR_WRONG_NUMBER_OF_ARGUMENTS = SdkError.fromAny('wrong number of arguments'); 11 | export const ERR_INVALID_GAME_CREATOR = SdkError.fromAny('invalid game creator'); 12 | export const ERR_INVALID_GAME_STATE = SdkError.fromAny('invalid game state'); 13 | export const ERR_EXTENSION_ALREADY_ADDED = SdkError.fromAny('extension already added'); 14 | export const ERR_EXTENSION_NOT_ADDED = SdkError.fromAny('extension not added'); 15 | export const ERR_ADDING_EXTENSION_IN_PROGRESS = SdkError.fromAny('adding extension in progress'); 16 | export const ERR_NOT_ENOUGH_REAL_FUNDS = SdkError.fromAny('not enough real funds'); 17 | export const ERR_NOT_ENOUGH_VIRTUAL_FUNDS = SdkError.fromAny('not enough virtual funds'); 18 | -------------------------------------------------------------------------------- /packages/sdk/src/helpers.ts: -------------------------------------------------------------------------------- 1 | import { SdkEnvironmentNames, getSdkEnvironment } from './environments'; 2 | import { Environment } from './modules'; 3 | import { Sdk } from './Sdk'; 4 | 5 | /** 6 | * creates sdk 7 | * @param env 8 | */ 9 | export function createSdk(env: SdkEnvironmentNames | Environment): Sdk { 10 | let environment: Environment = null; 11 | if (env instanceof Environment) { 12 | environment = env; 13 | } else { 14 | environment = getSdkEnvironment(env); 15 | } 16 | 17 | return new Sdk(environment); 18 | } 19 | -------------------------------------------------------------------------------- /packages/sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as sdkConstants from './constants'; 2 | import * as sdkInterfaces from './interfaces'; 3 | import * as sdkModules from './modules'; 4 | import * as sdkTypes from './types'; 5 | 6 | export * from './errors'; 7 | export * from './helpers'; 8 | export * from './environments'; 9 | export * from './redux'; 10 | export * from './Sdk'; 11 | export * from './SdkError'; 12 | 13 | export { 14 | sdkConstants, 15 | sdkInterfaces, 16 | sdkModules, 17 | sdkTypes, 18 | }; 19 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/AccountGame.ts: -------------------------------------------------------------------------------- 1 | import { abiEncodePacked, ZERO_ADDRESS } from '@netgum/utils'; 2 | import { IAccountGame } from '../interfaces'; 3 | import { ApiMethods } from './ApiMethods'; 4 | import { Contract } from './Contract'; 5 | import { Device } from './Device'; 6 | import { State } from './State'; 7 | 8 | export class AccountGame { 9 | constructor( 10 | private apiMethods: ApiMethods, 11 | private contract: Contract, 12 | private device: Device, 13 | private state: State, 14 | ) { 15 | // 16 | } 17 | 18 | public joinAccountGame(accountGame: IAccountGame): Promise { 19 | const { accountAddress } = this.state; 20 | const { id, deposit, creator: { account, payment } } = accountGame; 21 | const { address } = this.contract.virtualPaymentManager; 22 | 23 | const message = abiEncodePacked( 24 | 'address', 25 | 'address', 26 | 'address', 27 | 'address', 28 | 'bytes', 29 | 'uint256', 30 | )( 31 | address, 32 | accountAddress, 33 | account.address, 34 | deposit.token ? deposit.token.address : ZERO_ADDRESS, 35 | payment.hash, 36 | deposit.value, 37 | ); 38 | 39 | const signature = this.device.signPersonalMessage(message); 40 | 41 | return this.apiMethods.joinAccountGame(accountAddress, id, signature); 42 | } 43 | 44 | public startAccountGame(accountGame: IAccountGame): Promise { 45 | const { accountAddress } = this.state; 46 | const { id, deposit, opponent: { account, payment } } = accountGame; 47 | const { address } = this.contract.virtualPaymentManager; 48 | 49 | const message = abiEncodePacked( 50 | 'address', 51 | 'address', 52 | 'address', 53 | 'address', 54 | 'bytes', 55 | 'uint256', 56 | )( 57 | address, 58 | accountAddress, 59 | account.address, 60 | deposit.token ? deposit.token.address : ZERO_ADDRESS, 61 | payment.hash, 62 | deposit.value, 63 | ); 64 | 65 | const signature = this.device.signPersonalMessage(message); 66 | 67 | return this.apiMethods.startAccountGame(accountAddress, id, signature); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/AccountPayment.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | import { abiEncodePacked, ZERO_ADDRESS } from '@netgum/utils'; 3 | import { IAccountPayment } from '../interfaces'; 4 | import { ApiMethods } from './ApiMethods'; 5 | import { Contract } from './Contract'; 6 | import { Device } from './Device'; 7 | import { State } from './State'; 8 | 9 | export class AccountPayment { 10 | constructor( 11 | private apiMethods: ApiMethods, 12 | private contract: Contract, 13 | private device: Device, 14 | private state: State, 15 | ) { 16 | // 17 | } 18 | 19 | public async createAccountPayment( 20 | recipient: string, 21 | token: string, 22 | value: number | string | BN, 23 | ): Promise { 24 | const { accountAddress } = this.state; 25 | let payment = await this.apiMethods.createAccountPayment(accountAddress, recipient, token, value); 26 | 27 | if (payment && recipient) { 28 | payment = await this.signAccountPayment(payment); 29 | } 30 | 31 | return payment; 32 | } 33 | 34 | public async signAccountPayment(payment: IAccountPayment): Promise { 35 | const { accountAddress } = this.state; 36 | const { hash, value, recipient, token } = payment; 37 | const { address } = this.contract.virtualPaymentManager; 38 | const message = abiEncodePacked( 39 | 'address', 40 | 'address', 41 | 'address', 42 | 'address', 43 | 'bytes', 44 | 'uint256', 45 | )( 46 | address, 47 | accountAddress, 48 | recipient.address || recipient.account.address, 49 | token && token.address ? token.address : ZERO_ADDRESS, 50 | hash, 51 | value, 52 | ); 53 | 54 | const signature = this.device.signPersonalMessage(message); 55 | 56 | return this.apiMethods.signAccountPayment(accountAddress, hash, signature); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/AccountTransaction.ts: -------------------------------------------------------------------------------- 1 | import { abiEncodePacked } from '@netgum/utils'; 2 | import { IEstimatedAccountProxyTransaction } from '../interfaces'; 3 | import { ApiMethods } from './ApiMethods'; 4 | import { Contract } from './Contract'; 5 | import { Device } from './Device'; 6 | import { State } from './State'; 7 | 8 | export class AccountTransaction { 9 | constructor( 10 | private apiMethods: ApiMethods, 11 | private contract: Contract, 12 | private device: Device, 13 | private state: State, 14 | ) { 15 | // 16 | } 17 | 18 | public async submitAccountProxyTransaction({ nonce, data, fixedGas, gasPrice, guardianSignature }: IEstimatedAccountProxyTransaction): Promise { 19 | const { accountAddress } = this.state; 20 | const { accountProxy } = this.contract; 21 | 22 | const message = abiEncodePacked( 23 | 'address', 24 | 'bytes', 25 | 'address', 26 | 'uint256', 27 | 'bytes', 28 | 'uint256', 29 | 'uint256', 30 | )( 31 | accountProxy.address, 32 | accountProxy.getMethodSignature('forwardAccountOwnerCall'), 33 | accountAddress, 34 | nonce, 35 | data.map((value, index) => index ? value.substr(2) : value).join(''), 36 | fixedGas, 37 | gasPrice, 38 | ); 39 | 40 | const signature = this.device.signPersonalMessage(message); 41 | 42 | return this.apiMethods.submitAccountProxyTransaction(accountAddress, data, signature, gasPrice, guardianSignature); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Action.ts: -------------------------------------------------------------------------------- 1 | import { Subscription } from 'rxjs'; 2 | import { UniqueBehaviorSubject } from 'rxjs-addons'; 3 | import { filter, tap } from 'rxjs/operators'; 4 | 5 | export class Action { 6 | public static createAction(type: Action.Types, payload: T): Action.IAction { 7 | return { 8 | type, 9 | payload, 10 | timestamp: Date.now(), 11 | }; 12 | } 13 | 14 | public $incoming = new UniqueBehaviorSubject(null); 15 | public $accepted = new UniqueBehaviorSubject(null); 16 | 17 | constructor(private options: Action.IOptions) { 18 | // 19 | } 20 | 21 | public setup(): Subscription { 22 | return this.options && this.options.autoAccept 23 | ? this 24 | .$incoming 25 | .pipe( 26 | filter(action => !!action), 27 | tap(() => this.acceptAction()), 28 | ) 29 | .subscribe() 30 | : null; 31 | } 32 | 33 | public acceptAction(action: Action.IAction = null): void { 34 | if (!action) { 35 | action = this.$incoming.value; 36 | if (action) { 37 | this.$incoming.next(null); 38 | } 39 | } 40 | 41 | if (action) { 42 | this.$accepted.next(action); 43 | } 44 | } 45 | 46 | public dismissAction(): void { 47 | this.$incoming.next(null); 48 | this.$accepted.next(null); 49 | } 50 | } 51 | 52 | export namespace Action { 53 | export interface IOptions { 54 | autoAccept?: boolean; 55 | } 56 | 57 | export enum Types { 58 | RequestAddAccountDevice = 'RequestAddAccountDevice', 59 | AccountDeviceAdded = 'AccountDeviceAdded', 60 | RequestSignSecureCode = 'RequestSignSecureCode', 61 | } 62 | 63 | export interface IAction { 64 | type: Types; 65 | payload: T; 66 | timestamp: number; 67 | } 68 | 69 | export interface IRequestAddAccountDevicePayload { 70 | account?: string; 71 | device: string; 72 | callbackEndpoint?: string; 73 | } 74 | 75 | export interface IAccountDeviceAddedPayload { 76 | account: string; 77 | } 78 | 79 | export interface IRequestSignSecureCodePayload { 80 | code: string; 81 | creator: string; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/ApiError.ts: -------------------------------------------------------------------------------- 1 | export class ApiError extends Error { 2 | public static isApiError(err: any, type: ApiError.Types = null): boolean { 3 | let result = ( 4 | typeof err === 'object' && 5 | err && 6 | err instanceof this 7 | ); 8 | 9 | if (result && type) { 10 | result = err.type === type; 11 | } 12 | 13 | return result; 14 | } 15 | 16 | public error: string = null; 17 | 18 | public errors: { [key: string]: string } = {}; 19 | 20 | constructor( 21 | public type: ApiError.Types, 22 | response: { 23 | error?: string; 24 | errors?: { 25 | type: string; 26 | path: string; 27 | }[]; 28 | } = null, 29 | ) { 30 | super(type); 31 | 32 | if (response) { 33 | if (response.error) { 34 | this.error = response.error; 35 | } else if (response.errors) { 36 | this.errors = response.errors.reduce( 37 | (result, error) => { 38 | return { 39 | ...result, 40 | [error.path]: error.type, 41 | }; 42 | }, 43 | {}, 44 | ); 45 | } 46 | } 47 | } 48 | } 49 | 50 | export namespace ApiError { 51 | export enum Types { 52 | BadRequest = 'bad request', 53 | Unauthorized = 'unauthorized', 54 | Forbidden = 'forbidden', 55 | NotFound = 'not found', 56 | Failed = 'failed', 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Device.ts: -------------------------------------------------------------------------------- 1 | import { generateRandomPrivateKey, privateKeyToAddress, signPersonalMessage, anyToBuffer, verifyPrivateKey } from '@netgum/utils'; 2 | import { State } from './State'; 3 | import { Storage } from './Storage'; 4 | 5 | export class Device { 6 | private privateKey: Buffer = null; 7 | 8 | constructor( 9 | private state: State, 10 | private storage: Storage, 11 | ) { 12 | // 13 | } 14 | 15 | public async setup(options: Device.ISetupOptions = {}): Promise { 16 | if (options.privateKey) { 17 | const privateKey = anyToBuffer(options.privateKey, { defaults: null }); 18 | if (verifyPrivateKey(privateKey)) { 19 | this.privateKey = privateKey; 20 | 21 | await this.storage.setItem(Device.StorageKeys.PrivateKey, this.privateKey); 22 | } 23 | } 24 | 25 | if (!this.privateKey) { 26 | this.privateKey = await this.storage.getItem(Device.StorageKeys.PrivateKey); 27 | } 28 | 29 | if (!this.privateKey) { 30 | await this.generatePrivateKey(); 31 | } 32 | 33 | this.emitState(); 34 | } 35 | 36 | public async reset(): Promise { 37 | await this.generatePrivateKey(); 38 | 39 | this.emitState(); 40 | } 41 | 42 | public signPersonalMessage(message: string | Buffer): Buffer { 43 | return signPersonalMessage(message, this.privateKey); 44 | } 45 | 46 | private async generatePrivateKey(): Promise { 47 | this.privateKey = generateRandomPrivateKey(); 48 | 49 | await this.storage.setItem(Device.StorageKeys.PrivateKey, this.privateKey); 50 | } 51 | 52 | private emitState(): void { 53 | const address = privateKeyToAddress(this.privateKey); 54 | 55 | this.state.device$.next({ 56 | address, 57 | }); 58 | } 59 | } 60 | 61 | export namespace Device { 62 | export enum StorageKeys { 63 | PrivateKey = 'private_key', 64 | } 65 | 66 | export interface ISetupOptions { 67 | privateKey?: string | Buffer; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Ens.ts: -------------------------------------------------------------------------------- 1 | import { getEnsNameHash, getEnsNameInfo, normalizeEnsName } from '@netgum/utils'; 2 | import { Eth } from './Eth'; 3 | import { State } from './State'; 4 | 5 | export class Ens { 6 | constructor(private options: Ens.IOptions, private eth: Eth, private state: State) { 7 | this.state.ens$.next(this.buildState()); 8 | } 9 | 10 | public buildName(label: string, rootName: string = null): string { 11 | let result: string = null; 12 | 13 | if (label) { 14 | const { supportedRoots } = this.state.ens; 15 | 16 | if (supportedRoots.length) { 17 | if (!rootName) { 18 | ({ name: rootName } = supportedRoots[0]); 19 | } 20 | const nameInfo = getEnsNameInfo(label, rootName); 21 | 22 | if ( 23 | nameInfo && 24 | nameInfo.rootNode && 25 | supportedRoots.find(({ name }) => name === nameInfo.rootNode.name) 26 | ) { 27 | result = nameInfo.name; 28 | } 29 | } 30 | } 31 | 32 | return result; 33 | } 34 | 35 | private buildState(): State.IEns { 36 | const { supportedRootNames } = this.options; 37 | return { 38 | supportedRoots: supportedRootNames ? 39 | supportedRootNames 40 | .map((domain) => { 41 | const name = normalizeEnsName(domain); 42 | const nameHash = getEnsNameHash(name); 43 | 44 | return { 45 | name, 46 | nameHash, 47 | }; 48 | }) 49 | : [], 50 | }; 51 | } 52 | } 53 | 54 | export namespace Ens { 55 | export interface IOptions { 56 | supportedRootNames: string[]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Environment.ts: -------------------------------------------------------------------------------- 1 | import { Action } from './Action'; 2 | import { Api } from './Api'; 3 | import { Ens } from './Ens'; 4 | import { Eth } from './Eth'; 5 | import { Storage } from './Storage'; 6 | import { Url } from './Url'; 7 | 8 | export class Environment { 9 | constructor(private configs: Environment.IConfigs) { 10 | // 11 | } 12 | 13 | public getConfig( 14 | key: K, 15 | ): Environment.IConfigs[K] { 16 | return this.configs[key] || null; 17 | } 18 | 19 | public setConfig( 20 | key: K, 21 | config: Environment.IConfigs[K], 22 | ): this { 23 | this.configs[key] = config; 24 | return this; 25 | } 26 | 27 | public extendConfig( 28 | key: K, 29 | config: Partial, 30 | ): this { 31 | this.configs[key] = { 32 | ...(this.configs[key] as object), 33 | ...(config as object), 34 | }; 35 | return this; 36 | } 37 | } 38 | 39 | export namespace Environment { 40 | export type TKeys = keyof IConfigs; 41 | 42 | export interface IConfigs { 43 | actionOptions?: Action.IOptions; 44 | apiOptions: Api.IOptions; 45 | apiWebSocketConstructor?: Api.IWebSocketConstructor; 46 | ensOptions: Ens.IOptions; 47 | ethOptions: Eth.IOptions; 48 | storageOptions: Storage.IOptions; 49 | storageAdapter?: Storage.IAdapter; 50 | urlOptions?: Url.IOptions; 51 | urlAdapter?: Url.IAdapter; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Eth.ts: -------------------------------------------------------------------------------- 1 | import EthJs from 'ethjs'; 2 | import { ContractNames, getContractAddress } from '@archanova/contracts'; 3 | import { Api } from './Api'; 4 | import { State } from './State'; 5 | import { EthError } from './EthError'; 6 | 7 | export class Eth extends EthJs { 8 | constructor( 9 | private options: Eth.IOptions, 10 | api: Api, 11 | state: State, 12 | ) { 13 | super(api.toEthProvider(EthError)); 14 | 15 | state.eth$.next(this.buildState()); 16 | } 17 | 18 | public getNetworkId(): string { 19 | const { networkId } = this.options; 20 | return networkId; 21 | } 22 | 23 | public getContractAddress(contractName: ContractNames): string { 24 | let result: string = null; 25 | const { networkId, contractAddresses } = this.options; 26 | if ( 27 | contractAddresses && 28 | contractAddresses[contractName] 29 | ) { 30 | result = contractAddresses[contractName]; 31 | } 32 | 33 | if (!result) { 34 | result = getContractAddress(contractName, networkId); 35 | } 36 | 37 | return result; 38 | } 39 | 40 | private buildState(): State.IEth { 41 | const { networkId } = this.options; 42 | let networkName: string = 'Unknown'; 43 | 44 | switch (networkId) { 45 | case '1': 46 | networkName = 'Main'; 47 | break; 48 | 49 | case '3': 50 | networkName = 'Ropsten'; 51 | break; 52 | 53 | case '4': 54 | networkName = 'Rinkeby'; 55 | break; 56 | 57 | case '42': 58 | networkName = 'Kovan'; 59 | break; 60 | 61 | case '77': 62 | networkName = 'Sokol'; 63 | break; 64 | 65 | case '100': 66 | networkName = 'xDai'; 67 | break; 68 | 69 | default: 70 | networkName = 'Local'; 71 | } 72 | 73 | return { 74 | networkId, 75 | networkName, 76 | }; 77 | } 78 | } 79 | 80 | export namespace Eth { 81 | export interface IOptions { 82 | networkId: string; 83 | gasPrice?: string; 84 | contractAddresses?: { [key: string]: string }; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/EthError.ts: -------------------------------------------------------------------------------- 1 | export class EthError extends Error { 2 | public static isEthError(err: any): boolean { 3 | return ( 4 | typeof err === 'object' && 5 | err && 6 | err instanceof this 7 | ); 8 | } 9 | 10 | constructor(public httpError: any = null) { 11 | super('unknown'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/Storage.ts: -------------------------------------------------------------------------------- 1 | import { jsonReviver, jsonReplacer } from '@netgum/utils'; 2 | 3 | export class Storage { 4 | static SEPARATOR = ':'; 5 | 6 | constructor( 7 | private options: Storage.IOptions, 8 | private adapter: Storage.IAdapter = null, 9 | ) { 10 | // 11 | } 12 | 13 | public createChild(namespace: string): Storage { 14 | return new Storage({ 15 | namespace: this.prepareKey(namespace), 16 | }, this.adapter); 17 | } 18 | 19 | public async getItem(key: string | string[]): Promise { 20 | let result: T = null; 21 | 22 | if (this.adapter) { 23 | try { 24 | const adapterKey = this.prepareKey(key); 25 | const raw: string = await Promise.resolve(this.adapter.getItem(adapterKey)); 26 | 27 | if (raw) { 28 | result = JSON.parse(raw, jsonReviver); 29 | } 30 | } catch (err) { 31 | result = null; 32 | } 33 | } 34 | 35 | return result || null; 36 | } 37 | 38 | public async setItem(key: string | string[], item: T): Promise { 39 | if (!item) { 40 | return this.removeItem(key); 41 | } 42 | 43 | if (this.adapter) { 44 | try { 45 | const adapterKey = this.prepareKey(key); 46 | const raw = JSON.stringify(item, jsonReplacer); 47 | await Promise.resolve(this.adapter.setItem(adapterKey, raw)); 48 | } catch (err) { 49 | // 50 | } 51 | } 52 | } 53 | 54 | public async removeItem(key: string | string[]): Promise { 55 | if (this.adapter) { 56 | try { 57 | const adapterKey = this.prepareKey(key); 58 | await Promise.resolve(this.adapter.removeItem(adapterKey)); 59 | } catch (err) { 60 | // 61 | } 62 | } 63 | } 64 | 65 | private prepareKey(key: string | string[]): string { 66 | const { namespace } = this.options; 67 | 68 | let parts: string[] = Array.isArray(key) 69 | ? key 70 | : [key]; 71 | 72 | if (namespace) { 73 | parts = [ 74 | namespace, 75 | ...parts, 76 | ]; 77 | } 78 | 79 | return parts.join(Storage.SEPARATOR); 80 | } 81 | } 82 | 83 | export namespace Storage { 84 | export interface IOptions { 85 | namespace?: string; 86 | } 87 | 88 | export interface IAdapter { 89 | getItem(key: string): string | Promise; 90 | 91 | setItem(key: string, value: string): void | Promise; 92 | 93 | removeItem(key: string): void | Promise; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /packages/sdk/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AccountFriendRecovery'; 2 | export * from './AccountGame'; 3 | export * from './AccountPayment'; 4 | export * from './AccountTransaction'; 5 | export * from './Action'; 6 | export * from './Api'; 7 | export * from './ApiError'; 8 | export * from './ApiMethods'; 9 | export * from './Contract'; 10 | export * from './Device'; 11 | export * from './Ens'; 12 | export * from './Environment'; 13 | export * from './Eth'; 14 | export * from './EthError'; 15 | export * from './Session'; 16 | export * from './State'; 17 | export * from './Storage'; 18 | export * from './Url'; 19 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/actions.ts: -------------------------------------------------------------------------------- 1 | export enum ReduxSdkActionTypes { 2 | SetInitialized = '@archanova-sdk/SetInitialized', 3 | SetConnected = '@archanova-sdk/SetConnected', 4 | SetAccount = '@archanova-sdk/SetAccount', 5 | SetAccountDevice = '@archanova-sdk/SetAccountDevice', 6 | SetAccountFriendRecovery = '@archanova-sdk/SetAccountFriendRecovery', 7 | SetDevice = '@archanova-sdk/SetDevice', 8 | SetEns = '@archanova-sdk/SetEns', 9 | SetEth = '@archanova-sdk/SetEth', 10 | SetIncomingAction = '@archanova-sdk/SetIncomingAction', 11 | SetAuthenticated = '@archanova-sdk/SetAuthenticated', 12 | } 13 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/helpers.ts: -------------------------------------------------------------------------------- 1 | import { AnyAction, Reducer } from 'redux'; 2 | import { ReduxSdkActionTypes } from './actions'; 3 | 4 | export function createActionCreator(type: ReduxSdkActionTypes): (payload: any) => any { 5 | return payload => ({ 6 | type, 7 | payload, 8 | }); 9 | } 10 | 11 | export function createReducer(type: ReduxSdkActionTypes): Reducer { 12 | return (state = null, action: AnyAction) => { 13 | return action.type === type 14 | ? action.payload 15 | : state; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/index.ts: -------------------------------------------------------------------------------- 1 | export * from './actions'; 2 | export * from './interfaces'; 3 | export * from './middleware'; 4 | export * from './reducers'; 5 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { Action, State } from '../modules'; 2 | import { IAccount, IAccountDevice, IAccountFriendRecovery, IDevice } from '../interfaces'; 3 | 4 | export interface ISdkReduxState { 5 | initialized: boolean; 6 | connected: boolean; 7 | authenticated: boolean; 8 | account: IAccount; 9 | accountDevice: IAccountDevice; 10 | accountFriendRecovery: IAccountFriendRecovery; 11 | device: IDevice; 12 | ens: State.IEns; 13 | eth: State.IEth; 14 | incomingAction: Action.IAction; 15 | } 16 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/middleware.ts: -------------------------------------------------------------------------------- 1 | import { merge } from 'rxjs'; 2 | import { map } from 'rxjs/operators'; 3 | import { Middleware, Store } from 'redux'; 4 | import { Sdk } from '../Sdk'; 5 | import { ReduxSdkActionTypes } from './actions'; 6 | import { createActionCreator } from './helpers'; 7 | 8 | export function createReduxSdkMiddleware(sdk: Sdk): Middleware { 9 | const { 10 | initialized$, 11 | connected$, 12 | authenticated$, 13 | account$, 14 | accountDevice$, 15 | accountFriendRecovery$, 16 | device$, 17 | ens$, 18 | eth$, 19 | incomingAction$, 20 | } = sdk.state; 21 | 22 | return (store: Store) => { 23 | setTimeout( 24 | () => { 25 | merge( 26 | initialized$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetInitialized))), 27 | connected$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetConnected))), 28 | account$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetAccount))), 29 | accountDevice$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetAccountDevice))), 30 | accountFriendRecovery$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetAccountFriendRecovery))), 31 | device$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetDevice))), 32 | ens$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetEns))), 33 | eth$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetEth))), 34 | incomingAction$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetIncomingAction))), 35 | authenticated$.pipe(map(createActionCreator(ReduxSdkActionTypes.SetAuthenticated))), 36 | ) 37 | .subscribe(store.dispatch); 38 | }, 39 | 0, 40 | ); 41 | 42 | return next => action => next(action); 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /packages/sdk/src/redux/reducers.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers, Reducer } from 'redux'; 2 | import { ReduxSdkActionTypes } from './actions'; 3 | import { createReducer } from './helpers'; 4 | 5 | export const reduxSdkReducer = combineReducers({ 6 | initialized: createReducer(ReduxSdkActionTypes.SetInitialized), 7 | connected: createReducer(ReduxSdkActionTypes.SetConnected), 8 | authenticated: createReducer(ReduxSdkActionTypes.SetAuthenticated), 9 | account: createReducer(ReduxSdkActionTypes.SetAccount), 10 | accountDevice: createReducer(ReduxSdkActionTypes.SetAccountDevice), 11 | accountFriendRecovery: createReducer(ReduxSdkActionTypes.SetAccountFriendRecovery), 12 | device: createReducer(ReduxSdkActionTypes.SetDevice), 13 | ens: createReducer(ReduxSdkActionTypes.SetEns), 14 | eth: createReducer(ReduxSdkActionTypes.SetEth), 15 | incomingAction: createReducer(ReduxSdkActionTypes.SetIncomingAction), 16 | }) as any as Reducer; 17 | -------------------------------------------------------------------------------- /packages/sdk/src/types.ts: -------------------------------------------------------------------------------- 1 | import BN from 'bn.js'; 2 | 3 | export type TAnyNumber = number | string | BN; 4 | export type TAnyData = string | Buffer; 5 | -------------------------------------------------------------------------------- /packages/sdk/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "outDir": "./build" 5 | }, 6 | "exclude": [ 7 | "./src/**/*.test.ts" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /packages/sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig", 3 | "compilerOptions": { 4 | "jsx": "react", 5 | "typeRoots": [ 6 | "./node_modules/@types", 7 | "./node_modules/@netgum/types/node" 8 | ] 9 | }, 10 | "include": [ 11 | "./src/**/*" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "skipLibCheck": true, 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "declaration": true, 11 | "module": "commonjs", 12 | "target": "es2016", 13 | "lib": [ 14 | "esnext.asynciterable", 15 | "es2015.promise", 16 | "es2015.proxy", 17 | "es2016", 18 | "es2017.object", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint-config-airbnb", 3 | "rules": { 4 | "max-line-length": [ 5 | true, 6 | 160 7 | ], 8 | "no-parameter-reassignment": false, 9 | "import-name": false, 10 | "align": { 11 | "options": [ 12 | "parameters", 13 | "statements" 14 | ] 15 | } 16 | } 17 | } 18 | --------------------------------------------------------------------------------