├── docs
├── .nojekyll
├── modules.md
├── _sidebar.md
├── enums
│ ├── constants.network.md
│ └── constants.ilostate.md
├── index.html
├── interfaces
│ └── batch.batchrequest.md
├── modules
│ ├── batch.md
│ ├── constants.md
│ ├── utils.md
│ ├── zilo.md
│ └── index.md
├── CONTRIBUTING.md
├── README.md
└── classes
│ ├── zilo.zilo-1.md
│ └── index.zilswap.md
├── .gitignore
├── .prettierrc
├── tslint.json
├── .github
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── LICENSE
├── package.json
├── src
├── batch.ts
├── constants.ts
├── utils.ts
├── test.ts
├── zilo.ts
└── index.ts
├── README.md
├── CODE_OF_CONDUCT.md
├── tsconfig.json
└── yarn.lock
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /lib
3 | index.js
4 | .DS_Store
5 | yarn-error.log
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 140,
3 | "singleQuote": true,
4 | "semi": false,
5 | "arrowParens": "avoid"
6 | }
7 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["tslint:recommended", "tslint-config-prettier"],
3 | "rules": {
4 | "one-variable-per-declaration": false,
5 | "no-console": false,
6 | "no-string-literal": false
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/docs/modules.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](README.md) / Exports
2 |
3 | # zilswap-sdk
4 |
5 | ## Table of contents
6 |
7 | ### Modules
8 |
9 | - [batch](modules/batch.md)
10 | - [constants](modules/constants.md)
11 | - [index](modules/index.md)
12 | - [utils](modules/utils.md)
13 | - [zilo](modules/zilo.md)
14 |
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | - [Documentation](/)
2 | - [modules]
3 | - [batch](modules/batch.md)
4 | - [constants](modules/constants.md)
5 | - [utils](modules/utils.md)
6 | - [zilo](modules/zilo.md)
7 | - [zilswap](modules/index.md)
8 | - classes
9 | - [zilo](classes/zilo.zilo-1.md)
10 | - [zilswap](classes/index.zilswap.md)
11 | - enums
12 | - [ilostate](enums/constants.ilostate.md)
13 | - [network](enums/constants.network.md)
14 | - interfaces
15 | - [batchrequest](interfaces/batch.batchrequest.md)
16 | - [Contributing](CONTRIBUTING.md)
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE] ..."
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/docs/enums/constants.network.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / [constants](../modules/constants.md) / Network
2 |
3 | # Enumeration: Network
4 |
5 | [constants](../modules/constants.md)
6 |
7 | ## Table of contents
8 |
9 | ### Enumeration members
10 |
11 | - [MainNet](constants.network.md#mainnet)
12 | - [TestNet](constants.network.md#testnet)
13 |
14 | ## Enumeration members
15 |
16 | ### MainNet
17 |
18 | • **MainNet** = "MainNet"
19 |
20 | #### Defined in
21 |
22 | [constants.ts:4](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L4)
23 |
24 | ___
25 |
26 | ### TestNet
27 |
28 | • **TestNet** = "TestNet"
29 |
30 | #### Defined in
31 |
32 | [constants.ts:5](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L5)
33 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Document
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG] ..."
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Switcheo
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 |
--------------------------------------------------------------------------------
/docs/interfaces/batch.batchrequest.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / [batch](../modules/batch.md) / BatchRequest
2 |
3 | # Interface: BatchRequest
4 |
5 | [batch](../modules/batch.md)
6 |
7 | ## Table of contents
8 |
9 | ### Properties
10 |
11 | - [id](batch.batchrequest.md#id)
12 | - [jsonrpc](batch.batchrequest.md#jsonrpc)
13 | - [method](batch.batchrequest.md#method)
14 | - [params](batch.batchrequest.md#params)
15 |
16 | ## Properties
17 |
18 | ### id
19 |
20 | • **id**: `string`
21 |
22 | #### Defined in
23 |
24 | [batch.ts:4](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L4)
25 |
26 | ___
27 |
28 | ### jsonrpc
29 |
30 | • **jsonrpc**: `string`
31 |
32 | #### Defined in
33 |
34 | [batch.ts:5](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L5)
35 |
36 | ___
37 |
38 | ### method
39 |
40 | • **method**: `string`
41 |
42 | #### Defined in
43 |
44 | [batch.ts:6](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L6)
45 |
46 | ___
47 |
48 | ### params
49 |
50 | • **params**: `any`[]
51 |
52 | #### Defined in
53 |
54 | [batch.ts:7](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L7)
55 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zilswap-sdk",
3 | "version": "1.3.27",
4 | "description": "Zilswap TypeScript SDK",
5 | "main": "lib/index.js",
6 | "types": "lib/index.d.ts",
7 | "repository": "https://github.com/Switcheo/zilswap-sdk",
8 | "homepage": "https://github.com/Switcheo/zilswap-sdk#readme",
9 | "author": "Switcheo ",
10 | "license": "MIT",
11 | "scripts": {
12 | "build": "tsc",
13 | "test": "tsc && node lib/test.js",
14 | "format": "prettier --write \"src/**/*.ts\"",
15 | "lint": "tslint -p tsconfig.json",
16 | "prepare": "yarn run build",
17 | "prepublishOnly": "yarn run lint",
18 | "preversion": "yarn run lint",
19 | "version": "yarn run format && git add -A src",
20 | "postversion": "git push && git push --tags"
21 | },
22 | "files": [
23 | "lib/**/*"
24 | ],
25 | "dependencies": {
26 | "@zilliqa-js/zilliqa": "^2.2.0",
27 | "async-mutex": "^0.2.2",
28 | "bignumber.js": "^9.0.0",
29 | "bn.js": "^5.1.1",
30 | "isomorphic-fetch": "^3.0.0",
31 | "tslib": "^1.11.2"
32 | },
33 | "devDependencies": {
34 | "@types/node": "^13.13.5",
35 | "@types/websocket": "^1.0.0",
36 | "prettier": "^2.0.5",
37 | "tslint-config-prettier": "^1.18.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/batch.ts:
--------------------------------------------------------------------------------
1 | import 'isomorphic-fetch'
2 |
3 | export interface BatchRequest {
4 | id: string
5 | jsonrpc: string
6 | method: string
7 | params: any[]
8 | }
9 |
10 | export type BatchResponse = { [key in string]: any }
11 |
12 | /**
13 | * Sends a series of requests as a batch to the Zilliqa API.
14 | *
15 | * @param rpcEndpoint The rpc endpoint to query.
16 | * @param requests[] An array of RPC requests.
17 | * @returns Promise<{ [key in string]: BatchResponse }> Map of RPC responses keyed by the request ID.
18 | */
19 | export const sendBatchRequest = async (rpcEndpoint: string, requests: BatchRequest[]): Promise => {
20 | const response = await fetch(rpcEndpoint, {
21 | method: 'POST',
22 | mode: 'cors',
23 | cache: 'no-cache',
24 | headers: {
25 | 'Content-Type': 'application/json',
26 | },
27 | redirect: 'follow',
28 | referrerPolicy: 'no-referrer',
29 | body: JSON.stringify(requests),
30 | })
31 |
32 | const results: BatchResponse[] = await response.json()
33 | const errors = results
34 | .map(r => (r.error ? `[${r.id}] ${r.error.message}` : null))
35 | .filter(e => !!e)
36 | .join('. ')
37 | if (errors && errors.length > 0) {
38 | throw new Error('Failed to send batch request: ' + errors)
39 | }
40 | return results.reduce((a, c) => ({ ...a, [c.id]: c.result }), {})
41 | }
42 |
--------------------------------------------------------------------------------
/docs/modules/batch.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / batch
2 |
3 | # Module: batch
4 |
5 | ## Table of contents
6 |
7 | ### Interfaces
8 |
9 | - [BatchRequest](../interfaces/batch.batchrequest.md)
10 |
11 | ### Type aliases
12 |
13 | - [BatchResponse](batch.md#batchresponse)
14 |
15 | ### Functions
16 |
17 | - [sendBatchRequest](batch.md#sendbatchrequest)
18 |
19 | ## Type aliases
20 |
21 | ### BatchResponse
22 |
23 | Ƭ **BatchResponse**: { [key in string]: any}
24 |
25 | #### Defined in
26 |
27 | [batch.ts:10](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L10)
28 |
29 | ## Functions
30 |
31 | ### sendBatchRequest
32 |
33 | ▸ `Const` **sendBatchRequest**(`rpcEndpoint`, `requests`): `Promise`<[BatchResponse](batch.md#batchresponse)\>
34 |
35 | Sends a series of requests as a batch to the Zilliqa API.
36 |
37 | #### Parameters
38 |
39 | | Name | Type | Description |
40 | | :------ | :------ | :------ |
41 | | `rpcEndpoint` | `string` | The rpc endpoint to query. |
42 | | `requests` | [BatchRequest](../interfaces/batch.batchrequest.md)[] | - |
43 |
44 | #### Returns
45 |
46 | `Promise`<[BatchResponse](batch.md#batchresponse)\>
47 |
48 | Promise<{ [key in string]: BatchResponse }> Map of RPC responses keyed by the request ID.
49 |
50 | #### Defined in
51 |
52 | [batch.ts:19](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/batch.ts#L19)
53 |
--------------------------------------------------------------------------------
/docs/enums/constants.ilostate.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / [constants](../modules/constants.md) / ILOState
2 |
3 | # Enumeration: ILOState
4 |
5 | [constants](../modules/constants.md)
6 |
7 | ## Table of contents
8 |
9 | ### Enumeration members
10 |
11 | - [Active](constants.ilostate.md#active)
12 | - [Completed](constants.ilostate.md#completed)
13 | - [Failed](constants.ilostate.md#failed)
14 | - [Pending](constants.ilostate.md#pending)
15 | - [Uninitialized](constants.ilostate.md#uninitialized)
16 |
17 | ## Enumeration members
18 |
19 | ### Active
20 |
21 | • **Active** = "Active"
22 |
23 | #### Defined in
24 |
25 | [constants.ts:27](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L27)
26 |
27 | ___
28 |
29 | ### Completed
30 |
31 | • **Completed** = "Completed"
32 |
33 | #### Defined in
34 |
35 | [constants.ts:29](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L29)
36 |
37 | ___
38 |
39 | ### Failed
40 |
41 | • **Failed** = "Failed"
42 |
43 | #### Defined in
44 |
45 | [constants.ts:28](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L28)
46 |
47 | ___
48 |
49 | ### Pending
50 |
51 | • **Pending** = "Pending"
52 |
53 | #### Defined in
54 |
55 | [constants.ts:26](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L26)
56 |
57 | ___
58 |
59 | ### Uninitialized
60 |
61 | • **Uninitialized** = "Uninitialized"
62 |
63 | #### Defined in
64 |
65 | [constants.ts:25](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L25)
66 |
--------------------------------------------------------------------------------
/docs/modules/constants.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / constants
2 |
3 | # Module: constants
4 |
5 | ## Table of contents
6 |
7 | ### Enumerations
8 |
9 | - [ILOState](../enums/constants.ilostate.md)
10 | - [Network](../enums/constants.network.md)
11 |
12 | ### Variables
13 |
14 | - [APIS](constants.md#apis)
15 | - [BASIS](constants.md#basis)
16 | - [CHAIN\_VERSIONS](constants.md#chain_versions)
17 | - [CONTRACTS](constants.md#contracts)
18 | - [WSS](constants.md#wss)
19 | - [ZIL\_HASH](constants.md#zil_hash)
20 |
21 | ## Variables
22 |
23 | ### APIS
24 |
25 | • `Const` **APIS**: { [key in Networks]: string}
26 |
27 | #### Defined in
28 |
29 | [constants.ts:9](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L9)
30 |
31 | ___
32 |
33 | ### BASIS
34 |
35 | • `Const` **BASIS**: ``10000``
36 |
37 | #### Defined in
38 |
39 | [constants.ts:37](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L37)
40 |
41 | ___
42 |
43 | ### CHAIN\_VERSIONS
44 |
45 | • `Const` **CHAIN\_VERSIONS**: { [key in Networks]: number}
46 |
47 | #### Defined in
48 |
49 | [constants.ts:32](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L32)
50 |
51 | ___
52 |
53 | ### CONTRACTS
54 |
55 | • `Const` **CONTRACTS**: { [key in Networks]: string}
56 |
57 | #### Defined in
58 |
59 | [constants.ts:19](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L19)
60 |
61 | ___
62 |
63 | ### WSS
64 |
65 | • `Const` **WSS**: { [key in Networks]: string}
66 |
67 | #### Defined in
68 |
69 | [constants.ts:14](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L14)
70 |
71 | ___
72 |
73 | ### ZIL\_HASH
74 |
75 | • `Const` **ZIL\_HASH**: ``"0x0000000000000000000000000000000000000000"``
76 |
77 | #### Defined in
78 |
79 | [constants.ts:39](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/constants.ts#L39)
80 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | import { bytes } from '@zilliqa-js/util'
2 |
3 | export enum Network {
4 | MainNet = 'MainNet',
5 | TestNet = 'TestNet',
6 | }
7 | type Networks = keyof typeof Network
8 |
9 | export const APIS: { [key in Networks]: string } = {
10 | [Network.MainNet]: 'https://api.zilliqa.com',
11 | [Network.TestNet]: 'https://dev-api.zilliqa.com',
12 | }
13 |
14 | export const WSS: { [key in Networks]: string } = {
15 | [Network.MainNet]: 'wss://api-ws.zilliqa.com',
16 | [Network.TestNet]: 'wss://dev-ws.zilliqa.com',
17 | }
18 |
19 | export const CONTRACTS: { [key in Networks]: string } = {
20 | [Network.MainNet]: 'zil1gkwt95a67lnpe774lcmz72y6ay4jh2asmmjw6u',
21 | [Network.TestNet]: 'zil1rf3dm8yykryffr94rlrxfws58earfxzu5lw792',
22 | }
23 |
24 | export const ARK_CONTRACTS: { [key in Networks]: string } = {
25 | [Network.MainNet]: '',
26 | [Network.TestNet]: 'zil1sgf3zpgt6qeflg053pxjwx9s9pxclx3p7s06gp',
27 | }
28 |
29 | export const WHITELISTED_TOKENS: { [key in Networks]: string[] } = {
30 | [Network.MainNet]: [
31 | 'zil1gvr0jgwfsfmxsyx0xsnhtlte4gks6r3yk8x5fn', // wZIL
32 | 'zil1p5suryq6q647usxczale29cu3336hhp376c627', // ZWAP
33 | 'zil1zu72vac254htqpg3mtywdcfm84l3dfd9qzww8t', // XSGD
34 | 'zil14pzuzq6v6pmmmrfjhczywguu0e97djepxt8g3e', // gZIL
35 | 'zil1sxx29cshups269ahh5qjffyr58mxjv9ft78jqy', // zUSDT
36 | 'zil1wha8mzaxhm22dpm5cav2tepuldnr8kwkvmqtjq', // zWBTC
37 | 'zil19j33tapjje2xzng7svslnsjjjgge930jx0w09v', // zETH
38 | 'zil1yk93f957fanapf0yszgm84p62xrxxfytj4d2tl', // SWTH
39 | ],
40 | [Network.TestNet]: [],
41 | }
42 |
43 | export enum ILOState {
44 | Uninitialized = 'Uninitialized',
45 | Pending = 'Pending',
46 | Active = 'Active',
47 | Failed = 'Failed',
48 | Completed = 'Completed',
49 | }
50 |
51 | export const CHAIN_VERSIONS: { [key in Networks]: number } = {
52 | [Network.MainNet]: bytes.pack(1, 1),
53 | [Network.TestNet]: bytes.pack(333, 1),
54 | }
55 |
56 | export const BASIS = 10000
57 |
58 | export const ZIL_HASH = '0x0000000000000000000000000000000000000000'
59 |
--------------------------------------------------------------------------------
/docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # CONTRIBUTING
2 |
3 | ## How to contribute to Zilswap SDK
4 |
5 | ### **Do you intend to add your project's token logo?**
6 |
7 | Please visit the [zilswap token list](https://github.com/Switcheo/zilswap-token-list) to add your token logo. This repository only hosts the Zilswap UI source code.
8 |
9 | ### **Did you find a bug?**
10 |
11 | * **Do not open up a GitHub issue if the bug is a security vulnerability
12 | in the Zilswap SDK or smart contract**, and instead to send an email to [security@switcheo.network](mailto:https://security@switcheo.network).
13 |
14 | * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/Switcheo/zilswap-sdk/issues).
15 |
16 | * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Switcheo/zilswap-sdk/issues/new).
17 | Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or
18 | an **executable test case** demonstrating the expected behavior that is not occurring.
19 |
20 | * If possible, use the relevant bug report templates to create the issue.
21 |
22 | ### **Did you write a patch that fixes a bug?**
23 |
24 | * Open a new GitHub pull request with the patch.
25 |
26 | * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
27 |
28 | ### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
29 |
30 | Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of Zilswap will generally not be accepted.
31 |
32 | ### **Do you intend to add a new feature or change an existing one?**
33 |
34 | * Suggest your change in the [zilswap discord channel](https://discord.gg/5n8AMQH) and start writing code.
35 |
36 | * Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
37 |
38 | ### **Do you want to contribute to the Zilswap UI or documentation?**
39 |
40 | * Please see [https://github.com/Switcheo/zilswap-webapp/blob/master/CONTRIBUTING.md] to contribute to the Zilswap UI.
41 |
42 | * Please see [https://github.com/Switcheo/zilswap/blob/master/CONTRIBUTING.md] to contribute to the Zilswap docuemntation.
43 |
44 | ### **Do you have questions about the source code?**
45 |
46 | Ask any question about how to use Zilswap in the [zilswap discord channel](https://discord.gg/5n8AMQH).
47 |
--------------------------------------------------------------------------------
/docs/modules/utils.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / utils
2 |
3 | # Module: utils
4 |
5 | ## Table of contents
6 |
7 | ### Functions
8 |
9 | - [contractInitToMap](utils.md#contractinittomap)
10 | - [isLocalStorageAvailable](utils.md#islocalstorageavailable)
11 | - [toPositiveQa](utils.md#topositiveqa)
12 | - [unitlessBigNumber](utils.md#unitlessbignumber)
13 |
14 | ## Functions
15 |
16 | ### contractInitToMap
17 |
18 | ▸ `Const` **contractInitToMap**(`params`): `Object`
19 |
20 | Converts `Value[]` array to map of string values.
21 | `Value.type` is ignored, all values are returned as string.
22 |
23 | sample input:
24 | ```javascript
25 | [{
26 | name: 'address',
27 | type: 'ByStr20',
28 | value: '0xbadbeef',
29 | }, {
30 | name: 'balance',
31 | type: 'UInt28',
32 | value: '100000000',
33 | }]
34 | ```
35 |
36 | output:
37 | ```javascript
38 | {
39 | address: '0xbadbeef',
40 | balance: '100000000',
41 | }
42 | ```
43 |
44 | #### Parameters
45 |
46 | | Name | Type | Description |
47 | | :------ | :------ | :------ |
48 | | `params` | `Value`[] | parameters in `Value[]` array representation |
49 |
50 | #### Returns
51 |
52 | `Object`
53 |
54 | mapped object representation - refer to sample output
55 |
56 | #### Defined in
57 |
58 | [utils.ts:150](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/utils.ts#L150)
59 |
60 | ___
61 |
62 | ### isLocalStorageAvailable
63 |
64 | ▸ `Const` **isLocalStorageAvailable**(): `boolean`
65 |
66 | #### Returns
67 |
68 | `boolean`
69 |
70 | #### Defined in
71 |
72 | [utils.ts:100](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/utils.ts#L100)
73 |
74 | ___
75 |
76 | ### toPositiveQa
77 |
78 | ▸ `Const` **toPositiveQa**(`input`, `unitOrDecimals`): `BN`
79 |
80 | #### Parameters
81 |
82 | | Name | Type |
83 | | :------ | :------ |
84 | | `input` | `string` \| `number` \| `BN` |
85 | | `unitOrDecimals` | `number` \| `Zil` \| `Li` \| `Qa` |
86 |
87 | #### Returns
88 |
89 | `BN`
90 |
91 | #### Defined in
92 |
93 | [utils.ts:40](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/utils.ts#L40)
94 |
95 | ___
96 |
97 | ### unitlessBigNumber
98 |
99 | ▸ `Const` **unitlessBigNumber**(`str`): `BigNumber`
100 |
101 | #### Parameters
102 |
103 | | Name | Type |
104 | | :------ | :------ |
105 | | `str` | `string` |
106 |
107 | #### Returns
108 |
109 | `BigNumber`
110 |
111 | #### Defined in
112 |
113 | [utils.ts:32](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/utils.ts#L32)
114 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Zilswap Typescript SDK
2 |
3 | ## Setup
4 |
5 | Install from npm:
6 |
7 | `npm install zilswap-sdk`
8 |
9 | ## SDK Usage
10 |
11 | Initialize the sdk based on the required network, then call the required methods which will automatically map and call the corresponding smart contract correct transitions.
12 |
13 | ```ts
14 | import { Zilswap } from 'zilswap-sdk'
15 |
16 | (async () => {
17 | const zilswap = new Zilswap(Network.TestNet)
18 | await zilswap.initialize()
19 | await zilswap.addLiquidity('SWTH', '42', '42')
20 | await zilswap.teardown()
21 | })()
22 | ```
23 |
24 | ### Methods
25 |
26 | All public Zilswap methods can be found on the [`Zilswap` SDK object](classes/index.zilswap.md).
27 |
28 | All public Zilo methods can be found on the [`Zilo` SDK object](classes/zilo.zilo-1.md).
29 |
30 | Full typescript definitions can also be found in the [Modules](modules.md).
31 |
32 | The following is a list of methods to quickly get you started:
33 |
34 | #### Swap & Liquidity
35 |
36 | - `approveTokenTransferIfRequired` - approves transfers to zilswap for the given token contract, if the current approval amount is insufficient.
37 | - `addLiquidity` - adds liquidity to the pool
38 | - `removeLiquidity` - removes liquidity to the pool
39 | - `swapWithExactInput` - swaps a token for another token, specifying the exact amount that should be given.
40 | - `swapWithExactOutput` - swaps a token for another token, specifying the exact amount that should be received.
41 |
42 | #### Getters
43 |
44 | - `getAppState` - gets the current dApp state
45 | - `getPool` - gets the reserve values for a pool
46 | - `getObservedTxs` - gets the txs that the SDK is observing
47 |
48 | #### Configuration
49 |
50 | - `addToken` - adds a token that is not in the pre-built list
51 | - `observeTx` - observe a zilliqa blockchain tx
52 | - `setDeadlineBlocks` - set the number of blocks before a transition sent by the SDK to expires
53 |
54 | #### Helpers
55 |
56 | - `toUnitless` - converts a human amount into a unitless integer that is used by Scilla.
57 | - `toUnit` - converts a unitless integer used by scilla into a human readable amount.
58 | - `getRatesForInput` - get the current exchange rates for a pool by giving an input amount.
59 | - `getRatesForOutput` - get the current exchange rates for a pool by giving an output amount.
60 |
61 | ## Test Usage
62 |
63 | 1. Ensure enough tokens minted to your address on testnet
64 | 2. Run `PRIVATE_KEY=xxx yarn run test`
65 |
66 | ## Developing
67 |
68 | Generate documentation with typedoc. Install with:
69 |
70 | `npm i typedoc typedoc-plugin-markdown --global`
71 |
72 | then run:
73 |
74 | `typedoc --out ./doc ./src --excludePrivate --excludeNotExported --plugin typedoc-plugin-markdown`
75 |
76 | ## Contributing
77 |
78 | Please review the [contribution guidelines](./CONTRIBUTING.md) before contributing or opening pull requests.
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zilswap Typescript SDK
2 |
3 | ## Setup
4 |
5 | Install from npm:
6 |
7 | `npm install zilswap-sdk`
8 |
9 | ## SDK Usage
10 |
11 | Initialize the sdk based on the required network, then call the required methods which will automatically map and call the corresponding smart contract correct transitions.
12 |
13 | ```ts
14 | import { Zilswap } from 'zilswap-sdk'
15 |
16 | (async () => {
17 | const zilswap = new Zilswap(Network.TestNet)
18 | await zilswap.initialize()
19 | await zilswap.addLiquidity('SWTH', '42', '42')
20 | await zilswap.teardown()
21 | })()
22 | ```
23 |
24 | ### Methods
25 |
26 | All public Zilswap methods can be found on the [`Zilswap` SDK object](./docs/classes/index.zilswap.md).
27 |
28 | All public Zilo methods can be found on the [`Zilo` SDK object](./docs/classes/zilo.zilo-1.md).
29 |
30 | Full typescript definitions can also be found in the [Modules](./docs/modules.md).
31 |
32 | The following is a list of methods to quickly get you started:
33 |
34 | #### Swap & Liquidity
35 |
36 | - `approveTokenTransferIfRequired` - approves transfers to zilswap for the given token contract, if the current approval amount is insufficient.
37 | - `addLiquidity` - adds liquidity to the pool
38 | - `removeLiquidity` - removes liquidity to the pool
39 | - `swapWithExactInput` - swaps a token for another token, specifying the exact amount that should be given.
40 | - `swapWithExactOutput` - swaps a token for another token, specifying the exact amount that should be received.
41 |
42 | #### Getters
43 |
44 | - `getAppState` - gets the current dApp state
45 | - `getPool` - gets the reserve values for a pool
46 | - `getObservedTxs` - gets the txs that the SDK is observing
47 |
48 | #### Configuration
49 |
50 | - `addToken` - adds a token that is not in the pre-built list
51 | - `observeTx` - observe a zilliqa blockchain tx
52 | - `setDeadlineBlocks` - set the number of blocks before a transition sent by the SDK to expires
53 |
54 | #### Helpers
55 |
56 | - `toUnitless` - converts a human amount into a unitless integer that is used by Scilla.
57 | - `toUnit` - converts a unitless integer used by scilla into a human readable amount.
58 | - `getRatesForInput` - get the current exchange rates for a pool by giving an input amount.
59 | - `getRatesForOutput` - get the current exchange rates for a pool by giving an output amount.
60 |
61 | ## Test Usage
62 |
63 | 1. Ensure enough tokens minted to your address on testnet
64 | 2. Run `PRIVATE_KEY=xxx yarn run test`
65 |
66 | ## Developing
67 |
68 | Generate documentation with typedoc. Install with:
69 |
70 | `npm i typedoc typedoc-plugin-markdown --global`
71 |
72 | then run:
73 |
74 | `typedoc --out ./doc ./src --excludePrivate --excludeNotExported --plugin typedoc-plugin-markdown`
75 |
76 | ## Contributing
77 |
78 | Please review the [contribution guidelines](docs/CONTRIBUTING.md) before contributing or opening pull requests.
79 |
--------------------------------------------------------------------------------
/docs/modules/zilo.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / zilo
2 |
3 | # Module: zilo
4 |
5 | ## Table of contents
6 |
7 | ### Classes
8 |
9 | - [Zilo](../classes/zilo.zilo-1.md)
10 |
11 | ### Type aliases
12 |
13 | - [OnStateUpdate](zilo.md#onstateupdate)
14 | - [ZiloAppState](zilo.md#ziloappstate)
15 | - [ZiloContractInit](zilo.md#zilocontractinit)
16 | - [ZiloContractState](zilo.md#zilocontractstate)
17 |
18 | ## Type aliases
19 |
20 | ### OnStateUpdate
21 |
22 | Ƭ **OnStateUpdate**: (`appState`: [ZiloAppState](zilo.md#ziloappstate)) => `void`
23 |
24 | #### Type declaration
25 |
26 | ▸ (`appState`): `void`
27 |
28 | ##### Parameters
29 |
30 | | Name | Type |
31 | | :------ | :------ |
32 | | `appState` | [ZiloAppState](zilo.md#ziloappstate) |
33 |
34 | ##### Returns
35 |
36 | `void`
37 |
38 | #### Defined in
39 |
40 | [zilo.ts:14](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L14)
41 |
42 | ___
43 |
44 | ### ZiloAppState
45 |
46 | Ƭ **ZiloAppState**: `Object`
47 |
48 | #### Type declaration
49 |
50 | | Name | Type |
51 | | :------ | :------ |
52 | | `claimable` | `boolean` |
53 | | `contractInit` | [ZiloContractInit](zilo.md#zilocontractinit) \| ``null`` |
54 | | `contractState` | [ZiloContractState](zilo.md#zilocontractstate) |
55 | | `contributed` | `boolean` |
56 | | `currentNonce` | `number` \| ``null`` |
57 | | `currentUser` | `string` \| ``null`` |
58 | | `state` | [ILOState](../enums/constants.ilostate.md) |
59 | | `userContribution` | `BigNumber` |
60 |
61 | #### Defined in
62 |
63 | [zilo.ts:39](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L39)
64 |
65 | ___
66 |
67 | ### ZiloContractInit
68 |
69 | Ƭ **ZiloContractInit**: `Object`
70 |
71 | #### Type declaration
72 |
73 | | Name | Type |
74 | | :------ | :------ |
75 | | `_creation_block` | `string` |
76 | | `_scilla_version` | `string` |
77 | | `_this_address` | `string` |
78 | | `end_block` | `number` |
79 | | `liquidity_address` | `string` |
80 | | `liquidity_zil_amount` | `BigNumber` |
81 | | `minimum_zil_amount` | `BigNumber` |
82 | | `receiver_address` | `string` |
83 | | `start_block` | `number` |
84 | | `target_zil_amount` | `BigNumber` |
85 | | `target_zwap_amount` | `BigNumber` |
86 | | `token_address` | `string` |
87 | | `token_amount` | `BigNumber` |
88 | | `zwap_address` | `string` |
89 |
90 | #### Defined in
91 |
92 | [zilo.ts:22](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L22)
93 |
94 | ___
95 |
96 | ### ZiloContractState
97 |
98 | Ƭ **ZiloContractState**: `Object`
99 |
100 | #### Type declaration
101 |
102 | | Name | Type |
103 | | :------ | :------ |
104 | | `contributions` | `Object` |
105 | | `initialized` | `ADTValue` |
106 | | `total_contributions` | `string` |
107 |
108 | #### Defined in
109 |
110 | [zilo.ts:16](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L16)
111 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at engineering@switcheo.network. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/docs/classes/zilo.zilo-1.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / [zilo](../modules/zilo.md) / Zilo
2 |
3 | # Class: Zilo
4 |
5 | [zilo](../modules/zilo.md)
6 |
7 | Zilo class to represent an instance of a ZilSwap Initial Launch Offering.
8 |
9 | Usage:
10 | ```
11 | const zilswap = new Zilswap(Network.TestNet)
12 | await zilswap.initialize()
13 | const zilo = await zilswap.registerZilo(ZILO_ADDRESS, ziloStateObserver)
14 |
15 | const ziloState = zilo.getZiloState()
16 |
17 | if (ziloState.state === ILOState.Active) {
18 | const amount = new BigNumber(1).shiftedBy(ZIL_DECIMALS).toString(10)
19 | const tx = await zilo.contribute(amount)
20 |
21 | console.log("distribute TX sent", tx.hash)
22 | } else {
23 | console.log("ZILO not yet active")
24 | }
25 | ```
26 |
27 | ## Table of contents
28 |
29 | ### Constructors
30 |
31 | - [constructor](zilo.zilo-1.md#constructor)
32 |
33 | ### Methods
34 |
35 | - [claim](zilo.zilo-1.md#claim)
36 | - [complete](zilo.zilo-1.md#complete)
37 | - [contribute](zilo.zilo-1.md#contribute)
38 | - [getZiloState](zilo.zilo-1.md#getzilostate)
39 | - [initialize](zilo.zilo-1.md#initialize)
40 | - [updateBlockHeight](zilo.zilo-1.md#updateblockheight)
41 | - [updateObserver](zilo.zilo-1.md#updateobserver)
42 | - [updateZiloState](zilo.zilo-1.md#updatezilostate)
43 |
44 | ## Constructors
45 |
46 | ### constructor
47 |
48 | • **new Zilo**(`zilswap`, `address`)
49 |
50 | #### Parameters
51 |
52 | | Name | Type |
53 | | :------ | :------ |
54 | | `zilswap` | [Zilswap](index.zilswap.md) |
55 | | `address` | `string` |
56 |
57 | #### Defined in
58 |
59 | [zilo.ts:76](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L76)
60 |
61 | ## Methods
62 |
63 | ### claim
64 |
65 | ▸ **claim**(): `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
66 |
67 | Execute claim function if user contributed
68 |
69 | #### Returns
70 |
71 | `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
72 |
73 | #### Defined in
74 |
75 | [zilo.ts:223](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L223)
76 |
77 | ___
78 |
79 | ### complete
80 |
81 | ▸ **complete**(): `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
82 |
83 | #### Returns
84 |
85 | `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
86 |
87 | #### Defined in
88 |
89 | [zilo.ts:254](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L254)
90 |
91 | ___
92 |
93 | ### contribute
94 |
95 | ▸ **contribute**(`amountToContributeStr`): `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
96 |
97 | Contribute to the ILO, may need to increase token allowance before proceeding
98 |
99 | #### Parameters
100 |
101 | | Name | Type | Description |
102 | | :------ | :------ | :------ |
103 | | `amountToContributeStr` | `string` | is the exact amount of ZIL to be contribute as a unitless string (without decimals). |
104 |
105 | #### Returns
106 |
107 | `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
108 |
109 | #### Defined in
110 |
111 | [zilo.ts:285](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L285)
112 |
113 | ___
114 |
115 | ### getZiloState
116 |
117 | ▸ **getZiloState**(): [ZiloAppState](../modules/zilo.md#ziloappstate)
118 |
119 | #### Returns
120 |
121 | [ZiloAppState](../modules/zilo.md#ziloappstate)
122 |
123 | #### Defined in
124 |
125 | [zilo.ts:178](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L178)
126 |
127 | ___
128 |
129 | ### initialize
130 |
131 | ▸ **initialize**(`observer?`): `Promise`
132 |
133 | #### Parameters
134 |
135 | | Name | Type |
136 | | :------ | :------ |
137 | | `observer?` | [OnStateUpdate](../modules/zilo.md#onstateupdate) |
138 |
139 | #### Returns
140 |
141 | `Promise`
142 |
143 | #### Defined in
144 |
145 | [zilo.ts:83](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L83)
146 |
147 | ___
148 |
149 | ### updateBlockHeight
150 |
151 | ▸ **updateBlockHeight**(`height?`): `Promise`
152 |
153 | #### Parameters
154 |
155 | | Name | Type |
156 | | :------ | :------ |
157 | | `height?` | `number` |
158 |
159 | #### Returns
160 |
161 | `Promise`
162 |
163 | #### Defined in
164 |
165 | [zilo.ts:160](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L160)
166 |
167 | ___
168 |
169 | ### updateObserver
170 |
171 | ▸ **updateObserver**(`observer?`): `void`
172 |
173 | #### Parameters
174 |
175 | | Name | Type |
176 | | :------ | :------ |
177 | | `observer?` | [OnStateUpdate](../modules/zilo.md#onstateupdate) |
178 |
179 | #### Returns
180 |
181 | `void`
182 |
183 | #### Defined in
184 |
185 | [zilo.ts:88](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L88)
186 |
187 | ___
188 |
189 | ### updateZiloState
190 |
191 | ▸ **updateZiloState**(): `Promise`
192 |
193 | #### Returns
194 |
195 | `Promise`
196 |
197 | #### Defined in
198 |
199 | [zilo.ts:126](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/zilo.ts#L126)
200 |
--------------------------------------------------------------------------------
/docs/modules/index.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / index
2 |
3 | # Module: index
4 |
5 | ## Table of contents
6 |
7 | ### References
8 |
9 | - [Zilo](index.md#zilo)
10 |
11 | ### Classes
12 |
13 | - [Zilswap](../classes/index.zilswap.md)
14 |
15 | ### Type aliases
16 |
17 | - [AppState](index.md#appstate)
18 | - [ContractState](index.md#contractstate)
19 | - [ObservedTx](index.md#observedtx)
20 | - [OnUpdate](index.md#onupdate)
21 | - [Options](index.md#options)
22 | - [Pool](index.md#pool)
23 | - [Rates](index.md#rates)
24 | - [TokenDetails](index.md#tokendetails)
25 | - [TxParams](index.md#txparams)
26 | - [TxReceipt](index.md#txreceipt)
27 | - [TxStatus](index.md#txstatus)
28 | - [WalletProvider](index.md#walletprovider)
29 |
30 | ## References
31 |
32 | ### Zilo
33 |
34 | Renames and exports: [zilo](zilo.md)
35 |
36 | ## Type aliases
37 |
38 | ### AppState
39 |
40 | Ƭ **AppState**: `Object`
41 |
42 | #### Type declaration
43 |
44 | | Name | Type |
45 | | :------ | :------ |
46 | | `contractState` | [ContractState](index.md#contractstate) |
47 | | `currentBalance` | `BigNumber` \| ``null`` |
48 | | `currentNonce` | `number` \| ``null`` |
49 | | `currentUser` | `string` \| ``null`` |
50 | | `pools` | { [key in string]?: Pool} |
51 | | `tokens` | { [key in string]: TokenDetails} |
52 |
53 | #### Defined in
54 |
55 | [index.ts:64](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L64)
56 |
57 | ___
58 |
59 | ### ContractState
60 |
61 | Ƭ **ContractState**: `Object`
62 |
63 | #### Type declaration
64 |
65 | | Name | Type |
66 | | :------ | :------ |
67 | | `balances` | { [key in string]?: { [key2 in string]?: string}} |
68 | | `output_after_fee` | `string` |
69 | | `pools` | { [key in string]?: object} |
70 | | `total_contributions` | { [key in string]?: string} |
71 |
72 | #### Defined in
73 |
74 | [index.ts:57](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L57)
75 |
76 | ___
77 |
78 | ### ObservedTx
79 |
80 | Ƭ **ObservedTx**: `Object`
81 |
82 | #### Type declaration
83 |
84 | | Name | Type |
85 | | :------ | :------ |
86 | | `deadline` | `number` |
87 | | `hash` | `string` |
88 |
89 | #### Defined in
90 |
91 | [index.ts:28](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L28)
92 |
93 | ___
94 |
95 | ### OnUpdate
96 |
97 | Ƭ **OnUpdate**: (`tx`: [ObservedTx](index.md#observedtx), `status`: [TxStatus](index.md#txstatus), `receipt?`: [TxReceipt](index.md#txreceipt)) => `void`
98 |
99 | #### Type declaration
100 |
101 | ▸ (`tx`, `status`, `receipt?`): `void`
102 |
103 | ##### Parameters
104 |
105 | | Name | Type |
106 | | :------ | :------ |
107 | | `tx` | [ObservedTx](index.md#observedtx) |
108 | | `status` | [TxStatus](index.md#txstatus) |
109 | | `receipt?` | [TxReceipt](index.md#txreceipt) |
110 |
111 | ##### Returns
112 |
113 | `void`
114 |
115 | #### Defined in
116 |
117 | [index.ts:26](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L26)
118 |
119 | ___
120 |
121 | ### Options
122 |
123 | Ƭ **Options**: `Object`
124 |
125 | #### Type declaration
126 |
127 | | Name | Type |
128 | | :------ | :------ |
129 | | `deadlineBuffer?` | `number` |
130 | | `gasLimit?` | `number` |
131 | | `gasPrice?` | `number` |
132 | | `rpcEndpoint?` | `string` |
133 |
134 | #### Defined in
135 |
136 | [index.ts:19](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L19)
137 |
138 | ___
139 |
140 | ### Pool
141 |
142 | Ƭ **Pool**: `Object`
143 |
144 | #### Type declaration
145 |
146 | | Name | Type |
147 | | :------ | :------ |
148 | | `contributionPercentage` | `BigNumber` |
149 | | `exchangeRate` | `BigNumber` |
150 | | `tokenReserve` | `BigNumber` |
151 | | `totalContribution` | `BigNumber` |
152 | | `userContribution` | `BigNumber` |
153 | | `zilReserve` | `BigNumber` |
154 |
155 | #### Defined in
156 |
157 | [index.ts:73](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L73)
158 |
159 | ___
160 |
161 | ### Rates
162 |
163 | Ƭ **Rates**: `Object`
164 |
165 | #### Type declaration
166 |
167 | | Name | Type |
168 | | :------ | :------ |
169 | | `expectedAmount` | `BigNumber` |
170 | | `slippage` | `BigNumber` |
171 |
172 | #### Defined in
173 |
174 | [index.ts:82](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L82)
175 |
176 | ___
177 |
178 | ### TokenDetails
179 |
180 | Ƭ **TokenDetails**: `Object`
181 |
182 | #### Type declaration
183 |
184 | | Name | Type |
185 | | :------ | :------ |
186 | | `address` | `string` |
187 | | `contract` | `Contract` |
188 | | `decimals` | `number` |
189 | | `hash` | `string` |
190 | | `registered` | `boolean` |
191 | | `symbol` | `string` |
192 | | `whitelisted` | `boolean` |
193 |
194 | #### Defined in
195 |
196 | [index.ts:47](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L47)
197 |
198 | ___
199 |
200 | ### TxParams
201 |
202 | Ƭ **TxParams**: `Object`
203 |
204 | #### Type declaration
205 |
206 | | Name | Type |
207 | | :------ | :------ |
208 | | `gasLimit` | `Long` |
209 | | `gasPrice` | `BN` |
210 | | `version` | `number` |
211 |
212 | #### Defined in
213 |
214 | [index.ts:41](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L41)
215 |
216 | ___
217 |
218 | ### TxReceipt
219 |
220 | Ƭ **TxReceipt**: `\_TxReceipt`
221 |
222 | #### Defined in
223 |
224 | [index.ts:39](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L39)
225 |
226 | ___
227 |
228 | ### TxStatus
229 |
230 | Ƭ **TxStatus**: ``"confirmed"`` \| ``"rejected"`` \| ``"expired"``
231 |
232 | #### Defined in
233 |
234 | [index.ts:37](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L37)
235 |
236 | ___
237 |
238 | ### WalletProvider
239 |
240 | Ƭ **WalletProvider**: `Omit`<`Zilliqa` & { `wallet`: `Wallet` & { `defaultAccount`: { `base16`: `string` ; `bech32`: `string` } ; `net`: `string` } }, ``"subscriptionBuilder"``\>
241 |
242 | #### Defined in
243 |
244 | [index.ts:87](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L87)
245 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [
3 | "src/**/*"
4 | ],
5 | "compilerOptions": {
6 | /* Basic Options */
7 | // "incremental": true, /* Enable incremental compilation */
8 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
9 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
10 | // "lib": [], /* Specify library files to be included in the compilation. */
11 | // "allowJs": true, /* Allow javascript files to be compiled. */
12 | // "checkJs": true, /* Report errors in .js files. */
13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
14 | "declaration": true, /* Generates corresponding '.d.ts' file. */
15 | "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
16 | "sourceMap": true, /* Generates corresponding '.map' file. */
17 | // "outFile": "./", /* Concatenate and emit output to single file. */
18 | "outDir": "./lib", /* Redirect output structure to the directory. */
19 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
20 | // "composite": true, /* Enable project compilation */
21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
22 | // "removeComments": true, /* Do not emit comments to output. */
23 | // "noEmit": true, /* Do not emit outputs. */
24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
27 |
28 | /* Strict Type-Checking Options */
29 | "strict": true, /* Enable all strict type-checking options. */
30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
31 | // "strictNullChecks": true, /* Enable strict null checks. */
32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
37 |
38 | /* Additional Checks */
39 | // "noUnusedLocals": true, /* Report errors on unused locals. */
40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
43 |
44 | /* Module Resolution Options */
45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
49 | // "typeRoots": [], /* List of folders to include type definitions from. */
50 | // "types": [], /* Type declaration files to be included in compilation. */
51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
52 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
55 |
56 | /* Source Map Options */
57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
61 |
62 | /* Experimental Options */
63 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
64 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
65 |
66 | /* Advanced Options */
67 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { Value } from '@zilliqa-js/contract'
2 | import { fromBech32Address } from '@zilliqa-js/crypto'
3 | import { BN, units } from '@zilliqa-js/util'
4 | import { BigNumber } from 'bignumber.js'
5 | import { Network, ARK_CONTRACTS, ZIL_HASH } from './constants'
6 | import crypto from 'crypto'
7 |
8 | BigNumber.config({ EXPONENTIAL_AT: 1e9 }) // never!
9 |
10 | // The following code is based on: @zilliqa-js/util/src/unit.ts.
11 | // toPositiveQa is modified from toQa to accept arbitrary number units,
12 | // while not accepting negative inputs.
13 |
14 | const unitMap = new Map([
15 | [units.Units.Qa, '1'],
16 | [units.Units.Li, '1000000'], // 1e6 qa
17 | [units.Units.Zil, '1000000000000'], // 1e12 qa
18 | ])
19 |
20 | const numToStr = (input: string | number | BN) => {
21 | if (typeof input === 'string') {
22 | if (!input.match(/^-?[0-9.]+$/)) {
23 | throw new Error(`while converting number to string, invalid number value '${input}', should be a number matching (^[0-9.]+).`)
24 | }
25 | return input
26 | } else if (typeof input === 'number') {
27 | return String(input)
28 | } else if (BN.isBN(input)) {
29 | return input.toString(10)
30 | }
31 |
32 | throw new Error(`while converting number to string, invalid number value '${input}' type ${typeof input}.`)
33 | }
34 |
35 | export const unitlessBigNumber = (str: string): BigNumber => {
36 | const bn = new BigNumber(str)
37 | if (!bn.integerValue().isEqualTo(bn)) {
38 | throw new Error(`number ${bn} should be unitless (no decimals).`)
39 | }
40 | return bn
41 | }
42 |
43 | export const toPositiveQa = (input: string | number | BN, unitOrDecimals: units.Units | number) => {
44 | const inputStr = numToStr(input)
45 |
46 | let base: BN
47 | let baseNumDecimals: number
48 |
49 | if (typeof unitOrDecimals === 'number') {
50 | // decimals
51 | if (unitOrDecimals < 0 || unitOrDecimals % 1 !== 0) {
52 | throw new Error(`Invalid decimals ${unitOrDecimals}, must be non-negative integer.`)
53 | }
54 |
55 | baseNumDecimals = unitOrDecimals
56 | base = new BN(10).pow(new BN(baseNumDecimals))
57 | } else {
58 | // unit
59 | const baseStr = unitMap.get(unitOrDecimals)
60 |
61 | if (!baseStr) {
62 | throw new Error(`No unit of type ${unitOrDecimals} exists.`)
63 | }
64 |
65 | baseNumDecimals = baseStr.length - 1
66 | base = new BN(baseStr, 10)
67 | }
68 |
69 | if (inputStr === '.') {
70 | throw new Error(`Cannot convert ${inputStr} to Qa.`)
71 | }
72 |
73 | // Split it into a whole and fractional part
74 | const comps = inputStr.split('.')
75 | if (comps.length > 2) {
76 | throw new Error(`Cannot convert ${inputStr} to Qa.`)
77 | }
78 |
79 | let [whole, fraction] = comps
80 |
81 | if (!whole) {
82 | whole = '0'
83 | }
84 | if (!fraction) {
85 | fraction = '0'
86 | }
87 | if (fraction.length > baseNumDecimals) {
88 | throw new Error(`Cannot convert ${inputStr} to Qa.`)
89 | }
90 |
91 | while (fraction.length < baseNumDecimals) {
92 | fraction += '0'
93 | }
94 |
95 | const wholeBN = new BN(whole)
96 | const fractionBN = new BN(fraction)
97 | const qa = wholeBN.mul(base).add(fractionBN)
98 |
99 | return new BN(qa.toString(10), 10)
100 | }
101 |
102 | let _lsAvailable: boolean | null = null
103 | export const isLocalStorageAvailable = () => {
104 | if (_lsAvailable !== null) {
105 | // only check for ls once
106 | return _lsAvailable
107 | }
108 |
109 | _lsAvailable = false
110 | if (typeof localStorage !== 'undefined') {
111 | try {
112 | localStorage.setItem('ls_feature_test', 'yes')
113 | if (localStorage.getItem('ls_feature_test') === 'yes') {
114 | localStorage.removeItem('ls_feature_test')
115 | _lsAvailable = true
116 | }
117 | } catch (e) {
118 | // fall-through as `false`
119 | }
120 | }
121 | return _lsAvailable
122 | }
123 |
124 | /**
125 | * Converts `Value[]` array to map of string values.
126 | * `Value.type` is ignored, all values are returned as string.
127 | *
128 | *
129 | * sample input:
130 | * ```javascript
131 | * [{
132 | * name: 'address',
133 | * type: 'ByStr20',
134 | * value: '0xbadbeef',
135 | * }, {
136 | * name: 'balance',
137 | * type: 'UInt28',
138 | * value: '100000000',
139 | * }]
140 | * ```
141 | *
142 | * output:
143 | * ```javascript
144 | * {
145 | * address: '0xbadbeef',
146 | * balance: '100000000',
147 | * }
148 | * ```
149 | *
150 | * @param params parameters in `Value[]` array representation
151 | * @returns mapped object representation - refer to sample output
152 | */
153 | export const contractInitToMap = (params: Value[]): { [index: string]: any } => {
154 | const output: { [index: string]: any } = {}
155 | for (const set of params) {
156 | output[set.vname] = set.value
157 | }
158 | return output
159 | }
160 |
161 | /* ARK utils */
162 |
163 | /**
164 | * Returns the message hash to sign.
165 | * @param msg - the utf-8 message
166 | * @returns - the computed message hahs to sign
167 | */
168 | export const hashMessage = (msg: string): string => {
169 | return crypto.createHash('sha256').update(Buffer.from(msg, 'utf-8')).digest('hex')
170 | }
171 |
172 | /**
173 | * Returns the message to sign for ARK.
174 | * @param type - the type of message, either 'Execute' or 'Void'
175 | * @param chequeHash - the computed cheque hash for the trade intent
176 | * @returns
177 | */
178 | export const arkMessage = (type: 'Execute' | 'Void', chequeHash: string) => {
179 | return `Zilliqa Signed Message:\n${type} ARK Cheque 0x${chequeHash}`
180 | }
181 |
182 | export type ArkChequeParams = {
183 | network: Network
184 | side: 'Buy' | 'Sell'
185 | token: { id: string; address: string }
186 | price: { amount: BigNumber; address: string }
187 | feeAmount: BigNumber
188 | expiry: number
189 | nonce: number
190 | }
191 |
192 | /**
193 | * Computes the cheque hash for a trade intent on ARK.
194 | * @param params - trade parameters
195 | * @returns
196 | */
197 | export const arkChequeHash = (params: ArkChequeParams): string => {
198 | const { network, side, token, price, feeAmount, expiry, nonce } = params
199 | const brokerAddress = fromBech32Address(ARK_CONTRACTS[network]).toLowerCase()
200 | let buffer = brokerAddress.replace('0x', '')
201 | buffer += sha256(strToHex(`${brokerAddress}.${side}`))
202 | buffer += sha256(serializeNFT(brokerAddress, token))
203 | buffer += sha256(serializePrice(brokerAddress, price))
204 | buffer += sha256(serializeUint128(side === 'Buy' ? 0 : feeAmount))
205 | buffer += sha256(strToHex(expiry.toString())) // BNum is serialized as a String
206 | buffer += sha256(serializeUint128(nonce))
207 | return sha256(buffer)
208 | }
209 |
210 | const serializeNFT = (brokerAddress: string, token: { id: string; address: string }): string => {
211 | let buffer = strToHex(`${brokerAddress}.NFT`)
212 | buffer += token.address.replace('0x', '').toLowerCase()
213 | buffer += serializeUint256(token.id)
214 | return buffer
215 | }
216 |
217 | const serializePrice = (brokerAddress: string, price: { amount: BigNumber; address: string }): string => {
218 | let buffer = strToHex(`${brokerAddress}.Coins`)
219 | if (price.address === ZIL_HASH) {
220 | buffer += strToHex(`${brokerAddress}.Zil`)
221 | } else {
222 | buffer += strToHex(`${brokerAddress}.Token`)
223 | buffer += price.address.replace('0x', '').toLowerCase()
224 | }
225 | buffer += serializeUint128(price.amount)
226 | return buffer
227 | }
228 |
229 | const serializeUint128 = (val: BigNumber | number): string => {
230 | return new BN(val.toString()).toBuffer('be', 16).toString('hex')
231 | }
232 |
233 | const serializeUint256 = (val: BigNumber | string): string => {
234 | return new BN(val.toString()).toBuffer('be', 32).toString('hex')
235 | }
236 |
237 | const strToHex = (str: string): string => {
238 | return Array.from(new TextEncoder().encode(str), byte => byte.toString(16).padStart(2, '0')).join('')
239 | }
240 |
241 | const sha256 = (byteHexString: string): string => {
242 | return crypto.createHash('sha256').update(Buffer.from(byteHexString, 'hex')).digest('hex')
243 | }
244 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | import BigNumber from 'bignumber.js'
2 | import { sign, getPubKeyFromPrivateKey, getAddressFromPrivateKey } from '@zilliqa-js/crypto'
3 | import { Zilswap, ObservedTx, TxStatus, TxReceipt } from './index'
4 | import { Network, ZIL_HASH } from './constants'
5 | import { arkMessage, arkChequeHash, hashMessage } from './utils'
6 |
7 | const key: string | undefined = process.env.PRIVATE_KEY || undefined
8 | const zilswap = new Zilswap(Network.TestNet, key)
9 |
10 | const test = async () => {
11 | // init
12 | await zilswap.initialize(printResults)
13 |
14 | // get app state
15 | console.log('\ninitial app state:\n')
16 | console.log(JSON.stringify(zilswap.getAppState(), null, 2))
17 |
18 | try {
19 | // approve token
20 | const tx0 = await zilswap.approveTokenTransferIfRequired('SWTH', await zilswap.toUnitless('SWTH', '100000'))
21 | if (tx0) {
22 | console.log(`\ntx hash: ${tx0.hash}\n`)
23 | await waitForTx()
24 | }
25 |
26 | // add liquidity
27 | const tx1 = await zilswap.addLiquidity('SWTH', await zilswap.toUnitless('ZIL', '10000'), await zilswap.toUnitless('SWTH', '10000'))
28 | console.log(`\ntx hash: ${tx1.hash}\n`)
29 | // await waitForTx()
30 |
31 | // remove liquidity
32 | const pool = zilswap.getPool('SWTH')
33 | const remove25Percent = pool!.userContribution.dividedToIntegerBy(4).toString()
34 | const tx2 = await zilswap.removeLiquidity('SWTH', remove25Percent)
35 | console.log(`\ntx hash: ${tx2.hash}\n`)
36 | // await waitForTx()
37 |
38 | // constants
39 | const someSWTH = await zilswap.toUnitless('SWTH', '0.1')
40 | const someZIL = await zilswap.toUnitless('ZIL', '0.1')
41 |
42 | // get expected rates for exact input
43 | const r1 = await zilswap.getRatesForInput('SWTH', 'ZIL', someSWTH)
44 | console.log('\n0.1 SWTH -> ZIL\n')
45 | console.log(JSON.stringify(r1, null, 2))
46 |
47 | // swap exact zrc2 to zil
48 | const tx3 = await zilswap.swapWithExactInput('SWTH', 'ZIL', someSWTH)
49 | console.log(`\ntx hash: ${tx3.hash}\n`)
50 | // await waitForTx()
51 |
52 | // get expected rates for exact input
53 | const r2 = await zilswap.getRatesForInput('ZIL', 'SWTH', someZIL)
54 | console.log('\n0.1 ZIL -> SWTH\n')
55 | console.log(JSON.stringify(r2, null, 2))
56 |
57 | // swap exact zil to zrc2
58 | const tx4 = await zilswap.swapWithExactInput('ZIL', 'SWTH', someZIL)
59 | console.log(`\ntx hash: ${tx4.hash}\n`)
60 | // await waitForTx()
61 |
62 | // get expected rates for exact output
63 | const r3 = await zilswap.getRatesForOutput('SWTH', 'ZIL', someZIL)
64 | console.log('\nSWTH -> 0.1 ZIL\n')
65 | console.log(JSON.stringify(r3, null, 2))
66 |
67 | // swap zrc2 to exact zil
68 | const tx5 = await zilswap.swapWithExactOutput('SWTH', 'ZIL', someZIL)
69 | console.log(`\ntx hash: ${tx5.hash}\n`)
70 | await waitForTx()
71 |
72 | // get expected rates for exact output
73 | const r4 = await zilswap.getRatesForOutput('ZIL', 'SWTH', someSWTH)
74 | console.log('\nZIL -> 0.1 SWTH\n')
75 | console.log(JSON.stringify(r4, null, 2))
76 |
77 | // swap zil to exact zrc2
78 | const tx6 = await zilswap.swapWithExactOutput('ZIL', 'SWTH', someSWTH)
79 | console.log(`\ntx hash: ${tx6.hash}\n`)
80 | await waitForTx()
81 | } finally {
82 | await zilswap.teardown()
83 | }
84 | }
85 |
86 | const test2 = async () => {
87 | // init
88 | await zilswap.initialize(printResults)
89 |
90 | // get app state
91 | console.log('\ninitial app state:\n')
92 | console.log(JSON.stringify(zilswap.getAppState(), null, 2))
93 |
94 | try {
95 | // approve token
96 | const tx0 = await zilswap.approveTokenTransferIfRequired('XSGD', await zilswap.toUnitless('XSGD', '100000'))
97 | if (tx0) {
98 | console.log(`\ntx hash: ${tx0.hash}\n`)
99 | await waitForTx()
100 | }
101 |
102 | // add liquidity
103 | const tx1 = await zilswap.addLiquidity('XSGD', await zilswap.toUnitless('ZIL', '100000'), await zilswap.toUnitless('XSGD', '10000'))
104 | console.log(`\ntx hash: ${tx1.hash}\n`)
105 | await waitForTx()
106 |
107 | // remove liquidity
108 | const pool = zilswap.getPool('XSGD')
109 | const remove25Percent = pool!.userContribution.dividedToIntegerBy(4).toString()
110 | const tx2 = await zilswap.removeLiquidity('XSGD', remove25Percent)
111 | console.log(`\ntx hash: ${tx2.hash}\n`)
112 | await waitForTx()
113 |
114 | // constants
115 | const someSWTH = await zilswap.toUnitless('SWTH', '0.1')
116 | const someXSGD = await zilswap.toUnitless('XSGD', '0.1')
117 |
118 | // get expected rates for exact input
119 | const r1 = await zilswap.getRatesForInput('SWTH', 'XSGD', someSWTH)
120 | console.log('\n0.1 SWTH -> XSGD\n')
121 | console.log(JSON.stringify(r1, null, 2))
122 |
123 | // swap exact zrc2 to zrc2
124 | const tx3 = await zilswap.swapWithExactInput('SWTH', 'XSGD', someSWTH)
125 | console.log(`\ntx hash: ${tx3.hash}\n`)
126 | await waitForTx()
127 |
128 | // get expected rates for exact input
129 | const r2 = await zilswap.getRatesForInput('XSGD', 'SWTH', someXSGD)
130 | console.log('\n0.1 XSGD -> SWTH\n')
131 | console.log(JSON.stringify(r2, null, 2))
132 |
133 | // swap exact zrc2 to zrc2
134 | const tx4 = await zilswap.swapWithExactInput('XSGD', 'SWTH', someXSGD)
135 | console.log(`\ntx hash: ${tx4.hash}\n`)
136 | await waitForTx()
137 |
138 | // get expected rates for exact output
139 | const r3 = await zilswap.getRatesForOutput('SWTH', 'XSGD', someXSGD)
140 | console.log('\nSWTH -> 0.1 XSGD\n')
141 | console.log(JSON.stringify(r3, null, 2))
142 |
143 | // swap zrc2 to exact zrc2
144 | const tx5 = await zilswap.swapWithExactOutput('SWTH', 'XSGD', someXSGD)
145 | console.log(`\ntx hash: ${tx5.hash}\n`)
146 | await waitForTx()
147 |
148 | // get expected rates for exact output
149 | const r4 = await zilswap.getRatesForOutput('XSGD', 'SWTH', someSWTH)
150 | console.log('\nXSGD -> 0.1 SWTH\n')
151 | console.log(JSON.stringify(r4, null, 2))
152 |
153 | // swap zrc2 to exact zrc2
154 | const tx6 = await zilswap.swapWithExactOutput('XSGD', 'SWTH', someSWTH)
155 | console.log(`\ntx hash: ${tx6.hash}\n`)
156 | await waitForTx()
157 | } finally {
158 | await zilswap.teardown()
159 | }
160 | }
161 |
162 | const test3 = () => {
163 | const msg = arkMessage(
164 | 'Execute',
165 | arkChequeHash({
166 | network: Network.TestNet,
167 | side: 'Buy',
168 | token: { id: '206', address: '0xc948942f55ef05a95a46bb58ee9b0a67b0f871fa' },
169 | price: { amount: new BigNumber(10000), address: ZIL_HASH },
170 | feeAmount: new BigNumber(250),
171 | expiry: 100,
172 | nonce: 0,
173 | })
174 | )
175 | console.log('Message:', msg)
176 | const address = getAddressFromPrivateKey(key!)
177 | console.log('Address:', address)
178 | const publicKey = getPubKeyFromPrivateKey(key!)
179 | console.log('Public Key:', publicKey)
180 | const hash = hashMessage(msg)
181 | console.log('Message Hash:', hash)
182 | const signature = sign(Buffer.from(hash, 'hex'), key!, publicKey)
183 | console.log('Signature:', signature)
184 | }
185 |
186 | const printResults = (tx: ObservedTx, status: TxStatus, receipt?: TxReceipt) => {
187 | if (!receipt) {
188 | console.error(`\ntx ${tx.hash} failed with ${status}!\n`)
189 | } else if (status !== 'confirmed') {
190 | console.error(`\ntx ${tx.hash} failed with ${status}!\ntx receipt: \n`)
191 | console.error(JSON.stringify(receipt, null, 2))
192 | } else {
193 | console.log(`\ntx ${tx.hash} confirmed.\napp state:\n`)
194 | console.log(JSON.stringify(zilswap.getAppState(), null, 2))
195 | }
196 | }
197 |
198 | const waitForTx = async () => {
199 | return new Promise(resolve => {
200 | const check = async () => {
201 | if ((await zilswap.getObservedTxs()).length === 0) {
202 | resolve()
203 | } else {
204 | setTimeout(check, 100)
205 | }
206 | }
207 | check()
208 | })
209 | }
210 |
211 | ;(async () => {
212 | console.log('test starting..')
213 | try {
214 | // await test()
215 | // await test2()
216 | test3()
217 | console.log('test done!')
218 | } catch (err) {
219 | console.error(err)
220 | console.log('test failed!')
221 | }
222 | })()
223 |
--------------------------------------------------------------------------------
/src/zilo.ts:
--------------------------------------------------------------------------------
1 | import { Contract, Value } from '@zilliqa-js/contract'
2 | import { BN, Long } from '@zilliqa-js/util'
3 | import { BigNumber } from 'bignumber.js'
4 | import { ObservedTx, TxParams, Zilswap } from './index'
5 | import { ILOState } from './constants'
6 | import { contractInitToMap, unitlessBigNumber } from './utils'
7 |
8 | interface ADTValue {
9 | constructor: string
10 | argtypes: string[]
11 | arguments: Value[]
12 | }
13 |
14 | export type OnStateUpdate = (appState: ZiloAppState) => void
15 |
16 | export type ZiloContractState = {
17 | initialized: ADTValue
18 | contributions: { [byStr20Address: string]: BigNumber }
19 | total_contributions: string
20 | balances?: { [byStr20Address: string]: BigNumber }
21 | discount_whitelist?: {
22 | [byStr20Address: string]: string;
23 | }
24 | }
25 |
26 | export type ZiloContractInit = {
27 | zwap_address: string
28 | token_address: string
29 | token_amount: BigNumber
30 | target_zil_amount: BigNumber
31 | target_zwap_amount: BigNumber
32 | minimum_zil_amount: BigNumber
33 | liquidity_zil_amount: BigNumber
34 | receiver_address: string
35 | liquidity_address: string
36 | start_block: number
37 | end_block: number
38 | _scilla_version: string
39 | _creation_block: string
40 | _this_address: string
41 | discount_bps?: number
42 | }
43 |
44 | export type ZiloAppState = {
45 | contractState: ZiloContractState
46 | state: ILOState
47 | claimable: boolean
48 | contributed: boolean
49 | currentNonce: number | null
50 | currentUser: string | null
51 | userContribution: BigNumber
52 | contractInit: ZiloContractInit | null
53 | }
54 |
55 | /**
56 | * Zilo class to represent an instance of a ZilSwap Initial Launch Offering.
57 | *
58 | * Usage:
59 | * ```
60 | * const zilswap = new Zilswap(Network.TestNet)
61 | * await zilswap.initialize()
62 | * const zilo = await zilswap.registerZilo(ZILO_ADDRESS, ziloStateObserver)
63 | *
64 | * const ziloState = zilo.getZiloState()
65 | *
66 | * if (ziloState.state === ILOState.Active) {
67 | * const amount = new BigNumber(1).shiftedBy(ZIL_DECIMALS).toString(10)
68 | * const tx = await zilo.contribute(amount)
69 | *
70 | * console.log("distribute TX sent", tx.hash)
71 | * } else {
72 | * console.log("ZILO not yet active")
73 | * }
74 | * ```
75 | */
76 | export class Zilo {
77 | private zilswap: Zilswap
78 | private contract: Contract
79 | private appState?: ZiloAppState
80 |
81 | private stateObserver?: OnStateUpdate
82 |
83 | constructor(zilswap: Zilswap, address: string) {
84 | this.zilswap = zilswap
85 | this.contract = zilswap.getContract(address)
86 | }
87 |
88 | public async initialize(observer?: OnStateUpdate) {
89 | this.updateObserver(observer)
90 | await this.updateZiloState()
91 | }
92 |
93 | public updateObserver(observer?: OnStateUpdate) {
94 | this.stateObserver = observer
95 | }
96 |
97 | private async fetchContractInit(): Promise {
98 | const result = await this.zilswap.fetchContractInit(this.contract)
99 | if (!result) return
100 |
101 | const rawInit = contractInitToMap(result)
102 |
103 | return {
104 | ...rawInit,
105 |
106 | token_amount: new BigNumber(rawInit.token_amount),
107 | target_zil_amount: new BigNumber(rawInit.target_zil_amount),
108 | target_zwap_amount: new BigNumber(rawInit.target_zwap_amount),
109 | minimum_zil_amount: new BigNumber(rawInit.minimum_zil_amount),
110 | liquidity_zil_amount: new BigNumber(rawInit.liquidity_zil_amount),
111 |
112 | start_block: parseInt(rawInit.start_block, 10),
113 | end_block: parseInt(rawInit.end_block, 10),
114 | } as ZiloContractInit
115 | }
116 |
117 | private async fetchContractState(): Promise {
118 | const result = await this.contract.getState()
119 |
120 | const contributions: { [index: string]: BigNumber } = {}
121 | for (const byStr20Address of Object.keys(result.contributions)) {
122 | contributions[byStr20Address] = new BigNumber(result.contributions[byStr20Address])
123 | }
124 |
125 | const balances: { [index: string]: BigNumber } = {}
126 | for (const byStr20Address of Object.keys(result.balances ?? {})) {
127 | balances[byStr20Address] = new BigNumber(result.balances[byStr20Address])
128 | }
129 |
130 | return {
131 | ...result,
132 | contributions,
133 | ...!!result.balances && {
134 | balances,
135 | },
136 | } as ZiloContractState
137 | }
138 |
139 | public async updateZiloState() {
140 | const contractState = await this.fetchContractState()
141 | const stateOfContract = await this.checkStatus(contractState)
142 |
143 | const currentUser = this.zilswap.getAppState().currentUser
144 |
145 | const userContribution = contractState.contributions[currentUser || ''] ?? new BigNumber(0)
146 | const claimable = stateOfContract === ILOState.Completed && new BigNumber(userContribution).isPositive()
147 | const contributed = userContribution.gt(0)
148 | let contractInit = this.appState?.contractInit
149 |
150 | if (!contractInit) {
151 | contractInit = await this.fetchContractInit()
152 | if (!contractInit) {
153 | console.error(`Could not fetch contract init for Zilo ${this.contract.address}`)
154 | return
155 | }
156 | }
157 |
158 | const newState = {
159 | contractState,
160 | claimable,
161 | contributed,
162 | currentNonce: this.appState?.currentNonce || 0,
163 | currentUser,
164 | state: stateOfContract,
165 | userContribution,
166 | contractInit,
167 | }
168 |
169 | this.appState = newState
170 | this.stateObserver?.(newState)
171 | }
172 |
173 | public async updateBlockHeight(height?: number) {
174 | if (!this.appState?.contractInit) {
175 | // not initialized, ignore update.
176 | return
177 | }
178 |
179 | if (typeof height === 'undefined') {
180 | const response = await this.zilswap.zilliqa.blockchain.getNumTxBlocks()
181 | height = parseInt(response.result!, 10)
182 | }
183 |
184 | const contractInit = this.appState.contractInit
185 | if (height === contractInit.start_block || height === contractInit.end_block) {
186 | // trigger update if start/end block is current height
187 | await this.updateZiloState()
188 | }
189 | }
190 |
191 | public getZiloState(): ZiloAppState {
192 | if (!this.appState) {
193 | throw new Error('Zilo app state not loaded, call #initialize first.')
194 | }
195 | return this.appState
196 | }
197 |
198 | /**
199 | * Checks the state of the current contract
200 | * ILOState.Uninitialized = Contract deployed but not initialized
201 | * ILOState.Pending = Contract initialized not stated (current block < start block)
202 | * ILOState.Active = Contract started
203 | * ILOState.Failed = Contract ended but target amount not reached
204 | * ILOState.Completed = Contract ended and target amount fufilled
205 | *
206 | * @param contractState
207 | * @returns returns the current ILOState
208 | */
209 | private async checkStatus(contractState: ZiloContractState): Promise {
210 | const contractInit = await this.fetchContractInit()
211 |
212 | if (!contractInit || contractState.initialized.constructor !== 'True') {
213 | return ILOState.Uninitialized
214 | }
215 |
216 | const currentBlock = this.zilswap.getCurrentBlock()
217 |
218 | if (currentBlock < contractInit.start_block) {
219 | return ILOState.Pending
220 | }
221 |
222 | if (currentBlock < contractInit.end_block) {
223 | return ILOState.Active
224 | }
225 |
226 | if (new BigNumber(contractInit.minimum_zil_amount).gt(new BigNumber(contractState.total_contributions))) {
227 | return ILOState.Failed
228 | } else {
229 | return ILOState.Completed
230 | }
231 | }
232 |
233 | /**
234 | * Execute claim function if user contributed
235 | */
236 | public async claim(): Promise {
237 | // Check init
238 | this.zilswap.checkAppLoadedWithUser()
239 |
240 | // check if current state is claimable
241 | if (this.appState?.state !== ILOState.Completed && this.appState?.state !== ILOState.Failed) {
242 | throw new Error('Not yet claimable/refundable')
243 | }
244 |
245 | // no contribution
246 | if (!this.appState?.contributed) {
247 | throw new Error('User did not contribute')
248 | }
249 |
250 | const claimTxn = await this.zilswap.callContract(
251 | this.contract,
252 | 'Claim',
253 | [],
254 | { amount: new BN(0), ...this.zilswap.txParams(), gasLimit: Long.fromNumber(20000) },
255 | true
256 | )
257 |
258 | if (claimTxn.isRejected()) {
259 | throw new Error('Claim transaction was rejected.')
260 | }
261 |
262 | const deadline = this.zilswap.deadlineBlock()
263 |
264 | const observeTxn = {
265 | hash: claimTxn.id!,
266 | deadline,
267 | }
268 | await this.zilswap.observeTx(observeTxn)
269 |
270 | return observeTxn
271 | }
272 |
273 | public async complete(): Promise {
274 | this.zilswap.checkAppLoadedWithUser()
275 |
276 | const completeTxn = await this.zilswap.callContract(
277 | this.contract,
278 | 'Complete',
279 | [],
280 | { amount: new BN(0), ...this.zilswap.txParams() },
281 | true
282 | )
283 |
284 | if (completeTxn.isRejected()) {
285 | throw new Error('Complete transaction was rejected.')
286 | }
287 |
288 | const deadline = this.zilswap.deadlineBlock()
289 |
290 | const observeTxn = {
291 | hash: completeTxn.id!,
292 | deadline,
293 | }
294 | await this.zilswap.observeTx(observeTxn)
295 |
296 | return observeTxn
297 | }
298 |
299 | /**
300 | * Contribute to the ILO, may need to increase token allowance before proceeding
301 | *
302 | * @param amountToContributeStr is the exact amount of ZIL to be contribute as a unitless string (without decimals).
303 | */
304 | public async contribute(amountToContributeStr: string, opts?: TxParams): Promise {
305 | this.zilswap.checkAppLoadedWithUser()
306 |
307 | // Check init
308 | const amountToContribute = unitlessBigNumber(amountToContributeStr)
309 |
310 | const contributeTxn = await this.zilswap.callContract(
311 | this.contract,
312 | 'Contribute',
313 | [],
314 | {
315 | amount: new BN(amountToContribute.toString()),
316 | ...this.zilswap.txParams(),
317 | gasLimit: Long.fromNumber(10000),
318 | ...opts
319 | },
320 | true
321 | )
322 |
323 | if (contributeTxn.isRejected()) {
324 | throw new Error('Contribute transaction was rejected.')
325 | }
326 |
327 | const deadline = this.zilswap.deadlineBlock()
328 |
329 | const observeTxn = {
330 | hash: contributeTxn.id!,
331 | deadline,
332 | }
333 | await this.zilswap.observeTx(observeTxn)
334 |
335 | return observeTxn
336 | }
337 | }
338 |
--------------------------------------------------------------------------------
/docs/classes/index.zilswap.md:
--------------------------------------------------------------------------------
1 | [zilswap-sdk](../README.md) / [Exports](../modules.md) / [index](../modules/index.md) / Zilswap
2 |
3 | # Class: Zilswap
4 |
5 | [zilswap](../modules/index.md)
6 |
7 | ## Table of contents
8 |
9 | ### Constructors
10 |
11 | - [constructor](index.zilswap.md#constructor)
12 |
13 | ### Properties
14 |
15 | - [\_txParams](index.zilswap.md#_txparams)
16 | - [contract](index.zilswap.md#contract)
17 | - [contractAddress](index.zilswap.md#contractaddress)
18 | - [contractHash](index.zilswap.md#contracthash)
19 | - [network](index.zilswap.md#network)
20 | - [zilliqa](index.zilswap.md#zilliqa)
21 | - [zilos](index.zilswap.md#zilos)
22 |
23 | ### Methods
24 |
25 | - [addLiquidity](index.zilswap.md#addliquidity)
26 | - [addToken](index.zilswap.md#addtoken)
27 | - [approveTokenTransferIfRequired](index.zilswap.md#approvetokentransferifrequired)
28 | - [callContract](index.zilswap.md#callcontract)
29 | - [checkAppLoadedWithUser](index.zilswap.md#checkapploadedwithuser)
30 | - [deadlineBlock](index.zilswap.md#deadlineblock)
31 | - [deregisterZilo](index.zilswap.md#deregisterzilo)
32 | - [fetchContractInit](index.zilswap.md#fetchcontractinit)
33 | - [getAppState](index.zilswap.md#getappstate)
34 | - [getContract](index.zilswap.md#getcontract)
35 | - [getCurrentBlock](index.zilswap.md#getcurrentblock)
36 | - [getObservedTxs](index.zilswap.md#getobservedtxs)
37 | - [getPool](index.zilswap.md#getpool)
38 | - [getRatesForInput](index.zilswap.md#getratesforinput)
39 | - [getRatesForOutput](index.zilswap.md#getratesforoutput)
40 | - [initialize](index.zilswap.md#initialize)
41 | - [observeTx](index.zilswap.md#observetx)
42 | - [registerZilo](index.zilswap.md#registerzilo)
43 | - [removeLiquidity](index.zilswap.md#removeliquidity)
44 | - [setDeadlineBlocks](index.zilswap.md#setdeadlineblocks)
45 | - [swapWithExactInput](index.zilswap.md#swapwithexactinput)
46 | - [swapWithExactOutput](index.zilswap.md#swapwithexactoutput)
47 | - [teardown](index.zilswap.md#teardown)
48 | - [toUnit](index.zilswap.md#tounit)
49 | - [toUnitless](index.zilswap.md#tounitless)
50 | - [txParams](index.zilswap.md#txparams)
51 |
52 | ## Constructors
53 |
54 | ### constructor
55 |
56 | • **new Zilswap**(`network`, `walletProviderOrKey?`, `options?`)
57 |
58 | Creates the Zilswap SDK object. {@linkcode initalize} needs to be called after
59 | the object is created to begin watching the blockchain's state.
60 |
61 | #### Parameters
62 |
63 | | Name | Type | Description |
64 | | :------ | :------ | :------ |
65 | | `network` | [Network](../enums/constants.network.md) | the Network to use, either `TestNet` or `MainNet`. |
66 | | `walletProviderOrKey?` | `string` \| `Pick`<`Zilliqa` & { `wallet`: `Wallet` & { `defaultAccount`: { `base16`: `string` ; `bech32`: `string` } ; `net`: `string` } }, ``"provider"`` \| ``"blockchain"`` \| ``"network"`` \| ``"contracts"`` \| ``"transactions"`` \| ``"wallet"``\> | a Provider with Wallet or private key string to be used for signing txns. |
67 | | `options?` | [Options](../modules/index.md#options) | a set of Options that will be used for all txns. |
68 |
69 | #### Defined in
70 |
71 | [index.ts:127](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L127)
72 |
73 | ## Properties
74 |
75 | ### \_txParams
76 |
77 | • `Readonly` **\_txParams**: [TxParams](../modules/index.md#txparams)
78 |
79 | #### Defined in
80 |
81 | [index.ts:123](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L123)
82 |
83 | ___
84 |
85 | ### contract
86 |
87 | • `Readonly` **contract**: `Contract`
88 |
89 | #### Defined in
90 |
91 | [index.ts:115](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L115)
92 |
93 | ___
94 |
95 | ### contractAddress
96 |
97 | • `Readonly` **contractAddress**: `string`
98 |
99 | #### Defined in
100 |
101 | [index.ts:116](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L116)
102 |
103 | ___
104 |
105 | ### contractHash
106 |
107 | • `Readonly` **contractHash**: `string`
108 |
109 | #### Defined in
110 |
111 | [index.ts:117](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L117)
112 |
113 | ___
114 |
115 | ### network
116 |
117 | • `Readonly` **network**: [Network](../enums/constants.network.md)
118 |
119 | ___
120 |
121 | ### zilliqa
122 |
123 | • `Readonly` **zilliqa**: `Zilliqa`
124 |
125 | #### Defined in
126 |
127 | [index.ts:96](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L96)
128 |
129 | ___
130 |
131 | ### zilos
132 |
133 | • `Readonly` **zilos**: `Object`
134 |
135 | #### Index signature
136 |
137 | ▪ [address: `string`]: [Zilo](zilo.zilo-1.md)
138 |
139 | #### Defined in
140 |
141 | [index.ts:120](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L120)
142 |
143 | ## Methods
144 |
145 | ### addLiquidity
146 |
147 | ▸ **addLiquidity**(`tokenID`, `zilsToAddStr`, `tokensToAddStr`, `maxExchangeRateChange?`): `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
148 |
149 | Adds liquidity to the pool with the given `tokenID`. The given `zilsToAddHuman` represents the exact quantity of ZIL
150 | that will be contributed, while the given `tokensToAddHuman` represents the target quantity of ZRC-2 tokens to be
151 | contributed.
152 |
153 | To ensure the liquidity contributor does not lose value to arbitrage, the target token amount should be strictly
154 | derived from the current exchange rate that can be found using [`getPool`](index.zilswap.md#getpool).
155 |
156 | The maximum fluctuation in exchange rate from the given parameters can be controlled through `maxExchangeRateChange`,
157 | to protect against changes in pool reserves between the txn submission and txn confirmation on the Zilliqa blockchain.
158 |
159 | If the pool has no liquidity yet, the token amount given will be the exact quantity of tokens that will be contributed,
160 | and the `maxExchangeRateChange` is ignored.
161 |
162 | The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
163 |
164 | Note that all amounts should be given with decimals in it's human represented form, rather than as a unitless integer.
165 |
166 | #### Parameters
167 |
168 | | Name | Type | Default value | Description |
169 | | :------ | :------ | :------ | :------ |
170 | | `tokenID` | `string` | `undefined` | is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). |
171 | | `zilsToAddStr` | `string` | `undefined` | is the exact amount of zilliqas to contribute to the pool in ZILs as a unitless string. |
172 | | `tokensToAddStr` | `string` | `undefined` | is the target amount of tokens to contribute to the pool as a unitless string. |
173 | | `maxExchangeRateChange` | `number` | 200 | is the maximum allowed exchange rate flucuation given in [basis points](https://www.investopedia.com/terms/b/basispoint.asp). Defaults to 200 = 2.00% if not provided. |
174 |
175 | #### Returns
176 |
177 | `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
178 |
179 | #### Defined in
180 |
181 | [index.ts:534](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L534)
182 |
183 | ___
184 |
185 | ### addToken
186 |
187 | ▸ **addToken**(`tokenAddress`): `Promise`
188 |
189 | Adds a token which is not already loaded by the default tokens file to the SDK.
190 |
191 | #### Parameters
192 |
193 | | Name | Type | Description |
194 | | :------ | :------ | :------ |
195 | | `tokenAddress` | `string` | is the token address in base16 (0x...) or bech32 (zil...) form. |
196 |
197 | #### Returns
198 |
199 | `Promise`
200 |
201 | true if the token could be found, or false otherwise.
202 |
203 | #### Defined in
204 |
205 | [index.ts:415](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L415)
206 |
207 | ___
208 |
209 | ### approveTokenTransferIfRequired
210 |
211 | ▸ **approveTokenTransferIfRequired**(`tokenID`, `amountStrOrBN`, `spenderHash?`): `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
212 |
213 | Approves allowing the Zilswap contract to transfer ZRC-2 token with `tokenID`, if the current
214 | approved allowance is less than `amount`. If the allowance is sufficient, this method is a no-op.
215 |
216 | The approval is done by calling `IncreaseAllowance` with the allowance amount as the entire
217 | token supply. This is done so that the approval needs to only be done once per token contract,
218 | reducing the number of approval transactions required for users conducting multiple swaps.
219 |
220 | Non-custodial control of the token is ensured by the Zilswap contract itself, which does not
221 | allow for the transfer of tokens unless explicitly invoked by the sender.
222 |
223 | The transaction is added to the list of observedTxs, and the observer will be notified on
224 | a confirmation or rejection event. The transation will be assumed to be expired after the default
225 | deadline buffer, even though there is no deadline block for this transaction.
226 |
227 | #### Parameters
228 |
229 | | Name | Type | Description |
230 | | :------ | :------ | :------ |
231 | | `tokenID` | `string` | is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). |
232 | | `amountStrOrBN` | `string` \| `BigNumber` | is the required allowance amount the Zilswap contract requires, below which the `IncreaseAllowance` transition is invoked, as a unitless string or BigNumber. |
233 | | `spenderHash` | `string` | (optional) is the spender contract address, defaults to the ZilSwap contract address. |
234 |
235 | #### Returns
236 |
237 | `Promise`<``null`` \| [ObservedTx](../modules/index.md#observedtx)\>
238 |
239 | an ObservedTx if IncreaseAllowance was called, null if not.
240 |
241 | #### Defined in
242 |
243 | [index.ts:451](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L451)
244 |
245 | ___
246 |
247 | ### callContract
248 |
249 | ▸ **callContract**(`contract`, `transition`, `args`, `params`, `toDs?`): `Promise`
250 |
251 | #### Parameters
252 |
253 | | Name | Type |
254 | | :------ | :------ |
255 | | `contract` | `Contract` |
256 | | `transition` | `string` |
257 | | `args` | `Value`[] |
258 | | `params` | `Pick` |
259 | | `toDs?` | `boolean` |
260 |
261 | #### Returns
262 |
263 | `Promise`
264 |
265 | #### Defined in
266 |
267 | [index.ts:1157](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1157)
268 |
269 | ___
270 |
271 | ### checkAppLoadedWithUser
272 |
273 | ▸ **checkAppLoadedWithUser**(): `void`
274 |
275 | #### Returns
276 |
277 | `void`
278 |
279 | #### Defined in
280 |
281 | [index.ts:1546](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1546)
282 |
283 | ___
284 |
285 | ### deadlineBlock
286 |
287 | ▸ **deadlineBlock**(): `number`
288 |
289 | #### Returns
290 |
291 | `number`
292 |
293 | #### Defined in
294 |
295 | [index.ts:1579](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1579)
296 |
297 | ___
298 |
299 | ### deregisterZilo
300 |
301 | ▸ **deregisterZilo**(`address`): `void`
302 |
303 | Deregisters an existing Zilo instance. Does nothing if provided
304 | address is not already registered.
305 |
306 | #### Parameters
307 |
308 | | Name | Type | Description |
309 | | :------ | :------ | :------ |
310 | | `address` | `string` | is the Zilo contract address which can be given by either hash (0x...) or bech32 address (zil...). |
311 |
312 | #### Returns
313 |
314 | `void`
315 |
316 | #### Defined in
317 |
318 | [index.ts:227](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L227)
319 |
320 | ___
321 |
322 | ### fetchContractInit
323 |
324 | ▸ **fetchContractInit**(`contract`): `Promise`
325 |
326 | #### Parameters
327 |
328 | | Name | Type |
329 | | :------ | :------ |
330 | | `contract` | `Contract` |
331 |
332 | #### Returns
333 |
334 | `Promise`
335 |
336 | #### Defined in
337 |
338 | [index.ts:1454](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1454)
339 |
340 | ___
341 |
342 | ### getAppState
343 |
344 | ▸ **getAppState**(): [AppState](../modules/index.md#appstate)
345 |
346 | Gets the latest Zilswap app state.
347 |
348 | #### Returns
349 |
350 | [AppState](../modules/index.md#appstate)
351 |
352 | #### Defined in
353 |
354 | [index.ts:261](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L261)
355 |
356 | ___
357 |
358 | ### getContract
359 |
360 | ▸ **getContract**(`address`): `Contract`
361 |
362 | Gets the contract with the given address that can be called by the default account.
363 |
364 | #### Parameters
365 |
366 | | Name | Type |
367 | | :------ | :------ |
368 | | `address` | `string` |
369 |
370 | #### Returns
371 |
372 | `Contract`
373 |
374 | #### Defined in
375 |
376 | [index.ts:271](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L271)
377 |
378 | ___
379 |
380 | ### getCurrentBlock
381 |
382 | ▸ **getCurrentBlock**(): `number`
383 |
384 | #### Returns
385 |
386 | `number`
387 |
388 | #### Defined in
389 |
390 | [index.ts:1575](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1575)
391 |
392 | ___
393 |
394 | ### getObservedTxs
395 |
396 | ▸ **getObservedTxs**(): `Promise`<[ObservedTx](../modules/index.md#observedtx)[]\>
397 |
398 | Gets the currently observed transactions.
399 |
400 | #### Returns
401 |
402 | `Promise`<[ObservedTx](../modules/index.md#observedtx)[]\>
403 |
404 | #### Defined in
405 |
406 | [index.ts:292](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L292)
407 |
408 | ___
409 |
410 | ### getPool
411 |
412 | ▸ **getPool**(`tokenID`): ``null`` \| [Pool](../modules/index.md#pool)
413 |
414 | Gets the pool details for the given `tokenID`.
415 |
416 | #### Parameters
417 |
418 | | Name | Type | Description |
419 | | :------ | :------ | :------ |
420 | | `tokenID` | `string` | is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). |
421 |
422 | #### Returns
423 |
424 | ``null`` \| [Pool](../modules/index.md#pool)
425 |
426 | if pool exists, or `null` otherwise.
427 |
428 | #### Defined in
429 |
430 | [index.ts:282](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L282)
431 |
432 | ___
433 |
434 | ### getRatesForInput
435 |
436 | ▸ **getRatesForInput**(`tokenInID`, `tokenOutID`, `tokenInAmountStr`): [Rates](../modules/index.md#rates)
437 |
438 | Gets the expected output amount and slippage for a particular set of ZRC-2 or ZIL tokens at the given input amount.
439 |
440 | #### Parameters
441 |
442 | | Name | Type | Description |
443 | | :------ | :------ | :------ |
444 | | `tokenInID` | `string` | is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
445 | | `tokenOutID` | `string` | is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
446 | | `tokenInAmountStr` | `string` | is the exact amount of tokens to be sent to Zilswap as a unitless representable string (without decimals). |
447 |
448 | #### Returns
449 |
450 | [Rates](../modules/index.md#rates)
451 |
452 | #### Defined in
453 |
454 | [index.ts:342](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L342)
455 |
456 | ___
457 |
458 | ### getRatesForOutput
459 |
460 | ▸ **getRatesForOutput**(`tokenInID`, `tokenOutID`, `tokenOutAmountStr`): [Rates](../modules/index.md#rates)
461 |
462 | Gets the expected input amount and slippage for a particular set of ZRC-2 or ZIL tokens at the given output amount.
463 | Returns NaN values if the given output amount is larger than the pool reserve.
464 |
465 | #### Parameters
466 |
467 | | Name | Type | Description |
468 | | :------ | :------ | :------ |
469 | | `tokenInID` | `string` | is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
470 | | `tokenOutID` | `string` | is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
471 | | `tokenOutAmountStr` | `string` | is the exact amount of tokens to be received from Zilswap as a unitless representable string (without decimals). |
472 |
473 | #### Returns
474 |
475 | [Rates](../modules/index.md#rates)
476 |
477 | #### Defined in
478 |
479 | [index.ts:364](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L364)
480 |
481 | ___
482 |
483 | ### initialize
484 |
485 | ▸ **initialize**(`subscription?`, `observeTxs?`): `Promise`
486 |
487 | Intializes the SDK, fetching a cache of the Zilswap contract state and
488 | subscribing to subsequent state changes. You may optionally pass an array
489 | of ObservedTx's to subscribe to status changes on any of those txs.
490 |
491 | #### Parameters
492 |
493 | | Name | Type | Default value | Description |
494 | | :------ | :------ | :------ | :------ |
495 | | `subscription?` | [OnUpdate](../modules/index.md#onupdate) | `undefined` | is the callback function to call when a tx state changes. |
496 | | `observeTxs` | [ObservedTx](../modules/index.md#observedtx)[] | [] | - |
497 |
498 | #### Returns
499 |
500 | `Promise`
501 |
502 | #### Defined in
503 |
504 | [index.ts:173](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L173)
505 |
506 | ___
507 |
508 | ### observeTx
509 |
510 | ▸ **observeTx**(`observedTx`): `Promise`
511 |
512 | Observes the given transaction until the deadline block.
513 |
514 | Calls the `OnUpdate` callback given during `initialize` with the updated ObservedTx
515 | when a change has been observed.
516 |
517 | #### Parameters
518 |
519 | | Name | Type | Description |
520 | | :------ | :------ | :------ |
521 | | `observedTx` | [ObservedTx](../modules/index.md#observedtx) | is the txn hash of the txn to observe with the deadline block number. |
522 |
523 | #### Returns
524 |
525 | `Promise`
526 |
527 | #### Defined in
528 |
529 | [index.ts:400](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L400)
530 |
531 | ___
532 |
533 | ### registerZilo
534 |
535 | ▸ **registerZilo**(`address`, `onStateUpdate?`): `Promise`<[Zilo](zilo.zilo-1.md)\>
536 |
537 | Initializes a new Zilo instance and registers it to the ZilSwap SDK,
538 | subscribing to subsequent state changes in the Zilo instance. You may
539 | optionally pass a state observer to subscribe to state changes of this
540 | particular Zilo instance.
541 |
542 | If the Zilo instance is already registered, no new instance will be
543 | created. If a new state observer is provided, it will overwrite the
544 | existing one.
545 |
546 | #### Parameters
547 |
548 | | Name | Type | Description |
549 | | :------ | :------ | :------ |
550 | | `address` | `string` | is the Zilo contract address which can be given by either hash (0x...) or bech32 address (zil...). |
551 | | `onStateUpdate?` | [OnStateUpdate](../modules/zilo.md#onstateupdate) | is the state observer which triggers when state updates |
552 |
553 | #### Returns
554 |
555 | `Promise`<[Zilo](zilo.zilo-1.md)\>
556 |
557 | #### Defined in
558 |
559 | [index.ts:203](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L203)
560 |
561 | ___
562 |
563 | ### removeLiquidity
564 |
565 | ▸ **removeLiquidity**(`tokenID`, `contributionAmount`, `maxExchangeRateChange?`): `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
566 |
567 | Removes `contributionAmount` worth of liquidity from the pool with the given `tokenID`.
568 |
569 | The current user's contribution can be fetched in [`getPool`](index.zilswap.md#getpool), and the expected returned amounts at the
570 | current prevailing exchange rates can be calculated by prorating the liquidity pool reserves by the fraction of
571 | the user's current contribution against the pool's total contribution.
572 |
573 | The maximum fluctuation in exchange rate from the given parameters can be controlled through `maxExchangeRateChange`,
574 | to protect against changes in pool reserves between the txn submission and txn confirmation on the Zilliqa blockchain.
575 |
576 | The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
577 |
578 | #### Parameters
579 |
580 | | Name | Type | Default value | Description |
581 | | :------ | :------ | :------ | :------ |
582 | | `tokenID` | `string` | `undefined` | is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). |
583 | | `contributionAmount` | `string` | `undefined` | is the exact amount of zilliqas to contribute to the pool in ZILs as a string. |
584 | | `maxExchangeRateChange` | `number` | 200 | is the maximum allowed exchange rate flucuation given in [basis points](https://www.investopedia.com/terms/b/basispoint.asp). Defaults to 200 = 2.00% if not provided. |
585 |
586 | #### Returns
587 |
588 | `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
589 |
590 | #### Defined in
591 |
592 | [index.ts:634](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L634)
593 |
594 | ___
595 |
596 | ### setDeadlineBlocks
597 |
598 | ▸ **setDeadlineBlocks**(`bufferBlocks`): `void`
599 |
600 | Sets the number of blocks to use as the allowable buffer duration before transactions
601 | are considered invalid.
602 |
603 | When a transaction is signed, the deadline block by adding the buffer blocks to
604 | the latest confirmed block height.
605 |
606 | #### Parameters
607 |
608 | | Name | Type | Description |
609 | | :------ | :------ | :------ |
610 | | `bufferBlocks` | `number` | is the number of blocks to use as buffer for the deadline block. |
611 |
612 | #### Returns
613 |
614 | `void`
615 |
616 | #### Defined in
617 |
618 | [index.ts:385](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L385)
619 |
620 | ___
621 |
622 | ### swapWithExactInput
623 |
624 | ▸ **swapWithExactInput**(`tokenInID`, `tokenOutID`, `tokenInAmountStr`, `maxAdditionalSlippage?`, `recipientAddress?`): `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
625 |
626 | Swaps ZIL or a ZRC-2 token with `tokenInID` for a corresponding ZIL or ZRC-2 token with `tokenOutID`.
627 |
628 | The exact amount of ZIL or ZRC-2 to be sent in (sold) is `tokenInAmountHuman`. The amount received is determined by the prevailing
629 | exchange rate at the current AppState. The expected amount to be received can be given fetched by getExpectedOutput (NYI).
630 |
631 | The maximum additional slippage incurred due to fluctuations in exchange rate from when the
632 | transaction is signed and when it is processed by the Zilliqa blockchain can be bounded by the
633 | `maxAdditionalSlippage` variable.
634 |
635 | The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
636 |
637 | #### Parameters
638 |
639 | | Name | Type | Default value | Description |
640 | | :------ | :------ | :------ | :------ |
641 | | `tokenInID` | `string` | `undefined` | is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
642 | | `tokenOutID` | `string` | `undefined` | is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
643 | | `tokenInAmountStr` | `string` | `undefined` | is the exact amount of tokens to be sent to Zilswap as a unitless string (without decimals). |
644 | | `maxAdditionalSlippage` | `number` | 200 | is the maximum additional slippage (on top of slippage due to constant product formula) that the transition will allow before reverting. |
645 | | `recipientAddress` | ``null`` \| `string` | null | is an optional recipient address for receiving the output of the swap in base16 (0x...) or bech32 (zil...). Defaults to the sender address if `null` or undefined. |
646 |
647 | #### Returns
648 |
649 | `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
650 |
651 | #### Defined in
652 |
653 | [index.ts:735](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L735)
654 |
655 | ___
656 |
657 | ### swapWithExactOutput
658 |
659 | ▸ **swapWithExactOutput**(`tokenInID`, `tokenOutID`, `tokenOutAmountStr`, `maxAdditionalSlippage?`, `recipientAddress?`): `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
660 |
661 | Swaps ZIL or a ZRC-2 token with `tokenInID` for a corresponding ZIL or ZRC-2 token with `tokenOutID`.
662 |
663 | The exact amount of ZIL or ZRC-2 to be received (bought) is `tokenOutAmountHuman`. The amount sent is determined by the prevailing
664 | exchange rate at the current AppState. The expected amount to be sent can be given fetched by getExpectedInput (NYI).
665 |
666 | The maximum additional slippage incurred due to fluctuations in exchange rate from when the
667 | transaction is signed and when it is processed by the Zilliqa blockchain can be bounded by the
668 | `maxAdditionalSlippage` variable.
669 |
670 | The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
671 |
672 | #### Parameters
673 |
674 | | Name | Type | Default value | Description |
675 | | :------ | :------ | :------ | :------ |
676 | | `tokenInID` | `string` | `undefined` | is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
677 | | `tokenOutID` | `string` | `undefined` | is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
678 | | `tokenOutAmountStr` | `string` | `undefined` | is the exact amount of tokens to be received from Zilswap as a unitless string (withoout decimals). |
679 | | `maxAdditionalSlippage` | `number` | 200 | is the maximum additional slippage (on top of slippage due to constant product formula) that the transition will allow before reverting. |
680 | | `recipientAddress` | ``null`` \| `string` | null | is an optional recipient address for receiving the output of the swap in base16 (0x...) or bech32 (zil...). Defaults to the sender address if `null` or undefined. |
681 |
682 | #### Returns
683 |
684 | `Promise`<[ObservedTx](../modules/index.md#observedtx)\>
685 |
686 | #### Defined in
687 |
688 | [index.ts:905](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L905)
689 |
690 | ___
691 |
692 | ### teardown
693 |
694 | ▸ **teardown**(): `Promise`
695 |
696 | Stops watching the Zilswap contract state.
697 |
698 | #### Returns
699 |
700 | `Promise`
701 |
702 | #### Defined in
703 |
704 | [index.ts:242](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L242)
705 |
706 | ___
707 |
708 | ### toUnit
709 |
710 | ▸ **toUnit**(`tokenID`, `amountStr`): `string`
711 |
712 | Converts an amount to it's human representation (with decimals based on token contract, or 12 decimals for ZIL)
713 | from it's unitless representation (integer, no decimals).
714 |
715 | #### Parameters
716 |
717 | | Name | Type | Description |
718 | | :------ | :------ | :------ |
719 | | `tokenID` | `string` | is the token ID related to the conversion amount, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
720 | | `amountStr` | `string` | is the unitless amount as a string (e.g. 42000000000000 for 42 ZILs) to be converted. |
721 |
722 | #### Returns
723 |
724 | `string`
725 |
726 | #### Defined in
727 |
728 | [index.ts:324](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L324)
729 |
730 | ___
731 |
732 | ### toUnitless
733 |
734 | ▸ **toUnitless**(`tokenID`, `amountHuman`): `string`
735 |
736 | Converts an amount to it's unitless representation (integer, no decimals) from it's
737 | human representation (with decimals based on token contract, or 12 decimals for ZIL).
738 |
739 | #### Parameters
740 |
741 | | Name | Type | Description |
742 | | :------ | :------ | :------ |
743 | | `tokenID` | `string` | is the token ID related to the conversion amount, which can be given by either it's symbol (defined in constants.ts), hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant. |
744 | | `amountHuman` | `string` | is the amount as a human string (e.g. 4.2 for 4.2 ZILs) to be converted. |
745 |
746 | #### Returns
747 |
748 | `string`
749 |
750 | #### Defined in
751 |
752 | [index.ts:308](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L308)
753 |
754 | ___
755 |
756 | ### txParams
757 |
758 | ▸ **txParams**(): [TxParams](../modules/index.md#txparams) & { `nonce`: `number` }
759 |
760 | #### Returns
761 |
762 | [TxParams](../modules/index.md#txparams) & { `nonce`: `number` }
763 |
764 | #### Defined in
765 |
766 | [index.ts:1568](https://github.com/Switcheo/zilswap-sdk/blob/67d9128/src/index.ts#L1568)
767 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
6 | version "1.1.2"
7 | resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
8 | integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
9 |
10 | "@protobufjs/base64@^1.1.2":
11 | version "1.1.2"
12 | resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
13 | integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
14 |
15 | "@protobufjs/codegen@^2.0.4":
16 | version "2.0.4"
17 | resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
18 | integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
19 |
20 | "@protobufjs/eventemitter@^1.1.0":
21 | version "1.1.0"
22 | resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
23 | integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
24 |
25 | "@protobufjs/fetch@^1.1.0":
26 | version "1.1.0"
27 | resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
28 | integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
29 | dependencies:
30 | "@protobufjs/aspromise" "^1.1.1"
31 | "@protobufjs/inquire" "^1.1.0"
32 |
33 | "@protobufjs/float@^1.0.2":
34 | version "1.0.2"
35 | resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
36 | integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
37 |
38 | "@protobufjs/inquire@^1.1.0":
39 | version "1.1.0"
40 | resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
41 | integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
42 |
43 | "@protobufjs/path@^1.1.2":
44 | version "1.1.2"
45 | resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
46 | integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
47 |
48 | "@protobufjs/pool@^1.1.0":
49 | version "1.1.0"
50 | resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
51 | integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
52 |
53 | "@protobufjs/utf8@^1.1.0":
54 | version "1.1.0"
55 | resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
56 | integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
57 |
58 | "@types/bip39@^2.4.0":
59 | version "2.4.2"
60 | resolved "https://registry.yarnpkg.com/@types/bip39/-/bip39-2.4.2.tgz#f5d6617212be496bb998d3969f657f77a10c5287"
61 | integrity sha512-Vo9lqOIRq8uoIzEVrV87ZvcIM0PN9t0K3oYZ/CS61fIYKCBdOIM7mlWzXuRvSXrDtVa1uUO2w1cdfufxTC0bzg==
62 | dependencies:
63 | "@types/node" "*"
64 |
65 | "@types/bn.js@^4.11.3":
66 | version "4.11.6"
67 | resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
68 | integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==
69 | dependencies:
70 | "@types/node" "*"
71 |
72 | "@types/hdkey@^0.7.0":
73 | version "0.7.1"
74 | resolved "https://registry.yarnpkg.com/@types/hdkey/-/hdkey-0.7.1.tgz#9bc63ebbe96b107b277b65ea7a95442a677d0d61"
75 | integrity sha512-4Kkr06hq+R8a9EzVNqXGOY2x1xA7dhY6qlp6OvaZ+IJy1BCca1Cv126RD9X7CMJoXoLo8WvAizy8gQHpqW6K0Q==
76 | dependencies:
77 | "@types/node" "*"
78 |
79 | "@types/long@^4.0.0", "@types/long@^4.0.1":
80 | version "4.0.1"
81 | resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
82 | integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
83 |
84 | "@types/node@*", "@types/node@^13.13.5", "@types/node@^13.7.0":
85 | version "13.13.5"
86 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.5.tgz#96ec3b0afafd64a4ccea9107b75bf8489f0e5765"
87 | integrity sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==
88 |
89 | "@types/websocket@^1.0.0":
90 | version "1.0.0"
91 | resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.0.tgz#828c794b0a50949ad061aa311af1009934197e4b"
92 | integrity sha512-MLr8hDM8y7vvdAdnoDEP5LotRoYJj7wgT6mWzCUQH/gHqzS4qcnOT/K4dhC0WimWIUiA3Arj9QAJGGKNRiRZKA==
93 | dependencies:
94 | "@types/node" "*"
95 |
96 | "@zilliqa-js/account@2.2.1":
97 | version "2.2.1"
98 | resolved "https://registry.yarnpkg.com/@zilliqa-js/account/-/account-2.2.1.tgz#f12c2ef5219a899bd5c64077fbf0a4b677189ce4"
99 | integrity sha512-egq/S1KyrH8qlmMBKHaAmLU/RLl66JYPDEPe3n97NP/yvrbPTt7sEfgfOwL1IO0hIBLlJPQYIdKtlYHzn22BLw==
100 | dependencies:
101 | "@types/bip39" "^2.4.0"
102 | "@types/hdkey" "^0.7.0"
103 | "@zilliqa-js/core" "2.2.1"
104 | "@zilliqa-js/crypto" "2.2.1"
105 | "@zilliqa-js/proto" "2.2.0"
106 | "@zilliqa-js/util" "2.2.0"
107 | bip39 "^2.5.0"
108 | hdkey "^1.1.0"
109 |
110 | "@zilliqa-js/blockchain@2.2.1":
111 | version "2.2.1"
112 | resolved "https://registry.yarnpkg.com/@zilliqa-js/blockchain/-/blockchain-2.2.1.tgz#bed1811bc5af4ce8cd7f32620a1aa4e368cad975"
113 | integrity sha512-GiUzRAceOgsF9Nk/LzdionZt6QlLMDH72Z4/qt1SQY2vdK0rz9fbjBtQbZjVjfvwvGSjmOBo3KVYPhviJHuGYQ==
114 | dependencies:
115 | "@zilliqa-js/account" "2.2.1"
116 | "@zilliqa-js/contract" "2.2.1"
117 | "@zilliqa-js/core" "2.2.1"
118 | "@zilliqa-js/crypto" "2.2.1"
119 | "@zilliqa-js/util" "2.2.0"
120 | utility-types "^3.4.1"
121 |
122 | "@zilliqa-js/contract@2.2.1":
123 | version "2.2.1"
124 | resolved "https://registry.yarnpkg.com/@zilliqa-js/contract/-/contract-2.2.1.tgz#2b123f0a0ce77f1a20b10a4d2effdffdc260330d"
125 | integrity sha512-DmhElqUbgyUNxwKwKSJq6L8WfxOBVrrQ72crHrnubIgnhN3uNRaS9lZ4oAMAi1o6eSYe94GCBHGOZ5imSYxFrg==
126 | dependencies:
127 | "@zilliqa-js/account" "2.2.1"
128 | "@zilliqa-js/blockchain" "2.2.1"
129 | "@zilliqa-js/core" "2.2.1"
130 | "@zilliqa-js/crypto" "2.2.1"
131 | "@zilliqa-js/util" "2.2.0"
132 | hash.js "^1.1.5"
133 | utility-types "^2.1.0"
134 |
135 | "@zilliqa-js/core@2.2.1":
136 | version "2.2.1"
137 | resolved "https://registry.yarnpkg.com/@zilliqa-js/core/-/core-2.2.1.tgz#c151d1e2cd530f8928236d68835f0ff7faa119b1"
138 | integrity sha512-dEViTcv54waiDckyWROgBcuwDX8iugSKY/Fooa2RynDGHTlb4XvvAxmShTy4+OF1tldhV86cE9nsDW//ICTZPQ==
139 | dependencies:
140 | "@zilliqa-js/crypto" "2.2.1"
141 | "@zilliqa-js/util" "2.2.0"
142 | cross-fetch "^2.2.2"
143 | mitt "^1.1.3"
144 |
145 | "@zilliqa-js/crypto@2.2.1":
146 | version "2.2.1"
147 | resolved "https://registry.yarnpkg.com/@zilliqa-js/crypto/-/crypto-2.2.1.tgz#c1468244f35a9ebf7f0ee27881e0a718c09f8d97"
148 | integrity sha512-80fCuf6Bjpci+mmTfBp9r+umhWbxji8WE4Ii8jz1QtszkWBXLUvXhw6xFv0txgt74ZmUj12Ot1MENALAFEJEDg==
149 | dependencies:
150 | "@zilliqa-js/util" "2.2.0"
151 | aes-js "^3.1.1"
152 | bsert "^0.0.4"
153 | elliptic "^6.5.0"
154 | hash.js "^1.1.5"
155 | hmac-drbg "^1.0.1"
156 | pbkdf2 "^3.0.16"
157 | randombytes "^2.0.6"
158 | scrypt-js "^3.0.1"
159 | scryptsy "^2.1.0"
160 | sodium-native "^3.2.0"
161 | uuid "^3.3.2"
162 |
163 | "@zilliqa-js/proto@2.2.0":
164 | version "2.2.0"
165 | resolved "https://registry.yarnpkg.com/@zilliqa-js/proto/-/proto-2.2.0.tgz#c3fea22daf4a8e385e5f239119765a0d60f18df7"
166 | integrity sha512-0QPNJdvafT0ItPGrqEff7KMYNCT/DkWCn0/x2/UwVoVANy5BHL3WkwDV3y49KthVwdZUotQVzRaweHTs6PIcuA==
167 | dependencies:
168 | protobufjs "^6.8.8"
169 |
170 | "@zilliqa-js/subscriptions@2.2.1":
171 | version "2.2.1"
172 | resolved "https://registry.yarnpkg.com/@zilliqa-js/subscriptions/-/subscriptions-2.2.1.tgz#f334ef896521d3b6d5c87507cee5acf6cfeeb6fd"
173 | integrity sha512-MIz7i1kRCF7TpDzmpOFOhL13xl2CxCfmzpXvaBF1keGcOrqf8o/rgF7YARZ2H5YXobLlGDP5Gjm2qcShkiYfWw==
174 | dependencies:
175 | "@zilliqa-js/core" "2.2.1"
176 | mock-socket "^9.0.2"
177 | websocket "^1.0.28"
178 |
179 | "@zilliqa-js/util@2.2.0":
180 | version "2.2.0"
181 | resolved "https://registry.yarnpkg.com/@zilliqa-js/util/-/util-2.2.0.tgz#6f64adc5494596c93dd0eff566f830b316eba677"
182 | integrity sha512-bzThiraMQKDumhQY0HMsutX28HPgqB+KKqiet8M8QQbCFvQODxAGpuxJX6bZiX+6K6tZUk8yDSW8Ri3dgOdRDg==
183 | dependencies:
184 | "@types/bn.js" "^4.11.3"
185 | "@types/long" "^4.0.0"
186 | bn.js "^4.11.8"
187 | long "^4.0.0"
188 |
189 | "@zilliqa-js/zilliqa@^2.2.0":
190 | version "2.2.1"
191 | resolved "https://registry.yarnpkg.com/@zilliqa-js/zilliqa/-/zilliqa-2.2.1.tgz#7d39c8e8459b050033bd5f77126a9fb0fd59d8f6"
192 | integrity sha512-gN3VnuwSvK7SFlzRiXUg18In9rBHn33iZRfmVrggRqTtwG04Dv4AyiCG37+ieNG5hQHI5O+gRrCIPSVG24/n2w==
193 | dependencies:
194 | "@zilliqa-js/account" "2.2.1"
195 | "@zilliqa-js/blockchain" "2.2.1"
196 | "@zilliqa-js/contract" "2.2.1"
197 | "@zilliqa-js/core" "2.2.1"
198 | "@zilliqa-js/crypto" "2.2.1"
199 | "@zilliqa-js/subscriptions" "2.2.1"
200 | "@zilliqa-js/util" "2.2.0"
201 |
202 | aes-js@^3.1.1:
203 | version "3.1.2"
204 | resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a"
205 | integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==
206 |
207 | async-mutex@^0.2.2:
208 | version "0.2.2"
209 | resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.2.tgz#3a9de4be23615abce7d52730b4d3a43d9258fe06"
210 | integrity sha512-L1wZNK83y16khj/Fqezy+FfOp5KuywxypF/C2aYfAN3NOMLYdAVKRk3UDklqv+ngX+O+tNSEkPX+FxprxELsMA==
211 | dependencies:
212 | tslib "^1.11.1"
213 |
214 | base-x@^3.0.2:
215 | version "3.0.8"
216 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d"
217 | integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==
218 | dependencies:
219 | safe-buffer "^5.0.1"
220 |
221 | bignumber.js@^9.0.0:
222 | version "9.0.1"
223 | resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
224 | integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
225 |
226 | bindings@^1.5.0:
227 | version "1.5.0"
228 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
229 | integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
230 | dependencies:
231 | file-uri-to-path "1.0.0"
232 |
233 | bip39@^2.5.0:
234 | version "2.6.0"
235 | resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c"
236 | integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==
237 | dependencies:
238 | create-hash "^1.1.0"
239 | pbkdf2 "^3.0.9"
240 | randombytes "^2.0.1"
241 | safe-buffer "^5.0.1"
242 | unorm "^1.3.3"
243 |
244 | bip66@^1.1.5:
245 | version "1.1.5"
246 | resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22"
247 | integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=
248 | dependencies:
249 | safe-buffer "^5.0.1"
250 |
251 | bn.js@^4.11.8, bn.js@^4.11.9:
252 | version "4.12.0"
253 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
254 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
255 |
256 | bn.js@^5.1.1:
257 | version "5.1.1"
258 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.1.tgz#48efc4031a9c4041b9c99c6941d903463ab62eb5"
259 | integrity sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==
260 |
261 | brorand@^1.1.0:
262 | version "1.1.0"
263 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
264 | integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
265 |
266 | browserify-aes@^1.0.6:
267 | version "1.2.0"
268 | resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
269 | integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
270 | dependencies:
271 | buffer-xor "^1.0.3"
272 | cipher-base "^1.0.0"
273 | create-hash "^1.1.0"
274 | evp_bytestokey "^1.0.3"
275 | inherits "^2.0.1"
276 | safe-buffer "^5.0.1"
277 |
278 | bs58@^4.0.0:
279 | version "4.0.1"
280 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
281 | integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo=
282 | dependencies:
283 | base-x "^3.0.2"
284 |
285 | bs58check@^2.1.2:
286 | version "2.1.2"
287 | resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc"
288 | integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==
289 | dependencies:
290 | bs58 "^4.0.0"
291 | create-hash "^1.1.0"
292 | safe-buffer "^5.1.2"
293 |
294 | bsert@^0.0.4:
295 | version "0.0.4"
296 | resolved "https://registry.yarnpkg.com/bsert/-/bsert-0.0.4.tgz#2b3c236357923f0625f948802a5f9b66c0383d0b"
297 | integrity sha512-VReLe1aTaHRmf80YLOHUk8ONQ48SjseZP76GlNIDheD5REYByn/Mm9yrtI0/ZCaFrcfxzgpiw1/hMMCUOSMa3w==
298 |
299 | buffer-xor@^1.0.3:
300 | version "1.0.3"
301 | resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
302 | integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
303 |
304 | cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
305 | version "1.0.4"
306 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
307 | integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
308 | dependencies:
309 | inherits "^2.0.1"
310 | safe-buffer "^5.0.1"
311 |
312 | create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
313 | version "1.2.0"
314 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
315 | integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
316 | dependencies:
317 | cipher-base "^1.0.1"
318 | inherits "^2.0.1"
319 | md5.js "^1.3.4"
320 | ripemd160 "^2.0.1"
321 | sha.js "^2.4.0"
322 |
323 | create-hmac@^1.1.4:
324 | version "1.1.7"
325 | resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
326 | integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
327 | dependencies:
328 | cipher-base "^1.0.3"
329 | create-hash "^1.1.0"
330 | inherits "^2.0.1"
331 | ripemd160 "^2.0.0"
332 | safe-buffer "^5.0.1"
333 | sha.js "^2.4.8"
334 |
335 | cross-fetch@^2.2.2:
336 | version "2.2.3"
337 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e"
338 | integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==
339 | dependencies:
340 | node-fetch "2.1.2"
341 | whatwg-fetch "2.0.4"
342 |
343 | d@1, d@^1.0.1:
344 | version "1.0.1"
345 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
346 | integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
347 | dependencies:
348 | es5-ext "^0.10.50"
349 | type "^1.0.1"
350 |
351 | debug@^2.2.0:
352 | version "2.6.9"
353 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
354 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
355 | dependencies:
356 | ms "2.0.0"
357 |
358 | drbg.js@^1.0.1:
359 | version "1.0.1"
360 | resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b"
361 | integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=
362 | dependencies:
363 | browserify-aes "^1.0.6"
364 | create-hash "^1.1.2"
365 | create-hmac "^1.1.4"
366 |
367 | elliptic@^6.5.0, elliptic@^6.5.2:
368 | version "6.5.4"
369 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
370 | integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
371 | dependencies:
372 | bn.js "^4.11.9"
373 | brorand "^1.1.0"
374 | hash.js "^1.0.0"
375 | hmac-drbg "^1.0.1"
376 | inherits "^2.0.4"
377 | minimalistic-assert "^1.0.1"
378 | minimalistic-crypto-utils "^1.0.1"
379 |
380 | es5-ext@^0.10.35, es5-ext@^0.10.50:
381 | version "0.10.53"
382 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
383 | integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
384 | dependencies:
385 | es6-iterator "~2.0.3"
386 | es6-symbol "~3.1.3"
387 | next-tick "~1.0.0"
388 |
389 | es6-iterator@~2.0.3:
390 | version "2.0.3"
391 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
392 | integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
393 | dependencies:
394 | d "1"
395 | es5-ext "^0.10.35"
396 | es6-symbol "^3.1.1"
397 |
398 | es6-symbol@^3.1.1, es6-symbol@~3.1.3:
399 | version "3.1.3"
400 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
401 | integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
402 | dependencies:
403 | d "^1.0.1"
404 | ext "^1.1.2"
405 |
406 | evp_bytestokey@^1.0.3:
407 | version "1.0.3"
408 | resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
409 | integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
410 | dependencies:
411 | md5.js "^1.3.4"
412 | safe-buffer "^5.1.1"
413 |
414 | ext@^1.1.2:
415 | version "1.4.0"
416 | resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
417 | integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
418 | dependencies:
419 | type "^2.0.0"
420 |
421 | file-uri-to-path@1.0.0:
422 | version "1.0.0"
423 | resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
424 | integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
425 |
426 | hash-base@^3.0.0:
427 | version "3.1.0"
428 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
429 | integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
430 | dependencies:
431 | inherits "^2.0.4"
432 | readable-stream "^3.6.0"
433 | safe-buffer "^5.2.0"
434 |
435 | hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.5:
436 | version "1.1.7"
437 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
438 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
439 | dependencies:
440 | inherits "^2.0.3"
441 | minimalistic-assert "^1.0.1"
442 |
443 | hdkey@^1.1.0:
444 | version "1.1.2"
445 | resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.2.tgz#c60f9cf6f90fbf24a8a52ea06893f36a0108cd3e"
446 | integrity sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ==
447 | dependencies:
448 | bs58check "^2.1.2"
449 | safe-buffer "^5.1.1"
450 | secp256k1 "^3.0.1"
451 |
452 | hmac-drbg@^1.0.1:
453 | version "1.0.1"
454 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
455 | integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
456 | dependencies:
457 | hash.js "^1.0.3"
458 | minimalistic-assert "^1.0.0"
459 | minimalistic-crypto-utils "^1.0.1"
460 |
461 | inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4:
462 | version "2.0.4"
463 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
464 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
465 |
466 | ini@^1.3.5:
467 | version "1.3.8"
468 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
469 | integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
470 |
471 | is-typedarray@^1.0.0:
472 | version "1.0.0"
473 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
474 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
475 |
476 | isomorphic-fetch@^3.0.0:
477 | version "3.0.0"
478 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4"
479 | integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==
480 | dependencies:
481 | node-fetch "^2.6.1"
482 | whatwg-fetch "^3.4.1"
483 |
484 | long@^4.0.0:
485 | version "4.0.0"
486 | resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
487 | integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
488 |
489 | md5.js@^1.3.4:
490 | version "1.3.5"
491 | resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
492 | integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
493 | dependencies:
494 | hash-base "^3.0.0"
495 | inherits "^2.0.1"
496 | safe-buffer "^5.1.2"
497 |
498 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
499 | version "1.0.1"
500 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
501 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
502 |
503 | minimalistic-crypto-utils@^1.0.1:
504 | version "1.0.1"
505 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
506 | integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
507 |
508 | mitt@^1.1.3:
509 | version "1.2.0"
510 | resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d"
511 | integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==
512 |
513 | mock-socket@^9.0.2:
514 | version "9.0.3"
515 | resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.0.3.tgz#4bc6d2aea33191e4fed5ec71f039e2bbeb95e414"
516 | integrity sha512-SxIiD2yE/By79p3cNAAXyLQWTvEFNEzcAO7PH+DzRqKSFaplAPFjiQLmw8ofmpCsZf+Rhfn2/xCJagpdGmYdTw==
517 | dependencies:
518 | url-parse "^1.4.4"
519 |
520 | ms@2.0.0:
521 | version "2.0.0"
522 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
523 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
524 |
525 | nan@^2.14.0:
526 | version "2.14.1"
527 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
528 | integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
529 |
530 | next-tick@~1.0.0:
531 | version "1.0.0"
532 | resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
533 | integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
534 |
535 | node-fetch@2.1.2:
536 | version "2.1.2"
537 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5"
538 | integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=
539 |
540 | node-fetch@^2.6.1:
541 | version "2.6.1"
542 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
543 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
544 |
545 | node-gyp-build@^4.2.0:
546 | version "4.2.3"
547 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739"
548 | integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==
549 |
550 | pbkdf2@^3.0.16, pbkdf2@^3.0.9:
551 | version "3.0.17"
552 | resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
553 | integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==
554 | dependencies:
555 | create-hash "^1.1.2"
556 | create-hmac "^1.1.4"
557 | ripemd160 "^2.0.1"
558 | safe-buffer "^5.0.1"
559 | sha.js "^2.4.8"
560 |
561 | prettier@^2.0.5:
562 | version "2.0.5"
563 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
564 | integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
565 |
566 | protobufjs@^6.8.8:
567 | version "6.9.0"
568 | resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.9.0.tgz#c08b2bf636682598e6fabbf0edb0b1256ff090bd"
569 | integrity sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==
570 | dependencies:
571 | "@protobufjs/aspromise" "^1.1.2"
572 | "@protobufjs/base64" "^1.1.2"
573 | "@protobufjs/codegen" "^2.0.4"
574 | "@protobufjs/eventemitter" "^1.1.0"
575 | "@protobufjs/fetch" "^1.1.0"
576 | "@protobufjs/float" "^1.0.2"
577 | "@protobufjs/inquire" "^1.1.0"
578 | "@protobufjs/path" "^1.1.2"
579 | "@protobufjs/pool" "^1.1.0"
580 | "@protobufjs/utf8" "^1.1.0"
581 | "@types/long" "^4.0.1"
582 | "@types/node" "^13.7.0"
583 | long "^4.0.0"
584 |
585 | querystringify@^2.1.1:
586 | version "2.2.0"
587 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
588 | integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
589 |
590 | randombytes@^2.0.1, randombytes@^2.0.6:
591 | version "2.1.0"
592 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
593 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
594 | dependencies:
595 | safe-buffer "^5.1.0"
596 |
597 | readable-stream@^3.6.0:
598 | version "3.6.0"
599 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
600 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
601 | dependencies:
602 | inherits "^2.0.3"
603 | string_decoder "^1.1.1"
604 | util-deprecate "^1.0.1"
605 |
606 | requires-port@^1.0.0:
607 | version "1.0.0"
608 | resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
609 | integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
610 |
611 | ripemd160@^2.0.0, ripemd160@^2.0.1:
612 | version "2.0.2"
613 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
614 | integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
615 | dependencies:
616 | hash-base "^3.0.0"
617 | inherits "^2.0.1"
618 |
619 | safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
620 | version "5.2.1"
621 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
622 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
623 |
624 | scrypt-js@^3.0.1:
625 | version "3.0.1"
626 | resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
627 | integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==
628 |
629 | scryptsy@^2.1.0:
630 | version "2.1.0"
631 | resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790"
632 | integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==
633 |
634 | secp256k1@^3.0.1:
635 | version "3.8.0"
636 | resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d"
637 | integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==
638 | dependencies:
639 | bindings "^1.5.0"
640 | bip66 "^1.1.5"
641 | bn.js "^4.11.8"
642 | create-hash "^1.2.0"
643 | drbg.js "^1.0.1"
644 | elliptic "^6.5.2"
645 | nan "^2.14.0"
646 | safe-buffer "^5.1.2"
647 |
648 | sha.js@^2.4.0, sha.js@^2.4.8:
649 | version "2.4.11"
650 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
651 | integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
652 | dependencies:
653 | inherits "^2.0.1"
654 | safe-buffer "^5.0.1"
655 |
656 | sodium-native@^3.2.0:
657 | version "3.2.0"
658 | resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-3.2.0.tgz#68a9469b96edadffef320cbce51294ad5f72a37f"
659 | integrity sha512-8aq/vQSegLwsRch8Sb/Bpf9aAqlNe5dp0+NVhb9UjHv42zDZ0D5zX3wBRUbXK9Ejum9uZE6DUgT4vVLlUFRBWg==
660 | dependencies:
661 | ini "^1.3.5"
662 | node-gyp-build "^4.2.0"
663 |
664 | string_decoder@^1.1.1:
665 | version "1.3.0"
666 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
667 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
668 | dependencies:
669 | safe-buffer "~5.2.0"
670 |
671 | tslib@^1.11.1:
672 | version "1.13.0"
673 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
674 | integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
675 |
676 | tslib@^1.11.2:
677 | version "1.11.2"
678 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.2.tgz#9c79d83272c9a7aaf166f73915c9667ecdde3cc9"
679 | integrity sha512-tTSkux6IGPnUGUd1XAZHcpu85MOkIl5zX49pO+jfsie3eP0B6pyhOlLXm3cAC6T7s+euSDDUUV+Acop5WmtkVg==
680 |
681 | tslint-config-prettier@^1.18.0:
682 | version "1.18.0"
683 | resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37"
684 | integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==
685 |
686 | type@^1.0.1:
687 | version "1.2.0"
688 | resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
689 | integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
690 |
691 | type@^2.0.0:
692 | version "2.0.0"
693 | resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
694 | integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==
695 |
696 | typedarray-to-buffer@^3.1.5:
697 | version "3.1.5"
698 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
699 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
700 | dependencies:
701 | is-typedarray "^1.0.0"
702 |
703 | unorm@^1.3.3:
704 | version "1.6.0"
705 | resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af"
706 | integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==
707 |
708 | url-parse@^1.4.4:
709 | version "1.5.1"
710 | resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
711 | integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
712 | dependencies:
713 | querystringify "^2.1.1"
714 | requires-port "^1.0.0"
715 |
716 | util-deprecate@^1.0.1:
717 | version "1.0.2"
718 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
719 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
720 |
721 | utility-types@^2.1.0:
722 | version "2.1.0"
723 | resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-2.1.0.tgz#0c78fc9f7eb424d14302222b4ddd13fdb17f44ab"
724 | integrity sha512-/nP2gqavggo6l38rtQI/CdeV+2fmBGXVvHgj9kV2MAnms3TIi77Mz9BtapPFI0+GZQCqqom0vACQ+VlTTaCovw==
725 |
726 | utility-types@^3.4.1:
727 | version "3.10.0"
728 | resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b"
729 | integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
730 |
731 | uuid@^3.3.2:
732 | version "3.4.0"
733 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
734 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
735 |
736 | websocket@^1.0.28:
737 | version "1.0.31"
738 | resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.31.tgz#e5d0f16c3340ed87670e489ecae6144c79358730"
739 | integrity sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==
740 | dependencies:
741 | debug "^2.2.0"
742 | es5-ext "^0.10.50"
743 | nan "^2.14.0"
744 | typedarray-to-buffer "^3.1.5"
745 | yaeti "^0.0.6"
746 |
747 | whatwg-fetch@2.0.4:
748 | version "2.0.4"
749 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
750 | integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==
751 |
752 | whatwg-fetch@^3.4.1:
753 | version "3.4.1"
754 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3"
755 | integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ==
756 |
757 | yaeti@^0.0.6:
758 | version "0.0.6"
759 | resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577"
760 | integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=
761 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import 'isomorphic-fetch'
2 | import { Zilliqa } from '@zilliqa-js/zilliqa'
3 | import { Wallet, Transaction, TxReceipt as _TxReceipt } from '@zilliqa-js/account'
4 | import { Contract, Value, CallParams } from '@zilliqa-js/contract'
5 | import { fromBech32Address, toBech32Address } from '@zilliqa-js/crypto'
6 | import { StatusType, MessageType, NewEventSubscription } from '@zilliqa-js/subscriptions'
7 | import { BN, Long, units } from '@zilliqa-js/util'
8 | import { BigNumber } from 'bignumber.js'
9 | import { Mutex } from 'async-mutex'
10 |
11 | import { APIS, WSS, CONTRACTS, CHAIN_VERSIONS, BASIS, Network, ZIL_HASH, WHITELISTED_TOKENS } from './constants'
12 | import { unitlessBigNumber, toPositiveQa, isLocalStorageAvailable } from './utils'
13 | import { sendBatchRequest, BatchRequest } from './batch'
14 | import { Zilo, OnStateUpdate } from './zilo'
15 | export * as Zilo from './zilo'
16 |
17 | BigNumber.config({ EXPONENTIAL_AT: 1e9 }) // never!
18 |
19 | export type Options = {
20 | deadlineBuffer?: number
21 | gasPrice?: number
22 | gasLimit?: number
23 | rpcEndpoint?: string
24 | }
25 |
26 | export type OnUpdate = (tx: ObservedTx, status: TxStatus, receipt?: TxReceipt) => void
27 |
28 | export type ObservedTx = {
29 | hash: string
30 | deadline: number
31 | }
32 |
33 | // The tx status of an observed tx.
34 | // Confirmed = txn was found, confirmed and processed without reverting
35 | // Rejected = txn was found, confirmed, but had an error and reverted during smart contract execution
36 | // Expired = current block height has exceeded the txn's deadline block
37 | export type TxStatus = 'confirmed' | 'rejected' | 'expired'
38 |
39 | export type TxReceipt = _TxReceipt
40 |
41 | export type TxParams = {
42 | version: number
43 | gasPrice: BN
44 | gasLimit: Long
45 | }
46 |
47 | export type TokenDetails = {
48 | contract: Contract // instance
49 | address: string
50 | hash: string
51 | name: string
52 | symbol: string
53 | decimals: number
54 | registered: boolean // is in default token list
55 | whitelisted: boolean // is a verified token
56 | }
57 |
58 | export type ContractState = {
59 | balances: { [key in string]?: { [key2 in string]?: string } }
60 | output_after_fee: string
61 | pools: { [key in string]?: { arguments: ReadonlyArray } }
62 | total_contributions: { [key in string]?: string }
63 | }
64 |
65 | export type AppState = {
66 | contractState: ContractState
67 | tokens: { [key in string]: TokenDetails }
68 | pools: { [key in string]?: Pool }
69 | currentUser: string | null
70 | currentNonce: number | null
71 | currentBalance: BigNumber | null
72 | }
73 |
74 | export type Pool = {
75 | zilReserve: BigNumber
76 | tokenReserve: BigNumber
77 | exchangeRate: BigNumber // the zero slippage exchange rate
78 | totalContribution: BigNumber
79 | userContribution: BigNumber
80 | contributionPercentage: BigNumber
81 | }
82 |
83 | export type Rates = {
84 | expectedAmount: BigNumber // in human amounts (with decimals)
85 | slippage: BigNumber // in percentage points
86 | }
87 |
88 | export type WalletProvider = Omit<
89 | Zilliqa & { wallet: Wallet & { net: string; defaultAccount: { base16: string; bech32: string } } }, // ugly hack for zilpay non-standard API
90 | 'subscriptionBuilder'
91 | >
92 |
93 | type RPCBalanceResponse = { balance: string; nonce: string }
94 |
95 | export class Zilswap {
96 | /* Zilliqa SDK */
97 | readonly zilliqa: Zilliqa
98 |
99 | /* Internals */
100 | private readonly rpcEndpoint: string
101 | private readonly walletProvider?: WalletProvider // zilpay
102 | private readonly tokens: { [key in string]: string } // symbol => hash mappings
103 | private appState?: AppState // cached blockchain state for dApp and user
104 |
105 | /* Txn observers */
106 | private subscription: NewEventSubscription | null = null
107 | private observer: OnUpdate | null = null
108 | private observerMutex: Mutex
109 | private observedTxs: ObservedTx[] = []
110 |
111 | /* Deadline tracking */
112 | private deadlineBuffer: number = 3
113 | private currentBlock: number = -1
114 |
115 | /* Zilswap contract attributes */
116 | readonly contract: Contract
117 | readonly contractAddress: string
118 | readonly contractHash: string
119 |
120 | /* Zilswap initial launch offerings */
121 | readonly zilos: { [address: string]: Zilo }
122 |
123 | /* Transaction attributes */
124 | readonly _txParams: TxParams = {
125 | version: -1,
126 | gasPrice: new BN(0),
127 | gasLimit: Long.fromNumber(5000),
128 | }
129 |
130 | /**
131 | * Creates the Zilswap SDK object. {@linkcode initalize} needs to be called after
132 | * the object is created to begin watching the blockchain's state.
133 | *
134 | * @param network the Network to use, either `TestNet` or `MainNet`.
135 | * @param walletProviderOrKey a Provider with Wallet or private key string to be used for signing txns.
136 | * @param options a set of Options that will be used for all txns.
137 | */
138 | constructor(readonly network: Network, walletProviderOrKey?: WalletProvider | string, options?: Options) {
139 | this.rpcEndpoint = options?.rpcEndpoint || APIS[network]
140 | if (typeof walletProviderOrKey === 'string') {
141 | this.zilliqa = new Zilliqa(this.rpcEndpoint)
142 | this.zilliqa.wallet.addByPrivateKey(walletProviderOrKey)
143 | } else if (walletProviderOrKey) {
144 | this.zilliqa = new Zilliqa(this.rpcEndpoint, walletProviderOrKey.provider)
145 | this.walletProvider = walletProviderOrKey
146 | } else {
147 | this.zilliqa = new Zilliqa(this.rpcEndpoint)
148 | }
149 |
150 | this.contractAddress = CONTRACTS[network]
151 | this.contract = (this.walletProvider || this.zilliqa).contracts.at(this.contractAddress)
152 | this.contractHash = fromBech32Address(this.contractAddress).toLowerCase()
153 | this.tokens = {}
154 | this.zilos = {}
155 | this._txParams.version = CHAIN_VERSIONS[network]
156 |
157 | if (options) {
158 | if (options.deadlineBuffer && options.deadlineBuffer > 0) this.deadlineBuffer = options.deadlineBuffer
159 | if (options.gasPrice && options.gasPrice > 0) this._txParams.gasPrice = toPositiveQa(options.gasPrice, units.Units.Li)
160 | if (options.gasLimit && options.gasLimit > 0) this._txParams.gasLimit = Long.fromNumber(options.gasLimit)
161 | }
162 |
163 | this.observerMutex = new Mutex()
164 | }
165 |
166 | /**
167 | * Intializes the SDK, fetching a cache of the Zilswap contract state and
168 | * subscribing to subsequent state changes. You may optionally pass an array
169 | * of ObservedTx's to subscribe to status changes on any of those txs.
170 | *
171 | * @param subscription is the callback function to call when a tx state changes.
172 | * @param observedTx is the array of txs to observe.
173 | */
174 | public async initialize(subscription?: OnUpdate, observeTxs: ObservedTx[] = []) {
175 | this.observedTxs = observeTxs
176 | if (subscription) this.observer = subscription
177 | if (this._txParams.gasPrice.isZero()) {
178 | const minGasPrice = await this.zilliqa.blockchain.getMinimumGasPrice()
179 | if (!minGasPrice.result) throw new Error('Failed to get min gas price.')
180 | this._txParams.gasPrice = new BN(minGasPrice.result)
181 | }
182 | await this.loadTokenList()
183 | await this.updateBlockHeight()
184 | await this.updateAppState()
185 | await this.updateBalanceAndNonce()
186 | }
187 |
188 | /**
189 | * Initializes a new Zilo instance and registers it to the ZilSwap SDK,
190 | * subscribing to subsequent state changes in the Zilo instance. You may
191 | * optionally pass a state observer to subscribe to state changes of this
192 | * particular Zilo instance.
193 | *
194 | * If the Zilo instance is already registered, no new instance will be
195 | * created. If a new state observer is provided, it will overwrite the
196 | * existing one.
197 | *
198 | * @param address is the Zilo contract address which can be given by
199 | * either hash (0x...) or bech32 address (zil...).
200 | * @param onStateUpdate is the state observer which triggers when state
201 | * updates
202 | */
203 | public async registerZilo(address: string, onStateUpdate?: OnStateUpdate): Promise {
204 | const byStr20Address = this.parseRecipientAddress(address)
205 |
206 | if (this.zilos[byStr20Address]) {
207 | this.zilos[byStr20Address].updateObserver(onStateUpdate)
208 | return this.zilos[byStr20Address]
209 | }
210 |
211 | const zilo = new Zilo(this, byStr20Address)
212 | await zilo.initialize(onStateUpdate)
213 | this.zilos[byStr20Address] = zilo
214 |
215 | this.subscribeToAppChanges()
216 |
217 | return zilo
218 | }
219 |
220 | /**
221 | * Deregisters an existing Zilo instance. Does nothing if provided
222 | * address is not already registered.
223 | *
224 | * @param address is the Zilo contract address which can be given by
225 | * either hash (0x...) or bech32 address (zil...).
226 | */
227 | public deregisterZilo(address: string) {
228 | const byStr20Address = this.parseRecipientAddress(address)
229 |
230 | if (!this.zilos[byStr20Address]) {
231 | return
232 | }
233 |
234 | delete this.zilos[address]
235 |
236 | this.subscribeToAppChanges()
237 | }
238 |
239 | /**
240 | * Stops watching the Zilswap contract state.
241 | */
242 | public async teardown() {
243 | this.subscription?.stop()
244 |
245 | const stopped = new Promise(resolve => {
246 | const checkSubscription = () => {
247 | if (this.subscription) {
248 | setTimeout(checkSubscription, 100)
249 | } else {
250 | resolve()
251 | }
252 | }
253 | checkSubscription()
254 | })
255 | await stopped
256 | }
257 |
258 | /**
259 | * Gets the latest Zilswap app state.
260 | */
261 | public getAppState(): AppState {
262 | if (!this.appState) {
263 | throw new Error('App state not loaded, call #initialize first.')
264 | }
265 | return this.appState
266 | }
267 |
268 | /**
269 | * Gets the contract with the given address that can be called by the default account.
270 | */
271 | public getContract(address: string): Contract {
272 | return (this.walletProvider || this.zilliqa).contracts.at(address)
273 | }
274 |
275 | /**
276 | * Gets the pool details for the given `tokenID`.
277 | *
278 | * @param tokenID is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts),
279 | * hash (0x...) or bech32 address (zil...).
280 | * @returns {Pool} if pool exists, or `null` otherwise.
281 | */
282 | public getPool(tokenID: string): Pool | null {
283 | if (!this.appState) {
284 | throw new Error('App state not loaded, call #initialize first.')
285 | }
286 | return this.appState.pools[this.getTokenAddresses(tokenID).hash] || null
287 | }
288 |
289 | /**
290 | * Gets the currently observed transactions.
291 | */
292 | public async getObservedTxs(): Promise {
293 | const release = await this.observerMutex.acquire()
294 | try {
295 | return [...this.observedTxs]
296 | } finally {
297 | release()
298 | }
299 | }
300 |
301 | /**
302 | * Converts an amount to it's unitless representation (integer, no decimals) from it's
303 | * human representation (with decimals based on token contract, or 12 decimals for ZIL).
304 | * @param tokenID is the token ID related to the conversion amount, which can be given by either it's symbol (defined in constants.ts),
305 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
306 | * @param amountHuman is the amount as a human string (e.g. 4.2 for 4.2 ZILs) to be converted.
307 | */
308 | public toUnitless(tokenID: string, amountHuman: string): string {
309 | const token = this.getTokenDetails(tokenID)
310 | const amountUnitless = new BigNumber(amountHuman).shiftedBy(token.decimals)
311 | if (!amountUnitless.integerValue().isEqualTo(amountUnitless)) {
312 | throw new Error(`Amount ${amountHuman} for ${token.symbol} has too many decimals, max is ${token.decimals}.`)
313 | }
314 | return amountUnitless.toString()
315 | }
316 |
317 | /**
318 | * Converts an amount to it's human representation (with decimals based on token contract, or 12 decimals for ZIL)
319 | * from it's unitless representation (integer, no decimals).
320 | * @param tokenID is the token ID related to the conversion amount, which can be given by either it's symbol (defined in constants.ts),
321 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
322 | * @param amountStr is the unitless amount as a string (e.g. 42000000000000 for 42 ZILs) to be converted.
323 | */
324 | public toUnit(tokenID: string, amountStr: string): string {
325 | const token = this.getTokenDetails(tokenID)
326 | const amountBN = new BigNumber(amountStr)
327 | if (!amountBN.integerValue().isEqualTo(amountStr)) {
328 | throw new Error(`Amount ${amountStr} for ${token.symbol} cannot have decimals.`)
329 | }
330 | return amountBN.shiftedBy(-token.decimals).toString()
331 | }
332 |
333 | /**
334 | * Gets the expected output amount and slippage for a particular set of ZRC-2 or ZIL tokens at the given input amount.
335 | *
336 | * @param tokenInID is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts),
337 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
338 | * @param tokenOutID is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts),
339 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
340 | * @param tokenInAmountStr is the exact amount of tokens to be sent to Zilswap as a unitless representable string (without decimals).
341 | */
342 | public getRatesForInput(tokenInID: string, tokenOutID: string, tokenInAmountStr: string): Rates {
343 | const tokenIn = this.getTokenDetails(tokenInID)
344 | const tokenOut = this.getTokenDetails(tokenOutID)
345 | const tokenInAmount = unitlessBigNumber(tokenInAmountStr)
346 | const { epsilonOutput, expectedOutput } = this.getOutputs(tokenIn, tokenOut, tokenInAmount)
347 |
348 | return {
349 | expectedAmount: expectedOutput,
350 | slippage: epsilonOutput.minus(expectedOutput).times(100).dividedBy(epsilonOutput).minus(0.3),
351 | }
352 | }
353 |
354 | /**
355 | * Gets the expected input amount and slippage for a particular set of ZRC-2 or ZIL tokens at the given output amount.
356 | * Returns NaN values if the given output amount is larger than the pool reserve.
357 | *
358 | * @param tokenInID is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts),
359 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
360 | * @param tokenOutID is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts),
361 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
362 | * @param tokenOutAmountStr is the exact amount of tokens to be received from Zilswap as a unitless representable string (without decimals).
363 | */
364 | public getRatesForOutput(tokenInID: string, tokenOutID: string, tokenOutAmountStr: string): Rates {
365 | const tokenIn = this.getTokenDetails(tokenInID)
366 | const tokenOut = this.getTokenDetails(tokenOutID)
367 | const tokenOutAmount = unitlessBigNumber(tokenOutAmountStr)
368 | const { epsilonInput, expectedInput } = this.getInputs(tokenIn, tokenOut, tokenOutAmount)
369 |
370 | return {
371 | expectedAmount: expectedInput,
372 | slippage: expectedInput.minus(epsilonInput).times(100).dividedBy(expectedInput).minus(0.3),
373 | }
374 | }
375 |
376 | /**
377 | * Sets the number of blocks to use as the allowable buffer duration before transactions
378 | * are considered invalid.
379 | *
380 | * When a transaction is signed, the deadline block by adding the buffer blocks to
381 | * the latest confirmed block height.
382 | *
383 | * @param bufferBlocks is the number of blocks to use as buffer for the deadline block.
384 | */
385 | public setDeadlineBlocks(bufferBlocks: number) {
386 | if (bufferBlocks <= 0) {
387 | throw new Error('Buffer blocks must be greater than 0.')
388 | }
389 | this.deadlineBuffer = bufferBlocks
390 | }
391 |
392 | /**
393 | * Observes the given transaction until the deadline block.
394 | *
395 | * Calls the `OnUpdate` callback given during `initialize` with the updated ObservedTx
396 | * when a change has been observed.
397 | *
398 | * @param observedTx is the txn hash of the txn to observe with the deadline block number.
399 | */
400 | public async observeTx(observedTx: ObservedTx) {
401 | const release = await this.observerMutex.acquire()
402 | try {
403 | this.observedTxs.push(observedTx)
404 | } finally {
405 | release()
406 | }
407 | }
408 |
409 | /**
410 | * Adds a token which is not already loaded by the default tokens file to the SDK.
411 | * @param tokenAddress is the token address in base16 (0x...) or bech32 (zil...) form.
412 | *
413 | * @returns true if the token could be found, or false otherwise.
414 | */
415 | public async addToken(tokenAddress: string): Promise {
416 | if (!this.appState) {
417 | throw new Error('App state not loaded, call #initialize first.')
418 | }
419 | try {
420 | const details = await this.fetchTokenDetails(tokenAddress)
421 | if (details === null) return false
422 | this.appState!.tokens[details.hash] = details
423 | return true
424 | } catch {
425 | return false
426 | }
427 | }
428 |
429 | /**
430 | * Approves allowing the Zilswap contract to transfer ZRC-2 token with `tokenID`, if the current
431 | * approved allowance is less than `amount`. If the allowance is sufficient, this method is a no-op.
432 | *
433 | * The approval is done by calling `IncreaseAllowance` with the allowance amount as the entire
434 | * token supply. This is done so that the approval needs to only be done once per token contract,
435 | * reducing the number of approval transactions required for users conducting multiple swaps.
436 | *
437 | * Non-custodial control of the token is ensured by the Zilswap contract itself, which does not
438 | * allow for the transfer of tokens unless explicitly invoked by the sender.
439 | *
440 | * The transaction is added to the list of observedTxs, and the observer will be notified on
441 | * a confirmation or rejection event. The transation will be assumed to be expired after the default
442 | * deadline buffer, even though there is no deadline block for this transaction.
443 | *
444 | * @param tokenID is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts),
445 | * hash (0x...) or bech32 address (zil...).
446 | * @param amountStrOrBN is the required allowance amount the Zilswap contract requires, below which the
447 | * `IncreaseAllowance` transition is invoked, as a unitless string or BigNumber.
448 | * @param spenderHash (optional) is the spender contract address, defaults to the ZilSwap contract address.
449 | *
450 | * @returns an ObservedTx if IncreaseAllowance was called, null if not.
451 | */
452 | public async approveTokenTransferIfRequired(
453 | tokenID: string,
454 | amountStrOrBN: BigNumber | string,
455 | spenderHash: string = this.contractHash
456 | ): Promise {
457 | // Check logged in
458 | this.checkAppLoadedWithUser()
459 |
460 | const _spenderHash = this.parseRecipientAddress(spenderHash)
461 | const token = this.getTokenDetails(tokenID)
462 | const tokenState = await token.contract.getSubState('allowances', [this.appState!.currentUser!, _spenderHash])
463 | const allowance = new BigNumber(tokenState?.allowances[this.appState!.currentUser!]?.[_spenderHash] || 0)
464 | const amount: BigNumber = typeof amountStrOrBN === 'string' ? unitlessBigNumber(amountStrOrBN) : amountStrOrBN
465 |
466 | if (allowance.lt(amount)) {
467 | try {
468 | console.log('sending increase allowance txn..')
469 | const approveTxn = await this.callContract(
470 | token.contract,
471 | 'IncreaseAllowance',
472 | [
473 | {
474 | vname: 'spender',
475 | type: 'ByStr20',
476 | value: _spenderHash,
477 | },
478 | {
479 | vname: 'amount',
480 | type: 'Uint128',
481 | value: new BigNumber(2).pow(128).minus(1).minus(allowance).toString(),
482 | },
483 | ],
484 | {
485 | amount: new BN(0),
486 | ...this.txParams(),
487 | },
488 | true
489 | )
490 |
491 | const observeTxn = {
492 | hash: approveTxn.id!,
493 | deadline: this.deadlineBlock(),
494 | }
495 | await this.observeTx(observeTxn)
496 |
497 | return observeTxn
498 | } catch (err) {
499 | if ((err as any).message === 'Could not get balance') {
500 | throw new Error('No ZIL to pay for transaction.')
501 | } else {
502 | throw err
503 | }
504 | }
505 | }
506 |
507 | return null
508 | }
509 |
510 | /**
511 | * Adds liquidity to the pool with the given `tokenID`. The given `zilsToAddHuman` represents the exact quantity of ZIL
512 | * that will be contributed, while the given `tokensToAddHuman` represents the target quantity of ZRC-2 tokens to be
513 | * contributed.
514 | *
515 | * To ensure the liquidity contributor does not lose value to arbitrage, the target token amount should be strictly
516 | * derived from the current exchange rate that can be found using {@linkcode getPool}.
517 | *
518 | * The maximum fluctuation in exchange rate from the given parameters can be controlled through `maxExchangeRateChange`,
519 | * to protect against changes in pool reserves between the txn submission and txn confirmation on the Zilliqa blockchain.
520 | *
521 | * If the pool has no liquidity yet, the token amount given will be the exact quantity of tokens that will be contributed,
522 | * and the `maxExchangeRateChange` is ignored.
523 | *
524 | * The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
525 | *
526 | * Note that all amounts should be given with decimals in it's human represented form, rather than as a unitless integer.
527 | *
528 | * @param tokenID is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts),
529 | * hash (0x...) or bech32 address (zil...).
530 | * @param zilsToAddStr is the exact amount of zilliqas to contribute to the pool in ZILs as a unitless string.
531 | * @param tokensToAddStr is the target amount of tokens to contribute to the pool as a unitless string.
532 | * @param maxExchangeRateChange is the maximum allowed exchange rate flucuation
533 | * given in {@link https://www.investopedia.com/terms/b/basispoint.asp basis points}. Defaults to 200 = 2.00% if not provided.
534 | */
535 | public async addLiquidity(
536 | tokenID: string,
537 | zilsToAddStr: string,
538 | tokensToAddStr: string,
539 | maxExchangeRateChange: number = 200
540 | ): Promise {
541 | // Check logged in
542 | this.checkAppLoadedWithUser()
543 |
544 | // Format token amounts
545 | const token = this.getTokenDetails(tokenID)
546 | const zil = this.getTokenDetails(ZIL_HASH)
547 | const tokensToAdd = new BigNumber(tokensToAddStr)
548 | const zilsToAdd = new BigNumber(zilsToAddStr)
549 |
550 | // Calculate allowances
551 | const pool = this.getPool(token.hash)
552 | const maxTokens = pool ? tokensToAdd.times(BASIS + maxExchangeRateChange).dividedToIntegerBy(BASIS) : tokensToAdd
553 | let minContribution = new BN(0)
554 | if (pool) {
555 | // sqrt(delta) * x = max allowed change in zil reserve
556 | // min contribution = zil added / max zil reserve * current total contributions
557 | const { zilReserve } = pool
558 | this.validateMaxExchangeRateChange(maxExchangeRateChange)
559 | const totalContribution = pool.totalContribution
560 | const numerator = totalContribution.times(zilsToAdd.toString())
561 | const denominator = new BigNumber(BASIS).plus(maxExchangeRateChange).sqrt().times(zilReserve.toString())
562 | minContribution = new BN(numerator.dividedToIntegerBy(denominator).toString())
563 | }
564 |
565 | // Check balances
566 | await this.checkAllowedBalance(token, tokensToAdd)
567 | await this.checkAllowedBalance(zil, zilsToAdd)
568 |
569 | const deadline = this.deadlineBlock()
570 |
571 | console.log('sending add liquidity txn..')
572 | const addLiquidityTxn = await this.callContract(
573 | this.contract,
574 | 'AddLiquidity',
575 | [
576 | {
577 | vname: 'token_address',
578 | type: 'ByStr20',
579 | value: token.hash,
580 | },
581 | {
582 | vname: 'min_contribution_amount',
583 | type: 'Uint128',
584 | value: minContribution.toString(),
585 | },
586 | {
587 | vname: 'max_token_amount',
588 | type: 'Uint128',
589 | value: maxTokens.toString(),
590 | },
591 | {
592 | vname: 'deadline_block',
593 | type: 'BNum',
594 | value: deadline.toString(),
595 | },
596 | ],
597 | {
598 | amount: new BN(zilsToAdd.toString()), // _amount
599 | ...this.txParams(),
600 | },
601 | true
602 | )
603 |
604 | if (addLiquidityTxn.isRejected()) {
605 | throw new Error('Submitted transaction was rejected.')
606 | }
607 |
608 | const observeTxn = {
609 | hash: addLiquidityTxn.id!,
610 | deadline,
611 | }
612 | await this.observeTx(observeTxn)
613 |
614 | return observeTxn
615 | }
616 |
617 | /**
618 | * Removes `contributionAmount` worth of liquidity from the pool with the given `tokenID`.
619 | *
620 | * The current user's contribution can be fetched in {@linkcode getPool}, and the expected returned amounts at the
621 | * current prevailing exchange rates can be calculated by prorating the liquidity pool reserves by the fraction of
622 | * the user's current contribution against the pool's total contribution.
623 | *
624 | * The maximum fluctuation in exchange rate from the given parameters can be controlled through `maxExchangeRateChange`,
625 | * to protect against changes in pool reserves between the txn submission and txn confirmation on the Zilliqa blockchain.
626 | *
627 | * The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
628 | *
629 | * @param tokenID is the token ID for the pool, which can be given by either it's symbol (defined in constants.ts),
630 | * hash (0x...) or bech32 address (zil...).
631 | * @param contributionAmount is the exact amount of zilliqas to contribute to the pool in ZILs as a string.
632 | * @param maxExchangeRateChange is the maximum allowed exchange rate flucuation
633 | * given in {@link https://www.investopedia.com/terms/b/basispoint.asp basis points}. Defaults to 200 = 2.00% if not provided.
634 | */
635 | public async removeLiquidity(tokenID: string, contributionAmount: string, maxExchangeRateChange: number = 200): Promise {
636 | // Check logged in
637 | this.checkAppLoadedWithUser()
638 |
639 | // Check parameters
640 | this.validateMaxExchangeRateChange(maxExchangeRateChange)
641 |
642 | // Calculate contribution
643 | const token = this.getTokenDetails(tokenID)
644 | const pool = this.getPool(token.hash)
645 | if (!pool) {
646 | throw new Error('Pool not found.')
647 | }
648 |
649 | const { zilReserve, tokenReserve, userContribution, contributionPercentage } = pool
650 | // expected = reserve * (contributionPercentage / 100) * (contributionAmount / userContribution)
651 | const expectedZilAmount = zilReserve.times(contributionPercentage).times(contributionAmount).dividedBy(userContribution.times(100))
652 | const expectedTokenAmount = tokenReserve.times(contributionPercentage).times(contributionAmount).dividedBy(userContribution.times(100))
653 | const minZilAmount = expectedZilAmount.times(BASIS).dividedToIntegerBy(BASIS + maxExchangeRateChange)
654 | const minTokenAmount = expectedTokenAmount.times(BASIS).dividedToIntegerBy(BASIS + maxExchangeRateChange)
655 |
656 | // Check contribution
657 | if (userContribution.lt(contributionAmount)) {
658 | throw new Error('Trying to remove more contribution than available.')
659 | }
660 |
661 | const deadline = this.deadlineBlock()
662 |
663 | console.log('sending remove liquidity txn..')
664 | const removeLiquidityTxn = await this.callContract(
665 | this.contract,
666 | 'RemoveLiquidity',
667 | [
668 | {
669 | vname: 'token_address',
670 | type: 'ByStr20',
671 | value: token.hash,
672 | },
673 | {
674 | vname: 'contribution_amount',
675 | type: 'Uint128',
676 | value: contributionAmount,
677 | },
678 | {
679 | vname: 'min_zil_amount',
680 | type: 'Uint128',
681 | value: minZilAmount.toString(),
682 | },
683 | {
684 | vname: 'min_token_amount',
685 | type: 'Uint128',
686 | value: minTokenAmount.toString(),
687 | },
688 | {
689 | vname: 'deadline_block',
690 | type: 'BNum',
691 | value: deadline.toString(),
692 | },
693 | ],
694 | {
695 | amount: new BN(0),
696 | ...this.txParams(),
697 | },
698 | true
699 | )
700 |
701 | if (removeLiquidityTxn.isRejected()) {
702 | throw new Error('Submitted transaction was rejected.')
703 | }
704 |
705 | const observeTxn = {
706 | hash: removeLiquidityTxn.id!,
707 | deadline,
708 | }
709 | await this.observeTx(observeTxn)
710 |
711 | return observeTxn
712 | }
713 |
714 | /**
715 | * Swaps ZIL or a ZRC-2 token with `tokenInID` for a corresponding ZIL or ZRC-2 token with `tokenOutID`.
716 | *
717 | * The exact amount of ZIL or ZRC-2 to be sent in (sold) is `tokenInAmountHuman`. The amount received is determined by the prevailing
718 | * exchange rate at the current AppState. The expected amount to be received can be given fetched by getExpectedOutput (NYI).
719 | *
720 | * The maximum additional slippage incurred due to fluctuations in exchange rate from when the
721 | * transaction is signed and when it is processed by the Zilliqa blockchain can be bounded by the
722 | * `maxAdditionalSlippage` variable.
723 | *
724 | * The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
725 | *
726 | * @param tokenInID is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts),
727 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
728 | * @param tokenOutID is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts),
729 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
730 | * @param tokenInAmountStr is the exact amount of tokens to be sent to Zilswap as a unitless string (without decimals).
731 | * @param maxAdditionalSlippage is the maximum additional slippage (on top of slippage due to constant product formula) that the
732 | * transition will allow before reverting.
733 | * @param recipientAddress is an optional recipient address for receiving the output of the swap in base16 (0x...) or bech32 (zil...).
734 | * Defaults to the sender address if `null` or undefined.
735 | */
736 | public async swapWithExactInput(
737 | tokenInID: string,
738 | tokenOutID: string,
739 | tokenInAmountStr: string,
740 | maxAdditionalSlippage: number = 200,
741 | recipientAddress: string | null = null
742 | ): Promise {
743 | this.checkAppLoadedWithUser()
744 |
745 | const tokenIn = this.getTokenDetails(tokenInID)
746 | const tokenOut = this.getTokenDetails(tokenOutID)
747 | const tokenInAmount = unitlessBigNumber(tokenInAmountStr)
748 | const { expectedOutput } = this.getOutputs(tokenIn, tokenOut, tokenInAmount)
749 | const minimumOutput = expectedOutput.times(BASIS).dividedToIntegerBy(BASIS + maxAdditionalSlippage)
750 | const parsedRecipientAddress = this.parseRecipientAddress(recipientAddress)
751 |
752 | await this.checkAllowedBalance(tokenIn, tokenInAmount)
753 |
754 | const deadline = this.deadlineBlock()
755 |
756 | let txn: { transition: string; args: Value[]; params: CallParams }
757 |
758 | if (tokenIn.hash === ZIL_HASH) {
759 | // zil to zrc2
760 | txn = {
761 | transition: 'SwapExactZILForTokens',
762 | args: [
763 | {
764 | vname: 'token_address',
765 | type: 'ByStr20',
766 | value: tokenOut.hash,
767 | },
768 | {
769 | vname: 'min_token_amount',
770 | type: 'Uint128',
771 | value: minimumOutput.toString(),
772 | },
773 | {
774 | vname: 'deadline_block',
775 | type: 'BNum',
776 | value: deadline.toString(),
777 | },
778 | {
779 | vname: 'recipient_address',
780 | type: 'ByStr20',
781 | value: parsedRecipientAddress,
782 | },
783 | ],
784 | params: {
785 | amount: new BN(tokenInAmount.toString()),
786 | ...this.txParams(),
787 | },
788 | }
789 | } else if (tokenOut.hash === ZIL_HASH) {
790 | // zrc2 to zil
791 | txn = {
792 | transition: 'SwapExactTokensForZIL',
793 | args: [
794 | {
795 | vname: 'token_address',
796 | type: 'ByStr20',
797 | value: tokenIn.hash,
798 | },
799 | {
800 | vname: 'token_amount',
801 | type: 'Uint128',
802 | value: tokenInAmount.toString(),
803 | },
804 | {
805 | vname: 'min_zil_amount',
806 | type: 'Uint128',
807 | value: minimumOutput.toString(),
808 | },
809 | {
810 | vname: 'deadline_block',
811 | type: 'BNum',
812 | value: deadline.toString(),
813 | },
814 | {
815 | vname: 'recipient_address',
816 | type: 'ByStr20',
817 | value: parsedRecipientAddress,
818 | },
819 | ],
820 | params: {
821 | amount: new BN(0),
822 | ...this.txParams(),
823 | },
824 | }
825 | } else {
826 | // zrc2 to zrc2
827 | txn = {
828 | transition: 'SwapExactTokensForTokens',
829 | args: [
830 | {
831 | vname: 'token0_address',
832 | type: 'ByStr20',
833 | value: tokenIn.hash,
834 | },
835 | {
836 | vname: 'token1_address',
837 | type: 'ByStr20',
838 | value: tokenOut.hash,
839 | },
840 | {
841 | vname: 'token0_amount',
842 | type: 'Uint128',
843 | value: tokenInAmount.toString(),
844 | },
845 | {
846 | vname: 'min_token1_amount',
847 | type: 'Uint128',
848 | value: minimumOutput.toString(),
849 | },
850 | {
851 | vname: 'deadline_block',
852 | type: 'BNum',
853 | value: deadline.toString(),
854 | },
855 | {
856 | vname: 'recipient_address',
857 | type: 'ByStr20',
858 | value: parsedRecipientAddress,
859 | },
860 | ],
861 | params: {
862 | amount: new BN(0),
863 | ...this.txParams(),
864 | },
865 | }
866 | }
867 |
868 | console.log('sending swap txn..')
869 | const swapTxn = await this.callContract(this.contract, txn.transition, txn.args, txn.params, true)
870 |
871 | if (swapTxn.isRejected()) {
872 | throw new Error('Submitted transaction was rejected.')
873 | }
874 |
875 | const observeTxn = {
876 | hash: swapTxn.id!,
877 | deadline,
878 | }
879 | await this.observeTx(observeTxn)
880 |
881 | return observeTxn
882 | }
883 |
884 | /**
885 | * Swaps ZIL or a ZRC-2 token with `tokenInID` for a corresponding ZIL or ZRC-2 token with `tokenOutID`.
886 | *
887 | * The exact amount of ZIL or ZRC-2 to be received (bought) is `tokenOutAmountHuman`. The amount sent is determined by the prevailing
888 | * exchange rate at the current AppState. The expected amount to be sent can be given fetched by getExpectedInput (NYI).
889 | *
890 | * The maximum additional slippage incurred due to fluctuations in exchange rate from when the
891 | * transaction is signed and when it is processed by the Zilliqa blockchain can be bounded by the
892 | * `maxAdditionalSlippage` variable.
893 | *
894 | * The transaction is added to the list of observedTxs, and the observer will be notified on change in tx status.
895 | *
896 | * @param tokenInID is the token ID to be sent to Zilswap (sold), which can be given by either it's symbol (defined in constants.ts),
897 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
898 | * @param tokenOutID is the token ID to be taken from Zilswap (bought), which can be given by either it's symbol (defined in constants.ts),
899 | * hash (0x...) or bech32 address (zil...). The hash for ZIL is represented by the ZIL_HASH constant.
900 | * @param tokenOutAmountStr is the exact amount of tokens to be received from Zilswap as a unitless string (withoout decimals).
901 | * @param maxAdditionalSlippage is the maximum additional slippage (on top of slippage due to constant product formula) that the
902 | * transition will allow before reverting.
903 | * @param recipientAddress is an optional recipient address for receiving the output of the swap in base16 (0x...) or bech32 (zil...).
904 | * Defaults to the sender address if `null` or undefined.
905 | */
906 | public async swapWithExactOutput(
907 | tokenInID: string,
908 | tokenOutID: string,
909 | tokenOutAmountStr: string,
910 | maxAdditionalSlippage: number = 200,
911 | recipientAddress: string | null = null
912 | ): Promise {
913 | this.checkAppLoadedWithUser()
914 |
915 | const tokenIn = this.getTokenDetails(tokenInID)
916 | const tokenOut = this.getTokenDetails(tokenOutID)
917 | const tokenOutAmount = unitlessBigNumber(tokenOutAmountStr)
918 | const { expectedInput } = this.getInputs(tokenIn, tokenOut, tokenOutAmount)
919 | const maximumInput = expectedInput.times(BASIS + maxAdditionalSlippage).dividedToIntegerBy(BASIS)
920 | const parsedRecipientAddress = this.parseRecipientAddress(recipientAddress)
921 |
922 | await this.checkAllowedBalance(tokenIn, maximumInput)
923 |
924 | const deadline = this.deadlineBlock()
925 |
926 | let txn: { transition: string; args: Value[]; params: CallParams }
927 |
928 | if (tokenIn.hash === ZIL_HASH) {
929 | // zil to zrc2
930 | txn = {
931 | transition: 'SwapZILForExactTokens',
932 | args: [
933 | {
934 | vname: 'token_address',
935 | type: 'ByStr20',
936 | value: tokenOut.hash,
937 | },
938 | {
939 | vname: 'token_amount',
940 | type: 'Uint128',
941 | value: tokenOutAmount.toString(),
942 | },
943 | {
944 | vname: 'deadline_block',
945 | type: 'BNum',
946 | value: deadline.toString(),
947 | },
948 | {
949 | vname: 'recipient_address',
950 | type: 'ByStr20',
951 | value: parsedRecipientAddress,
952 | },
953 | ],
954 | params: {
955 | amount: new BN(maximumInput.toString()),
956 | ...this.txParams(),
957 | },
958 | }
959 | } else if (tokenOut.hash === ZIL_HASH) {
960 | // zrc2 to zil
961 | txn = {
962 | transition: 'SwapTokensForExactZIL',
963 | args: [
964 | {
965 | vname: 'token_address',
966 | type: 'ByStr20',
967 | value: tokenIn.hash,
968 | },
969 | {
970 | vname: 'max_token_amount',
971 | type: 'Uint128',
972 | value: maximumInput.toString(),
973 | },
974 | {
975 | vname: 'zil_amount',
976 | type: 'Uint128',
977 | value: tokenOutAmount.toString(),
978 | },
979 | {
980 | vname: 'deadline_block',
981 | type: 'BNum',
982 | value: deadline.toString(),
983 | },
984 | {
985 | vname: 'recipient_address',
986 | type: 'ByStr20',
987 | value: parsedRecipientAddress,
988 | },
989 | ],
990 | params: {
991 | amount: new BN(0),
992 | ...this.txParams(),
993 | },
994 | }
995 | } else {
996 | // zrc2 to zrc2
997 | txn = {
998 | transition: 'SwapTokensForExactTokens',
999 | args: [
1000 | {
1001 | vname: 'token0_address',
1002 | type: 'ByStr20',
1003 | value: tokenIn.hash,
1004 | },
1005 | {
1006 | vname: 'token1_address',
1007 | type: 'ByStr20',
1008 | value: tokenOut.hash,
1009 | },
1010 | {
1011 | vname: 'max_token0_amount',
1012 | type: 'Uint128',
1013 | value: maximumInput.toString(),
1014 | },
1015 | {
1016 | vname: 'token1_amount',
1017 | type: 'Uint128',
1018 | value: tokenOutAmount.toString(),
1019 | },
1020 | {
1021 | vname: 'deadline_block',
1022 | type: 'BNum',
1023 | value: deadline.toString(),
1024 | },
1025 | {
1026 | vname: 'recipient_address',
1027 | type: 'ByStr20',
1028 | value: parsedRecipientAddress,
1029 | },
1030 | ],
1031 | params: {
1032 | amount: new BN(0),
1033 | ...this.txParams(),
1034 | },
1035 | }
1036 | }
1037 |
1038 | console.log('sending swap txn..')
1039 | const swapTxn = await this.callContract(this.contract, txn.transition, txn.args, txn.params, true)
1040 |
1041 | if (swapTxn.isRejected()) {
1042 | throw new Error('Submitted transaction was rejected.')
1043 | }
1044 |
1045 | const observeTxn = {
1046 | hash: swapTxn.id!,
1047 | deadline,
1048 | }
1049 | await this.observeTx(observeTxn)
1050 |
1051 | return observeTxn
1052 | }
1053 |
1054 | private getInputs(
1055 | tokenIn: TokenDetails,
1056 | tokenOut: TokenDetails,
1057 | tokenOutAmount: BigNumber
1058 | ): { epsilonInput: BigNumber; expectedInput: BigNumber } {
1059 | let expectedInput: BigNumber // the expected amount after slippage and fees
1060 | let epsilonInput: BigNumber // the zero slippage input
1061 |
1062 | if (tokenIn.hash === ZIL_HASH) {
1063 | // zil to zrc2
1064 | const { zilReserve, tokenReserve } = this.getReserves(tokenOut)
1065 | epsilonInput = tokenOutAmount.times(zilReserve).dividedToIntegerBy(tokenReserve)
1066 | expectedInput = this.getInputFor(tokenOutAmount, zilReserve, tokenReserve)
1067 | } else if (tokenOut.hash === ZIL_HASH) {
1068 | // zrc2 to zil
1069 | const { zilReserve, tokenReserve } = this.getReserves(tokenIn)
1070 | epsilonInput = tokenOutAmount.times(tokenReserve).dividedToIntegerBy(zilReserve)
1071 | expectedInput = this.getInputFor(tokenOutAmount, tokenReserve, zilReserve)
1072 | } else {
1073 | // zrc2 to zrc2
1074 | const { zilReserve: zr1, tokenReserve: tr1 } = this.getReserves(tokenOut)
1075 | const intermediateEpsilonInput = tokenOutAmount.times(zr1).dividedToIntegerBy(tr1)
1076 | const intermediateInput = this.getInputFor(tokenOutAmount, zr1, tr1)
1077 |
1078 | const { zilReserve: zr2, tokenReserve: tr2 } = this.getReserves(tokenIn)
1079 | epsilonInput = intermediateEpsilonInput.times(tr2).dividedToIntegerBy(zr2)
1080 | expectedInput = this.getInputFor(intermediateInput, tr2, zr2)
1081 | }
1082 |
1083 | return { epsilonInput, expectedInput }
1084 | }
1085 |
1086 | private getOutputs(
1087 | tokenIn: TokenDetails,
1088 | tokenOut: TokenDetails,
1089 | tokenInAmount: BigNumber
1090 | ): { epsilonOutput: BigNumber; expectedOutput: BigNumber } {
1091 | let epsilonOutput: BigNumber // the zero slippage output
1092 | let expectedOutput: BigNumber // the expected amount after slippage and fees
1093 |
1094 | if (tokenIn.hash === ZIL_HASH) {
1095 | // zil to zrc2
1096 | const { zilReserve, tokenReserve } = this.getReserves(tokenOut)
1097 | epsilonOutput = tokenInAmount.times(tokenReserve).dividedToIntegerBy(zilReserve)
1098 | expectedOutput = this.getOutputFor(tokenInAmount, zilReserve, tokenReserve)
1099 | } else if (tokenOut.hash === ZIL_HASH) {
1100 | // zrc2 to zil
1101 | const { zilReserve, tokenReserve } = this.getReserves(tokenIn)
1102 | epsilonOutput = tokenInAmount.times(zilReserve).dividedToIntegerBy(tokenReserve)
1103 | expectedOutput = this.getOutputFor(tokenInAmount, tokenReserve, zilReserve)
1104 | } else {
1105 | // zrc2 to zrc2
1106 | const { zilReserve: zr1, tokenReserve: tr1 } = this.getReserves(tokenIn)
1107 | const intermediateEpsilonOutput = tokenInAmount.times(zr1).dividedToIntegerBy(tr1)
1108 | const intermediateOutput = this.getOutputFor(tokenInAmount, tr1, zr1)
1109 |
1110 | const { zilReserve: zr2, tokenReserve: tr2 } = this.getReserves(tokenOut)
1111 | epsilonOutput = intermediateEpsilonOutput.times(tr2).dividedToIntegerBy(zr2)
1112 | expectedOutput = this.getOutputFor(intermediateOutput, zr2, tr2)
1113 | }
1114 |
1115 | return { epsilonOutput, expectedOutput }
1116 | }
1117 |
1118 | private getInputFor(outputAmount: BigNumber, inputReserve: BigNumber, outputReserve: BigNumber): BigNumber {
1119 | if (inputReserve.isZero() || outputReserve.isZero()) {
1120 | throw new Error('Reserve has 0 tokens.')
1121 | }
1122 | if (outputReserve.lte(outputAmount)) {
1123 | return new BigNumber('NaN')
1124 | }
1125 | const numerator = inputReserve.times(outputAmount).times(10000)
1126 | const denominator = outputReserve.minus(outputAmount).times(this.getAfterFeeBps())
1127 | return numerator.dividedToIntegerBy(denominator).plus(1)
1128 | }
1129 |
1130 | private getOutputFor(inputAmount: BigNumber, inputReserve: BigNumber, outputReserve: BigNumber): BigNumber {
1131 | if (inputReserve.isZero() || outputReserve.isZero()) {
1132 | throw new Error('Reserve has 0 tokens.')
1133 | }
1134 | const inputAfterFee = inputAmount.times(this.getAfterFeeBps())
1135 | const numerator = inputAfterFee.times(outputReserve)
1136 | const denominator = inputReserve.times(10000).plus(inputAfterFee)
1137 | return numerator.dividedToIntegerBy(denominator)
1138 | }
1139 |
1140 | private getAfterFeeBps(): string {
1141 | return this.getAppState().contractState.output_after_fee
1142 | }
1143 |
1144 | private getReserves(token: TokenDetails) {
1145 | const pool = this.getPool(token.hash)
1146 |
1147 | if (!pool) {
1148 | return {
1149 | zilReserve: new BigNumber(0),
1150 | tokenReserve: new BigNumber(0),
1151 | }
1152 | }
1153 |
1154 | const { zilReserve, tokenReserve } = pool
1155 | return { zilReserve, tokenReserve }
1156 | }
1157 |
1158 | public async callContract(
1159 | contract: Contract,
1160 | transition: string,
1161 | args: Value[],
1162 | params: CallParams,
1163 | toDs?: boolean
1164 | ): Promise {
1165 | if (this.walletProvider) {
1166 | // ugly hack for zilpay provider
1167 | const txn = await (contract as any).call(transition, args, params, toDs)
1168 | txn.id = txn.ID
1169 | txn.isRejected = function (this: { errors: any[]; exceptions: any[] }) {
1170 | return this.errors.length > 0 || this.exceptions.length > 0
1171 | }
1172 | return txn
1173 | } else {
1174 | return await contract.callWithoutConfirm(transition, args, params, toDs)
1175 | }
1176 | }
1177 |
1178 | public subscribeToAppChanges() {
1179 | // clear existing subscription, if any
1180 | this.subscription?.stop()
1181 |
1182 | const ziloContractHashes = Object.keys(this.zilos)
1183 | const subscription = this.zilliqa.subscriptionBuilder.buildEventLogSubscriptions(WSS[this.network], {
1184 | addresses: [this.contractHash, ...ziloContractHashes],
1185 | })
1186 |
1187 | subscription.subscribe({ query: MessageType.NEW_BLOCK })
1188 |
1189 | subscription.emitter.on(StatusType.SUBSCRIBE_EVENT_LOG, event => {
1190 | console.log('ws connected: ', event)
1191 | })
1192 |
1193 | subscription.emitter.on(MessageType.NEW_BLOCK, event => {
1194 | // console.log('ws new block: ', JSON.stringify(event, null, 2))
1195 | this.updateBlockHeight().then(() => this.updateObservedTxs())
1196 | })
1197 |
1198 | subscription.emitter.on(MessageType.EVENT_LOG, event => {
1199 | if (!event.value) return
1200 | // console.log('ws update: ', JSON.stringify(event, null, 2))
1201 | this.updateAppState()
1202 |
1203 | // update zilo states
1204 |
1205 | const ziloAddresses = Object.keys(this.zilos)
1206 | if (!ziloAddresses.length) return
1207 |
1208 | // loop through events to find updates in registered zilos
1209 | for (const item of event.value) {
1210 | const byStr20Address = `0x${item.address}`
1211 | const index = ziloAddresses.indexOf(byStr20Address)
1212 | if (index >= 0) {
1213 | this.zilos[byStr20Address].updateZiloState()
1214 |
1215 | // remove updated zilo contract from list
1216 | ziloAddresses.splice(index, 1)
1217 | }
1218 | }
1219 | })
1220 |
1221 | subscription.emitter.on(MessageType.UNSUBSCRIBE, event => {
1222 | console.log('ws disconnected: ', event)
1223 | this.subscription = null
1224 | })
1225 |
1226 | subscription.start()
1227 |
1228 | this.subscription = subscription
1229 | }
1230 |
1231 | private async loadTokenList() {
1232 | if (this.network === Network.TestNet) {
1233 | this.tokens['ZIL'] = 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz'
1234 | this.tokens['wZIL'] = 'zil1nzn3k336xwal7egdzgalqnclxtgu3dggxed85m'
1235 | this.tokens['ZWAP'] = 'zil1k2c3ncjfduj9jrhlgx03t2smd6p25ur56cfzgz'
1236 | this.tokens['gZIL'] = 'zil1fytuayks6njpze00ukasq3m4y4s44k79hvz8q5'
1237 | this.tokens['SWTH'] = 'zil1d6yfgycu9ythxy037hkt3phc3jf7h6rfzuft0s'
1238 | this.tokens['XSGD'] = 'zil10a9z324aunx2qj64984vke93gjdnzlnl5exygv'
1239 | this.tokens['ZLP'] = 'zil1du93l0dpn8wy40769raza23fjkvm868j9rjehn'
1240 | this.tokens['PORT'] = 'zil10v5nstu2ff9jsm7074wer6s6xtklh9xga7n8xc'
1241 | this.tokens['REDC'] = 'zil14jmjrkvfcz2uvj3y69kl6gas34ecuf2j5ggmye'
1242 | this.tokens['STREAM'] = 'zil10w9gdtaau3d5uzqescshuqn9fd23gpa82myjqc'
1243 | this.tokens['zDAI'] = 'zil1nnga67uer2vk0harvu345vz7vl3v0pta6vr3sf'
1244 | this.tokens['zETH'] = 'zil1j53x0y8myrcpy6u4n42qe0yuxn5t2ttedah8jp'
1245 | return
1246 | } else if (this.network === Network.MainNet) {
1247 | this.tokens['ZIL'] = 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz'
1248 | this.tokens['wZIL'] = 'zil1gvr0jgwfsfmxsyx0xsnhtlte4gks6r3yk8x5fn'
1249 | }
1250 |
1251 | try {
1252 | const res = await fetch('https://api.zilstream.com/tokens')
1253 | const tokens = await res.json()
1254 | interface ZilStreamToken {
1255 | symbol: string
1256 | address_bech32: string
1257 | }
1258 |
1259 | tokens.forEach((token: ZilStreamToken) => (this.tokens[token.symbol] = token.address_bech32.split(',')[0]))
1260 | } catch (err) {
1261 | console.warn('WARNING: failed to load token list from zilstream, using defaults only.\nError: ' + err)
1262 | }
1263 | }
1264 |
1265 | private async updateBlockHeight(): Promise {
1266 | const response = await this.zilliqa.blockchain.getNumTxBlocks()
1267 | const bNum = parseInt(response.result!, 10)
1268 | this.currentBlock = bNum
1269 |
1270 | for (const ziloAddress of Object.keys(this.zilos)) {
1271 | // updateBlockHeight should only trigger update if
1272 | // contract state will be changed, i.e. only when
1273 | // currentBlock === zilo init.start_block or init.end_block.
1274 | await this.zilos[ziloAddress].updateBlockHeight(bNum)
1275 | }
1276 | }
1277 |
1278 | private async updateAppState(): Promise {
1279 | // Get user address
1280 | const currentUser = this.walletProvider
1281 | ? // ugly hack for zilpay provider
1282 | this.walletProvider.wallet.defaultAccount.base16.toLowerCase()
1283 | : this.zilliqa.wallet.defaultAccount?.address?.toLowerCase() || null
1284 |
1285 | // Get the contract state
1286 | const requests: BatchRequest[] = []
1287 | const address = this.contractHash.replace('0x', '')
1288 | requests.push({ id: '1', method: 'GetSmartContractSubState', params: [address, 'output_after_fee', []], jsonrpc: '2.0' })
1289 | requests.push({ id: '2', method: 'GetSmartContractSubState', params: [address, 'pools', []], jsonrpc: '2.0' })
1290 | requests.push({ id: '3', method: 'GetSmartContractSubState', params: [address, 'total_contributions', []], jsonrpc: '2.0' })
1291 | const result = await sendBatchRequest(this.rpcEndpoint, requests)
1292 | const contractState = Object.values(result).reduce((a, i) => ({ ...a, ...i }), { balances: {} }) as ContractState
1293 |
1294 | if (currentUser) {
1295 | const requests2: BatchRequest[] = []
1296 | Object.keys(contractState.pools).forEach(token => {
1297 | requests2.push({
1298 | id: token,
1299 | method: 'GetSmartContractSubState',
1300 | params: [address, 'balances', [token, currentUser]],
1301 | jsonrpc: '2.0',
1302 | })
1303 | })
1304 | const result2 = await sendBatchRequest(this.rpcEndpoint, requests2)
1305 | Object.entries(result2).forEach(([token, mapOrNull]) => {
1306 | contractState.balances[token] = mapOrNull ? mapOrNull.balances[token] : {}
1307 | })
1308 | }
1309 |
1310 | // Get id of tokens that have liquidity pools
1311 | const poolTokenHashes = Object.keys(contractState.pools)
1312 | const defaultTokenHashes = Object.values(this.tokens).map((bech32: string) => this.getTokenAddresses(bech32).hash)
1313 | const tokenHashes = poolTokenHashes.concat(defaultTokenHashes.filter((item: string) => poolTokenHashes.indexOf(item) < 0))
1314 |
1315 | // Get token details
1316 | const tokens: { [key in string]: TokenDetails } = {}
1317 | const promises = tokenHashes.map(async hash => {
1318 | try {
1319 | const d = await this.fetchTokenDetails(hash)
1320 | if (d === null) return
1321 |
1322 | tokens[hash] = d
1323 | } catch (err) {
1324 | if (
1325 | (err as any).message?.startsWith('Could not retrieve contract init params') ||
1326 | (err as any).message?.startsWith('Address not contract address')
1327 | ) {
1328 | return
1329 | }
1330 | throw err
1331 | }
1332 | })
1333 | await Promise.all(promises)
1334 |
1335 |
1336 | // Get exchange rates
1337 | const pools: { [key in string]: Pool } = {}
1338 | tokenHashes.forEach(tokenHash => {
1339 | if (!contractState.pools[tokenHash]) return
1340 |
1341 | const [x, y] = contractState.pools[tokenHash]!.arguments
1342 | const zilReserve = new BigNumber(x)
1343 | const tokenReserve = new BigNumber(y)
1344 | const exchangeRate = zilReserve.dividedBy(tokenReserve)
1345 | const totalContribution = new BigNumber(contractState.total_contributions[tokenHash]!)
1346 | const poolBalances = contractState.balances[tokenHash]
1347 | const userContribution = new BigNumber(poolBalances && currentUser ? poolBalances[currentUser] || 0 : 0)
1348 | const contributionPercentage = userContribution.dividedBy(totalContribution).times(100)
1349 |
1350 | pools[tokenHash] = {
1351 | zilReserve,
1352 | tokenReserve,
1353 | exchangeRate,
1354 | totalContribution,
1355 | userContribution,
1356 | contributionPercentage,
1357 | }
1358 | })
1359 |
1360 |
1361 | // Set new state
1362 | this.appState = {
1363 | contractState,
1364 | tokens,
1365 | pools,
1366 | currentUser,
1367 | currentNonce: this.appState?.currentNonce || null,
1368 | currentBalance: this.appState?.currentBalance || null,
1369 | }
1370 | }
1371 |
1372 | private async updateBalanceAndNonce() {
1373 | if (this.appState?.currentUser) {
1374 | try {
1375 | const res: RPCBalanceResponse = (await this.zilliqa.blockchain.getBalance(this.appState.currentUser)).result
1376 | if (!res) {
1377 | this.appState.currentBalance = new BigNumber(0)
1378 | this.appState.currentNonce = 0
1379 | return
1380 | }
1381 | this.appState.currentBalance = new BigNumber(res.balance)
1382 | this.appState.currentNonce = parseInt(res.nonce, 10)
1383 | } catch (err) {
1384 | // ugly hack for zilpay non-standard API
1385 | if ((err as any).message === 'Account is not created') {
1386 | this.appState.currentBalance = new BigNumber(0)
1387 | this.appState.currentNonce = 0
1388 | }
1389 | }
1390 | }
1391 | }
1392 |
1393 | private async updateObservedTxs() {
1394 | const release = await this.observerMutex.acquire()
1395 | try {
1396 | const removeTxs: string[] = []
1397 | const promises = this.observedTxs.map(async (observedTx: ObservedTx) => {
1398 | try {
1399 | const result = await this.zilliqa.blockchain.getTransactionStatus(observedTx.hash)
1400 |
1401 | if (result && result.modificationState === 2) {
1402 | // either confirmed or rejected
1403 | const confirmedTxn = await this.zilliqa.blockchain.getTransaction(observedTx.hash)
1404 | const receipt = confirmedTxn.getReceipt()
1405 | const txStatus = confirmedTxn.isRejected() ? 'rejected' : receipt?.success ? 'confirmed' : 'rejected'
1406 | if (this.observer) this.observer(observedTx, txStatus, receipt)
1407 | removeTxs.push(observedTx.hash)
1408 | return
1409 | }
1410 | } catch (err) {
1411 | if ((err as any).code === -20) {
1412 | // "Txn Hash not Present"
1413 | console.warn(`tx not found in mempool: ${observedTx.hash}`)
1414 | } else {
1415 | console.warn('error fetching tx state')
1416 | console.error(err)
1417 | }
1418 | }
1419 | if (observedTx.deadline < this.currentBlock) {
1420 | // expired
1421 | console.log(`tx exceeded deadline: ${observedTx.deadline}, current: ${this.currentBlock}`)
1422 | if (this.observer) this.observer(observedTx, 'expired')
1423 | removeTxs.push(observedTx.hash)
1424 | }
1425 | })
1426 |
1427 | await Promise.all(promises)
1428 |
1429 | this.observedTxs = this.observedTxs.filter((tx: ObservedTx) => !removeTxs.includes(tx.hash))
1430 |
1431 | await this.updateBalanceAndNonce()
1432 | } finally {
1433 | release()
1434 | }
1435 | }
1436 |
1437 | private parseRecipientAddress(addr: string | null): string {
1438 | const address: string = addr === null ? this.getAppState().currentUser! : addr
1439 | if (address.substr(0, 2) === '0x') {
1440 | return address.toLowerCase()
1441 | } else if (address.length === 32) {
1442 | return `0x${address}`.toLowerCase()
1443 | } else if (address.substr(0, 3) === 'zil') {
1444 | return fromBech32Address(address).toLowerCase()
1445 | } else {
1446 | throw new Error('Invalid recipient address format!')
1447 | }
1448 | }
1449 |
1450 | private getTokenAddresses(id: string): { hash: string; address: string } {
1451 | let hash, address
1452 |
1453 | if (id.substr(0, 2) === '0x') {
1454 | hash = id.toLowerCase()
1455 | address = toBech32Address(hash)
1456 | } else if (id.substr(0, 3) === 'zil' && id.length > 3) {
1457 | address = id
1458 | hash = fromBech32Address(address).toLowerCase()
1459 | } else {
1460 | address = this.tokens[id]
1461 | hash = fromBech32Address(address).toLowerCase()
1462 | }
1463 |
1464 | return { hash, address }
1465 | }
1466 |
1467 | private getTokenDetails(id: string): TokenDetails {
1468 | const { hash } = this.getTokenAddresses(id)
1469 | if (!this.appState) {
1470 | throw new Error('App state not loaded, call #initialize first.')
1471 | }
1472 | if (!this.appState.tokens[hash]) {
1473 | throw new Error(`Could not find token details for ${id}`)
1474 | }
1475 | return this.appState.tokens[hash]
1476 | }
1477 |
1478 | public async fetchContractInit(contract: Contract): Promise {
1479 | // try to use cache first
1480 | const lsCacheKey = `contractInit:${contract.address!}`
1481 | if (isLocalStorageAvailable()) {
1482 | const result = localStorage.getItem(lsCacheKey)
1483 | if (result && result !== '""') {
1484 | try {
1485 | return JSON.parse(result)
1486 | } catch (e) {
1487 | console.error(e)
1488 | }
1489 | }
1490 | }
1491 | // motivation: workaround api.zilliqa.com intermittent connection issues.
1492 | try {
1493 | // some wallet providers throw an uncaught error when address is non-contract
1494 | const init = await new Zilliqa(this.rpcEndpoint).contracts.at(contract.address!).getInit()
1495 | if (init === undefined) throw new Error(`Could not retrieve contract init params ${contract.address}`)
1496 | if (!init) return null;
1497 |
1498 | if (isLocalStorageAvailable()) {
1499 | localStorage.setItem(lsCacheKey, JSON.stringify(init))
1500 | }
1501 | return init
1502 | } catch (err) {
1503 | if ((err as any).message === 'Network request failed') {
1504 | // make another fetch attempt after 800ms
1505 | return this.fetchContractInit(contract)
1506 | } else {
1507 | throw err
1508 | }
1509 | }
1510 | }
1511 |
1512 | private async fetchTokenDetails(id: string): Promise {
1513 | const { hash, address } = this.getTokenAddresses(id)
1514 |
1515 | if (!!this.appState?.tokens[hash]) return this.appState.tokens[hash]
1516 |
1517 | const contract = this.getContract(address)
1518 |
1519 | if (hash === ZIL_HASH) {
1520 | return { contract, address, hash, name: 'Zilliqa', symbol: 'ZIL', decimals: 12, whitelisted: true, registered: true }
1521 | }
1522 |
1523 | const init = await this.fetchContractInit(contract)
1524 | if (init === null) return null
1525 |
1526 | const decimalStr = init.find((e: Value) => e.vname === 'decimals').value as string
1527 | const decimals = parseInt(decimalStr, 10)
1528 | const name = init.find((e: Value) => e.vname === 'name').value as string
1529 | const symbol = init.find((e: Value) => e.vname === 'symbol').value as string
1530 | const registered = this.tokens[symbol] === address
1531 | const whitelisted = registered && WHITELISTED_TOKENS[this.network].includes(address)
1532 |
1533 | return { contract, address, hash, name, symbol, decimals, whitelisted, registered }
1534 | }
1535 |
1536 | private async checkAllowedBalance(token: TokenDetails, amount: BigNumber) {
1537 | // Check init
1538 | this.checkAppLoadedWithUser()
1539 | const user = this.appState!.currentUser!
1540 |
1541 | if (token.hash === ZIL_HASH) {
1542 | // Check zil balance
1543 | const zilBalance = this.appState!.currentBalance!
1544 | if (zilBalance.lt(amount)) {
1545 | throw new Error(`Insufficent ZIL in wallet.
1546 | Required: ${this.toUnit(token.hash, amount.toString()).toString()},
1547 | have: ${this.toUnit(token.hash, zilBalance.toString()).toString()}.`)
1548 | }
1549 | } else {
1550 | // Check zrc-2 balance
1551 | const requests: BatchRequest[] = []
1552 | const address = token.contract.address!.replace('0x', '')
1553 | requests.push({ id: 'balances', method: 'GetSmartContractSubState', params: [address, 'balances', [user!]], jsonrpc: '2.0' })
1554 | requests.push({
1555 | id: 'allowances',
1556 | method: 'GetSmartContractSubState',
1557 | params: [address, 'allowances', [user!, this.contractHash]],
1558 | jsonrpc: '2.0',
1559 | })
1560 | const result = await sendBatchRequest(this.rpcEndpoint, requests)
1561 | const balance = new BigNumber(result.balances?.balances[user] || 0)
1562 | if (balance.lt(amount)) {
1563 | throw new Error(`Insufficent tokens in wallet.
1564 | Required: ${this.toUnit(token.hash, amount.toString()).toString()},
1565 | have: ${this.toUnit(token.hash, balance.toString()).toString()}.`)
1566 | }
1567 | const allowance = new BigNumber(result.allowances?.allowances[user]?.[this.contractHash] || 0)
1568 | if (allowance.lt(amount)) {
1569 | throw new Error(`Tokens need to be approved first.
1570 | Required: ${this.toUnit(token.hash, amount.toString()).toString()},
1571 | approved: ${this.toUnit(token.hash, allowance.toString()).toString()}.`)
1572 | }
1573 | }
1574 | }
1575 |
1576 | public checkAppLoadedWithUser() {
1577 | // Check init
1578 | if (!this.appState) {
1579 | throw new Error('App state not loaded, call #initialize first.')
1580 | }
1581 |
1582 | // Check user address
1583 | if (this.appState!.currentUser === null) {
1584 | throw new Error('No wallet connected.')
1585 | }
1586 |
1587 | // Check wallet account
1588 | if (this.walletProvider && this.walletProvider.wallet.defaultAccount.base16.toLowerCase() !== this.appState!.currentUser) {
1589 | throw new Error('Wallet user has changed, please reconnect.')
1590 | }
1591 |
1592 | // Check network is correct
1593 | if (this.walletProvider && this.walletProvider.wallet.net.toLowerCase() !== this.network.toLowerCase()) {
1594 | throw new Error('Wallet is connected to wrong network.')
1595 | }
1596 | }
1597 |
1598 | public txParams(): TxParams & { nonce: number } {
1599 | return {
1600 | nonce: this.nonce(),
1601 | ...this._txParams,
1602 | }
1603 | }
1604 |
1605 | public getCurrentBlock(): number {
1606 | return this.currentBlock
1607 | }
1608 |
1609 | public deadlineBlock(): number {
1610 | return this.currentBlock + this.deadlineBuffer!
1611 | }
1612 |
1613 | private nonce(): number {
1614 | return this.appState!.currentNonce! + this.observedTxs.length + 1
1615 | }
1616 |
1617 | private validateMaxExchangeRateChange(maxExchangeRateChange: number) {
1618 | if (maxExchangeRateChange % 1 !== 0 || maxExchangeRateChange >= BASIS || maxExchangeRateChange < 0) {
1619 | throw new Error(`MaxExchangeRateChange ${maxExchangeRateChange} must be an integer between 0 and ${BASIS + 1}.`)
1620 | }
1621 | }
1622 | }
1623 |
--------------------------------------------------------------------------------