├── .eslintrc ├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── src ├── config.js ├── fn │ ├── checkFields.js │ └── toHex.js ├── index.js ├── rpc.js ├── socket.js └── viewblock.js ├── test └── index.js └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["zavatta", "prettier"], 3 | "rules": { 4 | "no-console": 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | 3 | .nyc_output/ 4 | dist/ 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | printWidth: 100 2 | semi: false 3 | singleQuote: true 4 | trailingComma: all 5 | arrowParens: avoid 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10 4 | - 12 5 | - 14 6 | before_install: 7 | - yarn config set ignore-engines true 8 | script: 9 | - yarn lint 10 | - yarn report 11 | env: 12 | global: 13 | secure: fZnsFvSny6a5Zag9xW36z7eSUl4CVI17gI7cpgULpzvEYe4aj5KTB82y9v6oIxhuvkgxVQpcsKstt6MNn2dEaTcfDE0O12uqPNNHmVEHiw0N9FSGeJEWgnJJSR3yx8noiZ4d5PDqqixV7acIcXRXfPTpy91Dne/EAf0Apj6fRxWg/P3W5UaZFIt8x7/vCAo1QYMo4YBWrvp3LlCFiRnc5Mc5ilB3RsOIbQp964slEWRSrKXVwKBeqZW5m1QSIv8abtD9OI3aV19TKYxKoP0TUKIf6bdQG8QNKgmUlij2YDIu8/gHIE3Gr5ovE9lxHL8IEdzDX4mehXgH0tEjZbucK2SbWhDET44uQI48xaoy8RT2FVRC5jCmGcOlh+6q8EJFF9lBnVkXmOnOY6KQAZMFGFWpOZFE2yMI/0KhTg1ZA0mY23ZO1rhdeDcKU3YOGFNBKDdPHa2ooXRSkVmllAy7KTk3XBPGSShFrM2S7IHeZH5dp+xWjiNKoKXMJlt+qGZTv8wBRucLBUG4SqsaDFCMhQisiRYa6eXDj3BUh82RYifr1nqu1IV8LD4OipV74GxVhFua/NLqqtqUJGVuJIoF2Ok63u7UjuS6PHG/UzM9/9lk8g5NonObXFlwbkZHsqiVFxAHK36PWOh1mZDTQSDrjMlgvGNtyL5Lhezy6jSfQD0= 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ashlar Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @zilliqa-js/viewblock [![build](https://img.shields.io/travis/Ashlar/zilliqa-js-viewblock/master.svg?style=flat-square)](https://travis-ci.org/Ashlar/zilliqa-js-viewblock) [![cover](https://img.shields.io/coveralls/Ashlar/zilliqa-js-viewblock.svg?style=flat-square)](https://coveralls.io/github/Ashlar/zilliqa-js-viewblock) 2 | 3 | > A library interfacing with the Zilliqa blockchain and ViewBlock's APIs 4 | 5 | ### Table of Contents 6 | 7 | - [Setup](#setup) 8 | * [Client](#client) 9 | - [Transactions](#transactions) 10 | * [getTx](#gettx) 11 | * [getPendingTxs](#getpendingtxs) 12 | * [createTx](#createtx) 13 | - [Addresses](#addresses) 14 | * [getAddress](#getaddress) 15 | * [getAddressTxs](#getaddresstxs) 16 | * [getAddressTokenTxs](#getaddresstokentxs) 17 | - [Smart Contracts](#smart-contracts) 18 | * [getSCInit](#getscinit) 19 | * [getSCState](#getscstate) 20 | - [Blocks](#blocks) 21 | * [getBlock](#getblock) 22 | * [getBlockTxs](#getblocktxs) 23 | - [Subscriptions](#subscriptions) 24 | * [block](#block) 25 | * [transaction](#transaction) 26 | * [addressTx](#addressTx) 27 | * [contractEvent](#contractEvent) 28 | - [Misc](#misc) 29 | * [getGasPrice](#getgasprice) 30 | 31 | ### Setup 32 | 33 | Install using your favorite package manager. 34 | 35 | ``` 36 | yarn add @zilliqa-js/viewblock 37 | ``` 38 | 39 | #### Client 40 | 41 | The library client is exposed as the default export in the form of a factory function. 42 | 43 | > :warning: Although not enforced, not providing an `apiKey` will disable most of the methods of the library. 44 | Get one on [ViewBlock](https://viewblock.io) by creating an account and a key in your settings. 45 | 46 | | Param | Type | Required | Default | Values | 47 | | -------- | -------- | -------- | --------- | -------------------- | 48 | | apiKey | `String` | `false` | | | 49 | | agent | `Agent` | `false` | `null` | `http.Agent` | 50 | | network | `String` | `false` | `mainnet` | `mainnet`, `testnet` | 51 | 52 | ```js 53 | import Zilliqa from '@zilliqa-js/viewblock' 54 | 55 | const client = Zilliqa({ 56 | apiKey: 'xxx', 57 | }) 58 | ``` 59 | 60 | You can obviously use basic commonjs requires too: 61 | 62 | ```js 63 | const Zilliqa = require('@zilliqa-js/viewblock') 64 | ``` 65 | 66 | The `agent` parameter allows to use any `http.Agent` implementation of your choice. 67 | As an example, [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) could be 68 | provided to proxy the requests. 69 | 70 | These 3 parameters passed when creating the client act as a global default configuration, but 71 | can be overriden on each individual call for convenience purposes. As an example: 72 | 73 | ```js 74 | const client = Zilliqa({ apiKey: 'xxx' }) 75 | 76 | client.getBlock(42, { network: 'testnet' }) 77 | client.getGasPrice({ network: 'testnet' }) 78 | ``` 79 | 80 | Here, although the client defaults to `mainnet`, we override it specifically for these two calls. 81 | It won't affect subsequent methods, as they will use the default network. 82 | 83 | All the methods return a `Promise`, making it `await` compatible. 84 | 85 | ### Transactions 86 | 87 | #### getTx 88 | 89 | Get one transaction by hash. 90 | 91 | 92 | ```js 93 | await client.getTx('0x65fd90f1fc2d3b631a0cf6a77be9947e9f4559d9ece9b9a1eef170d593bd9213') 94 | ``` 95 | 96 |
97 | Output 98 | 99 | ```js 100 | { 101 | hash: '0x65fd90f1fc2d3b631a0cf6a77be9947e9f4559d9ece9b9a1eef170d593bd9213', 102 | blockHeight: 577008, 103 | from: 'zil1kshhphza3vlyfamjchamk2d3j022a55kn6es38', 104 | to: 'zil1z3zky3kv20f37z3wkq86qfy00t4a875fxxw7sw', 105 | value: '29000000000000', 106 | fee: '1000000000', 107 | timestamp: 1590005268574, 108 | signature: 109 | '0xEA74CF5062954368ECBEB9EA00014C9F78590391703E0DCEF002FAB50D30C1147D84BDC8A1703A33181CD3BDE315E6B28627EB0266DCD0D3CB886130B06312D1', 110 | nonce: 1, 111 | receiptSuccess: true, 112 | data: null, 113 | internalTransfers: [], 114 | events: [], 115 | transitions: [] 116 | } 117 | ``` 118 | 119 |
120 | 121 | #### getPendingTxs 122 | 123 | > :warning: Pending implementation. 124 | 125 | #### createTx 126 | 127 | Create a transaction using the JSON RPC. Follow the [create transaction](https://apidocs.zilliqa.com/#createtransaction) 128 | transaction parameters documentation to get a better idea on how to construct it. 129 | 130 | ```js 131 | await client.createTx({ 132 | version: 65537, 133 | nonce: 1, 134 | toAddr: '0x4BAF5faDA8e5Db92C3d3242618c5B47133AE003C', 135 | amount: '1000000000000', 136 | pubKey: '0205273e54f262f8717a687250591dcfb5755b8ce4e3bd340c7abefd0de1276574', 137 | gasPrice: '1000000000', 138 | gasLimit: '1', 139 | code: '', 140 | data: '', 141 | signature: '29ad673848dcd7f5168f205f7a9fcd1e8109408e6c4d7d03e4e869317b9067e636b216a32314dd37176c35d51f9d4c24e0e519ba80e66206457c83c9029a490d', 142 | priority: false 143 | }) 144 | ``` 145 | 146 |
147 | Output 148 | 149 | ```js 150 | { 151 | msg: 'Non-contract txn, sent to shard', 152 | hash: '2d1eea871d8845472e98dbe9b7a7d788fbcce226f52e4216612592167b89042c' 153 | } 154 | ``` 155 | 156 |
157 | 158 | ### Addresses 159 | 160 | #### getAddress 161 | 162 | Retrieve one address by hash. 163 | 164 | ```js 165 | await client.getAddress('zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', { network: 'testnet' }) 166 | ``` 167 | 168 |
169 | Output 170 | 171 | ```js 172 | { 173 | hash: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 174 | balance: '999962495000000000', 175 | nonce: 4, 176 | type: 'normal' 177 | } 178 | ``` 179 | 180 |
181 | 182 | #### getAddressTxs 183 | 184 | Get the transactions made by an address. 185 | 186 | | Param | Type | Required | Default | 187 | | -------- | -------- | -------- | --------- | 188 | | page | `Number` | `false` | `1` | 189 | 190 | ```js 191 | await client.getAddressTxs('zil16awfafxs789g8nthnm5s9p4l8vnxs5zpfr3upr', { page: 1 }) 192 | ``` 193 | 194 |
195 | Output 196 | 197 | ```js 198 | { 199 | docs: [ 200 | { 201 | hash: '0xced4731d535e1b0ba72d562d6c1dfd0ef71d1189abfa1ead8341667ca22aa01b', 202 | blockHeight: 1128974, 203 | from: 'zil15wglkgh0vht9zeaqe9x4axmw4nkw2mr79z6g3x', 204 | to: 'zil16awfafxs789g8nthnm5s9p4l8vnxs5zpfr3upr', 205 | value: '25000000000000', 206 | fee: '3026000000000', 207 | timestamp: 1581304554974, 208 | signature: 209 | '0x2E293AB15F747F90292D1262731DCD597008C456266E654466823728F92BDC6F6FB7E819C9A1518DA827C0031E1A7DD349FA920B04C420359053808E3E177648', 210 | direction: 'in', 211 | nonce: 312, 212 | receiptSuccess: true, 213 | data: '{"_tag": "request", "params": []}', 214 | internalTransfers: [ 215 | { 216 | from: 'zil16awfafxs789g8nthnm5s9p4l8vnxs5zpfr3upr', 217 | to: 'zil1mejpsqd5cw589xyq3llzvrk0nvetm9v0l5kcn7', 218 | value: '25000000000000', 219 | direction: 'in', 220 | depth: '0,0', 221 | }, 222 | ], 223 | events: [ 224 | { 225 | address: 'zil1mejpsqd5cw589xyq3llzvrk0nvetm9v0l5kcn7', 226 | name: 'request', 227 | details: 228 | 'request (String msg, Uint32 id, ByStr20 from, Uint32 reqtype, Uint128 gaslimit, Uint128 gasprice, String paramdata, Uint128 fee)', 229 | params: { 230 | msg: 'send request success', 231 | id: '10', 232 | from: '0xa391fb22ef65d65167a0c94d5e9b6eacece56c7e', 233 | reqtype: '1', 234 | gaslimit: '20000', 235 | gasprice: '1000000000', 236 | paramdata: 237 | "{'url':'https://samples.openweathermap.org/data/2.5/weather',\n 'params':{'q':'London,uk','appid':'b6907d289e10d714a6e88b30761fae22'}}", 238 | fee: '3999000000000', 239 | }, 240 | }, 241 | ], 242 | transitions: [ 243 | { 244 | addr: '0xd75c9ea4d0f1ca83cd779ee90286bf3b26685041', 245 | depth: 0, 246 | msg: { 247 | _amount: '25000000000000', 248 | _recipient: '0xde641801b4c3a87298808ffe260ecf9b32bd958f', 249 | _tag: 'request', 250 | params: [ 251 | { 252 | type: 'ByStr20', 253 | value: '0xa391fb22ef65d65167a0c94d5e9b6eacece56c7e', 254 | vname: 'user_addr', 255 | }, 256 | { 257 | type: 'Uint32', 258 | value: '1', 259 | vname: 'request_type', 260 | }, 261 | { 262 | type: 'String', 263 | value: 264 | "{'url':'https://samples.openweathermap.org/data/2.5/weather',\n 'params':{'q':'London,uk','appid':'b6907d289e10d714a6e88b30761fae22'}}", 265 | vname: 'param_data', 266 | }, 267 | { 268 | type: 'Uint128', 269 | value: '1000000000', 270 | vname: 'gas_price', 271 | }, 272 | { 273 | type: 'Uint128', 274 | value: '20000', 275 | vname: 'gas_limit', 276 | }, 277 | { 278 | type: 'String', 279 | value: 'callback', 280 | vname: 'callback_func', 281 | }, 282 | ], 283 | }, 284 | }, 285 | { 286 | addr: '0xde641801b4c3a87298808ffe260ecf9b32bd958f', 287 | depth: 1, 288 | msg: { 289 | _amount: '25000000000000', 290 | _recipient: '0xc4818b8c0d0c2ae775e8ed1998d72c7aa0743063', 291 | _tag: '', 292 | params: [], 293 | }, 294 | }, 295 | ], 296 | }, 297 | { 298 | hash: '0x6bc8fcd7a14bef419eae03d8d9ac68de0bcc279a50a86fe3a00c24d99833c5e3', 299 | blockHeight: 1064704, 300 | from: 'zil10h9339zp277h8gmdhds6zuq0elgpsf5qga4qvh', 301 | to: 'zil16awfafxs789g8nthnm5s9p4l8vnxs5zpfr3upr', 302 | value: '0', 303 | fee: '2590000000000', 304 | timestamp: 1579266403473, 305 | signature: 306 | '0x5A72F6B4826EBCE69F62DB2D85991D780A54ED4C459BB0732EB1F8B2C77DDE8F2B3DB6F022797561809E30310E830E755A98EDAE526F96675A76137815BBF81C', 307 | direction: 'in', 308 | nonce: 208, 309 | receiptSuccess: true, 310 | data: 311 | '[{"vname": "_scilla_version", "type": "Uint32", "value": "0"}, {"vname": "owner", "type": "ByStr20", "value": "0x7dcb18944157bd73a36dbb61a1700fcfd0182680"}]', 312 | internalTransfers: [], 313 | events: [], 314 | transitions: [], 315 | }, 316 | ], 317 | page: 1, 318 | totalPages: 1, 319 | total: 2, 320 | limit: 25, 321 | nextPage: null, 322 | prevPage: null 323 | } 324 | ``` 325 | 326 |
327 | 328 | #### getAddressTokenTxs 329 | 330 | Get the token transactions associated with an address. Note `token` can be specified 331 | to filter for specific token transactions. 332 | 333 | | Param | Type | Required | Default | 334 | | -------- | -------- | -------- | --------- | 335 | | page | `Number` | `false` | `1` | 336 | | token | `String` | `false` | | 337 | 338 | ```js 339 | await client.getAddressTokenTxs('zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', { 340 | page: 1, 341 | token: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 342 | }) 343 | ``` 344 | 345 |
346 | Output 347 | 348 | ```js 349 | { 350 | docs: [ 351 | { 352 | hash: '0x3c60b3194a175fa4d484fb3074f3bd7ba9bfd62c7d6dc1da6f86a4c948bb7f92', 353 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 354 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 355 | value: '0.02', 356 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 357 | blockHeight: 1776290, 358 | timestamp: 1599139330519, 359 | direction: 'in', 360 | }, 361 | { 362 | hash: '0x7b7555d456cf4415c1f58af26a8b8788ebb3431c41ccb893d0c3a06c2157c064', 363 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 364 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 365 | value: '0', 366 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 367 | blockHeight: 1776298, 368 | timestamp: 1599139497307, 369 | direction: 'in', 370 | }, 371 | { 372 | hash: '0xc5f582866251b022ac32e98a6e4598319288234ef8722b04bf5c285122094af1', 373 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 374 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 375 | value: '0.01', 376 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 377 | blockHeight: 1776348, 378 | timestamp: 1599140579375, 379 | direction: 'in', 380 | }, 381 | { 382 | hash: '0x7b1356842d1e595384ee2de38df7fc24ed1a57f5df65c3cc23c7b4f02415cdeb', 383 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 384 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 385 | value: '0.04', 386 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 387 | blockHeight: 1776384, 388 | timestamp: 1599141333323, 389 | direction: 'in', 390 | }, 391 | { 392 | hash: '0x7e1da8fb622bfb6203d65573cb4367077f85fd65b90697fd82ca3e8e145b0841', 393 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 394 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 395 | value: '0', 396 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 397 | blockHeight: 1776390, 398 | timestamp: 1599141458698, 399 | direction: 'in', 400 | }, 401 | { 402 | hash: '0xe0094c46b4bd1fb0ef0fbb623c9d0431f835d850a28e8a5b81886ca7e91061b2', 403 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 404 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 405 | value: '0', 406 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 407 | blockHeight: 1776704, 408 | timestamp: 1599148162726, 409 | direction: 'in', 410 | }, 411 | { 412 | hash: '0x785f21e312a10307907ac3f06da0d6056056082fa0265ef64fa8b402676425ab', 413 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 414 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 415 | value: '0.0196969696', 416 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 417 | blockHeight: 1776986, 418 | timestamp: 1599154120380, 419 | direction: 'in', 420 | }, 421 | ], 422 | page: 1, 423 | totalPages: 1, 424 | total: 7, 425 | limit: 25, 426 | nextPage: null, 427 | prevPage: null 428 | } 429 | ``` 430 | 431 |
432 | 433 | ### Smart Contracts 434 | 435 | #### getSCInit 436 | 437 | Get the init parameters of a given smart contract. 438 | 439 | ```js 440 | await client.getSCInit('zil1cm2x24v7807w7yjvmkz0am0y37vkys8lwtxsth') 441 | ``` 442 | 443 |
444 | Output 445 | 446 | ```js 447 | [ 448 | { 449 | "type": "Uint32", 450 | "value": "0", 451 | "vname": "_scilla_version" 452 | }, 453 | { 454 | "type": "List ByStr20", 455 | "value": { 456 | "argtypes": [ 457 | "ByStr20" 458 | ], 459 | "arguments": [ 460 | "0x5B42879E9c497EdAE5b3A7B3DCfD40920feC0599", 461 | { 462 | "argtypes": [ 463 | "ByStr20" 464 | ], 465 | "arguments": [ 466 | "0x98c656454b4E27762ab62D176246f31def011875", 467 | { 468 | "argtypes": [ 469 | "ByStr20" 470 | ], 471 | "arguments": [ 472 | "0x09EE3238528247354862700f5C00A349a499badB", 473 | { 474 | "argtypes": [ 475 | "ByStr20" 476 | ], 477 | "arguments": [ 478 | "0x705856236100A28106BD3b760ADaFDea7F990dFB", 479 | { 480 | "argtypes": [ 481 | "ByStr20" 482 | ], 483 | "arguments": [], 484 | "constructor": "Nil" 485 | } 486 | ], 487 | "constructor": "Cons" 488 | } 489 | ], 490 | "constructor": "Cons" 491 | } 492 | ], 493 | "constructor": "Cons" 494 | } 495 | ], 496 | "constructor": "Cons" 497 | }, 498 | "vname": "owners_list" 499 | }, 500 | { 501 | "type": "Uint32", 502 | "value": "2", 503 | "vname": "required_signatures" 504 | }, 505 | { 506 | "type": "BNum", 507 | "value": "300675", 508 | "vname": "_creation_block" 509 | }, 510 | { 511 | "type": "ByStr20", 512 | "value": "0xc6d465559e3bfcef124cdd84feede48f996240ff", 513 | "vname": "_this_address" 514 | } 515 | ] 516 | ``` 517 | 518 |
519 | 520 | #### getSCState 521 | 522 | Get the state or sub-state of a smart contract. 523 | 524 | | Param | Type | Required | 525 | | ------------------ | ----------------- | -------- | 526 | | payload | `String`/`Object` | `true` | 527 | | payload.address | `String` | `false` | 528 | | payload.name | `String` | `false` | 529 | | payload.indices | `Array` | `false` | 530 | 531 | ```js 532 | await client.getSCState('zil1cm2x24v7807w7yjvmkz0am0y37vkys8lwtxsth') 533 | ``` 534 | 535 |
536 | Output 537 | 538 | ```js 539 | { 540 | _balance: "762000001000000000000", 541 | contract_valid: { 542 | argtypes: [], 543 | arguments: [], 544 | constructor: 'Valid' 545 | }, 546 | owners: { 547 | '0x09ee3238528247354862700f5c00a349a499badb': { 548 | argtypes: [], 549 | arguments: [], 550 | constructor: 'True' 551 | }, 552 | '0x5b42879e9c497edae5b3a7b3dcfd40920fec0599': { 553 | argtypes: [], 554 | arguments: [], 555 | constructor: 'True' 556 | }, 557 | '0x705856236100a28106bd3b760adafdea7f990dfb': { 558 | "argtypes": [], 559 | "arguments": [], 560 | "constructor": 'True' 561 | }, 562 | '0x98c656454b4e27762ab62d176246f31def011875': { 563 | argtypes: [], 564 | arguments: [], 565 | constructor: 'True' 566 | } 567 | }, 568 | signature_counts: {}, 569 | signatures: {}, 570 | transactionCount: '0', 571 | transactions: {} 572 | } 573 | ``` 574 | 575 |
576 | 577 | If you want to retrieve only part of the contract state, send an object payload and provide the optional `name` or `indices` parameters: 578 | 579 | ```js 580 | await client.getSCState({ 581 | address: 'zil1cm2x24v7807w7yjvmkz0am0y37vkys8lwtxsth', 582 | name: 'owners', 583 | indices: ['0x09ee3238528247354862700f5c00a349a499badb'], 584 | }) 585 | ``` 586 | 587 |
588 | Output 589 | 590 | ```js 591 | { 592 | owners: { 593 | '0x09ee3238528247354862700f5c00a349a499badb': { 594 | argtypes: [], 595 | arguments: [], 596 | constructor: 'True' 597 | } 598 | } 599 | } 600 | ``` 601 | 602 |
603 | 604 | ### Blocks 605 | 606 | #### getBlock 607 | 608 | Retrieve one block information by its height. 609 | 610 | ```js 611 | await client.getBlock(59903) 612 | ``` 613 | 614 |
615 | Output 616 | 617 | ```js 618 | { 619 | height: 59903, 620 | timestamp: 1554172478877, 621 | txCount: 890, 622 | dsHeight: 600, 623 | gasLimit: '1500000', 624 | gasUsed: '890', 625 | minerPubKey: '0x0227939F72067FE1AC79276CE779A27C560391A660D42FDE0102229964F1C2C511', 626 | microBlocks: [ 627 | { 628 | hash: '3b7041c131b80fc8ab6aa65fc1590272f08ce13c0919a621563e90ab544f948c', 629 | shardId: 0, 630 | txRootHash: 'ed461421c0a698ed009aeefddc5a4d1c0a03570081931efdc75d5e5d54e4e017' 631 | }, 632 | { 633 | hash: 'ed64ecba273c3366e4fc558c218f8d67d7c1e2ccf77dc10379f41fb279af70ee', 634 | shardId: 1, 635 | txRootHash: '692374ea2ad4ac5240ec8ee89d9d3a5899a6ed8c1c25d96ed9ad2066ce0539c5' 636 | }, 637 | { 638 | hash: '4f3dcf4078ecc0e4cae69068565b72fbd47012daa0f858bafb028edf1536a3ff', 639 | shardId: 2, 640 | txRootHash: '0000000000000000000000000000000000000000000000000000000000000000' 641 | } 642 | ], 643 | stateDeltaHash: '6e62ee3e1af7927a1c9ee8ec375951770b38a34305f3eae772f673942dfb5923', 644 | stateRootHash: '6dde256dd2be07ef69906a31790c539266b410ffdfba64198e6f16ed7b62d888' 645 | } 646 | ``` 647 | 648 |
649 | 650 | #### getBlockTxs 651 | 652 | Retrieve the transactions confirmed in a block. 653 | 654 | | Param | Type | Required | Default | 655 | | -------- | -------- | -------- | --------- | 656 | | page | `Number` | `false` | `1` | 657 | 658 | ```js 659 | await client.getBlockTxs(59903, { page: 1 }) 660 | ``` 661 | 662 |
663 | Output 664 | 665 | ```js 666 | { 667 | docs: [ 668 | { 669 | hash: '0xfe55cf4954507a5b809cdfa8725a499d0656e3644838c2cd826eaa57a8e48f62', 670 | from: 'zil16ttxueshqnnun5hlen8ql8q5rvx7vvtm63ccna', 671 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 672 | value: '703140978601111', 673 | fee: '1000000000', 674 | timestamp: 1554172478877, 675 | nonce: 1, 676 | receiptSuccess: true, 677 | events: [], 678 | data: null, 679 | internalTransfers: [], 680 | transitions: [] 681 | }, 682 | { 683 | hash: '0xfd816a3d5118d7a21e4a56d2c91f06a30315e0ba8851cfdaf6b9a6c61fc524fd', 684 | from: 'zil1mtzdp32j5jm7hfj4n3mxzf24lt779mf93pw0dy', 685 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 686 | value: '1887350370678611', 687 | fee: '1000000000', 688 | timestamp: 1554172478877, 689 | nonce: 1, 690 | receiptSuccess: true, 691 | events: [], 692 | data: null, 693 | internalTransfers: [], 694 | transitions: [] 695 | }, 696 | { 697 | hash: '0xfd0448f629b93038b5e4cddd51d2b90f9682882cd40ef3ee465bc4f0e55e357b', 698 | from: 'zil19n6d3h6a3jalkucg9aue8m3gaqdjt3ltayktml', 699 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 700 | value: '749245402553526', 701 | fee: '1000000000', 702 | timestamp: 1554172478877, 703 | nonce: 1, 704 | receiptSuccess: true, 705 | events: [], 706 | data: null, 707 | internalTransfers: [], 708 | transitions: [] 709 | }, 710 | { 711 | hash: '0xfbc097da285c436171d4724c3a4fbf6aa6c309868bf717aa6bebf6bab09cdc10', 712 | from: 'zil1ph8pkmdgche9y9n529qdu9z4q772440eaae5pe', 713 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 714 | value: '569420970197693', 715 | fee: '1000000000', 716 | timestamp: 1554172478877, 717 | nonce: 1, 718 | receiptSuccess: true, 719 | events: [], 720 | data: null, 721 | internalTransfers: [], 722 | transitions: [] 723 | }, 724 | { 725 | hash: '0xfa8bf7715d4cbe23524e72ab7920efac722be6284445dccdade4b0b6f6a4caac', 726 | from: 'zil1ujn9s37yc7hs0eklnwfnhrkgvtqljdwafgxjm2', 727 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 728 | value: '426896695040558', 729 | fee: '1000000000', 730 | timestamp: 1554172478877, 731 | nonce: 1, 732 | receiptSuccess: true, 733 | events: [], 734 | data: null, 735 | internalTransfers: [], 736 | transitions: [] 737 | }, 738 | { 739 | hash: '0xf9072f1aafad82a8f144b32b4404f685649fbcc82518d3c731835ec745211179', 740 | from: 'zil18ejxkf2u3cfknr6kulp36g6drsvylf6t3w0cpe', 741 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 742 | value: '1193069646888861', 743 | fee: '1000000000', 744 | timestamp: 1554172478877, 745 | nonce: 1, 746 | receiptSuccess: true, 747 | events: [], 748 | data: null, 749 | internalTransfers: [], 750 | transitions: [] 751 | }, 752 | { 753 | hash: '0xf8fc4928dfd539f9bf84a52531c8b06d59a95615c7845e4cb37b5f92aae775cd', 754 | from: 'zil1thtkpmzjpx26jhyvau2xdy5s7e66rvu9xcu2gh', 755 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 756 | value: '996044741466089', 757 | fee: '1000000000', 758 | timestamp: 1554172478877, 759 | nonce: 1, 760 | receiptSuccess: true, 761 | events: [], 762 | data: null, 763 | internalTransfers: [], 764 | transitions: [] 765 | }, 766 | { 767 | hash: '0xf8b489747fa37488634eb2c14d38784729157ee9c46be59744a70dbd133cf587', 768 | from: 'zil10pfk76qdxmykvxqfu7ffajkgshe240v3x26w65', 769 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 770 | value: '270809781797106', 771 | fee: '1000000000', 772 | timestamp: 1554172478877, 773 | nonce: 1, 774 | receiptSuccess: true, 775 | events: [], 776 | data: null, 777 | internalTransfers: [], 778 | transitions: [] 779 | }, 780 | { 781 | hash: '0xf895b7f488bbecc8c91e8101163c1a2fa2731e6af1ca70dd49f45a18ecb4ca81', 782 | from: 'zil1mwz4xelqdkddqdnvdptagx57mmzktjfaz2mjpz', 783 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 784 | value: '1504033644577742', 785 | fee: '1000000000', 786 | timestamp: 1554172478877, 787 | nonce: 1, 788 | receiptSuccess: true, 789 | events: [], 790 | data: null, 791 | internalTransfers: [], 792 | transitions: [] 793 | }, 794 | { 795 | hash: '0xf8339e2ae31695d1ca04a9fd238029f9c75de36665f06726fe0d5096aad85b8b', 796 | from: 'zil1phfhqqh5axt7ehmlj3vul3syc48xhyp47h65gr', 797 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 798 | value: '1477095734460620', 799 | fee: '1000000000', 800 | timestamp: 1554172478877, 801 | nonce: 1, 802 | receiptSuccess: true, 803 | events: [], 804 | data: null, 805 | internalTransfers: [], 806 | transitions: [] }, 807 | { 808 | hash: '0xf81b71e96f13760d405f88b7f97ee7a4ef71174e7018d041b03c0f27a3760b4b', 809 | from: 'zil1xrr4s95lsgxur9seqp34ck5g7ml7relmp7v5rz', 810 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 811 | value: '458516000791614', 812 | fee: '1000000000', 813 | timestamp: 1554172478877, 814 | nonce: 1, 815 | receiptSuccess: true, 816 | events: [], 817 | data: null, 818 | internalTransfers: [], 819 | transitions: [] }, 820 | { 821 | hash: '0xf78f7c922e5b4134020ce0f3db293b7a73a3eb417b25cf9ec519aab78355d216', 822 | from: 'zil17m0k2yrwkwakgg20hncpmd5sqdsl2qfhdhncds', 823 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 824 | value: '1935315546888898', 825 | fee: '1000000000', 826 | timestamp: 1554172478877, 827 | nonce: 1, 828 | receiptSuccess: true, 829 | events: [], 830 | data: null, 831 | internalTransfers: [], 832 | transitions: [] }, 833 | { 834 | hash: '0xf78f0b36d102e3ef84df276400a0c3ae226a822df89204a7a525bda7f87b39c7', 835 | from: 'zil1df9a5sjwc2z26nt04u8tzyepp4m8ffvav4m6r3', 836 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 837 | value: '553574187949524', 838 | fee: '1000000000', 839 | timestamp: 1554172478877, 840 | nonce: 1, 841 | receiptSuccess: true, 842 | events: [], 843 | data: null, 844 | internalTransfers: [], 845 | transitions: [] }, 846 | { 847 | hash: '0xf74a6e9bd7966c3511ef64babcef2ae3ce5d92f3385bd27f1385615ba830ab35', 848 | from: 'zil1zyz8prlg4d8vgd4v33y5j8chzn5tuerlue9lst', 849 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 850 | value: '1303886940618567', 851 | fee: '1000000000', 852 | timestamp: 1554172478877, 853 | nonce: 1, 854 | receiptSuccess: true, 855 | events: [], 856 | data: null, 857 | internalTransfers: [], 858 | transitions: [] }, 859 | { 860 | hash: '0xf73f85115573583f3e9df51311b309c17671e400e0627d6637dad64bb590e4d8', 861 | from: 'zil1g3s4wcum26qxansyd0kyyxl7fua5gj8hataw72', 862 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 863 | value: '735988218756618', 864 | fee: '1000000000', 865 | timestamp: 1554172478877, 866 | nonce: 1, 867 | receiptSuccess: true, 868 | events: [], 869 | data: null, 870 | internalTransfers: [], 871 | transitions: [] }, 872 | { 873 | hash: '0xf73c0822667907d34d8c68ce479cac1d135858675fa1c6744a4fbbe0b2a67855', 874 | from: 'zil1lv6ndxd32z6tva3umadggmhat94swsk3ze24xt', 875 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 876 | value: '771788300225705', 877 | fee: '1000000000', 878 | timestamp: 1554172478877, 879 | nonce: 1, 880 | receiptSuccess: true, 881 | events: [], 882 | data: null, 883 | internalTransfers: [], 884 | transitions: [] }, 885 | { 886 | hash: '0xf6f31a96e497dfee0d365ad3c82a4c7cea79530a22a2dcd1bee4a951b755d881', 887 | from: 'zil15w6xm7uhlng98qflsqfjf8u3kw785nh42yyhz4', 888 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 889 | value: '633389789623963', 890 | fee: '1000000000', 891 | timestamp: 1554172478877, 892 | nonce: 1, 893 | receiptSuccess: true, 894 | events: [], 895 | data: null, 896 | internalTransfers: [], 897 | transitions: [] }, 898 | { 899 | hash: '0xf59bc4f6e7d0f242850f54cd05405d44996057ce24f358425f74672099166a16', 900 | from: 'zil1fmp5jhpxhj4g3zgq5nymwcnpnuwftq0fzcu5yw', 901 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 902 | value: '916336607383980', 903 | fee: '1000000000', 904 | timestamp: 1554172478877, 905 | nonce: 1, 906 | receiptSuccess: true, 907 | events: [], 908 | data: null, 909 | internalTransfers: [], 910 | transitions: [] }, 911 | { 912 | hash: '0xf53b2045870539c2a2afbc2198f55059477f2a366b1671a2a31303e351836385', 913 | from: 'zil19zjpgvsm2nh3qf5r2c0k2gfyznnnp39mxfvqua', 914 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 915 | value: '754173130172251', 916 | fee: '1000000000', 917 | timestamp: 1554172478877, 918 | nonce: 1, 919 | receiptSuccess: true, 920 | events: [], 921 | data: null, 922 | internalTransfers: [], 923 | transitions: [] }, 924 | { 925 | hash: '0xf4effdc7b51e640031d296db79f06581355afb2962898ad0927997d65562e7df', 926 | from: 'zil1dvugerq6rg35jxvplvmx7c3w5rvset3rt4fk7x', 927 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 928 | value: '498768754250469', 929 | fee: '1000000000', 930 | timestamp: 1554172478877, 931 | nonce: 1, 932 | receiptSuccess: true, 933 | events: [], 934 | data: null, 935 | internalTransfers: [], 936 | transitions: [] }, 937 | { 938 | hash: '0xf4e059c173886bd7ff2a752df35f056a04152957079eb5a81de8d28027a925f7', 939 | from: 'zil17kd4gs50y8mhj7f6e5ryq4qwpwp4tvrn8cdhue', 940 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 941 | value: '799534610127843', 942 | fee: '1000000000', 943 | timestamp: 1554172478877, 944 | nonce: 1, 945 | receiptSuccess: true, 946 | events: [], 947 | data: null, 948 | internalTransfers: [], 949 | transitions: [] }, 950 | { 951 | hash: '0xf415e05851f7e94437f54e8ad4616d909bd082c1af746aca952582a315f0ba11', 952 | from: 'zil10dapalzz0gua9z9gkrm6rdfg0j33ypq4ey37dm', 953 | to: 'zil1ggkgt2mcl92hw6yccer0f2q694xqkr6dk25cag', 954 | value: '666457777688691', 955 | fee: '1000000000', 956 | timestamp: 1554172478877, 957 | nonce: 1, 958 | receiptSuccess: true, 959 | events: [], 960 | data: null, 961 | internalTransfers: [], 962 | transitions: [] 963 | }, 964 | { 965 | hash: '0xf3c9bebca62fcb2362e4a55d6bdbd9def62c1de6ac5f561e934faa0428f1bd58', 966 | from: 'zil1kvzkh7hly8dd97xzaursd9xhvy2z0rhr6sqsgy', 967 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 968 | value: '711495675155375', 969 | fee: '1000000000', 970 | timestamp: 1554172478877, 971 | nonce: 1, 972 | receiptSuccess: true, 973 | events: [], 974 | data: null, 975 | internalTransfers: [], 976 | transitions: [] 977 | }, 978 | { 979 | hash: '0xf3545f099634bff0a536d9f8dfa74e361e1691b4c14df110b8099e4611622b6f', 980 | from: 'zil1jmwcy29y7whd5y8mys693hprjxsju83h384h7j', 981 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 982 | value: '365449579421433', 983 | fee: '1000000000', 984 | timestamp: 1554172478877, 985 | nonce: 1, 986 | receiptSuccess: true, 987 | events: [], 988 | data: null, 989 | internalTransfers: [], 990 | transitions: [] 991 | }, 992 | { 993 | hash: '0xf2a8773c01d5f3df44bcfa529b49118cf90d261ff63087609651cdc336f177f7', 994 | from: 'zil1h55wdqlhy8eaenlleyr38wnv0mj4wmkaq8xr87', 995 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 996 | value: '724632233105521', 997 | fee: '1000000000', 998 | timestamp: 1554172478877, 999 | nonce: 1, 1000 | receiptSuccess: true, 1001 | events: [], 1002 | data: null, 1003 | internalTransfers: [], 1004 | transitions: [] 1005 | } 1006 | ], 1007 | totalDocs: 890, 1008 | limit: 25, 1009 | hasPrevPage: false, 1010 | hasNextPage: true, 1011 | page: 1, 1012 | totalPages: 36, 1013 | pagingCounter: 1, 1014 | prevPage: null, 1015 | nextPage: 2, 1016 | pages: 36, 1017 | total: 890 1018 | } 1019 | ``` 1020 | 1021 |
1022 | 1023 | ### Subscriptions 1024 | 1025 | Allows to listen on a variety of events. 1026 | 1027 | > :warning: We do not guarantee either the order upon which the messages are sent, nor that all the messages will be delivered successfully (typically in case of an outage or disruption of service). 1028 | 1029 | #### block 1030 | 1031 | Subscribe to new blocks. 1032 | 1033 | ```js 1034 | client.subscribe('block', console.log) 1035 | ``` 1036 | 1037 | #### transaction 1038 | 1039 | Subscribe to new transactions. 1040 | 1041 | ```js 1042 | client.subscribe('transaction', console.log) 1043 | ``` 1044 | 1045 | #### addressTx 1046 | 1047 | Subscribe to transactions made to or from a specific address. 1048 | 1049 | ```js 1050 | client.subscribe({ event: 'addressTx', param: 'zil1gqww6yq9d9nefhg3rec989kxsqs4zm8dzeyr0q' }, console.log) 1051 | ``` 1052 | 1053 | #### contractEvent 1054 | 1055 | Subscribe to events emitted by one contract. 1056 | 1057 | ```js 1058 | client.subscribe({ event: 'contractEvent', param: 'zil1vszj220406ez4gglpf6jvlds5jkszju63kpvax' }, console.log) 1059 | ``` 1060 | 1061 | ### Misc 1062 | 1063 | #### getGasPrice 1064 | 1065 | Get the current minimum gas price for this DS epoch. 1066 | 1067 | ```js 1068 | await client.getGasPrice() 1069 | ``` 1070 | 1071 |
1072 | Output 1073 | 1074 | ```js 1075 | '1000000000' 1076 | ``` 1077 | 1078 |
1079 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@zilliqa-js/viewblock", 3 | "version": "0.0.5", 4 | "main": "./src/index.js", 5 | "scripts": { 6 | "test": "ava -v", 7 | "lint": "eslint src test", 8 | "cover": "nyc npm run test", 9 | "report": "npm run cover && nyc report --reporter=text-lcov | coveralls" 10 | }, 11 | "dependencies": { 12 | "@zilliqa-js/crypto": "^3.3.4", 13 | "node-fetch": "^3.2.3", 14 | "socketcluster-client": "^16.0.4" 15 | }, 16 | "devDependencies": { 17 | "ava": "^4.2.0", 18 | "coveralls": "^3.1.1", 19 | "dotenv": "^16.0.0", 20 | "eslint": "^8.14.0", 21 | "eslint-config-prettier": "^8.5.0", 22 | "eslint-config-zavatta": "^6.0.3", 23 | "nyc": "^15.1.0", 24 | "prettier": "^2.6.2" 25 | }, 26 | "ava": { 27 | "require": [ 28 | "dotenv/config" 29 | ], 30 | "nodeArguments": [ 31 | "--experimental-specifier-resolution=node" 32 | ], 33 | "files": [ 34 | "test/**/*", 35 | "!test/utils.js" 36 | ], 37 | "timeout": "2m" 38 | }, 39 | "type": "module", 40 | "author": "ViewBlock ", 41 | "license": "MIT" 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | export const NETWORK_URLS = { 2 | mainnet: 'https://api.zilliqa.com', 3 | testnet: 'https://dev-api.zilliqa.com', 4 | } 5 | -------------------------------------------------------------------------------- /src/fn/checkFields.js: -------------------------------------------------------------------------------- 1 | export default (t, obj, fields) => fields.forEach(field => t.truthy(obj[field])) 2 | -------------------------------------------------------------------------------- /src/fn/toHex.js: -------------------------------------------------------------------------------- 1 | import crypto from '@zilliqa-js/crypto' 2 | 3 | const zilReg = /^zil1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38}$/ 4 | 5 | export default address => { 6 | if (address.startsWith('0x')) { 7 | return address.substr(2) 8 | } 9 | 10 | if (!address.match(zilReg)) { 11 | return address 12 | } 13 | 14 | const hex = crypto.fromBech32Address(address) 15 | 16 | return hex.substr(2) 17 | } 18 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import rpc from './rpc.js' 2 | import vb from './viewblock.js' 3 | import getSubscribe from './socket.js' 4 | 5 | import toHex from './fn/toHex.js' 6 | 7 | export default ({ apiKey, network = 'mainnet', agent } = {}) => { 8 | const isAnon = !apiKey 9 | 10 | const getOpts = opts => ({ apiKey, network, agent, ...opts }) 11 | 12 | const rpcMethods = { 13 | createTx: (payload, opts) => 14 | rpc({ method: 'CreateTransaction', params: [payload] }, getOpts(opts)).then(res => ({ 15 | msg: res.Info, 16 | hash: res.TranID, 17 | })), 18 | getGasPrice: opts => rpc('GetMinimumGasPrice', getOpts(opts)), 19 | getSCInit: (hash, opts) => 20 | rpc({ method: 'GetSmartContractInit', params: [toHex(hash)] }, getOpts(opts)), 21 | getSCState: (body, opts) => { 22 | const isHash = typeof body === 'string' 23 | const { address, name = '', indices = [] } = isHash ? { address: body } : body 24 | 25 | return rpc( 26 | { method: 'GetSmartContractSubState', params: [toHex(address), name, indices] }, 27 | getOpts(opts), 28 | ) 29 | }, 30 | } 31 | 32 | if (isAnon) { 33 | console.warn(`Disabling main library features: No API credentials provided. 34 | Get them on https://viewblock.io by creating a free account and an API key.`) 35 | 36 | return rpcMethods 37 | } 38 | 39 | return { 40 | ...rpcMethods, 41 | 42 | subscribe: getSubscribe(apiKey), 43 | 44 | getBlock: (height, opts) => vb(`/v1/zilliqa/blocks/${height}`, getOpts(opts)), 45 | getBlockTxs: (height, opts = {}) => 46 | vb(`/v1/zilliqa/blocks/${height}/txs`, getOpts({ ...opts, query: { page: opts.page } })), 47 | 48 | getAddress: (hash, opts) => 49 | vb(`/v1/zilliqa/addresses/${hash}`, getOpts(opts)).then(res => res && res[0]), 50 | getAddressTxs: (hash, opts = {}) => 51 | vb(`/v2/zilliqa/addresses/${hash}/txs`, getOpts({ ...opts, query: { page: opts.page } })), 52 | getAddressTokenTxs: (hash, opts = {}) => 53 | vb( 54 | `/v2/zilliqa/addresses/${hash}/txs`, 55 | getOpts({ ...opts, query: { type: 'tokens', page: opts.page, token: opts.token } }), 56 | ), 57 | getTx: (hash, opts) => vb(`/v1/zilliqa/txs/${hash}`, getOpts(opts)), 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/rpc.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | 3 | import { NETWORK_URLS } from './config.js' 4 | 5 | export default (body, { network, agent = null }) => { 6 | const url = NETWORK_URLS[network] 7 | 8 | const payload = typeof body === 'string' ? { method: body } : body 9 | 10 | return fetch(url, { 11 | method: 'POST', 12 | body: JSON.stringify({ id: 1, jsonrpc: '2.0', params: [''], ...payload }), 13 | headers: { 'Content-Type': 'json' }, 14 | timeout: 1e3 * 30, 15 | agent, 16 | }) 17 | .then(res => res.json()) 18 | .then(json => { 19 | const { error, result } = json || {} 20 | if (error) { 21 | throw new Error(error.message) 22 | } 23 | 24 | return result 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /src/socket.js: -------------------------------------------------------------------------------- 1 | import socketCluster from 'socketcluster-client' 2 | 3 | const options = { 4 | hostname: 'live.viewblock.io', 5 | path: '/', 6 | port: 444, 7 | secure: true, 8 | 9 | connectTimeout: 10e3, 10 | autoConnect: true, 11 | autoReconnect: true, 12 | autoReconnectOptions: { 13 | initialDelay: 1e3, 14 | randomness: 5e3, 15 | multiplier: 1.1, 16 | maxDelay: 20e3, 17 | }, 18 | } 19 | 20 | const validEvents = { 21 | block: 1, 22 | transaction: 1, 23 | addressTx: 1, 24 | contractEvent: 1, 25 | } 26 | 27 | const getSocket = key => 28 | new Promise((resolve, reject) => { 29 | const socket = socketCluster.create(options) 30 | 31 | socket.on('connect', () => { 32 | socket.emit('login', { key }, errMsg => { 33 | if (errMsg) { 34 | return reject(new Error(errMsg)) 35 | } 36 | 37 | resolve(socket) 38 | }) 39 | }) 40 | 41 | socket.on('error', console.log) 42 | 43 | return socket 44 | }) 45 | 46 | export default apiKey => (payload, cb) => 47 | getSocket(apiKey).then(socket => { 48 | if (!payload) { 49 | throw new Error('Invalid subscription.') 50 | } 51 | 52 | const event = payload.event || payload 53 | 54 | if (!validEvents[event]) { 55 | throw new Error('Invalid subscription.') 56 | } 57 | 58 | const param = payload.param 59 | const key = `zilliqa:${event}${param ? `:${param}` : ''}` 60 | 61 | socket.subscribe(key).watch(cb) 62 | }) 63 | -------------------------------------------------------------------------------- /src/viewblock.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | 3 | const BASE_URL = 'https://api.viewblock.io' 4 | 5 | const makeQuery = params => { 6 | const keys = Object.keys(params).filter(k => params[k]) 7 | 8 | return `${keys.length ? '?' : ''}${keys 9 | .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`, '') 10 | .join('&')}` 11 | } 12 | 13 | export default (path, { apiKey, query = {}, network, agent = null }) => { 14 | const q = makeQuery({ ...query, network }) 15 | 16 | return fetch(`${BASE_URL}${path}${q}`, { 17 | headers: { 'Content-Type': 'json', 'X-APIKEY': apiKey }, 18 | timeout: 1e3 * 30, 19 | agent, 20 | }).then(res => res.json()) 21 | } 22 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | 3 | import Zilliqa from '../src' 4 | import toHex from '../src/fn/toHex' 5 | import checkFields from '../src/fn/checkFields' 6 | 7 | const client = Zilliqa({ apiKey: process.env.API_KEY }) 8 | 9 | const RESERVE_CONTRACT = 'zil1cm2x24v7807w7yjvmkz0am0y37vkys8lwtxsth' 10 | const OLD_TEST_ADDR = 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu' 11 | 12 | const OLD_TOKEN_TEST_ADDR = 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml' 13 | const OLD_TOKEN_TEST_CONTRACT = 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre' 14 | 15 | const BLOCK_HEIGHT = 59903 16 | 17 | test('[Main] Light client should only have rpc methods', t => { 18 | const client = Zilliqa() 19 | t.is(Object.keys(client).length, 4) 20 | }) 21 | 22 | test('[Main] Full client should have all methods', t => { 23 | t.is(Object.keys(client).length, 11) 24 | }) 25 | 26 | test('[Transaction] getTx', async t => { 27 | const tx = await client.getTx( 28 | '0x65fd90f1fc2d3b631a0cf6a77be9947e9f4559d9ece9b9a1eef170d593bd9213', 29 | ) 30 | 31 | t.deepEqual(tx, { 32 | hash: '0x65fd90f1fc2d3b631a0cf6a77be9947e9f4559d9ece9b9a1eef170d593bd9213', 33 | blockHeight: 577008, 34 | from: 'zil1kshhphza3vlyfamjchamk2d3j022a55kn6es38', 35 | to: 'zil1z3zky3kv20f37z3wkq86qfy00t4a875fxxw7sw', 36 | value: '29000000000000', 37 | fee: '1000000000', 38 | timestamp: 1590005268574, 39 | signature: 40 | '0xEA74CF5062954368ECBEB9EA00014C9F78590391703E0DCEF002FAB50D30C1147D84BDC8A1703A33181CD3BDE315E6B28627EB0266DCD0D3CB886130B06312D1', 41 | nonce: 1, 42 | receiptSuccess: true, 43 | events: [], 44 | internalTransfers: [], 45 | data: null, 46 | transitions: [], 47 | }) 48 | }) 49 | 50 | test('[Block] getBlock', async t => { 51 | const block = await client.getBlock(BLOCK_HEIGHT) 52 | 53 | t.truthy(block) 54 | t.is(block.height, BLOCK_HEIGHT) 55 | t.is(block.txCount, 890) 56 | t.is(block.dsHeight, 600) 57 | t.is(block.minerPubKey, '0x0227939F72067FE1AC79276CE779A27C560391A660D42FDE0102229964F1C2C511') 58 | }) 59 | 60 | test('[Block] getBlockTxs', async t => { 61 | const res = await client.getBlockTxs(BLOCK_HEIGHT) 62 | 63 | t.truthy(res) 64 | t.is(res.docs.length, 25) 65 | t.is(res.page, 1) 66 | t.is(res.total, 890) 67 | t.is(res.totalPages, 36) 68 | t.deepEqual(res.docs[0], { 69 | hash: '0xfe55cf4954507a5b809cdfa8725a499d0656e3644838c2cd826eaa57a8e48f62', 70 | from: 'zil16ttxueshqnnun5hlen8ql8q5rvx7vvtm63ccna', 71 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 72 | value: '703140978601111', 73 | fee: '1000000000', 74 | timestamp: 1554172478877, 75 | nonce: 1, 76 | receiptSuccess: true, 77 | events: [], 78 | internalTransfers: [], 79 | data: null, 80 | transitions: [], 81 | }) 82 | 83 | const next = await client.getBlockTxs(BLOCK_HEIGHT, { page: 2 }) 84 | 85 | t.is(next.docs.length, 25) 86 | t.is(next.page, 2) 87 | t.is(next.total, 890) 88 | t.is(next.totalPages, 36) 89 | t.deepEqual(next.docs[0], { 90 | hash: '0xf0b3a55731a4825956da6b9e12cfb35fb90b24adf8d3170e1d97329fb31f16b9', 91 | from: 'zil1mw5l7psjteusjuuwgu8pp9f3tr97fhjreddehu', 92 | to: 'zil1m9pv2cr087ewxncupyeujsr0q3fmulu6ep5elv', 93 | value: '545555182346812', 94 | fee: '1000000000', 95 | timestamp: 1554172478877, 96 | nonce: 1, 97 | receiptSuccess: true, 98 | events: [], 99 | internalTransfers: [], 100 | data: null, 101 | transitions: [], 102 | }) 103 | }) 104 | 105 | test('[Address] getAddress', async t => { 106 | const notFound = await client.getAddress(OLD_TEST_ADDR) 107 | t.is(notFound.type, 'normal') 108 | t.is(notFound.balance, 0) 109 | t.is(notFound.txCount, 0) 110 | t.is(notFound.hash, OLD_TEST_ADDR) 111 | 112 | const addr = await client.getAddress(OLD_TEST_ADDR, { network: 'testnet' }) 113 | t.is(addr.balance, '999962495000000000') 114 | t.is(addr.txCount, 5) 115 | t.is(addr.nonce, 4) 116 | }) 117 | 118 | test('[Address] getAddressTxs', async t => { 119 | const invalid = await client.getAddressTxs(OLD_TEST_ADDR) 120 | 121 | t.truthy(invalid) 122 | t.is(invalid.total, 0) 123 | t.is(invalid.docs.length, 0) 124 | t.is(invalid.totalPages, 1) 125 | t.is(invalid.page, 1) 126 | 127 | const txCount = 5 128 | 129 | const res = await client.getAddressTxs(OLD_TEST_ADDR, { network: 'testnet' }) 130 | 131 | t.truthy(res) 132 | t.is(res.page, 1) 133 | t.is(res.totalPages, 1) 134 | t.is(res.nextPage, null) 135 | t.is(res.prevPage, null) 136 | t.is(res.total, txCount) 137 | 138 | t.truthy(res.docs) 139 | t.is(res.docs.length, txCount) 140 | 141 | t.deepEqual(res.docs, [ 142 | { 143 | hash: '0x4824d98f9bc8bdb2137d17f6218a91d4e8765e32df6b43d710f444bcbe8d4e17', 144 | blockHeight: 444152, 145 | from: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 146 | to: 'zil1hwy2fzhukq07g3rfw0vkmmh7kvef732qzdv3qr', 147 | value: '0', 148 | fee: '9377000000000', 149 | timestamp: 1557973403680, 150 | signature: 151 | '0xCCEBFA70023F1627683AEDA6E73AFAB0A9A37EC6A826056F2E2AB0EDBA08D185AB82434F99298AE7257F1A0C9CABCD56CDFE5D173CBF9925449F3F059BD1486B', 152 | direction: 'out', 153 | nonce: 4, 154 | receiptSuccess: true, 155 | events: [], 156 | internalTransfers: [], 157 | data: '[{"vname":"_scilla_version","type":"Uint32","value":"0"},{"vname":"contractOwner","type":"ByStr20","value":"0xb826575569544c7f9afa65a92616fc0adf03d119"}]', 158 | transitions: [], 159 | }, 160 | { 161 | hash: '0x236fbf86726c0c93c735e4730cebaaea050286da3e5ee5706153a1fbd8dd1bb6', 162 | blockHeight: 313433, 163 | from: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 164 | to: 'zil16fjwdfkmcrpvedmzjpavjnu5vku8ztftv8rxpr', 165 | value: '0', 166 | fee: '9377000000000', 167 | timestamp: 1553850738169, 168 | signature: 169 | '0xB3F6BDA13160BF567AA275D13F209D6F4E5EA72E950EC5E21B25628F4F44D84DF1424D2785A29DFAA419D2A48BD47B3FCB4C1E061B5557A9DAD0216648B4C46E', 170 | direction: 'out', 171 | nonce: 3, 172 | receiptSuccess: true, 173 | events: [], 174 | internalTransfers: [], 175 | data: '[{"vname":"_scilla_version","type":"Uint32","value":"0"},{"vname":"contractOwner","type":"ByStr20","value":"0xb826575569544c7f9afa65a92616fc0adf03d119"}]', 176 | transitions: [], 177 | }, 178 | { 179 | hash: '0xcbeb9c32b16e6eddf74bba1fa6403298dba46f6083ab90593437d3a81579377d', 180 | blockHeight: 157624, 181 | from: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 182 | to: 'zil12eevlp9ak79lywnvjkxns4y0agwsdumdrxhu7f', 183 | value: '0', 184 | fee: '9377000000000', 185 | timestamp: 1551255474086, 186 | signature: 187 | '0xF8242F6C6BE7006770F6A26FA347E7BAB155E66C3EB5F21CDE6C1CD305E8786A52C6741517B016950C6807CFDD054FB08C502CB5B7BF6F55A9D48941D3F3DC02', 188 | direction: 'out', 189 | nonce: 2, 190 | receiptSuccess: true, 191 | events: [], 192 | internalTransfers: [], 193 | data: '[{"vname":"_scilla_version","type":"Uint32","value":"0"},{"vname":"contractOwner","type":"ByStr20","value":"0xb826575569544c7f9afa65a92616fc0adf03d119"}]', 194 | transitions: [], 195 | }, 196 | { 197 | hash: '0x99fdf3b323b446125bfd7cdef4347c77b7fd7594de8a6486a1b0aa28f3baf39d', 198 | blockHeight: 510, 199 | from: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 200 | to: 'zil13jcdkf7vct26x8wtunhr9xvzrhdqp2k9wed9qx', 201 | value: '0', 202 | fee: '9374000000000', 203 | timestamp: 1549272278119, 204 | signature: 205 | '0x86041BA59CDFE348FDE084CF4F8184AB4EF3B36795056EA09C62D8BF82E8F739766FFDBE107E2D357A3C323F25E23E92CAC84804E0E07458F6BCD3304A61B35F', 206 | direction: 'out', 207 | nonce: 1, 208 | receiptSuccess: true, 209 | events: [], 210 | internalTransfers: [], 211 | data: '[{"vname":"_scilla_version","type":"Uint32","value":"0"},{"vname":"contractOwner","type":"ByStr20","value":"0xb826575569544c7f9afa65a92616fc0adf03d119"}]', 212 | transitions: [], 213 | }, 214 | { 215 | hash: '0x9aa24045971adffe1eb97245f115babb0bbc1eb5fee1fd574c5264f584b101a4', 216 | blockHeight: 507, 217 | from: 'zil1z2u5waw9zrscnf3jx3xwdfd9vw4pj4c5jtsd9p', 218 | to: 'zil1hqn9w4tf23x8lxh6vk5jv9hupt0s85gemyetmu', 219 | value: '1000000000000000000', 220 | fee: '1000000000', 221 | timestamp: 1549272241251, 222 | signature: 223 | '0x4180574A8132E1B031B8361AACE5D50AAB6CD154B8F7D7A93F702E4300904E10C15B65889A075A449F717F5926DE8C0CA82E82DA4882F22F662B4AE458DEA6CB', 224 | direction: 'in', 225 | nonce: 6, 226 | receiptSuccess: true, 227 | events: [], 228 | internalTransfers: [], 229 | data: null, 230 | transitions: [], 231 | }, 232 | ]) 233 | 234 | const next = await client.getAddressTxs(OLD_TEST_ADDR, { network: 'testnet', page: 2 }) 235 | 236 | t.is(next.page, 2) 237 | t.is(next.totalPages, 1) 238 | t.is(next.total, txCount) 239 | t.is(next.docs.length, 0) 240 | t.is(next.prevPage, 1) 241 | }) 242 | 243 | test.skip('[Address] getAddressTokenTxs', async t => { 244 | const invalid = await client.getAddressTokenTxs(OLD_TOKEN_TEST_ADDR) 245 | 246 | t.truthy(invalid) 247 | t.is(invalid.total, 0) 248 | t.is(invalid.docs.length, 0) 249 | t.is(invalid.totalPages, 1) 250 | t.is(invalid.page, 1) 251 | 252 | const txCount = 7 253 | 254 | const res = await client.getAddressTokenTxs(OLD_TOKEN_TEST_ADDR, { 255 | network: 'testnet', 256 | token: OLD_TOKEN_TEST_CONTRACT, 257 | }) 258 | 259 | t.truthy(res) 260 | t.is(res.page, 1) 261 | t.is(res.totalPages, 1) 262 | t.is(res.nextPage, null) 263 | t.is(res.prevPage, null) 264 | t.is(res.total, txCount) 265 | 266 | t.truthy(res.docs) 267 | t.is(res.docs.length, txCount) 268 | 269 | t.deepEqual(res.docs, [ 270 | { 271 | hash: '0x3c60b3194a175fa4d484fb3074f3bd7ba9bfd62c7d6dc1da6f86a4c948bb7f92', 272 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 273 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 274 | value: '0.02', 275 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 276 | blockHeight: 1776290, 277 | timestamp: 1599139330519, 278 | direction: 'in', 279 | }, 280 | { 281 | hash: '0x7b7555d456cf4415c1f58af26a8b8788ebb3431c41ccb893d0c3a06c2157c064', 282 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 283 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 284 | value: '0', 285 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 286 | blockHeight: 1776298, 287 | timestamp: 1599139497307, 288 | direction: 'in', 289 | }, 290 | { 291 | hash: '0xc5f582866251b022ac32e98a6e4598319288234ef8722b04bf5c285122094af1', 292 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 293 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 294 | value: '0.01', 295 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 296 | blockHeight: 1776348, 297 | timestamp: 1599140579375, 298 | direction: 'in', 299 | }, 300 | { 301 | hash: '0x7b1356842d1e595384ee2de38df7fc24ed1a57f5df65c3cc23c7b4f02415cdeb', 302 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 303 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 304 | value: '0.04', 305 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 306 | blockHeight: 1776384, 307 | timestamp: 1599141333323, 308 | direction: 'in', 309 | }, 310 | { 311 | hash: '0x7e1da8fb622bfb6203d65573cb4367077f85fd65b90697fd82ca3e8e145b0841', 312 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 313 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 314 | value: '0', 315 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 316 | blockHeight: 1776390, 317 | timestamp: 1599141458698, 318 | direction: 'in', 319 | }, 320 | { 321 | hash: '0xe0094c46b4bd1fb0ef0fbb623c9d0431f835d850a28e8a5b81886ca7e91061b2', 322 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 323 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 324 | value: '0', 325 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 326 | blockHeight: 1776704, 327 | timestamp: 1599148162726, 328 | direction: 'in', 329 | }, 330 | { 331 | hash: '0x785f21e312a10307907ac3f06da0d6056056082fa0265ef64fa8b402676425ab', 332 | from: 'zil1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9yf6pz', 333 | to: 'zil1my8ju5uvur0cnjp88jknkclvgj3ufmvz5pxyml', 334 | value: '0.0196969696', 335 | tokenAddress: 'zil1l8mn5r5urrlxzf6q9z790zz2c5a9ya8366hzre', 336 | blockHeight: 1776986, 337 | timestamp: 1599154120380, 338 | direction: 'in', 339 | }, 340 | ]) 341 | 342 | const next = await client.getAddressTokenTxs(OLD_TOKEN_TEST_ADDR, { 343 | network: 'testnet', 344 | token: OLD_TOKEN_TEST_CONTRACT, 345 | page: 2, 346 | }) 347 | 348 | t.is(next.page, 2) 349 | t.is(next.totalPages, 1) 350 | t.is(next.total, txCount) 351 | t.is(next.docs.length, 0) 352 | t.is(next.prevPage, 1) 353 | }) 354 | 355 | test('[SC] Invalid address using default network', async t => { 356 | const c = Zilliqa({ network: 'testnet' }) 357 | 358 | try { 359 | await c.getSCInit(RESERVE_CONTRACT) 360 | } catch (err) { 361 | t.is(err.message, 'Address does not exist') 362 | } 363 | }) 364 | 365 | test('[SC] Invalid address using network override', async t => { 366 | try { 367 | await client.getSCInit(RESERVE_CONTRACT, { network: 'testnet' }) 368 | } catch (err) { 369 | t.is(err.message, 'Address does not exist') 370 | } 371 | }) 372 | 373 | test('[SC] getSCInit', async t => { 374 | const init = await client.getSCInit(RESERVE_CONTRACT) 375 | 376 | t.is(init.length, 5) 377 | t.deepEqual( 378 | init.map(d => d.vname), 379 | ['_scilla_version', 'owners_list', 'required_signatures', '_creation_block', '_this_address'], 380 | ) 381 | }) 382 | 383 | test('[SC] getSCState full', async t => { 384 | const state = await client.getSCState(RESERVE_CONTRACT) 385 | 386 | t.truthy(state) 387 | t.truthy(state._balance) 388 | t.truthy(state.owners) 389 | }) 390 | 391 | test('[SC] getSCState sub', async t => { 392 | const subOwners = await client.getSCState({ 393 | address: RESERVE_CONTRACT, 394 | name: 'owners', 395 | }) 396 | 397 | t.is(Object.keys(subOwners).length, 1) 398 | t.truthy(subOwners.owners) 399 | t.is(Object.keys(subOwners.owners).length, 4) 400 | 401 | const subOwner = await client.getSCState({ 402 | address: RESERVE_CONTRACT, 403 | name: 'owners', 404 | indices: ['0x09ee3238528247354862700f5c00a349a499badb'], 405 | }) 406 | 407 | t.is(Object.keys(subOwner).length, 1) 408 | t.truthy(subOwner.owners) 409 | t.is(Object.keys(subOwner.owners).length, 1) 410 | }) 411 | 412 | test('[Misc] toHex', t => { 413 | const expected = 'c6d465559E3BFCEF124Cdd84fEEdE48f996240ff' 414 | 415 | t.is(toHex(RESERVE_CONTRACT), expected, 'Bech32 to (((valid)))') 416 | t.is(toHex(`0x${expected}`), expected, 'Prefixed to (((valid)))') 417 | t.is(toHex(expected), expected, 'Same (((valid))) output') 418 | }) 419 | 420 | test('[Misc] getGasPrice', async t => { 421 | const gas = await client.getGasPrice() 422 | 423 | t.truthy(gas) 424 | t.truthy(gas > 0) 425 | }) 426 | 427 | test('[Socket] Throws with empty subscribe', async t => { 428 | await t.throwsAsync(client.subscribe()) 429 | }) 430 | 431 | test('[Socket] Throws with wrong subscribe', async t => { 432 | await t.throwsAsync(client.subscribe('yolo')) 433 | }) 434 | 435 | test.skip('[Socket] Throws with an invalid key', async t => { 436 | const client = Zilliqa({ apiKey: 'yolo' }) 437 | 438 | const err = await t.throwsAsync(client.subscribe('transaction')) 439 | t.is(err.message, 'Login failed') 440 | }) 441 | 442 | test.skip('[Socket] Basic', t => { 443 | const txFields = [ 444 | 'from', 445 | 'to', 446 | 'value', 447 | 'hash', 448 | 'blockHeight', 449 | 'internalTransfers', 450 | 'fee', 451 | 'ts', 452 | 'chain', 453 | ] 454 | 455 | client.subscribe('transaction', tx => { 456 | checkFields(t, tx, txFields) 457 | t.end() 458 | }) 459 | 460 | client.subscribe('block', block => { 461 | checkFields(t, block, ['timestamp', 'status', 'chain', 'network', 'height']) 462 | t.end() 463 | }) 464 | 465 | client.subscribe( 466 | { event: 'addressTx', param: 'zil1z3zky3kv20f37z3wkq86qfy00t4a875fxxw7sw' }, 467 | tx => { 468 | checkFields(t, tx, txFields) 469 | t.end() 470 | }, 471 | ) 472 | }) 473 | --------------------------------------------------------------------------------