├── .eslint.js
├── .eslintrc.js
├── .gitattributes
├── .github
├── CODEOWNERS
└── workflows
│ ├── build.yml
│ └── codeql.yml
├── .gitignore
├── LICENSE
├── README.md
├── lerna.json
├── package.json
├── packages
├── chains
│ ├── chains-bitcoin
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── APIs
│ │ │ │ ├── API.ts
│ │ │ │ ├── bitcoinDotCom.ts
│ │ │ │ ├── blockbook.ts
│ │ │ │ ├── blockchain.ts
│ │ │ │ ├── blockchair.ts
│ │ │ │ ├── blockstream.ts
│ │ │ │ ├── insight.ts
│ │ │ │ └── sochain.ts
│ │ │ ├── base.ts
│ │ │ ├── bitcoin.ts
│ │ │ ├── bitcoincash.ts
│ │ │ ├── declarations
│ │ │ │ └── declarations.d.ts
│ │ │ ├── digibyte.ts
│ │ │ ├── dogecoin.ts
│ │ │ ├── index.ts
│ │ │ ├── script
│ │ │ │ ├── index.ts
│ │ │ │ ├── opcodes.ts
│ │ │ │ └── script.ts
│ │ │ ├── utils
│ │ │ │ ├── bchaddrjs.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ │ └── zcash.ts
│ │ ├── test
│ │ │ ├── addressValidation.spec.ts
│ │ │ ├── bch.spec.ts
│ │ │ ├── broadcastTransaction.spec.ts
│ │ │ ├── btcAndZec.spec.ts
│ │ │ ├── digibyte.spec.ts
│ │ │ ├── getUTXOs.spec.ts
│ │ │ ├── script.spec.ts
│ │ │ └── utils.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
│ ├── chains-ethereum
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── arbitrum.ts
│ │ │ ├── avalanche.ts
│ │ │ ├── base.ts
│ │ │ ├── bsc.ts
│ │ │ ├── catalog.ts
│ │ │ ├── contracts
│ │ │ │ ├── ABIs
│ │ │ │ │ ├── BasicBridge.json
│ │ │ │ │ ├── ERC20.json
│ │ │ │ │ ├── GatewayRegistryV2.json
│ │ │ │ │ ├── LockGatewayV3.json
│ │ │ │ │ ├── MintGatewayV3.json
│ │ │ │ │ └── TransferWithLog.json
│ │ │ │ ├── index.ts
│ │ │ │ └── typechain
│ │ │ │ │ ├── BasicBridge.ts
│ │ │ │ │ ├── ERC20.ts
│ │ │ │ │ ├── GatewayRegistryV2.ts
│ │ │ │ │ ├── LockGatewayV3.ts
│ │ │ │ │ ├── MintGatewayV3.ts
│ │ │ │ │ ├── TransferWithLog.ts
│ │ │ │ │ └── common.ts
│ │ │ ├── ethereum.ts
│ │ │ ├── fantom.ts
│ │ │ ├── goerli.ts
│ │ │ ├── index.ts
│ │ │ ├── kava.ts
│ │ │ ├── moonbeam.ts
│ │ │ ├── optimism.ts
│ │ │ ├── polygon.ts
│ │ │ └── utils
│ │ │ │ ├── abi.ts
│ │ │ │ ├── errors.ts
│ │ │ │ ├── evmTxSubmitter.ts
│ │ │ │ ├── gatewayRegistry.ts
│ │ │ │ ├── generic.ts
│ │ │ │ ├── payloads
│ │ │ │ ├── evmAddressPayload.ts
│ │ │ │ ├── evmApprovalPayload.ts
│ │ │ │ ├── evmContractPayload.ts
│ │ │ │ ├── evmNoncePayload.ts
│ │ │ │ ├── evmParams.ts
│ │ │ │ └── evmTxPayload.ts
│ │ │ │ └── types.ts
│ │ ├── test
│ │ │ ├── abi.spec.ts
│ │ │ ├── assets.spec.ts
│ │ │ ├── initialization.spec.ts
│ │ │ ├── logs.spec.ts
│ │ │ └── utils.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
│ ├── chains-filecoin
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── filecoin.ts
│ │ │ ├── index.ts
│ │ │ └── utils
│ │ │ │ ├── declarations.d.ts
│ │ │ │ ├── deposit.ts
│ │ │ │ ├── filfox.ts
│ │ │ │ ├── lotus.ts
│ │ │ │ └── utils.ts
│ │ ├── test
│ │ │ ├── explorers.spec.ts
│ │ │ └── index.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
│ ├── chains-solana
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── declarations
│ │ │ │ └── declarations.d.ts
│ │ │ ├── index.ts
│ │ │ ├── layouts.ts
│ │ │ ├── networks.ts
│ │ │ ├── solana.ts
│ │ │ ├── solanaTxSubmitter.ts
│ │ │ ├── types
│ │ │ │ └── types.ts
│ │ │ ├── utils.ts
│ │ │ ├── utils
│ │ │ │ └── associatedTokenAccount.ts
│ │ │ └── wallet.ts
│ │ ├── test
│ │ │ ├── solana.spec.ts
│ │ │ └── utils.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
│ ├── chains-terra
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── api
│ │ │ │ ├── stakeId.ts
│ │ │ │ ├── terraDev.ts
│ │ │ │ └── types.ts
│ │ │ ├── index.ts
│ │ │ ├── terra.ts
│ │ │ └── utils.ts
│ │ ├── test
│ │ │ ├── index.spec.ts
│ │ │ └── utils.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
│ └── chains
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ ├── declarations
│ │ │ └── declarations.d.ts
│ │ └── index.ts
│ │ ├── test
│ │ ├── index.spec.ts
│ │ └── utils.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.module.json
├── mock-provider
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── MockChain.ts
│ │ ├── MockProvider.ts
│ │ ├── index.ts
│ │ └── utils.ts
│ ├── test
│ │ └── index.spec.ts
│ ├── tsconfig.json
│ └── tsconfig.module.json
├── provider
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ ├── methods
│ │ │ ├── index.ts
│ │ │ ├── ren_queryBlock.ts
│ │ │ ├── ren_queryBlockState.ts
│ │ │ ├── ren_queryConfig.ts
│ │ │ ├── ren_submitGateway.ts
│ │ │ └── ren_submitTx.ts
│ │ ├── provider.ts
│ │ ├── rpc
│ │ │ └── jsonRpc.ts
│ │ ├── rpcUrls.ts
│ │ ├── types
│ │ │ └── core.ts
│ │ └── unmarshal.ts
│ ├── test
│ │ ├── mockResponses
│ │ │ ├── ren_queryBlockState.json
│ │ │ ├── ren_queryState.json
│ │ │ └── selectPublicKey.json
│ │ ├── pack.spec.ts
│ │ └── selectPublicKey.spec.ts
│ ├── tsconfig.json
│ └── tsconfig.module.json
├── ren
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── gateway.ts
│ │ ├── gatewayTransaction.ts
│ │ ├── index.ts
│ │ ├── params.ts
│ │ ├── renVMTxSubmitter.ts
│ │ └── utils
│ │ │ ├── config.ts
│ │ │ ├── defaultTransactionHandler.ts
│ │ │ ├── fees.ts
│ │ │ ├── inputAndOutputTypes.ts
│ │ │ └── transactionEmitter.ts
│ ├── test
│ │ └── index.spec.ts
│ ├── tsconfig.json
│ └── tsconfig.module.json
└── utils
│ ├── README.md
│ ├── package.json
│ ├── src
│ ├── common.ts
│ ├── errors.ts
│ ├── index.ts
│ ├── internal
│ │ ├── assert.ts
│ │ ├── common.ts
│ │ ├── extractError.ts
│ │ ├── hashes.ts
│ │ ├── index.ts
│ │ ├── network.ts
│ │ └── sleep.ts
│ ├── libraries
│ │ ├── pack
│ │ │ ├── README.md
│ │ │ ├── binaryMarshal.ts
│ │ │ ├── common.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── unmarshal.ts
│ │ └── promiEvent
│ │ │ ├── LICENSE
│ │ │ └── index.ts
│ ├── pack
│ │ └── README.md
│ ├── renVMHashes.ts
│ ├── txSubmitter.ts
│ └── types
│ │ ├── chain.ts
│ │ ├── eventEmitter.ts
│ │ ├── index.ts
│ │ ├── logger.ts
│ │ ├── renNetwork.ts
│ │ ├── shard.ts
│ │ └── types.ts
│ ├── test
│ ├── assert.spec.ts
│ ├── common.spec.ts
│ ├── hash.spec.ts
│ ├── marshalPack.spec.ts
│ ├── renVMHashes.spec.ts
│ ├── signatureUtils.spec.ts
│ ├── txHash.spec.ts
│ └── workingtx.spec.ts
│ ├── tsconfig.json
│ └── tsconfig.module.json
├── test
├── gateway.spec.ts
├── index.ts
├── quickstart.spec.ts
├── simple.spec.ts
└── utils
│ ├── defaultGatewayHandler.ts
│ └── testUtils.ts
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.eslint.js:
--------------------------------------------------------------------------------
1 | .eslintrc.js
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @jazg @tok-kkk
2 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ${{ matrix.os }}
8 | strategy:
9 | matrix:
10 | node-version: [14.x, 16.x, 18.x]
11 | os: [ubuntu-latest, windows-latest]
12 | name: Build on ${{ matrix.os }} with Node.js ${{ matrix.node-version }}
13 | steps:
14 | - uses: actions/checkout@v2
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v2
17 | with:
18 | node-version: ${{ matrix.node-version }}
19 | cache: "yarn"
20 | - name: Install dependencies
21 | run: |
22 | yarn install --network-concurrency 1
23 | - name: Lint
24 | run: |
25 | yarn lint
26 | - name: Build
27 | run: |
28 | yarn build
29 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master, release/* ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '25 6 * * 6'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 |
52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53 | # queries: security-extended,security-and-quality
54 |
55 |
56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57 | # If this step fails, then you should remove it and run the build manually (see below)
58 | - name: Autobuild
59 | uses: github/codeql-action/autobuild@v2
60 |
61 | # ℹ️ Command-line programs to run using the OS shell.
62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63 |
64 | # If the Autobuild fails above, remove it and uncomment the following three lines.
65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66 |
67 | # - run: |
68 | # echo "Run, Build Application using script"
69 | # ./location_of_script_within_repo/buildscript.sh
70 |
71 | - name: Perform CodeQL Analysis
72 | uses: github/codeql-action/analyze@v2
73 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Any file in src or build will get pushed to npm
2 | !src
3 | build
4 |
5 | # Environment variables/secrets
6 | *.env
7 |
8 | # Typedoc output
9 | docs
10 |
11 | # NPM/Yarn files
12 | node_modules
13 | package-lock.json
14 | .npmrc
15 | .yarnrc
16 | .yarn
17 | lerna-debug.log
18 | yarn-error.log
19 | .cache
20 |
21 | # Misc. logs
22 | *.log
23 |
24 | # Coverage
25 | .nyc_output
26 | coverage
27 | reports
28 |
29 | # IDE/OS specific
30 | .vscode
31 | .idea
32 | .dir-locals.el
33 | .editorconfig
34 | .DS_Store
35 |
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Ren Project
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # `🛠️ ren-js`
2 |
3 | [](https://www.npmjs.com/package/@renproject/ren)
4 |
5 | The official Javascript SDK for interacting with [RenVM](https://renproject.io).
6 |
7 | ```sh
8 | yarn add @renproject/ren @renproject/chains
9 | ```
10 |
11 | ## Docs
12 |
13 | See [Ren Client Docs](https://renproject.github.io/ren-client-docs/ren-js/)
14 |
15 | ## RenJS v3
16 |
17 | RenJS v3 is currently available as an alpha release:
18 |
19 | ```sh
20 | yarn add @renproject/ren @renproject/chains
21 | ```
22 |
23 | [RenJS v3 Docs](https://renproject.github.io/ren-client-docs/ren-js/ren-js-v3) (WIP)
24 |
25 | ## Changelog
26 |
27 | See the [Releases page](https://github.com/renproject/ren-js/releases).
28 |
29 | ## Package list
30 |
31 | - [`ren`](./packages/ren) - Javascript SDK for interacting with RenVM.
32 | - [`provider`](./packages/provider) - JSON-RPC provider.
33 | - [`utils`](./packages/utils) - Helper functions used by the other packages.
34 | - [`mock-provider`](./packages/mock-provider) - For testing locally with Ganache/Hardhat
35 | - chains, for enabling support for blockchains and assets:
36 | - - [`chains-bitcoin`](./packages/chains/chains-bitcoin) - Bitcoin and Bitcoin forks
37 | - - [`chains-ethereum`](./packages/chains/chains-ethereum) - Ethereum and other EVM chains
38 | - - [`chains-terra`](./packages/chains/chains-terra) - Terra/LUNA
39 | - - [`chains-filecoin`](./packages/chains/chains-filecoin) - Filecoin
40 | - - [`chains-solana`](./packages/chains/chains-solana) - Solana
41 | - - [`chains`](./packages/chains/chains) - Combines all of the above chains into one package
42 |
43 |
44 |
45 |
46 | Developer docs - click to expand
47 |
48 |
49 |
50 | ## Developing locally
51 |
52 | ```sh
53 | # Clone repository
54 | git clone git@github.com:renproject/ren-js.git && cd ren-js
55 |
56 | # Install dependencies
57 | yarn
58 |
59 | # Build every package
60 | yarn run build
61 | ```
62 |
63 | ## Linking
64 |
65 | If you want to use your local version of RenJS in another repository, run
66 |
67 | ```sh
68 | # In the ren-js repository
69 | yarn run link:all
70 | ```
71 |
72 | You can now link it to any other local repository by running:
73 |
74 | ```sh
75 | # In other local repositories
76 | yarn link @renproject/ren @renproject/chains @renproject/utils @renproject/provider
77 | ```
78 |
79 | ## Running tests
80 |
81 | You'll need to:
82 |
83 | 1. Generate a mnemonic and send ETH (goerli for testnet) (path: `m/44'/60'/0'/0/`).
84 | - `let w = require("ethers").Wallet.createRandom(); console.debug(w.address, w.mnemonic.phrase);`
85 | 2. Generate a private key and send testnet crypto funds.
86 | - `require("send-crypto").newPrivateKey();`
87 | 3. Optionally generate an [Infura](https://infura.io) API key.
88 |
89 | Create a `.env` file which contains the following exported variables:
90 |
91 | ```sh
92 | export MNEMONIC="your mnemonic here"
93 | export TESTNET_PRIVATE_KEY="your bitcoin private key"
94 |
95 | # Optional
96 | export INFURA_KEY="your infura key"
97 | ```
98 |
99 | To run the tests:
100 |
101 | ```sh
102 | yarn run test
103 | ```
104 |
105 |
106 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "npmClient": "yarn",
3 | "useWorkspaces": true,
4 | "version": "3.6.0"
5 | }
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains-bitcoin`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains-bitcoin` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains_bitcoin.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains-bitcoin",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@noble/hashes": "1.1.2",
46 | "@renproject/utils": "^3.6.0",
47 | "@types/bchaddrjs": "0.4.0",
48 | "@types/bs58": "4.0.1",
49 | "@types/bs58check": "2.1.0",
50 | "@types/cashaddrjs": "0.3.0",
51 | "bchaddrjs": "0.5.2",
52 | "bech32": "2.0.0",
53 | "bignumber.js": "9.0.2",
54 | "bs58": "5.0.0",
55 | "bs58check": "2.1.2",
56 | "cashaddrjs": "0.4.4",
57 | "qs": "6.11.0",
58 | "wallet-address-validator": "0.2.4"
59 | },
60 | "nyc": {
61 | "extends": "@istanbuljs/nyc-config-typescript",
62 | "exclude": [
63 | "**/*.d.ts",
64 | "**/*.spec.js"
65 | ],
66 | "include": [
67 | "src"
68 | ]
69 | },
70 | "prettier": {
71 | "printWidth": 80,
72 | "semi": true,
73 | "singleQuote": false,
74 | "tabWidth": 4,
75 | "trailingComma": "all",
76 | "endOfLine": "lf",
77 | "arrowParens": "always"
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/bitcoin.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { Blockchain, BlockchainNetwork } from "./APIs/blockchain";
4 | import { Blockchair } from "./APIs/blockchair";
5 | import { Blockstream } from "./APIs/blockstream";
6 | import { SoChain } from "./APIs/sochain";
7 | import { BitcoinBaseChain } from "./base";
8 | import {
9 | BitcoinNetworkConfig,
10 | BitcoinNetworkConfigMap,
11 | BitcoinNetworkInput,
12 | } from "./utils/types";
13 | import {
14 | resolveBitcoinNetworkConfig,
15 | StandardBitcoinExplorer,
16 | } from "./utils/utils";
17 |
18 | const BitcoinMainnet: BitcoinNetworkConfig = {
19 | label: "Bitcoin",
20 |
21 | selector: "Bitcoin",
22 |
23 | nativeAsset: {
24 | name: "Bitcoin",
25 | symbol: "BTC",
26 | decimals: 8,
27 | },
28 | averageConfirmationTime: 60 * 10,
29 |
30 | explorer: StandardBitcoinExplorer("https://live.blockcypher.com/btc/"),
31 | p2shPrefix: new Uint8Array([0x05]),
32 | providers: [
33 | new Blockstream(),
34 | new Blockchair(),
35 | { api: new SoChain(), priority: 15 },
36 | { api: new Blockchain(BlockchainNetwork.Bitcoin), priority: 20 },
37 | ],
38 | // validateAddress: (address: string) =>
39 | // validateAddress(address, "BTC", "mainnet"),
40 | };
41 |
42 | const BitcoinTestnet: BitcoinNetworkConfig = {
43 | label: "Bitcoin Testnet",
44 |
45 | selector: "Bitcoin",
46 |
47 | nativeAsset: {
48 | name: "Testnet Bitcoin",
49 | symbol: "BTC",
50 | decimals: 8,
51 | },
52 | averageConfirmationTime: 60 * 10,
53 |
54 | isTestnet: true,
55 | explorer: StandardBitcoinExplorer(
56 | "https://live.blockcypher.com/btc-testnet/",
57 | ),
58 | p2shPrefix: new Uint8Array([0xc4]),
59 | providers: [
60 | new Blockstream({ testnet: true }),
61 | { api: new Blockchain(BlockchainNetwork.BitcoinTestnet), priority: 20 },
62 | // new Blockchair(BlockchairNetwork.BITCOIN_TESTNET),
63 | // { api: new SoChain(SoChainNetwork.BTCTEST), priority: 15 },
64 | ],
65 | // validateAddress: (address: string) =>
66 | // validateAddress(address, "BTC", "testnet"),
67 | };
68 |
69 | /**
70 | * The Bitcoin class adds support for the asset BTC.
71 | */
72 | export class Bitcoin extends BitcoinBaseChain {
73 | public static chain = "Bitcoin" as const;
74 | public static configMap: BitcoinNetworkConfigMap = {
75 | [RenNetwork.Mainnet]: BitcoinMainnet,
76 | [RenNetwork.Testnet]: BitcoinTestnet,
77 | };
78 | public configMap = Bitcoin.configMap;
79 |
80 | public static assets = {
81 | [RenNetwork.Mainnet]: {
82 | BTC: "BTC",
83 | },
84 | [RenNetwork.Testnet]: {
85 | BTC: "BTC",
86 | },
87 | };
88 |
89 | public assets:
90 | | typeof Bitcoin.assets[RenNetwork.Mainnet]
91 | | typeof Bitcoin.assets[RenNetwork.Testnet];
92 |
93 | public constructor({ network }: { network: BitcoinNetworkInput }) {
94 | super({
95 | network: resolveBitcoinNetworkConfig(Bitcoin.configMap, network),
96 | });
97 | this.assets =
98 | Bitcoin.assets[
99 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
100 | ];
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/declarations/declarations.d.ts:
--------------------------------------------------------------------------------
1 | declare module "wallet-address-validator";
2 | declare module "wallet-address-validator/src/bitcoin_validator";
3 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./base";
2 | export * from "./bitcoin";
3 | export * from "./bitcoincash";
4 | export * from "./digibyte";
5 | export * from "./dogecoin";
6 | export * from "./utils/types";
7 | export * from "./zcash";
8 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/script/index.ts:
--------------------------------------------------------------------------------
1 | import { Script } from "./script";
2 |
3 | const gatewayScript = (gGubKeyHash: Uint8Array, gHash: Uint8Array): Script =>
4 | new Script()
5 | .addData(gHash)
6 | .addOp(Script.OP.OP_DROP)
7 | .addOp(Script.OP.OP_DUP)
8 | .addOp(Script.OP.OP_HASH160)
9 | .addData(gGubKeyHash)
10 | .addOp(Script.OP.OP_EQUALVERIFY)
11 | .addOp(Script.OP.OP_CHECKSIG);
12 |
13 | export const createAddressArray = (
14 | gGubKeyHash: Uint8Array,
15 | gHash: Uint8Array,
16 | prefix: Uint8Array,
17 | ): Uint8Array => gatewayScript(gGubKeyHash, gHash).toAddress(prefix);
18 |
19 | export const calculatePubKeyScript = (
20 | gGubKeyHash: Uint8Array,
21 | gHash: Uint8Array,
22 | ): Uint8Array => gatewayScript(gGubKeyHash, gHash).toScriptHashOut();
23 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/script/opcodes.ts:
--------------------------------------------------------------------------------
1 | export enum Opcode {
2 | OP_FALSE = 0,
3 | OP_0 = 0,
4 | OP_PUSHDATA1 = 76,
5 | OP_PUSHDATA2 = 77,
6 | OP_PUSHDATA4 = 78,
7 | OP_1NEGATE = 79,
8 | OP_RESERVED = 80,
9 | OP_TRUE = 81,
10 | OP_1 = 81,
11 | OP_2 = 82,
12 | OP_3 = 83,
13 | OP_4 = 84,
14 | OP_5 = 85,
15 | OP_6 = 86,
16 | OP_7 = 87,
17 | OP_8 = 88,
18 | OP_9 = 89,
19 | OP_10 = 90,
20 | OP_11 = 91,
21 | OP_12 = 92,
22 | OP_13 = 93,
23 | OP_14 = 94,
24 | OP_15 = 95,
25 | OP_16 = 96,
26 | OP_NOP = 97,
27 | OP_VER = 98,
28 | OP_IF = 99,
29 | OP_NOTIF = 100,
30 | OP_VERIF = 101,
31 | OP_VERNOTIF = 102,
32 | OP_ELSE = 103,
33 | OP_ENDIF = 104,
34 | OP_VERIFY = 105,
35 | OP_RETURN = 106,
36 | OP_TOALTSTACK = 107,
37 | OP_FROMALTSTACK = 108,
38 | OP_2DROP = 109,
39 | OP_2DUP = 110,
40 | OP_3DUP = 111,
41 | OP_2OVER = 112,
42 | OP_2ROT = 113,
43 | OP_2SWAP = 114,
44 | OP_IFDUP = 115,
45 | OP_DEPTH = 116,
46 | OP_DROP = 117,
47 | OP_DUP = 118,
48 | OP_NIP = 119,
49 | OP_OVER = 120,
50 | OP_PICK = 121,
51 | OP_ROLL = 122,
52 | OP_ROT = 123,
53 | OP_SWAP = 124,
54 | OP_TUCK = 125,
55 | OP_CAT = 126,
56 | OP_SUBSTR = 127,
57 | OP_LEFT = 128,
58 | OP_RIGHT = 129,
59 | OP_SIZE = 130,
60 | OP_INVERT = 131,
61 | OP_AND = 132,
62 | OP_OR = 133,
63 | OP_XOR = 134,
64 | OP_EQUAL = 135,
65 | OP_EQUALVERIFY = 136,
66 | OP_RESERVED1 = 137,
67 | OP_RESERVED2 = 138,
68 | OP_1ADD = 139,
69 | OP_1SUB = 140,
70 | OP_2MUL = 141,
71 | OP_2DIV = 142,
72 | OP_NEGATE = 143,
73 | OP_ABS = 144,
74 | OP_NOT = 145,
75 | OP_0NOTEQUAL = 146,
76 | OP_ADD = 147,
77 | OP_SUB = 148,
78 | OP_MUL = 149,
79 | OP_DIV = 150,
80 | OP_MOD = 151,
81 | OP_LSHIFT = 152,
82 | OP_RSHIFT = 153,
83 | OP_BOOLAND = 154,
84 | OP_BOOLOR = 155,
85 | OP_NUMEQUAL = 156,
86 | OP_NUMEQUALVERIFY = 157,
87 | OP_NUMNOTEQUAL = 158,
88 | OP_LESSTHAN = 159,
89 | OP_GREATERTHAN = 160,
90 | OP_LESSTHANOREQUAL = 161,
91 | OP_GREATERTHANOREQUAL = 162,
92 | OP_MIN = 163,
93 | OP_MAX = 164,
94 | OP_WITHIN = 165,
95 | OP_RIPEMD160 = 166,
96 | OP_SHA1 = 167,
97 | OP_SHA256 = 168,
98 | OP_HASH160 = 169,
99 | OP_HASH256 = 170,
100 | OP_CODESEPARATOR = 171,
101 | OP_CHECKSIG = 172,
102 | OP_CHECKSIGVERIFY = 173,
103 | OP_CHECKMULTISIG = 174,
104 | OP_CHECKMULTISIGVERIFY = 175,
105 | OP_CHECKLOCKTIMEVERIFY = 177,
106 | OP_CHECKSEQUENCEVERIFY = 178,
107 | OP_NOP1 = 176,
108 | OP_NOP2 = 177,
109 | OP_NOP3 = 178,
110 | OP_NOP4 = 179,
111 | OP_NOP5 = 180,
112 | OP_NOP6 = 181,
113 | OP_NOP7 = 182,
114 | OP_NOP8 = 183,
115 | OP_NOP9 = 184,
116 | OP_NOP10 = 185,
117 | OP_PUBKEYHASH = 253,
118 | OP_PUBKEY = 254,
119 | OP_INVALIDOPCODE = 255,
120 | }
121 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/script/script.ts:
--------------------------------------------------------------------------------
1 | import { utils } from "@renproject/utils";
2 |
3 | import { hash160 } from "../utils/utils";
4 | import { Opcode } from "./opcodes";
5 |
6 | const checksum = (hash: Uint8Array) =>
7 | utils.sha256(utils.sha256(hash)).slice(0, 4);
8 |
9 | export class Script {
10 | private script: Uint8Array;
11 |
12 | public static OP = Opcode;
13 | public OP = Opcode;
14 |
15 | public constructor() {
16 | this.script = new Uint8Array();
17 | }
18 |
19 | public addOp = (op: Opcode): this => {
20 | this.script = new Uint8Array([...this.script, op]);
21 | return this;
22 | };
23 |
24 | public addData = (data: Uint8Array): this => {
25 | this.script = new Uint8Array([...this.script, data.length, ...data]);
26 | return this;
27 | };
28 |
29 | public bytes = (): Uint8Array => {
30 | return this.script;
31 | };
32 |
33 | public toScriptHashOut = (): Uint8Array => {
34 | return new Script()
35 | .addOp(Script.OP.OP_HASH160)
36 | .addData(hash160(this.bytes()))
37 | .addOp(Script.OP.OP_EQUAL)
38 | .bytes();
39 | };
40 |
41 | public toAddress = (prefix: Uint8Array | Uint8Array): Uint8Array => {
42 | // Hash
43 | const hash = hash160(this.bytes());
44 |
45 | // Prepend prefix
46 | const hashWithPrefix = utils.concat([prefix, hash]);
47 |
48 | // Append checksum
49 | const hashWithChecksum = utils.concat([
50 | hashWithPrefix,
51 | checksum(hashWithPrefix),
52 | ]);
53 |
54 | return hashWithChecksum;
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/utils/types.ts:
--------------------------------------------------------------------------------
1 | import { ChainTransaction, RenNetwork } from "@renproject/utils";
2 |
3 | import { APIWithPriority, BitcoinAPI } from "../APIs/API";
4 |
5 | export type BitcoinInputPayload =
6 | | {
7 | chain: string;
8 | type?: "gatewayAddress";
9 | }
10 | | {
11 | chain: string;
12 | type: "transaction";
13 | params: {
14 | tx: ChainTransaction;
15 | };
16 | };
17 |
18 | export interface BitcoinOutputPayload {
19 | chain: string;
20 | type?: "address";
21 | params: {
22 | address: string;
23 | };
24 | }
25 |
26 | export interface BitcoinNetworkConfig {
27 | label: string;
28 |
29 | selector: string;
30 |
31 | nativeAsset: {
32 | name: string;
33 | symbol: string;
34 | decimals: number;
35 | };
36 | averageConfirmationTime: number;
37 |
38 | isTestnet?: boolean;
39 | p2shPrefix: Uint8Array;
40 | explorer: {
41 | url: string;
42 | address: (address: string) => string;
43 | transaction: (txid: string) => string;
44 | };
45 | providers: Array;
46 | }
47 |
48 | export const isBitcoinNetworkConfig = (
49 | input: unknown,
50 | ): input is BitcoinNetworkConfig =>
51 | !!(input as BitcoinNetworkConfig).label &&
52 | !!(input as BitcoinNetworkConfig).selector &&
53 | !!(input as BitcoinNetworkConfig).nativeAsset &&
54 | !!(input as BitcoinNetworkConfig).p2shPrefix &&
55 | !!(input as BitcoinNetworkConfig).explorer &&
56 | !!(input as BitcoinNetworkConfig).providers;
57 |
58 | export type BitcoinNetworkConfigMap = {
59 | [network in RenNetwork]?: BitcoinNetworkConfig;
60 | };
61 |
62 | export type BitcoinNetworkInput =
63 | | RenNetwork
64 | | `${RenNetwork}`
65 | | BitcoinNetworkConfig;
66 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/src/zcash.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { Blockbook } from "./APIs/blockbook";
4 | import { Blockchair, BlockchairNetwork } from "./APIs/blockchair";
5 | import { Insight } from "./APIs/insight";
6 | import { SoChain, SoChainNetwork } from "./APIs/sochain";
7 | import { BitcoinBaseChain } from "./base";
8 | import {
9 | BitcoinNetworkConfig,
10 | BitcoinNetworkConfigMap,
11 | BitcoinNetworkInput,
12 | } from "./utils/types";
13 | import { resolveBitcoinNetworkConfig, SoChainExplorer } from "./utils/utils";
14 |
15 | const ZcashMainnet: BitcoinNetworkConfig = {
16 | label: "Zcash",
17 | selector: "Zcash",
18 |
19 | nativeAsset: {
20 | name: "Zcash",
21 | symbol: "ZEC",
22 | decimals: 8,
23 | },
24 | averageConfirmationTime: 75,
25 |
26 | explorer: SoChainExplorer("zcash", "ZEC"),
27 | p2shPrefix: new Uint8Array([0x1c, 0xbd]),
28 | providers: [
29 | new Blockbook("https://zecblockexplorer.com/api/"),
30 | new Blockchair(BlockchairNetwork.ZCASH),
31 | { api: new SoChain(SoChainNetwork.ZEC), priority: 15 },
32 | { api: new Insight("https://explorer.z.cash/api/"), priority: 20 }, // TODO: test again, currently broken
33 | { api: new Insight("https://zechain.net/api/v1/"), priority: 20 }, // TODO: test again, currently broken
34 | ],
35 | // validateAddress: (address: string) =>
36 | // validateAddress(address, "ZEC", "mainnet"),
37 | };
38 |
39 | const ZcashTestnet: BitcoinNetworkConfig = {
40 | label: "Zcash Testnet",
41 | selector: "Zcash",
42 |
43 | nativeAsset: {
44 | name: "Testnet Zcash",
45 | symbol: "ZEC",
46 | decimals: 8,
47 | },
48 | averageConfirmationTime: 75,
49 |
50 | isTestnet: true,
51 | explorer: SoChainExplorer("testnet/zcash", "ZECTEST"),
52 | p2shPrefix: new Uint8Array([0x1c, 0xba]),
53 | providers: [
54 | new Insight("https://explorer.testnet.z.cash/api/"),
55 | { api: new SoChain(SoChainNetwork.ZECTEST), priority: 15 },
56 | ],
57 | // validateAddress: (address: string) =>
58 | // validateAddress(address, "ZEC", "testnet"),
59 | };
60 |
61 | export class Zcash extends BitcoinBaseChain {
62 | public static chain = "Zcash" as const;
63 | public static configMap: BitcoinNetworkConfigMap = {
64 | [RenNetwork.Mainnet]: ZcashMainnet,
65 | [RenNetwork.Testnet]: ZcashTestnet,
66 | };
67 | public configMap = Zcash.configMap;
68 |
69 | public static assets = {
70 | [RenNetwork.Mainnet]: {
71 | ZEC: "ZEC",
72 | },
73 | [RenNetwork.Testnet]: {
74 | ZEC: "ZEC",
75 | },
76 | };
77 |
78 | public assets:
79 | | typeof Zcash.assets[RenNetwork.Mainnet]
80 | | typeof Zcash.assets[RenNetwork.Testnet];
81 |
82 | public constructor({ network }: { network: BitcoinNetworkInput }) {
83 | super({
84 | network: resolveBitcoinNetworkConfig(Zcash.configMap, network),
85 | });
86 | this.assets =
87 | Zcash.assets[
88 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
89 | ];
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/bch.spec.ts:
--------------------------------------------------------------------------------
1 | import { utils } from "@renproject/utils";
2 | import { expect } from "chai";
3 | /* eslint-disable no-console */
4 | import { describe, it } from "mocha";
5 |
6 | import { BitcoinCash } from "../src";
7 |
8 | describe("BCH", () => {
9 | it("address to buffer", () => {
10 | const bch = new BitcoinCash({ network: "testnet" });
11 | expect(
12 | utils.toHex(
13 | bch.addressToBytes(
14 | "bchtest:pq35hhjj35we555szq8xsa47ry093mkasudz8aetvr",
15 | ),
16 | ),
17 | ).to.equal("08234bde528d1d9a5290100e6876be191e58eedd87");
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/broadcastTransaction.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import { describe, it } from "mocha";
3 |
4 | import { Blockchain, BlockchainNetwork } from "../src/APIs/blockchain";
5 |
6 | describe.skip("broadcast transaction", () => {
7 | it("blockchain.com", async () => {
8 | const blockchain = new Blockchain(BlockchainNetwork.Bitcoin);
9 | console.debug(await blockchain.broadcastTransaction("123456"));
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/digibyte.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import { RenNetwork } from "@renproject/utils";
3 | import { expect } from "chai";
4 | import { describe, it } from "mocha";
5 |
6 | import { DigiByte } from "../src";
7 | import { APIWithPriority, BitcoinAPI } from "../src/APIs/API";
8 |
9 | describe("DigiByte", () => {
10 | it("watch for deposits", async () => {
11 | const digibyte = new DigiByte({ network: "mainnet" });
12 | const providerConfig =
13 | digibyte.configMap[RenNetwork.Mainnet].providers[0];
14 | const provider: BitcoinAPI =
15 | (providerConfig as APIWithPriority).api ||
16 | (providerConfig as BitcoinAPI);
17 |
18 | const txs = await provider.fetchUTXOs(
19 | "DRNiw2k4iFuHGS2fF1wMahounXo6H9iGbh",
20 | );
21 |
22 | expect(txs[txs.length - 1]).to.deep.equal({
23 | txid: "9f5c0a8146e7633911cbf5be44ebebb9b65bb360511f6795bea04c650ed600b8",
24 | amount: "16205616929",
25 | txindex: "2",
26 | height: "3127600",
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/getUTXOs.spec.ts:
--------------------------------------------------------------------------------
1 | // import { renMainnet, renTestnet } from "@renproject/chains";
2 | import chai from "chai";
3 |
4 | // import RenJS from "@renproject/ren";
5 |
6 | chai.should();
7 |
8 | describe("mercury.ts", () => {
9 | // it("Testnet BTC UTXOS", async () => {
10 | // const utxos = await RenJS.utils.btc.getUTXOs(renTestnet)("n2e9DLJqFoAiaqjo2JFQSW1GVC6gMLXEPa", 0);
11 | // utxos.length.should.be.greaterThan(0);
12 | // utxos[0].txHash.should.equal("af946e4182f1e5cbf0e682233b037a3ec8a5692b4f037cf016c7d11f0a97766d");
13 | // utxos[0].amount.should.equal(13370);
14 | // utxos[0].confirmations.should.be.greaterThan(0);
15 | // });
16 | // it("Testnet BTC UTXOS [second API]", async () => {
17 | // const utxos = await RenJS.utils.btc.getUTXOs(renTestnet)("n2e9DLJqFoAiaqjo2JFQSW1GVC6gMLXEPa", 0);
18 | // utxos.length.should.be.greaterThan(0);
19 | // utxos[0].txHash.should.equal("af946e4182f1e5cbf0e682233b037a3ec8a5692b4f037cf016c7d11f0a97766d");
20 | // utxos[0].amount.should.equal(13370);
21 | // utxos[0].confirmations.should.be.greaterThan(0);
22 | // });
23 | // it("Testnet ZCash UTXOS", async () => {
24 | // const utxos = await RenJS.utils.zec.getUTXOs(renTestnet)("tm9iMLAuYMzJHDJZAFmzVmEa81uddHz1viK", 0);
25 | // utxos.length.should.be.greaterThan(0);
26 | // utxos[0].txHash.should.equal("6d6f1781c589d9eafc923d480fa39656da088110b4553c043f9da2cf843d2b03");
27 | // utxos[0].amount.should.equal(100000000);
28 | // utxos[0].confirmations.should.be.greaterThan(0);
29 | // });
30 | // it("Mainnet BTC UTXOS", async () => {
31 | // const utxos = await RenJS.utils.btc.getUTXOs(renMainnet)("3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX", 0);
32 | // utxos.length.should.be.greaterThan(0);
33 | // utxos[0].txHash.should.equal("27c3a32f18d6274eb348dfd401defe6cccc2738eda277c4e55ae44370f91d98f");
34 | // utxos[0].amount.should.equal(12772);
35 | // utxos[0].confirmations.should.be.greaterThan(0);
36 | // });
37 | // it("Mainnet ZEC UTXOS", async () => {
38 | // const utxos = await RenJS.utils.zec.getUTXOs(renMainnet)("t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd", 0);
39 | // utxos.length.should.be.greaterThan(0);
40 | // utxos[0].txHash.should.equal("6482a18a61cea7da8abb7ac8c44939b701889343afac7130fec4898ad1b29307");
41 | // utxos[0].amount.should.equal(7873358);
42 | // utxos[0].confirmations.should.be.greaterThan(0);
43 | // });
44 | // it("Mainnet BCH UTXOS", async () => {
45 | // const utxos = await RenJS.utils.bch.getUTXOs(renMainnet)("bitcoincash:qqt6g6wul02yakpt05amm0hey67lhh7wagrrqxcmys", 0);
46 | // utxos.length.should.be.greaterThan(0);
47 | // utxos[0].txHash.should.equal("2d05f0c9c3e1c226e63b5fac240137687544cf631cd616fd34fd188fc9020866");
48 | // utxos[0].amount.should.equal(5000000000);
49 | // utxos[0].confirmations.should.be.greaterThan(0);
50 | // });
51 | // it.skip("Testnet BCH UTXOS", async () => {
52 | // const utxos = await RenJS.utils.bch.getUTXOs(renTestnet)("bchtest:qrhfzqeen0a59gy3576n00k54p2ja9s3egxdkyy7hr", 0);
53 | // utxos.length.should.be.greaterThan(0);
54 | // utxos[0].txHash.should.equal("d9d587c9f77996e5618141a564d46f3bb7c92a7cdd8cbe9142bc43eb18a63887");
55 | // utxos[0].amount.should.equal(13999000);
56 | // utxos[0].confirmations.should.be.greaterThan(0);
57 | // });
58 | });
59 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/script.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from "mocha";
2 |
3 | /* eslint-disable no-console */
4 | import { RenNetwork, utils } from "@renproject/utils";
5 |
6 | import { Bitcoin, BitcoinCash, Dogecoin, Zcash } from "../src";
7 | import { hash160 } from "../src/utils/utils";
8 |
9 | describe("Common", () => {
10 | for (const ChainClass of [Bitcoin, Zcash, BitcoinCash, Dogecoin]) {
11 | for (const network of [RenNetwork.Mainnet, RenNetwork.Testnet]) {
12 | it(ChainClass.chain, async () => {
13 | const chain = new ChainClass({ network });
14 | const gHash = utils.fromBase64(
15 | "cQ+CJ8bOP4RMopOCNDvbQ020Eu8KRpYykurZyKNFM1I=",
16 | );
17 |
18 | const publicKey = utils.fromHex(
19 | "030dd65f7db2920bb229912e3f4213dd150e5f972c9b73e9be714d844561ac355c",
20 | );
21 |
22 | const address = await chain.createGatewayAddress(
23 | chain.assets[Object.keys(chain.assets)[0]],
24 | {
25 | chain: chain.chain,
26 | },
27 | hash160(publicKey),
28 | gHash,
29 | );
30 |
31 | if (false as boolean) {
32 | console.debug(`${chain.chain} ${network}: ${address}`);
33 | }
34 | });
35 | }
36 | }
37 | });
38 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/test/utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 |
3 | import { Bitcoin, Dogecoin } from "../src";
4 |
5 | describe("Utils", () => {
6 | it("validateTransaction", () => {
7 | const bitcoin = new Bitcoin({
8 | network: "testnet",
9 | });
10 |
11 | expect(
12 | bitcoin.validateTransaction({
13 | txHash: "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
14 | }),
15 | ).to.be.true;
16 |
17 | expect(
18 | bitcoin.validateTransaction({
19 | txHash: "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
20 | txid: "jdT1-9XpgPwC81xs4UWTWxHihGBb9ZmhPG1BXbVdB6E",
21 | txindex: "1",
22 | }),
23 | ).to.be.true;
24 |
25 | const dogecoinMainnet = new Dogecoin({ network: "mainnet" });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/chains/chains-bitcoin/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains-ethereum`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains-ethereum` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains_ethereum.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains-ethereum",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@ethersproject/abi": "5.7.0",
46 | "@ethersproject/bytes": "5.7.0",
47 | "@ethersproject/providers": "5.7.2",
48 | "@renproject/utils": "^3.6.0",
49 | "@types/elliptic": "6.4.14",
50 | "bignumber.js": "9.0.2",
51 | "elliptic": "6.5.4",
52 | "ethers": "5.7.2"
53 | },
54 | "nyc": {
55 | "extends": "@istanbuljs/nyc-config-typescript",
56 | "exclude": [
57 | "**/*.d.ts",
58 | "**/*.spec.js"
59 | ],
60 | "include": [
61 | "src"
62 | ]
63 | },
64 | "prettier": {
65 | "printWidth": 80,
66 | "semi": true,
67 | "singleQuote": false,
68 | "tabWidth": 4,
69 | "trailingComma": "all",
70 | "endOfLine": "lf",
71 | "arrowParens": "always"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/arbitrum.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Arbitrum",
9 |
10 | nativeAsset: { name: "Arbitrum Ether", symbol: "ArbETH", decimals: 18 },
11 | averageConfirmationTime: 4,
12 |
13 | config: {
14 | chainId: "0xa4b1",
15 | chainName: "Arbitrum One",
16 | nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
17 | rpcUrls: [
18 | "https://arb1.arbitrum.io/rpc",
19 | "https://rpc.ankr.com/arbitrum",
20 | "https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
21 | // "https://arbitrum-mainnet.infura.io/v3/${INFURA_API_KEY}",
22 | ],
23 | blockExplorerUrls: ["https://arbiscan.io"],
24 | },
25 |
26 | logRequestLimit: 20000,
27 | addresses: {
28 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
29 | BasicBridge: "0x82DF02A52E2e76C0c233367f2fE6c9cfe51578c5",
30 | },
31 | },
32 | [RenNetwork.Testnet]: {
33 | selector: "Arbitrum",
34 | isTestnet: true,
35 |
36 | nativeAsset: {
37 | name: "Arbitrum Görli Ether",
38 | symbol: "ArbETH",
39 | decimals: 18,
40 | },
41 | averageConfirmationTime: 4,
42 |
43 | config: {
44 | chainId: "0x66eeb",
45 | chainName: "Arbitrum Görli",
46 | nativeCurrency: {
47 | name: "Arbitrum Görli Ether",
48 | symbol: "ARETH",
49 | decimals: 18,
50 | },
51 | rpcUrls: [
52 | "https://goerli-rollup.arbitrum.io/rpc",
53 | "https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
54 | "wss://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
55 | ],
56 | blockExplorerUrls: ["https://goerli.arbiscan.io"],
57 | },
58 |
59 | logRequestLimit: 20000,
60 | addresses: {
61 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
62 | BasicBridge: "0x081636b68aBD7695006e0baE4d8663b91EC5Cfc1",
63 | },
64 | },
65 | };
66 |
67 | /**
68 | * Arbitrum/arbETH configuration.
69 | */
70 | export class Arbitrum extends EthereumBaseChain {
71 | // Static members.
72 | public static chain = "Arbitrum" as const;
73 | public static configMap = configMap;
74 | public static assets = {
75 | [RenNetwork.Mainnet]: { ArbETH: "ArbETH" as const },
76 | [RenNetwork.Testnet]: { ArbETH: "ArbETH" as const },
77 | };
78 |
79 | public configMap = configMap;
80 | public assets:
81 | | typeof Arbitrum.assets[RenNetwork.Mainnet]
82 | | typeof Arbitrum.assets[RenNetwork.Testnet];
83 |
84 | public constructor({
85 | network,
86 | ...params
87 | }: ConstructorParameters[0]) {
88 | super({
89 | ...params,
90 | network: resolveEVMNetworkConfig(configMap, network),
91 | });
92 | this.assets =
93 | Arbitrum.assets[
94 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
95 | ];
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/avalanche.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Avalanche",
9 |
10 | nativeAsset: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
11 | averageConfirmationTime: 2,
12 |
13 | config: {
14 | chainId: "0xa86a",
15 | chainName: "Avalanche C-Chain",
16 | nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
17 | rpcUrls: [
18 | "https://api.avax.network/ext/bc/C/rpc",
19 | "https://rpc.ankr.com/avalanche",
20 | "https://ava-mainnet.public.blastapi.io/ext/bc/C/rpc",
21 | ],
22 | blockExplorerUrls: ["https://snowtrace.io"],
23 | },
24 |
25 | logRequestLimit: 2048,
26 | addresses: {
27 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
28 | BasicBridge: "0x82DF02A52E2e76C0c233367f2fE6c9cfe51578c5",
29 | },
30 | },
31 |
32 | [RenNetwork.Testnet]: {
33 | selector: "Avalanche",
34 | isTestnet: true,
35 |
36 | nativeAsset: {
37 | name: "Testnet Avalanche",
38 | symbol: "AVAX",
39 | decimals: 18,
40 | },
41 | averageConfirmationTime: 2,
42 |
43 | config: {
44 | chainId: "0xa869",
45 | chainName: "Avalanche Fuji Testnet",
46 | nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
47 | rpcUrls: ["https://api.avax-test.network/ext/bc/C/rpc"],
48 | blockExplorerUrls: ["https://testnet.snowtrace.io"],
49 | },
50 |
51 | logRequestLimit: 2048,
52 | addresses: {
53 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
54 | BasicBridge: "0xcb6bD6B6c7D7415C0157e393Bb2B6Def7555d518",
55 | },
56 | },
57 | };
58 |
59 | /**
60 | * Avalanche/AVAX configuration.
61 | */
62 | export class Avalanche extends EthereumBaseChain {
63 | // Static members.
64 | public static chain = "Avalanche" as const;
65 | public static configMap = configMap;
66 | public static assets = {
67 | [RenNetwork.Mainnet]: { AVAX: "AVAX" as const },
68 | [RenNetwork.Testnet]: { AVAX: "AVAX" as const },
69 | };
70 |
71 | public configMap = configMap;
72 | public assets:
73 | | typeof Avalanche.assets[RenNetwork.Mainnet]
74 | | typeof Avalanche.assets[RenNetwork.Testnet];
75 |
76 | public constructor({
77 | network,
78 | ...params
79 | }: ConstructorParameters[0]) {
80 | super({
81 | ...params,
82 | network: resolveEVMNetworkConfig(configMap, network),
83 | });
84 | this.assets =
85 | Avalanche.assets[
86 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
87 | ];
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/catalog.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Catalog",
9 |
10 | nativeAsset: { name: "DCE EVM", symbol: "dceETH", decimals: 18 },
11 | averageConfirmationTime: 15,
12 |
13 | config: {
14 | chainId: "0xC30",
15 | chainName: "Catalog Mainnet",
16 | nativeCurrency: { name: "DCE EVM", symbol: "dceETH", decimals: 18 },
17 | rpcUrls: ["https://mainnet.catalog.fi/rpc"],
18 | blockExplorerUrls: null,
19 | },
20 |
21 | addresses: {
22 | GatewayRegistry: "0x44c2CdaE368F90544A01522C413376fC72ebd4F2",
23 | BasicBridge: "0x5D952fA25eD90b1151473d57F2B6C6DB568b865d",
24 | },
25 | },
26 |
27 | [RenNetwork.Testnet]: {
28 | selector: "Catalog",
29 |
30 | nativeAsset: { name: "DCE EVM", symbol: "dceETH", decimals: 18 },
31 | averageConfirmationTime: 15,
32 |
33 | config: {
34 | chainId: "0x47EE",
35 | chainName: "Catalog Testnet",
36 | nativeCurrency: { name: "DCE EVM", symbol: "dceETH", decimals: 18 },
37 | rpcUrls: ["https://rpc.catalog.fi/testnet"],
38 | blockExplorerUrls: null,
39 | },
40 |
41 | addresses: {
42 | GatewayRegistry: "0x44c2CdaE368F90544A01522C413376fC72ebd4F2",
43 | BasicBridge: "0xfc5681F4343803C11eB5Bb7aFd2108238bbd7177",
44 | },
45 | },
46 | };
47 |
48 | /**
49 | * Catalog configuration.
50 | */
51 | export class Catalog extends EthereumBaseChain {
52 | // Static members.
53 | public static chain = "Catalog" as const;
54 | public static configMap = configMap;
55 | public static assets = {
56 | [RenNetwork.Mainnet]: {},
57 | [RenNetwork.Testnet]: {},
58 | };
59 |
60 | public configMap = configMap;
61 | public assets:
62 | | typeof Catalog.assets[RenNetwork.Mainnet]
63 | | typeof Catalog.assets[RenNetwork.Testnet];
64 |
65 | public constructor({
66 | network,
67 | ...params
68 | }: ConstructorParameters[0]) {
69 | super({
70 | ...params,
71 | network: resolveEVMNetworkConfig(configMap, network),
72 | });
73 | this.assets =
74 | Catalog.assets[
75 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
76 | ];
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/contracts/ABIs/TransferWithLog.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "from",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "to",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "amount",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "LogTransferred",
25 | "type": "event"
26 | },
27 | {
28 | "inputs": [],
29 | "name": "NAME",
30 | "outputs": [
31 | {
32 | "internalType": "string",
33 | "name": "",
34 | "type": "string"
35 | }
36 | ],
37 | "stateMutability": "view",
38 | "type": "function"
39 | },
40 | {
41 | "inputs": [
42 | {
43 | "internalType": "address payable",
44 | "name": "to",
45 | "type": "address"
46 | }
47 | ],
48 | "name": "transferWithLog",
49 | "outputs": [],
50 | "stateMutability": "payable",
51 | "type": "function"
52 | }
53 | ]
54 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/contracts/index.ts:
--------------------------------------------------------------------------------
1 | import { Provider } from "@ethersproject/providers";
2 | import { utils } from "@renproject/utils";
3 | import { Contract, Signer } from "ethers";
4 |
5 | import { AbiItem } from "../utils/abi";
6 | import BasicBridgeJSON from "./ABIs/BasicBridge.json";
7 | import ERC20JSON from "./ABIs/ERC20.json";
8 | import GatewayRegistryJSON from "./ABIs/GatewayRegistryV2.json";
9 | import LockGatewayJSON from "./ABIs/LockGatewayV3.json";
10 | import MintGatewayJSON from "./ABIs/MintGatewayV3.json";
11 | import TransferWithLogJSON from "./ABIs/TransferWithLog.json";
12 | import { ERC20 } from "./typechain/ERC20";
13 | import { GatewayRegistryV2 } from "./typechain/GatewayRegistryV2";
14 | import { LockGatewayV3 } from "./typechain/LockGatewayV3";
15 | import { MintGatewayV3 } from "./typechain/MintGatewayV3";
16 |
17 | export const BasicBridgeABI = BasicBridgeJSON as AbiItem[];
18 | export const ERC20ABI = ERC20JSON as AbiItem[];
19 | export const GatewayRegistryABI = GatewayRegistryJSON as AbiItem[];
20 | export const LockGatewayABI = LockGatewayJSON as AbiItem[];
21 | export const MintGatewayABI = MintGatewayJSON as AbiItem[];
22 | export const TransferWithLogABI = TransferWithLogJSON as AbiItem[];
23 |
24 | export const findABIMethod = (abi: AbiItem[], name: string): AbiItem => {
25 | const first = abi.filter((item) => item.name === name)[0];
26 | if (!first) {
27 | throw new Error(`No ABI entry found for "${name}".`);
28 | }
29 | return first;
30 | };
31 |
32 | export const getEventTopic = (abiItem: AbiItem): Uint8Array => {
33 | const parameters =
34 | abiItem.inputs && abiItem.inputs.length > 0
35 | ? abiItem.inputs.map((input) => input.type).join(",")
36 | : "";
37 | if (!abiItem.name) {
38 | throw new Error(
39 | `No name found in ABI item (parameters: ${parameters}).`,
40 | );
41 | }
42 | const eventSignature = `${abiItem.name}(${parameters})`;
43 | return utils.keccak256(utils.fromUTF8String(eventSignature));
44 | };
45 |
46 | export const getMintGatewayInstance = (
47 | signerOrProvider: Signer | Provider,
48 | address: string,
49 | ): MintGatewayV3 =>
50 | new Contract(address, MintGatewayABI, signerOrProvider) as MintGatewayV3;
51 |
52 | export const getLockGatewayInstance = (
53 | signerOrProvider: Signer | Provider,
54 | address: string,
55 | ): LockGatewayV3 =>
56 | new Contract(address, LockGatewayABI, signerOrProvider) as LockGatewayV3;
57 |
58 | export const getGatewayRegistryInstance = (
59 | signerOrProvider: Signer | Provider,
60 | address: string,
61 | ): GatewayRegistryV2 =>
62 | new Contract(
63 | address,
64 | GatewayRegistryABI,
65 | signerOrProvider,
66 | ) as GatewayRegistryV2;
67 |
68 | export const getERC20Instance = (
69 | signerOrProvider: Signer | Provider,
70 | address: string,
71 | ): ERC20 => new Contract(address, ERC20ABI, signerOrProvider) as ERC20;
72 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/contracts/typechain/common.ts:
--------------------------------------------------------------------------------
1 | /* Autogenerated file. Do not edit manually. */
2 | /* tslint:disable */
3 | /* eslint-disable */
4 | import type { Listener } from "@ethersproject/providers";
5 | import type { Event, EventFilter } from "ethers";
6 |
7 | export interface TypedEvent<
8 | TArgsArray extends Array = any,
9 | TArgsObject = any,
10 | > extends Event {
11 | args: TArgsArray & TArgsObject;
12 | }
13 |
14 | export interface TypedEventFilter<_TEvent extends TypedEvent>
15 | extends EventFilter {}
16 |
17 | export interface TypedListener {
18 | (...listenerArg: [...__TypechainArgsArray, TEvent]): void;
19 | }
20 |
21 | type __TypechainArgsArray = T extends TypedEvent ? U : never;
22 |
23 | export interface OnEvent {
24 | (
25 | eventFilter: TypedEventFilter,
26 | listener: TypedListener,
27 | ): TRes;
28 | (eventName: string, listener: Listener): TRes;
29 | }
30 |
31 | export type MinEthersFactory = {
32 | deploy(...a: ARGS[]): Promise;
33 | };
34 |
35 | export type GetContractTypeFromFactory = F extends MinEthersFactory<
36 | infer C,
37 | any
38 | >
39 | ? C
40 | : never;
41 |
42 | export type GetARGsTypeFromFactory = F extends MinEthersFactory
43 | ? Parameters
44 | : never;
45 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/fantom.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Fantom",
9 |
10 | nativeAsset: { name: "Fantom", symbol: "FTM", decimals: 18 },
11 | averageConfirmationTime: 1,
12 |
13 | config: {
14 | chainId: "0xfa",
15 | chainName: "Fantom Opera",
16 | nativeCurrency: { name: "Fantom", symbol: "FTM", decimals: 18 },
17 | rpcUrls: [
18 | "https://rpc.ftm.tools",
19 | "https://fantom-mainnet.gateway.pokt.network/v1/lb/62759259ea1b320039c9e7ac",
20 | "https://rpc.ankr.com/fantom",
21 | "https://rpc.fantom.network",
22 | "https://rpc2.fantom.network",
23 | "https://rpc3.fantom.network",
24 | "https://rpcapi.fantom.network",
25 | "https://fantom-mainnet.public.blastapi.io",
26 | ],
27 | blockExplorerUrls: ["https://ftmscan.com"],
28 | },
29 |
30 | addresses: {
31 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
32 | BasicBridge: "0x82DF02A52E2e76C0c233367f2fE6c9cfe51578c5",
33 | },
34 | },
35 |
36 | [RenNetwork.Testnet]: {
37 | selector: "Fantom",
38 |
39 | nativeAsset: { name: "Testnet Fantom", symbol: "FTM", decimals: 18 },
40 | averageConfirmationTime: 1,
41 |
42 | config: {
43 | chainId: "0xfa2",
44 | chainName: "Fantom Testnet",
45 | nativeCurrency: { name: "Fantom", symbol: "FTM", decimals: 18 },
46 | rpcUrls: ["https://rpc.testnet.fantom.network"],
47 | blockExplorerUrls: ["https://testnet.ftmscan.com"],
48 | },
49 |
50 | addresses: {
51 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
52 | BasicBridge: "0xcb6bD6B6c7D7415C0157e393Bb2B6Def7555d518",
53 | },
54 | },
55 | };
56 |
57 | export class Fantom extends EthereumBaseChain {
58 | // Static members.
59 | public static chain = "Fantom" as const;
60 | public static configMap = configMap;
61 | public static assets = {
62 | [RenNetwork.Mainnet]: { FTM: "FTM" as const },
63 | [RenNetwork.Testnet]: { FTM: "FTM" as const },
64 | };
65 |
66 | public configMap = Fantom.configMap;
67 | public assets:
68 | | typeof Fantom.assets[RenNetwork.Mainnet]
69 | | typeof Fantom.assets[RenNetwork.Testnet];
70 |
71 | public constructor({
72 | network,
73 | ...params
74 | }: ConstructorParameters[0]) {
75 | super({
76 | ...params,
77 | network: resolveEVMNetworkConfig(configMap, network),
78 | });
79 | this.assets =
80 | Fantom.assets[
81 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
82 | ];
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/goerli.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { EthereumTestnet, goerliConfigMap } from "./ethereum";
5 | import { resolveEVMNetworkConfig } from "./utils/generic";
6 |
7 | export class Goerli extends EthereumBaseChain {
8 | // Static members.
9 | public static chain = "Goerli" as const;
10 | public static configMap = goerliConfigMap;
11 | public static assets = {
12 | [RenNetwork.Testnet]: {
13 | gETH: "gETH" as const,
14 | REN: "REN_Goerli" as const,
15 | DAI: "DAI_Goerli" as const,
16 | USDC: "USDC_Goerli" as const,
17 | USDT: "USDT_Goerli" as const,
18 |
19 | // Aliases
20 | ETH: "gETH" as const,
21 | ETH_Goerli: "gETH" as const,
22 | REN_Goerli: "REN_Goerli" as const,
23 | DAI_Goerli: "DAI_Goerli" as const,
24 | USDC_Goerli: "USDC_Goerli" as const,
25 | USDT_Goerli: "USDT_Goerli" as const,
26 | },
27 | };
28 |
29 | public configMap = goerliConfigMap;
30 | public assets: typeof Goerli.assets[RenNetwork.Testnet];
31 |
32 | public constructor({
33 | network,
34 | ...params
35 | }: ConstructorParameters[0] & {
36 | defaultTestnet?: EthereumTestnet.Goerli | `${EthereumTestnet.Goerli}`;
37 | }) {
38 | super({
39 | ...params,
40 | network: resolveEVMNetworkConfig(goerliConfigMap, network),
41 | });
42 | this.assets = Goerli.assets[RenNetwork.Testnet];
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./utils/types";
2 | export { EVMParam } from "./utils/payloads/evmParams";
3 | export { EVM_ERROR } from "./utils/errors";
4 | export { EthereumBaseChain } from "./base";
5 | export {
6 | resolveRpcEndpoints,
7 | isEVMNetworkConfig,
8 | resolveEVMNetworkConfig,
9 | } from "./utils/generic";
10 |
11 | // Chains
12 | export { Arbitrum } from "./arbitrum";
13 | export { Avalanche } from "./avalanche";
14 | export { BinanceSmartChain } from "./bsc";
15 | export { Catalog } from "./catalog";
16 | export { Ethereum } from "./ethereum";
17 | export { Fantom } from "./fantom";
18 | export { Goerli } from "./goerli";
19 | export { Kava } from "./kava";
20 | export { Moonbeam } from "./moonbeam";
21 | export { Optimism } from "./optimism";
22 | export { Polygon } from "./polygon";
23 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/kava.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Kava",
9 |
10 | nativeAsset: { name: "Kava", symbol: "KAVA", decimals: 18 },
11 | averageConfirmationTime: 5,
12 | logRequestLimit: 10000,
13 |
14 | config: {
15 | chainId: "0x8ae",
16 | chainName: "Kava EVM",
17 | nativeCurrency: { name: "Kava", symbol: "KAVA", decimals: 18 },
18 | rpcUrls: [
19 | "https://evm.kava.io",
20 | "https://evm2.kava.io",
21 | "wss://wevm.kava.io",
22 | "wss://wevm2.kava.io",
23 | ],
24 | blockExplorerUrls: ["https://explorer.kava.io"],
25 | },
26 |
27 | addresses: {
28 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
29 | BasicBridge: "0xa3FA9A73D22618FfdF6958Ba6285FB3F565e1443",
30 | },
31 | },
32 |
33 | [RenNetwork.Testnet]: {
34 | selector: "Kava",
35 |
36 | nativeAsset: { name: "Testnet Kava", symbol: "KAVA", decimals: 18 },
37 | averageConfirmationTime: 5,
38 | logRequestLimit: 10000,
39 |
40 | config: {
41 | chainId: "0x8ad",
42 | chainName: "Kava EVM Testnet",
43 | nativeCurrency: { name: "Kava", symbol: "KAVA", decimals: 18 },
44 | rpcUrls: [
45 | "https://evm.testnet.kava.io",
46 | "wss://wevm.testnet.kava.io",
47 | ],
48 | blockExplorerUrls: ["https://explorer.testnet.kava.io"],
49 | },
50 |
51 | addresses: {
52 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
53 | BasicBridge: "0xcb6bD6B6c7D7415C0157e393Bb2B6Def7555d518",
54 | },
55 | },
56 | };
57 |
58 | export class Kava extends EthereumBaseChain {
59 | // Static members.
60 | public static chain = "Kava" as const;
61 | public static configMap = configMap;
62 | public static assets = {
63 | [RenNetwork.Mainnet]: { KAVA: "KAVA" as const },
64 | [RenNetwork.Testnet]: { KAVA: "KAVA" as const },
65 | };
66 |
67 | public configMap = configMap;
68 | public assets:
69 | | typeof Kava.assets[RenNetwork.Mainnet]
70 | | typeof Kava.assets[RenNetwork.Testnet];
71 |
72 | public constructor({
73 | network,
74 | ...params
75 | }: ConstructorParameters[0]) {
76 | super({
77 | ...params,
78 | network: resolveEVMNetworkConfig(configMap, network),
79 | });
80 | this.assets =
81 | Kava.assets[
82 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
83 | ];
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/moonbeam.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Moonbeam",
9 |
10 | nativeAsset: { name: "Glimmer", symbol: "GLMR", decimals: 18 },
11 | averageConfirmationTime: 12,
12 | logRequestLimit: 2000,
13 |
14 | config: {
15 | chainId: "0x504",
16 | chainName: "Moonbeam",
17 | nativeCurrency: { name: "Glimmer", symbol: "GLMR", decimals: 18 },
18 | rpcUrls: [
19 | "https://rpc.api.moonbeam.network",
20 | "wss://wss.api.moonbeam.network",
21 | ],
22 | blockExplorerUrls: ["https://moonbeam.moonscan.io"],
23 | },
24 |
25 | addresses: {
26 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
27 | BasicBridge: "0xa3FA9A73D22618FfdF6958Ba6285FB3F565e1443",
28 | },
29 | },
30 |
31 | [RenNetwork.Testnet]: {
32 | selector: "Moonbeam",
33 |
34 | nativeAsset: { name: "Glimmer", symbol: "GLMR", decimals: 18 },
35 | averageConfirmationTime: 12,
36 | logRequestLimit: 2000,
37 |
38 | config: {
39 | chainId: "0x507",
40 | chainName: "Moonbase Alpha",
41 | nativeCurrency: { name: "Dev", symbol: "DEV", decimals: 18 },
42 | rpcUrls: [
43 | "https://rpc.api.moonbase.moonbeam.network",
44 | "https://rpc.testnet.moonbeam.network",
45 | ],
46 | blockExplorerUrls: ["https://moonbase.moonscan.io"],
47 | },
48 |
49 | addresses: {
50 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
51 | BasicBridge: "0xcb6bD6B6c7D7415C0157e393Bb2B6Def7555d518",
52 | },
53 | },
54 | };
55 |
56 | export class Moonbeam extends EthereumBaseChain {
57 | // Static members.
58 | public static chain = "Moonbeam" as const;
59 | public static configMap = configMap;
60 | public static assets = {
61 | [RenNetwork.Mainnet]: { GLMR: "GLMR" as const },
62 | [RenNetwork.Testnet]: { GLMR: "GLMR" as const },
63 | };
64 |
65 | public configMap = configMap;
66 | public assets:
67 | | typeof Moonbeam.assets[RenNetwork.Mainnet]
68 | | typeof Moonbeam.assets[RenNetwork.Testnet];
69 |
70 | public constructor({
71 | network,
72 | ...params
73 | }: ConstructorParameters[0]) {
74 | super({
75 | ...params,
76 | network: resolveEVMNetworkConfig(configMap, network),
77 | });
78 | this.assets =
79 | Moonbeam.assets[
80 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
81 | ];
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/optimism.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | import { EthereumBaseChain } from "./base";
4 | import { resolveEVMNetworkConfig } from "./utils/generic";
5 |
6 | const configMap: EthereumBaseChain["configMap"] = {
7 | [RenNetwork.Mainnet]: {
8 | selector: "Optimism",
9 |
10 | nativeAsset: { name: "Optimism Ether", symbol: "oETH", decimals: 18 },
11 | averageConfirmationTime: 5,
12 | logRequestLimit: 10000,
13 |
14 | config: {
15 | chainId: "0xA",
16 | chainName: "Optimism",
17 | nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
18 | rpcUrls: [
19 | "https://mainnet.optimism.io/",
20 | "https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
21 | "wss://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
22 | ],
23 | blockExplorerUrls: ["https://optimistic.etherscan.io"],
24 | },
25 |
26 | addresses: {
27 | GatewayRegistry: "0xf36666C230Fa12333579b9Bd6196CB634D6BC506",
28 | BasicBridge: "0xa3FA9A73D22618FfdF6958Ba6285FB3F565e1443",
29 | },
30 | },
31 |
32 | [RenNetwork.Testnet]: {
33 | selector: "Optimism",
34 |
35 | nativeAsset: {
36 | name: "Optimism Görli Ether",
37 | symbol: "oETH",
38 | decimals: 18,
39 | },
40 | averageConfirmationTime: 5,
41 | logRequestLimit: 10000,
42 |
43 | config: {
44 | chainId: "0x45",
45 | chainName: "Optimism Görli",
46 | nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
47 | rpcUrls: [
48 | "https://goerli.optimism.io",
49 | "https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
50 | "wss://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
51 | ],
52 | blockExplorerUrls: ["https://goerli-optimism.etherscan.io"],
53 | },
54 |
55 | addresses: {
56 | GatewayRegistry: "0x5076a1F237531fa4dC8ad99bb68024aB6e1Ff701",
57 | BasicBridge: "0x081636b68aBD7695006e0baE4d8663b91EC5Cfc1",
58 | },
59 | },
60 | };
61 |
62 | export class Optimism extends EthereumBaseChain {
63 | // Static members.
64 | public static chain = "Optimism" as const;
65 | public static configMap = configMap;
66 | public static assets = {
67 | [RenNetwork.Mainnet]: { oETH: "oETH" as const },
68 | [RenNetwork.Testnet]: { oETH: "oETH" as const },
69 | };
70 |
71 | public configMap = configMap;
72 | public assets:
73 | | typeof Optimism.assets[RenNetwork.Mainnet]
74 | | typeof Optimism.assets[RenNetwork.Testnet];
75 |
76 | public constructor({
77 | network,
78 | ...params
79 | }: ConstructorParameters[0]) {
80 | super({
81 | ...params,
82 | network: resolveEVMNetworkConfig(configMap, network),
83 | });
84 | this.assets =
85 | Optimism.assets[
86 | this.network.isTestnet ? RenNetwork.Testnet : RenNetwork.Mainnet
87 | ];
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/utils/errors.ts:
--------------------------------------------------------------------------------
1 | export enum EVM_ERROR {
2 | ASSET_NOT_SUPPORTED = "RENJS:ASSET_NOT_SUPPORTED",
3 | NETWORK_ERROR = "RENJS:NETWORK_ERROR",
4 | }
5 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/utils/gatewayRegistry.ts:
--------------------------------------------------------------------------------
1 | import { Provider } from "@ethersproject/providers";
2 | import { ErrorWithCode, utils } from "@renproject/utils";
3 |
4 | import { getGatewayRegistryInstance } from "../contracts";
5 | import { EVM_ERROR } from "./errors";
6 | import { EVMNetworkConfig } from "./types";
7 |
8 | /**
9 | * Utilities for fetching gateway contract addresses and token addresses.
10 | */
11 |
12 | /** The equivalent to `address(0x0)` in Solidity. */
13 | const EMPTY_ADDRESS = "0x" + "00".repeat(20);
14 |
15 | enum GatewayRegistryLookup {
16 | MintGateway = "Mint Gateway",
17 | LockGateway = "Lock Gateway",
18 | RenAsset = "Ren Asset",
19 | LockAsset = "Lock Asset",
20 | }
21 |
22 | const gatewayRegistryMethods = {
23 | [GatewayRegistryLookup.MintGateway]: "getMintGatewayBySymbol",
24 | [GatewayRegistryLookup.LockGateway]: "getLockGatewayBySymbol",
25 | [GatewayRegistryLookup.RenAsset]: "getRenAssetBySymbol",
26 | [GatewayRegistryLookup.LockAsset]: "getLockAssetBySymbol",
27 | };
28 |
29 | const createGatewayRegistryFetcher =
30 | (lookup: GatewayRegistryLookup) =>
31 | async (
32 | network: EVMNetworkConfig,
33 | provider: Provider,
34 | asset: string,
35 | ): Promise => {
36 | try {
37 | const registry = getGatewayRegistryInstance(
38 | provider,
39 | network.addresses.GatewayRegistry,
40 | );
41 | const registryAddress: string = utils.Ox(
42 | await registry[gatewayRegistryMethods[lookup]](asset),
43 | );
44 | if (!registryAddress || registryAddress === EMPTY_ADDRESS) {
45 | throw new ErrorWithCode(
46 | `${asset} not supported on ${network.selector} - unable to get ${asset} ${lookup}`,
47 | EVM_ERROR.ASSET_NOT_SUPPORTED,
48 | );
49 | }
50 | return registryAddress;
51 | } catch (error: unknown) {
52 | throw ErrorWithCode.updateError(
53 | error,
54 | EVM_ERROR.NETWORK_ERROR,
55 | `Error looking up ${asset} ${lookup}`,
56 | );
57 | }
58 | };
59 |
60 | export const getMintGateway = createGatewayRegistryFetcher(
61 | GatewayRegistryLookup.MintGateway,
62 | );
63 | export const getLockGateway = createGatewayRegistryFetcher(
64 | GatewayRegistryLookup.LockGateway,
65 | );
66 | export const getRenAsset = createGatewayRegistryFetcher(
67 | GatewayRegistryLookup.RenAsset,
68 | );
69 | export const getLockAsset = createGatewayRegistryFetcher(
70 | GatewayRegistryLookup.LockAsset,
71 | );
72 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/utils/payloads/evmNoncePayload.ts:
--------------------------------------------------------------------------------
1 | import { PopulatedTransaction } from "ethers";
2 |
3 | import { EVMPayloadInterface, PayloadHandler } from "./evmParams";
4 |
5 | export type EVMNoncePayload = EVMPayloadInterface<
6 | "nonce",
7 | {
8 | nonce: string | number;
9 | }
10 | >;
11 |
12 | export const noncePayloadHandler: PayloadHandler = {
13 | export: (): PopulatedTransaction => {
14 | throw new Error(`Unable to export nonce payload.`);
15 | },
16 | };
17 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/src/utils/payloads/evmTxPayload.ts:
--------------------------------------------------------------------------------
1 | import { ChainTransaction } from "@renproject/utils";
2 | import { PopulatedTransaction } from "ethers";
3 |
4 | import { EVMPayloadInterface, PayloadHandler } from "./evmParams";
5 |
6 | export type EVMTxPayload = EVMPayloadInterface<
7 | "transaction",
8 | {
9 | tx: ChainTransaction;
10 | }
11 | >;
12 |
13 | export const txPayloadHandler: PayloadHandler = {
14 | export: (): PopulatedTransaction => {
15 | throw new Error(`Unable to export transaction payload.`);
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/test/abi.spec.ts:
--------------------------------------------------------------------------------
1 | import chai, { expect } from "chai";
2 |
3 | import { payloadToABI, payloadToMintABI } from "../src/utils/abi";
4 |
5 | chai.should();
6 |
7 | describe("abi.ts", () => {
8 | it("payloadToABI", () => {
9 | const expectedABI = [
10 | {
11 | name: "functionName",
12 | type: "function",
13 | inputs: [
14 | { type: "address", name: "_spender" },
15 | { type: "uint256", name: "_value" },
16 | ],
17 | stateMutability: "payable",
18 | outputs: [],
19 | },
20 | ];
21 |
22 | payloadToABI("functionName", [
23 | { name: "_spender", type: "address", value: "ethereum.eth" },
24 | { name: "_value", type: "uint256", value: 1 },
25 | ]).should.deep.eq(expectedABI);
26 | });
27 |
28 | it("payloadToMintABI", () => {
29 | const expectedABI = {
30 | constant: false,
31 | inputs: [
32 | { name: "_spender", type: "address" },
33 | { name: "_value", type: "uint256" },
34 | { name: "_amount", type: "uint256" },
35 | { name: "_nHash", type: "bytes32" },
36 | { name: "_sig", type: "bytes" },
37 | ],
38 | name: "functionName",
39 | outputs: [],
40 | payable: true,
41 | stateMutability: "payable",
42 | type: "function",
43 | };
44 |
45 | payloadToMintABI("functionName", [
46 | { name: "_spender", type: "address", value: "ethereum.eth" },
47 | { name: "_value", type: "uint256", value: 1 },
48 | ]).should.deep.eq(expectedABI);
49 | });
50 |
51 | it("fixTuple", () => {
52 | expect(
53 | payloadToABI("methodWithTuple", [
54 | {
55 | type: "tuple(address,uint256,address,bytes)",
56 | name: "param",
57 | value: [
58 | "0x0000000000000000000000000000000000000000",
59 | 0,
60 | "0x0000000000000000000000000000000000000000",
61 | Buffer.from([0]),
62 | ],
63 | },
64 | ])[0].inputs[0].components.length,
65 | ).to.equal(4);
66 | });
67 | });
68 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/test/assets.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { join } from "path";
4 |
5 | import { RenNetwork } from "@renproject/utils";
6 | import chai, { expect } from "chai";
7 | import { config as loadDotEnv } from "dotenv";
8 |
9 | import { Goerli, resolveRpcEndpoints } from "../src";
10 |
11 | loadDotEnv({ path: join(__dirname, "../../../../.env") });
12 |
13 | chai.should();
14 |
15 | describe("asset", () => {
16 | it("Fetch lock and mint assets", async () => {
17 | const chain = new Goerli({
18 | provider: resolveRpcEndpoints(
19 | Goerli.configMap["testnet"].config.rpcUrls,
20 | {
21 | INFURA_API_KEY: process.env.INFURA_KEY,
22 | },
23 | )[0],
24 | network: RenNetwork.Testnet,
25 | defaultTestnet: "goerli",
26 | });
27 |
28 | expect(await chain.getLockAsset("DAI_Goerli")).to.not.be.empty;
29 | expect(await chain.getLockAsset("USDC_Goerli")).to.not.be.empty;
30 | expect(await chain.getLockAsset("REN_Goerli")).to.not.be.empty;
31 | expect(await chain.getLockAsset("USDT_Goerli")).to.not.be.empty;
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/test/initialization.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { join } from "path";
4 |
5 | import { RenNetwork } from "@renproject/utils";
6 | import chai, { expect } from "chai";
7 | import { config as loadDotEnv } from "dotenv";
8 |
9 | import { Ethereum } from "../src/ethereum";
10 |
11 | loadDotEnv({ path: join(__dirname, "../../../../.env") });
12 |
13 | chai.should();
14 |
15 | describe("Initialization", () => {
16 | it("Initialize with correct testnet", async () => {
17 | const mainnet = new Ethereum({
18 | network: RenNetwork.Mainnet,
19 | provider: "",
20 | defaultTestnet: "goerli",
21 | });
22 |
23 | expect(mainnet.configMap.mainnet.selector).to.equal("Ethereum");
24 | expect(mainnet.assets.ETH).to.equal("ETH");
25 |
26 | const goerli = new Ethereum({
27 | network: RenNetwork.Testnet,
28 | provider: "",
29 | defaultTestnet: "goerli",
30 | });
31 |
32 | expect(goerli.configMap.testnet.selector).to.equal("Goerli");
33 | expect(goerli.assets.ETH).to.equal("gETH");
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/test/logs.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { join } from "path";
4 |
5 | import { RenNetwork } from "@renproject/utils";
6 | import chai from "chai";
7 | import { config as loadDotEnv } from "dotenv";
8 | import { providers } from "ethers";
9 |
10 | import { BinanceSmartChain } from "../src";
11 | import { findABIMethod, LockGatewayABI } from "../src/contracts";
12 | import { LogLockToChainEvent } from "../src/contracts/typechain/LockGatewayV3";
13 | import { Ethereum } from "../src/ethereum";
14 | import { getMintGateway } from "../src/utils/gatewayRegistry";
15 | import {
16 | filterLogs,
17 | mapLockLogToInputChainTransaction,
18 | } from "../src/utils/generic";
19 |
20 | loadDotEnv({ path: join(__dirname, "../../../../.env") });
21 |
22 | chai.should();
23 |
24 | describe("Logs", () => {
25 | it.skip("LogLock", async () => {
26 | const network = RenNetwork.Testnet;
27 | const ethNetwork = Ethereum.configMap[network];
28 |
29 | const infuraURL = ethNetwork.config.rpcUrls[0];
30 |
31 | const provider = new providers.JsonRpcProvider(infuraURL);
32 |
33 | const txHash =
34 | "0x9c272d76e8067833c391af3e0cb5f3e23699db508216816c6a8288fdfbe243a1";
35 | const receipt = await provider.getTransactionReceipt(txHash);
36 |
37 | const logLockABI = findABIMethod(LockGatewayABI, "LogLockToChain");
38 | const lockDetails = filterLogs(
39 | receipt.logs,
40 | logLockABI,
41 | ).map((e) =>
42 | mapLockLogToInputChainTransaction("Ethereun", "BTC", e.event, ""),
43 | );
44 | console.debug(lockDetails);
45 | });
46 |
47 | it("Get mint gateway", async () => {
48 | const network = RenNetwork.Testnet;
49 | const ethNetwork = BinanceSmartChain.configMap[network];
50 |
51 | const infuraURL = ethNetwork.config.rpcUrls[0];
52 |
53 | const provider = new providers.JsonRpcProvider(infuraURL);
54 |
55 | console.debug(await getMintGateway(ethNetwork, provider, "DAI"));
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/chains/chains-ethereum/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains-filecoin`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains-filecoin` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains_filecoin.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains-filecoin",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@glif/filecoin-address": "1.1.0",
46 | "@glif/filecoin-rpc-client": "1.1.0",
47 | "@renproject/utils": "^3.6.0",
48 | "@types/elliptic": "6.4.14",
49 | "bignumber.js": "9.0.2",
50 | "blakejs": "1.2.1",
51 | "elliptic": "6.5.4",
52 | "multiformats": "9.7.1"
53 | },
54 | "nyc": {
55 | "extends": "@istanbuljs/nyc-config-typescript",
56 | "exclude": [
57 | "**/*.d.ts",
58 | "**/*.spec.js"
59 | ],
60 | "include": [
61 | "src"
62 | ]
63 | },
64 | "prettier": {
65 | "printWidth": 80,
66 | "semi": true,
67 | "singleQuote": false,
68 | "tabWidth": 4,
69 | "trailingComma": "all",
70 | "endOfLine": "lf",
71 | "arrowParens": "always"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./filecoin";
2 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/src/utils/declarations.d.ts:
--------------------------------------------------------------------------------
1 | declare module "blakejs";
2 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/src/utils/deposit.ts:
--------------------------------------------------------------------------------
1 | export enum FilNetwork {
2 | Mainnet = "mainnet",
3 | Testnet = "testnet",
4 | }
5 |
6 | export interface FilTransaction {
7 | cid: string;
8 |
9 | amount: string; // 18 decimal places
10 | params: string; // base64
11 | confirmations: number;
12 | nonce: number;
13 |
14 | reverted?: boolean;
15 | }
16 |
17 | export interface FilExplorer {
18 | fetchDeposits: (
19 | address: string,
20 | params?: string | undefined,
21 | page?: number,
22 | ) => Promise;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/src/utils/lotus.ts:
--------------------------------------------------------------------------------
1 | import FilecoinClient from "@glif/filecoin-rpc-client";
2 |
3 | import { FilTransaction } from "./deposit";
4 |
5 | export const getHeight = async (client: FilecoinClient): Promise => {
6 | const chainHead = await client.request("ChainHead");
7 | return chainHead.Height;
8 | };
9 |
10 | export const fetchDeposits = async (
11 | client: FilecoinClient,
12 | address: string,
13 | // params: string | undefined | null,
14 | addressPrefix: string,
15 | fromHeight: number,
16 | latestHeight: number,
17 | ): Promise => {
18 | const latestTXs: Array<{ "/": string }> = await client.request(
19 | "StateListMessages",
20 | {
21 | Version: 0,
22 | To: address,
23 | From: null,
24 | Nonce: 0,
25 | Value: "0",
26 | GasPrice: "0",
27 | GasLimit: 0,
28 | Method: 0,
29 | Params: undefined,
30 | },
31 | [],
32 | fromHeight,
33 | );
34 |
35 | return await Promise.all(
36 | (latestTXs || []).map(async (cid) =>
37 | fetchMessage(client, cid["/"], addressPrefix, latestHeight),
38 | ),
39 | );
40 | };
41 |
42 | export const fetchMessage = async (
43 | client: FilecoinClient,
44 | cid: string,
45 | addressPrefix: string,
46 | height?: number,
47 | ): Promise => {
48 | const [details, receipt, { Height: chainHeight }]: [
49 | ChainMessage,
50 | StateMsg | undefined,
51 | { Height: number },
52 | ] = await Promise.all([
53 | client.request("ChainGetMessage", { "/": cid }),
54 | client.request("StateSearchMsg", { "/": cid }).catch(() => undefined),
55 | height ? { Height: height } : client.request("ChainHead"),
56 | ]);
57 |
58 | // Fix addresses.
59 | details.To = details.To.replace(/^f/, addressPrefix);
60 | details.From = details.From.replace(/^f/, addressPrefix);
61 |
62 | const tx: FilTransaction = {
63 | cid,
64 | amount: details.Value,
65 | params: details.Params || "",
66 | nonce: details.Nonce,
67 | confirmations: receipt ? chainHeight - receipt.Height : 0,
68 | };
69 |
70 | return tx;
71 | };
72 |
73 | export interface ChainMessage {
74 | Version: number; // 0;
75 | To: string; // "t1gvyvits5chiahib7cz6uyh6kijgqgycnaiuj47i";
76 | From: string; // "t14wczuvodunv3xzexobzywpbj6qpr6jwdrbkrmbq";
77 | Nonce: number; // 20;
78 | Value: string; // "1000000000000000000";
79 | GasLimit: number; // 609960;
80 | GasFeeCap: string; // "101409";
81 | GasPremium: string; // "100355";
82 | Method: number; // 0;
83 | Params: string | null; // null;
84 | CID: {
85 | "/": string; // "bafy2bzacebhs4svm2bl5zq5geaxtywctwlo2sys7udbefpggsrouwfcepv5vu";
86 | };
87 | }
88 |
89 | export interface StateMsg {
90 | Message: {
91 | "/": string; // "bafy2bzaceaq23gg46ii4zowpnzpo33252t5lsdxxfpa5d7cyezsaczqdzefl2";
92 | };
93 | Receipt: {
94 | ExitCode: number; // 0;
95 | Return: null; // null;
96 | GasUsed: number; // 487968
97 | };
98 | ReturnDec: null; // null;
99 | TipSet: [
100 | {
101 | "/": string; // "bafy2bzaced6lrvssnkr27dd5akp4zxr2awjxjl73s5meaq42j7sacfwastfpi";
102 | },
103 | ];
104 | Height: number; // 174172;
105 | }
106 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/src/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { CID } from "multiformats";
2 |
3 | /**
4 | * Convert a Filecoin transaction hash from its standard format to the format
5 | * required by RenVM.
6 | *
7 | * @param txHash A Filecoin transaction hash formatted as a CID string.
8 | * @returns The same Filecoin transaction hash as bytes.
9 | */
10 | export const txHashToBytes = (txHash: string): Uint8Array => {
11 | return new Uint8Array(CID.parse(txHash).bytes);
12 | };
13 |
14 | /**
15 | * Convert a Filecoin transaction hash from the format required by RenVM to its
16 | * standard format.
17 | *
18 | * @param bytes A Filecoin transaction hash as bytes.
19 | * @returns The same Filecoin transaction hash formatted as a CID string.
20 | */
21 | export const txHashFromBytes = (bytes: Uint8Array): string => {
22 | return CID.decode(bytes).toString();
23 | };
24 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/test/explorers.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { join } from "path";
4 |
5 | import chai from "chai";
6 | import { config as loadDotEnv } from "dotenv";
7 |
8 | import { Filfox } from "../src/utils/filfox";
9 |
10 | chai.should();
11 |
12 | loadDotEnv({ path: join(__dirname, "../../../../.env") });
13 |
14 | describe.skip("Filecoin explorers", () => {
15 | it("mint to contract", async () => {
16 | const filfox = new Filfox("mainnet");
17 |
18 | console.debug(
19 | "filfox",
20 | await filfox.fetchDeposits(
21 | "f15wjyn36z6x5ypq7f73yaolqbxyiiwkg5mmuyo2q",
22 | 0,
23 | 1,
24 | ),
25 | );
26 | }).timeout(100000000000);
27 | });
28 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/chains/chains-filecoin/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains-solana`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains-solana` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains_solana.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains-solana",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@renproject/utils": "^3.6.0",
46 | "@scure/bip39": "1.1.0",
47 | "@solana/spl-token": "0.2.0",
48 | "@solana/web3.js": "1.50.1",
49 | "@types/bs58": "4.0.1",
50 | "@types/node-fetch": "2.6.2",
51 | "bignumber.js": "9.0.2",
52 | "bs58": "5.0.0",
53 | "buffer-layout": "1.2.2",
54 | "ed25519-hd-key": "1.3.0",
55 | "tweetnacl": "1.0.3"
56 | },
57 | "nyc": {
58 | "extends": "@istanbuljs/nyc-config-typescript",
59 | "exclude": [
60 | "**/*.d.ts",
61 | "**/*.spec.js"
62 | ],
63 | "include": [
64 | "src"
65 | ]
66 | },
67 | "prettier": {
68 | "printWidth": 80,
69 | "semi": true,
70 | "singleQuote": false,
71 | "tabWidth": 4,
72 | "trailingComma": "all",
73 | "endOfLine": "lf",
74 | "arrowParens": "always"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/src/declarations/declarations.d.ts:
--------------------------------------------------------------------------------
1 | declare module "buffer-layout";
2 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/src/index.ts:
--------------------------------------------------------------------------------
1 | export { Solana } from "./solana";
2 | export * from "./types/types";
3 |
4 | export { SolNetworkConfig, renMainnet, renTestnet } from "./networks";
5 | export { signerFromPrivateKey } from "./utils";
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/src/networks.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | export interface SolNetworkConfig {
4 | name: RenNetwork;
5 | symbol: string;
6 | chain: string;
7 | isTestnet?: boolean;
8 | chainLabel: string;
9 |
10 | nativeAsset: {
11 | name: string;
12 | symbol: string;
13 | decimals: number;
14 | };
15 | averageConfirmationTime: number;
16 |
17 | chainExplorer: string;
18 | endpoint: string;
19 | addresses: {
20 | GatewayRegistry: string;
21 | };
22 | // used for identifying the network (similar to chainID in eth)
23 | genesisHash: string;
24 | }
25 |
26 | const isSolNetworkConfig = (x: unknown): x is SolNetworkConfig =>
27 | (x as SolNetworkConfig).genesisHash !== undefined;
28 |
29 | export const resolveNetwork = (
30 | networkInput: RenNetwork | `${RenNetwork}` | SolNetworkConfig,
31 | ): SolNetworkConfig => {
32 | if (typeof networkInput === "string") {
33 | switch (networkInput) {
34 | case RenNetwork.Mainnet:
35 | return renMainnet;
36 | case RenNetwork.Testnet:
37 | return renTestnet;
38 | }
39 | throw new Error(`Unrecognized solana network ${networkInput}.`);
40 | }
41 | if (isSolNetworkConfig(networkInput)) {
42 | return networkInput;
43 | }
44 | // TODO: Throw better error and point out any missing fields.
45 | throw new Error(
46 | `Unrecognized solana network configuration (${String(networkInput)}).`,
47 | );
48 | };
49 |
50 | export const renMainnet: SolNetworkConfig = {
51 | name: RenNetwork.Mainnet,
52 | symbol: "SOL",
53 | chain: "mainnet-beta",
54 | chainLabel: "Mainnet Beta",
55 |
56 | nativeAsset: {
57 | name: "Solana",
58 | symbol: "SOL",
59 | decimals: 18,
60 | },
61 | averageConfirmationTime: 0.5,
62 |
63 | endpoint: "https://ren.rpcpool.com/",
64 | chainExplorer: "https://explorer.solana.com",
65 | addresses: {
66 | GatewayRegistry: "REGrPFKQhRneFFdUV3e9UDdzqUJyS6SKj88GdXFCRd2",
67 | },
68 | genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d",
69 | };
70 |
71 | export const renTestnet: SolNetworkConfig = {
72 | name: RenNetwork.Testnet,
73 | symbol: "SOL",
74 | chain: "devnet",
75 | isTestnet: true,
76 | chainLabel: "Devnet",
77 |
78 | nativeAsset: {
79 | name: "Solana",
80 | symbol: "SOL",
81 | decimals: 18,
82 | },
83 | averageConfirmationTime: 0.5,
84 |
85 | endpoint: "https://api.devnet.solana.com",
86 | chainExplorer: "https://explorer.solana.com",
87 | addresses: {
88 | GatewayRegistry: "REGrPFKQhRneFFdUV3e9UDdzqUJyS6SKj88GdXFCRd2",
89 | },
90 | genesisHash: "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG",
91 | };
92 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/src/types/types.ts:
--------------------------------------------------------------------------------
1 | import { ChainTransaction } from "@renproject/utils";
2 | import { Connection } from "@solana/web3.js";
3 |
4 | import { Wallet } from "../wallet";
5 |
6 | export type SolanaProvider = Connection;
7 | export type SolanaSigner = Wallet;
8 |
9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
10 | export interface SolanaPayloadInterface {
11 | chain: string;
12 | type: Name;
13 | params: T;
14 | setup?: {
15 | [name: string]: SolanaPayloadInterface;
16 | };
17 | }
18 |
19 | export type MintToAddress = SolanaPayloadInterface<
20 | "mintToAddress",
21 | {
22 | to: string;
23 | }
24 | >;
25 |
26 | export type MintToTokenAddress = SolanaPayloadInterface<
27 | "mintToTokenAddress",
28 | {
29 | to: string;
30 | }
31 | >;
32 |
33 | export type BurnFromAddress = SolanaPayloadInterface<
34 | "burnToAddress",
35 | {
36 | amount: number | string;
37 | convertUnit?: boolean;
38 | address?: string;
39 | }
40 | >;
41 |
42 | export type BurnNonce = SolanaPayloadInterface<
43 | "burnNonce",
44 | {
45 | burnNonce: string | number;
46 | }
47 | >;
48 |
49 | export type Transaction = SolanaPayloadInterface<
50 | "transaction",
51 | {
52 | tx: ChainTransaction;
53 | }
54 | >;
55 |
56 | export type SolanaOutputPayload = MintToAddress | MintToTokenAddress;
57 | export type SolanaInputPayload = BurnFromAddress | BurnNonce | Transaction;
58 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/src/wallet.ts:
--------------------------------------------------------------------------------
1 | import { PublicKey, Transaction } from "@solana/web3.js";
2 |
3 | // See @project-serum/sol-wallet-adapter
4 | export type Wallet = {
5 | signTransaction(transaction: Transaction): Promise;
6 | publicKey: PublicKey;
7 | };
8 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/test/utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { Connection } from "@solana/web3.js";
2 | import { expect } from "chai";
3 |
4 | import { Solana } from "../src";
5 | import { signerFromMnemonic, signerFromPrivateKey } from "../src/utils";
6 |
7 | describe("Utils", () => {
8 | it("validateTransaction", () => {
9 | const solana = new Solana({
10 | network: "testnet",
11 | provider: {} as unknown as Connection,
12 | });
13 |
14 | expect(
15 | solana.validateTransaction({
16 | txHash: "3mabcf8u7eduVN3GfM8nyGwJ3g3GqApqbGq8m2CtoakgeEVHsw1ZgqSL7KWCRaEdK9rcHUwWNfpkGAb17ewC6XwV",
17 | }),
18 | ).to.be.true;
19 |
20 | expect(
21 | solana.validateTransaction({
22 | txHash: "3mabcf8u7eduVN3GfM8nyGwJ3g3GqApqbGq8m2CtoakgeEVHsw1ZgqSL7KWCRaEdK9rcHUwWNfpkGAb17ewC6XwV",
23 | txid: "ino6crZYCRm5Lm6kMlt9hZo68stwCZywdXZdsttSXoB_tDfB7cB4fDdeBX-xodXoFwZl3MfKpwDj0_tKDogfCA",
24 | txindex: "0",
25 | }),
26 | ).to.be.true;
27 | });
28 |
29 | it("signerFromMnemonic", () => {
30 | // Test mnemonic - DO NOT USE.
31 | const mnemonic =
32 | "fiber quarter possible fluid fatal harvest layer harsh east neck jewel marine";
33 |
34 | const signer1 = signerFromMnemonic(mnemonic);
35 | expect(signer1.publicKey.toBase58()).to.equal(
36 | "GCQcNnHZ712nkkNeGFhHRj22qbps3tmvesSu2bhb3U4f",
37 | );
38 |
39 | const signer2 = signerFromMnemonic(mnemonic, "m/44'/501'/0'");
40 | expect(signer2.publicKey.toBase58()).to.equal(
41 | "8dMCt1MtKNaFrBJeb6Bp5FETSqQPqB4gGsAFqWpsNvoc",
42 | );
43 | });
44 |
45 | it("signerFromPrivateKey", () => {
46 | // Test private keys - DO NOT USE.
47 |
48 | // From hex.
49 | const signer1 = signerFromPrivateKey(
50 | "1cd9ae6e2b1ba34523096765bae7f0f95563254469934e97c3c282171748f57ae1cb637c9b36af38f20615450a15d45278825cad9dc2c59e2a2e4e77fad57210",
51 | );
52 | expect(signer1.publicKey.toBase58()).to.equal(
53 | "GCQcNnHZ712nkkNeGFhHRj22qbps3tmvesSu2bhb3U4f",
54 | );
55 |
56 | // From base58.
57 | const signer2 = signerFromPrivateKey(
58 | "aTPc1419CrWBNz95E5YNpaR6Tq1D1Jnq2XiyoGy9TdyrFSmYJRmZ8DBcETrWWhJg6s5g9Q6Xss9GstKntEUdVGB",
59 | );
60 | expect(signer2.publicKey.toBase58()).to.equal(
61 | "GCQcNnHZ712nkkNeGFhHRj22qbps3tmvesSu2bhb3U4f",
62 | );
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "downlevelIteration": true,
6 | "rootDir": "src",
7 | "moduleResolution": "node",
8 | "module": "commonjs",
9 | "declaration": true,
10 | "removeComments": false,
11 | "esModuleInterop": true,
12 | "strict": true,
13 | "noUnusedLocals": false,
14 | "noUnusedParameters": true,
15 | "noImplicitReturns": true,
16 | "noFallthroughCasesInSwitch": true,
17 | "traceResolution": false,
18 | "listEmittedFiles": false,
19 | "listFiles": false,
20 | "pretty": true,
21 | "lib": ["es2017", "dom"],
22 | "types": ["node"],
23 | "typeRoots": ["node_modules/@types", "src/types"],
24 | "resolveJsonModule": true,
25 | "forceConsistentCasingInFileNames": true,
26 | "noImplicitThis": true,
27 | "noImplicitAny": true,
28 | "strictNullChecks": true,
29 | "suppressImplicitAnyIndexErrors": true,
30 | "strictPropertyInitialization": true,
31 | "alwaysStrict": true,
32 | "strictFunctionTypes": true,
33 | "sourceMap": true,
34 | "declarationMap": true,
35 | "skipLibCheck": true
36 | },
37 | "include": ["src/**/*.ts"],
38 | "exclude": ["node_modules/**"],
39 | "compileOnSave": false
40 | }
41 |
--------------------------------------------------------------------------------
/packages/chains/chains-solana/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es2020",
5 | "outDir": "build/module",
6 | "module": "es2020"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains-terra`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains-terra` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains_terra.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains-terra",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@renproject/utils": "^3.6.0",
46 | "@terra-money/terra.js": "3.1.5",
47 | "@types/elliptic": "6.4.14",
48 | "bech32": "2.0.0",
49 | "bignumber.js": "9.0.2",
50 | "elliptic": "6.5.4"
51 | },
52 | "nyc": {
53 | "extends": "@istanbuljs/nyc-config-typescript",
54 | "exclude": [
55 | "**/*.d.ts",
56 | "**/*.spec.js"
57 | ],
58 | "include": [
59 | "src"
60 | ]
61 | },
62 | "prettier": {
63 | "printWidth": 80,
64 | "semi": true,
65 | "singleQuote": false,
66 | "tabWidth": 4,
67 | "trailingComma": "all",
68 | "endOfLine": "lf",
69 | "arrowParens": "always"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/src/api/types.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from "bignumber.js";
2 |
3 | export interface TerraNetworkConfig {
4 | selector: string;
5 | chainId: string;
6 | addressPrefix: string;
7 | isTestnet?: boolean;
8 |
9 | nativeAsset: {
10 | name: string;
11 | symbol: string;
12 | decimals: number;
13 | };
14 | averageConfirmationTime: number;
15 | explorer: string;
16 | apiUrl: string;
17 | }
18 |
19 | export const isTerraNetworkConfig = (
20 | renNetwork: unknown,
21 | ): renNetwork is TerraNetworkConfig =>
22 | !!(renNetwork as TerraNetworkConfig).selector &&
23 | !!(renNetwork as TerraNetworkConfig).chainId &&
24 | !!(renNetwork as TerraNetworkConfig).nativeAsset &&
25 | !!(renNetwork as TerraNetworkConfig).explorer &&
26 | !!(renNetwork as TerraNetworkConfig).apiUrl;
27 |
28 | export interface TerraTransaction {
29 | hash: string;
30 | from: string;
31 | to: string;
32 | denomination: string;
33 | amount: string;
34 | memo: string;
35 | confirmations: number;
36 | messageIndex: number;
37 | }
38 |
39 | export interface TerraAPI {
40 | fetchDeposits: (
41 | address: string,
42 | memo?: string | undefined,
43 | page?: number,
44 | ) => Promise;
45 |
46 | fetchConfirmations: (hash: string) => Promise;
47 | }
48 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./terra";
2 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { utils } from "@renproject/utils";
2 |
3 | /**
4 | * Convert a Terra transaction hash from its standard format to the format
5 | * required by RenVM.
6 | *
7 | * @param txHash A Terra transaction hash formatted as an unprefixed
8 | * hex string.
9 | * @returns The same Terra transaction hash formatted as a base64 string.
10 | */
11 | export const txHashToBytes = (txHash: string): Uint8Array => {
12 | return utils.fromHex(txHash);
13 | };
14 |
15 | /**
16 | * Convert a Terra transaction hash from the format required by RenVM to its
17 | * standard format.
18 | *
19 | * @param bytes A Terra transaction hash formatted as a base64 string.
20 | * @returns The same Terra transaction hash formatted as an unprefixed hex
21 | * string.
22 | */
23 | export const txHashFromBytes = (bytes: Uint8Array): string => {
24 | return utils.toHex(bytes).toUpperCase();
25 | };
26 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/test/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 |
3 | import { Terra } from "../src";
4 |
5 | describe("@renproject/chains-terra", () => {
6 | it("should export Terra correctly", async () => {
7 | expect(Terra).not.to.equal(undefined);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/test/utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 |
3 | import { Terra } from "../src";
4 |
5 | describe("Utils", () => {
6 | it("validateTransaction", () => {
7 | const terra = new Terra({
8 | network: "testnet",
9 | });
10 |
11 | expect(
12 | terra.validateTransaction({
13 | txHash: "79EC7C5DBA526D3C3B7CCCFFDA1B06F16D3E2402A3D6B82D7D251F26B68C4489",
14 | }),
15 | ).to.be.true;
16 |
17 | expect(
18 | terra.validateTransaction({
19 | txHash: "79EC7C5DBA526D3C3B7CCCFFDA1B06F16D3E2402A3D6B82D7D251F26B68C4489",
20 | txid: "eex8XbpSbTw7fMz_2hsG8W0-JAKj1rgtfSUfJraMRIk",
21 | txindex: "0",
22 | }),
23 | ).to.be.true;
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/chains/chains-terra/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/chains/chains/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/chains`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/chains` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_chains.html)
6 |
--------------------------------------------------------------------------------
/packages/chains/chains/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/chains",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@renproject/chains-bitcoin": "^3.6.0",
46 | "@renproject/chains-ethereum": "^3.6.0",
47 | "@renproject/chains-filecoin": "^3.6.0",
48 | "@renproject/chains-solana": "^3.6.0",
49 | "@renproject/chains-terra": "^3.6.0",
50 | "@renproject/utils": "^3.6.0"
51 | },
52 | "nyc": {
53 | "extends": "@istanbuljs/nyc-config-typescript",
54 | "exclude": [
55 | "**/*.d.ts",
56 | "**/*.spec.js"
57 | ],
58 | "include": [
59 | "src"
60 | ]
61 | },
62 | "prettier": {
63 | "printWidth": 80,
64 | "semi": true,
65 | "singleQuote": false,
66 | "tabWidth": 4,
67 | "trailingComma": "all",
68 | "endOfLine": "lf",
69 | "arrowParens": "always"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/packages/chains/chains/src/declarations/declarations.d.ts:
--------------------------------------------------------------------------------
1 | // declare module "wallet-address-validator";
2 | // declare module "wallet-address-validator/src/bitcoin_validator";
3 | // declare module "blakejs";
4 | declare module "buffer-layout";
5 |
--------------------------------------------------------------------------------
/packages/chains/chains/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "@renproject/chains-bitcoin";
2 | export * from "@renproject/chains-ethereum";
3 | export * from "@renproject/chains-filecoin";
4 | export * from "@renproject/chains-terra";
5 | export * from "@renproject/chains-solana";
6 |
7 | import {
8 | Bitcoin,
9 | BitcoinCash,
10 | DigiByte,
11 | Dogecoin,
12 | Zcash,
13 | } from "@renproject/chains-bitcoin";
14 | import {
15 | Arbitrum,
16 | Avalanche,
17 | BinanceSmartChain,
18 | Catalog,
19 | Ethereum,
20 | Fantom,
21 | Goerli,
22 | Kava,
23 | Moonbeam,
24 | Optimism,
25 | Polygon,
26 | } from "@renproject/chains-ethereum";
27 | import { Filecoin } from "@renproject/chains-filecoin";
28 | import { Solana } from "@renproject/chains-solana";
29 | import { Terra } from "@renproject/chains-terra";
30 | import { RenNetwork } from "@renproject/utils";
31 |
32 | export const chains = {
33 | Arbitrum,
34 | Avalanche,
35 | BinanceSmartChain,
36 | Bitcoin,
37 | BitcoinCash,
38 | Catalog,
39 | DigiByte,
40 | Dogecoin,
41 | Ethereum,
42 | Fantom,
43 | Filecoin,
44 | Goerli,
45 | Kava,
46 | Moonbeam,
47 | Optimism,
48 | Polygon,
49 | Solana,
50 | Terra,
51 | Zcash,
52 | };
53 |
54 | export enum Asset {
55 | ArbETH = "ArbETH",
56 | AVAX = "AVAX",
57 | BADGER = "BADGER",
58 | BCH = "BCH",
59 | BNB = "BNB",
60 | BTC = "BTC",
61 | BUSD = "BUSD",
62 | CRV = "CRV",
63 | DAI = "DAI",
64 | DGB = "DGB",
65 | DOGE = "DOGE",
66 | ETH = "ETH",
67 | EURT = "EURT",
68 | FIL = "FIL",
69 | FTM = "FTM",
70 | FTT = "FTT",
71 | gETH = "gETH",
72 | GLMR = "GLMR",
73 | KAVA = "KAVA",
74 | KNC = "KNC",
75 | LINK = "LINK",
76 | LUNA = "LUNA",
77 | MATIC = "MATIC",
78 | MIM = "MIM",
79 | oETH = "oETH",
80 | REN = "REN",
81 | ROOK = "ROOK",
82 | SOL = "SOL",
83 | SUSHI = "SUSHI",
84 | UNI = "UNI",
85 | USDC = "USDC",
86 | USDT = "USDT",
87 | ZEC = "ZEC",
88 | }
89 |
90 | export const assets = Object.values(chains).reduce(
91 | (acc, chain) =>
92 | acc.concat(
93 | Object.values(
94 | chain.assets[RenNetwork.Mainnet] ||
95 | chain.assets[RenNetwork.Testnet],
96 | ),
97 | ),
98 | [],
99 | );
100 |
101 | /* eslint-disable @typescript-eslint/no-shadow */
102 | export enum Chain {
103 | Arbitrum = "Arbitrum",
104 | Avalanche = "Avalanche",
105 | BinanceSmartChain = "BinanceSmartChain",
106 | Bitcoin = "Bitcoin",
107 | BitcoinCash = "BitcoinCash",
108 | DigiByte = "DigiByte",
109 | Dogecoin = "Dogecoin",
110 | Ethereum = "Ethereum",
111 | Fantom = "Fantom",
112 | Filecoin = "Filecoin",
113 | Goerli = "Goerli",
114 | Kava = "Kava",
115 | Moonbeam = "Moonbeam",
116 | Optimism = "Optimism",
117 | Polygon = "Polygon",
118 | Catalog = "Catalog",
119 | Solana = "Solana",
120 | Terra = "Terra",
121 | Zcash = "Zcash",
122 | }
123 |
124 | export default chains;
125 |
--------------------------------------------------------------------------------
/packages/chains/chains/test/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 |
3 | import * as Chains from "../src";
4 |
5 | describe("@renproject/chains", () => {
6 | it("should export chains correctly", async () => {
7 | expect(Chains.Ethereum).not.to.equal(undefined);
8 | expect(Chains.Bitcoin).not.to.equal(undefined);
9 | expect(Chains.BitcoinCash).not.to.equal(undefined);
10 | expect(Chains.Zcash).not.to.equal(undefined);
11 | expect(Chains.BinanceSmartChain).not.to.equal(undefined);
12 | expect(Chains.Solana).not.to.equal(undefined);
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/packages/chains/chains/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/chains/chains/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/mock-provider/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/mock-provider`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/mock-provider` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_mock_provider.html)
6 |
--------------------------------------------------------------------------------
/packages/mock-provider/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/mock-provider",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s build:main test:* lint",
36 | "test:unit": "nyc ../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@renproject/chains-bitcoin": "^3.6.0",
46 | "@renproject/provider": "^3.6.0",
47 | "@renproject/utils": "^3.6.0",
48 | "@types/elliptic": "6.4.14",
49 | "bignumber.js": "9.0.2",
50 | "elliptic": "6.5.4",
51 | "ethereumjs-util": "7.1.5",
52 | "immutable": "4.1.0"
53 | },
54 | "nyc": {
55 | "extends": "@istanbuljs/nyc-config-typescript",
56 | "exclude": [
57 | "**/*.d.ts",
58 | "**/*.spec.js"
59 | ],
60 | "include": [
61 | "src"
62 | ]
63 | },
64 | "prettier": {
65 | "printWidth": 80,
66 | "semi": true,
67 | "singleQuote": false,
68 | "tabWidth": 4,
69 | "trailingComma": "all",
70 | "endOfLine": "lf",
71 | "arrowParens": "always"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/packages/mock-provider/src/MockChain.ts:
--------------------------------------------------------------------------------
1 | import {
2 | BitcoinBaseChain,
3 | BitcoinInputPayload,
4 | BitcoinOutputPayload,
5 | } from "@renproject/chains-bitcoin";
6 | import { UTXO } from "@renproject/chains-bitcoin/APIs/API";
7 | import { DepositChain, utils } from "@renproject/utils";
8 | import BigNumber from "bignumber.js";
9 |
10 | import { randomBytes } from "./utils";
11 |
12 | export class MockChain
13 | extends BitcoinBaseChain
14 | implements DepositChain
15 | {
16 | public mempool: Array;
17 |
18 | public assets: {
19 | default: string;
20 | };
21 |
22 | public constructor({ chain, asset }: { chain: string; asset: string }) {
23 | super({
24 | network: {
25 | label: chain,
26 | selector: chain,
27 |
28 | nativeAsset: {
29 | name: asset,
30 | symbol: asset,
31 | decimals: 8,
32 | },
33 | averageConfirmationTime: 1,
34 |
35 | isTestnet: true,
36 | p2shPrefix: new Uint8Array([0xc4]),
37 | explorer: {
38 | url: "",
39 | address: (_address: string) => "",
40 | transaction: (_txid: string) => "",
41 | },
42 | providers: [
43 | {
44 | fetchHeight: async () => Promise.resolve("6"),
45 | fetchUTXO: async (txid: string, txindex: string) =>
46 | this.fetchUTXO(txid, txindex),
47 | fetchUTXOs: async (address: string) =>
48 | this.fetchUTXOs(address),
49 | fetchTXs: (_address: string) => Promise.resolve([]),
50 | },
51 | ],
52 | },
53 | });
54 | this.mempool = [];
55 | this.chain = chain;
56 | this.assets = {
57 | default: asset,
58 | };
59 | }
60 |
61 | // eslint-disable-next-line @typescript-eslint/require-await
62 | public fetchUTXO = async (txid: string, txindex: string): Promise => {
63 | const utxo = this.mempool.find(
64 | (x) => x.txid === txid && x.txindex === txindex,
65 | );
66 | if (utxo) {
67 | return utxo;
68 | }
69 | throw new Error(`UTXO ${txid}, ${txindex} not found`);
70 | };
71 | // eslint-disable-next-line @typescript-eslint/require-await
72 | public fetchUTXOs = async (address: string): Promise =>
73 | this.mempool.filter((x) => x.to === address);
74 |
75 | public addUTXO = (to: string, amount: BigNumber | number): UTXO => {
76 | const tx: UTXO & { to: string } = {
77 | to,
78 | txid: utils.toHex(randomBytes(32)),
79 | txindex: "0",
80 | amount: amount.toString(),
81 | height: "0",
82 | };
83 | this.mempool.push(tx);
84 | return tx;
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/packages/mock-provider/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./MockProvider";
2 | export * from "./MockChain";
3 |
--------------------------------------------------------------------------------
/packages/mock-provider/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { utils } from "@renproject/utils";
2 |
3 | /**
4 | * Generates a random hex string (prefixed with '0x').
5 | *
6 | * @param bytes The number of bytes to generate.
7 | */
8 | export const randomBytes = (bytes: number): Uint8Array => {
9 | try {
10 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
11 | // @ts-ignore
12 | if (window) {
13 | const uints = new Uint32Array(bytes / 4); // 4 bytes (32 bits)
14 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
15 | // @ts-ignore
16 | window.crypto.getRandomValues(uints);
17 | let str = "";
18 | for (const uint of uints) {
19 | str +=
20 | "0".repeat(8 - uint.toString(16).length) +
21 | String(uint.toString(16));
22 | }
23 | return utils.fromHex(str);
24 | }
25 | } catch (error: unknown) {
26 | // Ignore error
27 | }
28 | // eslint-disable-next-line @typescript-eslint/no-var-requires
29 | const crypto = require("crypto") as {
30 | randomBytes: (length: number) => Uint8Array;
31 | };
32 | return crypto.randomBytes(bytes);
33 | };
34 |
35 | // context("randomBytes", () => {
36 | // // Restore global window state afterwards incase this is being run in
37 | // // a browser environment.
38 | // let previousWindow: unknown;
39 | // before(() => {
40 | // previousWindow = (global as { window: unknown }).window;
41 | // });
42 | // after(() => {
43 | // (global as { window: unknown }).window = previousWindow;
44 | // });
45 |
46 | // it("returns random bytes of the correct length", () => {
47 | // expect(randomBytes(32).length).to.equal(32);
48 | // expect(randomBytes(32)).not.to.equal(randomBytes(32));
49 | // (global as { window: unknown }).window = {
50 | // crypto: {
51 | // getRandomValues: (uints: Uint32Array) => {
52 | // for (let i = 0; i < uints.length; i++) {
53 | // uints[i] = 0;
54 | // }
55 | // },
56 | // },
57 | // };
58 | // expect(randomBytes(32).length).to.equal(32);
59 | // });
60 | // });
61 |
--------------------------------------------------------------------------------
/packages/mock-provider/test/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { RPCMethod } from "@renproject/provider/methods";
2 | import { expect } from "chai";
3 |
4 | import { MockChain, MockProvider } from "../src";
5 |
6 | describe("@renproject/mock-provider", () => {
7 | it("should export MockProvider and MockChain correctly", async () => {
8 | expect(MockProvider).not.to.equal(undefined);
9 | expect(MockChain).not.to.equal(undefined);
10 | });
11 |
12 | it("can provide a gPubKey", async () => {
13 | const gPubKey = "Aw3WX32ykguyKZEuP0IT3RUOX5csm3PpvnFNhEVhrDVc";
14 | const provider = new MockProvider({
15 | gPubKey,
16 | });
17 | const blockState = await provider.sendMessage(
18 | RPCMethod.QueryBlockState,
19 | {
20 | contract: "BTC",
21 | },
22 | );
23 | expect(blockState.state.v["BTC"].shards[0].pubKey).to.equal(gPubKey);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/packages/mock-provider/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/mock-provider/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "esnext",
5 | "outDir": "build/module",
6 | "module": "esnext"
7 | },
8 | "exclude": [
9 | "node_modules/**"
10 | ]
11 | }
--------------------------------------------------------------------------------
/packages/provider/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/provider`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/provider` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_provider.html)
6 |
--------------------------------------------------------------------------------
/packages/provider/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/provider",
3 | "version": "3.6.0",
4 | "description": "Official Ren JavaScript client",
5 | "repository": {
6 | "type": "git",
7 | "url": "git+https://github.com/renproject/ren-js.git"
8 | },
9 | "publishConfig": {
10 | "access": "public",
11 | "directory": "build"
12 | },
13 | "author": "Ren",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/renproject/ren-js/issues"
17 | },
18 | "main": "./build/index.js",
19 | "typings": "./build/index.d.ts",
20 | "module": "./build/module/index.js",
21 | "scripts": {
22 | "clean": "yarn rimraf ./build ./node_modules",
23 | "link": "yarn build:link && cd build && yarn link",
24 | "unlink": "yarn unlink",
25 | "build": "run-s build:*",
26 | "build:main": "tsc -p tsconfig.json",
27 | "build:module": "tsc -p tsconfig.module.json",
28 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
29 | "prettier": "yarn fix:prettier",
30 | "lint": "run-s lint:*",
31 | "lint:eslint": "eslint --config ../../.eslintrc.js src",
32 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
33 | "fix": "run-s fix:*",
34 | "fix:eslint": "yarn lint:eslint --fix",
35 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
36 | "test": "run-s test:* lint",
37 | "test:unit": "nyc ../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
38 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
39 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
40 | "cov:html": "nyc report --reporter=html",
41 | "cov:send": "nyc report --reporter=lcov && codecov",
42 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
43 | "prepare": "yarn build"
44 | },
45 | "dependencies": {
46 | "@renproject/utils": "^3.6.0",
47 | "axios": "0.27.2",
48 | "bignumber.js": "9.0.2"
49 | },
50 | "nyc": {
51 | "extends": "@istanbuljs/nyc-config-typescript",
52 | "exclude": [
53 | "**/*.d.ts",
54 | "**/*.spec.js"
55 | ],
56 | "include": [
57 | "src"
58 | ]
59 | },
60 | "prettier": {
61 | "printWidth": 80,
62 | "semi": true,
63 | "singleQuote": false,
64 | "tabWidth": 4,
65 | "trailingComma": "all",
66 | "endOfLine": "lf",
67 | "arrowParens": "always"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/packages/provider/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./provider";
2 | export * from "./methods/index";
3 | export * from "./methods/ren_queryBlockState";
4 | export * from "./unmarshal";
5 | export * from "./types/core";
6 |
--------------------------------------------------------------------------------
/packages/provider/src/methods/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ParamsQueryBlock,
3 | ParamsQueryBlocks,
4 | ResponseQueryBlock,
5 | ResponseQueryBlocks,
6 | } from "./ren_queryBlock";
7 | import {
8 | ParamsQueryBlockState,
9 | ResponseQueryBlockState,
10 | } from "./ren_queryBlockState";
11 | import { ParamsQueryConfig, ResponseQueryConfig } from "./ren_queryConfig";
12 | import { ParamsSubmitGateway } from "./ren_submitGateway";
13 | import {
14 | ParamsQueryTx,
15 | ParamsQueryTxs,
16 | ParamsSubmitTx,
17 | ResponseQueryTx,
18 | ResponseQueryTxs,
19 | ResponseSubmitGateway,
20 | ResponseSubmitTx,
21 | } from "./ren_submitTx";
22 |
23 | export * from "./ren_queryBlock";
24 | export * from "./ren_queryBlockState";
25 | export * from "./ren_queryConfig";
26 | export * from "./ren_submitGateway";
27 | export * from "./ren_submitTx";
28 |
29 | export enum RPCMethod {
30 | // MethodSubmitGateway submits the details of a gateway to the lightnode,
31 | // used for recovering mints that didn't get submitted to RenVM.
32 | SubmitGateway = "ren_submitGateway",
33 |
34 | // MethodSubmitTx submits a new transaction to the Darknode for acceptance
35 | // into the transaction pool.
36 | SubmitTx = "ren_submitTx",
37 |
38 | // MethodQueryTx returns the latest information about a transaction
39 | // identified by a transaction hash.
40 | QueryTx = "ren_queryTx",
41 |
42 | // MethodQueryTxs returns pages of transactions with optional filtering by
43 | // status and tags.
44 | QueryTxs = "ren_queryTxs",
45 |
46 | // MethodQueryBlock returns a block identified by the block height.
47 | QueryBlock = "ren_queryBlock",
48 |
49 | // MethodQueryBlocks returns recently committed blocks.
50 | QueryBlocks = "ren_queryBlocks",
51 |
52 | // MethodQueryConfig returns the node configuration.
53 | QueryConfig = "ren_queryConfig",
54 |
55 | // MethodQueryBlockState returns the contract state.
56 | QueryBlockState = "ren_queryBlockState",
57 | }
58 |
59 | // /////////////////////////////////////////////////////////////////////////////
60 |
61 | export type RPCParams = {
62 | [RPCMethod.SubmitTx]: ParamsSubmitTx;
63 | [RPCMethod.SubmitGateway]: ParamsSubmitGateway;
64 | [RPCMethod.QueryTx]: ParamsQueryTx;
65 | [RPCMethod.QueryTxs]: ParamsQueryTxs;
66 | [RPCMethod.QueryBlock]: ParamsQueryBlock;
67 | [RPCMethod.QueryBlocks]: ParamsQueryBlocks;
68 | [RPCMethod.QueryConfig]: ParamsQueryConfig;
69 | [RPCMethod.QueryBlockState]: ParamsQueryBlockState;
70 | };
71 |
72 | export type RPCResponses = {
73 | [RPCMethod.SubmitTx]: ResponseSubmitTx;
74 | [RPCMethod.SubmitGateway]: ResponseSubmitGateway;
75 | [RPCMethod.QueryTx]: ResponseQueryTx;
76 | [RPCMethod.QueryTxs]: ResponseQueryTxs;
77 | [RPCMethod.QueryBlock]: ResponseQueryBlock;
78 | [RPCMethod.QueryBlocks]: ResponseQueryBlocks;
79 | [RPCMethod.QueryConfig]: ResponseQueryConfig;
80 | [RPCMethod.QueryBlockState]: ResponseQueryBlockState;
81 | };
82 |
83 | // The following lines will throw a type error if RenVMResponses or RenVMParams
84 | // aren't defined for all RPC methods.
85 | (): RPCParams[RPCMethod] | void => {};
86 | (): RPCResponses[RPCMethod] | void => {};
87 |
--------------------------------------------------------------------------------
/packages/provider/src/methods/ren_queryBlock.ts:
--------------------------------------------------------------------------------
1 | import { Marshalled, PackPrimitive, PackStructType } from "@renproject/utils";
2 |
3 | export const renVMBlockType: PackStructType = {
4 | struct: [
5 | { height: PackPrimitive.U64 },
6 | { hash: PackPrimitive.Bytes },
7 | { parentHash: PackPrimitive.Bytes },
8 | { commitment: { list: PackPrimitive.Bytes } },
9 | { timestamp: PackPrimitive.U64 },
10 | { round: PackPrimitive.U64 },
11 | { stateRoot: PackPrimitive.Bytes },
12 | { intrinsicTxs: { list: PackPrimitive.Bytes } },
13 | { extrinsicTxs: { list: PackPrimitive.Bytes } },
14 | ],
15 | };
16 |
17 | export interface MarshalledRenVMBlock {
18 | height: Marshalled;
19 | hash: Marshalled;
20 | parentHash: Marshalled;
21 | commitment: Array>;
22 | timestamp: Marshalled;
23 | round: Marshalled;
24 | stateRoot: Marshalled;
25 | intrinsicTxs: Array>;
26 | extrinsicTxs: Array>;
27 | }
28 |
29 | // ParamsQueryBlock defines the parameters of the MethodQueryBlock.
30 | export interface ParamsQueryBlock {
31 | // BlockHeight of the block that will be returned. A nil value can be used
32 | // to request the latest block.
33 | blockHeight?: Marshalled;
34 | }
35 |
36 | // ParamsQueryBlocks defines the parameters of the MethodQueryBlocks.
37 | export interface ParamsQueryBlocks {
38 | // BlockHeight of the youngest block that will be returned in the list. A
39 | // nil value can be used to request a list of the latest blocks.
40 | blockHeight?: Marshalled;
41 | // N defines the maximum number of ancestor blocks that will be returned. A
42 | // nil value can be used to request the maximum allowed number of blocks.
43 | n?: Marshalled;
44 | }
45 |
46 | // ResponseQueryBlock defines the response of the MethodQueryBlock.
47 | export interface ResponseQueryBlock {
48 | block: MarshalledRenVMBlock; // Block json.RawMessage`json:"block"`
49 | }
50 |
51 | // ResponseQueryBlocks defines the response of the MethodQueryBlocks.
52 | export interface ResponseQueryBlocks {
53 | blocks: MarshalledRenVMBlock[]; // Blocks json.RawMessage`json:"blocks"`
54 | }
55 |
--------------------------------------------------------------------------------
/packages/provider/src/methods/ren_queryConfig.ts:
--------------------------------------------------------------------------------
1 | import { Marshalled, PackPrimitive } from "@renproject/utils";
2 |
3 | // ParamsQueryConfig defines the parameters of the MethodQueryConfig.
4 | export interface ParamsQueryConfig {
5 | // No parameters.
6 | }
7 |
8 | // Responses ///////////////////////////////////////////////////////////////////
9 |
10 | // ResponseQueryConfig defines the response of the MethodQueryConfig.
11 | export interface ResponseQueryConfig {
12 | confirmations: {
13 | [chain: string]: Marshalled;
14 | };
15 | maxConfirmations: {
16 | [chain: string]: Marshalled;
17 | };
18 | network: string;
19 | registries: {
20 | [chain: string]: string;
21 | };
22 | whitelist: string[];
23 | }
24 |
--------------------------------------------------------------------------------
/packages/provider/src/methods/ren_submitGateway.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Marshalled,
3 | PackPrimitive,
4 | PackTypeDefinition,
5 | TypedPackValue,
6 | } from "@renproject/utils";
7 |
8 | export interface SubmitGatewayInput {
9 | version: string;
10 | selector: string;
11 | in: SubmitGateway;
12 | }
13 |
14 | export const submitGatewayType: PackTypeDefinition = {
15 | struct: [
16 | {
17 | payload: PackPrimitive.Bytes,
18 | },
19 | {
20 | phash: PackPrimitive.Bytes32,
21 | },
22 | {
23 | to: PackPrimitive.Str,
24 | },
25 | {
26 | nonce: PackPrimitive.Bytes32,
27 | },
28 | {
29 | nhash: PackPrimitive.Bytes32,
30 | },
31 | {
32 | gpubkey: PackPrimitive.Bytes,
33 | },
34 | {
35 | ghash: PackPrimitive.Bytes32,
36 | },
37 | ],
38 | };
39 |
40 | export type SubmitGateway = TypedPackValue<
41 | // Types
42 | typeof submitGatewayType,
43 | // Values
44 | {
45 | amount: Marshalled;
46 | ghash: Marshalled; // "x0gTBzbXmM1Xdwk-B8PHJ4sgY2T_NcrWsxK6MJ2xYos",
47 | gpubkey: Marshalled; // "8Qnq",
48 | nhash: Marshalled; // "a_46LkThVhVYlkIxBXaInubuEmYcfDNk45EBl60prhA",
49 | nonce: Marshalled; // "vPIiF6apzdJ4Rr8IMpT2uywo8LbuHOcaEXQ21ydXFBA",
50 | payload: Marshalled; // "I_9MVtYiO4NlH7lwIx8",
51 | phash: Marshalled; // "ibSvPHswcsI3o3nkQRpHp23ANg3tf9L5ivk5kKwnGTQ",
52 | to: Marshalled; // "𧚞𧜿",
53 | txid: Marshalled;
54 | txindex: Marshalled;
55 | }
56 | >;
57 |
58 | export type ParamsSubmitGateway = {
59 | gateway: string;
60 | tx: SubmitGatewayInput;
61 | };
62 |
--------------------------------------------------------------------------------
/packages/provider/src/rpcUrls.ts:
--------------------------------------------------------------------------------
1 | import { RenNetwork } from "@renproject/utils";
2 |
3 | export const renRpcUrls = {
4 | [RenNetwork.Mainnet]: "https://rpc.renproject.io",
5 | [RenNetwork.Testnet]: "https://rpc-testnet.renproject.io",
6 | };
7 |
8 | export const renExplorerUrls = {
9 | [RenNetwork.Mainnet]: "https://explorer.renproject.io",
10 | [RenNetwork.Testnet]: "https://explorer-testnet.renproject.io",
11 | };
12 |
--------------------------------------------------------------------------------
/packages/provider/src/types/core.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from "bignumber.js";
2 |
3 | import { TxStatus, UrlBase64String } from "@renproject/utils";
4 |
5 | export interface RenVMBlock {
6 | height: BigNumber;
7 | hash: Uint8Array;
8 | parentHash: Uint8Array;
9 | commitment: Uint8Array;
10 | timestamp: BigNumber;
11 | round: BigNumber;
12 | stateRoot: Uint8Array;
13 | intrinsicTxs: Uint8Array[];
14 | extrinsicTxs: Uint8Array[];
15 | }
16 |
17 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
18 | export interface RenVMTransaction {
19 | hash: UrlBase64String;
20 | version: number;
21 | selector: string; // "BTC/fromEthereum",
22 | in: Input;
23 | out?: Output;
24 | }
25 |
26 | export interface RenVMTransactionWithStatus<
27 | Transaction extends RenVMTransaction = RenVMTransaction,
28 | > {
29 | tx: Transaction;
30 | txStatus: TxStatus;
31 | }
32 |
33 | export type RenVMCrossChainTransaction = RenVMTransaction<
34 | // Input
35 | {
36 | txid: Uint8Array;
37 | txindex: BigNumber;
38 | amount: BigNumber;
39 | payload: Uint8Array;
40 | phash: Uint8Array;
41 | to: string;
42 | nonce: Uint8Array;
43 | nhash: Uint8Array;
44 | gpubkey: Uint8Array;
45 | ghash: Uint8Array;
46 | },
47 | // Output
48 | {
49 | amount: BigNumber;
50 | fees: BigNumber;
51 | hash: Uint8Array;
52 | revert: string;
53 | sig: Uint8Array;
54 | sighash: Uint8Array;
55 | txid: Uint8Array;
56 | txindex: BigNumber;
57 | }
58 | >;
59 |
--------------------------------------------------------------------------------
/packages/provider/src/unmarshal.ts:
--------------------------------------------------------------------------------
1 | import { normalizeSignature, pack, TypedPackValue } from "@renproject/utils";
2 |
3 | import { ResponseQueryTx } from "./methods";
4 | import { RenVMTransaction } from "./types/core";
5 |
6 | export const unmarshalRenVMTransaction = <
7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
8 | Input = any,
9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
10 | Output = any,
11 | TypedInput extends TypedPackValue = TypedPackValue,
12 | TypedOutput extends TypedPackValue = TypedPackValue,
13 | >(
14 | tx: ResponseQueryTx["tx"],
15 | ): RenVMTransaction => {
16 | // If the transaction has a signature output, apply standard signature fixes.
17 | const out = pack.unmarshal.unmarshalTypedPackValue(tx.out);
18 | if (out && out.sig && out.sig instanceof Uint8Array && out.sig.length > 0) {
19 | out.sig = normalizeSignature(out.sig);
20 | }
21 |
22 | return {
23 | version: parseInt(tx.version),
24 | hash: tx.hash,
25 | selector: tx.selector,
26 | in: pack.unmarshal.unmarshalTypedPackValue(tx.in),
27 | out,
28 | };
29 | };
30 |
--------------------------------------------------------------------------------
/packages/provider/test/pack.spec.ts:
--------------------------------------------------------------------------------
1 | import { utils } from "@renproject/utils";
2 | import BigNumber from "bignumber.js";
3 | import { expect } from "chai";
4 | import { describe, it } from "mocha";
5 |
6 | import { unmarshalPackValue } from "../../utils/src/libraries/pack/unmarshal";
7 | import { burnParamsType, crossChainParamsType } from "../src";
8 |
9 | describe("Pack", () => {
10 | it("Unmarshal burn - 1", () => {
11 | const amount =
12 | "51423850459342719531259112406474019285406140697150570331000675381551947991775";
13 | const nonce = "H8AmOgjiSt8ULnuw1mDzPMJogHDOS2J1uNELrDma0xg";
14 | const to = "1234";
15 |
16 | const result = unmarshalPackValue(burnParamsType, {
17 | amount,
18 | nonce,
19 | to,
20 | });
21 |
22 | expect(result).to.deep.equal({
23 | amount: new BigNumber(amount),
24 | nonce: utils.fromBase64(nonce),
25 | to,
26 | });
27 | });
28 |
29 | it("Unmarshal mint", () => {
30 | const ghash = "x0gTBzbXmM1Xdwk-B8PHJ4sgY2T_NcrWsxK6MJ2xYos";
31 | const gpubkey = "8Qnq";
32 | const nhash = "a_46LkThVhVYlkIxBXaInubuEmYcfDNk45EBl60prhA";
33 | const nonce = "vPIiF6apzdJ4Rr8IMpT2uywo8LbuHOcaEXQ21ydXFBA";
34 | const txid = "_yJG1tKIALMrvaSes9BB4dYx5eCN8OK5V_PEM4N3R10";
35 | const txindex = "2288363171";
36 | const amount = "503863382662879832";
37 | const payload = "I_9MVtYiO4NlH7lwIx8";
38 | const phash = "ibSvPHswcsI3o3nkQRpHp23ANg3tf9L5ivk5kKwnGTQ";
39 | const to = "1234";
40 |
41 | const result = unmarshalPackValue(crossChainParamsType, {
42 | ghash,
43 | gpubkey,
44 | nhash,
45 | nonce,
46 | txid,
47 | txindex,
48 | amount,
49 | payload,
50 | phash,
51 | to,
52 | });
53 |
54 | expect(result).to.deep.equal({
55 | ghash: utils.fromBase64(ghash),
56 | gpubkey: utils.fromBase64(gpubkey),
57 | nhash: utils.fromBase64(nhash),
58 | nonce: utils.fromBase64(nonce),
59 | txid: utils.fromBase64(txid),
60 | txindex: new BigNumber(txindex),
61 | amount: new BigNumber(amount),
62 | payload: utils.fromBase64(payload),
63 | phash: utils.fromBase64(phash),
64 | to: to,
65 | });
66 | });
67 | });
68 |
--------------------------------------------------------------------------------
/packages/provider/test/selectPublicKey.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-var-requires */
2 |
3 | import chai from "chai";
4 |
5 | import { utils } from "@renproject/utils";
6 |
7 | import { RenVMProvider } from "../src";
8 |
9 | chai.should();
10 |
11 | describe("RenVMProvider v2", () => {
12 | it("selectShard", async () => {
13 | const renVMProvider = new RenVMProvider({
14 | sendMessage: (method) => {
15 | switch (method) {
16 | case "ren_queryState":
17 | return require("./mockResponses/ren_queryState.json")
18 | .result;
19 | case "ren_queryBlockState":
20 | return require("./mockResponses/ren_queryBlockState.json")
21 | .result;
22 | default:
23 | return {};
24 | }
25 | },
26 | } as any); // eslint-disable-line @typescript-eslint/no-explicit-any
27 | utils
28 | .Ox((await renVMProvider.selectShard("BTC")).gPubKey)
29 | .should.equal("0xA6Auk8-MR7JQB1sK9h-W69EDdsCqp2NRSOiJyytRyWkn");
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/packages/provider/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/provider/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/ren/README.md:
--------------------------------------------------------------------------------
1 | ../../README.md
--------------------------------------------------------------------------------
/packages/ren/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/ren",
3 | "version": "3.6.0",
4 | "description": "Official Ren JavaScript SDK for bridging crypto assets cross-chain.",
5 | "repository": {
6 | "type": "git",
7 | "url": "git+https://github.com/renproject/ren-js.git"
8 | },
9 | "publishConfig": {
10 | "access": "public",
11 | "directory": "build"
12 | },
13 | "keywords": [
14 | "RenVM",
15 | "Ren",
16 | "Cross-Chain",
17 | "Ethereum",
18 | "Bitcoin",
19 | "Solana",
20 | "Dogecoin",
21 | "Web3",
22 | "DeFi"
23 | ],
24 | "author": "Ren",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/renproject/ren-js/issues"
28 | },
29 | "main": "./build/index.js",
30 | "typings": "./build/index.d.ts",
31 | "module": "./build/module/index.js",
32 | "scripts": {
33 | "clean": "yarn rimraf ./build ./node_modules",
34 | "link": "yarn build:link && cd build && yarn link",
35 | "unlink": "yarn unlink",
36 | "build": "run-s build:*",
37 | "build:main": "tsc -p tsconfig.json",
38 | "build:module": "tsc -p tsconfig.module.json",
39 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
40 | "_build:bundled": "cross-env NODE_ENV=production webpack --config ../../webpack.config.js --mode production --progress --color",
41 | "prettier": "yarn fix:prettier",
42 | "lint": "run-s lint:*",
43 | "lint:eslint": "eslint --config ../../.eslintrc.js src",
44 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
45 | "fix": "run-s fix:*",
46 | "fix:eslint": "yarn lint:eslint --fix",
47 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
48 | "test": "run-s test:* lint",
49 | "test-all": "ALL_TESTS=true run-s build:main test:unit lint",
50 | "test:unit": "nyc ../../node_modules/ts-mocha/bin/ts-mocha --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./test/*.spec.ts ./test/**/*.spec.ts",
51 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
52 | "cov": "run-s build:main test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
53 | "cov:html": "nyc report --reporter=html",
54 | "cov:send": "nyc report --reporter=lcov && codecov",
55 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
56 | "prepare": "yarn build"
57 | },
58 | "dependencies": {
59 | "@renproject/provider": "^3.6.0",
60 | "@renproject/utils": "^3.6.0",
61 | "bignumber.js": "9.0.2",
62 | "events": "3.3.0",
63 | "immutable": "4.1.0"
64 | },
65 | "nyc": {
66 | "extends": "@istanbuljs/nyc-config-typescript",
67 | "exclude": [
68 | "**/*.d.ts",
69 | "**/*.spec.js"
70 | ],
71 | "include": [
72 | "src"
73 | ]
74 | },
75 | "prettier": {
76 | "printWidth": 80,
77 | "semi": true,
78 | "singleQuote": false,
79 | "tabWidth": 4,
80 | "trailingComma": "all",
81 | "endOfLine": "lf",
82 | "arrowParens": "always"
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/packages/ren/src/utils/config.ts:
--------------------------------------------------------------------------------
1 | import { defaultLogger, Logger, LogLevel, utils } from "@renproject/utils";
2 |
3 | export { LogLevel } from "@renproject/utils";
4 |
5 | export interface RenJSConfig {
6 | /**
7 | * The logger and logLevel are used to configure where RenJS sends debug
8 | * and error logs. Set the logLevel to `LogLevel.Debug` or `LogLevel.Trace`
9 | * to receive debug logs.
10 | */
11 | logLevel?: LogLevel;
12 | logger?: Logger;
13 |
14 | /**
15 | * `networkDelay` is the timeout in ms between retrying various network
16 | * requests including 1) fetching deposits, 2) fetching confirmations and
17 | * 3) fetching a transaction's RenVM status.
18 | *
19 | * It defaults to `15000` (15 seconds).
20 | */
21 | networkDelay?: number;
22 |
23 | /**
24 | * `loadCompletedDeposits` whether or not to detect deposits that have
25 | * already been minted.
26 | *
27 | * It defaults to false
28 | */
29 | // loadCompletedDeposits?: boolean;
30 | }
31 |
32 | export const defaultRenJSConfig = {
33 | logLevel: LogLevel.Debug,
34 | logger: defaultLogger,
35 | networkDelay: 15 * utils.sleep.SECONDS,
36 | // loadCompletedDeposits: false as boolean,
37 | };
38 |
39 | // Check that defaultRenJSConfig is a valid RenJSConfig object, while
40 | // still allowing typescript to infer its type from is value, so that it knows
41 | // that `defaultRenJSConfig.logger` is not potentially undefined.
42 | const _check: RenJSConfig = defaultRenJSConfig;
43 |
--------------------------------------------------------------------------------
/packages/ren/src/utils/transactionEmitter.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from "events";
2 |
3 | import { EventEmitterTyped } from "@renproject/utils";
4 |
5 | import { GatewayTransaction } from "../gatewayTransaction";
6 |
7 | // The TransactionEmitter extends the built-in EventEmitter, adding the ability
8 | // to retrieve previous transactions that have been emitted.
9 | export class TransactionEmitter<
10 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
11 | ToPayload extends { chain: string; txConfig?: any } = any,
12 | >
13 | extends EventEmitter
14 | implements
15 | EventEmitterTyped<{ transaction: [GatewayTransaction] }>
16 | {
17 | private getTransactions: () => Array>;
18 |
19 | public constructor(
20 | getTransactions: () => Array>,
21 | ) {
22 | super();
23 |
24 | this.getTransactions = getTransactions;
25 | }
26 |
27 | public addListener = (
28 | event: Event,
29 | callback: Event extends "transaction"
30 | ? (deposit: GatewayTransaction) => void
31 | : never,
32 | ): this => {
33 | // Emit previous deposit events.
34 | if (event === "transaction") {
35 | this.getTransactions().map(callback);
36 | }
37 |
38 | super.on(event, callback);
39 | return this;
40 | };
41 |
42 | /**
43 | * `on` creates a new listener to `"transaction"` events, returning
44 | * [[GatewayTransaction]] instances.
45 | *
46 | * `on` extends `EventEmitter.on`, modifying it to immediately return all
47 | * previous `"transaction"` events, in addition to new events, when a new
48 | * listener is created.
49 | *
50 | * @category Main
51 | */
52 | public on = (
53 | event: Event,
54 | callback: (
55 | ...values: { transaction: [GatewayTransaction] }[Event]
56 | ) => void | Promise,
57 | ): this =>
58 | this.addListener(
59 | event,
60 | callback as Event extends "transaction"
61 | ? (deposit: GatewayTransaction) => void
62 | : never,
63 | );
64 |
65 | public once = (
66 | event: Event,
67 | callback: (
68 | ...values: { transaction: [GatewayTransaction] }[Event]
69 | ) => void | Promise,
70 | ): this =>
71 | super.once(
72 | event,
73 | callback as Event extends "transaction"
74 | ? (deposit: GatewayTransaction) => void
75 | : never,
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/packages/ren/test/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 |
3 | import RenJS from "../src";
4 |
5 | describe("@renproject/ren", () => {
6 | it("should export RenJS correctly", async () => {
7 | expect(RenJS).not.to.equal(undefined);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/packages/ren/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["node"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/ren/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/utils/README.md:
--------------------------------------------------------------------------------
1 | # `@renproject/utils`
2 |
3 | This package is part of [RenJS](https://github.com/renproject.ren-js).
4 |
5 | See [`@renproject/utils` docs](https://renproject.github.io/ren-js-v3-docs/modules/_renproject_utils.html)
6 |
--------------------------------------------------------------------------------
/packages/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@renproject/utils",
3 | "version": "3.6.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "git+https://github.com/renproject/ren-js.git"
7 | },
8 | "publishConfig": {
9 | "access": "public",
10 | "directory": "build"
11 | },
12 | "author": "Ren",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/renproject/ren-js/issues"
16 | },
17 | "main": "./build/index.js",
18 | "typings": "./build/index.d.ts",
19 | "module": "./build/module/index.js",
20 | "scripts": {
21 | "clean": "yarn rimraf ./build ./node_modules",
22 | "link": "yarn build:link && cd build && yarn link",
23 | "unlink": "yarn unlink",
24 | "build": "run-s build:*",
25 | "build:main": "tsc -p tsconfig.json",
26 | "build:module": "tsc -p tsconfig.module.json",
27 | "build:link": "cp package.json build && cp README.md build && sed -i.tmp 's/\\/build\\//\\//' ./build/package.json && rm ./build/package.json.tmp",
28 | "prettier": "yarn fix:prettier",
29 | "lint": "run-s lint:*",
30 | "lint:eslint": "eslint --config ../../.eslintrc.js src",
31 | "lint:prettier": "prettier --check \"./(src|test)/**/*.ts*\"",
32 | "fix": "run-s fix:*",
33 | "fix:eslint": "yarn lint:eslint --fix",
34 | "fix:prettier": "prettier --write './(src|test)/**/*.ts*'",
35 | "test": "run-s test:* lint",
36 | "test:unit": "nyc ../../node_modules/ts-mocha/bin/ts-mocha --bail --sort --exit --timeout 180000 --paths -p ./tsconfig.json ./src/*.spec.ts ./src/**/*.spec.ts ./test/*.spec.ts ./test/**/*.spec.ts --ignore ./test/testutils/chai.d.ts",
37 | "watch": "run-s build:main && run-s \"build:main -- -w\"",
38 | "cov": "run-s test:unit cov:html && echo \"\n\nTo see coverage, run: 'open coverage/index.html'\n\n\"",
39 | "cov:html": "nyc report --reporter=html",
40 | "cov:send": "nyc report --reporter=lcov && codecov",
41 | "cov:check": "nyc report && nyc check-coverage --lines 0 --functions 0 --branches 0",
42 | "prepare": "yarn build"
43 | },
44 | "dependencies": {
45 | "@noble/hashes": "1.1.2",
46 | "@types/events": "3.0.0",
47 | "axios": "0.27.2",
48 | "base64-js": "1.5.1",
49 | "bignumber.js": "9.0.2",
50 | "events": "3.3.0",
51 | "immutable": "4.1.0"
52 | },
53 | "nyc": {
54 | "extends": "@istanbuljs/nyc-config-typescript",
55 | "exclude": [
56 | "**/*.d.ts",
57 | "**/*.spec.js"
58 | ],
59 | "include": [
60 | "src"
61 | ]
62 | },
63 | "prettier": {
64 | "printWidth": 80,
65 | "semi": true,
66 | "singleQuote": false,
67 | "tabWidth": 4,
68 | "trailingComma": "all",
69 | "endOfLine": "lf",
70 | "arrowParens": "always"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/packages/utils/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./common";
2 | export * from "./errors";
3 | export * from "./internal";
4 | export * from "./internal/assert";
5 | export * from "./libraries/pack";
6 | export * from "./renVMHashes";
7 | export * from "./txSubmitter";
8 | export * from "./types";
9 |
--------------------------------------------------------------------------------
/packages/utils/src/internal/extractError.ts:
--------------------------------------------------------------------------------
1 | export const hasOwnProperty = (
2 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
3 | object: any,
4 | property: keyof T,
5 | ): object is T => Object.prototype.hasOwnProperty.call(object, property);
6 |
7 | export const invalidError = (errorMessage: string): boolean =>
8 | errorMessage === "" ||
9 | errorMessage === "null" ||
10 | errorMessage === "undefined";
11 |
12 | /**
13 | * Attempt to extract a more meaningful error from a thrown error, such as
14 | * the body of a network response.
15 | */
16 | export const extractError = (error: unknown): string => {
17 | if (error && typeof error === "object") {
18 | if (hasOwnProperty(error, "response") && error.response) {
19 | const extractedError = extractError(error.response);
20 | if (!invalidError(extractedError)) {
21 | return extractedError;
22 | }
23 | }
24 | if (hasOwnProperty(error, "data") && error.data) {
25 | const extractedError = extractError(error.data);
26 | if (!invalidError(extractedError)) {
27 | return extractedError;
28 | }
29 | }
30 | if (hasOwnProperty(error, "error") && error.error) {
31 | const extractedError = extractError(error.error);
32 | if (!invalidError(extractedError)) {
33 | return extractedError;
34 | }
35 | }
36 | if (hasOwnProperty(error, "context") && error.context) {
37 | const extractedError = extractError(error.context);
38 | if (!invalidError(extractedError)) {
39 | return extractedError;
40 | }
41 | }
42 | if (hasOwnProperty(error, "message") && error.message) {
43 | const extractedError = extractError(error.message);
44 | if (!invalidError(extractedError)) {
45 | return extractedError;
46 | }
47 | }
48 | if (hasOwnProperty(error, "statusText") && error.statusText) {
49 | const extractedError = extractError(error.statusText);
50 | if (!invalidError(extractedError)) {
51 | return extractedError;
52 | }
53 | }
54 | }
55 | try {
56 | if (typeof error === "string") {
57 | if (error.slice(0, 7) === "Error: ") {
58 | error = error.slice(7);
59 | }
60 | return String(error);
61 | }
62 | return JSON.stringify(error);
63 | } catch (innerError) {
64 | // Ignore JSON error
65 | }
66 | return String(error);
67 | };
68 |
--------------------------------------------------------------------------------
/packages/utils/src/internal/hashes.ts:
--------------------------------------------------------------------------------
1 | import { sha256 as createSha256 } from "@noble/hashes/sha256";
2 | import { keccak_256 as createKeccak256 } from "@noble/hashes/sha3";
3 |
4 | import { assertType } from "./assert";
5 | import { concat } from "./common";
6 |
7 | /**
8 | * Returns the keccak256 hash of an array of Uint8Arrays. The inputs are
9 | * concatenated before being hashed.
10 | *
11 | * @param msg One ore more Uint8Arrays to hash.
12 | * @returns The keccak256 hash of the concatenated input Uint8Arrays.
13 | */
14 | export const keccak256 = (...msg: Uint8Array[]): Uint8Array => {
15 | assertType("Uint8Array[]", { msg });
16 | return new Uint8Array(createKeccak256(concat(msg)));
17 | };
18 |
19 | /**
20 | * Returns the sha256 hash of an array of Uint8Arrays. The inputs are
21 | * concatenated before being hashed.
22 | *
23 | * @param msg One ore more Uint8Arrays to hash.
24 | * @returns The sha256 hash of the concatenated input Uint8Arrays.
25 | */
26 | export const sha256 = (...msg: Uint8Array[]): Uint8Array => {
27 | assertType("Uint8Array[]", { msg });
28 | return new Uint8Array(createSha256(concat(msg)));
29 | };
30 |
--------------------------------------------------------------------------------
/packages/utils/src/internal/index.ts:
--------------------------------------------------------------------------------
1 | import * as asset from "./assert";
2 | import * as common from "./common";
3 | import * as extractError from "./extractError";
4 | import * as hashes from "./hashes";
5 | import * as network from "./network";
6 | import * as sleep from "./sleep";
7 |
8 | export const utils = {
9 | ...common,
10 | ...asset,
11 | ...hashes,
12 | ...network,
13 | ...extractError,
14 | ...sleep,
15 | };
16 |
--------------------------------------------------------------------------------
/packages/utils/src/internal/network.ts:
--------------------------------------------------------------------------------
1 | import Axios, { AxiosRequestConfig } from "axios";
2 |
3 | import { extractError } from "./extractError";
4 | import { sleep } from "./sleep";
5 |
6 | // Default timeout for network requests.
7 | export const DEFAULT_TIMEOUT = 30 * sleep.SECONDS;
8 |
9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
10 | export const GET = async (
11 | url: string,
12 | config?: AxiosRequestConfig,
13 | ): Promise => {
14 | try {
15 | const response = await Axios.get(url, {
16 | timeout: DEFAULT_TIMEOUT,
17 | ...config,
18 | });
19 |
20 | return response.data;
21 | } catch (error: unknown) {
22 | throw new Error(extractError(error));
23 | }
24 | };
25 |
26 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
27 | export const POST = async (
28 | url: string,
29 | data?: D,
30 | config?: AxiosRequestConfig,
31 | ): Promise => {
32 | try {
33 | const response = await Axios.post(url, data, {
34 | timeout: DEFAULT_TIMEOUT,
35 | ...config,
36 | });
37 |
38 | return response.data;
39 | } catch (error: unknown) {
40 | throw new Error(extractError(error));
41 | }
42 | };
43 |
--------------------------------------------------------------------------------
/packages/utils/src/internal/sleep.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Pauses the thread for the specified number of milliseconds.
3 | *
4 | * @param ms The number of milliseconds to pause for.
5 | */
6 | export const sleep = async (ms: number): Promise => {
7 | return new Promise((resolve) => {
8 | setTimeout(resolve, ms);
9 | });
10 | };
11 | sleep.SECONDS = 1000;
12 | sleep.MINUTES = 60 * sleep.SECONDS;
13 |
--------------------------------------------------------------------------------
/packages/utils/src/libraries/pack/README.md:
--------------------------------------------------------------------------------
1 | # `📦 pack`
2 |
3 | An interface for serializing well-typed values to binary and JSON without losing
4 | any type information.
5 |
6 | Reference implementation (Go): https://github.com/renproject/pack
7 |
8 | ## Implementation checklist
9 |
10 | - [x] JSON unmarshalling
11 | - [ ] JSON marshalling
12 | - [ ] Binary unmarshalling
13 | - [x] Binary marshalling
14 |
--------------------------------------------------------------------------------
/packages/utils/src/libraries/pack/common.ts:
--------------------------------------------------------------------------------
1 | import { PackListType, PackStructType } from "./types";
2 |
3 | /**
4 | * Check that the passed-in value is a PackStructType - i.e. an object that has
5 | * a single field called `struct` which stores an array.
6 | */
7 | export const isPackStructType = (type: unknown): type is PackStructType =>
8 | typeof type === "object" &&
9 | type !== null &&
10 | Object.keys(type).length === 1 &&
11 | (type as PackStructType).struct !== undefined &&
12 | Array.isArray((type as PackStructType).struct);
13 |
14 | /**
15 | * Check that the passed-in value is a PackListType - i.e. an object that has
16 | * a single field called `list`.
17 | */
18 | export const isPackListType = (type: unknown): type is PackListType =>
19 | typeof type === "object" && (type as PackListType).list !== undefined;
20 |
--------------------------------------------------------------------------------
/packages/utils/src/libraries/pack/index.ts:
--------------------------------------------------------------------------------
1 | import * as binaryMarshal from "./binaryMarshal";
2 | import { isPackListType, isPackStructType } from "./common";
3 | import * as unmarshal from "./unmarshal";
4 |
5 | export * from "./types";
6 |
7 | /**
8 | * `pack` implements marshalling and marshalling for the pack serializing
9 | * standard. See github.com/renproject/pack
10 | */
11 | export const pack = {
12 | isPackStructType,
13 | isPackListType,
14 | binaryMarshal,
15 | unmarshal,
16 | };
17 |
--------------------------------------------------------------------------------
/packages/utils/src/libraries/pack/types.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-explicit-any */
2 |
3 | import BigNumber from "bignumber.js";
4 |
5 | export enum PackPrimitive {
6 | Bool = "bool",
7 | U8 = "u8",
8 | U16 = "u16",
9 | U32 = "u32",
10 | U64 = "u64",
11 | U128 = "u128",
12 | U256 = "u256",
13 | Str = "string",
14 | Bytes = "bytes",
15 | Bytes32 = "bytes32",
16 | Bytes65 = "bytes65",
17 | }
18 |
19 | export interface PackStructType<
20 | T extends Array<{ [name: string]: PackTypeDefinition }> = Array<{
21 | [name: string]: PackTypeDefinition;
22 | }>,
23 | > {
24 | struct: T;
25 | }
26 |
27 | export interface PackListType<
28 | T extends PackTypeDefinition = PackTypeDefinition,
29 | > {
30 | list: T;
31 | }
32 |
33 | export type PackNilType = "nil";
34 |
35 | export type PackTypeDefinition =
36 | | PackPrimitive
37 | | PackStructType
38 | | PackListType
39 | | PackNilType;
40 |
41 | // export type PackType = PackPrimitive | PackNilType | "list" | "struct";
42 |
43 | export type MarshalledPackArray = T[];
44 | export type MarshalledPackStruct = T;
45 |
46 | export type Marshalled<
47 | Type extends PackTypeDefinition,
48 | InnerType extends PackTypeDefinition = PackTypeDefinition,
49 | > = Type extends PackPrimitive.Bool
50 | ? boolean
51 | : Type extends PackPrimitive.U8
52 | ? string
53 | : Type extends PackPrimitive.U16
54 | ? string
55 | : Type extends PackPrimitive.U32
56 | ? string
57 | : Type extends PackPrimitive.U64
58 | ? string
59 | : Type extends PackPrimitive.U128
60 | ? string
61 | : Type extends PackPrimitive.U256
62 | ? string
63 | : Type extends PackPrimitive.Str
64 | ? string
65 | : Type extends PackPrimitive.Bytes
66 | ? string
67 | : Type extends PackPrimitive.Bytes32
68 | ? string
69 | : Type extends PackPrimitive.Bytes65
70 | ? string
71 | : Type extends PackNilType
72 | ? string
73 | : Type extends { list: InnerType }
74 | ? Array>
75 | : Type extends { struct: Array<{ [key: string]: PackTypeDefinition }> }
76 | ? { [k: string]: any }
77 | : never;
78 |
79 | export type Unmarshalled<
80 | Type extends PackTypeDefinition,
81 | InnerType extends PackTypeDefinition = PackTypeDefinition,
82 | > = Type extends PackPrimitive.Bool
83 | ? boolean
84 | : Type extends PackPrimitive.U8
85 | ? BigNumber
86 | : Type extends PackPrimitive.U16
87 | ? BigNumber
88 | : Type extends PackPrimitive.U32
89 | ? BigNumber
90 | : Type extends PackPrimitive.U64
91 | ? BigNumber
92 | : Type extends PackPrimitive.U128
93 | ? BigNumber
94 | : Type extends PackPrimitive.U256
95 | ? BigNumber
96 | : Type extends PackPrimitive.Str
97 | ? string
98 | : Type extends PackPrimitive.Bytes
99 | ? Uint8Array
100 | : Type extends PackPrimitive.Bytes32
101 | ? Uint8Array
102 | : Type extends PackPrimitive.Bytes65
103 | ? Uint8Array
104 | : Type extends PackNilType
105 | ? null
106 | : Type extends { list: InnerType }
107 | ? Array>
108 | : Type extends { struct: Array<{ [key: string]: PackTypeDefinition }> }
109 | ? { [k: string]: any }
110 | : never;
111 |
112 | export interface TypedPackValue<
113 | T extends PackTypeDefinition = PackTypeDefinition,
114 | V = any,
115 | > {
116 | t: T;
117 | v: V;
118 | }
119 |
--------------------------------------------------------------------------------
/packages/utils/src/libraries/promiEvent/LICENSE:
--------------------------------------------------------------------------------
1 | This file is part of web3.js.
2 |
3 | web3.js is free software: you can redistribute it and/or modify
4 | it under the terms of the GNU Lesser General Public License as published by
5 | the Free Software Foundation, either version 3 of the License, or
6 | (at your option) any later version.
7 |
8 | web3.js is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU Lesser General Public License for more details.
12 |
13 | You should have received a copy of the GNU Lesser General Public License
14 | along with web3.js. If not, see .
--------------------------------------------------------------------------------
/packages/utils/src/pack/README.md:
--------------------------------------------------------------------------------
1 | # `pack`
2 |
3 | An application binary interface for well-typed message passing over networks and disks.
4 |
5 | Reference implementation (Go): https://github.com/renproject/pack
6 |
--------------------------------------------------------------------------------
/packages/utils/src/types/eventEmitter.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/ban-ts-comment */
2 |
3 | import { EventEmitter } from "events";
4 |
5 | import { Web3PromiEvent } from "../libraries/promiEvent";
6 |
7 | /** Interface for EventEmitter with well-typed events. */
8 | export class EventEmitterTyped<
9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
10 | EventTypes extends { [event: string]: any[] } = {},
11 | > {
12 | // @ts-ignore no initializer because of proxyHandler
13 | public readonly emit: (
14 | event: Event,
15 | ...args: EventTypes[Event]
16 | ) => boolean; // EventEmitter["emit"]
17 | // @ts-ignore no initializer because of proxyHandler
18 | public readonly removeListener: EventEmitter["removeListener"];
19 | // @ts-ignore no initializer because of proxyHandler
20 | public readonly on: (
21 | event: Event,
22 | callback: (...values: EventTypes[Event]) => void | Promise,
23 | ) => this;
24 | // @ts-ignore no initializer because of proxyHandler
25 | public readonly once: (
26 | event: Event,
27 | callback: (...values: EventTypes[Event]) => void | Promise,
28 | ) => this;
29 | // @ts-ignore no initializer because of proxyHandler
30 | public readonly listenerCount: (event: string | symbol) => number;
31 | }
32 |
33 | /** Create a new EventEmitterTyped */
34 | export const eventEmitter = <
35 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
36 | EventTypes extends { [event: string]: any[] } = {},
37 | >(): EventEmitterTyped =>
38 | new EventEmitter() as unknown as EventEmitterTyped;
39 |
40 | // Tell Typescript that Web3PromiEvent implements Promise.
41 | export type PromiEvent<
42 | T,
43 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
44 | EventTypes extends { [event: string]: any[] } = {},
45 | > = Web3PromiEvent & Promise;
46 |
--------------------------------------------------------------------------------
/packages/utils/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./chain";
2 | export * from "./eventEmitter";
3 | export * from "./logger";
4 | export * from "./renNetwork";
5 | export * from "./shard";
6 | export * from "./types";
7 | export * from "./types";
8 |
--------------------------------------------------------------------------------
/packages/utils/src/types/logger.ts:
--------------------------------------------------------------------------------
1 | /** Based on log levels from the `loglevel` npm package. */
2 | export enum LogLevel {
3 | Trace = 0,
4 | Debug = 1,
5 | Log = LogLevel.Debug,
6 | Info = 2,
7 | Warn = 3,
8 | Error = 4,
9 | Silent = 5,
10 | }
11 |
12 | /**
13 | * Standard logger/console interface.
14 | */
15 | export interface Logger {
16 | error(message?: unknown, ...optionalParams: unknown[]): void;
17 | warn(message?: unknown, ...optionalParams: unknown[]): void;
18 | info(message?: unknown, ...optionalParams: unknown[]): void;
19 | debug(message?: unknown, ...optionalParams: unknown[]): void;
20 |
21 | // Return the logging level, as a number from 0 (trace) to 5 (silent).
22 | getLevel?(): LogLevel | number;
23 | }
24 |
25 | const doNothing = (): void => {};
26 |
27 | /**
28 | * The defaultLogger forwards info, warn and error logs to the console, and
29 | * ignores debug logs.
30 | *
31 | * @example
32 | * ```
33 | * const logger = params.logger || defaultLogger;
34 | * logger.debug("Test.");
35 | * ```
36 | */
37 | export const defaultLogger: Logger = {
38 | debug: doNothing,
39 | // eslint-disable-next-line no-console
40 | info: console.info,
41 | warn: console.warn,
42 | error: console.error,
43 | };
44 |
--------------------------------------------------------------------------------
/packages/utils/src/types/renNetwork.ts:
--------------------------------------------------------------------------------
1 | export enum RenNetwork {
2 | Mainnet = "mainnet",
3 | Testnet = "testnet",
4 | }
5 |
6 | export type RenNetworkString = `${RenNetwork}`;
7 |
--------------------------------------------------------------------------------
/packages/utils/src/types/shard.ts:
--------------------------------------------------------------------------------
1 | // The details for a RenVM shard. The is currently only one shard that doesn't
2 | // expire.
3 | // There will be multiple levels of expiries - the `expiry` field will refer
4 | // to the time (as seconds since Unix epoch) by which gateway transactions
5 | // have to be submitted by. For mints and for contract-based releases, RenVM
6 | // will then generate a signature which needs to be submitted by a second
7 | // deadline.
8 | export interface RenVMShard {
9 | gPubKey: string;
10 |
11 | expiry?: number;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/utils/src/types/types.ts:
--------------------------------------------------------------------------------
1 | export type UrlBase64String = string;
2 | export type HexString = string;
3 |
4 | export enum TxStatus {
5 | // TxStatusNil is used for transactions that have not been seen, or are
6 | // otherwise unknown.
7 | TxStatusNil = "nil",
8 | // TxStatusConfirming is used for transactions that are currently waiting
9 | // for their underlying blockchain transactions to be confirmed.
10 | TxStatusConfirming = "confirming",
11 | // TxStatusPending is used for transactions that are waiting for consensus
12 | // to be reached on when the transaction should be executed.
13 | TxStatusPending = "pending",
14 | // TxStatusExecuting is used for transactions that are currently being
15 | // executed.
16 | TxStatusExecuting = "executing",
17 | // TxStatusReverted is used for transactions that were reverted during
18 | // execution.
19 | TxStatusReverted = "reverted",
20 | // TxStatusDone is used for transactions that have been successfully
21 | // executed.
22 | TxStatusDone = "done",
23 | }
24 |
25 | export const TxStatusIndex = {
26 | [TxStatus.TxStatusNil]: 0,
27 | [TxStatus.TxStatusConfirming]: 1,
28 | [TxStatus.TxStatusPending]: 2,
29 | [TxStatus.TxStatusExecuting]: 3,
30 | [TxStatus.TxStatusReverted]: 4,
31 | [TxStatus.TxStatusDone]: 5,
32 | };
33 |
--------------------------------------------------------------------------------
/packages/utils/test/hash.spec.ts:
--------------------------------------------------------------------------------
1 | import chai, { expect } from "chai";
2 |
3 | import { utils } from "../src";
4 | import { keccak256 } from "../src/internal/hashes";
5 |
6 | chai.should();
7 |
8 | const testCases = [
9 | {
10 | msg: Buffer.from([1, 2, 3]),
11 | hashes: {
12 | keccak256:
13 | "f1885eda54b7a053318cd41e2093220dab15d65381b1157a3633a83bfd5c9239",
14 | },
15 | },
16 | {
17 | msg: Buffer.from([]),
18 | hashes: {
19 | keccak256:
20 | "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
21 | },
22 | },
23 | {
24 | msg: Buffer.from("00".repeat(20), "hex"),
25 | hashes: {
26 | keccak256:
27 | "5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a",
28 | },
29 | },
30 | ];
31 |
32 | const hashers = { keccak256 };
33 |
34 | describe("keccak256", () => {
35 | it("returns correct result for hard-coded testcases", () => {
36 | for (const testCase of testCases) {
37 | for (const hash of Object.keys(testCase.hashes)) {
38 | const result = hashers[hash](testCase.msg);
39 | expect(result instanceof Uint8Array).to.be.true;
40 | expect(utils.toHex(result)).to.equal(testCase.hashes[hash]);
41 | }
42 | }
43 | });
44 | });
45 |
46 | /*
47 | * Generate new test cases:
48 | *
49 | * ```js
50 | const { hash160, keccak256, ripemd160, sha256 } = require("@renproject/utils");
51 | let msg = Buffer.from([0])
52 | let hashers = {keccak256, ripemd160, sha256, hash160 }
53 | let hash = (msg) => {
54 | let obj = {};
55 | for (const hash of Object.keys(hashers)) {
56 | obj[hash] = hashers[hash](msg).toString("hex");
57 | }
58 | console.debug(JSON.stringify(obj, null, " "))
59 | }
60 | * ```
61 | */
62 |
--------------------------------------------------------------------------------
/packages/utils/test/marshalPack.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 | import { describe, it } from "mocha";
3 |
4 | import { Ox } from "../src/internal/common";
5 | import { PackPrimitive, TypedPackValue } from "../src/libraries/pack";
6 |
7 | describe("Pack", () => {
8 | it("Marshal pack value", () => {
9 | const expected =
10 | "0x140000000400000006616d6f756e740700000005746f6b656e0a00000002746f0a000000056e6f6e63650ccb6beefca4aded539a56f136a7ff24a2901fe6627233b8bf8d7d7f69c8737fc300000144f2b580a8f0ac80a2f294b3a9f1afaf86f18597b6f38186a3f1ada7aff185bc94f2908ba6f1a7afb3e4aaa2f481b0b1f29986a5f3aea7b1f488a3a1f396958aebad83f283ad81f0b2a8b5f193ada4f2b0b1b0f3a9b692f2a4a9bef2a9acb3f39d8abef189aab0f2878585f38aa1a9f18b97adf09d978cf29caabff3b099b9f2a494a5f39294a9f2b58299f393ba94f388979ae3b185f2b58fa9f294bfa2f390aa9df3ba84a1f29db093f0a1a7a4f18f939ef1a59d9df48fb0aaeb81ade49fb8e88aaaf0968aa2f1a488aaf381b6a8f0a4bdbaf3bf99aaf2a98e97f29eb486f2b294a2f1a98c86f1bab29be7babaf399bf93f285bf89f3b08996f3839b8df2b8af9af392adb6f0b58cabf2a484b3f0b6ac8af0a4808ff0aeb3a0f282949ceebfa9f2b5b48af3bb9da7f286819bf1b9b1baf39bbeb8f0baa484f18f8b8af398a691f2a39fa700000168f38285acf2bb93b7f0a0b195f0b3bfb6f1b980a7f2b4b28bf1b785b0f2a2afbef3baa99bf0b5b59cf187a6a1f3acb58ff3a5899df38cb3baf2b78f94f18bb599f29d908cf38290a3f1b2a8aef0b39785ecb1bbf0a5bb86eeac81f3a4aa8ff4858299f3bc80bef2ae80a3f1a396a8f28ca18bf3b794b5f38faaa3f0b181a5f3928a8bf2989cbaf2a9919ef296a8b5f39cb0aaf09eb5abf098abb0f2a382b1f1b3b1a8f1acb5aaf1b2bb98efb1bbf2b580adf1849facf39d8cbcf19bb5b9f09a8aa9f39f88bbe5b2b3f29c80a3f39fb596f1a7af97f48f87a6f0bb91b3f398a9a2f28d82a6f0a5a394f2999e93f0a5bc92f3a48b8af3bda295f482adb6f3a9a3a5f3bc89b5f195a1baf2a18db4f2969b9bf1a5bcb1f2b1b19bf39ea5abef9e9ff1b68d91f0b895b9f18db590f3b691baf399a9abe8afbbf094a9b2e98f8cf295b0b8f18eafb0f2868cbbf2a48e9bf3bdadaef394a9b8f1acb3a3f4878a8de7b0acf3b59495f48a8ba6df46480fdfbf78dfc7f1fea5dfd3a5b4668f5c48e16e086baf28852beb01a9d4";
11 |
12 | const packValue: TypedPackValue = {
13 | t: {
14 | struct: [
15 | { amount: PackPrimitive.U256 },
16 | { token: PackPrimitive.Str },
17 | { to: PackPrimitive.Str },
18 | { nonce: PackPrimitive.Bytes32 },
19 | ],
20 | },
21 | v: {
22 | amount: "92010210325214225514040705701652972196351460568772244563366741439829733769155",
23 | nonce: "30ZID9-_eN_H8f6l39OltGaPXEjhbghrryiFK-sBqdQ",
24 | to: "𠱕챻𥻆𱁥𘫰ﱻ岳𥣔𥼒读鏌簬",
25 | token: "𬀢䪢뭃𝗌㱅𡧤끭䟸芪𤽺纺𤀏",
26 | },
27 | };
28 |
29 | // const data = `0000000130000000104254432f66726f6d457468657265756d` + expected;
30 | // const hash = "c4e423c339ffb1c1bd37b6493a4f209391fb498466bb257fc565ba904804af5a";
31 |
32 | // expect(Ox(marshalTypedPackValue(packValue))).to.equal(expected);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/packages/utils/test/renVMHashes.spec.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from "bignumber.js";
2 | import { expect } from "chai";
3 |
4 | import { fromHex, Ox, toNBytes } from "../src/internal/common";
5 | import {
6 | generateGHash,
7 | generateNHash,
8 | generatePHash,
9 | generateSHash,
10 | generateSighash,
11 | } from "../src/renVMHashes";
12 |
13 | describe("renVMHashes", () => {
14 | const payload: Uint8Array = toNBytes(1, 32);
15 |
16 | context("generateSHash", () => {
17 | it("hashes correctly", () => {
18 | expect(Ox(generateSHash("BTC/toEthereum"))).to.equal(
19 | "0x1fb79ec5bb04cf1aa8eb8fdeda8d3f986e5ebaba72d0e12048cec0a95188fe5e",
20 | );
21 | expect(Ox(generateSHash("ZEC/toFantom"))).to.equal(
22 | "0x2cb58c03e9b6bb1f395dd8a458fc8e76767253ae17b364c817871899e2cf48ad",
23 | );
24 | });
25 |
26 | it("removes from chain for host-to-host", () => {
27 | expect(Ox(generateSHash("BTC/fromFantomToEthereum"))).to.equal(
28 | Ox(generateSHash("BTC/toEthereum")),
29 | );
30 | });
31 | });
32 |
33 | it("generatePHash", () => {
34 | expect(Ox(generatePHash(payload))).to.equal(
35 | "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6",
36 | );
37 | expect(Ox(generatePHash(payload))).to.equal(
38 | "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6",
39 | );
40 | });
41 |
42 | it("generateGHash", () => {
43 | const to = fromHex("00".repeat(20));
44 | const sHash = fromHex("00".repeat(20));
45 | const nonce = fromHex("00".repeat(32));
46 |
47 | expect(
48 | Ox(generateGHash(generatePHash(payload), to, sHash, nonce)),
49 | ).to.equal(
50 | "0x4b606c6a759e54ae3332637bd88050fff7be648b58d03f36491e277f94062ea9",
51 | );
52 | });
53 |
54 | it("generateNHash", () => {
55 | const nonce = fromHex("00".repeat(32));
56 | const txid = fromHex("00".repeat(32));
57 | const txindex = "1";
58 | expect(Ox(generateNHash(nonce, txid, txindex))).to.equal(
59 | "0xb92afca8929110484eee9b91373c9ed41205b90ce83867e5e9363041a70cfe3e",
60 | );
61 | });
62 |
63 | it("generateSighash", () => {
64 | const pHash = fromHex("12".repeat(32));
65 | const amount = new BigNumber(102);
66 | const to = fromHex("34".repeat(20));
67 | const selectorHash = fromHex("56".repeat(32));
68 | const nHash = fromHex("78".repeat(32));
69 |
70 | expect(
71 | Ox(generateSighash(pHash, amount, to, selectorHash, nHash)),
72 | ).to.equal(
73 | "0xcc6eacb85506fcb76a1951e79dfcc42a10751ff04bbfe5377fb06a1ecbe76e54",
74 | );
75 | });
76 | });
77 |
--------------------------------------------------------------------------------
/packages/utils/test/signatureUtils.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 | import { concat } from "ethers/lib/utils";
3 |
4 | import { utils } from "../src";
5 | import { normalizeSignature } from "../src/common";
6 | import { fromHex } from "../src/internal/common";
7 |
8 | const secp256k1nBuffer = fromHex(
9 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
10 | );
11 |
12 | describe("signatureUtils", () => {
13 | context("normalizeSignature", () => {
14 | it("should return fixed signatures", () => {
15 | expect(
16 | utils.toHex(
17 | normalizeSignature(
18 | concat([
19 | fromHex("11".repeat(32)),
20 | fromHex("00".repeat(32)),
21 | new Uint8Array([0]),
22 | ]),
23 | ),
24 | ),
25 | ).to.deep.equal(
26 | utils.toHex(
27 | concat([
28 | fromHex("11".repeat(32)),
29 | fromHex("00".repeat(32)),
30 | new Uint8Array([27]),
31 | ]),
32 | ),
33 | );
34 | expect(
35 | utils.toHex(
36 | normalizeSignature(
37 | concat([
38 | fromHex("00".repeat(32)),
39 | fromHex("00".repeat(32)),
40 | new Uint8Array([0]),
41 | ]),
42 | ),
43 | ),
44 | ).to.deep.equal(
45 | utils.toHex(
46 | concat([
47 | fromHex("00".repeat(32)),
48 | fromHex("00".repeat(32)),
49 | new Uint8Array([0]),
50 | ]),
51 | ),
52 | );
53 | expect(
54 | utils.toHex(
55 | normalizeSignature(
56 | concat([
57 | fromHex("00".repeat(32)),
58 | secp256k1nBuffer,
59 | new Uint8Array([0]),
60 | ]),
61 | ),
62 | ),
63 | ).to.deep.equal(
64 | utils.toHex(
65 | concat([
66 | fromHex("00".repeat(32)),
67 | fromHex("00".repeat(32)),
68 | new Uint8Array([28]),
69 | ]),
70 | ),
71 | );
72 | expect(
73 | utils.toHex(
74 | normalizeSignature(
75 | concat([
76 | fromHex("00".repeat(32)),
77 | secp256k1nBuffer,
78 | new Uint8Array([1]),
79 | ]),
80 | ),
81 | ),
82 | ).to.deep.equal(
83 | utils.toHex(
84 | concat([
85 | fromHex("00".repeat(32)),
86 | fromHex("00".repeat(32)),
87 | new Uint8Array([27]),
88 | ]),
89 | ),
90 | );
91 | });
92 | });
93 | });
94 |
--------------------------------------------------------------------------------
/packages/utils/test/txHash.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 | import { describe, it } from "mocha";
3 |
4 | import { Ox } from "../src/internal/common";
5 | import { PackPrimitive, TypedPackValue } from "../src/libraries/pack";
6 | import { generateTransactionHash } from "../src/renVMHashes";
7 |
8 | describe("txHash", () => {
9 | it("Hash transaction", () => {
10 | const expected =
11 | "0xc4e423c339ffb1c1bd37b6493a4f209391fb498466bb257fc565ba904804af5a";
12 |
13 | const packValue: TypedPackValue = {
14 | t: {
15 | struct: [
16 | { amount: PackPrimitive.U256 },
17 | { token: PackPrimitive.Str },
18 | { to: PackPrimitive.Str },
19 | { nonce: PackPrimitive.Bytes32 },
20 | ],
21 | },
22 | v: {
23 | amount: "92010210325214225514040705701652972196351460568772244563366741439829733769155",
24 | nonce: "30ZID9-_eN_H8f6l39OltGaPXEjhbghrryiFK-sBqdQ",
25 | to: "𠱕챻𥻆𱁥𘫰ﱻ岳𥣔𥼒读鏌簬",
26 | token: "𬀢䪢뭃𝗌㱅𡧤끭䟸芪𤽺纺𤀏",
27 | },
28 | };
29 |
30 | // const data = `0000000130000000104254432f66726f6d457468657265756d` + expected;
31 | // const hash = "";
32 |
33 | // 0000000131000000104254432f66726f6d457468657265756d140000000400000006616d6f756e740700000005746f6b656e0a00000002746f0a000000056e6f6e63650ccb6beefca4aded539a56f136a7ff24a2901fe6627233b8bf8d7d7f69c8737fc300000144f2b580a8f0ac80a2f294b3a9f1afaf86f18597b6f38186a3f1ada7aff185bc94f2908ba6f1a7afb3e4aaa2f481b0b1f29986a5f3aea7b1f488a3a1f396958aebad83f283ad81f0b2a8b5f193ada4f2b0b1b0f3a9b692f2a4a9bef2a9acb3f39d8abef189aab0f2878585f38aa1a9f18b97adf09d978cf29caabff3b099b9f2a494a5f39294a9f2b58299f393ba94f388979ae3b185f2b58fa9f294bfa2f390aa9df3ba84a1f29db093f0a1a7a4f18f939ef1a59d9df48fb0aaeb81ade49fb8e88aaaf0968aa2f1a488aaf381b6a8f0a4bdbaf3bf99aaf2a98e97f29eb486f2b294a2f1a98c86f1bab29be7babaf399bf93f285bf89f3b08996f3839b8df2b8af9af392adb6f0b58cabf2a484b3f0b6ac8af0a4808ff0aeb3a0f282949ceebfa9f2b5b48af3bb9da7f286819bf1b9b1baf39bbeb8f0baa484f18f8b8af398a691f2a39fa700000168f38285acf2bb93b7f0a0b195f0b3bfb6f1b980a7f2b4b28bf1b785b0f2a2afbef3baa99bf0b5b59cf187a6a1f3acb58ff3a5899df38cb3baf2b78f94f18bb599f29d908cf38290a3f1b2a8aef0b39785ecb1bbf0a5bb86eeac81f3a4aa8ff4858299f3bc80bef2ae80a3f1a396a8f28ca18bf3b794b5f38faaa3f0b181a5f3928a8bf2989cbaf2a9919ef296a8b5f39cb0aaf09eb5abf098abb0f2a382b1f1b3b1a8f1acb5aaf1b2bb98efb1bbf2b580adf1849facf39d8cbcf19bb5b9f09a8aa9f39f88bbe5b2b3f29c80a3f39fb596f1a7af97f48f87a6f0bb91b3f398a9a2f28d82a6f0a5a394f2999e93f0a5bc92f3a48b8af3bda295f482adb6f3a9a3a5f3bc89b5f195a1baf2a18db4f2969b9bf1a5bcb1f2b1b19bf39ea5abef9e9ff1b68d91f0b895b9f18db590f3b691baf399a9abe8afbbf094a9b2e98f8cf295b0b8f18eafb0f2868cbbf2a48e9bf3bdadaef394a9b8f1acb3a3f4878a8de7b0acf3b59495f48a8ba6df46480fdfbf78dfc7f1fea5dfd3a5b4668f5c48e16e086baf28852beb01a9d4
34 |
35 | expect(
36 | Ox(generateTransactionHash("0", "BTC/fromEthereum", packValue)),
37 | ).to.equal(expected);
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/packages/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "outDir": "build",
5 | "rootDir": "src",
6 | "moduleResolution": "node",
7 | "module": "commonjs",
8 | "declaration": true,
9 | "removeComments": false,
10 | "esModuleInterop": true,
11 | "strict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "traceResolution": false,
17 | "listEmittedFiles": false,
18 | "listFiles": false,
19 | "pretty": true,
20 | "lib": ["es2017", "dom"],
21 | "types": ["mocha"],
22 | "typeRoots": ["node_modules/@types", "src/types"],
23 | "resolveJsonModule": true,
24 | "forceConsistentCasingInFileNames": true,
25 | "noImplicitThis": true,
26 | "noImplicitAny": true,
27 | "strictNullChecks": true,
28 | "suppressImplicitAnyIndexErrors": true,
29 | "strictPropertyInitialization": true,
30 | "alwaysStrict": true,
31 | "strictFunctionTypes": true,
32 | "sourceMap": true,
33 | "declarationMap": true
34 | },
35 | "include": ["src/**/*.ts"],
36 | "exclude": ["node_modules/**"],
37 | "compileOnSave": false
38 | }
39 |
--------------------------------------------------------------------------------
/packages/utils/tsconfig.module.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "target": "es6",
5 | "outDir": "build/module",
6 | "module": "es6"
7 | },
8 | "exclude": ["node_modules/**"]
9 | }
10 |
--------------------------------------------------------------------------------
/test/index.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { Ethereum } from "packages/chains/chains-ethereum/src";
4 | import { BinanceSmartChain } from "packages/chains/chains/src";
5 | import RenJS from "packages/ren/src";
6 | import { RenNetwork } from "packages/utils";
7 |
8 | import { initializeChain } from "./utils/testUtils";
9 |
10 | const network = RenNetwork.Testnet;
11 |
12 | const main = async () => {
13 | // Initialize Ethereum and BSC chains.
14 | const ethereum = initializeChain(Ethereum, network);
15 | const bsc = initializeChain(BinanceSmartChain, network);
16 |
17 | // Create RenJS instance. NOTE - chains must now be linked to RenJS using
18 | // `withChains`.
19 | const renJS = new RenJS(network).withChains(ethereum, bsc);
20 |
21 | // Create gateway. Gateway parameters are serializable.
22 | const gateway = await renJS.gateway({
23 | asset: ethereum.assets.DAI,
24 | from: ethereum.Account({ amount: 2, convertUnit: true }),
25 | to: bsc.Account(),
26 | });
27 |
28 | // `gateway.fees` exposes values and helpers for calculating fees.
29 | console.debug("Fees", gateway.fees);
30 |
31 | // `gateway.inSetup` may contain multiple transactions.
32 | await gateway.inSetup.approval.submit({
33 | txConfig: {
34 | gasLimit: 1000000,
35 | },
36 | });
37 | // All transactions now follow a submit/wait pattern - see TxSubmitter
38 | // interface.
39 | await gateway.inSetup.approval.wait();
40 |
41 | // Transactions emit a `status`
42 | await gateway.in.submit().on("progress", console.debug);
43 | await gateway.in.wait(1);
44 |
45 | await new Promise((resolve, reject) => {
46 | gateway.on("transaction", (tx) => {
47 | (async () => {
48 | // GatewayTransaction parameters are serializable. To re-create
49 | // the transaction, call `renJS.gatewayTransaction`.
50 | console.debug(tx.params);
51 |
52 | // Wait for remaining confirmations for input transaction.
53 | await tx.in.wait();
54 |
55 | // RenVM transaction also follows the submit/wait pattern.
56 | await tx.renVM.submit().on("progress", console.debug);
57 | await tx.renVM.wait();
58 |
59 | // `submit` accepts a `txConfig` parameter for overriding
60 | // transaction config.
61 | await tx.out.submit({
62 | txConfig: {
63 | gasLimit: 1000000,
64 | },
65 | });
66 | await tx.out.wait();
67 |
68 | // All transactions return a `ChainTransaction` object in the
69 | // progress, with a `txid` field (base64) and a `txHash`
70 | // field (chain-dependent)
71 | const outTx = tx.out.progress.transaction;
72 | console.debug("Done:", outTx.txHash);
73 |
74 | resolve();
75 | })().catch(reject);
76 | });
77 | });
78 | };
79 |
80 | main().catch((error) => {
81 | console.error(error);
82 | process.exit(1);
83 | });
84 |
--------------------------------------------------------------------------------
/test/quickstart.spec.ts:
--------------------------------------------------------------------------------
1 | // import { providers, Wallet } from "ethers";
2 |
3 | // import { Bitcoin, Ethereum } from "@renproject/chains";
4 | // import RenJS from "@renproject/ren";
5 |
6 | // // Test account - do not send real funds.
7 | // const mnemonic =
8 | // "black magic humor turtle symptom liar salmon rally hurt concert tower run";
9 |
10 | // const main = async () => {
11 | // const network = "testnet";
12 |
13 | // // Initialize Bitcoin and Ethereum.
14 | // const bitcoin = new Bitcoin({ network });
15 | // const ethereum = new Ethereum({
16 | // network,
17 | // provider: new providers.JsonRpcProvider(
18 | // Ethereum.configMap[network].config.rpcUrls[0],
19 | // ),
20 | // signer: Wallet.fromMnemonic(mnemonic),
21 | // });
22 |
23 | // // Create RenJS instance. NOTE - chains must now be linked to RenJS using
24 | // // `withChains`.
25 | // const renJS = new RenJS(network).withChains(bitcoin, ethereum);
26 |
27 | // // Create gateway - mints and burns are both initialized with `gateway`.
28 | // // Gateway parameters are serializable.
29 | // const gateway = await renJS.gateway({
30 | // asset: ethereum.assets.DAI, // "DAI"
31 | // from: bitcoin.GatewayAddress(),
32 | // to: ethereum.Account(),
33 | // });
34 |
35 | // // `gateway.fees` exposes values and helpers for calculating fees.
36 | // console.info(gateway.fees);
37 |
38 | // console.info(`Deposit ${gateway.params.asset} to ${gateway.gatewayAddress}`);
39 |
40 | // // NOTE: Event has been renamed from "deposit" to "transaction".
41 | // gateway.on("transaction", (tx) => {
42 | // (async () => {
43 | // // GatewayTransaction parameters are serializable. To re-create
44 | // // the transaction, call `renJS.gatewayTransaction`.
45 | // console.info(tx.params);
46 |
47 | // // Wait for remaining confirmations for input transaction.
48 | // await tx.in.wait();
49 |
50 | // // RenVM transaction also follows the submit/wait pattern.
51 | // await tx.renVM.submit().on("progress", console.info);
52 | // await tx.renVM.wait();
53 |
54 | // // `submit` accepts a `txConfig` parameter for overriding
55 | // // transaction config.
56 | // await tx.out.submit({
57 | // txConfig: {
58 | // gasLimit: 1000000,
59 | // },
60 | // });
61 | // await tx.out.wait();
62 |
63 | // // All transactions return a `ChainTransaction` object in the
64 | // // progress, with a `txid` field (base64) and a `txHash`
65 | // // field (chain-dependent).
66 | // const outTx = tx.out.progress.transaction;
67 | // console.info("Done:", outTx.txHash);
68 |
69 | // // All chain classes expose a common set of helper functions (see
70 | // // `Chain` class.)
71 | // console.info(tx.toChain.transactionExplorerLink(outTx));
72 | // })().catch(console.error);
73 | // });
74 | // };
75 |
76 | // main().catch((error) => {
77 | // console.error(error);
78 | // process.exit(1);
79 | // });
80 |
--------------------------------------------------------------------------------
/test/simple.spec.ts:
--------------------------------------------------------------------------------
1 | import { Ethereum } from "@renproject/chains-ethereum/src";
2 | import { RenNetwork } from "@renproject/utils";
3 | /* eslint-disable no-console */
4 | import chalk from "chalk";
5 | import { BinanceSmartChain } from "packages/chains/chains/src";
6 | import RenJS from "packages/ren/src";
7 |
8 | import { initializeChain } from "./utils/testUtils";
9 |
10 | const network = RenNetwork.Testnet;
11 |
12 | /**
13 | * Same as daiToBsc except:
14 | * - calls `gateway.inSetup.approval` directly instead of looping through `setup`
15 | * - no retrying on errors
16 | * - less logs
17 | */
18 |
19 | describe("DAI/toBinanceSmartChain - simpler", () => {
20 | it("DAI/toBinanceSmartChain - simpler", async () => {
21 | const ethereum = initializeChain(Ethereum, network);
22 | const bsc = initializeChain(BinanceSmartChain, network);
23 |
24 | const renJS = new RenJS(network).withChains(ethereum, bsc);
25 |
26 | const gateway = await renJS.gateway({
27 | asset: ethereum.assets.DAI,
28 | from: ethereum.Account({ amount: 2, convertUnit: true }),
29 | to: bsc.Account(),
30 | });
31 |
32 | console.debug(chalk.cyan("gateway parameters"), gateway.params);
33 |
34 | console.debug(chalk.cyan("calling setup.approval.submit()"));
35 | await gateway.inSetup.approval.submit({
36 | txConfig: {
37 | gasLimit: 1000000,
38 | },
39 | });
40 | await gateway.inSetup.approval.wait();
41 |
42 | console.debug(chalk.cyan("calling in.submit()"));
43 | await gateway.in.submit().on("progress", console.debug);
44 | await gateway.in.wait(1);
45 |
46 | await new Promise((resolve, reject) => {
47 | gateway.on("transaction", (tx) => {
48 | (async () => {
49 | console.debug(chalk.cyan("tx parameters"), tx.params);
50 |
51 | await tx.in.wait();
52 |
53 | console.debug(chalk.cyan("calling renVM.submit()"));
54 | await tx.renVM.submit().on("progress", console.debug);
55 | await tx.renVM.wait();
56 |
57 | console.debug(chalk.cyan("calling out.submit()"));
58 | await tx.out
59 | .submit({
60 | txConfig: {
61 | gasLimit: 1000000,
62 | },
63 | })
64 | .on("progress", console.debug);
65 | await tx.out.wait();
66 |
67 | console.debug(
68 | chalk.cyan("Done"),
69 | tx.out.progress.transaction,
70 | );
71 |
72 | resolve();
73 | })().catch(reject);
74 | });
75 | });
76 | }).timeout(100000000000);
77 | });
78 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "esModuleInterop": true
5 | },
6 | "exclude": ["node_modules/**"]
7 | }
8 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require("path");
2 | var nodeExternals = require("webpack-node-externals");
3 |
4 | let common = {
5 | entry: "./src/index.ts",
6 | devtool: "source-map",
7 | module: {
8 | rules: [
9 | {
10 | test: /\.tsx?$/,
11 | use: ["babel-loader", "ts-loader"],
12 | exclude: /node_modules/,
13 | },
14 | ],
15 | },
16 | plugins: [],
17 | resolve: {
18 | extensions: [".ts", ".tsx", ".js"],
19 | },
20 | };
21 |
22 | module.exports = [
23 | Object.assign({}, common, {
24 | target: "web",
25 | entry: ["babel-polyfill", "./src/index.ts"],
26 | output: {
27 | path: path.resolve(/* __dirname */ "./", "build/bundled"),
28 | filename: "browser.js",
29 | libraryTarget: "var",
30 | library: "RenVM", // This is the var name in browser
31 | libraryExport: "default",
32 | },
33 | resolve: {
34 | ...common.resolve,
35 | fallback: {
36 | fs: "empty",
37 | child_process: "empty",
38 | },
39 | },
40 | }),
41 | Object.assign({}, common, {
42 | target: "node",
43 | output: {
44 | path: path.resolve(/* __dirname */ "./", "build/bundled"),
45 | filename: "index.js",
46 | libraryTarget: "commonjs2",
47 | // libraryExport: 'default'
48 | },
49 | externals: [nodeExternals()],
50 | }),
51 | ];
52 |
--------------------------------------------------------------------------------