├── .circleci └── config.yml ├── .devcontainer ├── Dockerfile ├── devcontainer.json └── docker-compose.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── .yarnrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api-extractor-base.json ├── common └── api │ ├── epicvault-api.api.json │ ├── epicvault-api.api.md │ ├── epicvault-core.api.json │ ├── epicvault-core.api.md │ ├── epicvault-js.api.json │ ├── epicvault-js.api.md │ ├── epicvault-ledger.api.json │ ├── epicvault-ledger.api.md │ ├── epicvault-uri.api.json │ └── epicvault-uri.api.md ├── debug ├── sale.js ├── tokenBalance.js └── vote.js ├── docs ├── api │ ├── core │ │ ├── const.md │ │ ├── logging.md │ │ ├── rpc.md │ │ ├── sc.md │ │ ├── tx.md │ │ ├── u.md │ │ └── wallet.md │ └── index.md ├── changelog │ ├── v1.md │ ├── v2.md │ ├── v3.md │ ├── v4.md │ └── v5.md ├── guides │ ├── facade.md │ ├── readingData.md │ └── transfer.md ├── installation.md ├── overview.md └── structure.md ├── examples ├── README.md ├── browser │ ├── README.md │ ├── doinvoke │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getaccountstate │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getassetstate │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getbalance │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getbestblockhash │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getblock │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getblockcount │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getblockheader │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getblocksysfee │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getconnectioncount │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getcontractstate │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getpeers │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getrawmempool │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getrawtransaction │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getstorage │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── gettxout │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getvalidators │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── getversion │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── index │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── invokefunction │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── invokescript │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ ├── subscribenotifications │ │ └── demo │ │ │ ├── demo.css │ │ │ ├── demo.details │ │ │ ├── demo.html │ │ │ └── demo.js │ └── validateaddress │ │ └── demo │ │ ├── demo.css │ │ ├── demo.details │ │ ├── demo.html │ │ └── demo.js ├── eslintrc.json ├── generate.js ├── package.json ├── src │ ├── facade.js │ ├── readingData.js │ └── transfer.js └── yarn.lock ├── helpers ├── findTransactions.js ├── generateContractHash.js ├── generateInteropEnum.js ├── getBaseBranch.js └── urls.ts ├── jest.config.js ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── epicvault-api │ ├── README.md │ ├── __integration__ │ │ ├── NetworkFacade.ts │ │ ├── api │ │ │ ├── getFeeInformation.ts │ │ │ ├── getTokenBalances.ts │ │ │ └── getTokenInfos.ts │ │ └── transaction │ │ │ └── validator.ts │ ├── __tests__ │ │ ├── api │ │ │ ├── calculateNetworkFee.ts │ │ │ ├── getTokenBalances.ts │ │ │ └── getTokenInfos.ts │ │ └── transaction │ │ │ ├── TransactionBuilder.ts │ │ │ ├── signer.ts │ │ │ └── validator.ts │ ├── api-extractor.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── NetworkFacade.ts │ │ ├── api │ │ │ ├── calculateNetworkFee.ts │ │ │ ├── getCandidates.ts │ │ │ ├── getFeeInformation.ts │ │ │ ├── getTokenBalances.ts │ │ │ ├── getTokenInfos.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ └── transaction │ │ │ ├── TransactionBuilder.ts │ │ │ ├── index.ts │ │ │ ├── signer.ts │ │ │ ├── signing.ts │ │ │ └── validator.ts │ └── tsconfig.json ├── epicvault-core │ ├── README.md │ ├── __integration__ │ │ ├── rpc │ │ │ ├── RPCClient.ts │ │ │ └── clients │ │ │ │ ├── EpicChainServerRpcClient.ts │ │ │ │ └── TokenTrackerRpcClient.ts │ │ ├── sc │ │ │ └── contracts │ │ │ │ ├── EpicChainContract.ts │ │ │ │ └── Xep17Contract.ts │ │ └── wallet │ │ │ └── multisig.ts │ ├── __tests__ │ │ ├── internal.ts │ │ ├── rpc │ │ │ ├── Network.ts │ │ │ ├── Protocol.ts │ │ │ ├── Query.ts │ │ │ ├── clients │ │ │ │ └── RpcDispatcher.ts │ │ │ └── parse.ts │ │ ├── sc │ │ │ ├── ContractParam.ts │ │ │ ├── Nef.ts │ │ │ ├── OpToken.ts │ │ │ ├── ScriptBuilder.ts │ │ │ ├── StackItem.ts │ │ │ ├── contracts │ │ │ │ ├── BaseContract.ts │ │ │ │ ├── CovenantChain.ts │ │ │ │ ├── EpicChainContract.ts │ │ │ │ └── Xep17Contract.ts │ │ │ ├── core.ts │ │ │ ├── djnicholson.NeoPetShopContract.manifest.json │ │ │ ├── djnicholson.NeoPetShopContract.nef │ │ │ ├── fees.ts │ │ │ ├── manifest │ │ │ │ └── ContractManifest.ts │ │ │ ├── scriptIntents.json │ │ │ └── serializedData.json │ │ ├── testKeys.json │ │ ├── testWallet.json │ │ ├── testWallet1.json │ │ ├── testWallet2.json │ │ ├── testWallet3.json │ │ ├── tx │ │ │ ├── components │ │ │ │ ├── Signer.ts │ │ │ │ ├── TransactionAttribute.ts │ │ │ │ ├── Witness.ts │ │ │ │ ├── WitnessCondition.ts │ │ │ │ ├── WitnessRule.ts │ │ │ │ └── WitnessScope.ts │ │ │ └── transaction │ │ │ │ ├── Transaction.json │ │ │ │ └── Transaction.ts │ │ ├── u │ │ │ ├── BigInteger.ts │ │ │ ├── HexString.ts │ │ │ ├── StringStream.ts │ │ │ ├── basic │ │ │ │ ├── base64.ts │ │ │ │ ├── curve.ts │ │ │ │ ├── hash.ts │ │ │ │ └── hex.ts │ │ │ ├── convert.ts │ │ │ ├── misc.ts │ │ │ ├── random.ts │ │ │ └── serialize.ts │ │ └── wallet │ │ │ ├── Account.ts │ │ │ ├── Wallet.ts │ │ │ ├── core.ts │ │ │ ├── multisig.ts │ │ │ ├── nep2.ts │ │ │ ├── signing.ts │ │ │ └── verify.ts │ ├── api-extractor.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── consts.ts │ │ ├── events.ts │ │ ├── index.ts │ │ ├── internal.ts │ │ ├── logging.ts │ │ ├── model.ts │ │ ├── rpc.ts │ │ ├── rpc │ │ │ ├── BatchQuery.ts │ │ │ ├── Network.ts │ │ │ ├── Protocol.ts │ │ │ ├── Query.ts │ │ │ ├── RPCClient.ts │ │ │ ├── clients │ │ │ │ ├── ApplicationLogsRpcClient.ts │ │ │ │ ├── EpicChainServerRpcClient.ts │ │ │ │ ├── RpcDispatcher.ts │ │ │ │ ├── TokenTrackerRpcClient.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── parse.ts │ │ ├── sc │ │ │ ├── CallFlags.ts │ │ │ ├── ContractParam.ts │ │ │ ├── InteropServiceCode.ts │ │ │ ├── InteropServicePrices.ts │ │ │ ├── MethodToken.ts │ │ │ ├── OpCode.ts │ │ │ ├── OpCodeAnnotations.ts │ │ │ ├── OpCodePrices.ts │ │ │ ├── OpToken.ts │ │ │ ├── ScriptBuilder.ts │ │ │ ├── StackItem.ts │ │ │ ├── XEF.ts │ │ │ ├── contracts │ │ │ │ ├── BaseContract.ts │ │ │ │ ├── CovenantChain.ts │ │ │ │ ├── EpicChainContract.ts │ │ │ │ ├── EpicPulseContract.ts │ │ │ │ ├── Xep17Contract.ts │ │ │ │ ├── index.ts │ │ │ │ └── templates │ │ │ │ │ ├── EpicChainTemplateAbi.json │ │ │ │ │ ├── EpicPulseTemplateAbi.json │ │ │ │ │ ├── PolicyTemplateAbi.json │ │ │ │ │ └── Xep17TemplateAbi.json │ │ │ ├── core.ts │ │ │ ├── fees.ts │ │ │ ├── index.ts │ │ │ ├── manifest │ │ │ │ ├── ContractAbi.ts │ │ │ │ ├── ContractEventDefiniton.ts │ │ │ │ ├── ContractGroup.ts │ │ │ │ ├── ContractManifest.ts │ │ │ │ ├── ContractMethodDefinition.ts │ │ │ │ ├── ContractParameterDefinition.ts │ │ │ │ ├── ContractPermission.ts │ │ │ │ └── index.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── token.ts │ │ ├── tx │ │ │ ├── components │ │ │ │ ├── Signer.ts │ │ │ │ ├── TransactionAttribute.ts │ │ │ │ ├── Witness.ts │ │ │ │ ├── WitnessCondition.ts │ │ │ │ ├── WitnessRule.ts │ │ │ │ ├── WitnessScope.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── transaction │ │ │ │ ├── Transaction.ts │ │ │ │ ├── index.ts │ │ │ │ └── main.ts │ │ ├── types.ts │ │ ├── u │ │ │ ├── BigInteger.ts │ │ │ ├── HexString.ts │ │ │ ├── StringStream.ts │ │ │ ├── basic │ │ │ │ ├── base64.ts │ │ │ │ ├── curve.ts │ │ │ │ ├── hash.ts │ │ │ │ ├── hex.ts │ │ │ │ ├── index.ts │ │ │ │ └── random.ts │ │ │ ├── convert.ts │ │ │ ├── index.ts │ │ │ ├── misc.ts │ │ │ └── serialize.ts │ │ └── wallet │ │ │ ├── Account.ts │ │ │ ├── Wallet.ts │ │ │ ├── core.ts │ │ │ ├── index.ts │ │ │ ├── multisig.ts │ │ │ ├── signing.ts │ │ │ ├── upgrade.ts │ │ │ ├── verify.ts │ │ │ └── xep2.ts │ ├── test.html │ ├── tsconfig.json │ └── webpack.config.js ├── epicvault-js │ ├── README.md │ ├── __integration__ │ │ └── experimental │ │ │ ├── contract3.manifest.json │ │ │ ├── contract3.nef │ │ │ ├── contract3.py │ │ │ └── helpers.ts │ ├── api-extractor.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── experimental │ │ │ ├── README.md │ │ │ ├── contract.ts │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── xep17 │ │ │ │ ├── base.ts │ │ │ │ └── index.ts │ │ ├── features.ts │ │ └── index.ts │ ├── test.html │ ├── tsconfig.json │ └── webpack.config.js ├── epicvault-ledger │ ├── README.md │ ├── __tests__ │ │ ├── BIP44.ts │ │ └── main.ts │ ├── api-extractor.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── BIP44.ts │ │ ├── ErrorCode.ts │ │ ├── features.ts │ │ ├── index.ts │ │ ├── main.ts │ │ └── utils.ts │ ├── test.node.js │ └── tsconfig.json ├── epicvault-test │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json └── epicvault-uri │ ├── README.md │ ├── __tests__ │ └── parse.ts │ ├── api-extractor.json │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── create.ts │ ├── features.ts │ ├── index.ts │ └── parse.ts │ └── tsconfig.json ├── test.html ├── test.sh ├── testHelpers.ts ├── tsconfig-base.json ├── tsconfig-test.json ├── tsconfig.json ├── webpack.common.js ├── website ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── customTheme.css │ └── pages │ │ ├── help.js │ │ └── index.js └── static │ ├── css │ └── custom.css │ └── img │ ├── console.png │ ├── coz_med.png │ ├── docusaurus.svg │ ├── favicon │ └── favicon.ico │ ├── logo.svg │ └── logo_full.svg └── yarn.lock /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Update the VARIANT arg in docker-compose.yml to pick a Node version: 14, 16, 18 2 | ARG VARIANT=16 3 | 4 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT} 5 | 6 | RUN sudo apt-get update && sudo apt-get -y install libusb-1.0-0-dev libusb-1.0-0 libudev-dev 7 | 8 | # Update args in docker-compose.yaml to set the UID/GID of the "node" user. 9 | ARG USER_UID=1000 10 | ARG USER_GID=$USER_UID 11 | RUN if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \ 12 | groupmod --gid $USER_GID node \ 13 | && usermod --uid $USER_UID --gid $USER_GID node \ 14 | && chmod -R $USER_UID:$USER_GID /home/node \ 15 | && chmod -R $USER_UID:root /usr/local/share/nvm /usr/local/share/npm-global; \ 16 | fi 17 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "neo N3 neon-js dev environment", 3 | "dockerComposeFile": "docker-compose.yml", 4 | "service": "main", 5 | "workspaceFolder": "/workspace", 6 | "settings": { 7 | "terminal.integrated.shell.linux": "/bin/bash" 8 | }, 9 | "extensions": [ 10 | "dbaeumer.vscode-eslint", 11 | "esbenp.prettier-vscode" 12 | ], 13 | "forwardPorts": [ 14 | 3000, 15 | 20332 16 | ], 17 | "postCreateCommand": "npm i", 18 | "remoteUser": "node" 19 | } -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | main: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | args: 9 | # [Choice] Node.js version: 16, 18, 19 10 | VARIANT: 18 11 | # On Linux, you may need to update USER_UID and USER_GID below if not your local UID is not 1000. 12 | USER_UID: 1000 13 | USER_GID: 1000 14 | 15 | volumes: 16 | - ..:/workspace:cached 17 | 18 | # Overrides default command so things don't shut down after the process ends. 19 | command: sleep infinity 20 | 21 | # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. 22 | network_mode: service:solonet 23 | 24 | # Uncomment the next line to use a non-root user for all processes. 25 | # user: node 26 | # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 27 | # (Adding the "ports" property to this file will not forward from a Codespace.) 28 | 29 | solonet: 30 | image: snowypowers/n3-csharp-solonet:3.5.0 31 | restart: unless-stopped 32 | volumes: 33 | - ../tmp/:/opt/neo-cli:consistent 34 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Node modules 2 | /node_modules/ 3 | 4 | # Website 5 | /website/ 6 | 7 | /examples/ 8 | 9 | # Packages output dir 10 | /packages/**/lib/ 11 | /packages/**/node_modules/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | .pnp/ 4 | .pnp.js 5 | 6 | # Testing 7 | coverage/ 8 | .nyc_output/ 9 | 10 | # Production 11 | dist/ 12 | build/ 13 | *.min.js 14 | *.min.css 15 | 16 | # Development 17 | .env 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | # Logs 24 | logs 25 | *.log 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | 30 | # Editor directories and files 31 | .idea/ 32 | .vscode/ 33 | *.suo 34 | *.ntvs* 35 | *.njsproj 36 | *.sln 37 | *.sw? 38 | 39 | # OS generated files 40 | .DS_Store 41 | .DS_Store? 42 | ._* 43 | .Spotlight-V100 44 | .Trashes 45 | ehthumbs.db 46 | Thumbs.db 47 | 48 | # Lerna 49 | lerna-debug.log 50 | 51 | # TypeScript 52 | *.tsbuildinfo 53 | 54 | # Temporary files 55 | *.tmp 56 | *.temp 57 | .temp/ 58 | .tmp/ 59 | 60 | # Cache 61 | .cache/ 62 | .npm/ 63 | .eslintcache 64 | .stylelintcache 65 | 66 | # Misc 67 | .DS_Store 68 | .env.local 69 | .env.development.local 70 | .env.test.local 71 | .env.production.local 72 | 73 | # Globally ignored folder names 74 | .nyc_output 75 | /lib/ 76 | 77 | # IDE specific 78 | !.vscode/settings.json 79 | !.vscode/launch.json 80 | 81 | # Package stuff 82 | packages/**/lib 83 | packages/**/dist 84 | packages/**/temp 85 | 86 | # Website 87 | website/.docusaurus -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Jest run all", 11 | "program": "${workspaceRoot}/node_modules/jest/bin/jest", 12 | "args": ["--verbose", "-i", "--no-cache"], 13 | "console": "integratedTerminal", 14 | "internalConsoleOptions": "neverOpen", 15 | "skipFiles": ["/**/*.js"] 16 | }, 17 | { 18 | "type": "node", 19 | "request": "launch", 20 | "name": "Jest watch current file", 21 | "program": "${workspaceRoot}/node_modules/jest/bin/jest", 22 | "args": ["${fileBasename}", "--verbose", "-i", "--watchAll"], 23 | "console": "integratedTerminal", 24 | "internalConsoleOptions": "neverOpen", 25 | "skipFiles": ["/**/*.js"] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib", 3 | } 4 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | workspaces-experimental true 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2024 EpicChain Lab's 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api-extractor-base.json: -------------------------------------------------------------------------------- 1 | /** 2 | * Config file for API Extractor. For more info, please visit: https://api-extractor.com 3 | */ 4 | { 5 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 6 | "mainEntryPointFilePath": "/lib/index.d.ts", 7 | "bundledPackages": [], 8 | /** 9 | * Configures how the API report file (*.api.md) will be generated. 10 | */ 11 | "apiReport": { 12 | "enabled": true, 13 | "reportFolder": "/../../common/api" 14 | }, 15 | /** 16 | * Configures how the doc model file (*.api.json) will be generated. 17 | */ 18 | "docModel": { 19 | "enabled": true, 20 | "apiJsonFilePath": "/../../common/api/.api.json" 21 | }, 22 | /** 23 | * Configures how the .d.ts rollup file will be generated. 24 | */ 25 | "dtsRollup": { 26 | "enabled": false, 27 | "untrimmedFilePath": "/dist/index.d.ts" 28 | }, 29 | /** 30 | * Configures how the tsdoc-metadata.json file will be generated. 31 | */ 32 | "tsdocMetadata": { 33 | "enabled": false 34 | }, 35 | "newlineKind": "os", 36 | /** 37 | * Configures how API Extractor reports error and warning messages produced during analysis. 38 | * 39 | * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. 40 | */ 41 | "messages": { 42 | "compilerMessageReporting": { 43 | "default": { 44 | "logLevel": "warning" 45 | } 46 | }, 47 | "extractorMessageReporting": { 48 | "default": { 49 | "logLevel": "warning" 50 | } 51 | }, 52 | "tsdocMessageReporting": { 53 | "default": { 54 | "logLevel": "warning" 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /common/api/epicvault-ledger.api.md: -------------------------------------------------------------------------------- 1 | ## API Report File for "@epicchain/epicvault-ledger" 2 | 3 | > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). 4 | 5 | ```ts 6 | 7 | import Transport from '@ledgerhq/hw-transport'; 8 | 9 | // @public 10 | export function BIP44(address?: number, change?: number, account?: number): string; 11 | 12 | // @public 13 | export function evalTransportError(err: Error): Error; 14 | 15 | // @public 16 | export function getAppName(ledger: Transport): Promise; 17 | 18 | // @public 19 | export function getAppVersion(ledger: Transport): Promise; 20 | 21 | // @public 22 | export function getDevicePaths(ledgerLibrary: typeof Transport): Promise>; 23 | 24 | // @public 25 | export function getPublicKey(ledger: Transport, bip44String: string, showAddressOnDevice?: boolean): Promise; 26 | 27 | // @public 28 | export function getSignature(ledger: Transport, payload: string, bip44String: string, network: number): Promise; 29 | 30 | // (No @packageDocumentation comment for this package) 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /common/api/epicvault-uri.api.md: -------------------------------------------------------------------------------- 1 | ## API Report File for "@epicchain/epicvault-uri" 2 | 3 | > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). 4 | 5 | ```ts 6 | 7 | import type { sc } from '@epicchain/epicvault-core'; 8 | 9 | // @public 10 | export function createPayUri(toAddress: string, asset: string, amount?: number): string; 11 | 12 | // @public 13 | export function createVoteUri(publicKey: string): string; 14 | 15 | // @public 16 | export function parse(uri: string): UriIntent; 17 | 18 | // @public 19 | export interface UriIntent { 20 | // (undocumented) 21 | contractCall: sc.ContractCallJson; 22 | // (undocumented) 23 | description: string; 24 | // (undocumented) 25 | intent: "pay" | "vote"; 26 | } 27 | 28 | // (No @packageDocumentation comment for this package) 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /debug/sale.js: -------------------------------------------------------------------------------- 1 | var Neon = require("../lib/index"); 2 | 3 | const contractHash = "ae36e5a84ee861200676627df409b0f6eec44bd7"; 4 | 5 | const config = { 6 | net: "TestNet", 7 | account: new Neon.wallet.Account( 8 | "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG" 9 | ), 10 | intents: Neon.api.makeIntent( 11 | { GAS: 1 }, 12 | Neon.wallet.getAddressFromScriptHash(contractHash) 13 | ), 14 | script: { 15 | scriptHash: contractHash, 16 | operation: "mintTokens", 17 | args: [], 18 | }, 19 | gas: 0, 20 | }; 21 | 22 | Neon.api 23 | .doInvoke(config) 24 | .then((res) => { 25 | console.log(res); 26 | }) 27 | .catch((err) => console.log(err)); 28 | -------------------------------------------------------------------------------- /debug/tokenBalance.js: -------------------------------------------------------------------------------- 1 | const Neon = require("../packages/neon-js/dist/index"); 2 | const testKeys = require("../packages/neon-core/__tests__/testKeys.json"); 3 | 4 | const url = "http://test1.cityofzion.io:8880"; 5 | console.log(Neon.nep5); 6 | const printTokenBalances = function (scriptHash) { 7 | return Neon.nep5 8 | .getToken(url, scriptHash) 9 | .then(({ symbol }) => { 10 | console.log(`=== ${symbol} ===`); 11 | }) 12 | .then(() => { 13 | const balances = Object.keys(testKeys).map((key) => { 14 | const addr = testKeys[key].address; 15 | return Neon.nep5 16 | .getToken(url, scriptHash, addr) 17 | .then((res) => console.log(`${key}: ${res.balance}`)); 18 | }); 19 | return Promise.all(balances); 20 | }); 21 | }; 22 | 23 | printTokenBalances(Neon.CONST.CONTRACTS.TEST_LWTF) 24 | .then(() => printTokenBalances(Neon.CONST.CONTRACTS.TEST_RPX)) 25 | .then(() => printTokenBalances("ae36e5a84ee861200676627df409b0f6eec44bd7")); 26 | -------------------------------------------------------------------------------- /debug/vote.js: -------------------------------------------------------------------------------- 1 | var Neon = require("../lib/index"); 2 | 3 | const config = { 4 | net: "TestNet", 5 | // ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW 6 | account: new Neon.wallet.Account( 7 | "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g" 8 | ), 9 | candidateKeys: [ 10 | "030ef96257401b803da5dd201233e2be828795672b775dd674d69df83f7aec1e36", 11 | "0327da12b5c40200e9f65569476bbff2218da4f32548ff43b6387ec1416a231ee8", 12 | ], 13 | }; 14 | 15 | Neon.api 16 | .setupVote(config) 17 | .then((res) => { 18 | console.log(res); 19 | console.log(res.tx.descriptors[0]); 20 | console.log(res.tx.serialize(true)); 21 | }) 22 | .catch((err) => { 23 | console.log(err); 24 | console.log(err.tx.descriptors[0]); 25 | console.log(err.tx.serialize(true)); 26 | }); 27 | -------------------------------------------------------------------------------- /docs/api/core/const.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: const 3 | title: Constants 4 | --- 5 | 6 | Constants are defined and exposed as: 7 | 8 | ```ts 9 | import Neon from "@cityofzion/neon-js"; 10 | const nativeContractHashes = Neon.CONST.NATIVE_CONTRACT_HASH; 11 | 12 | import { CONST } from "@cityofzion/neon-js"; 13 | const addrVersion = CONST.DEFAULT_ADDRESS_VERSION; 14 | ``` 15 | 16 | Do refer to the source code for all the constants available. 17 | -------------------------------------------------------------------------------- /docs/api/core/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: logging 3 | title: Logging 4 | --- 5 | 6 | The logging module is exposed only as a named import : 7 | 8 | ```ts 9 | import { logging } from "@cityofzion/neon-js"; 10 | logging.logger.setDefaultLevel("info"); // sets logging level of neon-js to 'info' 11 | const apiLogger = logging.logger.getLogger("api"); // gets the logger for the api package 12 | apiLogger.setLevel("warn"); // sets logging level only on the logger for the api package 13 | ``` 14 | 15 | All logs are piped towards `stdout` and `stderr`. Each named package within 16 | `neon-js` will have its own logger. The initial setting for all loggers is 17 | 'silent'. 18 | -------------------------------------------------------------------------------- /docs/api/core/tx.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: tx 3 | title: Transactions 4 | --- 5 | 6 | The `tx` module is exposed as: 7 | 8 | ```ts 9 | import { tx, wallet } from "@cityofzion/neon-js"; 10 | const acct = new wallet.Account(); 11 | const transaction = new tx.Transaction(); 12 | transaction.addSigner(new tx.Signer({ account: acct.scriptHash })); 13 | transaction.sign(acct); 14 | console.log(transaction.hash()); 15 | ``` 16 | 17 | Transactions form the core of the interaction with the blockchain. In order to 18 | effect any state changes on the chain, a transaction is required to be sent and 19 | processed into a block by the consensus nodes. 20 | 21 | ```js 22 | // We can use this serializedTx string and send it through sendrawtransaction RPC call. 23 | const serializedTx = transaction.serialize(); 24 | ``` 25 | --- 26 | 27 | ## Components 28 | 29 | Transactions are composed of the following parts: 30 | 31 | 1. Version 32 | 33 | This determines the version of the transaction. Protocol may defer for different 34 | versions. 35 | 36 | 2. Witnesses 37 | 38 | The witnesses to the transaction. These are the signatures to authorise the 39 | transaction. Usually the private key of the owner of the input assets is used to 40 | generate the signature. 41 | 42 | 3. Signers 43 | 44 | The signers control the validity of the signatures and can be checked in smart contracts using the `CheckWitness` 45 | functionality. A good article on how they work and can be used can be read here https://neospcc.medium.com/thou-shalt-check-their-witnesses-485d2bf8375d 46 | The first signer is also known as the `sender` and will pay for the transaction fees. 47 | 48 | 4. Attributes 49 | 50 | Extra attributes that are attached to the transaction. An example is a OracleResponse. 51 | Attributes can only be set by special entities in the system (being the consensus committee or an Oracle node). 52 | -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: index 3 | title: API 4 | sidebar_position: 1 5 | --- 6 | 7 | `neon-js` is laid out in a modules style, with each folder in the source code 8 | representing a module with a particular functionality. 9 | 10 | ## default 11 | 12 | The default import for Neon is a Javascript object where functions are arranged 13 | in a semantic manner following the convention of Verb-Noun. If a method goes 14 | beyond 2 levels, the rest of the name is camelCased at the noun level. 15 | 16 | ```js 17 | import Neon from "@cityofzion/neon-js"; 18 | Neon.create.privateKey(); 19 | Neon.serialize.tx(transactionObj); 20 | Neon.get.publicKeyFromPrivateKey(privateKey); 21 | ``` 22 | 23 | This style is recommended for beginners or anyone who just wishes to use Neon 24 | without hassle. 25 | 26 | ## api 27 | 28 | The `api` module contains code that interfaces with external APIs as well as 29 | providing a high level abstraction. 30 | 31 | ## wallet 32 | 33 | The `wallet` module deals with key manipulating as well as importing and 34 | exporting of wallet files. 35 | 36 | ## tx 37 | 38 | The `tx` module deals with transaction creation, serialization and 39 | deserialization. 40 | 41 | ## sc 42 | 43 | The `sc` module deals with smart contract script construction. It is used 44 | primarily to construct scripts that can be carried by InvocationTransaction. 45 | 46 | ## rpc 47 | 48 | The `rpc` module deals with the RPC interface exposed by the NEO node. 49 | 50 | ## u 51 | 52 | The `u` module is the utilities module containing methods handling the various 53 | data transformation aspects within NEO. 54 | 55 | ## CONST 56 | 57 | The `CONST` module is a collection of constants and defaults used across all 58 | modules. 59 | -------------------------------------------------------------------------------- /docs/changelog/v1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Changelog (v1) 3 | --- 4 | 5 | ## 1.1.1 6 | 7 | - Ledger support 8 | 9 | - Add ability to sign using external function for neonDB API. 10 | - Bugfix for \_emitNum 11 | 12 | 1.1.0 13 | 14 | --- 15 | 16 | - Transaction Overhaul 17 | 18 | - Transactions are now exposed semantically with the convention of Verb-Noun. 19 | - Transaction creation is exposed as `create.claim`, `create.contract` and 20 | `create.invocation` 21 | - Transactions can be serialized or deserialzed using `serializeTransaction` 22 | and `deserializeTransaction` 23 | - Transaction signing is now `signTransaction` and it returns the signed 24 | transaction instead of having to manually attach the signature. 25 | - Transaction Hash can be calculated using `getTransactionHash` passing in the 26 | transaction object. 27 | 28 | - ScriptBuilder for Smart Contract invocation 29 | 30 | - ScriptBuilder class is an object used to build VM scripts that mirrors the 31 | ScriptBuilder found in the C# repo. 32 | - `buildScript` is a convenient wrapper around ScriptBuilder to call a 33 | contract with `operation` accepting `args`. 34 | 35 | - getAccount methods renamed to getAccount and returns a single Account object 36 | instead of an array 37 | 38 | | getAccountsFromWIFKey -> getAccountFromWIFKey | getAccountsFromPrivateKey -> 39 | getAccountFromPrivateKey 40 | 41 | 1.0.4 42 | 43 | --- 44 | 45 | - Additional XEP2 wrapper methods (Simple encrypted WIF creation) 46 | - Address validation to guard against sending to non-NEO addresses. 47 | 48 | 1.0.2 49 | 50 | --- 51 | 52 | - Introduce XEP2 Support (encrypt / decrypt WIF) 53 | 54 | 1.0.1 55 | 56 | --- 57 | 58 | - Upgrade API support to v2 for neon-wallet-db 59 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: installation 3 | title: Installation 4 | --- 5 | 6 | ## Install 7 | 8 | To install 9 | 10 | ```sh 11 | npm install @cityofzion/neon-js 12 | ``` 13 | 14 | or 15 | 16 | ```sh 17 | npm install @cityofzion/neon-core 18 | ``` 19 | 20 | This will give you the release that is compatible for the neo3 mainnet and testnet. 21 | 22 | > **Note** 23 | > For most use-cases, we recommend `neon-js`. 24 | > Do not use `neon-js` and `neon-core` in the same project. The classes are not cross-package compatible. See https://github.com/CityOfZion/neon-js/issues/850. 25 | 26 | ## Node 27 | 28 | Support policy is to support the maintainence and LTS versions of Node. At the 29 | time of writing, this is: 30 | 31 | - Node 12 32 | - Node 14 33 | - Node 16 34 | 35 | ## Web 36 | 37 | Both `neon-core` and `neon-js` are packaged for the web. Use script tags: 38 | 39 | ```html 40 | 41 | ``` 42 | 43 | The library will be loaded under the variable `Neon`. 44 | -------------------------------------------------------------------------------- /docs/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: overview 3 | title: Overview 4 | slug: / 5 | --- 6 | 7 | `neon-js` is a Javascript library to interface with NEO blockchain, providing 8 | quick and easy methods to send RPC calls, create transactions and simple 9 | contract invocations. 10 | 11 | ## Features 12 | 13 | - Built-in RPC queries 14 | - Transaction creation, serialization and deserialization 15 | - Wallet key manipulation 16 | - Smart Contract script builder 17 | - 3rd party API support 18 | 19 | ## Usage 20 | 21 | Neon can be used in 2 ways: 22 | 23 | ### Semantic 24 | 25 | The default import for Neon is a Javascript object where functions are arranged 26 | in a semantic manner following the convention of Verb-Noun. If a method goes 27 | beyond 2 levels, the rest of the name is camelCased at the noun level. 28 | 29 | ```js 30 | import Neon from "@cityofzion/neon-js"; 31 | Neon.create.privateKey(); 32 | Neon.deserialize.tx(serializedTransaction); 33 | Neon.verify.message(message, signature, publicKey) 34 | ``` 35 | 36 | This style is recommended for beginners or anyone who just wishes to use Neon 37 | without hassle. 38 | 39 | ### Named 40 | 41 | Named imports are the conventional JS imports. The modules in Neon are: 42 | 43 | - `api` 44 | - `CONST` 45 | - `rpc` 46 | - `sc` 47 | - `tx` 48 | - `u` 49 | - `wallet` 50 | 51 | ```js 52 | import { api } from "@cityofzion/neon-js"; 53 | ``` 54 | 55 | This style offers more control and flexibility. Do refer to the source code for 56 | each module's exports. 57 | -------------------------------------------------------------------------------- /docs/structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: structure 3 | title: Structure 4 | --- 5 | 6 | The package `neon-js` is actually composed of several packages, each offering a 7 | different functionality. 8 | 9 | ## Core 10 | 11 | The core package is `neon-core`, comprised of the following folders: 12 | 13 | - `rpc` 14 | - `sc` 15 | - `tx` 16 | - `u` 17 | - `wallet` 18 | 19 | These are the minimum packages deemed necessary for basic functionality for 20 | interaction with the blockchain. The sub module `CONST` rounds off the core module with some defaults. 21 | 22 | For users who just require the bare functionality, you may just use the core 23 | package: 24 | 25 | ```js 26 | import { tx, wallet } from "@epicchain/epicvault-core"; 27 | const t = new tx.Transaction(); 28 | const acct = new wallet.Account(); 29 | ``` 30 | 31 | ## Other packages 32 | 33 | ### api 34 | Provides high level functionality for crafting transactions. 35 | 36 | ### ledger 37 | 38 | Provides an easy wrapper for communicating with the NEO N3 app on a Ledger. 39 | 40 | ### neon-js 41 | 42 | Constructed package using: 43 | 44 | - `neon-core` 45 | - `neon-api` 46 | 47 | In addition, this package exposes a high level semantic API binding for beginner usage. The semantic API can be found in the default export of the package. 48 | 49 | ```js 50 | const Neon = require("@cityofzion/neon-js"); 51 | 52 | console.log(Neon); // {wallet, tx, api, nep5, etc...} 53 | 54 | const NeonJs = Neon.default; 55 | 56 | console.log(NeonJs); // {create, get, sign, verify,...} 57 | ``` 58 | 59 | The semantic API follows a convention of Verb-Noun. Any extra words beyond the first 2 is collapsed into the Noun and camelcased. 60 | 61 | ```js 62 | NeonJs.create.stringStream("1234"); 63 | NeonJs.encrypt.privateKey("key"); 64 | ``` 65 | 66 | ### uri 67 | 68 | Provides the ability to parse a NEO URI schema string into a consumable intent object. 69 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Neon examples 2 | 3 | This is the source folder for guides generated to /docs/guides. The folder structure is the same. To start: 4 | 5 | ``` 6 | yarn 7 | node basic/facade.js 8 | ``` 9 | 10 | ## Develop 11 | 12 | `npm run generate` will parse the files and use `ljs2` to invert the comments and codeblocks. The outputs will override all the files in docs/guides. 13 | -------------------------------------------------------------------------------- /examples/browser/doinvoke/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/doinvoke/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: doInvoke (browser version) 2 | description: Demonstrates the doInvoke function of the neon-js API 3 | -------------------------------------------------------------------------------- /examples/browser/doinvoke/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to invoke the smart contract 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/doinvoke/demo/demo.js: -------------------------------------------------------------------------------- 1 | const sendingKey = 2 | "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69"; 3 | const additionalInvocationGas = 0; 4 | const additionalIntents = []; 5 | 6 | function InvokeOperation() 7 | { 8 | 9 | const provider = new Neon.api.neoscan.instance("TestNet"); 10 | 11 | Neon.settings.httpsOnly = true; 12 | 13 | const account = new Neon.wallet.Account(sendingKey); 14 | 15 | const props = { 16 | scriptHash: '9488220e8654d798f9b9cb9e74bd611ecc83fd0f', 17 | operation: 'getBalance', 18 | args: [Neon.u.reverseHex('def0c0fdcfe7838eff6ff104f9cdec2922297525'), 19 | Neon.u.reverseHex('def0c0fdcfe7838eff6ff104f9cdec2922297524')] 20 | } 21 | 22 | const script = Neon.sc.createScript(props); 23 | const gas = additionalInvocationGas; 24 | const intent = additionalIntents; 25 | const config = { 26 | api: provider, 27 | account: account, 28 | intents: intent, 29 | script: script, 30 | gas: gas 31 | }; 32 | Neon.api.doInvoke(config) 33 | .then(config => { 34 | document.getElementById("result").innerHTML = "Relayed TX: " + config.response.txid; 35 | console.log("\n\n--- Response ---"); 36 | console.log(config.response); 37 | }) 38 | .catch(config => { 39 | console.log(config); 40 | document.getElementById("result").innerHTML = config; 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/getaccountstate/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getaccountstate/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getaccountstate 2 | description: Get the account state for a wallet address 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getaccountstate/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getaccountstate/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Wallet address to query 2 | const accountAddress = "APJnYRic9fYo1bLAdrqDbwrsnqoUD92dWo" 3 | // Get an instance of Neoscan so we can find a working node 4 | const provider = new Neon.api.neoscan.instance("TestNet"); 5 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 6 | Neon.settings.httpsOnly = true; 7 | 8 | function InvokeOperation() 9 | { 10 | clearHtml(); 11 | 12 | // Get an RPC Endpoint (Neo Node) 13 | provider.getRPCEndpoint().then(nodeUrl => { 14 | const client = Neon.default.create.rpcClient(nodeUrl); 15 | client.getAccountState(accountAddress).then(response => { 16 | outputHtml('Wallet Address: ' + accountAddress); 17 | outputHtml('Account State:'); 18 | iterate(response, ''); 19 | }); 20 | }); 21 | } 22 | 23 | // Utility function to iterate over objects and display them to an output div 24 | function iterate(obj, stack) { 25 | for (var property in obj) { 26 | if (obj.hasOwnProperty(property)) { 27 | if (typeof obj[property] == "object") { 28 | iterate(obj[property], stack + '.' + property); 29 | } else { 30 | console.log(property + " " + obj[property]); 31 | outputHtml(stack + '.' + property + ': ' + obj[property]); 32 | } 33 | } 34 | } 35 | } 36 | 37 | // Utility function to print output to an HTML div tag 38 | function outputHtml(s) { 39 | document.getElementById("result").innerHTML += s + "
"; 40 | } 41 | 42 | function clearHtml() { 43 | document.getElementById("result").innerHTML = ""; 44 | } 45 | -------------------------------------------------------------------------------- /examples/browser/getassetstate/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getassetstate/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getassetstate 2 | description: Queries the asset information, based on the specified asset number. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getassetstate/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getassetstate/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hashes of the Neo and Gas assets 2 | const neoHash = "0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" 3 | const gasHash = "0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" 4 | const hash = neoHash 5 | 6 | // Get an instance of Neoscan so we can find a working node 7 | const provider = new Neon.api.neoscan.instance("TestNet"); 8 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 9 | Neon.settings.httpsOnly = true; 10 | 11 | function InvokeOperation() 12 | { 13 | clearHtml(); 14 | 15 | // Get an RPC Endpoint (Neo Node) 16 | provider.getRPCEndpoint().then(nodeUrl => { 17 | const client = Neon.default.create.rpcClient(nodeUrl); 18 | client.getAssetState(hash).then(response => { 19 | outputHtml('Hash: ' + hash); 20 | outputHtml('Asset:'); 21 | iterate(response, ''); 22 | }); 23 | }); 24 | } 25 | 26 | // Utility function to iterate over objects and display them to an output div 27 | function iterate(obj, stack) { 28 | for (var property in obj) { 29 | if (obj.hasOwnProperty(property)) { 30 | if (typeof obj[property] == "object") { 31 | iterate(obj[property], stack + '.' + property); 32 | } else { 33 | console.log(property + " " + obj[property]); 34 | outputHtml(stack + '.' + property + ': ' + obj[property]); 35 | } 36 | } 37 | } 38 | } 39 | 40 | // Utility function to print output to an HTML div tag 41 | function outputHtml(s) { 42 | document.getElementById("result").innerHTML += s; 43 | } 44 | 45 | function clearHtml() { 46 | document.getElementById("result").innerHTML = ""; 47 | } 48 | -------------------------------------------------------------------------------- /examples/browser/getbalance/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getbalance/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getbalance 2 | description: Returns the balance of the corresponding asset in the wallet according to the specified asset number. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getbalance/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getbalance/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hashes of the Neo and Gas assets 2 | const neoHash = "0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" 3 | const gasHash = "0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" 4 | const hash = neoHash 5 | 6 | // Get an instance of Neoscan so we can find a working node 7 | const provider = new Neon.api.neoscan.instance("TestNet"); 8 | 9 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 10 | Neon.settings.httpsOnly = true; 11 | 12 | function InvokeOperation() 13 | { 14 | clearHtml(); 15 | 16 | // Get an RPC Endpoint (Neo Node) 17 | provider.getRPCEndpoint().then(nodeUrl => { 18 | const client = Neon.default.create.rpcClient(nodeUrl); 19 | client.getBalance(hash).then(response => { 20 | outputHtml('Hash: ' + hash); 21 | outputHtml('Asset:'); 22 | iterate(response, ''); 23 | }); 24 | }); 25 | } 26 | 27 | // Utility function to iterate over objects and display them to an output div 28 | function iterate(obj, stack) { 29 | for (var property in obj) { 30 | if (obj.hasOwnProperty(property)) { 31 | if (typeof obj[property] == "object") { 32 | iterate(obj[property], stack + '.' + property); 33 | } else { 34 | console.log(property + " " + obj[property]); 35 | outputHtml(stack + '.' + property + ': ' + obj[property]); 36 | } 37 | } 38 | } 39 | } 40 | 41 | // Utility function to print output to an HTML div tag 42 | function outputHtml(s) { 43 | document.getElementById("result").innerHTML += s + "
"; 44 | } 45 | 46 | function clearHtml() { 47 | document.getElementById("result").innerHTML = ""; 48 | } 49 | -------------------------------------------------------------------------------- /examples/browser/getbestblockhash/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getbestblockhash/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getbestblockhash 2 | description: Get the hash of the highest (most recent) block. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getbestblockhash/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getbestblockhash/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getBestBlockHash().then(response => { 15 | outputHtml('Result: ' + response); 16 | }); 17 | }); 18 | } 19 | 20 | // Utility function to iterate over objects and display them to an output div 21 | function iterate(obj, stack) { 22 | for (var property in obj) { 23 | if (obj.hasOwnProperty(property)) { 24 | if (typeof obj[property] == "object") { 25 | iterate(obj[property], stack + '.' + property); 26 | } else { 27 | console.log(property + " " + obj[property]); 28 | outputHtml(stack + '.' + property + ': ' + obj[property]); 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Utility function to print output to an HTML div tag 35 | function outputHtml(s) { 36 | document.getElementById("result").innerHTML += s + "
"; 37 | } 38 | 39 | function clearHtml() { 40 | document.getElementById("result").innerHTML = ""; 41 | } 42 | -------------------------------------------------------------------------------- /examples/browser/getblock/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getblock/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getblock 2 | description: Get block data by its hash or index. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getblock/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getblock/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hash of the block to get 2 | const hash = "0x3d298e045e9b8d191e94239848a1ccee5b835afe01b9f7cfe07a1fa7af3d908c" 3 | 4 | // Index of the block to get 5 | const index = 0 // <- very first block ever on neo blockchain! 6 | 7 | // Get an instance of Neoscan so we can find a working node 8 | const provider = new Neon.api.neoscan.instance("TestNet"); 9 | 10 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 11 | Neon.settings.httpsOnly = true; 12 | 13 | function InvokeOperation() 14 | { 15 | clearHtml(); 16 | 17 | // Get an RPC Endpoint (Neo Node) 18 | provider.getRPCEndpoint().then(nodeUrl => { 19 | const client = Neon.default.create.rpcClient(nodeUrl); 20 | // change 'hash' below to 'index' to use the index version of getblock 21 | client.getBlock(hash).then(response => { 22 | outputHtml('Block Data: '); 23 | iterate(response, ''); 24 | }); 25 | }); 26 | } 27 | 28 | // Utility function to iterate over objects and display them to an output div 29 | function iterate(obj, stack) { 30 | for (var property in obj) { 31 | if (obj.hasOwnProperty(property)) { 32 | if (typeof obj[property] == "object") { 33 | iterate(obj[property], stack + '.' + property); 34 | } else { 35 | console.log(property + " " + obj[property]); 36 | outputHtml(stack + '.' + property + ': ' + obj[property]); 37 | } 38 | } 39 | } 40 | } 41 | 42 | // Utility function to print output to an HTML div tag 43 | function outputHtml(s) { 44 | document.getElementById("result").innerHTML += s + "
"; 45 | } 46 | 47 | function clearHtml() { 48 | document.getElementById("result").innerHTML = ""; 49 | } 50 | -------------------------------------------------------------------------------- /examples/browser/getblockcount/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getblockcount/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getblockcount 2 | description: Get the number of blocks on a chain. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getblockcount/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getblockcount/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getBlockCount().then(response => { 15 | outputHtml('Result: ' + response); 16 | }); 17 | }); 18 | } 19 | 20 | // Utility function to iterate over objects and display them to an output div 21 | function iterate(obj, stack) { 22 | for (var property in obj) { 23 | if (obj.hasOwnProperty(property)) { 24 | if (typeof obj[property] == "object") { 25 | iterate(obj[property], stack + '.' + property); 26 | } else { 27 | console.log(property + " " + obj[property]); 28 | outputHtml(stack + '.' + property + ': ' + obj[property]); 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Utility function to print output to an HTML div tag 35 | function outputHtml(s) { 36 | document.getElementById("result").innerHTML += s + "
"; 37 | } 38 | 39 | function clearHtml() { 40 | document.getElementById("result").innerHTML = ""; 41 | } 42 | -------------------------------------------------------------------------------- /examples/browser/getblockheader/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getblockheader/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getblockheader 2 | description: Returns the corresponding block header information according to the specified script hash. This method builds a custom request and executes it using the neon-js RPC query facility. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getblockheader/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getblockheader/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hash of the block to get 2 | const hash = "0x3d298e045e9b8d191e94239848a1ccee5b835afe01b9f7cfe07a1fa7af3d908c" 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | rpcQuery(response => { 17 | outputHtml('Block Data: '); 18 | outputHtml("Block Header: "); 19 | iterate(response, ''); 20 | }, nodeUrl, "getblockheader", hash); 21 | }); 22 | } 23 | 24 | // This is a reusable function that packages an unsupported RPC API call into a generic neon-js query object. 25 | function rpcQuery(callback, url, method, parms) { 26 | let args 27 | 28 | if (parms) { 29 | let s = parms 30 | args = s.split(',') 31 | outputHtml('args: ' + args); 32 | } 33 | 34 | const query = Neon.default.create.query({method: method, params: args}); 35 | 36 | query.execute(url).then(response => { 37 | callback(response); 38 | }); 39 | } 40 | 41 | // Utility function to iterate over objects and display them to an output div 42 | function iterate(obj, stack) { 43 | for (var property in obj) { 44 | if (obj.hasOwnProperty(property)) { 45 | if (typeof obj[property] == "object") { 46 | iterate(obj[property], stack + '.' + property); 47 | } else { 48 | console.log(property + " " + obj[property]); 49 | outputHtml(stack + '.' + property + ': ' + obj[property]); 50 | } 51 | } 52 | } 53 | } 54 | 55 | // Utility function to print output to an HTML div tag 56 | function outputHtml(s) { 57 | document.getElementById("result").innerHTML += s + "
"; 58 | } 59 | 60 | function clearHtml() { 61 | document.getElementById("result").innerHTML = ""; 62 | } 63 | -------------------------------------------------------------------------------- /examples/browser/getblocksysfee/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getblocksysfee/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getblocksysfee 2 | description: Returns the system fees of the block, based on the specified index. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getblocksysfee/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getblocksysfee/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Index of the block to get 2 | const index = 0 // <- very first block ever on neo blockchain! 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | const client = Neon.default.create.rpcClient(nodeUrl); 17 | client.getBlockSysFee(index).then(response => { 18 | outputHtml('Block Data: ' + response); 19 | }); 20 | }); 21 | } 22 | 23 | // Utility function to iterate over objects and display them to an output div 24 | function iterate(obj, stack) { 25 | for (var property in obj) { 26 | if (obj.hasOwnProperty(property)) { 27 | if (typeof obj[property] == "object") { 28 | iterate(obj[property], stack + '.' + property); 29 | } else { 30 | console.log(property + " " + obj[property]); 31 | outputHtml(stack + '.' + property + ': ' + obj[property]); 32 | } 33 | } 34 | } 35 | } 36 | 37 | // Utility function to print output to an HTML div tag 38 | function outputHtml(s) { 39 | document.getElementById("result").innerHTML += s + "
"; 40 | } 41 | 42 | function clearHtml() { 43 | document.getElementById("result").innerHTML = ""; 44 | } 45 | -------------------------------------------------------------------------------- /examples/browser/getconnectioncount/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getconnectioncount/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getconnectioncount 2 | description: Gets the current number of connections for the node. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getconnectioncount/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getconnectioncount/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getConnectionCount().then(response => { 15 | outputHtml('Result: ' + response); 16 | iterate(response, ''); 17 | }); 18 | }); 19 | } 20 | 21 | // Utility function to iterate over objects and display them to an output div 22 | function iterate(obj, stack) { 23 | for (var property in obj) { 24 | if (obj.hasOwnProperty(property)) { 25 | if (typeof obj[property] == "object") { 26 | iterate(obj[property], stack + '.' + property); 27 | } else { 28 | console.log(property + " " + obj[property]); 29 | outputHtml(stack + '.' + property + ': ' + obj[property]); 30 | } 31 | } 32 | } 33 | } 34 | 35 | // Utility function to print output to an HTML div tag 36 | function outputHtml(s) { 37 | document.getElementById("result").innerHTML += s + "
"; 38 | } 39 | 40 | function clearHtml() { 41 | document.getElementById("result").innerHTML = ""; 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/getcontractstate/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getcontractstate/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getcontractstate 2 | description: Queries contract information, according to the contract script hash. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getcontractstate/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getcontractstate/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hash of the contract to get 2 | const hash = "b3a14d99a3fb6646c78bf2f4e2f25a7964d2956a" 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | const client = Neon.default.create.rpcClient(nodeUrl); 17 | client.getContractState(hash).then(response => { 18 | outputHtml('Result: '); 19 | iterate(response, ''); 20 | }); 21 | }); 22 | } 23 | 24 | // Utility function to iterate over objects and display them to an output div 25 | function iterate(obj, stack) { 26 | for (var property in obj) { 27 | if (obj.hasOwnProperty(property)) { 28 | if (typeof obj[property] == "object") { 29 | iterate(obj[property], stack + '.' + property); 30 | } else { 31 | console.log(property + " " + obj[property]); 32 | outputHtml(stack + '.' + property + ': ' + obj[property]); 33 | } 34 | } 35 | } 36 | } 37 | 38 | // Utility function to print output to an HTML div tag 39 | function outputHtml(s) { 40 | document.getElementById("result").innerHTML += s + "
"; 41 | } 42 | 43 | function clearHtml() { 44 | document.getElementById("result").innerHTML = ""; 45 | } 46 | -------------------------------------------------------------------------------- /examples/browser/getpeers/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getpeers/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getpeers 2 | description: Gets a list of nodes that are currently connected/disconnected by this node. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getpeers/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getpeers/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getPeers().then(response => { 15 | outputHtml('Result: '); 16 | iterate(response, ''); 17 | }); 18 | }); 19 | } 20 | 21 | // Utility function to iterate over objects and display them to an output div 22 | function iterate(obj, stack) { 23 | for (var property in obj) { 24 | if (obj.hasOwnProperty(property)) { 25 | if (typeof obj[property] == "object") { 26 | iterate(obj[property], stack + '.' + property); 27 | } else { 28 | console.log(property + " " + obj[property]); 29 | outputHtml(stack + '.' + property + ': ' + obj[property]); 30 | } 31 | } 32 | } 33 | } 34 | 35 | // Utility function to print output to an HTML div tag 36 | function outputHtml(s) { 37 | document.getElementById("result").innerHTML += s + "
"; 38 | } 39 | 40 | function clearHtml() { 41 | document.getElementById("result").innerHTML = ""; 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/getrawmempool/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getrawmempool/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getrawmempool 2 | description: Gets a list of unconfirmed transactions in memory. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getrawmempool/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getrawmempool/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getRawMemPool().then(response => { 15 | outputHtml('Result: '); 16 | iterate(response, ''); 17 | }); 18 | }); 19 | } 20 | 21 | // Utility function to iterate over objects and display them to an output div 22 | function iterate(obj, stack) { 23 | for (var property in obj) { 24 | if (obj.hasOwnProperty(property)) { 25 | if (typeof obj[property] == "object") { 26 | iterate(obj[property], stack + '.' + property); 27 | } else { 28 | console.log(property + " " + obj[property]); 29 | outputHtml(stack + '.' + property + ': ' + obj[property]); 30 | } 31 | } 32 | } 33 | } 34 | 35 | // Utility function to print output to an HTML div tag 36 | function outputHtml(s) { 37 | document.getElementById("result").innerHTML += s + "
"; 38 | } 39 | 40 | function clearHtml() { 41 | document.getElementById("result").innerHTML = ""; 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/getrawtransaction/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getrawtransaction/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getrawtransaction 2 | description: Get the account state for a wallet address 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getrawtransaction/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getrawtransaction/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hash of the transaction we want 2 | const hash = "0x2e5793b7c9766aba7c9f9812243827dbd722a6a47b7e002204f1407f844332a8" 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | const client = Neon.default.create.rpcClient(nodeUrl); 17 | client.getRawTransaction(hash).then(response => { 18 | outputHtml('TxID: ' + hash); 19 | outputHtml('Transaction:'); 20 | iterate(response, ''); 21 | }); 22 | }); 23 | } 24 | 25 | // Utility function to iterate over objects and display them to an output div 26 | function iterate(obj, stack) { 27 | for (var property in obj) { 28 | if (obj.hasOwnProperty(property)) { 29 | if (typeof obj[property] == "object") { 30 | iterate(obj[property], stack + '.' + property); 31 | } else { 32 | console.log(property + " " + obj[property]); 33 | outputHtml(stack + '.' + property + ': ' + obj[property]); 34 | } 35 | } 36 | } 37 | } 38 | 39 | // Utility function to print output to an HTML div tag 40 | function outputHtml(s) { 41 | document.getElementById("result").innerHTML += s + "
"; 42 | } 43 | 44 | function clearHtml() { 45 | document.getElementById("result").innerHTML = ""; 46 | } 47 | -------------------------------------------------------------------------------- /examples/browser/getstorage/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getstorage/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getstorage 2 | description: Returns the stored value, according to the contract script hash and the stored key. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getstorage/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getstorage/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Hash of the contract to get 2 | const hash = "b3a14d99a3fb6646c78bf2f4e2f25a7964d2956a" 3 | 4 | // Key of the storage to get for this contract 5 | const key = "74657374" 6 | 7 | // Get an instance of Neoscan so we can find a working node 8 | const provider = new Neon.api.neoscan.instance("TestNet"); 9 | 10 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 11 | Neon.settings.httpsOnly = true; 12 | 13 | function InvokeOperation() 14 | { 15 | clearHtml(); 16 | 17 | // Get an RPC Endpoint (Neo Node) 18 | provider.getRPCEndpoint().then(nodeUrl => { 19 | const client = Neon.default.create.rpcClient(nodeUrl); 20 | client.getStorage(hash, key).then(response => { 21 | outputHtml('Result: ' + Neon.u.hexstring2str(response)); 22 | }); 23 | }); 24 | } 25 | 26 | // Utility function to iterate over objects and display them to an output div 27 | function iterate(obj, stack) { 28 | for (var property in obj) { 29 | if (obj.hasOwnProperty(property)) { 30 | if (typeof obj[property] == "object") { 31 | iterate(obj[property], stack + '.' + property); 32 | } else { 33 | console.log(property + " " + obj[property]); 34 | outputHtml(stack + '.' + property + ': ' + obj[property]); 35 | } 36 | } 37 | } 38 | } 39 | 40 | // Utility function to print output to an HTML div tag 41 | function outputHtml(s) { 42 | document.getElementById("result").innerHTML += s + "
"; 43 | } 44 | 45 | function clearHtml() { 46 | document.getElementById("result").innerHTML = ""; 47 | } 48 | -------------------------------------------------------------------------------- /examples/browser/gettxout/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/gettxout/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: gettxout 2 | description: Returns the corresponding unspent transaction output information (returned change), based on the specified hash and index. If the transaction output is already spent, the result value will be null. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/gettxout/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/gettxout/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Transaction id to get 2 | const hash = "f4250dab094c38d8265acc15c366dc508d2e14bf5699e12d9df26577ed74d657"; 3 | 4 | // Index of the unspent transaction output to get for the given tx 5 | const index = 0; 6 | 7 | // Get an instance of Neoscan so we can find a working node 8 | const provider = new Neon.api.neoscan.instance("TestNet"); 9 | 10 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 11 | Neon.settings.httpsOnly = true; 12 | 13 | function InvokeOperation() 14 | { 15 | clearHtml(); 16 | 17 | // Get an RPC Endpoint (Neo Node) 18 | provider.getRPCEndpoint().then(nodeUrl => { 19 | const client = Neon.default.create.rpcClient(nodeUrl); 20 | client.getTxOut(hash, index).then(response => { 21 | outputHtml('Result: ' + response); 22 | }); 23 | }); 24 | } 25 | 26 | // Utility function to iterate over objects and display them to an output div 27 | function iterate(obj, stack) { 28 | for (var property in obj) { 29 | if (obj.hasOwnProperty(property)) { 30 | if (typeof obj[property] == "object") { 31 | iterate(obj[property], stack + '.' + property); 32 | } else { 33 | console.log(property + " " + obj[property]); 34 | outputHtml(stack + '.' + property + ': ' + obj[property]); 35 | } 36 | } 37 | } 38 | } 39 | 40 | // Utility function to print output to an HTML div tag 41 | function outputHtml(s) { 42 | document.getElementById("result").innerHTML += s + "
"; 43 | } 44 | 45 | function clearHtml() { 46 | document.getElementById("result").innerHTML = ""; 47 | } 48 | -------------------------------------------------------------------------------- /examples/browser/getvalidators/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getvalidators/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getvalidators 2 | description: Returns the current NEO consensus nodes information and voting status. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getvalidators/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getvalidators/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getValidators().then(response => { 15 | outputHtml('Result: '); 16 | iterate(response, '') 17 | }); 18 | }); 19 | } 20 | 21 | // Utility function to iterate over objects and display them to an output div 22 | function iterate(obj, stack) { 23 | for (var property in obj) { 24 | if (obj.hasOwnProperty(property)) { 25 | if (typeof obj[property] == "object") { 26 | iterate(obj[property], stack + '.' + property); 27 | } else { 28 | console.log(property + " " + obj[property]); 29 | outputHtml(stack + '.' + property + ': ' + obj[property]); 30 | } 31 | } 32 | } 33 | } 34 | 35 | // Utility function to print output to an HTML div tag 36 | function outputHtml(s) { 37 | document.getElementById("result").innerHTML += s + "
"; 38 | } 39 | 40 | function clearHtml() { 41 | document.getElementById("result").innerHTML = ""; 42 | } 43 | -------------------------------------------------------------------------------- /examples/browser/getversion/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/getversion/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: getversion 2 | description: Gets version information of this node. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/getversion/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/getversion/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Get an instance of Neoscan so we can find a working node 2 | const provider = new Neon.api.neoscan.instance("TestNet"); 3 | 4 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 5 | Neon.settings.httpsOnly = true; 6 | 7 | function InvokeOperation() 8 | { 9 | clearHtml(); 10 | 11 | // Get an RPC Endpoint (Neo Node) 12 | provider.getRPCEndpoint().then(nodeUrl => { 13 | const client = Neon.default.create.rpcClient(nodeUrl); 14 | client.getVersion().then(response => { 15 | outputHtml('Result: ' + response); 16 | }); 17 | }); 18 | } 19 | 20 | // Utility function to iterate over objects and display them to an output div 21 | function iterate(obj, stack) { 22 | for (var property in obj) { 23 | if (obj.hasOwnProperty(property)) { 24 | if (typeof obj[property] == "object") { 25 | iterate(obj[property], stack + '.' + property); 26 | } else { 27 | console.log(property + " " + obj[property]); 28 | outputHtml(stack + '.' + property + ': ' + obj[property]); 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Utility function to print output to an HTML div tag 35 | function outputHtml(s) { 36 | document.getElementById("result").innerHTML += s + "
"; 37 | } 38 | 39 | function clearHtml() { 40 | document.getElementById("result").innerHTML = ""; 41 | } 42 | -------------------------------------------------------------------------------- /examples/browser/index/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | background: rgb(66, 184, 221); /* this is a light blue */ 15 | } 16 | #buttons { 17 | float: left; 18 | 19 | } 20 | 21 | #result { 22 | float: left; 23 | white-space: pre-wrap; /* CSS3 */ 24 | white-space: -moz-pre-wrap; /* Firefox */ 25 | white-space: -pre-wrap; /* Opera <7 */ 26 | white-space: -o-pre-wrap; /* Opera 7 */ 27 | word-wrap: break-word; /* IE */ 28 | } 29 | .child_div_1 { 30 | float: left; 31 | margin-right: 5px; 32 | } 33 | -------------------------------------------------------------------------------- /examples/browser/index/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: /Neon:v2.9.0/ API Browser Example Index 2 | description: Press each button to run that example 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/index/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 |

3 |

4 |
5 | 8 |

9 |

10 | 13 |

14 |

15 | 18 |

19 |

20 |
21 |
22 | Press a button to run an example. 23 |
24 | -------------------------------------------------------------------------------- /examples/browser/invokefunction/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/invokefunction/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: invokefunction 2 | description: Invokes a smart contract at specified script hash, passing in an operation and its params. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/invokefunction/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/invokefunction/demo/demo.js: -------------------------------------------------------------------------------- 1 | 2 | const contractHash = "5b7074e873973a6ed3708862f219a6fbf4d1c411"; 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | invokeFunction(response => { 17 | outputHtml('Results: '); 18 | iterate(response, ''); 19 | }, nodeUrl); 20 | }); 21 | } 22 | 23 | // We're wrapping the neon-js call to make our code a little clearer. 24 | function invokeFunction(callback, url) { 25 | Neon.rpc.Query.invokeFunction(contractHash, "name") 26 | .execute(url) 27 | .then(res => { 28 | callback(res); // You should get a result with state: "HALT, BREAK" 29 | }) 30 | } 31 | 32 | // Utility function to iterate over objects and display them to an output div 33 | function iterate(obj, stack) { 34 | for (var property in obj) { 35 | if (obj.hasOwnProperty(property)) { 36 | if (typeof obj[property] == "object") { 37 | iterate(obj[property], stack + '.' + property); 38 | } else { 39 | console.log(property + " " + obj[property]); 40 | outputHtml(stack + '.' + property + ': ' + obj[property]); 41 | } 42 | } 43 | } 44 | } 45 | 46 | // Utility function to print output to an HTML div tag 47 | function outputHtml(s) { 48 | document.getElementById("result").innerHTML += s + "
"; 49 | } 50 | 51 | function clearHtml() { 52 | document.getElementById("result").innerHTML = ""; 53 | } 54 | -------------------------------------------------------------------------------- /examples/browser/invokescript/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/invokescript/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: invokescript 2 | description: Runs a script through the virtual machine and returns the results. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/invokescript/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/invokescript/demo/demo.js: -------------------------------------------------------------------------------- 1 | const props = { 2 | // Scripthash for the contract 3 | scriptHash: '5b7074e873973a6ed3708862f219a6fbf4d1c411', 4 | // name of operation to perform. 5 | operation: 'balanceOf', 6 | // any optional arguments to pass in. If null, use empty array. 7 | args: [Neon.u.reverseHex('cef0c0fdcfe7838eff6ff104f9cdec2922297537')] 8 | } 9 | 10 | const script = Neon.sc.createScript(props); 11 | 12 | // Get an instance of Neoscan so we can find a working node 13 | const provider = new Neon.api.neoscan.instance("TestNet"); 14 | 15 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 16 | Neon.settings.httpsOnly = true; 17 | 18 | function InvokeOperation() 19 | { 20 | clearHtml(); 21 | 22 | // Get an RPC Endpoint (Neo Node) 23 | provider.getRPCEndpoint().then(nodeUrl => { 24 | invokeScipt(response => { 25 | outputHtml('Results: '); 26 | iterate(response, ''); 27 | }, nodeUrl); 28 | }); 29 | } 30 | 31 | // We're wrapping the neon-js call to make our code a little clearer. 32 | function invokeScipt(callback, url) { 33 | Neon.rpc.Query.invokeScript(script) 34 | .execute(url) 35 | .then(res => { 36 | callback(res); // You should get a result with state: "HALT, BREAK" 37 | }) 38 | } 39 | 40 | // Utility function to iterate over objects and display them to an output div 41 | function iterate(obj, stack) { 42 | for (var property in obj) { 43 | if (obj.hasOwnProperty(property)) { 44 | if (typeof obj[property] == "object") { 45 | iterate(obj[property], stack + '.' + property); 46 | } else { 47 | console.log(property + " " + obj[property]); 48 | outputHtml(stack + '.' + property + ': ' + obj[property]); 49 | } 50 | } 51 | } 52 | } 53 | 54 | // Utility function to print output to an HTML div tag 55 | function outputHtml(s) { 56 | document.getElementById("result").innerHTML += s + "
"; 57 | } 58 | 59 | function clearHtml() { 60 | document.getElementById("result").innerHTML = ""; 61 | } 62 | -------------------------------------------------------------------------------- /examples/browser/subscribenotifications/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/subscribenotifications/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: subscribeNotifications 2 | description: Subscribe to receive event notifications from a contract. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/subscribenotifications/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 |

9 |

10 |
11 | Press button above to run the example. 12 |
13 |

14 |

15 | -------------------------------------------------------------------------------- /examples/browser/subscribenotifications/demo/demo.js: -------------------------------------------------------------------------------- 1 | // ScriptHash of the contract to subscribe to 2 | const contractHash = "0x314b5aac1cdd01d10661b00886197f2194c3c89b"; 3 | // Subscriptions to null are equivalent to subscribing to all the contracts 4 | const allContractHashes = null; 5 | 6 | // Get an instance of the Notifications server 7 | const provider = new Neon.api.notifications.instance("wss://YOUR_PUBSUB_SERVER.com/event"); 8 | 9 | let subscription; 10 | 11 | function InvokeSubscribeOperation() 12 | { 13 | clearHtml(); 14 | 15 | // Create a subscription 16 | subscription = provider.subscribe(allContractHashes, (event) => { 17 | outputHtml('Event data: '); 18 | outputHtml(JSON.stringify(event, null, " ")); 19 | }); 20 | } 21 | 22 | function InvokeUnsubscribeOperation() 23 | { 24 | if(subscription !== undefined){ 25 | // Unsubscribe the previous handler 26 | subscription.unsubscribe(); 27 | } 28 | } 29 | 30 | 31 | // Utility function to print output to an HTML div tag 32 | function outputHtml(s) { 33 | document.getElementById("result").innerHTML += s + "
"; 34 | } 35 | 36 | function clearHtml() { 37 | document.getElementById("result").innerHTML = ""; 38 | } 39 | -------------------------------------------------------------------------------- /examples/browser/validateaddress/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #24292e; 3 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif; 4 | font-size: 16px; 5 | line-height: 1.5; 6 | -ms-text-size-adjust: 100%; 7 | -webkit-text-size-adjust: 100%; 8 | word-wrap: break-word; 9 | } 10 | 11 | button { 12 | font-size: 16px; 13 | color: white; 14 | border-radius: 4px; 15 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 16 | background: rgb(66, 184, 221); /* this is a light blue */ 17 | } 18 | -------------------------------------------------------------------------------- /examples/browser/validateaddress/demo/demo.details: -------------------------------------------------------------------------------- 1 | name: validateaddress 2 | description: Verify that the address is a correct NEO address. 3 | resources: 4 | - https://cdn.jsdelivr.net/npm/@cityofzion/neon-js/dist/browser.min.js 5 | -------------------------------------------------------------------------------- /examples/browser/validateaddress/demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |

6 |

7 |
8 | Press button above to run the example. 9 |
10 |

11 |

12 | -------------------------------------------------------------------------------- /examples/browser/validateaddress/demo/demo.js: -------------------------------------------------------------------------------- 1 | // Wallet address to query 2 | const accountAddress = "APJnYRic9fYo1bLAdrqDbwrsnqoUD92dWo"; 3 | 4 | // Get an instance of Neoscan so we can find a working node 5 | const provider = new Neon.api.neoscan.instance("TestNet"); 6 | 7 | // Ensure neon-js only talks to RPC endpoint (Neo node) using HTTPS 8 | Neon.settings.httpsOnly = true; 9 | 10 | function InvokeOperation() 11 | { 12 | clearHtml(); 13 | 14 | // Get an RPC Endpoint (Neo Node) 15 | provider.getRPCEndpoint().then(nodeUrl => { 16 | const client = Neon.default.create.rpcClient(nodeUrl); 17 | client.validateAddress(accountAddress).then(response => { 18 | outputHtml('Result: ' + response); 19 | }); 20 | }); 21 | } 22 | 23 | // Utility function to iterate over objects and display them to an output div 24 | function iterate(obj, stack) { 25 | for (var property in obj) { 26 | if (obj.hasOwnProperty(property)) { 27 | if (typeof obj[property] == "object") { 28 | iterate(obj[property], stack + '.' + property); 29 | } else { 30 | console.log(property + " " + obj[property]); 31 | outputHtml(stack + '.' + property + ': ' + obj[property]); 32 | } 33 | } 34 | } 35 | } 36 | 37 | // Utility function to print output to an HTML div tag 38 | function outputHtml(s) { 39 | document.getElementById("result").innerHTML += s + "
"; 40 | } 41 | 42 | function clearHtml() { 43 | document.getElementById("result").innerHTML = ""; 44 | } 45 | -------------------------------------------------------------------------------- /examples/eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "../eslintrc.js" 4 | ] 5 | } -------------------------------------------------------------------------------- /examples/generate.js: -------------------------------------------------------------------------------- 1 | import {execSync} from "child_process"; 2 | import {readdirSync, mkdirSync} from "fs"; 3 | import {join as joinPath, dirname} from "path"; 4 | import { fileURLToPath } from 'url'; 5 | 6 | const __filename = fileURLToPath(import.meta.url); 7 | const __dirname = dirname(__filename); 8 | 9 | 10 | // Output folder relative to this script's directory 11 | const OUTPUT_DIR = "../docs/guides" 12 | 13 | // The `src` directory will contain all the guides 14 | const SRC_DIR = "src" 15 | 16 | function absolutePath(input) { 17 | return joinPath(__dirname, input) 18 | } 19 | 20 | function absoluteOutputDir(dir) { 21 | return joinPath(__dirname, OUTPUT_DIR, dir); 22 | } 23 | 24 | // returns a list of files in the folder relative to the root dir 25 | function listAllFiles(rootDir) { 26 | const items = readdirSync(rootDir, { withFileTypes: true }) 27 | return items.map(i => i.isDirectory() ? listAllFiles(joinPath(rootDir, i.name)).map(fp => joinPath(i.name, fp)) : [i.name]).reduce((a,b) => a.concat(b), []) 28 | } 29 | 30 | function transformInputFile(inputFile) { 31 | return { 32 | inputFile: joinPath(SRC_DIR, inputFile), 33 | outputFile: joinPath(OUTPUT_DIR, (inputFile.substring(0, inputFile.lastIndexOf(".")) + ".md")) 34 | } 35 | } 36 | 37 | const files = listAllFiles(SRC_DIR).map(transformInputFile) 38 | console.log(files) 39 | files.forEach((f) => { 40 | execSync(`ljs2 ${absolutePath(f.inputFile)} -o ${absolutePath(f.outputFile)}`) 41 | console.log(`${f.inputFile} -> ${f.outputFile}`) 42 | }); 43 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "1.0.0", 4 | "description": "Runnable examples and guides for neon-js", 5 | "main": "generate.ts", 6 | "license": "MIT", 7 | "private": true, 8 | "type": "module", 9 | "engines": { 10 | "node": ">=14.0.0" 11 | }, 12 | "scripts": { 13 | "generate": "node generate.js", 14 | "lint": "eslint basic/* advanced/* --cache" 15 | }, 16 | "dependencies": { 17 | "@cityofzion/neon-core": "5.0.0-next.10", 18 | "@cityofzion/neon-js": "5.0.0-next.10" 19 | }, 20 | "devDependencies": { 21 | "eslint": "7.26.0", 22 | "eslint-config-prettier": "8.3.0", 23 | "eslint-plugin-prettier": "3.4.0", 24 | "prettier": "2.3.0", 25 | "ljs2": "^2.0.3" 26 | } 27 | } -------------------------------------------------------------------------------- /helpers/findTransactions.js: -------------------------------------------------------------------------------- 1 | const rpc = require("@cityofzion/neon-core").rpc; 2 | 3 | const START_BLOCK = 500; 4 | const STOPPING_POINT = 10; 5 | 6 | const client = new rpc.RPCClient("http://testnet3-seed.epic-chain.org:20111"); 7 | 8 | let currentBlock = START_BLOCK; 9 | let found = 0; 10 | (async () => { 11 | while (found < STOPPING_POINT) { 12 | const block = await client.getBlock(currentBlock, true); 13 | if (block.tx.length > 0) { 14 | found++; 15 | block.tx.forEach((tx) => console.log(tx.hash)); 16 | } 17 | currentBlock++; 18 | } 19 | })(); 20 | 21 | // Some TestNet examples 22 | //0x1e16f97be7fe8e9e2136dfdea37207fc27d2bc42661dd1feb6f37381233c44ad 23 | //0x4ab526c3384c98c713cd6f6648ec484a2ce7c1a4855561fe15bad91f1bda63c0 24 | //0xd8454136d8f911ee00028235579f635ddc684edadc92c3844aa1c03abab2c877 25 | //0x50dafac34a0ec0702883a64cb9dfc6559ac87a392a3b7d4c5c25bdbc3fc6880c 26 | -------------------------------------------------------------------------------- /helpers/generateContractHash.js: -------------------------------------------------------------------------------- 1 | const sc = require("@cityofzion/neon-core").sc; 2 | 3 | const nativeContractNames = [ 4 | "EpicChain", 5 | "EpicPulse", 6 | "CovenantChain", 7 | "ManagementContract", 8 | "OracleNexus", 9 | "DesignationContract", 10 | ]; 11 | 12 | console.log( 13 | nativeContractNames 14 | .map((name) => `${name} = "${sc.getNativeContractHash(name)}"`) 15 | .join(",\n") 16 | ); 17 | -------------------------------------------------------------------------------- /helpers/getBaseBranch.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios").default; 2 | 3 | const pullRequestUrl = process.argv[2]; 4 | const pullRequestNumber = /https:\/\/github.com\/.*\/.*\/pull\/(\d+)/.exec( 5 | pullRequestUrl 6 | )[1]; 7 | axios 8 | .get( 9 | `https://api.github.com/repos/epicchainlabs/epicvault-js/pulls/${pullRequestNumber}` 10 | ) 11 | .then((res) => { 12 | console.log(res.data.base.ref); 13 | }); 14 | -------------------------------------------------------------------------------- /helpers/urls.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from "@epicchain/epicvault-core"; 2 | 3 | const TESTNET_URLS = [ 4 | "http://testnet1-seed.epic-chain.org:20111", 5 | "http://testnet2-seed.epic-chain.org:20111", 6 | "http://testnet3-seed.epic-chain.org:20111", 7 | "http://testnet4-seed.epic-chain.org:20111", 8 | "http://testnet5-seed.epic-chain.org:20111", 9 | ]; 10 | 11 | const MAINNET_URLS = [ 12 | "http://mainnet1-seed.epic-chain.org:10111", 13 | "http://mainnet2-seed.epic-chain.org:10111", 14 | "http://mainnet3-seed.epic-chain.org:10111", 15 | "http://mainnet4-seed.epic-chain.org:10111", 16 | "http://mainnet5-seed.epic-chain.org:10111", 17 | ]; 18 | 19 | export function getUrls(net: string): string[] { 20 | if (net === "TestNet") { 21 | return TESTNET_URLS; 22 | } else if (net === "MainNet") { 23 | return MAINNET_URLS; 24 | } else { 25 | throw new Error("Expected MainNet or TestNet"); 26 | } 27 | } 28 | 29 | function cutArray(arr: T[]): T[] { 30 | const randomStartIndex = Math.floor(Math.random() * arr.length); 31 | return arr.slice(randomStartIndex).concat(arr.slice(0, randomStartIndex)); 32 | } 33 | export async function getUrl(net: string): Promise { 34 | const orderedUrls = getUrls(net); 35 | 36 | const slicedUrls = cutArray(orderedUrls); 37 | let previousBlockCount = 0; 38 | for (let i = 0; i < slicedUrls.length; i++) { 39 | try { 40 | const dispatcher = new rpc.RpcDispatcher(slicedUrls[i]); 41 | const currentBlockCount = await dispatcher.execute( 42 | rpc.Query.getBlockCount(), 43 | { 44 | timeout: 2000, 45 | } 46 | ); 47 | if (currentBlockCount - previousBlockCount <= 5) { 48 | return slicedUrls[i]; 49 | } 50 | previousBlockCount = Math.max(currentBlockCount, previousBlockCount); 51 | } catch (e) { 52 | continue; 53 | } 54 | } 55 | throw new Error("Explored all URLs, but no RPC available—still searching for a connection!"); 56 | } 57 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testRunner: "jest-circus/runner", 3 | testEnvironment: "node", 4 | globals: { 5 | __TARGETNET__: "LocalNet", 6 | }, 7 | watchPlugins: [ 8 | "jest-watch-typeahead/filename", 9 | "jest-watch-typeahead/testname", 10 | ], 11 | transform: { 12 | "^.+\\.tsx?$": [ 13 | "ts-jest", 14 | { 15 | tsconfig: "/tsconfig-test.json", 16 | diagnostics: false, 17 | }, 18 | ], 19 | }, 20 | coveragePathIgnorePatterns: [ 21 | "/packages/.*/lib/", 22 | "/packages/.*/dist/", 23 | ], 24 | testRegex: 25 | "((/packages/.*/)?__(tests|integration)__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 26 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 27 | }; 28 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["packages/*"], 3 | "version": "5.6.0", 4 | "npmClient": "npm", 5 | "useWorkspaces": true, 6 | "workspaces": ["packages/*"], 7 | "command": { 8 | "version": { 9 | "allowBranch": ["master", "next", "archive/*"] 10 | }, 11 | "publish": { 12 | "allowBranch": ["master", "next", "archive/*"] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/epicvault-api/__integration__/api/getFeeInformation.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from "@epicchain/epicvault-core"; 2 | import * as TestHelpers from "../../../../testHelpers"; 3 | 4 | import { getFeeInformation } from "../../src/api/getFeeInformation"; 5 | 6 | let client: rpc.EpicChainServerRpcClient; 7 | beforeAll(async () => { 8 | const url = await TestHelpers.getIntegrationEnvUrl(); 9 | client = new rpc.EpicChainServerRpcClient(url); 10 | }, 20000); 11 | 12 | describe("getFeeInformation", () => { 13 | test("success", async () => { 14 | const result = await getFeeInformation(client); 15 | 16 | expect(Object.keys(result)).toEqual( 17 | expect.arrayContaining(["feePerByte", "executionFeeFactor"]) 18 | ); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/epicvault-api/__integration__/api/getTokenBalances.ts: -------------------------------------------------------------------------------- 1 | import { rpc, CONST, wallet } from "@epicchain/epicvault-core"; 2 | import * as TestHelpers from "../../../../testHelpers"; 3 | import testWalletJson from "../../../neon-core/__tests__/testWallet.json"; 4 | 5 | import { getTokenBalances } from "../../src/api/getTokenBalances"; 6 | 7 | let client: rpc.EpicChainServerRpcClient; 8 | const address = testWalletJson.accounts[0].address; 9 | 10 | beforeAll(async () => { 11 | const url = await TestHelpers.getIntegrationEnvUrl(); 12 | client = new rpc.EpicChainServerRpcClient(url); 13 | }, 20000); 14 | 15 | describe("getTokenBalances", () => { 16 | test("EpicChain & EpicPulse (some balance)", async () => { 17 | const neoScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicChain; 18 | const gasScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicPulse; 19 | const result = await getTokenBalances( 20 | address, 21 | [neoScriptHash, gasScriptHash], 22 | client 23 | ); 24 | expect(result).toStrictEqual([expect.any(String), expect.any(String)]); 25 | expect(parseInt(result[0])).toBeGreaterThan(0); 26 | expect(parseInt(result[1])).toBeGreaterThan(0); 27 | }); 28 | 29 | test("EpicChain & EpicPulse (empty)", async () => { 30 | const neoScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicChain; 31 | const gasScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicPulse; 32 | const result = await getTokenBalances( 33 | new wallet.Account().address, 34 | [neoScriptHash, gasScriptHash], 35 | client 36 | ); 37 | expect(result).toStrictEqual(["0", "0.00000000"]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/epicvault-api/__integration__/api/getTokenInfos.ts: -------------------------------------------------------------------------------- 1 | import { rpc, CONST } from "@epicchain/epicvault-core"; 2 | import * as TestHelpers from "../../../../testHelpers"; 3 | 4 | import { getTokenInfos, TokenInfo } from "../../src/api/getTokenInfos"; 5 | 6 | let client: rpc.EpicChainServerRpcClient; 7 | 8 | beforeAll(async () => { 9 | const url = await TestHelpers.getIntegrationEnvUrl(); 10 | client = new rpc.EpicChainServerRpcClient(url); 11 | }, 20000); 12 | 13 | describe("getTokenInfos", () => { 14 | test("EpicChain & EpicPulse", async () => { 15 | const neoScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicChain; 16 | const gasScriptHash = CONST.NATIVE_CONTRACT_HASH.EpicPulse; 17 | const result = await getTokenInfos([neoScriptHash, gasScriptHash], client); 18 | expect(result).toStrictEqual([ 19 | { 20 | symbol: "NEO", 21 | decimals: 0, 22 | totalSupply: "100000000", 23 | } as TokenInfo, 24 | { 25 | symbol: "GAS", 26 | decimals: 8, 27 | totalSupply: expect.any(String), 28 | } as TokenInfo, 29 | ]); 30 | 31 | expect(parseInt(result[1].totalSupply)).toBeGreaterThan(0); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/epicvault-api/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "../../api-extractor-base.json" 4 | } -------------------------------------------------------------------------------- /packages/epicvault-api/jest.config.js: -------------------------------------------------------------------------------- 1 | const config = require("../../jest.config"); 2 | config.globals["ts-jest"]["tsconfig"] = "../../tsconfig-test.json"; 3 | module.exports = config; 4 | -------------------------------------------------------------------------------- /packages/epicvault-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epicchain/epicvault-api", 3 | "description": "The EpicVault-API Module is an advanced API layer built on top of the EpicVault-JS Core, providing an enhanced interface for seamless interaction with the EpicVault platform.", 4 | "version": "1.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/epicchainlabs/epicvault-js.git" 8 | }, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "keywords": [ 13 | "epicchain", 14 | "xmoohad", 15 | "javascript", 16 | "libraries" 17 | ], 18 | "author": "xmoohad (https://github.com/xmoohad)", 19 | "license": "MIT", 20 | "main": "dist/index.js", 21 | "module": "lib/index.js", 22 | "types": "lib/index.d.ts", 23 | "scripts": { 24 | "ae": "api-extractor run --local", 25 | "build": "tsc -b", 26 | "dist": "tsc -m commonjs --outDir dist", 27 | "dist:prod": "tsc -m commonjs --outDir dist", 28 | "clean": "rimraf ./lib ./dist ./temp tsconfig.tsbuildinfo", 29 | "prepublishOnly": "npm run clean && npm run build && npm run dist:prod", 30 | "lint": "eslint src/**/*.ts __tests__/**/*.ts __integration__/**/*.ts", 31 | "pretty": "prettier --write --loglevel=warn \"./{src,__{tests,integration}__}/**/*.ts\"", 32 | "start": "jest --watch", 33 | "test": "jest", 34 | "test:integration": "jest /packages/.*/__integration__/.*", 35 | "test:unit": "jest /packages/.*/__tests__/.*" 36 | }, 37 | "peerDependencies": { 38 | "@epicchain/epicvault-core": "^1.0.0" 39 | }, 40 | "files": [ 41 | "dist/", 42 | "lib/" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/api/getCandidates.ts: -------------------------------------------------------------------------------- 1 | import { rpc, sc, u } from "@epicchain/epicvault-core"; 2 | 3 | export interface Candidate { 4 | publicKey: string; 5 | votes: number; 6 | } 7 | 8 | type getCandidatesStack = [ 9 | { 10 | type: "Array"; 11 | value: { 12 | type: "Struct"; 13 | value: [ 14 | { type: "ByteArray"; value: string }, 15 | { type: "Integer"; value: string } 16 | ]; 17 | }[]; 18 | } 19 | ]; 20 | export async function getCandidates( 21 | client: rpc.EpicChainServerRpcClient 22 | ): Promise { 23 | const script = new sc.ScriptBuilder() 24 | .emitContractCall(sc.EpicChainContract.INSTANCE.getCandidates()) 25 | .build(); 26 | 27 | const res = await client.invokeScript(u.HexString.fromHex(script)); 28 | const arrayOfCandidates = res.stack as getCandidatesStack; 29 | return arrayOfCandidates[0].value.map((i) => { 30 | return { 31 | publicKey: u.HexString.fromBase64(i.value[0].value).toBigEndian(), 32 | votes: parseInt(i.value[1].value), 33 | }; 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/api/getFeeInformation.ts: -------------------------------------------------------------------------------- 1 | import { sc, rpc, u } from "@epicchain/epicvault-core"; 2 | 3 | /** 4 | * Helper method for retrieving fee-related information from CovenantChain. 5 | */ 6 | export async function getFeeInformation( 7 | client: rpc.EpicChainServerRpcClient 8 | ): Promise<{ feePerByte: u.BigInteger; executionFeeFactor: u.BigInteger }> { 9 | const policyScript = new sc.ScriptBuilder() 10 | .emitContractCall(sc.CovenantChain.INSTANCE.getFeePerByte()) 11 | .emitContractCall(sc.CovenantChain.INSTANCE.getExecFeeFactor()) 12 | .build(); 13 | 14 | const res = await client.invokeScript(u.HexString.fromHex(policyScript)); 15 | const [feePerByte, executionFeeFactor] = res.stack.map((s) => 16 | u.BigInteger.fromNumber(s.value as string) 17 | ); 18 | 19 | return { feePerByte, executionFeeFactor }; 20 | } 21 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/api/getTokenBalances.ts: -------------------------------------------------------------------------------- 1 | import { rpc, sc, u } from "@epicchain/epicvault-core"; 2 | 3 | const CHUNK_SIZE = 2; 4 | 5 | export async function getTokenBalances( 6 | address: string, 7 | contracts: (string | sc.Xep17Contract)[], 8 | client: rpc.EpicChainServerRpcClient 9 | ): Promise { 10 | const script = contracts 11 | .map((scriptHash) => 12 | scriptHash instanceof sc.Xep17Contract 13 | ? scriptHash 14 | : new sc.Xep17Contract(scriptHash) 15 | ) 16 | .map((contract) => [contract.decimals(), contract.balanceOf(address)]) 17 | .reduce((sb, contractCalls) => { 18 | contractCalls.forEach((cc) => sb.emitContractCall(cc)); 19 | return sb; 20 | }, new sc.ScriptBuilder()) 21 | .build(); 22 | 23 | const response = await client.invokeScript(u.HexString.fromHex(script)); 24 | if (response.state === "FAULT") { 25 | throw new Error( 26 | response.exception 27 | ? `Invoke exception: ${response.exception}}` 28 | : "No exception message returned." 29 | ); 30 | } 31 | 32 | const expectedStackLength = contracts.length * CHUNK_SIZE; 33 | if (response.stack.length !== expectedStackLength) { 34 | throw new Error( 35 | `Received unexpected results. Expected ${expectedStackLength} but got ${response.stack.length} instead.` 36 | ); 37 | } 38 | 39 | const results = []; 40 | for (let i = 0; i < response.stack.length; i += CHUNK_SIZE) { 41 | results.push(response.stack.slice(i, i + 3)); 42 | } 43 | 44 | return results.map((result) => { 45 | const decimals = parseInt(result[0].value as string); 46 | return u.BigInteger.fromNumber(result[1].value as string).toDecimal( 47 | decimals 48 | ); 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/api/getTokenInfos.ts: -------------------------------------------------------------------------------- 1 | import { rpc, sc, u } from "@epicchain/epicvault-core"; 2 | 3 | export interface TokenInfo { 4 | symbol: string; 5 | decimals: number; 6 | totalSupply: string; 7 | } 8 | 9 | const CHUNK_SIZE = 3; 10 | 11 | export async function getTokenInfos( 12 | contracts: (string | sc.Xep17Contract)[], 13 | client: rpc.EpicChainServerRpcClient 14 | ): Promise { 15 | const script = contracts 16 | .map((scriptHash) => 17 | scriptHash instanceof sc.Xep17Contract 18 | ? scriptHash 19 | : new sc.Xep17Contract(scriptHash) 20 | ) 21 | .map((contract) => [ 22 | contract.symbol(), 23 | contract.decimals(), 24 | contract.totalSupply(), 25 | ]) 26 | .reduce((sb, contractCalls) => { 27 | contractCalls.forEach((cc) => sb.emitContractCall(cc)); 28 | return sb; 29 | }, new sc.ScriptBuilder()) 30 | .build(); 31 | 32 | const response = await client.invokeScript(u.HexString.fromHex(script)); 33 | if (response.state === "FAULT") { 34 | throw new Error( 35 | response.exception 36 | ? `Invoke exception: ${response.exception}}` 37 | : "No exception message returned." 38 | ); 39 | } 40 | 41 | const expectedStackLength = contracts.length * CHUNK_SIZE; 42 | if (response.stack.length !== expectedStackLength) { 43 | throw new Error( 44 | `Received unexpected results. Expected ${expectedStackLength} but got ${response.stack.length} instead.` 45 | ); 46 | } 47 | 48 | const results = []; 49 | for (let i = 0; i < response.stack.length; i += CHUNK_SIZE) { 50 | results.push(response.stack.slice(i, i + CHUNK_SIZE)); 51 | } 52 | 53 | return results.map((result) => { 54 | const decimals = parseInt(result[1].value as string); 55 | return { 56 | symbol: u.HexString.fromBase64(result[0].value as string).toAscii(), 57 | decimals, 58 | totalSupply: u.BigInteger.fromNumber(result[2].value as string).toDecimal( 59 | decimals 60 | ), 61 | }; 62 | }); 63 | } 64 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./calculateNetworkFee"; 2 | export * from "./getFeeInformation"; 3 | export * from "./getTokenBalances"; 4 | export * from "./getTokenInfos"; 5 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./transaction"; 2 | export * from "./api"; 3 | export * from "./NetworkFacade"; 4 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/transaction/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./TransactionBuilder"; 2 | export * from "./validator"; 3 | export * from "./signer"; 4 | export * from "./signing"; 5 | -------------------------------------------------------------------------------- /packages/epicvault-api/src/transaction/signing.ts: -------------------------------------------------------------------------------- 1 | import { wallet, tx } from "@epicchain/epicvault-core"; 2 | 3 | export type SigningFunction = ( 4 | tx: tx.Transaction, 5 | details: { 6 | network: number; 7 | witnessIndex: number; 8 | } 9 | ) => Promise; 10 | 11 | export function signWithAccount(acct: wallet.Account): SigningFunction { 12 | return async (tx, details) => { 13 | const txData = tx.getMessageForSigning(details.network); 14 | const scriptHash = wallet.getScriptHashFromVerificationScript( 15 | tx.witnesses[details.witnessIndex].verificationScript.toString() 16 | ); 17 | if (scriptHash !== acct.scriptHash) { 18 | throw new Error( 19 | `Requested signature from ${wallet.getAddressFromScriptHash( 20 | scriptHash, 21 | acct.addressVersion 22 | )} but only have key of ${acct.address}.` 23 | ); 24 | } 25 | return wallet.sign(txData, acct.privateKey); 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /packages/epicvault-api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib" 6 | }, 7 | "references": [{ "path": "../epicvault-core" }], 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/epicvault-core/README.md: -------------------------------------------------------------------------------- 1 | v 2 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/internal.ts: -------------------------------------------------------------------------------- 1 | import { parseEnum } from "../src/internal"; 2 | 3 | enum TestEnum { 4 | Any = 0, 5 | First = 1, 6 | Second = 2, 7 | } 8 | describe("parseEnum", () => { 9 | test("integer", () => { 10 | const result = parseEnum(0, TestEnum); 11 | 12 | expect(result.toString()).toBe("0"); 13 | }); 14 | 15 | test("string", () => { 16 | const result = parseEnum("First", TestEnum); 17 | 18 | expect(result.toString()).toBe("1"); 19 | }); 20 | 21 | test("enum", () => { 22 | const result = parseEnum(TestEnum.Second, TestEnum); 23 | 24 | expect(result.toString()).toBe("2"); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/rpc/clients/RpcDispatcher.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from "../../../src"; 2 | 3 | test("throws on url without http", () => { 4 | expect(() => new rpc.RpcDispatcher("localhost:20332")).toThrowError( 5 | "starts with http" 6 | ); 7 | }); 8 | 9 | test("throws on url with typoed http", () => { 10 | expect(() => new rpc.RpcDispatcher("http:/localhost:20332")).toThrowError( 11 | "starts with http" 12 | ); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/contracts/CovenantChain.ts: -------------------------------------------------------------------------------- 1 | import { CovenantChain, CallFlags } from "../../../src/sc"; 2 | 3 | const contract = CovenantChain.INSTANCE; 4 | const scriptHash = "add3e350a8789c507686ea677da85d89272f064b"; 5 | 6 | test("scriptHash", () => { 7 | expect(contract.scriptHash).toEqual( 8 | "add3e350a8789c507686ea677da85d89272f064b" 9 | ); 10 | }); 11 | 12 | describe("default methods", () => { 13 | test("getFeePerByte", () => { 14 | const result = contract.getFeePerByte(); 15 | 16 | expect(result).toEqual({ 17 | scriptHash, 18 | callFlags: CallFlags.All, 19 | operation: "getFeePerByte", 20 | args: [], 21 | }); 22 | }); 23 | 24 | test("getExecFeeFactor", () => { 25 | const result = contract.getExecFeeFactor(); 26 | 27 | expect(result).toEqual({ 28 | scriptHash, 29 | callFlags: CallFlags.All, 30 | operation: "getExecFeeFactor", 31 | args: [], 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/contracts/EpicChainContract.ts: -------------------------------------------------------------------------------- 1 | import { EpicChainContract } from "../../../src/sc/contracts/EpicChainContract"; 2 | import { ContractParam, CallFlags } from "../../../src/sc"; 3 | import testWallet from "../../testWallet.json"; 4 | 5 | const contract = EpicChainContract.INSTANCE; 6 | const address = testWallet.accounts[0].address; 7 | const addressScriptHash = testWallet.accounts[0].extra.scriptHash as string; 8 | 9 | test("scriptHash", () => { 10 | expect(contract.scriptHash).toEqual( 11 | "6dc3bff7b2e6061f3cad5744edf307c14823328e" 12 | ); 13 | }); 14 | 15 | describe("EpicChain specific methods", () => { 16 | test("unclaimedEpicPulse", () => { 17 | const result = contract.unclaimedEpicChain(address, 123); 18 | 19 | expect(result).toEqual({ 20 | scriptHash: "6dc3bff7b2e6061f3cad5744edf307c14823328e", 21 | callFlags: CallFlags.All, 22 | operation: "unclaimedEpicPulse", 23 | args: [ 24 | ContractParam.hash160(addressScriptHash), 25 | ContractParam.integer(123), 26 | ], 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/core.ts: -------------------------------------------------------------------------------- 1 | import { createScript } from "../../src/sc/core"; 2 | import * as _u from "../../src/u"; 3 | import testIntents from "./scriptIntents.json"; 4 | 5 | beforeEach(() => { 6 | jest.clearAllMocks(); 7 | }); 8 | 9 | describe("createScript", () => { 10 | test("single ScriptIntent", () => { 11 | const result = createScript(testIntents[1].scriptIntent); 12 | expect(result).toBe(testIntents[1].script); 13 | }); 14 | 15 | test("hexstring", () => { 16 | const input1 = "ab"; 17 | const input2 = "cd"; 18 | const result = createScript(input1, input2); 19 | expect(result).toBe("abcd"); 20 | }); 21 | 22 | test("multiple ScriptIntents", () => { 23 | const intents = [testIntents[1], testIntents[2]]; 24 | const input = intents.map((i) => i.scriptIntent); 25 | const expected = intents.map((i) => i.script).join(""); 26 | const result = createScript(...input); 27 | expect(result).toBe(expected); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/djnicholson.NeoPetShopContract.manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"djnicholson.NeoPetShopContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"adoptPet","offset":0,"safe":false,"returntype":"Void","parameters":[{"name":"petId","type":"Integer"}]},{"name":"_deploy","offset":521,"safe":false,"returntype":"Void","parameters":[{"name":"data","type":"Any"},{"name":"update","type":"Boolean"}]},{"name":"feed","offset":430,"safe":false,"returntype":"Void","parameters":[{"name":"petId","type":"Integer"}]},{"name":"getAllStateJson","offset":575,"safe":false,"returntype":"String","parameters":[]},{"name":"getLastFeedingTime","offset":316,"safe":false,"returntype":"Integer","parameters":[{"name":"petId","type":"Integer"}]},{"name":"getPetOwner","offset":119,"safe":false,"returntype":"Hash160","parameters":[{"name":"petId","type":"Integer"}]},{"name":"getShopOwner","offset":644,"safe":false,"returntype":"Hash160","parameters":[]},{"name":"isHungry","offset":291,"safe":false,"returntype":"Boolean","parameters":[{"name":"petId","type":"Integer"}]},{"name":"update","offset":727,"safe":false,"returntype":"Void","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"String"}]},{"name":"_initialize","offset":798,"safe":false,"returntype":"Void","parameters":[]}],"events":[{"name":"PetAdopted","parameters":[{"name":"arg1","type":"Integer"},{"name":"arg2","type":"Hash160"}]},{"name":"PetFed","parameters":[{"name":"arg1","type":"Integer"},{"name":"arg2","type":"Hash160"},{"name":"arg3","type":"Integer"}]}]},"permissions":[{"contract":"0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0","methods":["atoi","base64Encode","itoa","jsonSerialize"]},{"contract":"0xfffdc93764dbaddd97c48f252a53ea4643faa3fd","methods":["update"]}],"trusts":[],"extra":{"Author":"David Nicholson","Email":"david@djntrading.com","Description":"Facilitates adoption of virtual pets"}} -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/djnicholson.NeoPetShopContract.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicvault-js/3efdf0390443d70164a3d69aab44857ca76fbb61/packages/epicvault-core/__tests__/sc/djnicholson.NeoPetShopContract.nef -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/sc/fees.ts: -------------------------------------------------------------------------------- 1 | import { 2 | calculateExecutionFee, 3 | InteropServiceCode, 4 | OpCode, 5 | OpToken, 6 | } from "../../src/sc"; 7 | 8 | describe("calculateExecutionFees", () => { 9 | test("zero", () => { 10 | const result = calculateExecutionFee("", 1); 11 | 12 | expect(result.toString()).toBe("0"); 13 | }); 14 | 15 | test("single signature verification fee", () => { 16 | const result = calculateExecutionFee( 17 | [ 18 | new OpToken(OpCode.PUSHDATA1, "0".repeat(66)), 19 | new OpToken(OpCode.SYSCALL, InteropServiceCode.SYSTEM_CRYPTO_CHECKSIG), 20 | ], 21 | 30 22 | ); 23 | 24 | expect(result.toString()).toBe("983280"); 25 | }); 26 | 27 | test("multisig verification fee", () => { 28 | const result = calculateExecutionFee( 29 | [ 30 | new OpToken(OpCode.PUSH2), 31 | new OpToken(OpCode.PUSHDATA1, "0".repeat(66)), 32 | new OpToken(OpCode.PUSHDATA1, "1".repeat(66)), 33 | new OpToken(OpCode.PUSHDATA1, "2".repeat(66)), 34 | new OpToken(OpCode.PUSH3), 35 | new OpToken( 36 | OpCode.SYSCALL, 37 | InteropServiceCode.SYSTEM_CRYPTO_CHECKMULTISIG 38 | ), 39 | ], 40 | 30 41 | ); 42 | 43 | expect(result.toString()).toBe("1966860"); 44 | }); 45 | 46 | test("invocationScript fee", () => { 47 | const result = calculateExecutionFee( 48 | [new OpToken(OpCode.PUSHDATA1, "0".repeat(128))], 49 | 30 50 | ); 51 | 52 | expect(result.toString()).toBe("240"); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/testKeys.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": { 3 | "address": "NNWAo5vdVJz1oyCuNiaTBA3amBHnWCF4Yk", 4 | "privateKey": "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344", 5 | "publicKey": "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef", 6 | "wif": "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g", 7 | "passphrase": "city of zion", 8 | "encryptedWif": "6PYUUUFei9PBBfVkSn8q7hFCnewWFRBKPxcn6Kz6Bmk3FqWyLyuTQE2XFH" 9 | }, 10 | "b": { 11 | "address": "NMBfzaEq2c5zodiNbLPoohVENARMbJim1r", 12 | "privateKey": "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69", 13 | "publicKey": "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9", 14 | "wif": "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG", 15 | "passphrase": "password", 16 | "encryptedWif": "6PYUmBuLcYxPAhigYaKQi2VAjmdf4d1zSdnD9aBVNtsfM1persEep9wa6S" 17 | }, 18 | "c": { 19 | "address": "NWcpK2143ZjgzDYyQJhoKrodJUymHTxPzR", 20 | "privateKey": "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b", 21 | "publicKey": "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa", 22 | "wif": "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG", 23 | "passphrase": "MyL33tP@33w0rd", 24 | "encryptedWif": "6PYSzKoJBQMj9uHUv1Sc2ZhMrydqDF8ZCTeE9FuPiNdEx7Lo9NoEuaXeyk" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/testWallet1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": null, 3 | "version": "3.0", 4 | "scrypt": { "n": 16384, "r": 8, "p": 8 }, 5 | "accounts": [ 6 | { 7 | "address": "NMPAXGtMfZ8s8rcfP9JhrYrNeZHG4xSVmd", 8 | "label": null, 9 | "isDefault": false, 10 | "lock": false, 11 | "key": "6PYWdzMKGbfxHbfb2JqZJ5Yr1y6jjjuSPLjvgS4byvDkgz2NdiBgeJwBFc", 12 | "contract": { 13 | "script": "DCECAoqZgm7cDJfRjiK2kyNz2QjTI6p/kmVqd\u002Bwm6IYWme8LQQqQatQ=", 14 | "parameters": [{ "name": "signature", "type": "Signature" }], 15 | "deployed": false 16 | }, 17 | "extra": { 18 | "privateKey": "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344", 19 | "publicKey": "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef", 20 | "wif": "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g", 21 | "passphrase": "city of zion" 22 | } 23 | } 24 | ], 25 | "extra": null 26 | } 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/testWallet2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": null, 3 | "version": "3.0", 4 | "scrypt": { "n": 16384, "r": 8, "p": 8 }, 5 | "accounts": [ 6 | { 7 | "address": "NRC6oteucWYXq7aASD6YWe5rNeXAw1ehye", 8 | "label": null, 9 | "isDefault": false, 10 | "lock": false, 11 | "key": "6PYLxXgqDZS1q1GJLQfmGchFndAoxuEtKJTxpYkZtcoty5PDtBvaTAS8qa", 12 | "contract": { 13 | "script": "DCEDHY4WMM5kCWaWe8bZUiPSH0QwQTMAMUDDtSAE3JgTSckLQQqQatQ=", 14 | "parameters": [{ "name": "signature", "type": "Signature" }], 15 | "deployed": false 16 | }, 17 | "extra": { 18 | "privateKey": "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69", 19 | "publicKey": "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9", 20 | "wif": "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG", 21 | "passphrase": "我的密码" 22 | } 23 | } 24 | ], 25 | "extra": null 26 | } 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/testWallet3.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": null, 3 | "version": "3.0", 4 | "scrypt": { "n": 16384, "r": 8, "p": 8 }, 5 | "accounts": [ 6 | { 7 | "address": "NTFAwXLGoiWwSMP5vJyZp8K4cBFwrzUs8m", 8 | "label": null, 9 | "isDefault": false, 10 | "lock": false, 11 | "key": "6PYRoabFnWARA3ZWwfJ4efQ4uuuB9WdVrA1LFbMkZLtXZ2DJg3bzjiK59s", 12 | "contract": { 13 | "script": "DCECIyzo0uIGPc4EURMYUdR0Ib/E/B2k2xFvylMCwHVkYvoLQQqQatQ=", 14 | "parameters": [{ "name": "signature", "type": "Signature" }], 15 | "deployed": false 16 | }, 17 | "extra": { 18 | "privateKey": "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b", 19 | "publicKey": "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa", 20 | "wif": "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG", 21 | "passphrase": "MyL33tP@33w0rd" 22 | } 23 | } 24 | ], 25 | "extra": null 26 | } 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/tx/components/TransactionAttribute.ts: -------------------------------------------------------------------------------- 1 | import { 2 | TransactionAttribute, 3 | TransactionAttributeJson, 4 | HighPriorityAttribute, 5 | OracleResponseTransactionAttributeJson, 6 | OracleResponseAttribute, 7 | } from "../../../src/tx/components/TransactionAttribute"; 8 | import { StringStream } from "../../../src/u"; 9 | 10 | describe("Tx Attributes", () => { 11 | test("high priority", () => { 12 | const input: TransactionAttributeJson = { 13 | type: "HighPriority", 14 | }; 15 | const result = TransactionAttribute.fromJson(input); 16 | expect(result).toBeInstanceOf(HighPriorityAttribute); 17 | expect(result.toJson()).toEqual(input); 18 | expect(result.size).toBe(1); 19 | expect(result.serialize()).toEqual("01"); 20 | 21 | const ss = new StringStream("01"); 22 | const deserializeResult = TransactionAttribute.deserialize(ss); 23 | expect(deserializeResult).toBeInstanceOf(HighPriorityAttribute); 24 | }); 25 | 26 | test("oracle response", () => { 27 | const input: OracleResponseTransactionAttributeJson = { 28 | type: "OracleResponse", 29 | id: 123, 30 | code: "Success", 31 | result: "AQID", 32 | }; 33 | const result = TransactionAttribute.fromJson(input); 34 | expect(result).toBeInstanceOf(OracleResponseAttribute); 35 | expect(result.toJson()).toEqual(input); 36 | expect(result.size).toBe(14); 37 | const captured = "117b000000000000000003010203"; 38 | expect(result.serialize()).toEqual(captured); 39 | const ss = new StringStream(captured); 40 | const deserialized = TransactionAttribute.deserialize(ss); 41 | expect(deserialized).toBeInstanceOf(OracleResponseAttribute); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/tx/components/WitnessScope.ts: -------------------------------------------------------------------------------- 1 | import { 2 | WitnessScope, 3 | parse, 4 | toString, 5 | } from "../../../src/tx/components/WitnessScope"; 6 | 7 | describe("parse", () => { 8 | test.each([ 9 | ["null", "", WitnessScope.None], 10 | ["single CallByEntry", "CalledByEntry", WitnessScope.CalledByEntry], 11 | ["single Global", "Global", WitnessScope.Global], 12 | ["single CustomContracts", "CustomContracts", WitnessScope.CustomContracts], 13 | [ 14 | "all", 15 | "CalledByEntry, CustomContracts,CustomGroups", 16 | WitnessScope.CalledByEntry | 17 | WitnessScope.CustomContracts | 18 | WitnessScope.CustomGroups, 19 | ], 20 | ])("%s", (_: string, stringFlags: string, expected: WitnessScope) => { 21 | const result = parse(stringFlags); 22 | expect(result).toEqual(expected); 23 | }); 24 | }); 25 | 26 | describe("toString", () => { 27 | test.each([ 28 | ["single CallByEntry", "CalledByEntry", WitnessScope.CalledByEntry], 29 | ["single Global", "Global", WitnessScope.Global], 30 | ["single CustomContracts", "CustomContracts", WitnessScope.CustomContracts], 31 | [ 32 | "all", 33 | "CalledByEntry,CustomContracts,CustomGroups", 34 | WitnessScope.CalledByEntry | 35 | WitnessScope.CustomContracts | 36 | WitnessScope.CustomGroups, 37 | ], 38 | ])("%s", (_: string, expected: string, flag: WitnessScope) => { 39 | const result = toString(flag); 40 | expect(result).toEqual(expected); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/u/basic/base64.ts: -------------------------------------------------------------------------------- 1 | import { 2 | base642hex, 3 | base642utf8, 4 | hex2base64, 5 | utf82base64, 6 | } from "../../../src/u/basic/base64"; 7 | 8 | const hexBase64testCases = [ 9 | ["4e454f", "TkVP"], // NEO 10 | ["6e656f", "bmVv"], // neo 11 | ["11", "EQ=="], 12 | ["41123e7fe8", "QRI+f+g="], 13 | ]; 14 | describe("hex and base64", () => { 15 | test.each(hexBase64testCases)( 16 | "hex2base64 %s", 17 | (input: string, expected: string) => { 18 | const result = hex2base64(input); 19 | expect(result).toBe(expected); 20 | } 21 | ); 22 | 23 | test.each(hexBase64testCases)( 24 | "base642hex %s", 25 | (expected: string, input: string) => { 26 | const result = base642hex(input); 27 | expect(result).toBe(expected); 28 | } 29 | ); 30 | }); 31 | 32 | const utf8Base64testCases = [ 33 | ["NEO", "TkVP"], 34 | ["neo", "bmVv"], 35 | ["neon-core", "bmVvbi1jb3Jl"], 36 | [ 37 | "αβγδεζηθικλμνξοπρστυφχψω", 38 | "zrHOss6zzrTOtc62zrfOuM65zrrOu868zr3Ovs6/z4DPgc+Dz4TPhc+Gz4fPiM+J", 39 | ], 40 | ]; 41 | describe("utf8 and base64", () => { 42 | test.each(utf8Base64testCases)( 43 | "utf82base64 %s", 44 | (input: string, expected: string) => { 45 | const result = utf82base64(input); 46 | expect(result).toBe(expected); 47 | } 48 | ); 49 | 50 | test.each(utf8Base64testCases)( 51 | "base642utf8 %s", 52 | (expected: string, input: string) => { 53 | const result = base642utf8(input); 54 | expect(result).toBe(expected); 55 | } 56 | ); 57 | }); 58 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/u/basic/hex.ts: -------------------------------------------------------------------------------- 1 | import { remove0xPrefix, reverseHex } from "../../../src/u/basic/hex"; 2 | 3 | describe("reverseHex", () => { 4 | test("throws if not hexstring", () => { 5 | expect(() => reverseHex("fg")).toThrow(); 6 | }); 7 | 8 | test("Reverses hex", () => { 9 | const input = "000102030405060708090a0b0c0d0e0f"; 10 | const result = reverseHex(input); 11 | expect(result).toBe("0f0e0d0c0b0a09080706050403020100"); 12 | }); 13 | 14 | test("Remove 0x prefix", () => { 15 | const input = "0x000102030405060708090a0b0c0d0e0f"; 16 | const result = remove0xPrefix(input); 17 | expect(result).toBe("000102030405060708090a0b0c0d0e0f"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/u/misc.ts: -------------------------------------------------------------------------------- 1 | import * as misc from "../../src/u/misc"; 2 | 3 | describe("hexXor", () => { 4 | test("throws if inputs of different length", () => { 5 | const input1 = "00"; 6 | const input2 = "0001"; 7 | expect(() => misc.hexXor(input1, input2)).toThrow(); 8 | }); 9 | 10 | test("Performs bitwise XOR", () => { 11 | const input1 = "0001101100011011"; 12 | const input2 = "0000000011111111"; 13 | const result = misc.hexXor(input1, input2); 14 | expect(result).toBe("0001101111100100"); 15 | }); 16 | }); 17 | 18 | describe("reverseArray", () => { 19 | test("throws if not array", () => { 20 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 21 | //@ts-ignore 22 | expect(() => misc.reverseArray(1)).toThrow(); 23 | }); 24 | 25 | test("Reverses an array", () => { 26 | const input = [1, 2, 3, 4, 5]; 27 | const result = misc.reverseArray(input); 28 | expect(result).toEqual([5, 4, 3, 2, 1]); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/u/random.ts: -------------------------------------------------------------------------------- 1 | import { generateRandomArray } from "../../src/u/basic/random"; 2 | 3 | it("returns empty array when 0", () => { 4 | const result = generateRandomArray(0); 5 | expect(result.length).toBe(0); 6 | }); 7 | 8 | it("returns correct length of bytes", () => { 9 | const result = generateRandomArray(10); 10 | 11 | expect(result.length).toBe(10); 12 | }); 13 | 14 | it("returns numbers within 0-255", () => { 15 | const randomNumbers = generateRandomArray(100); 16 | 17 | randomNumbers.forEach((n) => { 18 | expect(n).toBeLessThanOrEqual(255); 19 | expect(n).toBeGreaterThanOrEqual(0); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/u/serialize.ts: -------------------------------------------------------------------------------- 1 | import { HexString } from "../../src/u"; 2 | import { Witness } from "../../src/tx"; 3 | import { getSerializedSize } from "../../src/u/serialize"; 4 | 5 | describe("getSerializedSize", () => { 6 | test("size of HexString", () => { 7 | const input = HexString.fromHex("112233"); 8 | const result = getSerializedSize(input); 9 | expect(result).toBe(4); 10 | }); 11 | 12 | test("size of number < 0xfd", () => { 13 | const result = getSerializedSize(0xfc); 14 | expect(result).toBe(1); 15 | }); 16 | 17 | test("size of number <= 0xffff", () => { 18 | // lower boundary 19 | let result = getSerializedSize(0xfd); 20 | expect(result).toBe(3); 21 | // upper boundary 22 | result = getSerializedSize(0xffff); 23 | expect(result).toBe(3); 24 | }); 25 | 26 | test("size of number > 0xffff", () => { 27 | const result = getSerializedSize(0xffff + 1); 28 | expect(result).toBe(5); 29 | }); 30 | 31 | test("array of serializable objects", () => { 32 | const input = [ 33 | new Witness({ 34 | invocationScript: "01".repeat(256), 35 | verificationScript: "03", 36 | }), 37 | new Witness({ 38 | invocationScript: "01".repeat(256), 39 | verificationScript: "03", 40 | }), 41 | ]; 42 | 43 | const result = getSerializedSize(input); 44 | expect(result).toBe(523); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /packages/epicvault-core/__tests__/wallet/multisig.ts: -------------------------------------------------------------------------------- 1 | import { 2 | constructMultiSigVerificationScript, 3 | getPublicKeysFromVerificationScript, 4 | getSigningThresholdFromVerificationScript, 5 | } from "../../src/wallet"; 6 | 7 | const testData: [string, number, string[], string][] = [ 8 | [ 9 | "1 key 1 threshold", 10 | 1, 11 | ["03118a2b7962fa0226fa35acf5d224855b691c7ea978d1afe2c538631d5f7be85e"], 12 | "110c2103118a2b7962fa0226fa35acf5d224855b691c7ea978d1afe2c538631d5f7be85e11419ed0dc3a", 13 | ], 14 | [ 15 | "3 keys 2 threshold", 16 | 2, 17 | [ 18 | "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef", 19 | "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9", 20 | "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa", 21 | ], 22 | "120c2102028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef0c21031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c90c2102232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa13419ed0dc3a", 23 | ], 24 | ]; 25 | 26 | describe("constructMultiSigVerificationScript", () => { 27 | test.each(testData)( 28 | "%s", 29 | (_: string, threshold: number, keys: string[], script: string) => { 30 | const result = constructMultiSigVerificationScript(threshold, keys); 31 | expect(result).toBe(script); 32 | } 33 | ); 34 | }); 35 | 36 | describe("getPublicKeysFromVerificationScript", () => { 37 | test.each(testData)( 38 | "%s", 39 | (_: string, _threshold: number, keys: string[], script: string) => { 40 | const result = getPublicKeysFromVerificationScript(script); 41 | expect(result).toStrictEqual(keys); 42 | } 43 | ); 44 | }); 45 | 46 | describe("getSigningThresholdFromVerificationScript", () => { 47 | test.each(testData)( 48 | "%s", 49 | (_: string, threshold: number, _keys: string[], script: string) => { 50 | const result = getSigningThresholdFromVerificationScript(script); 51 | expect(result).toBe(threshold); 52 | } 53 | ); 54 | }); 55 | -------------------------------------------------------------------------------- /packages/epicvault-core/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "../../api-extractor-base.json" 4 | } -------------------------------------------------------------------------------- /packages/epicvault-core/jest.config.js: -------------------------------------------------------------------------------- 1 | const config = require("../../jest.config"); 2 | config.globals["ts-jest"]["tsconfig"] = "../../tsconfig-test.json"; 3 | module.exports = config; 4 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/consts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @deprecated If you are looking for the default MainNet address version for N3, please use DEFAULT_ADDRESS_VERSION. 3 | */ 4 | export const ADDR_VERSION = "76"; 5 | 6 | export const DEFAULT_ADDRESS_VERSION = 0x4C; 7 | 8 | export enum MAGIC_NUMBER { 9 | MainNet = 860833102, 10 | TestNet = 894710606, 11 | SoloNet = 1234567890, 12 | } 13 | 14 | export enum NATIVE_CONTRACT_HASH { 15 | EpicChain = "6dc3bff7b2e6061f3cad5744edf307c14823328e", 16 | EpicPulse = "bc8459660544656355b4f60861c22f544341e828", 17 | CovenantChain = "add3e350a8789c507686ea677da85d89272f064b", 18 | ManagementContract = "fffdc93764dbaddd97c48f252a53ea4643faa3fd", 19 | OracleNexus = "f95f1e73b6b852e0cdf1535d5371d211707a2d95", 20 | QuantumVaultAsset = "8fd7b7687ff40a5ddd6ea466a8787df2633ed3df", 21 | QuantumGuardNexus = "cffffd77bb491d262eda1056bd976e881fc18142", 22 | EssentialLib = "410276eb5920d29475c203e04a5015b99c44846a", 23 | CryptoHive = "494c1594ccfa500e9b1fdf567f9e55d8338f3495", 24 | } 25 | 26 | /** 27 | * @deprecated Please use NATIVE_CONTRACT_HASH 28 | */ 29 | export const ASSET_ID: { [key: string]: string } = { 30 | EpicChain: "6dc3bff7b2e6061f3cad5744edf307c14823328e", 31 | EpicPulse: "bc8459660544656355b4f60861c22f544341e828", 32 | }; 33 | export const DEFAULT_REQ = { 34 | jsonrpc: "1.0", 35 | method: "getblockcount", 36 | params: [], 37 | id: 1234, 38 | }; 39 | 40 | export const DEFAULT_SCRYPT = { 41 | n: 16384, 42 | r: 8, 43 | p: 8, 44 | size: 64, 45 | }; 46 | 47 | export const DEFAULT_WALLET = { 48 | name: "myWallet", 49 | version: "1.0", 50 | scrypt: DEFAULT_SCRYPT, 51 | extra: null, 52 | }; 53 | 54 | export const DEFAULT_ACCOUNT_CONTRACT = { 55 | script: "", 56 | parameters: [ 57 | { 58 | name: "signature", 59 | type: "Signature", 60 | }, 61 | ], 62 | deployed: false, 63 | }; 64 | 65 | // specified by XEP2, same as bip38 66 | export const XEP2_HEADER = "0142"; 67 | 68 | export const XEP2_FLAG = "e0"; 69 | 70 | // transaction related 71 | export const TX_VERSION = 0; 72 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * EpicVault Core Library 3 | * Main entry point for the EpicVault core functionality 4 | */ 5 | 6 | // Core Types and Interfaces 7 | export * from './types'; 8 | export * from './model'; 9 | export * from './consts'; 10 | 11 | // Core Functionality 12 | export * from './wallet'; 13 | export * from './tx'; 14 | export * from './sc'; 15 | export * from './rpc'; 16 | 17 | // Utilities 18 | export * from './u'; 19 | export * from './logging'; 20 | 21 | // Internal utilities (not recommended for direct use) 22 | export * from './internal'; 23 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/internal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parses a string, number or enum to an enum. 3 | */ 4 | export function parseEnum( 5 | input: string | number | T[keyof T], 6 | enumType: T 7 | ): T[keyof T] { 8 | if (typeof input === "string") { 9 | if (input in enumType) { 10 | return enumType[input as keyof typeof enumType]; 11 | } 12 | throw new Error(`${input} not found in enum!`); 13 | } 14 | return input as T[keyof T]; 15 | } 16 | 17 | /** 18 | * Simple type helper to merge types that have the same field names. 19 | */ 20 | export type EpicVaultLike = { 21 | [Property in keyof NeonType & keyof JsonType]: 22 | | NeonType[Property] 23 | | JsonType[Property]; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/rpc/BatchQuery.ts: -------------------------------------------------------------------------------- 1 | import { Query, JsonRpcParams } from "./Query"; 2 | 3 | /** 4 | * Helper class that maintains the types in a list of Queries. 5 | * This allows the RpcDispatcher to return correctly typed responses. 6 | */ 7 | export class BatchQuery< 8 | TParams extends JsonRpcParams[], 9 | TResponses extends unknown[] 10 | > { 11 | public queries: Query[]; 12 | 13 | private constructor(q: Query) { 14 | this.queries = [q]; 15 | } 16 | 17 | public add( 18 | q: Query 19 | ): BatchQuery<[...TParams, TParam], [...TResponses, TResponse]> { 20 | this.queries.push(q); 21 | return this; 22 | } 23 | 24 | public static of( 25 | q: Query 26 | ): BatchQuery<[TParams], [TResponse]> { 27 | return new BatchQuery(q); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/rpc/clients/ApplicationLogsRpcClient.ts: -------------------------------------------------------------------------------- 1 | import Query, { ApplicationLogJson } from "../Query"; 2 | import { RpcDispatcher, RpcDispatcherMixin } from "./RpcDispatcher"; 3 | 4 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types 5 | export function ApplicationLogsRpcMixin( 6 | base: TBase 7 | ) { 8 | return class extends base { 9 | public async getApplicationLog( 10 | blockOrTxHash: string 11 | ): Promise { 12 | return await this.execute(Query.getApplicationLog(blockOrTxHash)); 13 | } 14 | }; 15 | } 16 | 17 | export class ApplicationLogsRpcClient extends ApplicationLogsRpcMixin( 18 | RpcDispatcher 19 | ) { 20 | public get [Symbol.toStringTag](): string { 21 | return `ApplicationLogsRpcClient(${this.url})`; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/rpc/clients/TokenTrackerRpcClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Query, 3 | GetNep17BalancesResult, 4 | GetNep17TransfersResult, 5 | GetNep11TransfersResult, 6 | GetNep11BalancesResult, 7 | } from "../Query"; 8 | import { RpcDispatcher, RpcDispatcherMixin } from "./RpcDispatcher"; 9 | 10 | // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types 11 | export function TokenTrackerRpcMixin( 12 | base: TBase 13 | ) { 14 | return class TokenTrackerRpcInterface extends base { 15 | public async getNep17Transfers( 16 | accountIdentifier: string, 17 | startTime?: string, 18 | endTime?: string 19 | ): Promise { 20 | return this.execute( 21 | Query.getNep17Transfers(accountIdentifier, startTime, endTime) 22 | ); 23 | } 24 | public async getNep17Balances( 25 | accountIdentifier: string 26 | ): Promise { 27 | return this.execute(Query.getNep17Balances(accountIdentifier)); 28 | } 29 | 30 | public async getNep11Transfers( 31 | accountIdentifier: string, 32 | startTime?: string, 33 | endTime?: string 34 | ): Promise { 35 | return this.execute( 36 | Query.getNep11Transfers(accountIdentifier, startTime, endTime) 37 | ); 38 | } 39 | 40 | public async getNep11Balances( 41 | accountIdentifier: string 42 | ): Promise { 43 | return this.execute(Query.getNep11Balances(accountIdentifier)); 44 | } 45 | }; 46 | } 47 | 48 | export class TokenTrackerRpcClient extends TokenTrackerRpcMixin(RpcDispatcher) { 49 | public get [Symbol.toStringTag](): string { 50 | return `TokenTrackerRpcClient(${this.url})`; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/rpc/clients/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./RpcDispatcher"; 2 | export * from "./ApplicationLogsRpcClient"; 3 | export * from "./TokenTrackerRpcClient"; 4 | export * from "./EpicChainServerRpcClient"; 5 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/rpc/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Network"; 2 | export * from "./Protocol"; 3 | export * from "./Query"; 4 | export * from "./RPCClient"; 5 | export * from "./parse"; 6 | export * from "./clients"; 7 | export * from "./BatchQuery"; 8 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/CallFlags.ts: -------------------------------------------------------------------------------- 1 | export enum CallFlags { 2 | None = 0, 3 | ReadStates = 1 << 0, 4 | WriteStates = 1 << 1, 5 | AllowCall = 1 << 2, 6 | AllowNotify = 1 << 3, 7 | States = ReadStates | WriteStates, 8 | ReadOnly = ReadStates | AllowCall, 9 | All = States | AllowCall | AllowNotify, 10 | } 11 | 12 | export default CallFlags; 13 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/InteropServicePrices.ts: -------------------------------------------------------------------------------- 1 | import { InteropServiceCode } from "./InteropServiceCode"; 2 | 3 | const fixedPrices = { 4 | [InteropServiceCode.SYSTEM_CONTRACT_CALL]: 32768, 5 | [InteropServiceCode.SYSTEM_CONTRACT_CALLNATIVE]: 0, 6 | [InteropServiceCode.SYSTEM_CONTRACT_CREATEMULTISIGACCOUNT]: 256, 7 | [InteropServiceCode.SYSTEM_CONTRACT_CREATESTANDARDACCOUNT]: 256, 8 | [InteropServiceCode.SYSTEM_CONTRACT_GETCALLFLAGS]: 1024, 9 | [InteropServiceCode.SYSTEM_CONTRACT_NATIVEONPERSIST]: 0, 10 | [InteropServiceCode.SYSTEM_CONTRACT_NATIVEPOSTPERSIST]: 0, 11 | [InteropServiceCode.SYSTEM_CRYPTO_CHECKSIG]: 32768, 12 | [InteropServiceCode.SYSTEM_RUNTIME_GETADDRESSVERSION]: 8, 13 | [InteropServiceCode.SYSTEM_RUNTIME_GETINVOCATIONCOUNTER]: 16, 14 | [InteropServiceCode.SYSTEM_RUNTIME_GETNETWORK]: 8, 15 | [InteropServiceCode.SYSTEM_RUNTIME_GETNOTIFICATIONS]: 4096, 16 | [InteropServiceCode.SYSTEM_RUNTIME_GETSCRIPTCONTAINER]: 8, 17 | [InteropServiceCode.SYSTEM_RUNTIME_GETTIME]: 8, 18 | [InteropServiceCode.SYSTEM_RUNTIME_GETTRIGGER]: 8, 19 | [InteropServiceCode.SYSTEM_RUNTIME_LOG]: 32768, 20 | [InteropServiceCode.SYSTEM_RUNTIME_NOTIFY]: 32768, 21 | [InteropServiceCode.SYSTEM_RUNTIME_PLATFORM]: 8, 22 | [InteropServiceCode.SYSTEM_STORAGE_ASREADONLY]: 16, 23 | [InteropServiceCode.SYSTEM_STORAGE_DELETE]: 32768, 24 | [InteropServiceCode.SYSTEM_STORAGE_FIND]: 32768, 25 | [InteropServiceCode.SYSTEM_STORAGE_GET]: 32768, 26 | [InteropServiceCode.SYSTEM_STORAGE_GETCONTEXT]: 16, 27 | [InteropServiceCode.SYSTEM_STORAGE_GETREADONLYCONTEXT]: 16, 28 | [InteropServiceCode.SYSTEM_STORAGE_PUT]: 32768, 29 | }; 30 | 31 | type fixedPriceInteropServiceCode = keyof typeof fixedPrices; 32 | 33 | function isFixedPrice( 34 | code: InteropServiceCode 35 | ): code is fixedPriceInteropServiceCode { 36 | return code in fixedPrices; 37 | } 38 | 39 | export function getInteropServicePrice(service: InteropServiceCode): number { 40 | if (isFixedPrice(service)) { 41 | return fixedPrices[service as keyof typeof fixedPrices]; 42 | } 43 | 44 | throw new Error( 45 | `InteropServiceCode ${service} not supported as it is dynamically priced.` 46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/CovenantChain.ts: -------------------------------------------------------------------------------- 1 | import { ContractMethodDefinition } from "../manifest/ContractMethodDefinition"; 2 | import { ContractCall } from "../types"; 3 | import { BaseContract } from "./BaseContract"; 4 | import policyAbi from "./templates/PolicyTemplateAbi.json"; 5 | import { NATIVE_CONTRACT_HASH } from "../../consts"; 6 | 7 | let SINGLETON: CovenantChain; 8 | /** 9 | * Policy Contract that contains block-specific parameters for the current blockchain. 10 | * Helper methods are not fully implemented but the complete definition is available. 11 | */ 12 | export class CovenantChain extends BaseContract { 13 | public static get INSTANCE(): CovenantChain { 14 | if (!SINGLETON) { 15 | SINGLETON = new CovenantChain(); 16 | } 17 | return SINGLETON; 18 | } 19 | 20 | public static getMethods(): ContractMethodDefinition[] { 21 | return policyAbi.methods.map((m) => ContractMethodDefinition.fromJson(m)); 22 | } 23 | 24 | constructor() { 25 | super(NATIVE_CONTRACT_HASH.CovenantChain, CovenantChain.getMethods()); 26 | } 27 | 28 | public getFeePerByte(): ContractCall { 29 | return this.call("getFeePerByte"); 30 | } 31 | 32 | public getExecFeeFactor(): ContractCall { 33 | return this.call("getExecFeeFactor"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/EpicChainContract.ts: -------------------------------------------------------------------------------- 1 | import { NATIVE_CONTRACT_HASH } from "../../consts"; 2 | import { BigInteger, HexString } from "../../u"; 3 | import { ContractParam } from "../ContractParam"; 4 | import { ContractMethodDefinition } from "../manifest"; 5 | import { ContractCall } from "../types"; 6 | import { Xep17Contract } from "./Xep17Contract"; 7 | import epicchainAbi from "./templates/EpicChainTemplateAbi.json"; 8 | 9 | let SINGLETON: EpicChainContract; 10 | 11 | export class EpicChainContract extends Xep17Contract { 12 | public static get INSTANCE(): EpicChainContract { 13 | if (!SINGLETON) { 14 | SINGLETON = new EpicChainContract(); 15 | } 16 | return SINGLETON; 17 | } 18 | 19 | /** 20 | * The list of methods found on the EpicChain contract. 21 | */ 22 | public static getMethods(): ContractMethodDefinition[] { 23 | return epicchainAbi.methods.map((m) => ContractMethodDefinition.fromJson(m)); 24 | } 25 | 26 | constructor() { 27 | super(NATIVE_CONTRACT_HASH.EpicChain, EpicChainContract.getMethods()); 28 | } 29 | 30 | public unclaimedEpicChain(address: string, end: number | BigInteger): ContractCall { 31 | return this.call( 32 | "unclaimedEpicChain", 33 | ContractParam.hash160(address), 34 | ContractParam.integer(end) 35 | ); 36 | } 37 | 38 | public getCandidates(): ContractCall { 39 | return this.call("getCandidates"); 40 | } 41 | 42 | public getRegisterPrice(): ContractCall { 43 | return this.call("getRegisterPrice"); 44 | } 45 | 46 | public registerCandidate(publicKey: string | HexString): ContractCall { 47 | return this.call("registerCandidate", ContractParam.publicKey(publicKey)); 48 | } 49 | 50 | public vote(address: string, voteTo: string | HexString): ContractCall { 51 | return this.call( 52 | "vote", 53 | ContractParam.hash160(address), 54 | ContractParam.publicKey(voteTo) 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/EpicPulseContract.ts: -------------------------------------------------------------------------------- 1 | import { NATIVE_CONTRACT_HASH } from "../../consts"; 2 | import { ContractMethodDefinition } from "../manifest"; 3 | import { Xep17Contract } from "./Xep17Contract"; 4 | import gasAbi from "./templates/EpicPulseTemplateAbi.json"; 5 | 6 | let SINGLETON: EpicPulseContract; 7 | 8 | export class EpicPulseContract extends Xep17Contract { 9 | public static get INSTANCE(): EpicPulseContract { 10 | if (!SINGLETON) { 11 | SINGLETON = new EpicPulseContract(); 12 | } 13 | return SINGLETON; 14 | } 15 | 16 | /** 17 | * The list of methods found on the GAS contract. 18 | */ 19 | public static getMethods(): ContractMethodDefinition[] { 20 | return gasAbi.methods.map((m) => ContractMethodDefinition.fromJson(m)); 21 | } 22 | 23 | constructor() { 24 | super(NATIVE_CONTRACT_HASH.EpicPulse, EpicPulseContract.getMethods()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./BaseContract"; 2 | export * from "./Xep17Contract"; 3 | export * from "./EpicChainContract"; 4 | export * from "./EpicPulseContract"; 5 | export * from "./CovenantChain"; 6 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/templates/EpicPulseTemplateAbi.json: -------------------------------------------------------------------------------- 1 | { 2 | "methods": [ 3 | { 4 | "name": "totalSupply", 5 | "parameters": [], 6 | "offset": 0, 7 | "returntype": "Integer", 8 | "safe": true 9 | }, 10 | { 11 | "name": "balanceOf", 12 | "parameters": [ 13 | { 14 | "name": "account", 15 | "type": "ByteArray" 16 | } 17 | ], 18 | "offset": 0, 19 | "returntype": "Integer", 20 | "safe": true 21 | }, 22 | { 23 | "name": "transfer", 24 | "parameters": [ 25 | { 26 | "name": "from", 27 | "type": "ByteArray" 28 | }, 29 | { 30 | "name": "to", 31 | "type": "ByteArray" 32 | }, 33 | { 34 | "name": "amount", 35 | "type": "Integer" 36 | }, 37 | { 38 | "name": "data", 39 | "type": "Any" 40 | } 41 | ], 42 | "offset": 0, 43 | "returntype": "Boolean", 44 | "safe": false 45 | }, 46 | { 47 | "name": "symbol", 48 | "parameters": [], 49 | "offset": 0, 50 | "returntype": "String", 51 | "safe": true 52 | }, 53 | { 54 | "name": "decimals", 55 | "parameters": [], 56 | "offset": 0, 57 | "returntype": "Integer", 58 | "safe": true 59 | } 60 | ], 61 | "events": [ 62 | { 63 | "name": "Transfer", 64 | "parameters": [ 65 | { 66 | "name": "from", 67 | "type": "Hash160" 68 | }, 69 | { 70 | "name": "to", 71 | "type": "Hash160" 72 | }, 73 | { 74 | "name": "amount", 75 | "type": "Integer" 76 | } 77 | ] 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/contracts/templates/Xep17TemplateAbi.json: -------------------------------------------------------------------------------- 1 | { 2 | "methods": [ 3 | { 4 | "name": "totalSupply", 5 | "parameters": [], 6 | "offset": 0, 7 | "returntype": "Integer", 8 | "safe": true 9 | }, 10 | { 11 | "name": "balanceOf", 12 | "parameters": [ 13 | { 14 | "name": "account", 15 | "type": "ByteArray" 16 | } 17 | ], 18 | "offset": 0, 19 | "returntype": "Integer", 20 | "safe": true 21 | }, 22 | { 23 | "name": "transfer", 24 | "parameters": [ 25 | { 26 | "name": "from", 27 | "type": "ByteArray" 28 | }, 29 | { 30 | "name": "to", 31 | "type": "ByteArray" 32 | }, 33 | { 34 | "name": "amount", 35 | "type": "Integer" 36 | }, 37 | { 38 | "name": "data", 39 | "type": "Any" 40 | } 41 | ], 42 | "offset": 0, 43 | "returntype": "Boolean", 44 | "safe": false 45 | }, 46 | { 47 | "name": "symbol", 48 | "parameters": [], 49 | "offset": 0, 50 | "returntype": "String", 51 | "safe": true 52 | }, 53 | { 54 | "name": "decimals", 55 | "parameters": [], 56 | "offset": 0, 57 | "returntype": "Integer", 58 | "safe": true 59 | } 60 | ], 61 | "events": [ 62 | { 63 | "name": "Transfer", 64 | "parameters": [ 65 | { 66 | "name": "from", 67 | "type": "Hash160" 68 | }, 69 | { 70 | "name": "to", 71 | "type": "Hash160" 72 | }, 73 | { 74 | "name": "amount", 75 | "type": "Integer" 76 | } 77 | ] 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/core.ts: -------------------------------------------------------------------------------- 1 | import { ScriptBuilder } from "./ScriptBuilder"; 2 | import { ContractCall, ContractCallJson } from "./types"; 3 | /** 4 | * Translates a ScriptIntent / array of ScriptIntents into hexstring. 5 | * @param scripts - ContractCall or hexstrings. 6 | */ 7 | export function createScript( 8 | ...scripts: (ContractCall | ContractCallJson | string)[] 9 | ): string { 10 | const sb = new ScriptBuilder(); 11 | for (const script of scripts) { 12 | if (typeof script === "string") { 13 | sb.str += script; 14 | continue; 15 | } 16 | 17 | const contractCall = script; 18 | if (!contractCall.scriptHash) { 19 | throw new Error("No scriptHash found!"); 20 | } 21 | if (!contractCall.operation) { 22 | throw new Error("No operation found!"); 23 | } 24 | 25 | sb.emitContractCall(script); 26 | } 27 | return sb.build(); 28 | } 29 | 30 | export interface DeployParams { 31 | script: string; 32 | manifest: string; 33 | } 34 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ContractParam"; 2 | export * from "./core"; 3 | export * from "./ScriptBuilder"; 4 | export * from "./OpCode"; 5 | export * from "./OpCodePrices"; 6 | export * from "./InteropServiceCode"; 7 | export * from "./InteropServicePrices"; 8 | export * from "./StackItem"; 9 | export * from "./manifest"; 10 | export * from "./OpToken"; 11 | export * from "./contracts"; 12 | export * from "./fees"; 13 | export * from "./XEF"; 14 | export * from "./CallFlags"; 15 | export * from "./MethodToken"; 16 | export * from "./types"; 17 | export * from "./util"; 18 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/manifest/ContractAbi.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ContractMethodDefinition, 3 | ContractMethodDefinitionLike, 4 | ContractMethodDefinitionJson, 5 | } from "./ContractMethodDefinition"; 6 | import { 7 | ContractEventDefiniton, 8 | ContractEventDefinitonLike, 9 | ContractEventDefinitionJson, 10 | } from "./ContractEventDefiniton"; 11 | 12 | export interface ContractAbiLike { 13 | methods: ContractMethodDefinitionLike[]; 14 | events: ContractEventDefinitonLike[]; 15 | } 16 | 17 | export interface ContractAbiJson { 18 | methods: ContractMethodDefinitionJson[]; 19 | events: ContractEventDefinitionJson[]; 20 | } 21 | export class ContractAbi { 22 | public methods: ContractMethodDefinition[]; 23 | public events: ContractEventDefiniton[]; 24 | 25 | public static fromJson(json: ContractAbiJson): ContractAbi { 26 | return new ContractAbi({ 27 | methods: json.methods.map((m) => ContractMethodDefinition.fromJson(m)), 28 | events: json.events.map((e) => ContractEventDefiniton.fromJson(e)), 29 | }); 30 | } 31 | 32 | public constructor(obj: Partial) { 33 | const { methods = [], events = [] } = obj; 34 | 35 | this.methods = methods.map( 36 | (method) => new ContractMethodDefinition(method) 37 | ); 38 | this.events = events.map((event) => new ContractEventDefiniton(event)); 39 | } 40 | 41 | public toJson(): ContractAbiJson { 42 | return { 43 | methods: this.methods.map((m) => m.toJson()), 44 | events: this.events.map((e) => e.toJson()), 45 | }; 46 | } 47 | 48 | public export(): ContractAbiLike { 49 | return { 50 | methods: this.methods.map((method) => method.export()), 51 | events: this.events.map((event) => event.export()), 52 | }; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/manifest/ContractEventDefiniton.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ContractParameterDefinition, 3 | ContractParameterDefinitionJson, 4 | } from "./ContractParameterDefinition"; 5 | import { parseEnum } from "../../internal"; 6 | import { ContractParamType } from "../ContractParam"; 7 | 8 | export interface ContractEventDefinitonLike { 9 | name: string; 10 | parameters: ContractParameterDefinition[]; 11 | } 12 | 13 | export interface ContractEventDefinitionJson { 14 | name: string; 15 | parameters: ContractParameterDefinitionJson[]; 16 | } 17 | 18 | export class ContractEventDefiniton { 19 | public name: string; 20 | public parameters: ContractParameterDefinition[]; 21 | 22 | public static fromJson( 23 | json: ContractEventDefinitionJson 24 | ): ContractEventDefiniton { 25 | return new ContractEventDefiniton({ 26 | name: json.name, 27 | parameters: json.parameters.map((p) => ({ 28 | name: p.name, 29 | type: parseEnum(p.type, ContractParamType), 30 | })), 31 | }); 32 | } 33 | public constructor(obj: Partial) { 34 | const { name = "", parameters = [] } = obj; 35 | this.name = name; 36 | this.parameters = [...parameters]; 37 | } 38 | 39 | public toJson(): ContractEventDefinitionJson { 40 | return { 41 | name: this.name, 42 | parameters: this.parameters.map((p) => ({ 43 | name: p.name, 44 | type: ContractParamType[p.type], 45 | })), 46 | }; 47 | } 48 | 49 | public export(): ContractEventDefinitonLike { 50 | return { 51 | name: this.name, 52 | parameters: [...this.parameters], 53 | }; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/manifest/ContractGroup.ts: -------------------------------------------------------------------------------- 1 | import { HexString } from "../../u"; 2 | 3 | export interface ContractGroupLike { 4 | pubKey: string; 5 | signature: string; 6 | } 7 | 8 | export interface ContractGroupJson { 9 | pubkey: string; 10 | /** base64-encoded */ 11 | signature: string; 12 | } 13 | export class ContractGroup { 14 | public pubKey: string; 15 | public signature: string; 16 | 17 | public static fromJson(json: ContractGroupJson): ContractGroup { 18 | return new ContractGroup({ 19 | pubKey: json.pubkey, 20 | signature: HexString.fromBase64(json.signature).toBigEndian(), 21 | }); 22 | } 23 | public constructor(obj: Partial) { 24 | const { pubKey = "", signature = "" } = obj; 25 | this.pubKey = pubKey; 26 | this.signature = signature; 27 | } 28 | 29 | public toJson(): ContractGroupJson { 30 | return { 31 | pubkey: this.pubKey, 32 | signature: HexString.fromHex(this.signature).toBase64(), 33 | }; 34 | } 35 | 36 | public export(): ContractGroupLike { 37 | return { 38 | pubKey: this.pubKey, 39 | signature: this.signature, 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/manifest/ContractParameterDefinition.ts: -------------------------------------------------------------------------------- 1 | import { ContractParamType } from "../ContractParam"; 2 | 3 | export interface ContractParameterDefinition { 4 | name: string; 5 | type: ContractParamType; 6 | } 7 | 8 | export interface ContractParameterDefinitionJson { 9 | name: string; 10 | type: string; 11 | } 12 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/manifest/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ContractAbi"; 2 | export * from "./ContractEventDefiniton"; 3 | export * from "./ContractGroup"; 4 | export * from "./ContractManifest"; 5 | export * from "./ContractMethodDefinition"; 6 | export * from "./ContractParameterDefinition"; 7 | export * from "./ContractPermission"; 8 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/sc/types.ts: -------------------------------------------------------------------------------- 1 | import ContractParam, { ContractParamJson } from "./ContractParam"; 2 | import { CallFlags } from "./CallFlags"; 3 | 4 | export interface ContractCall { 5 | /** Hexstring of 40 characters in BE */ 6 | scriptHash: string; 7 | /** UTF8 string */ 8 | operation: string; 9 | callFlags?: CallFlags; 10 | args?: ContractParam[]; 11 | } 12 | 13 | export interface ContractCallJson { 14 | /** Hexstring of 40 characters in BE */ 15 | scriptHash: string; 16 | /** UTF8 string */ 17 | operation: string; 18 | callFlags?: CallFlags; 19 | args?: ContractParamJson[]; 20 | } 21 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/tx/components/WitnessRule.ts: -------------------------------------------------------------------------------- 1 | import { EpicVaultLike, parseEnum } from "../../internal"; 2 | import { EpicVaultSerializable, StringStream } from "../../u"; 3 | import { 4 | CalledByEntryWitnessCondition, 5 | WitnessCondition, 6 | WitnessConditionJson, 7 | } from "./WitnessCondition"; 8 | 9 | export enum WitnessRuleAction { 10 | Deny = 0, 11 | 12 | Allow = 1, 13 | } 14 | 15 | export interface WitnessRuleJson { 16 | action: string; 17 | condition: WitnessConditionJson; 18 | } 19 | 20 | export type WitnessRuleLike = EpicVaultLike; 21 | export class WitnessRule implements EpicVaultSerializable { 22 | public action: WitnessRuleAction; 23 | 24 | public condition: WitnessCondition; 25 | 26 | public get size(): number { 27 | return 1 + this.condition.size; 28 | } 29 | 30 | public static deserialize(ss: StringStream): WitnessRule { 31 | const action = parseEnum(parseInt(ss.read(1), 16), WitnessRuleAction); 32 | const condition = WitnessCondition.deserialize(ss); 33 | return new WitnessRule({ action, condition }); 34 | } 35 | 36 | public static fromJson(input: WitnessRuleJson): WitnessRule { 37 | return new WitnessRule(input); 38 | } 39 | constructor(input: Partial = {}) { 40 | this.action = 41 | input.action !== undefined 42 | ? parseEnum(input.action, WitnessRuleAction) 43 | : WitnessRuleAction.Deny; 44 | this.condition = 45 | input.condition !== undefined 46 | ? input.condition instanceof WitnessCondition 47 | ? input.condition 48 | : WitnessCondition.fromJson(input.condition) 49 | : new CalledByEntryWitnessCondition(); 50 | } 51 | 52 | public serialize(): string { 53 | return ( 54 | this.action.toString(16).padStart(2, "0") + this.condition.serialize() 55 | ); 56 | } 57 | 58 | public toJson(): WitnessRuleJson { 59 | return { 60 | action: WitnessRuleAction[this.action], 61 | condition: this.condition.toJson(), 62 | }; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/tx/components/WitnessScope.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to constrain witness to specified scope 3 | * The execution in vm of a script is kind of opaque, user could add scope on his signature to avoid abuse of signature 4 | */ 5 | export enum WitnessScope { 6 | None = 0, 7 | 8 | /** 9 | * CalledByEntry means that this condition must hold: EntryScriptHash == CallingScriptHash 10 | * No params is needed, as the witness/permission/signature given on first invocation will automatically expire if entering deeper internal invokes 11 | * This can be default safe choice for native EpicChain/EpicPulse (previously used on EpicChain as "attach" mode) 12 | */ 13 | CalledByEntry = 1 << 0, 14 | 15 | /** 16 | * Custom hash for contract-specific 17 | */ 18 | CustomContracts = 1 << 4, 19 | 20 | /** 21 | * Custom pubkey for group members, group can be found in contract manifest 22 | */ 23 | CustomGroups = 1 << 5, 24 | 25 | /** 26 | * Custom rules for witness to adhere by. 27 | */ 28 | WitnessRules = 1 << 6, 29 | 30 | /** 31 | * Global allows this witness in all contexts (default EpicChain behavior) 32 | * This cannot be combined with other flags 33 | */ 34 | Global = 1 << 7, 35 | } 36 | 37 | export function parse(stringFlags: string): WitnessScope { 38 | const flags = stringFlags.split(/\,/g); 39 | return flags.reduce( 40 | (p, c) => p | WitnessScope[c.trim() as keyof typeof WitnessScope], 41 | WitnessScope.None 42 | ); 43 | } 44 | 45 | function getEnums(): WitnessScope[] { 46 | return Object.values(WitnessScope).filter( 47 | (k) => typeof k === "number" 48 | ) as WitnessScope[]; 49 | } 50 | 51 | export function toString(flags: WitnessScope): string { 52 | if (flags === WitnessScope.None) { 53 | return "None"; 54 | } 55 | return getEnums() 56 | .filter((f) => flags & f) 57 | .map((f) => WitnessScope[f]) 58 | .join(","); 59 | } 60 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/tx/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./TransactionAttribute"; 2 | export * from "./Witness"; 3 | export * from "./Signer"; 4 | export * from "./WitnessScope"; 5 | export * from "./WitnessRule"; 6 | export * from "./WitnessCondition"; 7 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/tx/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./components"; 2 | export * from "./transaction"; 3 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/tx/transaction/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Transaction"; 2 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/basic/base64.ts: -------------------------------------------------------------------------------- 1 | import { enc } from "crypto-js"; 2 | 3 | export function hex2base64(input: string): string { 4 | return enc.Base64.stringify(enc.Hex.parse(input)); 5 | } 6 | 7 | export function base642hex(input: string): string { 8 | return enc.Base64.parse(input).toString(enc.Hex); 9 | } 10 | 11 | export function utf82base64(input: string): string { 12 | return enc.Base64.stringify(enc.Utf8.parse(input)); 13 | } 14 | 15 | export function base642utf8(input: string): string { 16 | return enc.Base64.parse(input).toString(enc.Utf8); 17 | } 18 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/basic/hash.ts: -------------------------------------------------------------------------------- 1 | import hexEncoding from "crypto-js/enc-hex"; 2 | import RIPEMD160 from "crypto-js/ripemd160"; 3 | import SHA256 from "crypto-js/sha256"; 4 | 5 | function hash( 6 | hex: string, 7 | hashingFunction: ( 8 | i: CryptoJS.lib.WordArray | string 9 | ) => CryptoJS.lib.WordArray 10 | ): string { 11 | const hexEncoded = hexEncoding.parse(hex); 12 | const result = hashingFunction(hexEncoded); 13 | return result.toString(hexEncoding); 14 | } 15 | 16 | /** 17 | * Performs a single SHA256. 18 | */ 19 | export function sha256(hex: string): string { 20 | return hash(hex, SHA256); 21 | } 22 | 23 | /** 24 | * Performs a single RIPEMD160. 25 | */ 26 | export function ripemd160(hex: string): string { 27 | return hash(hex, RIPEMD160); 28 | } 29 | 30 | /** 31 | * Performs a SHA256 followed by a RIPEMD160. 32 | */ 33 | export function hash160(hex: string): string { 34 | const sha = sha256(hex); 35 | return ripemd160(sha); 36 | } 37 | 38 | /** 39 | * Performs 2 SHA256. 40 | */ 41 | export function hash256(hex: string): string { 42 | const firstSha = sha256(hex); 43 | return sha256(firstSha); 44 | } 45 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/basic/hex.ts: -------------------------------------------------------------------------------- 1 | const hexRegex = /^([0-9A-Fa-f]{2})*$/; 2 | 3 | /** 4 | * Checks if input is a hexstring. Empty string is considered a hexstring. 5 | */ 6 | export function isHex(str: string): boolean { 7 | try { 8 | return hexRegex.test(str); 9 | } catch (err) { 10 | return false; 11 | } 12 | } 13 | 14 | /** 15 | * Remove the 0x prefix. 16 | */ 17 | export function remove0xPrefix(str: string): string { 18 | if (str.startsWith("0x")) { 19 | str = str.substring(2); 20 | } 21 | 22 | return str; 23 | } 24 | 25 | /** 26 | * Throws an error if input is not hexstring. 27 | */ 28 | export function ensureHex(str: string): void { 29 | if (!isHex(str)) { 30 | throw new Error(`Expected a hexstring but got ${str}`); 31 | } 32 | } 33 | 34 | /** 35 | * Reverses a HEX string, treating 2 chars as a byte. 36 | * 37 | * @example 38 | * reverseHex('abcdef') = 'efcdab' 39 | */ 40 | export function reverseHex(hex: string): string { 41 | ensureHex(hex); 42 | let out = ""; 43 | for (let i = hex.length - 2; i >= 0; i -= 2) { 44 | out += hex.substr(i, 2); 45 | } 46 | return out; 47 | } 48 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/basic/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./curve"; 2 | export * from "./hash"; 3 | export * from "./random"; 4 | export * from "./hex"; 5 | export * from "./base64"; 6 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/basic/random.ts: -------------------------------------------------------------------------------- 1 | import { lib } from "crypto-js"; 2 | /** 3 | * Generates a arrayBuffer filled with random bytes. 4 | * @param length - length of buffer. 5 | */ 6 | export const generateRandomArray = (length: number): number[] => { 7 | // Round up to nearest multiple of 4 so that the words generated is more than what we need. 8 | const numberOfWords = length % 4 === 0 ? length : length + (length % 4); 9 | 10 | // This converts the generated words into a hexstring. 11 | const wordArray = lib.WordArray.random(numberOfWords).toString(); 12 | 13 | // Chunk the hexstring into chunks of 2 which represents 1 byte each 14 | const hexStrings = wordArray.substr(0, length * 2).match(/.{1,2}/g) || []; 15 | return hexStrings.map((hexstr) => parseInt(hexstr, 16)); 16 | }; 17 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./basic"; 2 | export * from "./misc"; 3 | export * from "./convert"; 4 | export * from "./StringStream"; 5 | export * from "./HexString"; 6 | export * from "./BigInteger"; 7 | export * from "./serialize"; 8 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/misc.ts: -------------------------------------------------------------------------------- 1 | import { ab2hexstring } from "./convert"; 2 | import { ensureHex } from "./basic"; 3 | 4 | /** 5 | * XORs two hexstrings 6 | * 7 | * @param str1 - HEX string 8 | * @param str2 - HEX string 9 | * @returns XOR output as a HEX string 10 | */ 11 | export function hexXor(str1: string, str2: string): string { 12 | ensureHex(str1); 13 | ensureHex(str2); 14 | if (str1.length !== str2.length) { 15 | throw new Error( 16 | `strings are disparate lengths. Inputs are of length ${str1.length} and ${str2.length}` 17 | ); 18 | } 19 | const result = []; 20 | for (let i = 0; i < str1.length; i += 2) { 21 | result.push( 22 | // tslint:disable-next-line:no-bitwise 23 | parseInt(str1.substr(i, 2), 16) ^ parseInt(str2.substr(i, 2), 16) 24 | ); 25 | } 26 | return ab2hexstring(result); 27 | } 28 | 29 | /** 30 | * Reverses an array. 31 | * 32 | * @example 33 | * reverseArray('abcd') = 'dcba' 34 | */ 35 | export function reverseArray(arr: ArrayLike): T[] { 36 | if (typeof arr !== "object" || !arr.length) { 37 | throw new Error("reverseArray expects an array"); 38 | } 39 | const result = new Array(arr.length); 40 | for (let i = 0; i < arr.length; i++) { 41 | result[i] = arr[arr.length - 1 - i]; 42 | } 43 | return result; 44 | } 45 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/u/serialize.ts: -------------------------------------------------------------------------------- 1 | import { num2VarInt } from "./convert"; 2 | import { HexString } from "./HexString"; 3 | import { StringStream } from "./StringStream"; 4 | export interface EpicVaultSerializable { 5 | size: number; 6 | serialize: () => string; 7 | } 8 | type Serializables = number | HexString | EpicVaultSerializable[]; 9 | /** 10 | * Calculates the byte size of any supported input following NEO's variable int format. 11 | */ 12 | export function getSerializedSize(value: Serializables): number { 13 | switch (typeof value) { 14 | case "number": { 15 | if (value < 0xfd) return 1; 16 | else if (value <= 0xffff) return 3; 17 | else return 5; 18 | } 19 | case "object": { 20 | if (value instanceof HexString) { 21 | const size = value.byteLength; 22 | return getSerializedSize(size) + size; 23 | } else if (Array.isArray(value)) { 24 | let size = 0; 25 | if (value.length > 0) { 26 | if ( 27 | typeof value[0].size === "number" && 28 | typeof value[0].serialize === "function" 29 | ) { 30 | size = value 31 | .map((item) => item.size) 32 | .reduce((prev, curr) => prev + curr, 0); 33 | } 34 | } 35 | return getSerializedSize(value.length) + size; 36 | } 37 | // do not break here so we fall through to the default 38 | } 39 | default: 40 | throw new Error("Unsupported value type: " + typeof value); 41 | } 42 | } 43 | 44 | export function deserializeArrayOf( 45 | type: (ss: StringStream) => T, 46 | ss: StringStream 47 | ): T[] { 48 | const output = []; 49 | const len = ss.readVarInt(); 50 | for (let i = 0; i < len; i++) { 51 | output.push(type(ss)); 52 | } 53 | return output; 54 | } 55 | 56 | export function serializeArrayOf(prop: (EpicVaultSerializable | string)[]): string { 57 | return ( 58 | num2VarInt(prop.length) + 59 | prop.map((p) => (typeof p === "string" ? p : p.serialize())).join("") 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/wallet/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Account"; 2 | export * from "./core"; 3 | export * from "./xep2"; 4 | export * from "./verify"; 5 | export * from "./signing"; 6 | export * from "./Wallet"; 7 | export * from "./multisig"; 8 | export * from "./upgrade"; 9 | -------------------------------------------------------------------------------- /packages/epicvault-core/src/wallet/upgrade.ts: -------------------------------------------------------------------------------- 1 | import Account from "./Account"; 2 | import { decryptEpicChain } from "./xep2"; 3 | import { DEFAULT_SCRYPT } from "../consts"; 4 | 5 | /** 6 | * Upgrades a epicchain account to a epicchain account. If an encrypted account is provided, the returned account is also encrypted with the same passphrase. 7 | */ 8 | export async function upgrade( 9 | account: Account, 10 | passphrase = "", 11 | scryptParams = DEFAULT_SCRYPT 12 | ): Promise { 13 | // Checks that account is upgradable 14 | if (!account.tryGet("privateKey") && passphrase === "") { 15 | throw new Error(`The account needs an unencrypted private key.`); 16 | } 17 | // Check if address is epicchain style (Starts with A) 18 | if (!account.address.startsWith("A")) { 19 | throw new Error(`This is not a epicchain Address.`); 20 | } 21 | 22 | if (passphrase) { 23 | const wifKey = await decryptEpicChain( 24 | account.encrypted, 25 | passphrase, 26 | scryptParams 27 | ); 28 | const epicchainAccount = new Account(wifKey); 29 | return await epicchainAccount.encrypt(passphrase, scryptParams); 30 | } 31 | 32 | const wifKey = account.WIF; 33 | const epicchainAccount = new Account(wifKey); 34 | return epicchainAccount; 35 | } 36 | -------------------------------------------------------------------------------- /packages/epicvault-core/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Neon Browser Test 7 | 8 | 9 | 10 |
11 |
12 |

13 | Open Console 14 |

15 |
16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/epicvault-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib" 6 | }, 7 | // default include without extensions only includes typescript stuff 8 | "include": ["src/**/*", "src/**/*.json"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/epicvault-core/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const TerserPlugin = require("terser-webpack-plugin"); 4 | const common = require("../../webpack.common"); 5 | const base = common(__dirname); 6 | module.exports = function () { 7 | const nodeOutput = Object.assign({}, base, { 8 | target: "node", 9 | output: { 10 | path: path.resolve(__dirname, "dist"), 11 | filename: "index.js", 12 | libraryTarget: "commonjs2", 13 | }, 14 | }); 15 | nodeOutput.optimization = Object.assign({}, nodeOutput.optimization, { 16 | minimize: false, 17 | }); 18 | 19 | const webOutput = Object.assign({}, base, { 20 | target: "web", 21 | output: { 22 | path: path.resolve(__dirname, "dist"), 23 | filename: "browser.js", 24 | libraryTarget: "umd", 25 | library: "NeonCore", // This is the var name in browser 26 | }, 27 | plugins: [ 28 | new webpack.ProvidePlugin({ 29 | Buffer: ["buffer", "Buffer"], 30 | }), 31 | ], 32 | optimization: { 33 | minimizer: [ 34 | new TerserPlugin({ 35 | terserOptions: { 36 | format: { 37 | ascii_only: true, 38 | }, 39 | }, 40 | }), 41 | ], 42 | }, 43 | }); 44 | 45 | return [nodeOutput, webOutput]; 46 | }; 47 | -------------------------------------------------------------------------------- /packages/epicvault-js/__integration__/experimental/contract3.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "contract3", 3 | "groups": [], 4 | "features": {}, 5 | "abi": { 6 | "methods": [ 7 | { 8 | "name": "test_func", 9 | "offset": 2, 10 | "parameters": [], 11 | "returntype": "Integer", 12 | "safe": false 13 | }, 14 | { 15 | "name": "test_func2", 16 | "offset": 4, 17 | "parameters": [ 18 | { 19 | "name": "value", 20 | "type": "Integer" 21 | } 22 | ], 23 | "returntype": "Integer", 24 | "safe": false 25 | } 26 | ], 27 | "events": [] 28 | }, 29 | "permissions": [ 30 | { 31 | "contract": "*", 32 | "methods": "*" 33 | } 34 | ], 35 | "trusts": [], 36 | "supportedstandards": [], 37 | "extra": null 38 | } 39 | -------------------------------------------------------------------------------- /packages/epicvault-js/__integration__/experimental/contract3.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicvault-js/3efdf0390443d70164a3d69aab44857ca76fbb61/packages/epicvault-js/__integration__/experimental/contract3.nef -------------------------------------------------------------------------------- /packages/epicvault-js/__integration__/experimental/contract3.py: -------------------------------------------------------------------------------- 1 | from boa3.builtin import public 2 | 3 | def main() -> int: 4 | return 1 5 | 6 | @public 7 | def test_func() -> int: 8 | return 2 9 | 10 | @public 11 | def test_func2(value: int) -> int: 12 | return 1 + value -------------------------------------------------------------------------------- /packages/epicvault-js/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "../../api-extractor-base.json" 4 | } -------------------------------------------------------------------------------- /packages/epicvault-js/jest.config.js: -------------------------------------------------------------------------------- 1 | const config = require("../../jest.config"); 2 | config.globals["ts-jest"]["tsconfig"] = "../../tsconfig-test.json"; 3 | module.exports = config; 4 | -------------------------------------------------------------------------------- /packages/epicvault-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epicchain/epicvault-js", 3 | "description": "The EpicVault-JS SDK is a powerful JavaScript software development kit designed for seamless interaction with the EpicChain blockchain.", 4 | "version": "1.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/epicchainlabs/epicvault-js.git" 8 | }, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "keywords": [ 13 | "epicchain", 14 | "xmoohad", 15 | "javascript", 16 | "libraries" 17 | ], 18 | "author": "xmoohad (https://github.com/xmoohad)", 19 | "license": "MIT", 20 | "main": "dist/index.js", 21 | "browser": "dist/browser.js", 22 | "types": "lib/index.d.ts", 23 | "scripts": { 24 | "ae": "api-extractor run --local", 25 | "build": "tsc -b", 26 | "clean": "rimraf ./lib ./dist ./temp tsconfig.tsbuildinfo", 27 | "dist": "cross-env NODE_ENV=development webpack --mode development", 28 | "dist:prod": "cross-env NODE_ENV=production webpack --mode production", 29 | "prepublishOnly": "npm run clean && npm run build && npm run dist:prod", 30 | "lint": "eslint src/**/*.ts __tests__/**/*.ts __integration__/**/*.ts", 31 | "pretty": "prettier --write --loglevel=warn \"./{src,__{tests,integration}__}/**/*.ts\"" 32 | }, 33 | "dependencies": { 34 | "@epicchain/epicvault-api": "^1.0.0", 35 | "@epicchain/epicvault-core": "^1.0.1" 36 | }, 37 | "files": [ 38 | "dist/", 39 | "lib/" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /packages/epicvault-js/src/experimental/index.ts: -------------------------------------------------------------------------------- 1 | import * as nep17 from "./xep17"; 2 | import { SmartContract } from "./contract"; 3 | import { 4 | getSystemFee, 5 | calculateNetworkFee, 6 | setBlockExpiry, 7 | addFees, 8 | deployContract, 9 | getContractHash, 10 | } from "./helpers"; 11 | 12 | const txHelpers = { 13 | getSystemFee, 14 | calculateNetworkFee, 15 | setBlockExpiry, 16 | addFees, 17 | }; 18 | 19 | export { nep17, txHelpers, SmartContract, deployContract, getContractHash }; 20 | -------------------------------------------------------------------------------- /packages/epicvault-js/src/experimental/types.ts: -------------------------------------------------------------------------------- 1 | import { u, wallet } from "@epicchain/epicvault-core"; 2 | export interface CommonConfig { 3 | networkMagic: number; 4 | rpcAddress: string; 5 | /** 6 | * Extra GAS added to the networkFee to prioritise the transaction in the 7 | * memory pool. Cannot be used in combination with `networkFeeOverride` 8 | */ 9 | prioritisationFee?: number; 10 | blocksTillExpiry?: number; 11 | account?: wallet.Account; 12 | 13 | networkFeeOverride?: u.BigInteger; 14 | systemFeeOverride?: u.BigInteger; 15 | } 16 | -------------------------------------------------------------------------------- /packages/epicvault-js/src/experimental/xep17/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./base"; 2 | -------------------------------------------------------------------------------- /packages/epicvault-js/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Neon Browser Test 7 | 8 | 9 | 10 |
11 |
12 |

13 | Open Console 14 |

15 |
16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/epicvault-js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib" 6 | }, 7 | "references": [ 8 | { "path": "../epicvault-core" }, 9 | { "path": "../epicvault-api" } 10 | ], 11 | "include": ["src/**/*"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/epicvault-js/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const TerserPlugin = require("terser-webpack-plugin"); 4 | const common = require("../../webpack.common"); 5 | const base = common(__dirname); 6 | module.exports = function () { 7 | const nodeOutput = Object.assign({}, base, { 8 | target: "node", 9 | output: { 10 | path: path.resolve(__dirname, "dist"), 11 | filename: "index.js", 12 | libraryTarget: "commonjs2", 13 | }, 14 | }); 15 | nodeOutput.optimization = Object.assign({}, nodeOutput.optimization, { 16 | minimize: false, 17 | }); 18 | 19 | const webOutput = Object.assign({}, base, { 20 | target: "web", 21 | output: { 22 | path: path.resolve(__dirname, "dist"), 23 | filename: "browser.js", 24 | libraryTarget: "umd", 25 | library: "Neon", // This is the var name in browser 26 | }, 27 | plugins: [ 28 | new webpack.ProvidePlugin({ 29 | Buffer: ["buffer", "Buffer"], 30 | }), 31 | ], 32 | optimization: { 33 | minimizer: [ 34 | new TerserPlugin({ 35 | terserOptions: { 36 | format: { 37 | ascii_only: true, 38 | }, 39 | }, 40 | }), 41 | ], 42 | }, 43 | }); 44 | 45 | return [nodeOutput, webOutput]; 46 | }; 47 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/__tests__/BIP44.ts: -------------------------------------------------------------------------------- 1 | import BIP44 from "../src/BIP44"; 2 | 3 | const BIP44_PURPOSE = "8000002C"; 4 | const NEO_COINTYPE = "80000378"; 5 | 6 | test("Defaults to zeroth address", () => { 7 | const result = BIP44(); 8 | expect(result.length).toBe(40); 9 | const portions = result.match(/.{1,8}/g); 10 | expect(portions[0]).toEqual(BIP44_PURPOSE); 11 | expect(portions[1]).toEqual(NEO_COINTYPE); 12 | expect(portions[2]).toEqual("80000000"); 13 | expect(portions[3]).toEqual("00000000"); 14 | expect(portions[4]).toEqual("00000000"); 15 | }); 16 | 17 | test("Produces a string with the correct numbers", () => { 18 | const randInt = (): number => Math.floor(Math.random() * 100); 19 | const account = randInt(); 20 | const change = randInt(); 21 | const address = randInt(); 22 | 23 | const result = BIP44(address, change, account); 24 | expect(result.length).toBe(40); 25 | const portions = result.match(/.{1,8}/g); 26 | expect(portions[0]).toEqual(BIP44_PURPOSE); 27 | expect(portions[1]).toEqual(NEO_COINTYPE); 28 | expect(parseInt(portions[2], 16)).toEqual(0x80000000 + account); 29 | expect(parseInt(portions[3], 16)).toEqual(change); 30 | expect(parseInt(portions[4], 16)).toEqual(address); 31 | }); 32 | 33 | test("Errors when given negative number", () => { 34 | expect(() => BIP44(-1)).toThrow(/invalid input/); 35 | }); 36 | 37 | test("Errors when given non-integer", () => { 38 | expect(() => BIP44(1.1)).toThrow(/invalid input/); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "../../api-extractor-base.json" 4 | } -------------------------------------------------------------------------------- /packages/epicvault-ledger/jest.config.js: -------------------------------------------------------------------------------- 1 | const config = require("../../jest.config"); 2 | config.globals["ts-jest"]["tsconfig"] = "../../tsconfig-test.json"; 3 | module.exports = config; 4 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epicchain/epicvault-ledger", 3 | "description": "EpicVault Ledger Integration for EpicVault.js enables secure and seamless hardware wallet support within the EpicVault ecosystem.", 4 | "version": "1.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/epicchainlabs/epicvault-js.git" 8 | }, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "keywords": [ 13 | "epicchain", 14 | "xmoohad", 15 | "javascript", 16 | "libraries" 17 | ], 18 | "author": "xmoohad (https://github.com/xmoohad)", 19 | "license": "MIT", 20 | "main": "dist/index.js", 21 | "module": "lib/index.js", 22 | "types": "lib/index.d.ts", 23 | "scripts": { 24 | "ae": "api-extractor run --local", 25 | "build": "tsc -b", 26 | "dist": "tsc -m commonjs --outDir dist", 27 | "dist:prod": "tsc -m commonjs --outDir dist", 28 | "clean": "rimraf ./lib ./dist ./temp tsconfig.tsbuildinfo", 29 | "prepublishOnly": "npm run clean && npm run build && npm run dist:prod", 30 | "lint": "eslint src/**/*.ts __tests__/**/*.ts", 31 | "pretty": "prettier --write --loglevel=warn \"./{src,__{tests,integration}__}/**/*.ts\"", 32 | "start": "jest --watch", 33 | "test": "jest", 34 | "test:integration": "jest /packages/.*/__integration__/.*", 35 | "test:unit": "jest /packages/.*/__tests__/.*", 36 | "test:node": "node test.node.js" 37 | }, 38 | "dependencies": { 39 | "@ledgerhq/hw-transport": "6.28.1", 40 | "@types/ledgerhq__hw-transport": "4.21.4", 41 | "@types/lodash": "^4.14.191", 42 | "lodash": "4.17.21" 43 | }, 44 | "peerDependencies": { 45 | "@epicchain/epicvault-core": "^1.0.1" 46 | }, 47 | "files": [ 48 | "lib/", 49 | "typings/" 50 | ], 51 | "devDependencies": { 52 | "@epicchain/epicvault-js": "^1.0.0", 53 | "@ledgerhq/hw-transport-node-hid": "6.27.12", 54 | "@ledgerhq/hw-transport-u2f": "5.36.0-deprecated", 55 | "@types/ledgerhq__hw-transport-node-hid": "4.22.2" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/src/BIP44.ts: -------------------------------------------------------------------------------- 1 | function assertPositiveInteger(input: number, inputName: string): void { 2 | if (!Number.isInteger(input) || input < 0) { 3 | throw new Error(`${input} is an invalid input for ${inputName}`); 4 | } 5 | } 6 | 7 | function to8BitHex(num: number): string { 8 | const hex = num.toString(16); 9 | return "0".repeat(8 - hex.length) + hex; 10 | } 11 | 12 | /** 13 | * Returns a BIP44 string specific to EpicChain. 14 | */ 15 | export function BIP44(address = 0, change = 0, account = 0): string { 16 | assertPositiveInteger(address, "address"); 17 | assertPositiveInteger(change, "change"); 18 | assertPositiveInteger(account, "account"); 19 | const accountHex = to8BitHex(account + 0x80000000); 20 | const changeHex = to8BitHex(change); 21 | const addressHex = to8BitHex(address); 22 | return "8000002C" + "80000378" + accountHex + changeHex + addressHex; 23 | } 24 | 25 | export default BIP44; 26 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/src/index.ts: -------------------------------------------------------------------------------- 1 | import { LedgerManager, LedgerConfig, LedgerInfo, AppConfig } from "./features"; 2 | import { BIP44 } from "./BIP44"; 3 | import { StatusWord, evalTransportError, TransportStatusError, looksLikeTransportStatusError } from "./ErrorCode"; 4 | import { DerToHexSignature } from "./utils"; 5 | 6 | export { 7 | LedgerManager, 8 | LedgerConfig, 9 | LedgerInfo, 10 | AppConfig, 11 | BIP44, 12 | StatusWord, 13 | evalTransportError, 14 | TransportStatusError, 15 | looksLikeTransportStatusError, 16 | DerToHexSignature, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { u } from "@epicchain/epicvault-core"; 2 | 3 | /** 4 | * Converts a signature in DER format to HEX format. 5 | * @param response - signature in DER format 6 | * @returns Signature in HEX format (64 bytes) 7 | */ 8 | export function DerToHexSignature(response: string): string { 9 | const ss = new u.StringStream(response); 10 | // The first byte is format. It is usually 0x30 (SEQ) or 0x31 (SET) 11 | // The second byte represents the total length of the DER module. 12 | ss.read(2); 13 | // Now we read each field off 14 | // Each field is encoded with a type byte, length byte followed by the data itself 15 | ss.read(1); // Read and drop the type 16 | const r = ss.readVarBytes(); 17 | ss.read(1); 18 | const s = ss.readVarBytes(); 19 | 20 | // We will need to ensure both integers are 32 bytes long 21 | const integers = [r, s].map((i) => { 22 | if (i.length < 64) { 23 | i = "0".repeat(i.length - 64) + i; 24 | } 25 | if (i.length > 64) { 26 | i = i.substr(-64); 27 | } 28 | return i; 29 | }); 30 | 31 | return integers.join(""); 32 | } 33 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/test.node.js: -------------------------------------------------------------------------------- 1 | const nodeLedger = require("@ledgerhq/hw-transport-node-hid").default; 2 | const ledger = require("@cityofzion/neon-ledger").default; 3 | const neon = require("@cityofzion/neon-js"); 4 | 5 | const neonJs = { ...neon, ledger }; 6 | const addressNumber = 0; 7 | 8 | const neoscan = new neonJs.api.neoscan.instance("TestNet"); 9 | 10 | let ledgerInstance = null; 11 | 12 | neonJs.ledger 13 | .getDevicePaths(nodeLedger) 14 | .then((paths) => { 15 | console.log("\n\n ---Ledger devices---"); 16 | console.log(paths); 17 | ledgerInstance = nodeLedger.open(paths[0]); 18 | return ledgerInstance; 19 | }) 20 | .then((ledger) => { 21 | ledgerInstance = ledger; 22 | const bip = neonJs.ledger.BIP44(addressNumber); 23 | console.log("\n\n ---BIP44 String---"); 24 | console.log(bip); 25 | return neonJs.ledger.getPublicKey(ledger, bip); 26 | }) 27 | .then((key) => { 28 | console.log("\n\n ---Public Key---"); 29 | console.log(key); 30 | return key; 31 | }) 32 | .then((publicKey) => { 33 | return neonJs.api.sendAsset({ 34 | api: neoscan, 35 | account: new neonJs.wallet.Account(publicKey), 36 | intents: neonJs.api.makeIntent( 37 | { NEO: 1 }, 38 | "ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW" 39 | ), 40 | signingFunction: async (tx, pubKey) => { 41 | const sig = await neonJs.ledger.getSignature( 42 | ledgerInstance, 43 | tx, 44 | neonJs.ledger.BIP44(addressNumber) 45 | ); 46 | const witness = await neonJs.tx.Witness.fromSignature(sig, pubKey); 47 | return witness.serialize(); 48 | }, 49 | }); 50 | }) 51 | .then((sendAsset) => { 52 | console.log("\n\n---SendAsset---"); 53 | console.log(sendAsset.response); 54 | }) 55 | .catch((e) => { 56 | console.log(e); 57 | }); 58 | -------------------------------------------------------------------------------- /packages/epicvault-ledger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib" 6 | }, 7 | "references": [{ "path": "../epicvault-core" }], 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/epicvault-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "epicvault-test", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "license": "MIT", 7 | "private": true, 8 | "scripts": { 9 | "build": "tsc", 10 | "test": "node lib/index.js" 11 | }, 12 | "dependencies": { 13 | "@epicchain/epicvault": "^1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/epicvault-test/src/index.ts: -------------------------------------------------------------------------------- 1 | import { api, rpc } from "@epicchain/epicvault-js"; 2 | 3 | const RPC_URL = "https://testnet1-seed.epic-chain.org:20111"; 4 | 5 | const rpcClient = new rpc.RPCClient(RPC_URL); 6 | console.log("EpicChain Weather Report"); 7 | 8 | rpcClient 9 | .getBlockCount() 10 | .then((currentHeight) => console.log(`Blockchain height: ${currentHeight}`)) 11 | .then(() => api.getFeeInformation(rpcClient)) 12 | .then((feeInfo) => 13 | console.log( 14 | `Current fees: ${feeInfo.feePerByte} per byte, ${feeInfo.executionFeeFactor} multipler` 15 | ) 16 | ); 17 | -------------------------------------------------------------------------------- /packages/epicvault-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib", 6 | "module": "es6" 7 | }, 8 | "references": [{ "path": "../epicvault-core" }], 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/epicvault-uri/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "../../api-extractor-base.json" 4 | } -------------------------------------------------------------------------------- /packages/epicvault-uri/jest.config.js: -------------------------------------------------------------------------------- 1 | const config = require("../../jest.config"); 2 | config.globals["ts-jest"]["tsconfig"] = "../../tsconfig-test.json"; 3 | module.exports = config; 4 | -------------------------------------------------------------------------------- /packages/epicvault-uri/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epicchain/epicvault-uri", 3 | "description": "The EpicVault-uri Module is a specialized component within the EpicVault ecosystem designed to manage.", 4 | "version": "1.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/epicchainlabs/epicvault-js.git" 8 | }, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "keywords": [ 13 | "epicchain", 14 | "xmoohad", 15 | "javascript", 16 | "libraries" 17 | ], 18 | "author": "xmoohad (https://github.com/xmoohad)", 19 | "license": "MIT", 20 | "main": "dist/index.js", 21 | "module": "lib/index.js", 22 | "types": "lib/index.d.ts", 23 | "scripts": { 24 | "ae": "api-extractor run --local", 25 | "build": "tsc -b", 26 | "dist": "tsc -m commonjs --outDir dist", 27 | "dist:prod": "tsc -m commonjs --outDir dist", 28 | "clean": "rimraf ./lib ./dist ./temp tsconfig.tsbuildinfo", 29 | "prepublishOnly": "npm run clean && npm run build && npm run dist:prod", 30 | "lint": "eslint src/**/*.ts __tests__/**/*.ts __integration__/**/*.ts", 31 | "pretty": "prettier --write --loglevel=warn \"./{src,__{tests,integration}__}/**/*.ts\"", 32 | "start": "jest --watch", 33 | "test": "jest", 34 | "test:unit": "jest /packages/.*/__tests__/.*" 35 | }, 36 | "peerDependencies": { 37 | "@epicchain/epicvault-core": "^1.0.1" 38 | }, 39 | "files": [ 40 | "dist/", 41 | "lib/" 42 | ], 43 | "gitHead": "d21633d03deca1f4bc6c3a4f4e1d32a61aec2fe3" 44 | } 45 | -------------------------------------------------------------------------------- /packages/epicvault-uri/src/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a uri with voting intent. 3 | * @param publicKey - The candidate to vote for. 4 | */ 5 | export function createVoteUri(publicKey: string): string { 6 | return `epicchain:vote-${publicKey}`; 7 | } 8 | 9 | /** 10 | * Creates a uri to request token transfer. 11 | * @param toAddress - Receipent address of the tokens. 12 | * @param asset - 'epicpulse', 'epicpulse' or a contract scripthash. 13 | * @param amount - Amount of tokens to transfer in integer amounts. 14 | * 15 | * @example 16 | * 17 | * To request 1.23456789 EpicPulse to `NNWAo5vdVJz1oyCuNiaTBA3amBHnWCF4Yk`: 18 | * 19 | * ```ts 20 | * import {createPayUri} from "@epicchain/epicvault-uri"; 21 | * const uri = createPayUri("NNWAo5vdVJz1oyCuNiaTBA3amBHnWCF4Yk", "epicpulse", 123456789); 22 | * ``` 23 | * 24 | */ 25 | export function createPayUri( 26 | toAddress: string, 27 | asset: string, 28 | amount?: number 29 | ): string { 30 | let uri = `epicpulse:${toAddress}?asset=${asset}`; 31 | if (amount) { 32 | uri += `&amount=${amount}`; 33 | } 34 | 35 | return uri; 36 | } 37 | -------------------------------------------------------------------------------- /packages/epicvault-uri/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./create"; 2 | export * from "./parse"; 3 | export * from "./features"; 4 | -------------------------------------------------------------------------------- /packages/epicvault-uri/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib" 6 | }, 7 | "references": [{ "path": "../epicvault-core" }], 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eo pipefail 2 | FILES=$(git diff --name-only --diff-filter=bd $(git merge-base HEAD next) | grep '^packages/.*\.[tj]s$') 3 | echo $FILES 4 | exit 0 5 | -------------------------------------------------------------------------------- /testHelpers.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from "./packages/neon-core/src"; 2 | 3 | export const TESTNET_URLS = [ 4 | "http://seed1t4.neo.org:20332", 5 | "http://seed2t4.neo.org:20332", 6 | "http://seed3t4.neo.org:20332", 7 | "http://seed4t4.neo.org:20332", 8 | "http://seed5t4.neo.org:20332", 9 | ]; 10 | 11 | //Node17+ defaults to resolving IPv6 by default so localhost does not work anymore. 12 | export const LOCALNET_URLS = ["http://127.0.0.1:20332"]; 13 | 14 | export async function getIntegrationEnvUrl(): Promise { 15 | const urls = isTestNet() ? TESTNET_URLS : LOCALNET_URLS; 16 | return await getBestUrl(urls); 17 | } 18 | 19 | export function isTestNet(): boolean { 20 | return (global["__TARGETNET__"] as string).toLowerCase() === "testnet"; 21 | } 22 | export async function sleep(ms: number): Promise { 23 | return new Promise((resolve) => setTimeout(resolve, ms)); 24 | } 25 | 26 | export async function getBestUrl(urls: string[]): Promise { 27 | const data = await Promise.all(urls.map((url) => safelyCheckHeight(url))); 28 | const heights = data.map((h, i) => ({ height: h, url: urls[i] })); 29 | const best = heights.reduce( 30 | (bestSoFar, h) => (bestSoFar.height >= h.height ? bestSoFar : h), 31 | { height: -1, url: "" } 32 | ); 33 | if (!best.url) { 34 | throw new Error("No good endpoint found"); 35 | } 36 | return best.url; 37 | } 38 | 39 | async function safelyCheckHeight(url: string): Promise { 40 | try { 41 | const res = await rpc.sendQuery(url, rpc.Query.getBlockCount(), { 42 | timeout: 10000, 43 | }); 44 | return res.result; 45 | } catch (_e) { 46 | console.log("Error while checking RPC height:" + _e); 47 | return -1; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tsconfig-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2021", 4 | "lib": [ 5 | "es2021", 6 | "dom" 7 | ], 8 | "moduleResolution": "node", 9 | "composite": true, 10 | "declaration": true, 11 | "declarationMap": true, 12 | "strict": true, 13 | "esModuleInterop": true, 14 | "sourceMap": true, 15 | "resolveJsonModule": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "skipLibCheck": true, 18 | "incremental": true, 19 | "module": "commonjs", 20 | "outDir": "./dist", 21 | "rootDir": "./src", 22 | "baseUrl": ".", 23 | "paths": { 24 | "@/*": ["src/*"] 25 | } 26 | }, 27 | "exclude": [ 28 | "node_modules", 29 | "dist", 30 | "**/*.test.ts", 31 | "**/*.spec.ts" 32 | ] 33 | } -------------------------------------------------------------------------------- /tsconfig-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig-base.json", 3 | "exclude": ["packages/**/lib/**/*", "packages/**/dist/**/*"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "include": [], 4 | "references": [ 5 | { "path": "./packages/epicvault-core" }, 6 | { "path": "./packages/epicvault-api" }, 7 | { "path": "./packages/epicvault-uri" }, 8 | { "path": "./packages/epicvault-ledger"}, 9 | { "path": "./packages/epicvault-js" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "yarn build:guides &&docusaurus start", 4 | "build": "yarn build:guides && docusaurus build", 5 | "build:guides": "yarn --cwd ../examples run generate", 6 | "publish": "aws s3 sync ./build s3://docs-coz/neo3/neon-js --acl public-read", 7 | "release": "yarn build && yarn run publish", 8 | "swizzle": "docusaurus swizzle", 9 | "deploy": "docusaurus deploy", 10 | "docusaurus": "docusaurus", 11 | "build:api": "api-documenter markdown --input-folder ../common/api --output-folder ../docs/api" 12 | }, 13 | "dependencies": { 14 | "@docusaurus/core": "2.0.0-beta.17", 15 | "@docusaurus/plugin-client-redirects": "2.0.0-beta.17", 16 | "@docusaurus/preset-classic": "2.0.0-beta.17", 17 | "@microsoft/api-documenter": "^7.22.30", 18 | "clsx": "^1.1.1", 19 | "ljs2": "^2.0.3", 20 | "react": "^17.0.1", 21 | "react-dom": "^17.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /website/sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | docs: [ 3 | "overview", 4 | "installation", 5 | "structure", 6 | { 7 | Guides: [ 8 | { 9 | type: "autogenerated", 10 | dirName: "guides", 11 | }, 12 | ], 13 | }, 14 | { 15 | Changelog: [ 16 | { 17 | type: "autogenerated", 18 | dirName: "changelog", 19 | }, 20 | ], 21 | }, 22 | ], 23 | api: [ 24 | { 25 | type: "autogenerated", 26 | dirName: "api", 27 | }, 28 | ], 29 | }; 30 | -------------------------------------------------------------------------------- /website/src/css/customTheme.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --ifm-color-primary: #7836e7; 3 | --ifm-color-primary-dark: #671de4; 4 | --ifm-color-primary-darker: #611ad8; 5 | --ifm-color-primary-darkest: #5015b2; 6 | --ifm-color-primary-light: #894fea; 7 | --ifm-color-primary-lighter: #925cec; 8 | --ifm-color-primary-lightest: #ab82f0; 9 | } 10 | -------------------------------------------------------------------------------- /website/static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* your custom css */ 2 | 3 | @media only screen and (min-device-width: 360px) and (max-device-width: 736px) { 4 | } 5 | 6 | @media only screen and (min-width: 1024px) { 7 | } 8 | 9 | @media only screen and (max-width: 1023px) { 10 | } 11 | 12 | @media only screen and (min-width: 1400px) { 13 | } 14 | 15 | @media only screen and (min-width: 1500px) { 16 | } -------------------------------------------------------------------------------- /website/static/img/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicvault-js/3efdf0390443d70164a3d69aab44857ca76fbb61/website/static/img/console.png -------------------------------------------------------------------------------- /website/static/img/coz_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicvault-js/3efdf0390443d70164a3d69aab44857ca76fbb61/website/static/img/coz_med.png -------------------------------------------------------------------------------- /website/static/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicvault-js/3efdf0390443d70164a3d69aab44857ca76fbb61/website/static/img/favicon/favicon.ico -------------------------------------------------------------------------------- /website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Layer 1 7 | N 8 | N 9 | 10 | -------------------------------------------------------------------------------- /website/static/img/logo_full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Layer 1 7 | NEO 8 | NJS 9 | 10 | 11 | --------------------------------------------------------------------------------