Compare commits

..
376 Commits
Author SHA1 Message Date
Github Actions 033ff7a28c [CI Skip] 1.12.1
skip-checks: true
2020-04-29 22:23:45 +00:00
Jaco Greeff 7c8b2abf92 1.12 (#2221) 2020-04-30 00:13:27 +02:00
Github Actions 5312ec1f3a [CI Skip] 1.12.0-beta.15
skip-checks: true
2020-04-29 16:13:00 +00:00
Matej Nemček cdfbf91ee6 added Kodadot to @polkadot/api users section (#2220) 2020-04-29 18:00:50 +02:00
Github Actions 14f2abdc37 [CI Skip] 1.12.0-beta.14
skip-checks: true
2020-04-29 15:50:05 +00:00
Jake Naviasky 04c8d49e9d Add configurable provider auto-reconnect time. (#2215) 2020-04-29 17:39:31 +02:00
Github Actions 722929d0d4 [CI Skip] 1.12.0-beta.13
skip-checks: true
2020-04-29 14:57:15 +00:00
Jaco Greeff d1fae523ac Fix CompactAssignments types (#2219)
* Fix CompactAssignments types

* Cleanup mistaken type adjustments
2020-04-29 16:45:59 +02:00
Github Actions ce9a92cdc0 [CI Skip] 1.12.0-beta.12
skip-checks: true
2020-04-27 17:09:59 +00:00
Jaco Greeff 3de09a2e27 Hack around preimage failures (#2217) 2020-04-27 18:59:18 +02:00
Github Actions f28479180f [CI Skip] 1.12.0-beta.11
skip-checks: true
2020-04-27 14:04:29 +00:00
Jaco Greeff 0d1d42f6c2 Update promise combineLatest with generics (#2214) 2020-04-27 15:53:17 +02:00
Github Actions c93dad0bc5 [CI Skip] 1.12.0-beta.10
skip-checks: true
2020-04-27 07:04:47 +00:00
Jaco Greeff e3d3a1ff71 Handle no keysReturn StorageChangeSet with no keys (#2212) 2020-04-27 08:54:02 +02:00
Github Actions 1c8bd896e1 [CI Skip] 1.12.0-beta.9
skip-checks: true
2020-04-26 11:56:32 +00:00
Jaco Greeff e0119c1873 Bump metadata to current Substrate master (incl. types) (#2210) 2020-04-26 13:46:36 +02:00
Github Actions defe81e560 [CI Skip] 1.12.0-beta.8
skip-checks: true
2020-04-26 11:42:47 +00:00
Xiliang Chen 932122cd21 subscribeStorage parameter should be optional (#2208) 2020-04-26 13:32:43 +02:00
Github Actions 40d035eca7 [CI Skip] 1.12.0-beta.7
skip-checks: true
2020-04-25 07:58:44 +00:00
Jaco Greeff a135abaea2 Fix flags (council may not exist) (#2207) 2020-04-25 09:47:46 +02:00
Github Actions 00b8c10881 [CI Skip] 1.12.0-beta.6
skip-checks: true
2020-04-24 14:34:08 +00:00
Jaco Greeff 11e7b90918 Bump deps (#2206) 2020-04-24 16:22:18 +02:00
Github Actions ae74467e6a [CI Skip] 1.12.0-beta.5
skip-checks: true
2020-04-24 13:40:02 +00:00
Jeremías Díaz 5a929d3810 remove unnecessary parentheses and duplicate types (#2204)
* remove unnecessary parentheses and duplicate types

* fix: remove test code
2020-04-24 15:28:47 +02:00
Github Actions 63732f1456 [CI Skip] 1.12.0-beta.4
skip-checks: true
2020-04-24 08:54:04 +00:00
Jaco Greeff ea6bb83c01 Voting delegations (#2205) 2020-04-24 10:41:30 +02:00
Github Actions d6a443ca2a [CI Skip] 1.12.0-beta.3
skip-checks: true
2020-04-23 09:50:46 +00:00
Jaco Greeff d983ee106c migrateEra is first stakerPayouts era (#2202) 2020-04-23 11:39:39 +02:00
Github Actions beed1df5bd [CI Skip] 1.12.0-beta.2
skip-checks: true
2020-04-22 09:04:55 +00:00
Jaco Greeff 426aef6088 Update .123trigger 2020-04-22 10:55:01 +02:00
Github Actions 9be9b3fb83 [CI Skip] 1.12.0-beta.1
skip-checks: true
2020-04-22 07:56:01 +00:00
Jaco Greeff 8676f30cbf Reset to beta 2020-04-22 09:44:59 +02:00
Github Actions 154561c34c [CI Skip] 1.11.2
skip-checks: true
2020-04-22 07:40:26 +00:00
Jaco Greeff 714b242ec0 0.11.2 (#2200) 2020-04-22 09:30:02 +02:00
Github Actions 32ce650ee1 [CI Skip] 1.12.0-beta.0
skip-checks: true
2020-04-21 17:05:00 +00:00
Jaco Greeff 3715df2f5b Additional parachains types (#2199)
* Additional parachains types

* missing extensions listing

* trigger
2020-04-21 18:53:00 +02:00
Github Actions dd6e6ddfc1 [CI Skip] 1.11.1
skip-checks: true
2020-04-21 07:47:25 +00:00
Jaco Greeff 9975f58cfb 1.11 (#2198)
* 1.11

* isOptional is custom RPC sample

* Names is one-liner for custom RPCs
2020-04-21 09:38:09 +02:00
Github Actions 536369261f [CI Skip] 1.11.0-beta.35
skip-checks: true
2020-04-21 07:10:16 +00:00
Jaco Greeff 33165e93dc Add state_getReadProof (#2196) 2020-04-21 09:00:03 +02:00
Github Actions 39a38a6c44 [CI Skip] 1.11.0-beta.34
skip-checks: true
2020-04-21 05:41:16 +00:00
Keith Ingram b18bdc37f9 Add api.derive.accounts.flags (#2195)
* account flags in new call

* Fix
2020-04-21 07:31:00 +02:00
Github Actions 79847aabf7 [CI Skip] 1.11.0-beta.33
skip-checks: true
2020-04-20 09:22:55 +00:00
Jaco Greeff ab75863d94 Fix derive.democracy.preimage signature (#2194) 2020-04-20 11:12:03 +02:00
Github Actions c908a27b7d [CI Skip] 1.11.0-beta.32
skip-checks: true
2020-04-18 07:31:19 +00:00
Jaco Greeff 98c7e5d5ea Optimize entries retrieval (#2193) 2020-04-18 09:21:06 +02:00
Github Actions fd4587a0bc [CI Skip] 1.11.0-beta.31
skip-checks: true
2020-04-17 13:41:21 +00:00
Jaco Greeff e211ae1667 Added types for DoubleVoteReport (parachains) (#2192) 2020-04-17 15:32:51 +02:00
Github Actions af735176fe [CI Skip] 1.11.0-beta.30
skip-checks: true
2020-04-17 10:34:48 +00:00
Jaco Greeff 9eb44d6e89 console warnings on the use of node-template (#2191)
* console warnings on the use of node-template

* Message formatting
2020-04-17 12:23:44 +02:00
Github Actions 379e841808 [CI Skip] 1.11.0-beta.29
skip-checks: true
2020-04-17 06:07:08 +00:00
Jaco Greeff 5c16b8e8a1 Adjust spec types (starting versions) (#2189) 2020-04-17 07:55:53 +02:00
Github Actions 96d7d9ff5a [CI Skip] 1.11.0-beta.28
skip-checks: true
2020-04-16 19:55:16 +00:00
Jaco Greeff e9fbbbbd42 Typos 2020-04-16 21:44:04 +02:00
Github Actions 73750ddb7d [CI Skip] 1.11.0-beta.27
skip-checks: true
2020-04-16 19:39:17 +00:00
Jaco Greeff 4e1145c66f FAQ entry for Weight adjustment (#2188)
* FAQ entry for Weight adjustment

* CHANGELOG entry for rxjs Observable exposure

* Event decoding
2020-04-16 21:29:22 +02:00
Github Actions 7f35fa22d5 [CI Skip] 1.11.0-beta.26
skip-checks: true
2020-04-16 17:14:23 +00:00
Jeremías Díaz da1daf5bd9 fix: ensure consistent Observable version (#2187) 2020-04-16 19:03:00 +02:00
Github Actions 5afc87ce47 [CI Skip] 1.11.0-beta.25
skip-checks: true
2020-04-16 16:21:36 +00:00
Jaco Greeff a2269cd999 Explain where args come from and their types (#2186)
* Explain where args come from and their types

* Update api.query.other.md
2020-04-16 18:11:12 +02:00
Github Actions 201308c259 [CI Skip] 1.11.0-beta.24
skip-checks: true
2020-04-16 14:32:15 +00:00
Jaco Greeff 00490116dd Add system_{localPeerId, localListenAddresses} RPCs (#2185)
* Add system_{localPeerId, localListenAddresses} RPCs

* CHANGELOG
2020-04-16 16:21:40 +02:00
Github Actions 1968c878f5 [CI Skip] 1.11.0-beta.23
skip-checks: true
2020-04-16 13:52:16 +00:00
Jaco Greeff 52ccb9fbbf Linkage fixes (#2184)
* Fix linkage decoding

* Actually fix linkage

* CHANGELOG
2020-04-16 15:41:42 +02:00
Github Actions 03e21ea64b [CI Skip] 1.11.0-beta.22
skip-checks: true
2020-04-16 13:39:19 +00:00
Jaco Greeff 8c949bb3df StorageKey toHuman returns decoded key (#2183) 2020-04-16 15:28:15 +02:00
Github Actions e484e7cf35 [CI Skip] 1.11.0-beta.21
skip-checks: true
2020-04-16 11:32:18 +00:00
Jaco Greeff 7aac4c7936 Add missing cookbook .keys 2020-04-16 13:21:04 +02:00
Github Actions 933c8d48e2 [CI Skip] 1.11.0-beta.20
skip-checks: true
2020-04-16 11:18:25 +00:00
Jaco Greeff d3d3bb9b5a Adjust Weight to u64 (#2181)
* Adjust Weight to u64

* Adjust copy (really should be reading folders...)

* build:interfaces

* EventRecord test expectation update
2020-04-16 13:08:46 +02:00
Github Actions f4d976c337 [CI Skip] 1.11.0-beta.19
skip-checks: true
2020-04-16 10:17:47 +00:00
Jaco Greeff 07c4037fcf On subscriptions, ensure rx.runtimeVersion is set (#2180) 2020-04-16 12:05:35 +02:00
Github Actions 52d73d8698 [CI Skip] 1.11.0-beta.18
skip-checks: true
2020-04-16 09:02:05 +00:00
Jeremías Díaz ccfab75f41 fix: use camelCase for storage module names (#2176) 2020-04-16 10:51:19 +02:00
Github Actions b8204b138d [CI Skip] 1.11.0-beta.17
skip-checks: true
2020-04-16 08:46:32 +00:00
Jaco Greeff a97cb6e25d Return all identity hashes (not just as subset) (#2179) 2020-04-16 10:36:37 +02:00
Github Actions 11534a1153 [CI Skip] 1.11.0-beta.16
skip-checks: true
2020-04-16 07:21:00 +00:00
Jaco Greeff dd1fab5366 Adjust set bitfileds to LE (#2178) 2020-04-16 09:09:17 +02:00
Github Actions dbb3a5ccc2 [CI Skip] 1.11.0-beta.15
skip-checks: true
2020-04-15 16:26:29 +00:00
Jaco Greeff fb08215e0d Add Fixed128 type (#2175) 2020-04-15 18:15:11 +02:00
Github Actions d7d7ab2f89 [CI Skip] 1.11.0-beta.14
skip-checks: true
2020-04-15 08:54:43 +00:00
Jaco Greeff 25393cd982 Add note on field ordering (#2173)
* Add note on field ordering

* Field ordering additional links
2020-04-15 10:43:15 +02:00
Github Actions d6a6089e2d [CI Skip] 1.11.0-beta.13
skip-checks: true
2020-04-15 06:55:53 +00:00
Jaco Greeff a3eaca0270 Small doc cleanups (#2172) 2020-04-15 08:44:15 +02:00
Github Actions f9d1b4d653 [CI Skip] 1.11.0-beta.12
skip-checks: true
2020-04-14 20:22:21 +00:00
Jaco Greeff f81712343a Transaction batching (#2171) 2020-04-14 22:10:25 +02:00
Github Actions 33e414be12 [CI Skip] 1.11.0-beta.11
skip-checks: true
2020-04-14 16:27:55 +00:00
Jaco Greeff 9387103558 cookbook link 2020-04-14 18:15:28 +02:00
Github Actions 3b7c1afa95 [CI Skip] 1.11.0-beta.10
skip-checks: true
2020-04-14 15:28:01 +00:00
Jaco Greeff 7e1fa8954b Extend storage cookbook (#2169)
* Extend storage cookbook

* Update storage.md

* Update storage.md
2020-04-14 17:16:46 +02:00
Github Actions 53c62f1542 [CI Skip] 1.11.0-beta.9
skip-checks: true
2020-04-14 14:56:23 +00:00
Jaco Greeff 5ed94a50e1 Update .123trigger 2020-04-14 16:45:30 +02:00
Github Actions b1c047149b [CI Skip] 1.11.0-beta.8
skip-checks: true
2020-04-14 14:35:37 +00:00
Jaco Greeff 7a0efaf58c Kusama 1057 known types (#2168) 2020-04-14 16:24:19 +02:00
Github Actions 5acce98346 [CI Skip] 1.11.0-beta.7
skip-checks: true
2020-04-14 11:52:00 +00:00
Jaco Greeff 165179ebf2 Remove flags on derive.accounts.info (#2167)
* Remove flags from derive.account.info

* adjust types
2020-04-14 13:40:12 +02:00
Github Actions def60dce9e [CI Skip] 1.11.0-beta.6
skip-checks: true
2020-04-14 10:49:12 +00:00
Jaco Greeff c8f91fcf7a Parameterize DoNotConstruct (#2165)
* Parameterize DoNotConstruct

* Update DoNotConstruct list

* typo fix
2020-04-14 12:37:30 +02:00
Github Actions 70a160cca0 [CI Skip] 1.11.0-beta.5
skip-checks: true
2020-04-14 10:31:23 +00:00
Jaco Greeff 9691fd5ba7 don't subscribe to runtime updates with no subs (#2166) 2020-04-14 12:20:07 +02:00
Jaco Greeff 475cb4fa69 Move Digest to interfaces (#2164)
* Move Digest to interfaces

* Unconstructable typos
2020-04-14 12:09:36 +02:00
Github Actions 5c54b3cc92 [CI Skip] 1.11.0-beta.4
skip-checks: true
2020-04-14 10:05:31 +00:00
Jaco Greeff 55d8c58d95 Add transactionVerions to RuntimeVersion struct (#2163) 2020-04-14 11:54:42 +02:00
Github Actions edf8adaa88 [CI Skip] 1.11.0-beta.3
skip-checks: true
2020-04-14 08:49:43 +00:00
Jaco Greeff 1f8f6e54bd Add unsigned sending to cookbook (#2162)
* Add unsigned sending to cookbook

* Block author extraction example
2020-04-14 10:36:15 +02:00
Github Actions f6ca7b9a9d [CI Skip] 1.11.0-beta.2
skip-checks: true
2020-04-14 07:52:33 +00:00
Jaco Greeff 7732339fc0 Line lengths 2020-04-14 09:41:04 +02:00
Jaco Greeff 5a8a8c7ecb Fix cookbook links 2020-04-14 09:34:39 +02:00
Github Actions 05df087e73 [CI Skip] 1.11.0-beta.1
skip-checks: true
2020-04-14 06:58:37 +00:00
Jaco Greeff 5b71abfe80 Make a start at a cookbook... still loads to go (#2160) 2020-04-14 08:48:14 +02:00
Github Actions 1d6c33060a [CI Skip] 1.11.0-beta.0
skip-checks: true
2020-04-13 10:45:21 +00:00
Jaco Greeff eae573e6a2 Simplify entries() decoding (#2159) 2020-04-13 12:33:24 +02:00
Github Actions 0f08031792 [CI Skip] 1.10.1
skip-checks: true
2020-04-13 05:28:25 +00:00
Jaco Greeff e0bde927d1 1.10 (#2158)
* 1.10

* CHANGELOG

* key extract example
2020-04-13 07:16:43 +02:00
Github Actions e569de520a [CI Skip] 1.10.0-beta.29
skip-checks: true
2020-04-11 20:32:39 +00:00
Jaco Greeff a833dccdaf All private prefixed with _ (#2157)
* All private prefixed with _

* Fix test
2020-04-11 22:21:55 +02:00
Github Actions b58d772156 [CI Skip] 1.10.0-beta.28
skip-checks: true
2020-04-10 16:17:30 +00:00
Jaco Greeff e5d9bbc264 Filter old rewards with stakingLedger (ledger can update) (#2155)
* Filter old rewards with stakingLedger (ledger can update)

* Cleanup internal functions
2020-04-10 18:06:14 +02:00
Github Actions 3089529405 [CI Skip] 1.10.0-beta.27
skip-checks: true
2020-04-10 12:41:15 +00:00
Jaco Greeff 5ab24390c5 Indicate all protected members and variables (#2154)
* Indicate all protected members and variables

* Added dropped protected
2020-04-10 14:29:58 +02:00
Github Actions 245047a41f [CI Skip] 1.10.0-beta.26
skip-checks: true
2020-04-10 12:04:49 +00:00
Jaco Greeff 8aa1bd5bd0 Indicate protected raw with _raw in Base codec (#2153) 2020-04-10 13:54:15 +02:00
Github Actions e0dde35621 [CI Skip] 1.10.0-beta.25
skip-checks: true
2020-04-10 10:23:42 +00:00
Jaco Greeff 9ba91a3851 Use forkJoin for entries() retrieval (#2152)
* Use forkJoin for entries() retrieval

* Some current and validator retrieval opts

* Remove duplicate filtering
2020-04-10 12:12:10 +02:00
Github Actions 351cb97667 [CI Skip] 1.10.0-beta.24
skip-checks: true
2020-04-09 16:44:08 +00:00
Jaco Greeff afdb476796 Small cleanups & consistency (#2151)
* Small cleanups & consistency

* Fixes
2020-04-09 18:32:30 +02:00
Github Actions 3b67b65091 [CI Skip] 1.10.0-beta.23
skip-checks: true
2020-04-09 13:55:22 +00:00
Jaco Greeff 25580b2026 Update CHANGELOG, bump deps (#2150) 2020-04-09 15:44:07 +02:00
Github Actions 2db16e94b7 [CI Skip] 1.10.0-beta.22
skip-checks: true
2020-04-09 12:57:00 +00:00
Jaco Greeff 9184268c3d Bump metadata (#2148)
* Bump metadata

* Adjust to non-customized democracy params
2020-04-09 14:46:48 +02:00
Github Actions 83a762af1e [CI Skip] 1.10.0-beta.21
skip-checks: true
2020-04-09 12:39:49 +00:00
Jaco Greeff 6a8e5370b6 Add system_chainType RPC (#2149) 2020-04-09 14:28:43 +02:00
Github Actions 9cd4bf7cf7 [CI Skip] 1.10.0-beta.20
skip-checks: true
2020-04-09 07:31:24 +00:00
Jaco Greeff c4708dcfca Cleanup isPassing (#2147) 2020-04-09 09:19:56 +02:00
Github Actions 041d06a6c8 [CI Skip] 1.10.0-beta.19
skip-checks: true
2020-04-08 19:58:30 +00:00
Jaco Greeff 2b4bd75499 Adjust calc with turnout add/sub 2020-04-08 21:47:22 +02:00
Github Actions c4c47a84e1 [CI Skip] 1.10.0-beta.18
skip-checks: true
2020-04-08 15:36:45 +00:00
Jaco Greeff a241bd1c38 Adjust change calc (#2145) 2020-04-08 17:23:59 +02:00
Github Actions d420cede82 [CI Skip] 1.10.0-beta.17
skip-checks: true
2020-04-08 14:04:37 +00:00
Jaco Greeff b869695e40 Bump util (#2144) 2020-04-08 15:55:04 +02:00
Github Actions 37caf4e710 [CI Skip] 1.10.0-beta.16
skip-checks: true
2020-04-07 19:23:34 +00:00
Jaco Greeff 134bc22463 Westend (spec) 2020-04-07 21:11:37 +02:00
Github Actions 39d142876e [CI Skip] 1.10.0-beta.15
skip-checks: true
2020-04-07 18:42:57 +00:00
Jaco Greeff 6d95eb418d Westend (again) 2020-04-07 20:31:16 +02:00
Github Actions e26a6a28ff [CI Skip] 1.10.0-beta.14
skip-checks: true
2020-04-07 18:10:26 +00:00
Jaco Greeff d80d6f2a06 Westend update (#2143) 2020-04-07 19:59:08 +02:00
Github Actions ff8dabb249 [CI Skip] 1.10.0-beta.13
skip-checks: true
2020-04-07 09:30:13 +00:00
Jaco Greeff e7a01f9780 Dump dev (incl. eslint header checks) (#2142) 2020-04-07 11:20:07 +02:00
Github Actions 94938c7075 [CI Skip] 1.10.0-beta.12
skip-checks: true
2020-04-06 10:43:28 +00:00
Jaco Greeff f37e729605 Use bumbled node (#2141) 2020-04-06 12:32:05 +02:00
Github Actions 9cfde73ff8 [CI Skip] 1.10.0-beta.11
skip-checks: true
2020-04-05 10:23:01 +00:00
Jaco Greeff f5c140d1c2 Split derive.staking.currentPoints from overview (#2140) 2020-04-05 12:12:03 +02:00
Github Actions 472e1022d3 [CI Skip] 1.10.0-beta.10
skip-checks: true
2020-04-05 08:15:44 +00:00
Jaco Greeff f71211f5dc Bump deps (#2139) 2020-04-05 10:05:50 +02:00
Github Actions 7e06974f1b [CI Skip] 1.10.0-beta.9
skip-checks: true
2020-04-04 17:16:19 +00:00
Jaco Greeff f95384d9ff Bump deps (#2138)
* Bump deps

* Add lockfile :)
2020-04-04 19:04:42 +02:00
Github Actions baedd5b689 [CI Skip] 1.10.0-beta.8
skip-checks: true
2020-04-04 16:36:28 +00:00
Jaco Greeff 9ec1cb194a Update StakingLedger (simpl payouts) (#2102)
* Update StakingLedger (simpl payouts)

* Chain defs

* Allow stakers queries with exclude filter

* Generate interfaces

* Return all exposures

* Rework exposures

* Cleanups
2020-04-04 18:25:32 +02:00
Github Actions d730310ea5 [CI Skip] 1.10.0-beta.7
skip-checks: true
2020-04-03 12:58:06 +00:00
Jaco Greeff 641fe5c380 Refresh on scheduler entries (#2135)
* Refresh on scheduler entries

* Cleanups
2020-04-03 14:47:39 +02:00
Github Actions c5a8d5e018 [CI Skip] 1.10.0-beta.6
skip-checks: true
2020-04-03 11:40:23 +00:00
Jaco Greeff 02d130f0a0 Add Mandatory to DispatchClass (#2134) 2020-04-03 13:29:07 +02:00
Github Actions 5554f17f05 [CI Skip] 1.10.0-beta.5
skip-checks: true
2020-04-02 18:55:29 +00:00
Jaco Greeff 69351ceb9e Cater for new dispatch scheduler (#2130)
* Cater for new dispatch scheduler

* Updated

* debug logs

* Update types.ts
2020-04-02 20:44:27 +02:00
Github Actions 0cf9fa7405 [CI Skip] 1.10.0-beta.4
skip-checks: true
2020-04-02 14:27:07 +00:00
Jaco Greeff 8213fa7cb9 Add validator total to staker rewards (#2129)
* Add validator total to staker rewards

* yarn rewrite
2020-04-02 16:16:10 +02:00
Github Actions 8ef983169f [CI Skip] 1.10.0-beta.3
skip-checks: true
2020-04-02 09:24:58 +00:00
Jaco Greeff e392dd745e Base centrifuge types (#2125) 2020-04-02 11:15:28 +02:00
Github Actions 6b07a9c2a5 [CI Skip] 1.10.0-beta.2
skip-checks: true
2020-04-02 07:46:55 +00:00
Jaco Greeff 114ac59707 Reword FAQ 2020-04-02 09:35:16 +02:00
Github Actions 3c95bfe56e [CI Skip] 1.10.0-beta.1
skip-checks: true
2020-04-01 22:00:58 +00:00
Jaco Greeff 58de0b8b9c Rewrite yarn.lock (#2127) 2020-04-01 23:49:56 +02:00
Github Actions 1f97c5e9e3 [CI Skip] 1.10.0-beta.0
skip-checks: true
2020-04-01 20:54:58 +00:00
Jaco Greeff 0dc46445bc Bump dev (incl. lint fixes) (#2126)
* Bump dev (incl. lint fixes)

* Fix call encoding (stepped into that one)

* Event struct order

* Update with missing tuple type (getTypeDef type)
2020-04-01 22:44:34 +02:00
Github Actions 7d3464ae2c [CI Skip] 1.9.1
skip-checks: true
2020-04-01 10:26:10 +00:00
Jaco Greeff 295cd2a7e0 1.9 (#2124) 2020-04-01 12:14:00 +02:00
Github Actions 5a66ce5a87 [CI Skip] 1.9.0-beta.27
skip-checks: true
2020-04-01 08:01:14 +00:00
Jaco Greeff d8d008108d CI scripts (#2123) 2020-04-01 09:49:16 +02:00
Github Actions 491518405d [CI Skip] 1.9.0-beta.26
skip-checks: true
2020-03-31 13:18:37 +00:00
Jaco Greeff 7290b3d296 sanitize options (allowNamespaces) (#2122)
* sanitize options (allowNamespaces)

* Pass actual option to test
2020-03-31 15:07:35 +02:00
Github Actions b6162a316f [CI Skip] 1.9.0-beta.25
skip-checks: true
2020-03-31 13:06:05 +00:00
Jaco Greeff 71c1d16dc4 Bump @polkadot/util (#2121) 2020-03-31 14:54:49 +02:00
Github Actions 204f592bea [CI Skip] 1.9.0-beta.24
skip-checks: true
2020-03-31 11:52:59 +00:00
Jaco Greeff 39c44bb5aa Split @polkadot/types/known into @polkadot/types-known (#2120)
* Split @polkadot/types/known into @polkadot/types-known

* Rreadme link

* tsconfig typo

* script aliasses
2020-03-31 13:40:59 +02:00
Github Actions df0de49a67 [CI Skip] 1.9.0-beta.23
skip-checks: true
2020-03-31 07:28:28 +00:00
Jaco Greeff 0bdbf4b7a7 Use querystorageAt for map entries (optional) (#2119) 2020-03-31 09:17:36 +02:00
Github Actions ef9cd6fc4b [CI Skip] 1.9.0-beta.22
skip-checks: true
2020-03-30 16:33:11 +00:00
Jaco Greeff 5ab0bf3998 Aplit derive session.{info, progress} (#2117) 2020-03-30 18:20:34 +02:00
Github Actions e69d97619e [CI Skip] 1.9.0-beta.21
skip-checks: true
2020-03-30 12:04:00 +00:00
Jaco Greeff 6aa0d90fc0 Add childstate_* RPCs (#2065)
* Add childstate_* RPCs

* childstate into rpc-core

* PrefixedStorageKey
2020-03-30 13:53:33 +02:00
Jaco Greeff d338fcb58c Add derive for council voting info (#2115)
* Add derive for council voting info

* Update packages/api-derive/src/council/votes.ts
2020-03-30 13:48:14 +02:00
Github Actions b9a60a2519 [CI Skip] 1.9.0-beta.20
skip-checks: true
2020-03-28 21:06:18 +00:00
Jaco Greeff 7b8b4e8078 BTreeSet only has single sub (#2114) 2020-03-28 21:55:49 +01:00
Github Actions 50b551e4fc [CI Skip] 1.9.0-beta.19
skip-checks: true
2020-03-28 20:06:12 +00:00
Jaco Greeff a4ea4d648a Handle double-encoded Bytes in fallback/constants (#2113)
* Handle double-encoded Bytes in fallback/constants

* Fix import, bypass for tests
2020-03-28 20:55:39 +01:00
Github Actions 146360a454 [CI Skip] 1.9.0-beta.18
skip-checks: true
2020-03-27 20:00:32 +00:00
Jaco Greeff 2e83d92adc Derive for deomcracy nextExternal (#2108) 2020-03-27 20:49:18 +01:00
Github Actions b77e5d079c [CI Skip] 1.9.0-beta.17
skip-checks: true
2020-03-27 17:10:21 +00:00
Jaco Greeff 0d067c9484 Add api.derive.democracy.dispatchQueue (#2107) 2020-03-27 17:59:22 +01:00
Github Actions 88519eff3f [CI Skip] 1.9.0-beta.16
skip-checks: true
2020-03-27 14:44:07 +00:00
Jaco Greeff bb14471e60 Consistency in Derive* type names (#2106) 2020-03-27 15:34:41 +01:00
Github Actions 97ab7fcf2f [CI Skip] 1.9.0-beta.15
skip-checks: true
2020-03-27 13:18:21 +00:00
Jaco Greeff 922cfb8759 FAQ entry for node-template addresses (#2105) 2020-03-27 14:07:51 +01:00
Github Actions 717f33ca02 [CI Skip] 1.9.0-beta.14
skip-checks: true
2020-03-27 12:36:19 +00:00
Jaco Greeff 21a2b5f0b7 signAndSend with finalized hash (depending on lag) (#2104)
* signAndSend with finalized hash (depending on drift)

* Extract lag calc

* mock update

* getSigningHeader

* api.derive.tx (with submittable cleanups)

* Adjust mortal calculations

* Cleanup new tx derives

* Optimize calcs

* Comment cleanups, next-up testing

* Adjust mocks

* Adjust sig (period is now based on metadata)

* Remove extra fn, tested and it works
2020-03-27 13:26:12 +01:00
Github Actions 54efead9d7 [CI Skip] 1.9.0-beta.13
skip-checks: true
2020-03-27 09:29:42 +00:00
Jaco Greeff c472a451a4 Bump dev (#2103)
* Bump dev

* Rewrite yarn.lock
2020-03-27 10:20:02 +01:00
Github Actions 6ed2de43fc [CI Skip] 1.9.0-beta.12
skip-checks: true
2020-03-26 20:20:55 +00:00
Jaco Greeff 8976ded37f Add state_queryStorageAt RPC (#2082)
* Add state_queryStorageAt RPC

* Add queryStorageAt rpc

* Clanup merge
2020-03-26 21:08:34 +01:00
Github Actions 169a374544 [CI Skip] 1.9.0-beta.11
skip-checks: true
2020-03-26 15:52:15 +00:00
Jaco Greeff 6476d88e19 Update .123trigger 2020-03-26 16:40:34 +01:00
Github Actions 75de454619 [CI Skip] 1.9.0-beta.10
skip-checks: true
2020-03-26 15:35:59 +00:00
Jaco Greeff 851428aef9 Merge branch 'master' of github.com:polkadot-js/api 2020-03-26 16:25:50 +01:00
Jaco Greeff dfc51ad300 Adjust toCallsOnly typing 2020-03-26 16:25:45 +01:00
Github Actions e16d288644 [CI Skip] 1.9.0-beta.9
skip-checks: true
2020-03-26 15:18:52 +00:00
Jaco Greeff a19928fef9 Add additional types for offchain Phragmen (#2097)
* Add additional types for offchain Phragmen

* Trim down metadata toCallsOnly
2020-03-26 16:07:54 +01:00
Github Actions 0906c7837a [CI Skip] 1.9.0-beta.8
skip-checks: true
2020-03-26 14:27:21 +00:00
Jaco Greeff cb9831c4f8 Bump metadata (#2096)
* Bump metadata

* Update staking types

* Enum updates
2020-03-26 15:17:20 +01:00
Github Actions 620d3757ba [CI Skip] 1.9.0-beta.7
skip-checks: true
2020-03-25 13:14:24 +00:00
Jaco Greeff 601288b3ec Handle <module>::<Type> in sanitize (#2094)
* Handle <module>::<Type> in santize

* Sanitize all ::'s

* Additional cleanups
2020-03-25 14:01:24 +01:00
Github Actions efbeecc8f6 [CI Skip] 1.9.0-beta.6
skip-checks: true
2020-03-25 10:18:50 +00:00
Jaco Greeff 852e0d4f0b Additional referendum derive cleanups (#2093) 2020-03-25 11:06:16 +01:00
Github Actions 5c7f9f1c8a [CI Skip] 1.9.0-beta.5
skip-checks: true
2020-03-25 08:54:57 +00:00
Jaco Greeff 64f64c1001 Add referensumsActive (#2091) 2020-03-25 09:43:05 +01:00
Github Actions 15c3085511 [CI Skip] 1.9.0-beta.4
skip-checks: true
2020-03-25 08:34:25 +00:00
Jaco Greeff 27cd9b1ca4 Cleanup interfaces/rpc, types to correct locations (#2084)
* Cleanup interfaces/rcp, types to correct locations

* Update import locations
2020-03-25 09:23:03 +01:00
Github Actions 1c2a95f820 [CI Skip] 1.9.0-beta.3
skip-checks: true
2020-03-25 07:52:42 +00:00
Jaco Greeff 8bf5e51725 Return Observable when no referendums (#2090)
* Return Observable when no referendums

* Small ordering cleanups
2020-03-25 08:41:26 +01:00
Github Actions 493225aa9d [CI Skip] 1.9.0-beta.2
skip-checks: true
2020-03-25 07:12:03 +00:00
Jaco Greeff a0979a9ce3 Only format error log, upstream error from core (#2089)
* Only format error log, upstream error from core

* Remove (now unused) wrapping info
2020-03-25 08:00:14 +01:00
Github Actions 02849ae49b [CI Skip] 1.9.0-beta.1
skip-checks: true
2020-03-24 16:50:32 +00:00
Jaco Greeff 602bb1406b derive.referendum extended info (#2086)
* derive.referendum extended info

* update

* util bump
2020-03-24 17:39:37 +01:00
Github Actions d70930587c [CI Skip] 1.9.0-beta.0
skip-checks: true
2020-03-23 10:37:30 +00:00
Jaco Greeff 8c011cdc86 Adjust new vote retrieval with entries (#2080)
* Adjust new vote retrieval with entries

* testing
2020-03-23 11:24:06 +01:00
Github Actions eb3e7a0740 [CI Skip] 1.8.1
skip-checks: true
2020-03-22 17:58:16 +00:00
Jaco Greeff 2071de517d 1.8 (#2079) 2020-03-22 18:47:04 +01:00
Github Actions 205ae40f20 [CI Skip] 1.8.0-beta.12
skip-checks: true
2020-03-22 17:27:07 +00:00
Keith IngramandJaco Greeff aa37e372dd Derived account info flags (#2068)
* Derived account info flags

* Update packages/api-derive/src/accounts/info.ts

Co-Authored-By: Jaco Greeff <jacogr@gmail.com>

* Apply suggestions from code review

* Cleanups

Co-authored-by: Jaco Greeff <jacogr@gmail.com>
2020-03-22 18:16:43 +01:00
Github Actions 8cdac77a8e [CI Skip] 1.8.0-beta.11
skip-checks: true
2020-03-22 10:15:48 +00:00
Jaco Greeff 7a7d6e9b8a New democracy types (#2078)
* New democracy types

* ReferendumInfo

* Adjust democracy derives

* Spring cleaning

* Remove ReferendumInfoExtended
2020-03-22 11:05:57 +01:00
Github Actions 7a1bdb18a8 [CI Skip] 1.8.0-beta.10
skip-checks: true
2020-03-22 06:57:07 +00:00
Jaco Greeff 39f22ca403 Control wasm initialization via initWasm: false flag (#2076) 2020-03-22 07:45:22 +01:00
Github Actions b3c6a5acc5 [CI Skip] 1.8.0-beta.9
skip-checks: true
2020-03-22 06:43:14 +00:00
Jaco Greeff b3a6b3dcb5 Bump dev, arrow functions (#2077) 2020-03-22 07:31:55 +01:00
Github Actions 0c0e4c4d7c [CI Skip] 1.8.0-beta.8
skip-checks: true
2020-03-21 08:51:26 +00:00
Jaco Greeff 9d67d711d4 Bump deps, type import on generated (#2075)
* Bump deps, type import on generated

* type imports in types/types

* Re-export defs

* Split imports/exports

* Additional type import

* Remove import type

* Remove dupes
2020-03-21 09:40:59 +01:00
Github Actions f45d03fa17 [CI Skip] 1.8.0-beta.7
skip-checks: true
2020-03-21 07:00:35 +00:00
Jaco Greeff af11444b72 Update RPCs (babe, contracts) (#2074)
* Update RPCs (babe, contracts)

* Babe in rpc-core
2020-03-21 07:50:56 +01:00
Github Actions f412a5ac86 [CI Skip] 1.8.0-beta.6
skip-checks: true
2020-03-20 16:50:04 +00:00
Jaco Greeff c9dcd51ba6 is isWarning to ISubmittableResult (#2073) 2020-03-20 17:40:09 +01:00
Jaco Greeff 5dca826429 Retracted status to isWarning 2020-03-20 17:27:18 +01:00
Github Actions 8dc53e6339 [CI Skip] 1.8.0-beta.5
skip-checks: true
2020-03-20 15:41:13 +00:00
Jaco Greeff 5867f8ab0c Allow unknown struct fields (i.e. on Map, non-codec) (#2071) 2020-03-20 16:30:29 +01:00
Github Actions 6d3db2fb3f [CI Skip] 1.8.0-beta.4
skip-checks: true
2020-03-20 12:52:46 +00:00
Jaco Greeff 3a1634d67f Add all missing RPC endpoints (#2070)
* Add all missing RPC endpoints

* Rework RPC return types

* rpc-core interface

* Remove crap test, checked anyway
2020-03-20 13:42:18 +01:00
Github Actions 53d18d874d [CI Skip] 1.8.0-beta.3
skip-checks: true
2020-03-19 13:51:15 +00:00
Jaco Greeff 044efbc6de Convert jsonrpc & typings to definitions (#2064)
* Convert jsonrpc & typings to definitions

* Handle empty interface generation (no types)

* Move jsonrpc/create to rpc-core/create

* Create imports

* Remove jsonrpc package, generate rpc-core from defs

* Debug :)

* Generate RPC definitions via interfaces

* Generate md docs

* Remove @polkadot/jsonrpc refs (at least packages)

* No empty types

* Add PAHNTOM "cleanup" gen

* *sigh* regex loop

* Update mock for no jsonrpc

* Add definition export types

* Cleanup linting

* Mocking 1 fix

* Mocking 2 fix

* rpc-core tests updates

* CHANGELOG & docs

* Add jsonrpc (already mapped) to interfaces

* Add aliasses for RPCs

* Fix rpc-core tests
2020-03-19 14:40:54 +01:00
Github Actions 27e3fbfd0f [CI Skip] 1.8.0-beta.2
skip-checks: true
2020-03-18 21:50:49 +00:00
Jaco Greeff b7af4781ea Add Initialization to extrinsic phases (#2063) 2020-03-18 22:40:53 +01:00
Github Actions c51e351117 [CI Skip] 1.8.0-beta.1
skip-checks: true
2020-03-17 23:18:54 +00:00
Jaco Greeff e6afed9bb1 Allow electedInfo commition with/without linked maps (#2060) 2020-03-18 00:08:49 +01:00
Github Actions 4b07d5511e [CI Skip] 1.8.0-beta.0
skip-checks: true
2020-03-17 18:46:06 +00:00
Jaco Greeff a613308bdb Update 2020-03-17 19:34:51 +01:00
Jaco Greeff a863e5eb95 Non-array nominators 2020-03-17 19:22:16 +01:00
Github Actions 623420ca3d [CI Skip] 1.7.1
skip-checks: true
2020-03-17 13:49:41 +00:00
Jaco Greeff 9ea6053a42 1.7 (#2059) 2020-03-17 14:39:20 +01:00
Github Actions 73dce6bfd1 [CI Skip] 1.7.0-beta.19
skip-checks: true
2020-03-17 09:48:02 +00:00
Jaco Greeff 5a7811c80f Bump metadata (#2058)
* Bump metadata

* Add missing @types/jest

* Update tests for new metadata

* CHANGELOG for linked map removals

* expand re-added check
2020-03-17 10:37:24 +01:00
Github Actions 1c529bdc6a [CI Skip] 1.7.0-beta.18
skip-checks: true
2020-03-16 14:47:43 +00:00
Jaco Greeff 3f4576f524 Add yarn matrix (#2057) 2020-03-16 15:37:23 +01:00
Github Actions 2619489ec3 [CI Skip] 1.7.0-beta.17
skip-checks: true
2020-03-16 13:59:34 +00:00
Jaco Greeff f165845cc3 Collapse actions matrix (#2056) 2020-03-16 14:49:31 +01:00
Github Actions 897f03e4c1 [CI Skip] 1.7.0-beta.16
skip-checks: true
2020-03-16 10:24:34 +00:00
Jaco Greeff 82c1e3f35a Cater for new non-linked map validator queries (#2055)
* Cater for new non-linked map validator queries

* Update staking tests

* stakers -> stashes
2020-03-16 11:13:46 +01:00
Github Actions c06f260d3c [CI Skip] 1.7.0-beta.15
skip-checks: true
2020-03-16 07:23:55 +00:00
Jaco Greeff 63573ca0de Add ownExposure & ownSlashes (#2054) 2020-03-16 08:15:00 +01:00
Github Actions bf1a5f0d91 [CI Skip] 1.7.0-beta.14
skip-checks: true
2020-03-15 19:39:52 +00:00
Wei Tang 1750522cb6 Use /usr/bin/env bash instead of /bin/bash (#2053) 2020-03-15 20:29:45 +01:00
Github Actions ed3b507ea6 [CI Skip] 1.7.0-beta.13
skip-checks: true
2020-03-15 17:00:01 +00:00
Jaco Greeff f942510309 Expose stakerSlahes & eraSlashes (#2052) 2020-03-15 17:49:15 +01:00
Github Actions 09a9153645 [CI Skip] 1.7.0-beta.12
skip-checks: true
2020-03-15 09:03:36 +00:00
Jaco Greeff 908d0fcf52 Add missing commission to payout calculations (#2051)
* Add missing comission to payout calcs

* yarn

* Bump dev with version update fix
2020-03-15 09:51:52 +01:00
Github Actions 707c93a557 [CI Skip] 1.7.0-beta.11
skip-checks: true
2020-03-15 07:36:51 +00:00
Jaco Greeff 82addc4f6a Remove non-working CI cache (#2050) 2020-03-15 08:26:34 +01:00
Github Actions d595eb440c [CI Skip] 1.7.0-beta.10
skip-checks: true
2020-03-14 08:49:03 +00:00
Jaco Greeff e86fe5bab0 Bump deps (#2048) 2020-03-14 09:37:28 +01:00
Github Actions 7187dca2f7 [CI Skip] 1.7.0-beta.9
skip-checks: true
2020-03-13 20:17:16 +00:00
Jaco Greeff 94a3b1f09a eraPoints args (#2047) 2020-03-13 21:05:40 +01:00
Github Actions d88b300a6d [CI Skip] 1.7.0-beta.8
skip-checks: true
2020-03-13 18:52:54 +00:00
Jaco Greeff dd217f82b2 Chunk keys & values retrievals on keys()/entries() (#2046)
* Chunk keys & values retrievals on keys()/entries()

* Bump chunk sizes

* Fix concatMap index

* Update mock
2020-03-13 19:40:57 +01:00
Github Actions 3b4cee08e2 [CI Skip] 1.7.0-beta.7
skip-checks: true
2020-03-13 17:07:31 +00:00
Joshy Orndorff 34be2399eb Couple little typo fixes (#2045) 2020-03-13 17:54:29 +01:00
Github Actions 27d879a325 [CI Skip] 1.7.0-beta.6
skip-checks: true
2020-03-13 12:51:33 +00:00
Jaco Greeff 4093ef9ffa Add Identity hasher (#2044)
* Add Identity hasher

* Expand new V11 storage types

* Cleanups, use actual enum keys

* Sort augmented output (fy-by enhancement)

* Map get

* DEFAULT_FN
2020-03-13 13:39:34 +01:00
Github Actions 261eebee03 [CI Skip] 1.7.0-beta.5
skip-checks: true
2020-03-13 11:45:14 +00:00
Jaco Greeff d9dad3566a Use asyncScheduler for all derives (#2043) 2020-03-13 12:32:42 +01:00
Github Actions 3d0fdbd6da [CI Skip] 1.7.0-beta.4
skip-checks: true
2020-03-13 07:56:43 +00:00
Jaco Greeff affa5d390c Expose derive staking.nextElected (#2042) 2020-03-13 08:45:28 +01:00
Github Actions 1659e672ae [CI Skip] 1.7.0-beta.3
skip-checks: true
2020-03-13 07:05:20 +00:00
Jaco Greeff 0fa6b99c9e Query docs with entries & keys, submittable with paymentInfo (#2041) 2020-03-13 07:52:53 +01:00
Github Actions ef9db7bf78 [CI Skip] 1.7.0-beta.2
skip-checks: true
2020-03-13 05:45:54 +00:00
Jaco Greeff 8c6505d870 Map signs directly to H512 (no indirection) (#2038) 2020-03-13 06:34:46 +01:00
Github Actions 48f83c7d5b [CI Skip] 1.7.0-beta.1
skip-checks: true
2020-03-12 21:11:11 +00:00
Jaco Greeff f3c2c5c084 Re-enable argument checks (dropped in 1.6.2) (#2035)
* Re-enable argument checks (dropped in 1.6.2)

* typo

* Bump to preminor
2020-03-12 21:58:57 +01:00
Jaco Greeff 98e1cc3f73 Add staking.eraExposure derive (#2036) 2020-03-12 21:57:17 +01:00
Github Actions 4fd74a04c8 [CI Skip] 1.6.2
skip-checks: true
2020-03-12 14:03:53 +00:00
Jaco Greeff 421594b0eb Fix .at check, disable (release 1.6.2) (#2034)
* Fix .at check, disable (release 1.6.2)

* Remove isAt (keep at revert only)

* Grrr....

* yarn installl (really need to add this to version bump script)
2020-03-12 14:53:25 +01:00
Github Actions 2e79c25da1 [CI Skip] 1.6.1
skip-checks: true
2020-03-12 09:10:00 +00:00
Jaco Greeff ca2a313aec 1.6 (#2031)
* 1.6 CHANGELOG

* 1.6

* yarn
2020-03-12 09:57:09 +01:00
Github Actions 693315dad3 [CI Skip] 1.6.0-beta.30
skip-checks: true
2020-03-12 08:22:52 +00:00
Jaco Greeff c2f9ef7ca8 Add .keys on storage entries (#2032)
* Add .keys on storage entries

* Pass isOptional to storage type unwrap

* Linked maps TS types
2020-03-12 09:12:11 +01:00
Github Actions fc477b98bd [CI Skip] 1.6.0-beta.29
skip-checks: true
2020-03-12 06:41:19 +00:00
Jaco Greeff b8cdfd226a Validate storage args (#1507)
* Validate storage args

* Fix linting

* Update imports

* Update type extraction

* Move storage extraction to util

* Re-add CHANGELOG entry

* Add DoubleMap tests

* Adjust error for linked

* formatting

* Split map/doublemap

* Cleanups

* Update error sigs

* Just join
2020-03-12 07:29:18 +01:00
Github Actions a5725d7bd6 [CI Skip] 1.6.0-beta.28
skip-checks: true
2020-03-11 16:12:55 +00:00
Jaco Greeff 8995ef6ae2 dedupKeyPrefix as const 2020-03-11 17:01:07 +01:00
Github Actions 742baa3dad [CI Skip] 1.6.0-beta.27
skip-checks: true
2020-03-11 15:10:58 +00:00
Jaco Greeff 3a37bf1e6b Add multi variants for derive staking query & rewards (#2029) 2020-03-11 15:59:36 +01:00
Github Actions f4b51f6311 [CI Skip] 1.6.0-beta.26
skip-checks: true
2020-03-11 11:44:04 +00:00
Jaco Greeff a09fc51693 Add stakerRewards for available reward calcs (#2028) 2020-03-11 12:33:12 +01:00
Jaco Greeff 1d8b6a79ef Rework rpc.queryStorage to return [Hash, Codec[]][] (#2025) 2020-03-11 12:21:09 +01:00
Dylan Galea 164a1b6867 Updated users of the polkadot-js/api (#2027)
* Update README.md

Updated the README.md to include the PANIC for Polkadot, and Polkadot API Server projects as users.

* Update README.md

Fixed links.
2020-03-11 12:20:16 +01:00
Keith Ingram 032f2dc040 Remove parachains.watermark (#2026) 2020-03-11 12:18:47 +01:00
Github Actions 3dbe33378c [CI Skip] 1.6.0-beta.25
skip-checks: true
2020-03-11 08:22:30 +00:00
Jaco Greeff bb08ac4a28 Align CHANGELOG, bump @polkadot/util (#2024) 2020-03-11 09:11:29 +01:00
Github Actions 4656d32e22 [CI Skip] 1.6.0-beta.24
skip-checks: true
2020-03-10 18:55:55 +00:00
Jaco Greeff 60c982ed95 Fix range & entries with Option decoding (#2023) 2020-03-10 19:44:50 +01:00
Github Actions cacafab912 [CI Skip] 1.6.0-beta.23
skip-checks: true
2020-03-10 17:07:44 +00:00
Jaco Greeff 99d4806a0d Enable new indexes queries (#2022)
* Enable new indexes queries

* update mock for state_getKeys
2020-03-10 17:56:20 +01:00
Github Actions 59a194a48d [CI Skip] 1.6.0-beta.22
skip-checks: true
2020-03-10 14:17:03 +00:00
Jaco Greeff d818f61dc8 Support new map nextKeys in derives (#2021)
* Support new map nextKeys in derives

* Update packages/api-derive/src/staking/query.ts
2020-03-10 15:07:02 +01:00
Github Actions f1cbfff5a6 [CI Skip] 1.6.0-beta.21
skip-checks: true
2020-03-10 12:27:53 +00:00
Jaco Greeff 92cdc6c840 Query exposure via clipped (#2020) 2020-03-10 13:16:15 +01:00
Github Actions 1ff864ea2f [CI Skip] 1.6.0-beta.20
skip-checks: true
2020-03-10 11:20:22 +00:00
Jaco Greeff 071b5ba7cb Re-add erasRewards (#2019) 2020-03-10 12:09:18 +01:00
Github Actions 2e6d89a093 [CI Skip] 1.6.0-beta.19
skip-checks: true
2020-03-10 07:32:04 +00:00
Jaco Greeff 049a1a59f5 Rework eras* calls with minimum information (#2018) 2020-03-10 08:20:54 +01:00
Github Actions 201098e9f6 [CI Skip] 1.6.0-beta.18
skip-checks: true
2020-03-09 22:07:14 +00:00
Jaco Greeff 423227d385 Merge branch 'master' of github.com:polkadot-js/api 2020-03-09 22:57:13 +01:00
Jaco Greeff c1facd8b1c memo for range & entries 2020-03-09 22:57:09 +01:00
Github Actions 842d371699 [CI Skip] 1.6.0-beta.17
skip-checks: true
2020-03-09 20:52:41 +00:00
Jaco Greeff bcbd4b8d40 linked maps with getStorage only 2020-03-09 21:42:56 +01:00
Github Actions b526873837 [CI Skip] 1.6.0-beta.16
skip-checks: true
2020-03-09 19:19:28 +00:00
Jaco Greeff 6f85c6783e Update .123trigger 2020-03-09 20:07:29 +01:00
Github Actions 672983f6c1 [CI Skip] 1.6.0-beta.15
skip-checks: true
2020-03-09 19:01:22 +00:00
Jaco Greeff 3ee3fb05cc Use first() for entries and linked maps 2020-03-09 19:50:21 +01:00
Github Actions 8ff32d9c1e [CI Skip] 1.6.0-beta.14
skip-checks: true
2020-03-09 17:54:21 +00:00
Jaco Greeff 8ad3d35dd2 Lock all indeeds locks all 2020-03-09 18:44:30 +01:00
Github Actions cb5fdc9078 [CI Skip] 1.6.0-beta.13
skip-checks: true
2020-03-09 13:32:56 +00:00
Jaco Greeff 77d894dd00 reset identityOf 2020-03-09 14:21:06 +01:00
Jaco Greeff 5b40d95b0f Disbale identity (#2016) 2020-03-09 14:12:52 +01:00
Github Actions 385d157f3f [CI Skip] 1.6.0-beta.12
skip-checks: true
2020-03-09 09:23:23 +00:00
Jaco Greeff 81a2a51610 Expose eraReward on derives (#2015) 2020-03-09 10:14:45 +01:00
Github Actions ff8383c5ed [CI Skip] 1.6.0-beta.11
skip-checks: true
2020-03-09 07:38:29 +00:00
Jaco Greeff ca9f671553 Re-format jsonrpc errors (#2014) 2020-03-09 08:27:00 +01:00
Github Actions eb17de0888 [CI Skip] 1.6.0-beta.10
skip-checks: true
2020-03-08 14:32:37 +00:00
Jaco Greeff 110c9d199d Add 'everything' on balance format with max 2020-03-08 15:22:06 +01:00
Github Actions b5cc8f193e [CI Skip] 1.6.0-beta.9
skip-checks: true
2020-03-08 12:30:09 +00:00
Jaco Greeff abebe9ef43 unwrapOr(undefined) for subs 2020-03-08 13:20:05 +01:00
Github Actions e55f69a009 [CI Skip] 1.6.0-beta.8
skip-checks: true
2020-03-08 12:08:20 +00:00
Jaco Greeff 9bf854445c Fix entries values decoding (#2011)
* Fix entries values decoding

* Linting

* Properly unwrap storage subs
2020-03-08 12:57:03 +01:00
Github Actions 17f7e4b753 [CI Skip] 1.6.0-beta.7
skip-checks: true
2020-03-08 08:39:09 +00:00
Jaco Greeff 0a6c6ec4c5 Combine points into stakerRewards (#2008)
* Combine points into stakerRewards

* Bump dev
2020-03-08 09:26:54 +01:00
Github Actions 7456113cef [CI Skip] 1.6.0-beta.6
skip-checks: true
2020-03-08 08:24:46 +00:00
Jaco Greeff 7051e20d59 StorageKey map decoding test (#2009) 2020-03-08 09:13:18 +01:00
Github Actions 79dba43f0f [CI Skip] 1.6.0-beta.5
skip-checks: true
2020-03-07 09:49:05 +00:00
Jaco Greeff 6bb421dac6 Fix StorageKey args throw 2020-03-07 10:37:28 +01:00
Github Actions 0ce28c519f [CI Skip] 1.6.0-beta.4
skip-checks: true
2020-03-06 21:00:28 +00:00
Jaco Greeff cdde702db7 Cover all hashers in map/doublemap key decoding (#2007) 2020-03-06 21:49:09 +01:00
Github Actions 6b4a76b54b [CI Skip] 1.6.0-beta.3
skip-checks: true
2020-03-06 15:28:04 +00:00
Jaco Greeff 57e2a9dc14 No BalanceLock override for Polkadot 2020-03-06 16:18:18 +01:00
Github Actions 798f1e6e91 [CI Skip] 1.6.0-beta.2
skip-checks: true
2020-03-06 15:10:40 +00:00
Jaco Greeff 0e264a029e Polkadot StakingLedger 2020-03-06 15:58:46 +01:00
Github Actions 8745c059f7 [CI Skip] 1.6.0-beta.1
skip-checks: true
2020-03-06 12:57:58 +00:00
Jaco Greeff adee447cd0 Add .args to decoded StorageKeys (#2004)
* Add .args to decoded StorageKeys

* Small opts

* Formatting
2020-03-06 13:47:40 +01:00
Github Actions 63c22414ce [CI Skip] 1.6.0-beta.0
skip-checks: true
2020-03-06 10:18:07 +00:00
Jaco Greeff 89992ea03e Era exposure cleanups via .entries (#2003) 2020-03-06 11:06:10 +01:00
491 changed files with 13558 additions and 8728 deletions
+4 -3
View File
@@ -1,3 +1,4 @@
19
1.4.2
1.4.2
24
1.4.2
1.6.2
1.11.2
+5 -100
View File
@@ -2,110 +2,15 @@ name: PR
on: [pull_request]
jobs:
lint:
name: Linting
runs-on: ubuntu-latest
pr:
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: lint
run: |
yarn install --immutable | grep -v 'YN0013'
yarn lint
test:
name: Testing
step: ['lint', 'test', 'build', 'docs']
name: ${{ matrix.step }}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: test
- name: ${{ matrix.step }}
run: |
yarn install --immutable | grep -v 'YN0013'
yarn test
build_code:
name: Build Code
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: build
run: |
yarn install --immutable | grep -v 'YN0013'
yarn build
build_docs:
name: Build Docs
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: build
run: |
yarn install --immutable | grep -v 'YN0013'
yarn docs
yarn ${{ matrix.step }}
+8 -57
View File
@@ -5,82 +5,33 @@ on:
- master
jobs:
build_code:
name: Build Code
if: "! contains(github.event.head_commit.message, '[CI Skip]')"
runs-on: ubuntu-latest
master:
strategy:
matrix:
node-version: [12.x]
step: ['build:release', 'docs:release']
name: ${{ matrix.step }}
if: "! contains(github.event.head_commit.message, '[CI Skip]') && github.repository == 'polkadot-js/api'"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
token: ${{ secrets.GH_PAT }}
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: build
- name: ${{ matrix.step }}
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
GH_PAGES_SRC: build-docs
GH_PAT: ${{ secrets.GH_PAT }}
GH_TOKEN: ${{ secrets.GH_PAT }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
yarn install --immutable | grep -v 'YN0013'
yarn polkadot-ci-ghact-build
build_docs:
name: Build Docs
if: "! contains(github.event.head_commit.message, '[CI Skip]')"
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Config yarn cache
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: build
env:
GH_PAT: ${{ secrets.GH_PAT }}
GH_TOKEN: ${{ secrets.GH_PAT }}
GH_PAGES_SRC: build-docs
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
yarn install --immutable | grep -v 'YN0013'
yarn polkadot-ci-ghact-docs
yarn ${{ matrix.step }}
dummy:
name: Dummy
if: "contains(github.event.head_commit.message, '[CI Skip]')"
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- name: dummy
run: |
-58
View File
File diff suppressed because one or more lines are too long
Vendored Executable
+50
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -1,4 +1,5 @@
enableImmutableInstalls: false
enableProgressBars: false
nodeLinker: node-modules
@@ -7,4 +8,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.js
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-berry.js
yarnPath: .yarn/releases/yarn-rc.js
+102
View File
@@ -1,3 +1,105 @@
# 1.12.1 Apr 29, 2020
- Fix `CompactAssignments` types (Thanks to https://github.com/arjanz)
- Provider ayo-connect now allows for interval config (Thanks to https://github.com/jnaviask)
- Cleanup generation for c-like enums (Thanks to https://github.com/monitz87)
- Allow subscription to all storage keys, alignment with Substrate (Thanks to https://github.com/xlc)
- Cater for vote delegations in democracy derives
- Cleanup account derive flags where to allow for optional council modules
- Allow generic types in ApiPromise.combineLatest
- Update to latest substrate metadata
# 1.11.2 Apr 22, 2020
- Small patch to add missing Polkadot master types (will be in next Kusama update)
# 1.11.1 Apr 21, 2020
- **Important** Substrate master has an updated `Weight` (to `u64`), on older chains apply `Weight: 'u32'` (This does affect event decoding if wrongly set)
- Allow user type augmentation to work with different versions of rxjs (Thanks to https://github.com/monitz87)
- Align augmented generation with camelCase (Thanks to https://github.com/monitz87)
- Fix bitfield endian encoding (Thanks to investigation by https://github.com/xlc)
- Add account flag derives via `accounts.flags(accountId)` (Thanks to https://github.com/kwingram25)
- Fix entries decoding for `Option<Number>` (& simplify, decoding correctly on rpc layer)
- Add `system.{localPeerId, localListenAddresses}` & `state.getReadProof` RPCs
- Ensure proper propagation of `api.runtimeVersion` (used for signing) after upgrade
- Field ordering fix for deprecated `Linkage` (used in linked maps)
- `derive.account.info` now returns all field enum types decoded (not only raw)
- Add banner with FAQ entries for node-template to aid with common issues
- `Digest` has been moved to definitions, removal of `GenericDigest` type
- Support `Fixed128` type
- Add `transactionVersion` to `RuntimeVersion` struct
- Enhance API support for non-subscription providers (skip subscription to runtimeVersion)
- Adjust types for Kusama 1057 (notably the new `StakingLedger`)
# 1.10.1 Apr 13, 2020
- **Important** Substrate master has updated staking, on older chains apply `StakingLedger: 'StakingLedgerTo240'`
- Add `rpc.system.chainType` to retrieve the chain type (Development. Local, Live & Custom)
- Adjust types for Westend after the reset
- Adjust democracy derives, including the support of the frame-scheduler for scheduled deployments
- Allow staking derives to work with new staking payouts, specifically `tx.staking.payoutStakers`
- Cleanups to derives for democracy & staking to be more performant
- Add Centrifuge base types to `@polkadot/types-known`
- Adjust with all the latest substrate master types
- Internally all private/protected methods/variables are now `_` prefixed (Aligning with the `private/protected` indicators in the TS definitions)
- Update metadata/docs-from-metadata to the latest Substrate
# 1.9.1 Apr 1, 2020
- **Breaking change** (TypeScript with derives only) The return type names for `api.derive.*` have been adjusted for consistency, all starting with `Derive*` (previously a mixture of `Derived*` and `Derive*`)
- **Breaking change** (derives only) Additional cleanups of democracy proposal & referenda derives, including support for new Polkadot/Substrate vote retrievals
- Tx signing via `signAndSend` & `signAsync` now tries to use the last finalized block (depending on finalized drift)
- Add support for `api.rpc.childstate.*` Substrate RPCs, older nodes with still populate `api.rpc.state.*` with the child methods
- Adjust `Error.message` on RPC failures to not include the (already known) method signature
- Split `@polkadot/types/known` into `@polkadot/types-known`, allowing for base API overrides
- Extended `api.derive.democracy` to cater for dispatchQueue and externals
- Extended `api.derive.council` to cater for new phragmen elections
- Use new `queryStorageAt` for query `.entries`, removing unneeded subscriptions (use as available)
- Fix `BTreeSet` initialization when it forms part of query interfaces
- Fix encoding for `Vec<u8>`-related types as part of constants
- Internal adjustment of interface type locations (no impact on imports via `@polkadot/types/interfaces`)
# 1.8.1 Mar 22, 2020
- **Breaking change** The format for any custom RPCs have been changed (alongside API-internal changes) to allow for better RPC management. If you are currently using custom RPCs (or planning to do so), look at the [updated documentation](https://polkadot.js.org/api/start/rpc.custom.html)
- **Breaking change** Alongside API RPC changes, the `@polkadot/jsonrpc` package has been removed. Since it was never documented and only used internally, this should not have adverse impacts. All RPC definitions itself has now been moved to the relevant modules inside `@polkadot/types/interfaces`
- **Important** Substrate has an updated democracy module. If using an older chain add the `ReferendumInfo: 'ReferendumInfoTo239'` type when using referendums
- The `isRetracted` Extrinsic status is now a warning, not a fatal error, correctly aligning with Polkadot/Substrate
- The Substrate extrinsic phase definitions has been expanded with `Initialization` to align with the latest versions
- Add support for all known substrate RPC methods
- Extend account derives to include status flags, e.g. `isCouncil`, `isSudo`, ...
- Adjusted referendum derives to cater for bot new/old democracy. Derived `referendumInfo` now includes `status` field, not `info`
- Add `initWasm` flag to API options. When set to `false` does not init the WASM portion (leaving it to the user elsewhere)
# 1.7.1 Mar 17, 2020
- **Important** Current versions of Polkadot/Substrate have dropped support for linked maps on storage entries. If you are using these queries to retrieve all entries, for instance `staking.{nominators,validators}()` and using an upgraded chain, you need to swap to retrieving entries via `.entries()` or `.keys()` for the keys.
- Pull in support and types for latest Polkadot/Substrate
- Add support for the new Substrate `state_getKeysPaged` RPC, including use in storage keys
- Move `derive.staking.controllers` to `derive.staking.stashes`, reflecting actual content
- Cater for adjusted storage (non-linked mapped) for `derive.staking.stashes` queries (with old-compat)
- Expanded `derive.staking.*` derives, including addition of `derive.staking.own*`
- Re-add fixed (with tests) checks for query args, previously disabled in 1.6.2
# 1.6.2 Mar 12, 2020
- Revert checks for query args, not working on `.at()` queries (proper fix in next version)
# 1.6.1 Mar 12, 2020
- **Breaking change** `api.rpc.state.queryStorage(...)` now fully decodes the `Vec<StorageChangeSet>` and returns a decoded `[Hash, Codec[]][]` when using this RPC.
- `StorageKey` now has an `.args` property, decoded from meta where `twox64_concat` or `blake128_concat` are used on maps
- Fix `api.query.*.*.entries` type conversions to return exact types (not `Option` in some cases)
- Add `api.query.*.*.keys` to retrieve only the storage keys, similar to `.entries`
- Full linked map retrievals will now use direct getStorage queries for faster operation
- Underlying rpc-core interfaces now unwraps `Error("...")` when found in responses
- Added `derive.eras*` interfaces for queries to new Substrate staking interfaces
- Update `derive.account` to cater for new indices module storage (detected with fallbacks)
- Adjust derive queries for session without module prefix (DoubleMap -> Map), detected on use
- Add runtime validation for map arguments to `api.query.*`
- TypeScript interfaces for linked maps now correctly generates as `[Type, Linkage<Next>]`
# 1.5.1 Mar 06, 2020
- **Important** Substrate master has updated staking, on older chains supply `StakingLedger: 'StakingLedgerTo223'`
+4
View File
@@ -1 +1,5 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
module.exports = require('@polkadot/dev/config/babel');
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
function copy_folder () {
SRC="packages/$1/build"
@@ -18,6 +18,6 @@ copy_folder "api-derive"
copy_folder "metadata"
copy_folder "rpc-core"
copy_folder "rpc-provider"
copy_folder "jsonrpc"
copy_folder "types"
copy_folder "types-known"
copy_folder "typegen"
+12
View File
@@ -43,12 +43,24 @@ module.exports = {
['start/api.tx.wrap.md', 'Complex transactions'],
['start/types.basics.md', 'Type basics'],
['start/types.extend.md', 'Extending types'],
['start/rpc.custom.md', 'Custom RPC'],
['start/types.create.md', 'Creating types'],
['start/typescript.md', 'TypeScript interfaces'],
['start/typescript.user.md', 'TypeScript user generated'],
['start/FAQ.md', 'FAQ']
]
},
{
title: 'Cookbook',
path: '/cookbook/',
collapsable: false,
sidebarDepth: 0,
children: [
['cookbook/blocks.md', 'Blocks'],
['cookbook/storage.md', 'Storage'],
['cookbook/tx.md', 'Transactions']
]
},
{
title: 'Examples (Promise API)',
path: '/examples/promise/',
+2 -9
View File
@@ -13,7 +13,7 @@ features:
- title: Types
details: Various type interfaces to make using returned values from API calls transparent in your code.
footer: Apache-2 Licensed | Copyright © 2017-2019 polkadot-js authors and contributors
footer: Apache-2 Licensed | Copyright © 2017-2020 polkadot-js authors and contributors
---
## Welcome
@@ -21,16 +21,9 @@ footer: Apache-2 Licensed | Copyright © 2017-2019 polkadot-js authors and contr
The API provides application developers the ability to query a node and interact with the Polkadot or Substrate chains using Javascript. Here you will find documentation and examples to get you started.
::: tip Getting started & Examples
[Jump right in](/start/) and get an overview on using the API in your projects, from installation all the way through to making it do magic. Already understand how things work and just want the examples? [The ApiPromise examples](/examples/promise/) provide some basic recipies.
[Jump right in](/start/) and get an overview on using the API in your projects, from installation all the way through to making it do magic. Have things working and want tips? The [cookbook](/cookbook/) provides some tips and tricks. Getting started and want some full examples? [The ApiPromise examples](/examples/promise/) provide some basic examples.
:::
## Available packages
This repository split up into a number of internal packages, namely -
- [api](api/README.md) Promise and RxJS-based APIs
- [types](types/README.md) Type encoding and decoding wrappers
## The Polkadot Project
You can read more about the Polkadot Network at [https://polkadot.network/](https://polkadot.network/) and more about the polkadot-js projects at [https://polkadot.js.org](https://polkadot.js.org)
+19
View File
@@ -0,0 +1,19 @@
# Cookbook
The cookbook hosts small code snippets in a question-answer format. It does not walk you through the whole setup, like the [basic examples](../examples/), but rather aims to answer some questions around specific uses. It also does not replace the [getting started FAQ](../start/FAQ.md), rather this is focussed explicitly on code samples, instead of general trouble-shooting for common mishaps.
These questions are added as they do come up and the hope is that the snippets here is will be useful to others, instead of just the original person who asked on a specific use-case. As of today, it is only making a start and not fully comprehensive yet - check back early, check back often.
## Sections
The following cookbook sections are available -
- [Blocks](blocks.md) - Snippets around working with blocks and headers
- [Storage](storage.md) - Snippets for working with storage
- [Transactions](tx.md) - Snippets for working with transactions
... more to come.
## Contribute
And as always, if you have an addition to make, or a question to ask any [any PRs](https://github.com/polkadot-js/api/tree/master/docs) or [issues](https://github.com/polkadot-js/api/issues) are appreciated. The initial content was generate from exactly such questions, either in Riot chat or as submitted as issues.
+44
View File
@@ -0,0 +1,44 @@
# Blocks
The building blocks for each blockchain. As such there are a number of examples for working with blocks and headers, that could be useful.
## How do I retrieve the header/extrinsic hash from blocks?
A block hash refers to the hash over the header, the extrinsic hash refers to the hash of the encoded extrinsic. Since all objects returned by the API implements the `.hash => Hash` getter, we can simply use this to view the actual hash.
```js
// returns Hash
const blockHash = await this.api.rpc.chain.getBlockHash(blockNumber);
// returns SignedBlock
const signedBlock = await this.api.rpc.chain.getBlock(blockHash);
// the hash for the block, always via header (Hash -> toHex()) - will be
// the same as blockHash above (also available on any header retrieved,
// subscription or once-off)
console.log(signedBlock.header.hash.toHex());
// the hash for each extrinsic in the block
signedBlock.block.extrinsics.forEach((ex, index) => {
console.log(index, ex.hash.toHex());
});
```
## How do I extract the block author?
Th block author is encoded inside the consensus logs for the block. To extract, you need to decode the log (which the API does do) and then map the index of the validator to the list of session validators. This extraction is however available on the api derive for new head subscriptions, which returns an extended header with the author populated (assuming that the digest logs are known).
```js
// subscribe to all new headers (with extended info)
api.derive.chain.subscribeNewHeads((header) => {
console.log(`#${header.number}: ${header.author}`);
});
```
For a single header only, the derives also contain a `getHeader`, which once again returns a header extended with the author -
```js
// retrieve the last header (hash optional)
const header = await api.derive.chain.getHeader();
console.log(`#${header.number}: ${header.author}`);
```
+55
View File
@@ -0,0 +1,55 @@
# Storage
Here you will find snippets for working with storage.
## How do I check for storage existence?
In the metadata, for each storage item a fallback is provided. This means that when an entry does not exist, the fallback (which is the default value for the type) will be provided. This means, that querying for a non-existent key (unless an option), will yield a value -
```js
// retrieve Option<StakingLedger>
const ledger = await api.query.staking.ledger('EoukLS2Rzh6dZvMQSkqFy4zGvqeo14ron28Ue3yopVc8e3Q');
// retrieve ValidatorPrefs (will yield the default value)
const prefs = await api.query.staking.validators('EoukLS2Rzh6dZvMQSkqFy4zGvqeo14ron28Ue3yopVc8e3Q');
console.log(ledger.isNone, ledger.isSome); // true, false
console.log(JSON.stringify(prefs.toHuman())); // {"commission":"0"}
```
In the second case, the non-existent prefs returns the default/fallback value for the storage item. So in this case we don't know if the value is set to 0 or unset. Existence can be checked by using the storage size, which would be zero if nothing is stored.
```js
// exists
const sizeY = await api.query.staking.validators.size('DB2mp5nNhbFN86J9hxoAog8JALMhDXgwvWMxrRMLNUFMEY4');
// non existent
const sizeN = await api.query.staking.validators.size('EoukLS2Rzh6dZvMQSkqFy4zGvqeo14ron28Ue3yopVc8e3Q');
console.log(sizeY.isZero(), sizeY.toNumber()); // false 4
console.log(sizeN.isZero(), sizeY.toNumber()); // true 0
```
## How do I use .entries()/.keys() on double maps?
As [explained elsewhere](../start/api.query.other.md#map-keys-entries) each map-type storage entry exposes the entries/keys helpers to retrieve the whole list. In the case of double maps, with the addition of a single argument, you can retrieve either all entries or a subset based on the first map key.
In both these cases, entries/keys operate the same way, `.entries()` retrieving `(StorageKey, Codec)[]` and `.keys()` retrieving `StorageKey[]`
```js
// Retrieves the entries for all slashes, in all eras (no arg)
const allEntries = await api.query.staking.nominatorSlashInEra.entries();
// nominatorSlashInEra(EraIndex, AccountId) for the types of the key args
allEntries.forEach(([{ args: [era, nominatorId] }, value]) => {
console.log(`${era}: ${nominatorId} slashed ${value.toHuman()}`);
});
```
While we can retrieve only the keys for a specific era, using a argument for the first part of the doublemap (as defined here, an `EraIndex`) -
```js
// Retrieves the keys for the slashed validators in era 652
const slashedKeys = await api.query.staking.nominatorSlashInEra.keys(652);
// key args still contains [EraIndex, AccountId] decoded
console.log(`slashed: ${slashedKeys.map(({ args: [era, nominatorId] }) => nominatorId)`);
```
+112
View File
@@ -0,0 +1,112 @@
# Transactions
A blockchain is no fun if you are not submitting transactions. Or at least if somebody is not submitting any. Here you will find some snippets for dealing with some common issues.
## How do I estimate the transaction fees?
In addition to the `signAndSend` helper on transactions, `.paymentInfo` (with the exact same parameters) are also exposed. Using the same sender, it applies a dummy signature to the transaction and then gets the fee estimation via RPC.
```js
// estimate the fees as RuntimeDispatchInfo, using the signer (either
// address or locked/unlocked keypair) (When overrides are applied, e.g
// nonce, the format would be `paymentInfo(sender, { nonce })`)
const info = await api.tx.balances
.transfer(recipient, 123)
.paymentInfo(sender);
// log relevant info, partialFee is Balance, estimated for current
console.log(`
class=${class.toString()},
weight=${weight.toString()},
partialFee=${partialFee.toHuman()}
`);
```
## How do I get the decoded enum for an ExtrinsicFailed event?
Assuming you are sending a tx via `.signAndSend`, the callback yields information around the tx pool status as well as any events when `isInBlock` or `isFinalized`. If an extrinsic fails via `system.ExtrinsicFailed` event, you can retrieve the error, if defined as an enum on a module.
```js
api.tx.balances
.transfer(recipient, 123)
.signAndSend(sender, ({ status, events }) => {
if (status.isInBlock || status.isFinalized) {
events
// find/filter for failed events
.filter(({ section, method }) =>
section === 'system' &&
method === 'ExtrinsicFailed'
)
// we know that data for system.ExtrinsicFailed is
// (DispatchError, DispatchInfo)
.forEach(({ data: [error, info] }) => {
if (error.isModule) {
// for module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(error.asModule);
const { documentation, method, section } = decoded;
console.log(`${section}.${method}: ${documentation.join(' ')}`);
} else {
// Other, CannotLookup, BadOrigin, no extra info
console.log(error.toString());
}
});
}
});
```
## How do I send an unsigned extrinsic?
For most runtime modules, transactions need to be signed and validation for this happens node-side. There are however modules that accepts unsigned extrinsics, an example would be the Polkadot/Kusama token claims (which is here used as an example).
```js
// construct the transaction, exactly as per normal
const utx = api.tx.claims.claim(beneficiary, ethSignature);
// send it without calling sign, pass callback with status/events
tx.send(({ status }) => {
if (status.isInBlock) {
console.log(`included in ${status.asInBlock}`);
}
});
```
The signing is indicated by the first byte in the transaction, so in this case we have called `.send` on it (no `.sign` or `.signAndSend`), so it will be sent using the unsigned state, without signature attached.
## How can I batch transactions?
Polkadot/Substrate provides a `utility.batch` method that can be used to send a number of transactions at once. These are then executed from a single sender (single nonce specified) in sequence. This is very useful in a number of cases, for instance if you wish to create a payout for a validator for multiple eras, you can use this method. Likewise, you can send a number of transfers at once. Or even batch different types of transactions.
```js
// construct a list of transactions we want to batch
const txs = [
api.tx.balances.transfer(addrBob, 12345),
api.tx.balances.transfer(addrEve, 12345),
api.tx.staking.unbond(12345)
];
// construct the batch and send the transactions
api.tx.utility
.batch(txs)
.signAndSend(sender, ({ status }) => {
if (status.isInBlock) {
console.log(`included in ${status.asInBlock}`);
}
});
```
## How do I take the pending tx pool into account in my nonce?
The `system.account` query will always contain the current state, i.e. it will reflect the nonce for the last known block. As such when sending multiple transactions in quick succession (see batching above), there may be transactions in the pool that has the same nonce that `signAndSend` would apply - this call doesn't do any magic, it simply reads the state for the nonce. Since we can specify options to the `signandSend` operation, we can override the nonce, either by manually incrementing it o querying it via `nextNonce`.
```js
for (let i = 0; i < 10; i++) {
// retrieve the nextNonce, taking txs in the pool into account
const nonce = await api.rpc.account.nextNonce(sender);
// send, just retrieving the hash, not waiting on status
const txhash = await api.tx.balances
.transfer(recipient, 123)
.signAndSend(sender, { nonce });
}
```
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Required imports
const { ApiPromise, WsProvider } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -13,13 +14,13 @@ async function main () {
// Retrieve the initial balance. Since the call has no callback, it is simply a promise
// that resolves to the current on-chain value
let { nonce: previousNonce, data: { free: previousFree } } = await api.query.system.account(Alice);
let { data: { free: previousFree }, nonce: previousNonce } = await api.query.system.account(Alice);
console.log(`${Alice} has a balance of ${previousFree}, nonce ${previousNonce}`);
console.log(`You may leave this example running and start example 06 or transfer any value to ${Alice}`);
// Here we subscribe to any balance changes and update the on-screen value
api.query.system.account(Alice, ({ nonce: currentNonce, data: { free: currentFree } }) => {
api.query.system.account(Alice, ({ data: { free: currentFree }, nonce: currentNonce }) => {
// Calculate the delta
const change = currentFree.sub(previousFree);
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -24,7 +25,7 @@ async function main () {
if (validators && validators.length > 0) {
// Retrieve the balances for all validators
const validatorBalances = await Promise.all(
validators.map(authorityId =>
validators.map((authorityId) =>
api.query.system.account(authorityId)
)
);
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API, Keyring and some utility functions
const { ApiPromise } = require('@polkadot/api');
const { Keyring } = require('@polkadot/keyring');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API, Keyring and some utility functions
const { ApiPromise } = require('@polkadot/api');
const { Keyring } = require('@polkadot/keyring');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiPromise } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API & Provider and some utility functions
const { ApiPromise } = require('@polkadot/api');
@@ -44,7 +45,7 @@ async function main () {
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
events.forEach(({ event: { data, method, section }, phase }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
} else if (status.isFinalized) {
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API & Provider and some utility functions
const { ApiPromise, WsProvider } = require('@polkadot/api');
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Required imports
const { zip } = require('rxjs');
const { ApiRx } = require('@polkadot/api');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiRx } = require('@polkadot/api');
const { switchMap } = require('rxjs/operators');
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API and operators from RxJs
const { ApiRx } = require('@polkadot/api');
const { pairwise, startWith } = require('rxjs/operators');
@@ -27,6 +28,7 @@ async function main () {
// then balance[1] is the initial value of Alice account.
console.log(`Alice ${Alice} has a balance of ${balance[1].data.free}`);
console.log('You may leave this example running and start the "Make a transfer" example or transfer any value to Alice address');
return;
}
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiRx } = require('@polkadot/api');
const { switchMap } = require('rxjs/operators');
+3 -2
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API
const { ApiRx } = require('@polkadot/api');
const { combineLatest, of } = require('rxjs');
@@ -22,7 +23,7 @@ function main () {
// In the next step, we're checking if the node has active validators.
// If it does, we're making another call to the api to get the balances for all validators
const balances = (validators && validators.length > 0)
? combineLatest(validators.map(authorityId => api.query.system.account(authorityId).pipe(first())))
? combineLatest(validators.map((authorityId) => api.query.system.account(authorityId).pipe(first())))
: of(null);
// We're combining the results together with the emitted value 'validators',
+3 -1
View File
@@ -1,6 +1,8 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API, Keyring and some utility functions
const { ApiRx } = require('@polkadot/api');
const { Keyring } = require('@polkadot/keyring');
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API and selected RxJs operators
const { switchMap } = require('rxjs/operators');
const { ApiRx } = require('@polkadot/api');
+3 -2
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API and some utility functions
const { ApiRx } = require('@polkadot/api');
@@ -48,7 +49,7 @@ async function main () {
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
events.forEach(({ event: { data, method, section }, phase }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
} else if (status.isFinalized) {
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable header/header */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-var-requires */
// Import the API & Provider and some utility functions
const { ApiRx, WsProvider } = require('@polkadot/api');
// Import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
-5
View File
@@ -1,5 +0,0 @@
... somewhere also need a signer injection section, something along the lines of the singlesigner or this https://github.com/polkadot-js/tools/blob/master/packages/signer-cli/src/cmdSubmit.ts#L12
... DoubleMap & LinkedMap examples
... api.derive
+16 -2
View File
@@ -34,13 +34,13 @@ To submit these transactions, it needs to be send as a [wrapped transaction](api
## How do I call a function with a Tuple input
Tuples, as defined in the Polkadot/Substrate types appear as `(TypeA, TypeB)`. For instance we may have an `(AccountId, u64)` input as defined in the metadata or as part of the user types. To specify a Tuple as an input, wrap it is an array format, for instance to call `query.module.get((u32, u64))` where a `(u32, u64)` Tuple input is expected, you would do `query.module.get([123, 456])`
Tuples, as defined in the Polkadot/Substrate types appear as `(TypeA, TypeB)`. For instance we may have an `(AccountId, u64)` input as defined in the metadata or as part of the user types. To specify a Tuple as an input, wrap it in an array format, for instance to call `query.module.get((u32, u64))` where a `(u32, u64)` Tuple input is expected, you would do `query.module.get([123, 456])`
## How long do transactions live
Polkadot/Substrate supports both immortal and mortal transactions. For immortal, this means that the transaction has an infinite lifetime, for mortals, the transactions expire after a defined period. By default the API sends mortal transactions when no explicit extrinsic era has been specified. This means that all transaction has a limited lifetime and will expire if not included in the period set.
The length for this transaction validity is set to 50 blocks, which translates to 5 minutes assuming a default of 6 second blocktimes. (10 blocks per minute in this default configuration).
The length for this transaction validity is set to 5 minutes, calculated based on the blocktime for the chain. (10 blocks per minute in this default 6s Substrate configuration).
## My chain does not support system.account queries
@@ -49,3 +49,17 @@ The API always tracks the latest Substrate master in terms of examples. This mea
It is possible that you are connecting to an older chain that has not been upgraded yet. For these chains, this storage entry won't be available (yet). To query the nonce on older chains, you can do a query to `api.query.system.accountNonce(<account>)` and balances can be retrieved via `api.query.balances.freeBalance(<account>)`.
Likewise, if your chain has been upgraded recently and you are still using the old `system.accountNonce` or `balances.freeBalance` queries in your code (which is now not available in the chain metadata), you need to update it to query the new location.
## I cannot send transactions from my node-template-based chain
The API always injects the default type definitions as specified by the Substrate master fully-featured node. This means that any customizations to chains needs needs to be applied as types, should there be differences in specific user-implementations.
The Substrate node-template has added customizations for some types in the default template, specifically around the `Address` and `Lookup` types, removing any lookups based on indices. This means that the transaction payload saves 2 bytes for a transfer and is an approach followed by other chains as well, notably Polkadot & Kusama.
Due to these customizations and differences that bleed through to the transaction formats, out-of-the-box chains based on the node-template will have issues when sending transactions. To fix this, you would need to add [the customized Address types into your API](types.extend.md#impact-on-extrinsics) instances (or UIs), allowing the API to have the information required to adjust the encoding.
## Using a non-current-master node, I have issues parsing events
Recently Substrate master updated the `Weight` type from `u32` -> `u64`. This type is used in the `DispatchInfo` struct in the `system.ExtrinsicSuccess` events, to return the applied call weights as well as the resulting fees. Since the API master branch tracks Substrate master, this means the change has been applied by default, with the default set to `u64`.
If you are on a chain that has not been upgraded yet, you need to add `Weight: 'u32'` to your types to allow for successful parsing of all events. Without this override, parsing will fail. As soon as one event in the `Vec<EventRecord>` structure from `system.events` fails to parse, all subsequent events are affected and the decoding will return an error.
+1 -1
View File
@@ -23,7 +23,7 @@ A couple of items to note in the example above: we don't call `account` directly
...
// Retrieve a snapshot of the validators
const validators = await api.query.session.validators();
const validatorKeys = await api.query.session.validators.keys();
// Subscribe to the balances for these accounts
const unsub = await api.query.balances.account.multi(validators, (balances) => {
+56 -1
View File
@@ -22,7 +22,7 @@ const [{ data: balanceNow }, { data: balancePrev }] = await Promise.all([
console.log(`The delta was ${balanceNow.free.sub(balancePrev.free)}`);
```
In the above example, we introduce the `.at(<hash>[, ...params])` query. For all `.at` queries, the first parameter is always the block hash at which we want to make the query, in our example we use both the last retrieved block and the parent thereof. The params are optional as per the type of query made, for instance to retrieve the timestamp for a previous block, it would be -
In the above example, we introduce the `.at(<hash>[, ...params]): Type` query. For all `.at` queries, the first parameter is always the block hash at which we want to make the query, in our example we use both the last retrieved block and the parent thereof. The params are optional as per the type of query made, for instance to retrieve the timestamp for a previous block, it would be -
```js
...
@@ -35,6 +35,61 @@ The `.at` queries are all single-shot, i.e. there are no subscription option to
An additional point to take care of (briefly mentioned above), is state pruning. By default a Polkadot/Substrate node will only keep state for the last 256 blocks, unless it is explicitly run in archive mode. This means that querying state further back than the pruning period will result in an error returned from the Node. (Generally most public RPC nodes only run with default settings, which includes aggressive state pruning)
## State for a range of blocks
In addition to the `.at` queries, you can also query state starting at a specific historic block and up to either a specified or the latest blocks. This is done via the `.range([from, to?], <...opt params>): [Hash, Type][]` query. As an example -
```js
...
// Retrieve the current block header
const lastHdr = await api.rpc.chain.getHeader();
const startHdr = await api.rpc.chain.getBlockHash(lastHdr.number.unwrap().subn(500));
// retrieve the range of changes
const changes = await api.query.system.account.range([startHdr]);
changes.forEach(([hash, value]) => {
console.log(hash.toHex(), value.toHuman());
});
```
## Map keys & entries
When working maps and double-maps, it is possible to retrieve a list of all the keys and entries for the map. For this we can use the `.entries(<args>): [StorageKey, Type][]` queries. For example we may want to know the current list of validator exposures at a current era in the staking module -
```js
...
// Retrieve the active era
const activeEra = await api.query.staking.activeEra();
// retrieve all exposures for the active era
const exposures = await api.query.staking.erasStakers.entries(activeEra.index);
exposures.forEach(([key, exposure]) => {
console.log('key arguments:', key.args.map((k) => k.toHuman()));
console.log(' exposure:', exposure.toHuman());
});
```
To understand the usage of the `key.args`, you need to understand that map/doublemap keys are stored alongside their lookups. This means that the raw key has hashed parts as well as the raw data. The API will decode the keys and provide the raw key arguments in args. This would mean -
- if we are querying `api.query.staking.validators(validatorId: AccountId)` via `entries`, the `key.args` would be `[AccountId]`
- if we are querying `api.query.staking.erasStakers(era: EraIndex, validatorId: AccountId)` via `entries`, the `key.args` would be `[EraIndex, AccountId]`
the same applies to `.keys()` - here the list of keys also have the decoded args, as specified. You can think of `.args` as a tuple with the same types as the types required to retrieve a single entry in the map.
In the first example we are querying a double-map, so we supply 1 argument. No arguments on double-maps will be very costly, retrieving all the eras and associated entries. In the same way as above we can simply do `.keys(activeEra.index): StorageKey[]` to retrieve all the keys here, including the individual keys args (available on maps with decodable hashing functions) -
```js
// retrieve all the nominator keys
const keys = await api.query.staking.nominators.keys();
// extract the first key argument [AccountId] as string
const nominatorIds = keys.map(({ args: [nominatorId] }) => nominatorId);
console.log('all nominators:', nominatorIds.join(', '));
```
## State entries
In addition to using `api.query` to make actual on-chain queries, it can also be used to retrieve some information on the state entries. For instance to retrieve both the hash and size of an existing entry, we can make the following calls -
+17
View File
@@ -62,6 +62,23 @@ const unsub = await api.tx.balances
Be aware that when a transaction status is `isFinalized`, it means it is included, but it may still have failed - for instance if you try to send a larger amount that you have free, the transaction is included in a block, however from a end-user perspective the transaction failed since the transfer did not occur. In these cases a `system.ExtrinsicFailed` event will be available in the events array.
## Payment information
The Polkadot/Substrate RPC endpoints exposes weight/payment information that takes an encoded extrinsic and calculates the on-chain weight fees for it. A wrapper for this is available on the tx itself, taking exactly the same parameters as you would pass to a normal `.signAndSend` operation, specifically `.paymentInfo(sender, <any options>)`. To expand on our previous example -
```js
// construct a transaction
const transfer = api.tx.balances.transfer(BOB, 12345);
// retrieve the payment info
const { partialFee, weight } = await transfer.paymentInfo(alice);
console.log(`transaction will have a weight of ${weight}, with ${partialFee.toHuman()} weight fees`);
// send the tx
transfer.signAndSend(alice, ({ events = [], status }) => { ... });
```
## Complex transactions
In many cases transactions can carry quite complex information, be it for passing objects or proposing changes. In the next section we will take a dive [into complex transactions, including those wrapped for sudo](api.tx.wrap.md).
+58
View File
@@ -0,0 +1,58 @@
# Custom RPC
In previous sections we looked at the injection of types, as in use and defined in modules from the node. Another area that can be customized is RC definitions, and like with the types, the API provides the capability to add user-defined RPCs (in addition to the Polkadot/Substrate base) to allow use of these RPCs via the API.
## Custom definitions
RPCs are exposed as a method on a specific module, this means that once available you can call any rpc via the `api.rpc.<module>.<method>(...params[])` endpoints. To extend with user-defined RPCs, the injection can happen at the time of API creation with the addition of the `rpc` key (in addition to any other params, such as `types` or `provider`) -
```js
...
const api = await ApiPromise.create({
rpc: {
firstModule: {
testMethod: {
description: 'Just a test method',
params: [
{
name: 'index',
type: 'u64'
},
{
name: 'at',
type: 'Hash',
isOptional: true
}
],
type: 'Balance'
}
}
}
});
```
In the above example we have defined a new method, which is now available on the RPCs as `api.rpc.firstModule.testMethod(index: u64, at?: Hash) => Promise<Balance>`. In the case of optional params, we have added the `isOptional: true` flag alongside the `name` & `type` in the param definition.
Be aware that while defined, the method will only appear on the API if it is in the list as returned by `api.rpc.rpc.methods()`, which is the list of known RPCs the node exposes. When making changes to the node, always ensure that it does expose the RPC method correctly, otherwise it will not be decorated.
## Definition breakdown
While the above example should be self-explanatory, it is important to understand teh structure. The `rpc: { ... }` definitions are keyed first and foremost by the name of the module exposing the RPC. This means that when we have 2 modules `firstModule` & `testModule`, the first-level structure would follow the following pattern,
```js
...
const api = await ApiPromise.create({
rpc: {
firstModule: { ... },
testModule: { ... }
}
});
```
Inside the specific module definitions, the key is the actual expose RPC method. As we have seen in the first example, we expose a `testMethod` on `firstModule`. For the method definitions, apart from the description, we have definitions for the params and return a single result `type`.
Params itself, as an array, contains fields for `name`, `type` and an optional flag `isOptional` that indicates that the field is not required when making the call. (And example of this use would be in cases such as `state.getStorage(key, blockHash?)` where the last param is optional)
## Type creation
While the API always converts all the inputs into the underlying type required by the operation, be it for RPC, query or transaction, in some cases you may want to [create an instance of a type](types.create.md) yourself.
+2 -1
View File
@@ -57,7 +57,7 @@ Be aware that in the JS version naming defaults to `camelCase` where names of fi
Each enum has additional getters which are injected based on the fields wrapped. These take the form of `.is<Name>` and `.as<Name>` to allow you to check is the enum is a certain value or to retrieve the underlying value as a specific type.
As a real-world example, when an extrinsic is applied, the `Phase` enum has one of two states, `ApplyExtrinsic(u32)` or `Finalization`. In this case `.isApplyExtrinsic` would be `true` when an extrinsic is being applied, and `.asApplyExtrinsic` would return the value as a `u32` (which is the index of the extrinsic in the block, as it is being applied). When `isisApplyExtrinsic` is `false` and `asApplyExtrinsic` is called, the getter will throw.
As a real-world example, when an extrinsic is applied, the `Phase` enum has one of two states, `ApplyExtrinsic(u32)` or `Finalization`. In this case `.isApplyExtrinsic` would be `true` when an extrinsic is being applied, and `.asApplyExtrinsic` would return the value as a `u32` (which is the index of the extrinsic in the block, as it is being applied). When `isApplyExtrinsic` is `false` and `asApplyExtrinsic` is called, the getter will throw.
## Working with Option&lt;Type&gt;
@@ -67,6 +67,7 @@ An `Option<Type>` attempts to mimic the Rust approach of having `None` and `Some
- `.isSome` - this is `true` is a value is wrapped, i.e. if a `Option<u32>` has an actual underlying `u32`
- `.unwrap()` - when `isSome`, this will return the wrapped value, i.e. for `Option<u32>`, this would return the `u32`. When the value is `isNone`, this call will throw an exception.
- `.unwrapOr(<default value>)` - this extends `unwrap()`, returning the wrapped value when `isSome` and in the case of `isNone` it will return the `<default value>` passed.
- `.unwrapOrDefault()` - returns either the rapped value when `isSome`, or the default for the type when `isNone`
## Working with Tuples
+11 -2
View File
@@ -26,6 +26,15 @@ const api = await ApiPromise.create({
The above introduces the `types` registry, effectively allowing overrides and the definition of new types. The override above would mean that immediately the API will treat all occurrences of `Balance` not as the default, but rather as the defined size.
## Field ordering
When defining any custom structures or types, it is critical that the following rules are applied -
- Map exactly to what is defined in the Rust code, i.e. defining a `SaleType` cannot be `u16` on the one end and `u32` on the other end. If mismatches occur, the serialization will fail.
- Ensure that the field order is maintained in all definitions. The SCALE serialization is binary and contains no field names in the serialization, only the encoded values. Any decoding is therefore done based on the size of the type and the order thereof in the definitions.
These rules apply everywhere. Always ensure that the types match exactly between the environments and that the ordering is maintained, be it for structs, tuples or enums.
## User-defined structs
Registration also applies to any type that can be found on a specific chain, i.e. we can add any types that is available on a specific node -
@@ -201,6 +210,6 @@ const api = await ApiPromise.create({
Always look at customization and understand the impacts, replicating these changes between the node and the API. For the above the `Address` type is used in the construction of the `UncheckedExtrinsic` type, while the lookup type is applicable on transactions such as `balances.transfer(to: LookupSource, value: Balance)`
## Type creation
## Custom RPC
While the API always converts all the inputs into the underlying type required by the operation, in some cases you may want to [create an instance of a type](types.create.md) yourself.
In addition to customizing modules and types on your node, you can also add custom RPC definitions. Like the type definitions in ths section, [these can be defined and passed to the API](rpc.custom.md) for decoration.
+2 -2
View File
@@ -1,10 +1,10 @@
# TypeScript user generated
In the previous section we looked at the TypeScript definitions that are available and is generated from both the chain and definitions. Here we will expand upon the use of the infrastructure created to define types as part of the `@polkadot/types` library and see how to use them to generate your onw definitions and chain types.
In the previous section we looked at the TypeScript definitions that are available and is generated from both the chain and definitions. Here we will expand upon the use of the infrastructure created to define types as part of the `@polkadot/types` library and see how to use them to generate your own definitions and chain types.
## Definitions
A large part of the type definitions are defined not as classes, but rather as structures from which type definitions are extracted and that can be used as-is to let the API know how to decode a type. By now you should be familiar with [type extensions](types.extend.md), but effectively the [types library does exactly the same](https://github.com/polkadot-js/api/tree/master/packages/types/src/interfaces).
A large part of the type definitions are defined not as classes, but rather as structures from which type definitions are extracted and that can be used as-is to let the API know how to decode a type. By now you should be familiar with [type extensions](types.extend.md) and the [rules around fields](types.extend.md#field-ordering), but effectively the [types library does exactly the same](https://github.com/polkadot-js/api/tree/master/packages/types/src/interfaces).
To create TypeScript-aware definitions and keep your files in a single place, you can follow the same approach. Assuming you have a package named `@MeInc/stuff` where you have the definitions in an `stuff/interfaces` folder. Each sub-folder would indicate a runtime module, e.g.
+9 -15
View File
@@ -1,36 +1,30 @@
/* eslint-disable @typescript-eslint/camelcase */
/* eslint-disable @typescript-eslint/no-var-requires */
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
const config = require('@polkadot/dev/config/jest');
module.exports = Object.assign({}, config, {
moduleNameMapper: {
'@polkadot/api-contract(.*)$': '<rootDir>/packages/api-contract/src/$1',
'@polkadot/api-derive(.*)$': '<rootDir>/packages/api-derive/src/$1',
// eslint-disable-next-line sort-keys
'@polkadot/api(.*)$': '<rootDir>/packages/api/src/$1',
'@polkadot/jsonrpc(.*)$': '<rootDir>/packages/jsonrpc/src/$1',
'@polkadot/metadata(.*)$': '<rootDir>/packages/metadata/src/$1',
'@polkadot/rpc-(core|provider)(.*)$': '<rootDir>/packages/rpc-$1/src/$2',
'@polkadot/types-known(.*)$': '<rootDir>/packages/types-known/src/$1',
// eslint-disable-next-line sort-keys
'@polkadot/types(.*)$': '<rootDir>/packages/types/src/$1'
},
modulePathIgnorePatterns: [
'<rootDir>/packages/api/build',
'<rootDir>/packages/api-derive/build',
'<rootDir>/packages/api-contract/build',
'<rootDir>/packages/jsonrpc/build',
'<rootDir>/packages/metadata/build',
'<rootDir>/packages/rpc-core/build',
'<rootDir>/packages/rpc-provider/build',
'<rootDir>/packages/types/build'
'<rootDir>/packages/types/build',
'<rootDir>/packages/types-known/build'
],
globals: {
ws_local: 'ws://127.0.0.1:9944/',
ws_local_substrate_master: 'ws://127.0.0.1:9945/',
ws_local_substrate_1: 'ws://127.0.0.1:9946/',
ws_local_substrate_2: 'ws://127.0.0.1:9947/',
ws_local_polkadot_master: 'ws://127.0.0.1:9948/',
ws_local_polkadot_alex: 'ws://127.0.0.1:9949/',
ws_substrate_1: 'wss://substrate-rpc.parity.io/',
ws_polkadot_alex: 'wss://poc3-rpc.polkadot.io/'
},
resolver: './jest.resolver.js'
});
+1 -2
View File
@@ -1,8 +1,7 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
module.exports = function resolver (file, config) {
+1 -1
View File
@@ -9,5 +9,5 @@
"packages": [
"packages/*"
],
"version": "1.5.1"
"version": "1.12.1"
}
+8 -5
View File
@@ -12,7 +12,9 @@
"scripts": {
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
"build:interfaces": "polkadot-types-internal-interfaces",
"build:release": "polkadot-ci-ghact-build",
"docs": "polkadot-types-internal-metadata && polkadot-dev-build-docs",
"docs:release": "polkadot-ci-ghact-docs",
"chain:info": "polkadot-types-chain-info",
"lint": "polkadot-dev-run-lint",
"clean": "polkadot-dev-clean-build",
@@ -22,12 +24,13 @@
"test:watch": "polkadot-dev-run-test --watch"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/register": "^7.8.3",
"@babel/runtime": "^7.8.4",
"@polkadot/dev": "^0.50.27",
"@polkadot/ts": "^0.3.7",
"@babel/core": "^7.9.0",
"@babel/register": "^7.9.0",
"@babel/runtime": "^7.9.2",
"@polkadot/dev": "^0.52.11",
"@polkadot/ts": "^0.3.18",
"@polkadot/typegen": "workspace:packages/typegen",
"@types/jest": "^25.2.1",
"copyfiles": "^2.2.0"
}
}
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-contract",
"version": "1.5.1",
"version": "1.12.1",
"description": "Interfaces for interacting with contracts and contract ABIs",
"main": "index.js",
"keywords": [
@@ -26,12 +26,12 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api": "1.5.1",
"@polkadot/rpc-core": "1.5.1",
"@polkadot/types": "1.5.1",
"@polkadot/util": "^2.6.1",
"@babel/runtime": "^7.9.2",
"@polkadot/api": "1.12.1",
"@polkadot/rpc-core": "1.12.1",
"@polkadot/types": "1.12.1",
"@polkadot/util": "^2.9.0-beta.3",
"bn.js": "^5.1.1",
"rxjs": "^6.5.4"
"rxjs": "^6.5.5"
}
}
+2 -2
View File
@@ -18,10 +18,10 @@ export default class ContractAbi extends ContractRegistry implements InterfaceAb
constructor (registry: Registry, abi: ContractABIPre) {
super(registry, abi);
[this.abi, this.constructors, this.messages] = this.decodeAbi(abi);
[this.abi, this.constructors, this.messages] = this._decodeAbi(abi);
}
private decodeAbi (abiPre: ContractABIPre): [ContractABI, ContractABIFn[], AbiMessages] {
private _decodeAbi (abiPre: ContractABIPre): [ContractABI, ContractABIFn[], AbiMessages] {
this.validateAbi(abiPre);
const abi = this.convertAbi(abiPre);
+22 -17
View File
@@ -61,7 +61,7 @@ export default class ContractRegistry extends MetaRegistry {
const unknownKeys = Object.keys(arg).filter((key): boolean => !['name', 'type'].includes(key));
assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for ${name}`);
assert(isNumber(arg.name) && isString(this.stringAt(arg.name)), `${name} args should have valid name `);
assert(isNumber(arg.name) && isString(this._stringAt(arg.name)), `${name} args should have valid name `);
assert(isNumber(arg.type.ty) && isObject(this.typeDefAt(arg.type.ty)), `${name} args should have valid type`);
});
}
@@ -83,9 +83,9 @@ export default class ContractRegistry extends MetaRegistry {
assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for messages.${message.name}`);
const { name, selector, return_type: returnType } = message;
const { name, return_type: returnType, selector } = message;
assert(isNumber(name) && isString(this.stringAt(name)), `Expected name for ${fnname}`);
assert(isNumber(name) && isString(this._stringAt(name)), `Expected name for ${fnname}`);
assert(isNull(returnType) || (isNumber(returnType.ty) && isObject(this.typeDefAt(returnType.ty))), `Expected return_type for ${fnname}`);
parseSelector(this.registry, fnname, selector);
@@ -100,7 +100,7 @@ export default class ContractRegistry extends MetaRegistry {
const { contract: { constructors, messages, name } } = abi;
assert(constructors && messages && isString(this.stringAt(name)), 'ABI should have constructors, messages & name sections');
assert(constructors && messages && isString(this._stringAt(name)), 'ABI should have constructors, messages & name sections');
this.validateConstructors(abi);
this.validateMessages(abi);
@@ -109,13 +109,16 @@ export default class ContractRegistry extends MetaRegistry {
public createMessage (name: string, message: Partial<ContractABIMessage> & ContractABIMessageBase): ContractABIFn {
const args = message.args.map(({ name, type }): ContractABIFnArg => {
assert(isObject(type), `Invalid type at index ${type}`);
return {
name: stringCamelCase(name),
type
};
});
const Clazz = createArgClass(this.registry, args, isUndefined(message.selector) ? {} : { __selector: 'u32' });
const baseStruct: { [index: string]: any } = { __selector: isUndefined(message.selector) ? undefined : parseSelector(this.registry, name, message.selector) };
const encoder = (...params: CodecArg[]): Uint8Array => {
assert(params.length === args.length, `Expected ${args.length} arguments to contract ${name}, found ${params.length}`);
@@ -136,6 +139,7 @@ export default class ContractRegistry extends MetaRegistry {
fn.args = args;
fn.isConstant = !(message.mutates || false);
fn.type = message.returnType || null;
return fn;
}
@@ -147,21 +151,22 @@ export default class ContractRegistry extends MetaRegistry {
}
public convertArgs (args: ContractABIArgBasePre[]): any[] {
return args.map(({ name, type, ...arg }) => ({ ...arg, name: this.stringAt(name), type: this.convertType(type) }));
return args.map(({ name, type, ...arg }) => ({ ...arg, name: this._stringAt(name), type: this.convertType(type) }));
}
public convertType ({ ty, display_name: displayNameIndices }: ContractABITypePre): TypeDef {
public convertType ({ display_name: displayNameIndices, ty }: ContractABITypePre): TypeDef {
const displayName = this.stringsAt(displayNameIndices).join('::');
return this.typeDefAt(ty, { displayName });
}
public convertContract ({ constructors, messages, name, events, ...contract }: ContractABIContractPre): ContractABIContract {
public convertContract ({ constructors, events, messages, name, ...contract }: ContractABIContractPre): ContractABIContract {
return {
constructors: this.convertConstructors(constructors),
messages: messages.map(message => this.convertMessage(message)),
name: this.stringAt(name),
messages: messages.map((message) => this.convertMessage(message)),
name: this._stringAt(name),
...(events
? { events: events.map(event => this.convertEvent(event)) }
? { events: events.map((event) => this.convertEvent(event)) }
: {}),
...contract
};
@@ -179,7 +184,7 @@ export default class ContractRegistry extends MetaRegistry {
return {
...message,
args: this.convertArgs(args),
name: this.stringAt(name),
name: this._stringAt(name),
returnType: returnType ? this.convertType(returnType) : null
};
}
@@ -202,13 +207,13 @@ export default class ContractRegistry extends MetaRegistry {
}
}
public convertStorageStruct ({ 'struct.type': structType, 'struct.fields': structFields }: ContractABIStorageStructPre): ContractABIStorageStruct {
public convertStorageStruct ({ 'struct.fields': structFields, 'struct.type': structType }: ContractABIStorageStructPre): ContractABIStorageStruct {
return {
'struct.type': this.typeDefAt(structType),
'struct.fields': structFields.map(({ name, layout }) => ({
name: this.stringAt(name),
layout: this.convertStorageLayout(layout)
}))
'struct.fields': structFields.map(({ layout, name }) => ({
layout: this.convertStorageLayout(layout),
name: this._stringAt(name)
})),
'struct.type': this.typeDefAt(structType)
};
}
+50 -46
View File
@@ -48,7 +48,7 @@ class MetadataRegistryLookup {
this._types = types;
}
protected hasItemAt (index: number, variant: MetaRegistryItem): boolean {
protected _hasItemAt (index: number, variant: MetaRegistryItem): boolean {
switch (variant) {
case MetaRegistryItem.String:
return this._strings && !!this._strings[index - 1];
@@ -59,8 +59,8 @@ class MetadataRegistryLookup {
}
}
protected itemAt (index: number, variant: MetaRegistryItem): any {
assert(this.hasItemAt(index, variant), `MetaRegistry: Invalid ${variant} index ${index} found in metadata`);
protected _itemAt (index: number, variant: MetaRegistryItem): any {
assert(this._hasItemAt(index, variant), `MetaRegistry: Invalid ${variant} index ${index} found in metadata`);
switch (variant) {
case MetaRegistryItem.String:
@@ -72,33 +72,33 @@ class MetadataRegistryLookup {
}
}
protected itemsAt (indices: number[], variant: MetaRegistryItem): any[] {
return indices.map((index: number): string => this.itemAt(index, variant));
protected _itemsAt (indices: number[], variant: MetaRegistryItem): any[] {
return indices.map((index: number): string => this._itemAt(index, variant));
}
protected stringAt (index: StringIndex): string {
return this.itemAt(index, MetaRegistryItem.String);
protected _stringAt (index: StringIndex): string {
return this._itemAt(index, MetaRegistryItem.String);
}
public stringsAt (indices: StringIndex[]): string[] {
return this.itemsAt(indices, MetaRegistryItem.String);
return this._itemsAt(indices, MetaRegistryItem.String);
}
public typeAt (index: TypeIndex): MetaType {
return this.itemAt(index, MetaRegistryItem.Type);
return this._itemAt(index, MetaRegistryItem.Type);
}
public typesAt (indices: TypeIndex[]): MetaType[] {
return this.itemsAt(indices, MetaRegistryItem.Type);
return this._itemsAt(indices, MetaRegistryItem.Type);
}
public hasTypeDefAt (index: TypeIndex): boolean {
return this.hasItemAt(index, MetaRegistryItem.TypeDef);
return this._hasItemAt(index, MetaRegistryItem.TypeDef);
}
public typeDefAt (index: TypeIndex, extra: Pick<TypeDef, never> = {}): TypeDef {
return {
...this.itemAt(index, MetaRegistryItem.TypeDef),
...this._itemAt(index, MetaRegistryItem.TypeDef),
...extra
};
}
@@ -116,7 +116,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
this.typeDefs[typeIndex - 1] = this.typeDefFromMetaType(this.typeAt(typeIndex), typeIndex);
}
private typeDefIdFields ({ id }: MetaType): Pick<TypeDef, never> {
private _typeDefIdFields ({ id }: MetaType): Pick<TypeDef, never> {
const { 'custom.name': nameIndex, 'custom.namespace': namespaceIndices, 'custom.params': paramsIndices } = id as MetaTypeIdCustom;
if (!nameIndex) {
@@ -124,7 +124,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
}
return {
name: this.stringAt(nameIndex),
name: this._stringAt(nameIndex),
...(namespaceIndices && namespaceIndices.length
? { namespace: this.stringsAt(namespaceIndices).join('::') }
: {}
@@ -136,33 +136,33 @@ export default class MetaRegistry extends MetadataRegistryLookup {
};
}
private typeDefDefFields (metaType: MetaType, typeIndex?: TypeIndex): Pick<TypeDef, never> {
private _typeDefDefFields (metaType: MetaType, typeIndex?: TypeIndex): Pick<TypeDef, never> {
let typeDef;
switch (detectedType(metaType)) {
case MetaTypeInfo.BuiltinPlain:
typeDef = this.typeDefForBuiltinPlain(metaType.id as string);
typeDef = this._typeDefForBuiltinPlain(metaType.id as string);
break;
case MetaTypeInfo.BuiltinTuple:
typeDef = this.typeDefForBuiltinTuple(metaType.id as TypeIndex[]);
typeDef = this._typeDefForBuiltinTuple(metaType.id as TypeIndex[]);
break;
case MetaTypeInfo.BuiltinVec:
typeDef = this.typeDefForBuiltinVec(metaType.id as MetaTypeIdVec, typeIndex);
typeDef = this._typeDefForBuiltinVec(metaType.id as MetaTypeIdVec, typeIndex);
break;
case MetaTypeInfo.BuiltinVecFixed:
typeDef = this.typeDefForBuiltinVecFixed(metaType.id as MetaTypeIdVecFixed, typeIndex);
typeDef = this._typeDefForBuiltinVecFixed(metaType.id as MetaTypeIdVecFixed, typeIndex);
break;
case MetaTypeInfo.Enum:
typeDef = this.typeDefForEnum(metaType.def as MetaTypeDefEnum, metaType.id as MetaTypeIdCustom, typeIndex);
typeDef = this._typeDefForEnum(metaType.def as MetaTypeDefEnum, metaType.id as MetaTypeIdCustom, typeIndex);
break;
case MetaTypeInfo.ClikeEnum:
typeDef = this.typeDefForClikeEnum(metaType.def as MetaTypeDefClikeEnum);
typeDef = this._typeDefForClikeEnum(metaType.def as MetaTypeDefClikeEnum);
break;
case MetaTypeInfo.Struct:
typeDef = this.typeDefForStruct(metaType.def as MetaTypeDefStruct);
break;
case MetaTypeInfo.TupleStruct:
typeDef = this.typeDefForTupleStruct(metaType.def as MetaTypeDefTupleStruct);
typeDef = this._typeDefForTupleStruct(metaType.def as MetaTypeDefTupleStruct);
break;
case MetaTypeInfo.Null:
default:
@@ -176,8 +176,8 @@ export default class MetaRegistry extends MetadataRegistryLookup {
return withTypeString({
info: TypeDefInfo.Null,
type: '',
...this.typeDefDefFields(metaType, typeIndex),
...this.typeDefIdFields(metaType)
...this._typeDefDefFields(metaType, typeIndex),
...this._typeDefIdFields(metaType)
}) as TypeDef;
}
@@ -189,13 +189,13 @@ export default class MetaRegistry extends MetadataRegistryLookup {
return this.typeDefAt(typeIndex);
}
private typeDefForEnumVariant (variant: MetaTypeDefEnumVariant): Pick<TypeDef, any> {
private _typeDefForEnumVariant (variant: MetaTypeDefEnumVariant): Pick<TypeDef, any> {
const { 'unit_variant.name': unitNameIndex } = variant as MetaTypeDefEnumVariantUnit;
if (unitNameIndex) {
return {
info: TypeDefInfo.Plain,
name: this.stringAt(unitNameIndex),
name: this._stringAt(unitNameIndex),
type: 'Null'
};
}
@@ -203,7 +203,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
const { 'tuple_struct_variant.name': tupleStructVariantNameIndex } = variant as MetaTypeDefEnumVariantTupleStruct;
if (tupleStructVariantNameIndex) {
return this.typeDefForTupleStruct(variant as MetaTypeDefEnumVariantTupleStruct);
return this._typeDefForTupleStruct(variant as MetaTypeDefEnumVariantTupleStruct);
}
const { 'struct_variant.name': structVariantNameIndex } = variant as MetaTypeDefEnumVariantStruct;
@@ -218,14 +218,14 @@ export default class MetaRegistry extends MetadataRegistryLookup {
};
}
private typeDefForBuiltinPlain (id: string): Pick<TypeDef, never> {
private _typeDefForBuiltinPlain (id: string): Pick<TypeDef, never> {
return {
info: TypeDefInfo.Plain,
type: id
};
}
private typeDefForBuiltinTuple (id: TypeIndex[]): Pick<TypeDef, never> {
private _typeDefForBuiltinTuple (id: TypeIndex[]): Pick<TypeDef, never> {
const sub = id.map((tupleTypeIndex: number): TypeDef => this.typeDefFromMetaTypeAt(tupleTypeIndex));
return {
@@ -234,48 +234,52 @@ export default class MetaRegistry extends MetadataRegistryLookup {
};
}
private typeDefForBuiltinVec (id: MetaTypeIdVec, typeIndex?: TypeIndex): Pick<TypeDef, never> {
private _typeDefForBuiltinVec (id: MetaTypeIdVec, typeIndex?: TypeIndex): Pick<TypeDef, never> {
const { 'slice.type': vecTypeIndex } = id;
assert(!typeIndex || vecTypeIndex !== typeIndex, `MetaRegistry: self-referencing registry type at index ${typeIndex}`);
const type = displayType(this.typeDefFromMetaTypeAt(vecTypeIndex));
assert(type && type.length > 0, `MetaRegistry: Invalid builtin Vec type found at index ${typeIndex}`);
return {
info: TypeDefInfo.Vec,
type: `Vec<${type}>`,
sub: this.typeDefFromMetaTypeAt(vecTypeIndex)
sub: this.typeDefFromMetaTypeAt(vecTypeIndex),
type: `Vec<${type}>`
};
}
private typeDefForBuiltinVecFixed (id: MetaTypeIdVecFixed, typeIndex?: TypeIndex): Pick<TypeDef, never> {
const { 'array.type': vecTypeIndex, 'array.len': vecLength } = id;
private _typeDefForBuiltinVecFixed (id: MetaTypeIdVecFixed, typeIndex?: TypeIndex): Pick<TypeDef, never> {
const { 'array.len': vecLength, 'array.type': vecTypeIndex } = id;
assert(!vecLength || vecLength <= 256, 'MetaRegistry: Only support for [Type; <length>], where length <= 256');
assert(!typeIndex || vecTypeIndex !== typeIndex, `MetaRegistry: self-referencing registry type at index ${typeIndex}`);
const type = displayType(this.typeDefFromMetaTypeAt(vecTypeIndex));
assert(type && type.length > 0, `MetaRegistry: Invalid vector type found at index ${typeIndex}`);
return {
info: TypeDefInfo.VecFixed,
length: vecLength, // ex: { type: type }
type: `[${type};${vecLength}]`,
sub: this.typeDefFromMetaTypeAt(vecTypeIndex)
sub: this.typeDefFromMetaTypeAt(vecTypeIndex),
type: `[${type};${vecLength}]`
};
}
private typeDefForEnum (def: MetaTypeDefEnum, id: MetaTypeIdCustom, typeIndex?: TypeIndex): Pick<TypeDef, any> {
const name = id && this.stringAt(id['custom.name']);
private _typeDefForEnum (def: MetaTypeDefEnum, id: MetaTypeIdCustom, typeIndex?: TypeIndex): Pick<TypeDef, any> {
const name = id && this._stringAt(id['custom.name']);
switch (name) {
case 'Option':
return this.typeDefForOption(id, typeIndex);
case 'Result':
return this.typeDefForResult(id, typeIndex);
default: {
const sub = def['enum.variants'].map(variant => this.typeDefForEnumVariant(variant));
const sub = def['enum.variants'].map((variant) => this._typeDefForEnumVariant(variant));
return {
info: TypeDefInfo.Enum,
@@ -285,13 +289,13 @@ export default class MetaRegistry extends MetadataRegistryLookup {
}
}
private typeDefForClikeEnum (def: MetaTypeDefClikeEnum): Pick<TypeDef, never> {
private _typeDefForClikeEnum (def: MetaTypeDefClikeEnum): Pick<TypeDef, never> {
return {
info: TypeDefInfo.Enum,
sub: def['clike_enum.variants'].map(({ name: nameIndex, discriminant }): TypeDef => ({
sub: def['clike_enum.variants'].map(({ discriminant, name: nameIndex }): TypeDef => ({
ext: { discriminant },
info: TypeDefInfo.Plain,
name: this.stringAt(nameIndex),
name: this._stringAt(nameIndex),
type: 'Null'
}))
};
@@ -322,24 +326,24 @@ export default class MetaRegistry extends MetadataRegistryLookup {
return withTypeString({
info: TypeDefInfo.Struct,
...(structNameIndex
? { name: this.stringAt(structNameIndex) }
? { name: this._stringAt(structNameIndex) }
: {}
),
sub: structFields.map((field: MetaTypeDefStructField): TypeDef => ({
...this.typeDefFromMetaTypeAt(field.type),
name: this.stringAt(field.name)
name: this._stringAt(field.name)
}))
});
}
private typeDefForTupleStruct (def: MetaTypeDefTupleStruct | MetaTypeDefEnumVariantTupleStruct): Pick<TypeDef, any> {
private _typeDefForTupleStruct (def: MetaTypeDefTupleStruct | MetaTypeDefEnumVariantTupleStruct): Pick<TypeDef, any> {
const tupleStructTypes = (def as MetaTypeDefTupleStruct)['tuple_struct.types'] || (def as MetaTypeDefEnumVariantTupleStruct)['tuple_struct_variant.types'];
const tupleStructNameIndex = (def as MetaTypeDefEnumVariantTupleStruct)['tuple_struct_variant.name'];
return withTypeString({
info: TypeDefInfo.Tuple,
...(tupleStructNameIndex
? { name: this.stringAt(tupleStructNameIndex) }
? { name: this._stringAt(tupleStructNameIndex) }
: {}
),
sub: tupleStructTypes.map((fieldIndex: number, index: number): TypeDef => ({
+3 -3
View File
@@ -49,16 +49,16 @@ export default class Blueprint<ApiType extends ApiTypes> extends BaseWithTx<ApiT
return {
signAndSend: this.decorateMethod(
(account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription<ApiType> => {
return this.apiContracts
return this._apiContracts
.create(endowment, maxGas, this.codeHash, this.abi.constructors[constructorIndex](...params))
.signAndSend(account)
.pipe(map(this.createResult));
.pipe(map(this._createResult));
}
)
};
}
private createResult = (result: SubmittableResult): BlueprintCreateResult<ApiType> => {
private _createResult = (result: SubmittableResult): BlueprintCreateResult<ApiType> => {
let contract: Contract<ApiType> | undefined;
if (result.isInBlock) {
+3 -3
View File
@@ -48,15 +48,15 @@ export default class Code<ApiType extends ApiTypes> extends BaseWithTx<ApiType>
return {
signAndSend: this.decorateMethod(
(account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType> =>
this.apiContracts
this._apiContracts
.putCode(maxGas, compactAddLength(this.code))
.signAndSend(account)
.pipe(map(this.createResult))
.pipe(map(this._createResult))
)
};
}
private createResult = (result: ISubmittableResult): CodePutCodeResult<ApiType> => {
private _createResult = (result: ISubmittableResult): CodePutCodeResult<ApiType> => {
let blueprint: Blueprint<ApiType> | undefined;
if (result.isInBlock) {
+17 -17
View File
@@ -33,35 +33,41 @@ export type ContractCallResult<CallType extends ContractCallTypes> = CallType ex
export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpcCall<ApiType> {
public readonly address: Address;
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, address: string | AccountId | Address) {
super(api, abi, decorateMethod);
this.address = this.registry.createType('Address', address);
}
public call (as: 'rpc', message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, 'rpc'>;
public call (as: 'tx', message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, 'tx'>;
public call<CallType extends ContractCallTypes> (as: CallType, message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, CallType> {
const { fn, def } = this.getMessage(message);
const { def, fn } = this.getMessage(message);
return {
send: this.decorateMethod(
as === 'rpc' && this.hasRpcContractsCall
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> =>
this.rpcContractsCall(
this._rpcContractsCall(
this.registry.createType('ContractCallRequest', {
origin: account,
dest: this.address.toString(),
value,
gasLimit,
inputData: fn(...params)
inputData: fn(...params),
origin: account,
value
})
).pipe(map((result: ContractExecResult): ContractCallOutcome =>
this.createOutcome(result, this.registry.createType('AccountId', account), def, params)
this._createOutcome(result, this.registry.createType('AccountId', account), def, params)
))
: (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'tx'> =>
this.apiContracts
this._apiContracts
.call(this.address, value, gasLimit, fn(...params))
.signAndSend(account)
)
};
}
private createOutcome (result: ContractExecResult, origin: AccountId, message: ContractABIMessage, params: any[]): ContractCallOutcome {
private _createOutcome (result: ContractExecResult, origin: AccountId, message: ContractABIMessage, params: any[]): ContractCallOutcome {
let output: Codec | null = null;
if (result.isSuccess) {
@@ -73,19 +79,13 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
}
return {
time: Date.now(),
isSuccess: result.isSuccess,
message,
origin,
output,
params,
result,
isSuccess: result.isSuccess,
output
time: Date.now()
};
}
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, address: string | AccountId | Address) {
super(api, abi, decorateMethod);
this.address = this.registry.createType('Address', address);
}
}
+6 -5
View File
@@ -31,9 +31,9 @@ export abstract class Base<ApiType extends ApiTypes> implements ContractBase<Api
public get messages (): ContractMessage[] {
return this.abi.abi.contract.messages.map(
(def: ContractABIMessage, index): ContractMessage => ({
index,
def,
fn: this.abi.messages[def.name] || this.abi.messages[stringCamelCase(name)]
fn: this.abi.messages[def.name] || this.abi.messages[stringCamelCase(name)],
index
})
);
}
@@ -49,12 +49,13 @@ export abstract class Base<ApiType extends ApiTypes> implements ContractBase<Api
assert(!!def, `Attempted to access a contract message that does not exist: ${typeof nameOrIndex === 'number' ? `index ${nameOrIndex}` : nameOrIndex}`);
const fn = this.abi.messages[def.name] || this.abi.messages[stringCamelCase(def.name)];
return { index, def, fn };
return { def, fn, index };
}
}
export abstract class BaseWithTx<ApiType extends ApiTypes> extends Base<ApiType> {
protected get apiContracts (): SubmittableModuleExtrinsics<'rxjs'> {
protected get _apiContracts (): SubmittableModuleExtrinsics<'rxjs'> {
return this.api.rx.tx.contracts;
}
@@ -70,7 +71,7 @@ export abstract class BaseWithTxAndRpcCall<ApiType extends ApiTypes> extends Bas
return isFunction(this.api.rx.rpc.contracts?.call);
}
protected get rpcContractsCall (): DecoratedRpc<'rxjs', RpcInterface>['contracts']['call'] {
protected get _rpcContractsCall (): DecoratedRpc<'rxjs', RpcInterface>['contracts']['call'] {
assert(this.hasRpcContractsCall, 'You need to connect to a node with the contracts.call RPC method.');
return this.api.rx.rpc.contracts.call;
-1
View File
@@ -7,7 +7,6 @@ import { AccountId, Address, ContractExecResult } from '@polkadot/types/interfac
import { Codec, CodecArg } from '@polkadot/types/types';
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/create/types';
// import { Observable } from 'rxjs';
import { ApiPromise, ApiRx } from '@polkadot/api';
export type ApiObject<ApiType extends ApiTypes> = ApiType extends 'rxjs'
+1 -1
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Codec, Registry, TypeDefInfo, TypeDef } from '@polkadot/types/types';
import { Codec, Registry, TypeDef, TypeDefInfo } from '@polkadot/types/types';
import { Option, Raw, createClass, createTypeUnsafe } from '@polkadot/types';
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-derive",
"version": "1.5.1",
"version": "1.12.1",
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
"main": "index.js",
"keywords": [
@@ -27,18 +27,18 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api": "1.5.1",
"@polkadot/rpc-core": "1.5.1",
"@polkadot/rpc-provider": "1.5.1",
"@polkadot/types": "1.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"@babel/runtime": "^7.9.2",
"@polkadot/api": "1.12.1",
"@polkadot/rpc-core": "1.12.1",
"@polkadot/rpc-provider": "1.12.1",
"@polkadot/types": "1.12.1",
"@polkadot/util": "^2.9.0-beta.3",
"@polkadot/util-crypto": "^2.9.0-beta.3",
"bn.js": "^5.1.1",
"memoizee": "^0.4.14",
"rxjs": "^6.5.4"
"rxjs": "^6.5.5"
},
"devDependencies": {
"@polkadot/keyring": "^2.6.1"
"@polkadot/keyring": "^2.9.0-beta.3"
}
}
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Address, Balance } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveAccountFlags } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { Vec } from '@polkadot/types';
import { memo } from '../util';
type FlagsIntermediate = [
Vec<ITuple<[AccountId, Balance]>> | undefined,
AccountId[],
AccountId[],
AccountId[],
AccountId | undefined
];
function isIncludedFn (accountId: AccountId | Address | string): (_: AccountId | Address |string) => boolean {
return function (id: AccountId | Address | string): boolean {
return id.toString() === accountId.toString();
};
}
/**
* @name info
* @description Returns account membership flags
*/
export function flags (api: ApiInterfaceRx): (address?: AccountId | Address | string | null) => Observable<DeriveAccountFlags> {
return memo((address?: AccountId | Address | string | null): Observable<DeriveAccountFlags> => {
const councilSection = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections';
return (
combineLatest([
address && api.query[councilSection]?.members
? api.query[councilSection].members()
: of(undefined),
address && api.query.council?.members
? api.query.council.members()
: of([]),
address && api.query.technicalCommittee?.members
? api.query.technicalCommittee.members()
: of([]),
address && api.query.society?.members
? api.query.society.members()
: of([]),
address && api.query.sudo?.key
? api.query.sudo.key()
: of(undefined)
]) as Observable<FlagsIntermediate>
).pipe(
map(([electionsMembers, councilMembers, technicalCommitteeMembers, societyMembers, sudoKey]): DeriveAccountFlags => {
const isIncluded = address ? isIncludedFn(address) : (): boolean => false;
return {
isCouncil: (electionsMembers?.map(([id]: ITuple<[AccountId, Balance]>) => id) || councilMembers || []).some(isIncluded),
isSociety: (societyMembers || []).some(isIncluded),
isSudo: sudoKey?.toString() === address?.toString(),
isTechCommittee: (technicalCommitteeMembers || []).some(isIncluded)
};
})
);
});
}
@@ -3,18 +3,16 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
import { AccountIdAndIndex } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType } from '@polkadot/types';
import { isU8a } from '@polkadot/util';
import { decodeAddress } from '@polkadot/util-crypto';
import { memo } from '../util';
export type AccountIdAndIndex = [AccountId?, AccountIndex?];
function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIndex | string | null | undefined): Observable<AccountIdAndIndex> {
try {
// yes, this can fail, don't care too much, catch will catch it
@@ -23,14 +21,14 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn
: decodeAddress((address || '').toString());
if (decoded.length === 32) {
const accountId = createType(api.registry, 'AccountId', decoded);
const accountId = api.registry.createType('AccountId', decoded);
return api.derive.accounts.idToIndex(accountId).pipe(
map((accountIndex): AccountIdAndIndex => [accountId, accountIndex])
);
}
const accountIndex = createType(api.registry, 'AccountIndex', decoded);
const accountIndex = api.registry.createType('AccountIndex', decoded);
return api.derive.accounts.indexToId(accountIndex).pipe(
map((accountId): AccountIdAndIndex => [accountId, accountIndex])
@@ -6,7 +6,7 @@ import { AccountId, AccountIndex } from '@polkadot/types/interfaces';
import { AccountIndexes } from '../types';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
@@ -28,7 +28,6 @@ import { memo } from '../util';
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
return memo((accountId: AccountId | string): Observable<AccountIndex | undefined> =>
api.derive.accounts.indexes().pipe(
startWith({}),
map((indexes: AccountIndexes): AccountIndex | undefined =>
(indexes || {})[accountId.toString()]
)
@@ -2,6 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './flags';
export * from './idAndIndex';
export * from './idToIndex';
export * from './indexToId';
@@ -9,14 +9,14 @@ import { Observable, of } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
import { Option, Vec, createType } from '@polkadot/types';
import { Option, Vec } from '@polkadot/types';
import { memo } from '../util';
function queryEnumSet (api: ApiInterfaceRx, _accountIndex: AccountIndex | string): Observable<AccountId | undefined> {
const accountIndex = _accountIndex instanceof api.registry.createClass('AccountIndex')
? _accountIndex
: createType(api.registry, 'AccountIndex', _accountIndex);
: api.registry.createType('AccountIndex', _accountIndex);
return api.query.indices.enumSet<Vec<AccountId>>(accountIndex.div(ENUMSET_SIZE)).pipe(
startWith([]),
+20 -10
View File
@@ -7,9 +7,9 @@ import { AccountId, AccountIndex } from '@polkadot/types/interfaces';
import { AccountIndexes } from '../types';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { map, startWith, switchMap } from 'rxjs/operators';
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
import { Vec, createType } from '@polkadot/types';
import { Vec } from '@polkadot/types';
import { memo } from '../util';
@@ -25,24 +25,33 @@ function queryEnumSet (api: ApiInterfaceRx): Observable<AccountIndexes> {
api.query.indices.enumSet.multi<Vec<AccountId>>([...Array(next.toNumber() + 1).keys()])
),
map((all: AccountId[][]): AccountIndexes =>
all.reduce((result: AccountIndexes, list, outerIndex): AccountIndexes => {
all.reduce((indexes: AccountIndexes, list, outerIndex): AccountIndexes => {
(list || []).forEach((accountId, innerIndex): void => {
// re-create the index based on position 0 is [0][0] and likewise
// 64 (0..63 in first) is [1][0] (the first index value in set 2)
const index = (outerIndex * enumsetSize) + innerIndex;
result[accountId.toString()] = createType(api.registry, 'AccountIndex', index);
indexes[accountId.toString()] = api.registry.createType('AccountIndex', index);
});
return result;
return indexes;
}, {})
)
);
}
// TODO Reverse lookup (via query keys)
function query (): Observable<AccountIndexes> {
return of({} as AccountIndexes);
function queryAccounts (api: ApiInterfaceRx): Observable<AccountIndexes> {
return api.query.indices.accounts.entries().pipe(
map((entries): AccountIndexes =>
entries.reduce((indexes: AccountIndexes, [key, idOpt]): AccountIndexes => {
if (idOpt.isSome) {
indexes[idOpt.unwrap()[0].toString()] = key.args[0] as AccountIndex;
}
return indexes;
}, {})
)
);
}
/**
@@ -62,10 +71,11 @@ function query (): Observable<AccountIndexes> {
*/
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
return memo((): Observable<AccountIndexes> =>
api.query.indices
(api.query.indices
? api.query.indices.accounts
? query()
? queryAccounts(api)
: queryEnumSet(api)
: of({} as AccountIndexes)
).pipe(startWith({}))
);
}
+5 -5
View File
@@ -17,9 +17,9 @@ import { memo } from '../util';
function dataAsString (data: Data): string | undefined {
return data.isRaw
? u8aToString(data.asRaw.toU8a(true))
: data.isSha256
? data.asSha256.toHex()
: undefined;
: data.isNone
? undefined
: data.toHex();
}
function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<string | undefined> {
@@ -53,6 +53,7 @@ function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [Accou
: undefined,
email: dataAsString(info.email),
image: dataAsString(info.image),
judgements,
legal: dataAsString(info.legal),
other: info.additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
@@ -72,8 +73,7 @@ function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [Accou
: undefined,
riot: dataAsString(info.riot),
twitter: dataAsString(info.twitter),
web: dataAsString(info.web),
judgements
web: dataAsString(info.web)
};
}
+38
View File
@@ -0,0 +1,38 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, RegistrationJudgement } from '@polkadot/types/interfaces';
export type AccountIdAndIndex = [AccountId?, AccountIndex?];
export type AccountIndexes = Record<string, AccountIndex>;
export interface DeriveAccountRegistration {
display?: string;
displayParent?: string;
email?: string;
image?: string;
legal?: string;
other?: Record<string, string>;
parent?: AccountId;
pgp?: string;
riot?: string;
twitter?: string;
web?: string;
judgements: RegistrationJudgement[];
}
export interface DeriveAccountFlags {
isCouncil: boolean;
isSociety: boolean;
isSudo: boolean;
isTechCommittee: boolean;
}
export interface DeriveAccountInfo {
accountId?: AccountId;
accountIndex?: AccountIndex;
identity: DeriveAccountRegistration;
nickname?: string;
}
+11 -12
View File
@@ -4,18 +4,17 @@
import { AccountId, AccountData, AccountIndex, AccountInfo, Address, Balance, Index } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DerivedBalancesAccount } from '../types';
import { DeriveBalancesAccount } from '../types';
import { combineLatest, of, Observable } from 'rxjs';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType } from '@polkadot/types';
import { memo } from '../util';
type Result = [Balance, Balance, Balance, Balance, Index];
function calcBalances (api: ApiInterfaceRx, [accountId, [freeBalance, reservedBalance, frozenFee, frozenMisc, accountNonce]]: [AccountId, Result]): DerivedBalancesAccount {
function calcBalances (api: ApiInterfaceRx, [accountId, [freeBalance, reservedBalance, frozenFee, frozenMisc, accountNonce]]: [AccountId, Result]): DeriveBalancesAccount {
return {
accountId,
accountNonce,
@@ -23,7 +22,7 @@ function calcBalances (api: ApiInterfaceRx, [accountId, [freeBalance, reservedBa
frozenFee,
frozenMisc,
reservedBalance,
votingBalance: createType(api.registry, 'Balance', freeBalance.add(reservedBalance))
votingBalance: api.registry.createType('Balance', freeBalance.add(reservedBalance))
};
}
@@ -35,7 +34,7 @@ function queryBalancesFree (api: ApiInterfaceRx, accountId: AccountId): Observab
[api.query.system.accountNonce, accountId]
]).pipe(
map(([freeBalance, reservedBalance, accountNonce]): Result =>
[freeBalance, reservedBalance, createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), accountNonce]
[freeBalance, reservedBalance, api.registry.createType('Balance'), api.registry.createType('Balance'), accountNonce]
)
);
}
@@ -45,7 +44,7 @@ function queryBalancesAccount (api: ApiInterfaceRx, accountId: AccountId): Obser
[api.query.balances.account, accountId],
[api.query.system.accountNonce, accountId]
]).pipe(
map(([{ free, reserved, miscFrozen, feeFrozen }, accountNonce]): Result =>
map(([{ feeFrozen, free, miscFrozen, reserved }, accountNonce]): Result =>
[free, reserved, feeFrozen, miscFrozen, accountNonce]
)
);
@@ -55,7 +54,7 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Re
// AccountInfo is current, support old, eg. Edgeware
return api.query.system.account<AccountInfo | ITuple<[Index, AccountData]>>(accountId).pipe(
map((infoOrTuple): Result => {
const { free, reserved, miscFrozen, feeFrozen } = (infoOrTuple as AccountInfo).nonce
const { feeFrozen, free, miscFrozen, reserved } = (infoOrTuple as AccountInfo).nonce
? (infoOrTuple as AccountInfo).data
: (infoOrTuple as [Index, AccountData])[1];
const accountNonce = (infoOrTuple as AccountInfo).nonce || (infoOrTuple as [Index, AccountData])[0];
@@ -80,8 +79,8 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Re
* });
* ```
*/
export function account (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalancesAccount> {
return memo((address: AccountIndex | AccountId | Address | string): Observable<DerivedBalancesAccount> =>
export function account (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DeriveBalancesAccount> {
return memo((address: AccountIndex | AccountId | Address | string): Observable<DeriveBalancesAccount> =>
api.derive.accounts.info(address).pipe(
switchMap(({ accountId }): Observable<[AccountId, Result]> =>
(accountId
@@ -93,9 +92,9 @@ export function account (api: ApiInterfaceRx): (address: AccountIndex | AccountI
? queryBalancesAccount(api, accountId)
: queryBalancesFree(api, accountId)
])
: of([createType(api.registry, 'AccountId'), [createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), createType(api.registry, 'Index')]])
: of([api.registry.createType('AccountId'), [api.registry.createType('Balance'), api.registry.createType('Balance'), api.registry.createType('Balance'), api.registry.createType('Balance'), api.registry.createType('Index')]])
)
),
map((result): DerivedBalancesAccount => calcBalances(api, result))
map((result): DeriveBalancesAccount => calcBalances(api, result))
));
}
+19 -16
View File
@@ -3,23 +3,24 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, Address, Balance, BalanceLock, BalanceLockTo212, BlockNumber, VestingInfo, VestingSchedule } from '@polkadot/types/interfaces';
import { DerivedBalancesAccount, DerivedBalancesAll } from '../types';
import { DeriveBalancesAccount, DeriveBalancesAll } from '../types';
import BN from 'bn.js';
import { combineLatest, of, Observable } from 'rxjs';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, Vec, createType } from '@polkadot/types';
import { Option, Vec } from '@polkadot/types';
import { bnMax } from '@polkadot/util';
import { memo } from '../util';
type ResultBalance = [VestingInfo | null, (BalanceLock | BalanceLockTo212)[]];
type Result = [DerivedBalancesAccount, BlockNumber, ResultBalance];
type Result = [DeriveBalancesAccount, BlockNumber, ResultBalance];
function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBalance, frozenFee, frozenMisc, reservedBalance, votingBalance }, bestNumber, [vesting, locks]]: Result): DerivedBalancesAll {
let lockedBalance = createType(api.registry, 'Balance');
function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBalance, frozenFee, frozenMisc, reservedBalance, votingBalance }, bestNumber, [vesting, locks]]: Result): DeriveBalancesAll {
let lockedBalance = api.registry.createType('Balance');
let lockedBreakdown: (BalanceLock | BalanceLockTo212)[] = [];
let allLocked = false;
if (Array.isArray(locks)) {
// only get the locks that are valid until passed the current block
@@ -27,18 +28,20 @@ function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBala
const notAll = lockedBreakdown.filter(({ amount }): boolean => !amount.isMax());
allLocked = lockedBreakdown.some(({ amount }): boolean => amount.isMax());
// get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699
if (notAll.length) {
lockedBalance = createType(api.registry, 'Balance', bnMax(...notAll.map(({ amount }): Balance => amount)));
lockedBalance = api.registry.createType('Balance', bnMax(...notAll.map(({ amount }): Balance => amount)));
}
}
// Calculate the vesting balances,
// - offset = balance locked at startingBlock
// - perBlock is the unlock amount
const { locked: vestingTotal, perBlock, startingBlock } = vesting || createType(api.registry, 'VestingInfo');
const { locked: vestingTotal, perBlock, startingBlock } = vesting || api.registry.createType('VestingInfo');
const isStarted = bestNumber.gt(startingBlock);
const vestedBalance = createType(api.registry, 'Balance', isStarted ? perBlock.mul(bestNumber.sub(startingBlock)) : 0);
const vestedBalance = api.registry.createType('Balance', isStarted ? perBlock.mul(bestNumber.sub(startingBlock)) : 0);
const isVesting = isStarted && vestedBalance.lt(vestingTotal);
// The available balance & vested has an interplay here
@@ -50,7 +53,7 @@ function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBala
// ""
const floating = freeBalance.sub(lockedBalance);
const extraReceived = isVesting ? freeBalance.sub(vestingTotal) : new BN(0);
const availableBalance = createType(api.registry, 'Balance', bnMax(new BN(0), isVesting && floating.gt(vestedBalance) ? vestedBalance.add(extraReceived) : floating));
const availableBalance = api.registry.createType('Balance', allLocked ? 0 : bnMax(new BN(0), isVesting && floating.gt(vestedBalance) ? vestedBalance.add(extraReceived) : floating));
return {
accountId,
@@ -81,7 +84,7 @@ function queryOld (api: ApiInterfaceRx, accountId: AccountId): Observable<Result
if (optVesting.isSome) {
const { offset: locked, perBlock, startingBlock } = optVesting.unwrap();
vestingNew = createType(api.registry, 'VestingInfo', { locked, perBlock, startingBlock });
vestingNew = api.registry.createType('VestingInfo', { locked, perBlock, startingBlock });
}
return [vestingNew, locks];
@@ -99,7 +102,7 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Re
])
: api.query.balances.locks(accountId).pipe(
map((locks): [Vec<BalanceLock>, Option<VestingInfo>] =>
[locks, createType(api.registry, 'Option<VestingInfo>')]
[locks, api.registry.createType('Option<VestingInfo>')]
)
)
).pipe(
@@ -124,8 +127,8 @@ function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Re
* });
* ```
*/
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalancesAll> {
return memo((address: AccountIndex | AccountId | Address | string): Observable<DerivedBalancesAll> =>
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DeriveBalancesAll> {
return memo((address: AccountIndex | AccountId | Address | string): Observable<DeriveBalancesAll> =>
api.derive.balances.account(address).pipe(
switchMap((account): Observable<Result> =>
(!account.accountId.isEmpty
@@ -136,9 +139,9 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
? queryCurrent(api, account.accountId)
: queryOld(api, account.accountId)
])
: of([account, createType(api.registry, 'BlockNumber'), [null, createType(api.registry, 'Vec<BalanceLock>')]])
: of([account, api.registry.createType('BlockNumber'), [null, api.registry.createType('Vec<BalanceLock>')]])
)
),
map((result): DerivedBalancesAll => calcBalances(api, result))
map((result): DeriveBalancesAll => calcBalances(api, result))
));
}
+9 -10
View File
@@ -4,11 +4,10 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Balance } from '@polkadot/types/interfaces';
import { DerivedFees } from '../types';
import { DeriveFees } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { memo } from '../util';
@@ -25,19 +24,19 @@ import { memo } from '../util';
* });
* ```
*/
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
return memo((): Observable<DerivedFees> =>
export function fees (api: ApiInterfaceRx): () => Observable<DeriveFees> {
return memo((): Observable<DeriveFees> =>
of([
// deprecated - remove
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances?.creationFee as Balance) || api.registry.createType('Balance'),
(api.consts.balances?.transferFee as Balance) || api.registry.createType('Balance'),
// current
api.consts.balances.existentialDeposit,
api.consts.transactionPayment.transactionBaseFee,
api.consts.transactionPayment.transactionByteFee
(api.consts.balances?.existentialDeposit as Balance) || api.registry.createType('Balance'),
(api.consts.transactionPayment?.transactionBaseFee as Balance) || api.registry.createType('Balance'),
(api.consts.transactionPayment?.transactionByteFee as Balance) || api.registry.createType('Balance')
]).pipe(
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DerivedFees => ({
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DeriveFees => ({
creationFee,
existentialDeposit,
transactionBaseFee,
@@ -3,20 +3,21 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
import { DerivedBalancesAccount } from '../types';
import { DeriveBalancesAccount } from '../types';
import { combineLatest, Observable, of } from 'rxjs';
import { Observable, combineLatest, of } from 'rxjs';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DerivedBalancesAccount[]> {
return memo((addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalancesAccount[]> =>
export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DeriveBalancesAccount[]> {
return memo((addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DeriveBalancesAccount[]> =>
!addresses || !addresses.length
? of([] as DerivedBalancesAccount[])
? of([] as DeriveBalancesAccount[])
: combineLatest(
addresses.map((accountId): Observable<DerivedBalancesAccount> =>
api.derive.balances.account(accountId))
addresses.map((accountId): Observable<DeriveBalancesAccount> =>
api.derive.balances.account(accountId)
)
)
);
}
@@ -7,7 +7,6 @@ import { BlockNumber } from '@polkadot/types/interfaces';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType } from '@polkadot/types';
import { memo } from '../util';
@@ -31,7 +30,7 @@ export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumbe
api.derive.chain.bestNumberFinalized()
]).pipe(
map(([bestNumber, bestNumberFinalized]): BlockNumber =>
createType(api.registry, 'BlockNumber', bestNumber.sub(bestNumberFinalized))
api.registry.createType('BlockNumber', bestNumber.sub(bestNumberFinalized))
)
));
}
@@ -4,17 +4,19 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Hash, Proposal, Votes } from '@polkadot/types/interfaces';
import { DerivedCollectiveProposal } from '../types';
import { DeriveCollectiveProposal } from '../types';
import { combineLatest, Observable, of } from 'rxjs';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { memo } from '../util';
type Result = [Hash[], Option<Proposal>[], Option<Votes>[]];
function parse ([hashes, proposals, votes]: Result): DerivedCollectiveProposal[] {
function parse ([hashes, proposals, votes]: Result): DeriveCollectiveProposal[] {
return proposals
.map((proposalOpt, index): DerivedCollectiveProposal | null =>
.map((proposalOpt, index): DeriveCollectiveProposal | null =>
proposalOpt.isSome
? {
hash: hashes[index],
@@ -23,12 +25,12 @@ function parse ([hashes, proposals, votes]: Result): DerivedCollectiveProposal[]
}
: null
)
.filter((proposal): proposal is DerivedCollectiveProposal => !!proposal);
.filter((proposal): proposal is DeriveCollectiveProposal => !!proposal);
}
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DerivedCollectiveProposal[]> {
return (): Observable<DerivedCollectiveProposal[]> =>
api.query[section]
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DeriveCollectiveProposal[]> {
return memo((): Observable<DeriveCollectiveProposal[]> =>
api.query[section]?.proposals
? api.query[section].proposals().pipe(
switchMap((hashes: Hash[]): Observable<Result> =>
hashes.length
@@ -41,5 +43,6 @@ export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalC
),
map(parse)
)
: of([] as DerivedCollectiveProposal[]);
: of([] as DeriveCollectiveProposal[])
);
}
+6 -7
View File
@@ -3,12 +3,11 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedContractFees } from '../types';
import { DeriveContractFees } from '../types';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { memo } from '../util';
@@ -18,8 +17,8 @@ type ResultV2 = [BN, BN, BN, BN, BN, BN, BN, BN, BN];
function queryConstants (api: ApiInterfaceRx): Observable<ResultV2> {
return of([
// deprecated
api.consts.contracts.creationFee || createType(api.registry, 'Balance'),
api.consts.contracts.transferFee || createType(api.registry, 'Balance'),
api.consts.contracts.creationFee || api.registry.createType('Balance'),
api.consts.contracts.transferFee || api.registry.createType('Balance'),
// current
api.consts.contracts.callBaseFee,
@@ -45,10 +44,10 @@ function queryConstants (api: ApiInterfaceRx): Observable<ResultV2> {
* });
* ```
*/
export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees> {
return memo((): Observable<DerivedContractFees> => {
export function fees (api: ApiInterfaceRx): () => Observable<DeriveContractFees> {
return memo((): Observable<DeriveContractFees> => {
return queryConstants(api).pipe(
map(([creationFee, transferFee, callBaseFee, contractFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee]): DerivedContractFees => ({
map(([creationFee, transferFee, callBaseFee, contractFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee]): DeriveContractFees => ({
callBaseFee,
contractFee,
creationFee,
+2
View File
@@ -3,3 +3,5 @@
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './proposals';
export * from './votes';
export * from './votesOf';
+2 -2
View File
@@ -3,12 +3,12 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedCollectiveProposals } from '../types';
import { DeriveCollectiveProposals } from '../types';
import { Observable } from 'rxjs';
import { proposals as collectiveProposals } from '../collective';
import { memo } from '../util';
export function proposals (api: ApiInterfaceRx): () => Observable<DerivedCollectiveProposals> {
export function proposals (api: ApiInterfaceRx): () => Observable<DeriveCollectiveProposals> {
return memo(collectiveProposals(api, 'council'));
}
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance } from '@polkadot/types/interfaces';
export interface DeriveCouncilVote {
stake: Balance;
votes: AccountId[];
}
export type DeriveCouncilVotes = [AccountId, DeriveCouncilVote][];
+90
View File
@@ -0,0 +1,90 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveCouncilVote, DeriveCouncilVotes } from '../types';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { Vec } from '@polkadot/types';
import { memo } from '../util';
function retrieveStakeOf (api: ApiInterfaceRx): Observable<[AccountId, Balance][]> {
const elections = (api.query.electionsPhragmen || api.query.elections);
return elections.stakeOf.creator.meta.type.asMap.linked.isTrue
? elections.stakeOf<ITuple<[Vec<AccountId>, Vec<Balance>]>>().pipe(
map(([voters, stake]) =>
voters.map((voter, index): [AccountId, Balance] => [voter, stake[index]])
)
)
: elections.stakeOf.entries<Balance>().pipe(
map((entries) =>
entries.map(([key, stake]) => [key.args[0] as AccountId, stake])
)
);
}
function retrieveVoteOf (api: ApiInterfaceRx): Observable<[AccountId, AccountId[]][]> {
const elections = (api.query.electionsPhragmen || api.query.elections);
return elections.votesOf.creator.meta.type.asMap.linked.isTrue
? elections.votesOf<ITuple<[Vec<AccountId>, Vec<Vec<AccountId>>]>>().pipe(
map(([voters, votes]) =>
voters.map((voter, index) => [voter, votes[index]])
)
)
: elections.votesOf.entries<Vec<AccountId>>().pipe(
map((entries) =>
entries.map(([key, votes]) => [key.args[0] as AccountId, votes])
)
);
}
function retrievePrev (api: ApiInterfaceRx): Observable<DeriveCouncilVotes> {
return combineLatest([retrieveStakeOf(api), retrieveVoteOf(api)]).pipe(
map(([stakes, votes]): DeriveCouncilVotes => {
const result: DeriveCouncilVotes = [];
votes.forEach(([voter, votes]): void => {
result.push([voter, { stake: api.registry.createType('Balance'), votes }]);
});
stakes.forEach(([staker, stake]): void => {
const entry = result.find(([voter]) => voter.eq(staker));
if (entry) {
entry[1].stake = stake;
} else {
result.push([staker, { stake, votes: [] }]);
}
});
return result;
})
);
}
function retrieveCurrent (api: ApiInterfaceRx): Observable<DeriveCouncilVotes> {
const elections = (api.query.electionsPhragmen || api.query.elections);
return elections.voting.entries<ITuple<[Balance, Vec<AccountId>]>>().pipe(
map((entries): DeriveCouncilVotes =>
entries.map(([key, [stake, votes]]): [AccountId, DeriveCouncilVote] =>
[key.args[0] as AccountId, { stake, votes }]
)
)
);
}
export function votes (api: ApiInterfaceRx): () => Observable<DeriveCouncilVotes> {
return memo((): Observable<DeriveCouncilVotes> =>
(api.query.electionsPhragmen || api.query.elections).stakeOf
? retrievePrev(api)
: retrieveCurrent(api)
);
}
@@ -0,0 +1,24 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveCouncilVote } from '../types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { memo } from '../util';
export function votesOf (api: ApiInterfaceRx): (accountId: string | Uint8Array | AccountId) => Observable<DeriveCouncilVote> {
return memo((accountId: string | Uint8Array | AccountId): Observable<DeriveCouncilVote> =>
api.derive.council.votes().pipe(
map((votes): DeriveCouncilVote =>
(
votes.find(([from]) => from.eq(accountId)) ||
[null, { stake: api.registry.createType('Balance'), votes: [] as AccountId[] }]
)[1]
)
)
);
}
@@ -0,0 +1,105 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BlockNumber, Hash, ReferendumIndex, Scheduled } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveDispatch, DeriveProposalImage } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, Vec, u64 } from '@polkadot/types';
import { stringToHex } from '@polkadot/util';
import { memo } from '../util';
const DEMOCRACY_ID = stringToHex('democrac');
interface SchedulerInfo {
at: BlockNumber;
imageHash: Hash;
index: ReferendumIndex;
}
function queryQueue (api: ApiInterfaceRx): Observable<DeriveDispatch[]> {
return api.query.democracy.dispatchQueue<Vec<ITuple<[BlockNumber, Hash, ReferendumIndex]>>>().pipe(
switchMap((dispatches) =>
combineLatest([
of(dispatches),
api.derive.democracy.preimages(
dispatches.map(([, hash]) => hash))
])
),
map(([dispatches, images]) =>
dispatches.map(([at, imageHash, index], dispatchIndex): DeriveDispatch => ({
at,
image: images[dispatchIndex],
imageHash,
index
}))
)
);
}
function schedulerEntries (api: ApiInterfaceRx): Observable<[BlockNumber[], Option<Scheduled>[][]]> {
// We don't get entries, but rather we get the keys (triggered via finished referendums) and
// the subscribe to those keys - this means we pickup when the schedulers actually executes
// at a block, the entry for that block will become empty
return api.derive.democracy.referendumsFinished().pipe(
switchMap(() =>
api.query.scheduler.agenda.keys()
),
switchMap((keys) => {
const blockNumbers = keys.map((key) => key.args[0] as BlockNumber);
return combineLatest([
of(blockNumbers),
api.query.scheduler.agenda.multi<Vec<Option<Scheduled>>>(blockNumbers)
]);
})
);
}
function queryScheduler (api: ApiInterfaceRx): Observable<DeriveDispatch[]> {
return schedulerEntries(api).pipe(
switchMap(([blockNumbers, agendas]): Observable<[SchedulerInfo[], (DeriveProposalImage | undefined)[]]> => {
const result: SchedulerInfo[] = [];
blockNumbers.forEach((at, index): void => {
agendas[index].filter((optScheduled) => optScheduled.isSome).forEach((optScheduled): void => {
const scheduled = optScheduled.unwrap();
if (scheduled.maybeId.isSome) {
const id = scheduled.maybeId.unwrap().toHex();
if (id.startsWith(DEMOCRACY_ID)) {
const [, index] = api.registry.createType('(u64, ReferendumIndex)' as any, id) as ITuple<[u64, ReferendumIndex]>;
const imageHash = scheduled.call.args[0] as Hash;
result.push({ at, imageHash, index });
}
}
});
});
return combineLatest([
of(result),
api.derive.democracy.preimages(result.map(({ imageHash }) => imageHash))
]);
}),
map(([infos, images]): DeriveDispatch[] =>
infos.map((info, index) => ({ ...info, image: images[index] }))
)
);
}
export function dispatchQueue (api: ApiInterfaceRx): () => Observable<DeriveDispatch[]> {
return memo((): Observable<DeriveDispatch[]> =>
api.query.scheduler?.agenda
? queryScheduler(api)
: api.query.democracy.dispatchQueue
? queryQueue(api)
: of([])
);
}
+9 -3
View File
@@ -2,8 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './dispatchQueue';
export * from './nextExternal';
export * from './preimage';
export * from './preimages';
export * from './proposals';
export * from './referendumInfos';
export * from './referendumIds';
export * from './referendums';
export * from './referendumVotesFor';
export * from './votes';
export * from './referendumsActive';
export * from './referendumsFinished';
export * from './referendumsInfo';
export * from './sqrtElectorate';
@@ -0,0 +1,40 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Hash, VoteThreshold } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposalExternal } from '../types';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option } from '@polkadot/types';
import { memo } from '../util';
function withImage (api: ApiInterfaceRx, nextOpt: Option<ITuple<[Hash, VoteThreshold]>>): Observable<DeriveProposalExternal | null> {
if (nextOpt.isNone) {
return of(null);
}
const [imageHash, threshold] = nextOpt.unwrap();
return api.derive.democracy.preimage(imageHash).pipe(
map((image): DeriveProposalExternal => ({
image,
imageHash,
threshold
}))
);
}
export function nextExternal (api: ApiInterfaceRx): () => Observable<DeriveProposalExternal | null> {
return memo((): Observable<DeriveProposalExternal | null> =>
api.query.democracy?.nextExternal
? api.query.democracy.nextExternal<Option<ITuple<[Hash, VoteThreshold]>>>().pipe(
switchMap((nextOpt) => withImage(api, nextOpt))
)
: of(null)
);
}
@@ -0,0 +1,25 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveProposalImage } from '../types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Bytes, Option } from '@polkadot/types';
import { memo } from '../util';
import { parseImage } from './util';
type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
export function preimage (api: ApiInterfaceRx): (hash: Hash) => Observable<DeriveProposalImage | undefined> {
return memo((hash: Hash): Observable<DeriveProposalImage | undefined> =>
api.query.democracy.preimages<PreImage>(hash).pipe(
map((imageOpt) => parseImage(api, imageOpt))
)
);
}
@@ -0,0 +1,27 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveProposalImage } from '../types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Bytes, Option } from '@polkadot/types';
import { memo } from '../util';
import { parseImage } from './util';
type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
export function preimages (api: ApiInterfaceRx): (hashes: Hash[]) => Observable<(DeriveProposalImage | undefined)[]> {
return memo((hashes: Hash[]): Observable<(DeriveProposalImage | undefined)[]> =>
api.query.democracy.preimages.multi<PreImage>(hashes).pipe(
map((images): (DeriveProposalImage | undefined)[] =>
images.map((imageOpt) => parseImage(api, imageOpt))
)
)
);
}
+15 -43
View File
@@ -2,82 +2,54 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, PropIndex, Proposal } from '@polkadot/types/interfaces';
import { AccountId, Balance, Hash, PropIndex } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposal } from '../types';
import { DeriveProposalImage, DeriveProposal } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Bytes, Option, Vec, createType } from '@polkadot/types';
import { Option, Vec } from '@polkadot/types';
import { memo } from '../util';
export type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
type Depositors = Option<ITuple<[Balance, Vec<AccountId>]>>;
type Proposals = Vec<ITuple<[PropIndex, Hash, AccountId]>>;
interface Result {
depositors: Depositors[];
preimages: PreImage[];
proposals: Proposals;
}
function parse (api: ApiInterfaceRx, { depositors, proposals, preimages }: Result): DeriveProposal[] {
function parse ([proposals, images, depositors]: [Proposals, (DeriveProposalImage | undefined)[], Depositors[]]): DeriveProposal[] {
return proposals
.filter(([, , proposer], index): boolean =>
!!(depositors[index]?.isSome) && !proposer.isEmpty
)
.map(([propIndex, hash, proposer], index): DeriveProposal => {
const preimage = preimages[index].unwrapOr(null);
const depositor = depositors[index].unwrap();
let proposal: undefined | Proposal;
// we could end up in a situation where the proposal is non-decodable, e.g. after an upgrade
if (preimage) {
try {
proposal = createType(api.registry, 'Proposal', preimage[0].toU8a(true));
} catch (error) {
console.error(error);
}
}
.map(([index, imageHash, proposer], proposalIndex): DeriveProposal => {
const [balance, seconds] = depositors[proposalIndex].unwrap();
return {
balance: depositor[0],
hash,
index: propIndex,
preimage: preimage
? {
at: preimage[3],
balance: preimage[2],
proposer: preimage[1]
}
: undefined,
proposal,
balance,
image: images[proposalIndex],
imageHash,
index,
proposer,
seconds: depositor[1]
seconds
};
});
}
export function proposals (api: ApiInterfaceRx): () => Observable<DeriveProposal[]> {
return memo((): Observable<DeriveProposal[]> =>
api.query.democracy?.publicProps
api.query.democracy?.publicProps && api.query.democracy?.preimages
? api.query.democracy.publicProps<Proposals>().pipe(
switchMap((proposals) =>
combineLatest([
of(proposals),
api.query.democracy.preimages.multi<PreImage>(
api.derive.democracy.preimages(
proposals.map(([, hash]): Hash => hash)),
api.query.democracy.depositOf.multi<Depositors>(
proposals.map(([index]): PropIndex => index))
])
),
map(([proposals, preimages, depositors]): DeriveProposal[] =>
parse(api, { depositors, proposals, preimages })
)
map(parse)
)
: of([] as DeriveProposal[])
: of([])
);
}
@@ -0,0 +1,29 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ReferendumIndex } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { memo } from '../util';
export function referendumIds (api: ApiInterfaceRx): () => Observable<BN[]> {
return memo((): Observable<BN[]> =>
api.query.democracy?.lowestUnbaked
? api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
api.query.democracy.lowestUnbaked,
api.query.democracy.referendumCount
]).pipe(
map(([first, total]): BN[] =>
total.gt(first)
? [...Array(total.sub(first).toNumber())].map((_, i): BN => first.addn(i))
: []
)
)
: of([])
);
}
@@ -1,64 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ReferendumInfo } from '@polkadot/types/interfaces/democracy';
import { DerivedReferendum } from '../types';
import { PreImage } from './proposals';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, createType } from '@polkadot/types';
import { memo } from '../util';
function constructInfo (api: ApiInterfaceRx, index: BN | number, _info: Option<ReferendumInfo>, _preimage?: PreImage): DerivedReferendum | null {
const preImage = _preimage?.isSome
? _preimage.unwrap()
: null;
const info = _info.unwrapOr(null);
if (!info) {
return null;
}
return {
index: createType(api.registry, 'PropIndex', index),
info,
hash: info.proposalHash,
proposal: preImage
? createType(api.registry, 'Proposal', preImage[0].toU8a(true))
: undefined,
preimage: preImage
? {
at: preImage[3],
balance: preImage[2],
proposer: preImage[1]
}
: undefined
};
}
export function retrieveInfo (api: ApiInterfaceRx, index: BN | number, info: Option<ReferendumInfo>): Observable<DerivedReferendum | null> {
return ((
info?.isSome
? api.query.democracy.preimages(info.unwrap().proposalHash)
: of(undefined)
) as Observable<PreImage | undefined>).pipe(
map((preimage?: PreImage): DerivedReferendum | null =>
constructInfo(api, index, info, preimage)
)
);
}
export function referendumInfo (api: ApiInterfaceRx): (index: BN | number) => Observable<DerivedReferendum | null> {
return memo((index: BN | number): Observable<DerivedReferendum | null> =>
api.query.democracy.referendumInfoOf<Option<ReferendumInfo>>(index).pipe(
switchMap((info): Observable<DerivedReferendum | null> =>
retrieveInfo(api, index, info)
)
)
);
}
@@ -1,35 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ReferendumInfo } from '@polkadot/types/interfaces/democracy';
import { DerivedReferendum } from '../types';
import BN from 'bn.js';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option } from '@polkadot/types';
import { memo } from '../util';
import { retrieveInfo } from './referendumInfo';
export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<DerivedReferendum[]> {
return memo((ids: (BN | number)[] = []): Observable<DerivedReferendum[]> =>
(
!ids?.length
? of([] as Option<ReferendumInfo>[])
: api.query.democracy.referendumInfoOf.multi<Option<ReferendumInfo>>(ids)
).pipe(
switchMap((infos): Observable<(DerivedReferendum | null)[]> =>
combineLatest(
...ids.map((id, index): Observable<DerivedReferendum | null> =>
retrieveInfo(api, id, infos[index])
)
)
),
map((infos): DerivedReferendum[] =>
infos.filter((referendum): referendum is DerivedReferendum => !!referendum)
)
));
}
@@ -1,34 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Vote } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { combineLatest, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec, createType } from '@polkadot/types';
import { DerivedBalancesAccount, DerivedReferendumVote } from '../types';
import { memo } from '../util';
export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> {
return memo((referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalancesAccount[]]> =>
combineLatest([
of(votersFor),
api.derive.democracy.votes(referendumId, votersFor),
api.derive.balances.votingBalances(votersFor)
])
),
map(([votersFor, votes, balances]): DerivedReferendumVote[] =>
votersFor.map((accountId, index): DerivedReferendumVote => ({
accountId,
balance: balances[index].votingBalance || createType(api.registry, 'Balance'),
vote: votes[index] || createType(api.registry, 'Vote')
} as DerivedReferendumVote))
)
));
}
@@ -2,33 +2,29 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ReferendumIndex } from '@polkadot/types/interfaces/democracy';
import { DerivedReferendum } from '../types';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveReferendumExt } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { memo } from '../util';
export function referendums (api: ApiInterfaceRx): () => Observable<DerivedReferendum[]> {
return memo((): Observable<DerivedReferendum[]> =>
api.query.democracy?.lowestUnbaked
? api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
api.query.democracy.lowestUnbaked,
api.query.democracy.referendumCount
]).pipe(
switchMap(([earliest, referendumCount]): Observable<DerivedReferendum[]> =>
referendumCount?.gt(earliest) && referendumCount?.gtn(0)
? api.derive.democracy.referendumInfos(
[...Array(referendumCount.sub(earliest).toNumber())].map((_, i): BN =>
earliest.addn(i)
)
)
: of([])
)
export function referendums (api: ApiInterfaceRx): () => Observable<DeriveReferendumExt[]> {
return memo((): Observable<DeriveReferendumExt[]> =>
api.derive.democracy.referendumsActive().pipe(
switchMap((referendums) =>
combineLatest([
of(referendums),
api.derive.democracy._referendumsVotes(referendums)
])
),
map(([referendums, votes]) =>
referendums.map((referendum, index): DeriveReferendumExt => ({
...referendum,
...votes[index]
}))
)
: of([] as DerivedReferendum[])
)
);
}
@@ -0,0 +1,23 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveReferendum } from '../types';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { memo } from '../util';
export function referendumsActive (api: ApiInterfaceRx): () => Observable<DeriveReferendum[]> {
return memo((): Observable<DeriveReferendum[]> =>
api.derive.democracy.referendumIds().pipe(
switchMap((ids): Observable<DeriveReferendum[]> =>
ids.length
? api.derive.democracy.referendumsInfo(ids)
: of([])
)
)
);
}
@@ -0,0 +1,27 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ReferendumInfo, ReferendumInfoFinished } from '@polkadot/types/interfaces';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { memo } from '../util';
export function referendumsFinished (api: ApiInterfaceRx): () => Observable<ReferendumInfoFinished[]> {
return memo((): Observable<ReferendumInfoFinished[]> =>
api.derive.democracy.referendumIds().pipe(
switchMap((ids) => api.query.democracy.referendumInfoOf.multi<Option<ReferendumInfo>>(ids)),
map((infos): ReferendumInfoFinished[] =>
infos
.filter((optInfo) => optInfo.isSome)
.map((optInfo) => optInfo.unwrap())
.filter((info) => info.isFinished)
.map((info) => info.asFinished)
)
)
);
}
@@ -0,0 +1,155 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, ReferendumInfo, ReferendumInfoTo239, Vote, Voting, VotingDirectVote, VotingDelegating } from '@polkadot/types/interfaces';
import { DeriveBalancesAccount, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes } from '../types';
import BN from 'bn.js';
import { Observable, of, combineLatest } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option, Vec } from '@polkadot/types';
import { memo } from '../util';
import { calcVotes, getStatus, parseImage } from './util';
function votesPrev (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
return api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DeriveBalancesAccount[]]> =>
combineLatest([
of(votersFor),
votersFor.length
? api.query.democracy.voteOf.multi<Vote>(
votersFor.map((accountId): [BN | number, AccountId] =>
[referendumId, accountId]
)
)
: of([]),
api.derive.balances.votingBalances(votersFor)
])
),
map(([votersFor, votes, balances]): DeriveReferendumVote[] =>
votersFor.map((accountId, index): DeriveReferendumVote => ({
accountId,
balance: balances[index].votingBalance || api.registry.createType('Balance'),
isDelegating: false,
vote: votes[index] || api.registry.createType('Vote')
}))
)
);
}
function votesCurr (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
return api.query.democracy.votingOf.entries<Voting>().pipe(
map((allVoting): DeriveReferendumVote[] => {
const mapped = allVoting.map(([key, voting]): [AccountId, Voting] => [key.args[0] as AccountId, voting]);
const votes = mapped
.filter(([, voting]) => voting.isDirect)
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
accountId,
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
])
.filter(([, directVotes]) => !!directVotes.length)
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
// FIXME We are ignoring split votes
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
if (vote.isStandard) {
result.push({
accountId,
isDelegating: false,
...vote.asStandard
});
}
return result;
}, result), []
);
const delegations = mapped
.filter(([, voting]) => voting.isDelegating)
.map(([accountId, voting]): [AccountId, VotingDelegating] => [accountId, voting.asDelegating]);
// add delegations
delegations.forEach(([accountId, { balance, conviction, target }]): void => {
// Are we delegating to a delegator
const toDelegator = delegations.find(([accountId]) => accountId.eq(target));
const to = votes.find(({ accountId }) => accountId.eq(toDelegator ? toDelegator[0] : target));
// this delegation has a target
if (to) {
votes.push({
accountId,
balance,
isDelegating: true,
vote: api.registry.createType('Vote', { aye: to.vote.isAye, conviction })
});
}
});
return votes;
})
);
}
export function _referendumVotes (api: ApiInterfaceRx): (referendum: DeriveReferendum) => Observable<DeriveReferendumVotes> {
return memo((referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
combineLatest([
api.derive.democracy.sqrtElectorate(),
api.query.democracy.votingOf
? votesCurr(api, referendum.index)
: votesPrev(api, referendum.index)
]).pipe(
map(([sqrtElectorate, votes]) =>
calcVotes(sqrtElectorate, referendum, votes)
)
)
);
}
export function _referendumsVotes (api: ApiInterfaceRx): (referendums: DeriveReferendum[]) => Observable<DeriveReferendumVotes[]> {
return memo((referendums: DeriveReferendum[]): Observable<DeriveReferendumVotes[]> =>
referendums.length
? combineLatest(
referendums.map((referendum): Observable<DeriveReferendumVotes> =>
api.derive.democracy._referendumVotes(referendum)
)
)
: of([])
);
}
export function _referendumInfo (api: ApiInterfaceRx): (index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
return memo((index: BN, info: Option<ReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
const status = getStatus(info);
return status
? api.query.democracy.preimages(status.proposalHash).pipe(
map((preimage): DeriveReferendum => ({
image: parseImage(api, preimage),
imageHash: status.proposalHash,
index: api.registry.createType('ReferendumIndex', index),
status
}))
)
: of(null);
});
}
export function referendumsInfo (api: ApiInterfaceRx): (ids: BN[]) => Observable<DeriveReferendum[]> {
return memo((ids: BN[]): Observable<DeriveReferendum[]> =>
ids.length
? api.query.democracy.referendumInfoOf.multi<Option<ReferendumInfo>>(ids).pipe(
switchMap((infos): Observable<(DeriveReferendum | null)[]> =>
combineLatest(
ids.map((id, index): Observable<DeriveReferendum | null> =>
api.derive.democracy._referendumInfo(id, infos[index])
)
)
),
map((infos) =>
infos.filter((referendum): referendum is DeriveReferendum => !!referendum)
)
)
: of([])
);
}
@@ -0,0 +1,22 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import BN from 'bn.js';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { bnSqrt } from '@polkadot/util';
import { memo } from '../util';
export function sqrtElectorate (api: ApiInterfaceRx): () => Observable<BN> {
return memo((): Observable<BN> =>
api.query.balances.totalIssuance().pipe(
map((totalIssuance) =>
bnSqrt(totalIssuance)
)
)
);
}
@@ -0,0 +1,70 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, Proposal, PropIndex, ReferendumInfoTo239, ReferendumStatus, Vote, ReferendumIndex, VoteThreshold } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Vec } from '@polkadot/types';
export interface DeriveDispatch {
at: BlockNumber;
index: ReferendumIndex;
imageHash: Hash;
image?: DeriveProposalImage;
}
export interface DeriveProposalImage {
at: BlockNumber;
balance: Balance;
proposal?: Proposal;
proposer: AccountId;
}
export interface DeriveProposal {
balance?: Balance;
index: PropIndex;
image?: DeriveProposalImage;
imageHash: Hash;
proposer: AccountId;
seconds: Vec<AccountId>;
}
export interface DeriveProposalExternal {
image?: DeriveProposalImage;
imageHash: Hash;
threshold: VoteThreshold;
}
export interface DeriveReferendum {
index: ReferendumIndex;
image?: DeriveProposalImage;
imageHash: Hash;
status: ReferendumStatus | ReferendumInfoTo239;
}
export interface DeriveReferendumVote {
accountId: AccountId;
balance: Balance;
isDelegating: boolean;
vote: Vote;
}
export interface DeriveReferendumVoteState {
allAye: DeriveReferendumVote[];
allNay: DeriveReferendumVote[];
voteCount: number;
voteCountAye: number;
voteCountNay: number;
votedAye: BN;
votedNay: BN;
votedTotal: BN;
}
export interface DeriveReferendumVotes extends DeriveReferendumVoteState {
isPassing: boolean;
votes: DeriveReferendumVote[];
}
export interface DeriveReferendumExt extends DeriveReferendum, DeriveReferendumVotes {
}
+191
View File
@@ -0,0 +1,191 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Balance, BlockNumber, PreimageStatus, Proposal, ReferendumInfo, ReferendumInfoTo239, ReferendumStatus, Tally, VoteThreshold } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposalImage, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes, DeriveReferendumVoteState } from '../types';
import BN from 'bn.js';
import { Bytes, Option } from '@polkadot/types';
import { bnSqrt } from '@polkadot/util';
type PreimageInfo = [Bytes, AccountId, Balance, BlockNumber];
type OldPreimage = ITuple<PreimageInfo>;
interface ApproxState {
votedAye: BN;
votedNay: BN;
votedTotal: BN;
}
function isOldInfo (info: ReferendumInfo | ReferendumInfoTo239): info is ReferendumInfoTo239 {
return !!(info as ReferendumInfoTo239).proposalHash;
}
function isCurrentStatus (status: ReferendumStatus | ReferendumInfoTo239): status is ReferendumStatus {
return !!(status as ReferendumStatus).tally;
}
function isCurrentPreimage (api: ApiInterfaceRx, imageOpt: Option<OldPreimage> | Option<PreimageStatus>): imageOpt is Option<PreimageStatus> {
return !!imageOpt && !api.query.democracy.dispatchQueue;
}
export function compareRationals (n1: BN, d1: BN, n2: BN, d2: BN): boolean {
while (true) {
const q1 = n1.div(d1);
const q2 = n2.div(d2);
if (q1.lt(q2)) {
return true;
} else if (q2.lt(q1)) {
return false;
}
const r1 = n1.mod(d1);
const r2 = n2.mod(d2);
if (r2.isZero()) {
return false;
} else if (r1.isZero()) {
return true;
}
n1 = d2;
n2 = d1;
d1 = r2;
d2 = r1;
}
}
export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState): boolean {
const sqrtVoters = bnSqrt(votedTotal);
return sqrtVoters.isZero()
? false
: threshold.isSimplemajority
? votedAye.gt(votedNay)
: threshold.isSupermajorityapproval
? compareRationals(votedNay, sqrtVoters, votedAye, sqrtElectorate)
: compareRationals(votedNay, sqrtElectorate, votedAye, sqrtVoters);
}
function calcVotesPrev (votesFor: DeriveReferendumVote[]): DeriveReferendumVoteState {
return votesFor.reduce((state: DeriveReferendumVoteState, derived): DeriveReferendumVoteState => {
const { balance, vote } = derived;
const isDefault = vote.conviction.index === 0;
const counted = balance
.muln(isDefault ? 1 : vote.conviction.index)
.divn(isDefault ? 10 : 1);
if (vote.isAye) {
state.allAye.push(derived);
state.voteCountAye++;
state.votedAye = state.votedAye.add(counted);
} else {
state.allNay.push(derived);
state.voteCountNay++;
state.votedNay = state.votedNay.add(counted);
}
state.voteCount++;
state.votedTotal = state.votedTotal.add(counted);
return state;
}, {
allAye: [],
allNay: [],
voteCount: 0,
voteCountAye: 0,
voteCountNay: 0,
votedAye: new BN(0),
votedNay: new BN(0),
votedTotal: new BN(0)
});
}
function calcVotesCurrent (tally: Tally, votes: DeriveReferendumVote[]): DeriveReferendumVoteState {
const allAye: DeriveReferendumVote[] = [];
const allNay: DeriveReferendumVote[] = [];
votes.forEach((derived): void => {
if (derived.vote.isAye) {
allAye.push(derived);
} else {
allNay.push(derived);
}
});
return {
allAye,
allNay,
voteCount: allAye.length + allNay.length,
voteCountAye: allAye.length,
voteCountNay: allNay.length,
votedAye: tally.ayes,
votedNay: tally.nays,
votedTotal: tally.turnout
};
}
export function calcVotes (sqrtElectorate: BN, referendum: DeriveReferendum, votes: DeriveReferendumVote[]): DeriveReferendumVotes {
const state = isCurrentStatus(referendum.status)
? calcVotesCurrent(referendum.status.tally, votes)
: calcVotesPrev(votes);
return {
...state,
isPassing: calcPassing(referendum.status.threshold, sqrtElectorate, state),
votes
};
}
export function getStatus (info: Option<ReferendumInfo | ReferendumInfoTo239>): ReferendumStatus | ReferendumInfoTo239 | null {
if (info.isNone) {
return null;
}
const unwrapped = info.unwrap();
if (isOldInfo(unwrapped)) {
return unwrapped;
} else if (unwrapped.isOngoing) {
return unwrapped.asOngoing;
}
// done, we don't include it here... only currently active
return null;
}
function constructProposal (api: ApiInterfaceRx, [bytes, proposer, balance, at]: PreimageInfo): DeriveProposalImage {
let proposal: Proposal | undefined;
try {
proposal = api.registry.createType('Proposal', bytes.toU8a(true));
} catch (error) {
console.error(error);
}
return { at, balance, proposal, proposer };
}
export function parseImage (api: ApiInterfaceRx, imageOpt: Option<OldPreimage> | Option<PreimageStatus>): DeriveProposalImage | undefined {
if (imageOpt.isNone) {
return;
}
if (isCurrentPreimage(api, imageOpt)) {
const status = imageOpt.unwrap();
if (status.isMissing) {
return;
}
const { data, deposit, provider, since } = status.asAvailable;
return constructProposal(api, [data, provider, deposit, since]);
}
return constructProposal(api, imageOpt.unwrap());
}
@@ -1,23 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Vote } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
export function votes (api: ApiInterfaceRx): (referendumId: BN | number, accountIds?: AccountId[]) => Observable<Vote[]> {
return memo((referendumId: BN | number, accountIds: AccountId[] = []): Observable<Vote[]> =>
!accountIds || !accountIds.length
? of([] as Vote[])
: api.query.democracy.voteOf.multi<Vote>(
accountIds.map((accountId): [BN | number, AccountId] =>
[referendumId, accountId]
)
)
);
}
+9 -9
View File
@@ -8,16 +8,16 @@ import { ITuple } from '@polkadot/types/types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType, Vec, u32 } from '@polkadot/types';
import { Vec, u32 } from '@polkadot/types';
import { DerivedElectionsInfo } from '../types';
import { DeriveElectionsInfo } from '../types';
import { memo } from '../util';
function sortAccounts ([, balanceA]: ITuple<[AccountId, Balance]>, [, balanceB]: ITuple<[AccountId, Balance]>): number {
return balanceB.cmp(balanceA);
}
function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
function queryElections (api: ApiInterfaceRx): Observable<DeriveElectionsInfo> {
const section = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections';
return api.queryMulti<[Vec<AccountId>, Vec<AccountId>, Vec<ITuple<[AccountId, Balance]>>, Vec<ITuple<[AccountId, Balance]>>]>([
@@ -26,14 +26,14 @@ function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo>
api.query[section].members,
api.query[section].runnersUp
]).pipe(
map(([councilMembers, candidates, members, runnersUp]): DerivedElectionsInfo => ({
candidates,
candidateCount: createType(api.registry, 'u32', candidates.length),
map(([councilMembers, candidates, members, runnersUp]): DeriveElectionsInfo => ({
candidacyBond: api.consts[section].candidacyBond as Balance,
candidateCount: api.registry.createType('u32', candidates.length),
candidates,
desiredSeats: api.consts[section].desiredMembers as u32,
members: members.length
? members.sort(sortAccounts)
: councilMembers.map((accountId): [AccountId, Balance] => [accountId, createType(api.registry, 'Balance')]),
: councilMembers.map((accountId): [AccountId, Balance] => [accountId, api.registry.createType('Balance')]),
runnersUp: runnersUp.sort(sortAccounts),
termDuration: api.consts[section].termDuration as BlockNumber,
votingBond: api.consts[section].votingBond as Balance
@@ -54,6 +54,6 @@ function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo>
* });
* ```
*/
export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInfo> {
return memo((): Observable<DerivedElectionsInfo> => queryElections(api));
export function info (api: ApiInterfaceRx): () => Observable<DeriveElectionsInfo> {
return memo((): Observable<DeriveElectionsInfo> => queryElections(api));
}
@@ -3,9 +3,9 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId } from '@polkadot/types/interfaces';
import { DerivedHeartbeats } from '../types';
import { DeriveHeartbeats } from '../types';
import { of, Observable, combineLatest } from 'rxjs';
import { Observable, of, combineLatest } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Bytes, Option, u32 } from '@polkadot/types';
@@ -15,8 +15,8 @@ import { memo } from '../util';
/**
* @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session
*/
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> {
return memo((): Observable<DerivedHeartbeats> =>
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DeriveHeartbeats> {
return memo((): Observable<DeriveHeartbeats> =>
api.query.imOnline?.receivedHeartbeats
? api.derive.staking.overview().pipe(
switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option<Bytes>[], u32[]]> =>
@@ -28,8 +28,8 @@ export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<Deriv
validators.map((address) => [currentIndex, address]))
])
),
map(([validators, heartbeats, numBlocks]): DerivedHeartbeats =>
validators.reduce((result: DerivedHeartbeats, validator, index): DerivedHeartbeats => ({
map(([validators, heartbeats, numBlocks]): DeriveHeartbeats =>
validators.reduce((result: DeriveHeartbeats, validator, index): DeriveHeartbeats => ({
...result,
[validator.toString()]: {
blockCount: numBlocks[index],

Some files were not shown because too many files have changed in this diff Show More