Compare commits

..
139 Commits
Author SHA1 Message Date
Github Actions dbfc15ba88 [CI Skip] 1.4.1
skip-checks: true
2020-02-26 11:00:07 +00:00
Jaco Greeff 2d40d370f9 1.4 (#1949) 2020-02-26 11:52:37 +01:00
Github Actions 0728e40bfb [CI Skip] 1.4.0-beta.52
skip-checks: true
2020-02-26 10:32:30 +00:00
Keith Ingram 1a50298ffe Split parachains.derive calls (#1948)
* api.derive.registrar.parachains

* remove api parse

* suggestions

* some

* parachains: overview/info

* rm all

* rm all

* refine
2020-02-26 11:26:04 +01:00
Github Actions 68f2cb5bb2 [CI Skip] 1.4.0-beta.51
skip-checks: true
2020-02-26 10:23:37 +00:00
Jaco Greeff 8598002801 Swap to registry.createType (#1947) 2020-02-26 11:17:11 +01:00
Github Actions 333ff8528b [CI Skip] 1.4.0-beta.50
skip-checks: true
2020-02-25 16:08:21 +00:00
Jaco Greeff c17f93a3ec Update docs for system.account (#1944) 2020-02-25 17:01:41 +01:00
Github Actions 67841a9212 [CI Skip] 1.4.0-beta.49
skip-checks: true
2020-02-25 15:59:45 +00:00
Jaco Greeff 6be6b027cb More private field -> #field adjustments (#1945)
* More private field -> #field adjustments

* Work-around for set.add failures

* Remove FIXME, it is done
2020-02-25 16:53:04 +01:00
Github Actions 6943c9b36d [CI Skip] 1.4.0-beta.48
skip-checks: true
2020-02-25 14:17:45 +00:00
Jaco Greeff 253e48f7bb Return all additional identity fields (#1943) 2020-02-25 15:10:47 +01:00
Github Actions eeaf6118a5 [CI Skip] 1.4.0-beta.47
skip-checks: true
2020-02-25 13:22:44 +00:00
Jaco Greeff c3c77ffe43 Add Option.unwrapOrDefault (#1942)
* Add Option.unwrapOrDefault

* linting

* metadata createType(registry, ...) -> registry.createType(...)

* Linting

* Cleanup tests
2020-02-25 14:15:25 +01:00
Github Actions 71e82aece8 [CI Skip] 1.4.0-beta.46
skip-checks: true
2020-02-25 09:14:49 +00:00
Jaco Greeff a7132b4e9c Fix HEADER(...) in fromChain typegen (#1941) 2020-02-25 10:08:31 +01:00
Github Actions 8acb65931e [CI Skip] 1.4.0-beta.45
skip-checks: true
2020-02-25 08:50:07 +00:00
Jaco Greeff dcf053633b CHANGELOG & small strict adjustments (#1940) 2020-02-25 09:44:13 +01:00
Github Actions 015ade79e6 [CI Skip] 1.4.0-beta.44
skip-checks: true
2020-02-25 08:29:18 +00:00
Jaco Greeff a4f56d3d38 Remove deprecated types (up to metadata V5) (#1939) 2020-02-25 09:22:38 +01:00
Github Actions 73d10a55f1 [CI Skip] 1.4.0-beta.43
skip-checks: true
2020-02-25 07:47:12 +00:00
Jeremías Díaz 2d0ce2ddff Make Strict Mode Strict Again (#1938)
* fix: don't format "unorthodox" query input types

Also add support for tuples in `getSimilarTypes`

* fix: refactor type ignore logic into `formatType`

Had to use a regexp solution because types like `([AccountId | string | Uint8Array, Data | { none: any } | { raw: any } | { blakeTwo256: any } | { sha256: any } | { keccak256: any } | { shaThree256: any } | string | Uint8Array])[]` were not being ignored with the current logic, so they were passed to `getTypeDef` and causing delimiter errors.

* refactor: remove superfluous "FirstKeyType" param

* fix: ignore tuples with structs when formatting

* feat: eliminate all index signatures with --strict

* docs: fix doc generation
2020-02-25 08:40:07 +01:00
Github Actions 775697f51e [CI Skip] 1.4.0-beta.42
skip-checks: true
2020-02-24 21:48:03 +00:00
Jaco Greeff 9690777acb Update .123trigger 2020-02-24 22:41:22 +01:00
Jaco Greeff e7d38a5e59 Update CHANGELOG (#1936) 2020-02-24 22:34:54 +01:00
Jeremías Díaz c6355fb147 fix: don't format "unorthodox" query input types (#1934)
* fix: don't format "unorthodox" query input types

Also add support for tuples in `getSimilarTypes`

* fix: refactor type ignore logic into `formatType`

Had to use a regexp solution because types like `([AccountId | string | Uint8Array, Data | { none: any } | { raw: any } | { blakeTwo256: any } | { sha256: any } | { keccak256: any } | { shaThree256: any } | string | Uint8Array])[]` were not being ignored with the current logic, so they were passed to `getTypeDef` and causing delimiter errors.

* refactor: remove superfluous "FirstKeyType" param
2020-02-24 22:31:18 +01:00
Github Actions d85d9ca930 [CI Skip] 1.4.0-beta.41
skip-checks: true
2020-02-24 19:10:00 +00:00
Jaco Greeff af643401b8 Remove metadata index hack... and add another one (#1935)
* Remove metadata index hack

* Parse v9 and V10 upon failure
2020-02-24 20:03:35 +01:00
Github Actions fcea797c8a [CI Skip] 1.4.0-beta.40
skip-checks: true
2020-02-24 15:59:31 +00:00
Jaco Greeff cbc14cc291 Add new staking types, support derives (#1828)
* Add new staking types

* StakingLedgerTo213 - StakingLedgerTo223

* StakingLedgerTo223 in polkadot (dev)

* Add derive activeEra

* Map Ponts -> RewardPoints

* StakingLedger override CHANGELOG

* Cleanups

* Apparent CC dupes (don't see it, but cleanup useul)

* Cleanup result formatting for indexes

* Map nextElected -> validators

* Fix StakingLedger to current

* Merge CHANGELOG

* Mention derive staking updates

* Mark derive changes as breaking
2020-02-24 16:52:48 +01:00
Jaco Greeff 64aa4dcc1c More metadata clarifications (#1933) 2020-02-24 16:52:00 +01:00
Github Actions 429ea4ca99 [CI Skip] 1.4.0-beta.39
skip-checks: true
2020-02-24 14:08:24 +00:00
Jaco Greeff 86ce696808 Update CHANGELOG (#1932)
* Update CHANGELOG

* typos
2020-02-24 15:01:47 +01:00
Github Actions 57ca9a9c32 [CI Skip] 1.4.0-beta.38
skip-checks: true
2020-02-24 12:35:08 +00:00
Jaco Greeff 70a26e33a7 Docs for createType (#1931) 2020-02-24 13:28:08 +01:00
Github Actions c487094aa7 [CI Skip] 1.4.0-beta.37
skip-checks: true
2020-02-24 08:37:14 +00:00
Jaco Greeff bab79b6473 CHANGELOG 3.8 breaking change (#1930) 2020-02-24 09:30:56 +01:00
Github Actions 586e838788 [CI Skip] 1.4.0-beta.36
skip-checks: true
2020-02-23 14:02:59 +00:00
Jaco Greeff 51cb64ade7 Cleanup api.createType d.ts, add createType to registry (#1929)
* Cleanup api.createType d.ts, add createType to registry

* CHANGELOG
2020-02-23 14:57:30 +01:00
Github Actions d09dcb8282 [CI Skip] 1.4.0-beta.35
skip-checks: true
2020-02-23 12:50:23 +00:00
Jaco Greeff 869f9b7af9 InterfaceTypes -> keyof InterfaceRegistry (#1928)
* InterfaceTypes -> keyof InterfaceRegistry

* Renames
2020-02-23 13:43:37 +01:00
Github Actions a938cb545a [CI Skip] 1.4.0-beta.34
skip-checks: true
2020-02-23 11:54:54 +00:00
Jaco Greeff 553b3df0b2 Augment naming 2020-02-23 12:48:01 +01:00
Jaco Greeff 1fd157364b Use allDefs in augment-types 2020-02-23 12:42:05 +01:00
Github Actions fa7ae72c59 [CI Skip] 1.4.0-beta.33
skip-checks: true
2020-02-23 11:33:12 +00:00
Jaco Greeff 443706a6e0 Extract full interfaceRegistry (#1927)
* Extract full interfaceRegistry

* Move augment to top-level in api & types

* Type augment output

* Update with new augmented paths

* Update RPC path
2020-02-23 12:26:10 +01:00
Github Actions ba462aae8b [CI Skip] 1.4.0-beta.32
skip-checks: true
2020-02-23 10:55:21 +00:00
Jaco Greeff a35da085d6 Augment user type registry (#1926)
* Augment user type registry

* Augment InterfaceRegistry

* Addition api.createType test

* Import '@polkadot/types/interfaceAugment'

* Skip CC on generated

* Move augmentation to full path imports

* Output to augment-*
2020-02-23 11:48:40 +01:00
Github Actions 3d8d2e4988 [CI Skip] 1.4.0-beta.31
skip-checks: true
2020-02-23 09:29:30 +00:00
Jaco Greeff 6c5ef6ecd6 Generation scripts register user types (#1925)
* Generation scripts register user types

* Create augment.ts output

* Remove stray package
2020-02-23 10:22:55 +01:00
Github Actions 3bae45a331 [CI Skip] 1.4.0-beta.30
skip-checks: true
2020-02-22 16:08:46 +00:00
Jaco Greeff 196a0891b8 Use isChildClass & isBigInt from @polkadot/util (#1924)
* Use isChildClass & isBigInt from @polkadot/util

* Allow never

* Bumps

* Common 2.5.1

* Fix overrides

* Remove gh-pages script (in dev)
2020-02-22 17:02:03 +01:00
Github Actions 2a16b04420 [CI Skip] 1.4.0-beta.29
skip-checks: true
2020-02-22 14:00:27 +00:00
Jaco Greeff 790deca695 Update docs for isInBlock (rather late than never) (#1923)
* Update docs for isInBlock (rather late than never)

* Only warn on isInBlock filtering
2020-02-22 14:53:46 +01:00
Github Actions 4ec87dc51c [CI Skip] 1.4.0-beta.28
skip-checks: true
2020-02-22 13:03:37 +00:00
Jaco Greeff 51686f0cd4 Don't clobber global space in WS provider (#1922)
* Don't clbber global space in WS provider

* Re-use getWSClass
2020-02-22 13:56:37 +01:00
Github Actions deddc6dc79 [CI Skip] 1.4.0-beta.27
skip-checks: true
2020-02-22 10:37:34 +00:00
Jaco Greeff 3bf4c3fac5 Adjust class privates via #, where applicable (#1921)
* Adjust class priates via #, where applicable

* Remove stray log

* Cleanup rpc-provider

* Small adjustments

* No private access in tests

* Submittable privates

* Use derive for nonce derivation

* Tweak observers

* Alphabetical privates
2020-02-22 11:29:50 +01:00
Github Actions ccf32a6289 [CI Skip] 1.4.0-beta.26
skip-checks: true
2020-02-21 16:32:43 +00:00
Jaco Greeff 4540495a44 BigInt support (& some TS typing cleanups) (#1919)
* Some TS typing cleanups

* docs building again

* yarn.lock rewrite

* tweaks

* BigInt support

* Checktypes with BigInt

* AccountIndex support for BigInt

* Fix ApiPromise signAsync
2020-02-21 17:26:05 +01:00
Github Actions 429b797b23 [CI Skip] 1.4.0-beta.25
skip-checks: true
2020-02-21 13:20:47 +00:00
Jaco Greeff a3d5ef790c Move StorageData to interface (#1918)
* Move StorageDate to interface

* Move extrinsics interfaces

* Update interface imports
2020-02-21 14:13:23 +01:00
Github Actions b548277c05 [CI Skip] 1.4.0-beta.24
skip-checks: true
2020-02-21 12:40:24 +00:00
Jaco Greeff 2de9317b30 Cleanup CompactAssignments (alignment) (#1917)
* Cleanup CompactAssignments (alignment)

* Remove CompactAssignment

* Add CompactScore
2020-02-21 13:33:21 +01:00
Github Actions 877aa33efa [CI Skip] 1.4.0-beta.23
skip-checks: true
2020-02-21 12:24:23 +00:00
Jaco Greeff 8a9e523b84 Small type usage updates (#1916) 2020-02-21 13:17:40 +01:00
Github Actions 19743d6634 [CI Skip] 1.4.0-beta.22
skip-checks: true
2020-02-21 11:44:20 +00:00
Jaco Greeff 85ec141b56 Lazy reaping types & updates (#1914)
* Lazy reaping types & updates

* system.account queries

* AccountInfo -> ContractAccountInfo tests
2020-02-21 12:37:17 +01:00
Github Actions cb175b4bde [CI Skip] 1.4.0-beta.21
skip-checks: true
2020-02-21 11:19:43 +00:00
Jaco Greeff 8672a2e30e Move length to TypeDef (regularly used), IdentityFields to interface (#1913)
* Move length to TypeDef (regularly used), IdentityFields to interface

* Update api-contracts tests
2020-02-21 12:12:18 +01:00
Github Actions 17936f849b [CI Skip] 1.4.0-beta.20
skip-checks: true
2020-02-21 09:02:17 +00:00
Jaco Greeff 3b9f348223 Cleanup IdentityFields (re-use Set) (#1912)
* Cleanup IdentityFields

* Small cleanups

* Re-add commented IdentityFields
2020-02-21 09:55:18 +01:00
Github Actions b5ff0434d9 [CI Skip] 1.4.0-beta.19
skip-checks: true
2020-02-21 08:40:26 +00:00
Jaco Greeff 877a339353 Extrinsic toHuman aligns with .method (#1911) 2020-02-21 09:33:34 +01:00
Github Actions 716f473887 [CI Skip] 1.4.0-beta.18
skip-checks: true
2020-02-20 20:42:44 +00:00
Jaco Greeff 1c1bfb295d VecFixed now take sub, align ext with UInt (#1909)
* Allow nested definitions for fixed arrays

* Comment nested test

* Don't import U8aFixed + u8
2020-02-20 21:36:12 +01:00
Github Actions dd0a31803f [CI Skip] 1.4.0-beta.17
skip-checks: true
2020-02-20 15:35:25 +00:00
Jaco Greeff e04e5577ed Types for offchain phragmen (#1908) 2020-02-20 16:27:48 +01:00
Github Actions 09617aad2e [CI Skip] 1.4.0-beta.16
skip-checks: true
2020-02-20 12:33:42 +00:00
Jaco Greeff 3d8a57a7d5 Bump dev (#1907) 2020-02-20 13:27:22 +01:00
Github Actions feff458cbf [CI Skip] 1.4.0-beta.15
skip-checks: true
2020-02-20 12:10:28 +00:00
Jaco Greeff 543b4846f9 Fixed64 to an interface (#1906)
* Fixed64 to an interface

* Cleanups, re-use creation

* Fix Int export from codec

* Fix Int export
2020-02-20 13:03:29 +01:00
Github Actions 09ab373b54 [CI Skip] 1.4.0-beta.14
skip-checks: true
2020-02-20 11:58:08 +00:00
Jaco Greeff bec6dba14a Move primitive/Extrinsic -> extrinsic (#1905)
* Move primitive/Extrinsic -> extrinsic

* mv primitive/Generic -> generic

* Update registry with BitVec

* ove BitVec back to primitive

* Remove unused import

* Rebuild interfaces
2020-02-20 12:51:06 +01:00
Github Actions e80bea6680 [CI Skip] 1.4.0-beta.13
skip-checks: true
2020-02-20 09:20:54 +00:00
Jaco Greeff 9119e791d1 Add V4 extrinsic test (#1904)
* Add V4 extinsic test

* Update test with toHuman

* Remove unused import
2020-02-20 10:14:21 +01:00
Github Actions 46b99ae83d [CI Skip] 1.4.0-beta.12
skip-checks: true
2020-02-20 07:28:44 +00:00
Jaco Greeff 92129746dc Move inter-package deps to fixed (as per release) (#1903) 2020-02-20 08:21:17 +01:00
Github Actions 4a8a36d284 [CI Skip] 1.4.0-beta.11
skip-checks: true
2020-02-20 07:07:16 +00:00
Jaco Greeff 2b8ce1b3b7 Check AbstractInt bitLength on construction (#1902)
* Check AbstractInt bitLength on construction

* Language cleanups
2020-02-20 08:00:41 +01:00
Github Actions 0e1e0c0d37 [CI Skip] 1.4.0-beta.10
skip-checks: true
2020-02-19 19:05:23 +00:00
Jaco Greeff 427f821430 Fix 11 Jan 2019 issue (#1900)
* Fix 11 Jan 2019 issue

* Update SignedBlock tests
2020-02-19 19:57:59 +01:00
Github Actions 07307f8374 [CI Skip] 1.4.0-beta.9
skip-checks: true
2020-02-19 14:52:02 +00:00
Jaco Greeff cc5b5c81c9 Subscribe to runtime updates (#1896)
* Subscribe to runtime updates

* console.log -> l.log

* Add l.warn to api augment

* Expand logs with added & removed

* Re-do everything when genesis has changed

* augmentObject complexity

* Dedup [string[], strings[]]

* Update CHANGELOG
2020-02-19 15:45:03 +01:00
Jakub Pánik efbc017940 All heads subscription (#1899)
* [CI Skip]  1.4.0-beta.8

skip-checks: true

* Added support for all heads subscription
2020-02-19 15:30:24 +01:00
Github Actions 849972f7b0 [CI Skip] 1.4.0-beta.8
skip-checks: true
2020-02-19 05:54:02 +00:00
Axel Chalon 01758229eb Add manual seal RPCs (#1894)
* Add manual seal RPCs

* yarn build:interfaces
2020-02-19 06:48:00 +01:00
Github Actions add9b59402 [CI Skip] 1.4.0-beta.7
skip-checks: true
2020-02-18 20:36:58 +00:00
Jaco Greeff c8af75088a Add injectMetadata to api (with decoration) (#1892)
* Add injectMetadata to api (with decoration)

* warn function

* OCD

* OCD #2

* toHuman entry expansion

* CHANGELOG for injectMetadata
2020-02-18 21:30:43 +01:00
Github Actions d4b45921fd [CI Skip] 1.4.0-beta.6
skip-checks: true
2020-02-18 20:14:31 +00:00
Jaco Greeff 30f5baa906 ExtrinsicEra & Vote toHuman (#1893) 2020-02-18 21:08:18 +01:00
Github Actions 7150bdcbea [CI Skip] 1.4.0-beta.5
skip-checks: true
2020-02-18 15:46:08 +00:00
Jaco Greeff d041c0abb2 Support arbitrary UInt<bitLength> definitions (#1891)
* Support arbitrar UInt

* CHANGELOG

* Fix generation

* Move UInt
2020-02-18 16:39:18 +01:00
Github Actions 524e694b90 [CI Skip] 1.4.0-beta.4
skip-checks: true
2020-02-18 15:04:32 +00:00
Jaco Greeff bdd1e4c917 Move H160, H256 & H512 to interfaces (#1890)
* Move H160, H256 & H512 to interfaces

* Test for Hash -> H256

* Replace IHash & Codec.hash with H256

* [u8; n] extends U8aFixed

* Update formatting.ts
2020-02-18 15:56:50 +01:00
Github Actions 7233d7c754 [CI Skip] 1.4.0-beta.3
skip-checks: true
2020-02-18 14:00:33 +00:00
Jaco Greeff aee09c48b9 Use static with for derived H*, U* & I* primitives (#1889)
* Usestatic with for derived H*, U* & I* primitives

* Add with override tests

* Fix linting
2020-02-18 14:53:43 +01:00
Github Actions 7edbc58129 [CI Skip] 1.4.0-beta.2
skip-checks: true
2020-02-18 12:41:52 +00:00
Jaco Greeff ad2939cc4f Rework Unconstructable type (#1888)
* Rework Unconstructable type

* hasType updates

* Unknown -> Unconstructable (as it was)

* Remove commented test

* class name

* getOrThrow tests

* typo.

* getOrUnknown
2020-02-18 13:35:42 +01:00
Github Actions e984c74ca6 [CI Skip] 1.4.0-beta.1
skip-checks: true
2020-02-18 12:26:54 +00:00
Jaco Greeff a5c8e3c4e1 Convert DigestItem to definition (#1886)
* Convert DigestItem to definition

* Remove GenericDigestItem export

* Update CHANGELOG.md
2020-02-18 13:20:29 +01:00
Github Actions 1e5191d695 [CI Skip] 1.4.0-beta.0
skip-checks: true
2020-02-18 09:12:00 +00:00
Jaco Greeff b46093e5d3 Add .toHuman on SubmittableResult (#1885) 2020-02-18 10:05:48 +01:00
Github Actions 64f0d7b2a6 [CI Skip] 1.3.1
skip-checks: true
2020-02-18 08:40:23 +00:00
Jaco Greeff 4a1e504ca2 1.3 (#1883)
* 1.3

* Pair create update

* CHANGELOG update
2020-02-18 09:34:35 +01:00
Github Actions ebf3f4491e [CI Skip] 1.3.0-beta.11
skip-checks: true
2020-02-17 14:23:11 +00:00
Jaco Greeff 849f519efe Add GH actions yarn cache (#1881) 2020-02-17 15:16:09 +01:00
Github Actions accc2b4f7d [CI Skip] 1.3.0-beta.10
skip-checks: true
2020-02-17 13:15:05 +00:00
Jaco Greeff 01abc030f9 Cleanup stray accountNonce reference (#1880)
* Cleanup stray accountNonce reference

* Comment for system.account upgrades
2020-02-17 14:08:13 +01:00
Github Actions e041946de5 [CI Skip] 1.3.0-beta.9
skip-checks: true
2020-02-17 11:50:02 +00:00
Jaco Greeff 502e54ce5c Bump common (#1879)
* Bump common

* Add documentation to extended call

* TODO for toHuman event

* CHANGELOG
2020-02-17 12:43:03 +01:00
Github Actions 12986f0cda [CI Skip] 1.3.0-beta.8
skip-checks: true
2020-02-17 10:50:00 +00:00
Jaco Greeff 83d780220c Add toHuman with base formatting (#1878)
* Add toHuman with base formatting

* Balance formatting

* Externalize Enum decode
2020-02-17 11:43:08 +01:00
Github Actions ec7848ae92 [CI Skip] 1.3.0-beta.7
skip-checks: true
2020-02-17 07:53:42 +00:00
Jaco Greeff 2b5be7eaab Remove unexported staking.infostash derive (duplicated as .query) (#1877) 2020-02-17 08:46:59 +01:00
Github Actions 21f4e3107a [CI Skip] 1.3.0-beta.6
skip-checks: true
2020-02-17 07:16:52 +00:00
Jaco Greeff 8a152ea4c0 Split generation scripts into @polkadot/typegen (#1875)
* Split generation scripts into @polkadot/typegen

* Remove moved files

* CC overrides

* interfaces typo

* Cleanup imports

* Some import combinations

* Updates

* Generation updates

* Cleanups, split js wrapper & ts logic

* Rename jiggle 1

* Rename jiggle 2

* Style cleanups

* Expose enry function for scripts

* Typo

* Update script copy & include locations

* CC exclude location

* Minor adjustments

* argv parsing into main
2020-02-17 08:09:59 +01:00
Github Actions fd7b38e781 [CI Skip] 1.3.0-beta.5
skip-checks: true
2020-02-17 06:16:35 +00:00
Jeremías Díaz 5df22835f6 fix: make bn.js into a regular dependency (#1876)
Since `AbstractInt` is exposing `toBn(): BN` which uses `bn.js` types,
projects using polkadot are forced to install `@types/bn.js` on their own,
otherwise they get compilation errors
2020-02-17 07:09:30 +01:00
Github Actions 6a828eb11a [CI Skip] 1.3.0-beta.4
skip-checks: true
2020-02-16 16:48:32 +00:00
Jaco Greeff ad2b1abdc9 Move @polakdot/jsonrpc -> packages/jsonrpc (#1874)
* Move @polakdot/jsonrpc -> packages/jsonrpc

* Update links
2020-02-16 17:41:45 +01:00
Github Actions d3dc2cb00a [CI Skip] 1.3.0-beta.3
skip-checks: true
2020-02-16 12:58:16 +00:00
Jaco Greeff 921e55a82e Move types/codec/create -> types/create (#1871)
* Move types/codec/create -> types/create

* Update imports after move

* Cleanups

* Cleanup code circular deps

* Re-add dropped interfaces

* Drop duplicated code

* Fix imports

* Remove whacky comment
2020-02-16 13:51:37 +01:00
Github Actions fde076152a [CI Skip] 1.3.0-beta.2
skip-checks: true
2020-02-16 12:20:24 +00:00
Jaco Greeff 6e535b0502 Don't make types depend on api (dev deps) (#1869)
* Don't make types depend on api (dev deps)

* Naming cleanups

* Remove skipped tests

* Splt types/types into chunks

* Re-add setChainProperties (properties?: ChainProperties): void;
2020-02-16 13:13:56 +01:00
Github Actions 1ddad84d7e [CI Skip] 1.3.0-beta.1
skip-checks: true
2020-02-16 10:16:34 +00:00
Jaco Greeff 1e975c68ee Make chain properties available on registry (#1868)
* Make chain properties available on registry

* Use registry chainSS58 to format address

* CHANGELOG

* CHANGELOG typo

* Fix tests vis setChainProperties

* Cleanup tests via chain property set

* Remove global ss58 format set
2020-02-16 11:09:48 +01:00
Github Actions 5c962cf093 [CI Skip] 1.3.0-beta.0
skip-checks: true
2020-02-16 09:27:50 +00:00
Jaco Greeff 07f55af202 Documentation of ready rejections (#1870) 2020-02-16 10:21:19 +01:00
424 changed files with 7535 additions and 6506 deletions
+1 -1
View File
@@ -1 +1 @@
18
19
+4 -2
View File
@@ -4,6 +4,8 @@ exclude_patterns:
- "**/*.test.js"
- "**/*.test.ts"
- "docs/**/*.js"
- "packages/api/src/types/augment/"
- "packages/api/src/augment/"
- "packages/typegen/scripts"
- "packages/typegen/src"
- "packages/types/src/interfaces/"
- "packages/types/src/scripts/"
- "packages/types/src/augment/"
+40
View File
@@ -14,6 +14,16 @@ jobs:
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 --frozen-lockfile
@@ -31,6 +41,16 @@ jobs:
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
run: |
yarn install --frozen-lockfile
@@ -48,6 +68,16 @@ jobs:
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 --frozen-lockfile
@@ -65,6 +95,16 @@ jobs:
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 --frozen-lockfile
+20
View File
@@ -20,6 +20,16 @@ jobs:
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:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
@@ -44,6 +54,16 @@ jobs:
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 }}
+43 -9
View File
@@ -1,17 +1,51 @@
# 1.4.1 Feb 26, 2020
- **Breaking change** (TypeScript only) The `*.d.ts` files now contain TypeScript 3.8 features (specifically `#private`), which is not usable in TS versions < 3.8
- **Breaking change** - `api.derive.staking.*` has updated result types and detects support for lazy payouts queries
- Rework type generation for `api.{query, tx}` to properly handle complex type inputs (Thanks to https://github.com/monitz87)
- Rework metadata `--strict` mode to effectively decorate chain metadata (Thanks to https://github.com/monitz87)
- Add `api.rpc.chain.subscribeAllHeads` (not just best) (Thanks to https://github.com/jak-pan)
- Add `api.rpc.engine.*` for manual seal support
- Add `api.injectMetadata(metadata)` to initialize API with a specific metadata version
- The api now checks for runtime upgrades, augmenting the interfaces with new metadata when found
- Support types & interfaces required for lazy reaping, lazy payouts & offchain phragmen
- `Option` types now has an `.unwrapOrDefault` as an complement to `.unwrap` & `.unwrapOr`
- Support JS `BigInt` inputs in any derived `UInt` and `Int` object, e.g. `api.tx.balances.transfer(..., 9876543210123456789n)`
- `UInt` & `Int` now does source bitLength checks upon construction
- Registry now exposes `.createType(<type>, ...args)` as an additional helper (like the API)
- Expand `.toHuman` on `ExtrinsicEra`, `SubmittableResult` & `Vote`
- Move `DigestItem`, `Fixed64`, `H160`, `H256` & `H512` to interfaces in `@polkadot/types/interfaces`
- Align construction of unknown types in `registry.get` consistently warn on detection, throw on use
- Support for arbitrary UInt types via `UInt<bitLength>` type definitions
- Expose static `.with` on `UInt`, `Int` & `U8aFixed` classes with optional type name override
- Remove [11 Jan 2019](https://github.com/polkadot-js/api/issues/574) extrinsic length hack
- Use ES `#field` on private class fields as applicable
- Move `types/primitive/{extrinsics, generic}` to `types/{extrinsics, generic}`
- Cleanup augmentation and generation scripts for type definitions, aligning with api augmentation
- Bump to `@polkadot/{util, util-crypto, keyring}` 2.5.1
# 1.3.1 Feb 18, 2020
- Add `@types/bn.js` as a normal dependency, exposed in `*.d.ts` (Thanks to https://github.com/monitz87)
- Type generation scripts (including `polkadot-types-from-{chain,defs}`) has been moved to the `@polkadot/typegen` package
- The `@polkadot/types/codec/create` has been moved to `@polkadot/types/create`, imports from `@polkadot/types` are unaffected
- Expose chain properties on registry (and use for API type formatting)
- Add `toHuman(isExtended?: boolean)` to all codec types, formatting into a human-readable structure
# 1.2.1 Feb 16, 2020
- **Important** Update RPC status codes (latest Substrate 2), with the `isInBlock` (`isFinalized` now indicates finality)
- Storage `.entries(arg?: any)` now has the correct argument type for DoubleMap (Thanks to https://github.com/monitz87)
- Swap Kusama and Polkadot aliasses for `Address` to `AccountId` (future update)
- Add `LookupSource` and `LookupTarget` types instead of mapping these directly for aliassing
- Swap Kusama and Polkadot aliases for `Address` to `AccountId` (future update)
- Add `LookupSource` and `LookupTarget` types instead of mapping these directly for aliasing
- Add `BitVec` type primitive
- Add support for `system.account` for balance & nonce queries in derives as well as Submittables (Substrate composites)
- Add `rpc.author.hasKey` and `rpc.author.hasSessinKeys` RPCs
- Add `rpc.author.hasKey` and `rpc.author.hasSessionKeys` RPCs
- Add derives for the parachains interfaces
- Applied the latest types for Polkadot parachains
- `registry.findMetaError` now can take in a `DispatchErrorModule` object for error lookups (from `asModule` in `DispatchError`)
- Metadata now correctly serializes to the original input data via `toHex()` & `toU8a()`
- Metadata dcocumentation generation rework, including the output of errors from metadata
- Metadata documentation generation rework, including the output of errors from metadata
- Update all examples and comments to use latest `system.account` queries (instead of `system.accountNonce` and `balances.freeBalance`/`balances.reservedBalance`)
- Cleanup `codec/Date` tests to make it run properly on all timezones
- Add explicit dependencies to all packages and move TypeScript `@types/*` to dev deps
@@ -51,7 +85,7 @@
# 0.100.1 Jan 13, 2020
- **Important** This will the the last API version with Substrate 1.x support. Although you will still be able to use subsequent versions with older chans, dependent libraries such as sr25519 may not be compatible.
- **Important** This will the the last API version with Substrate 1.x support. Although you will still be able to use subsequent versions with older chains, dependent libraries such as sr25519 may not be compatible.
- Add support for the Substrate identity module
- Remove the `codec/Data` type, to remove a conflict with Substrate. This type is now named `Raw`
- Fix for linked maps using `Option`
@@ -65,7 +99,7 @@
- **Breaking change** The `Data` and `U8a` type has been renamed and just replaced with the `Raw` type
- **Breaking change** The `api.derive.staking.info` has been split into 2 - `staking.query` for non-balance related information (more effective) and `staking.account` that enhances query for all the information previously found `.info`
- Cleanup `DoubleMap` hashing to always hash over the full value (in the case of `Vec<T>`, this includes the length)
- Update democracy derives to take care of nextTally and lowestU*nbaked
- Update democracy derives to take care of nextTally and lowestUnbaked
- Add additional derives for both council & treasury
- Alignment with latest Polkadot/Substrate master branch types
@@ -120,7 +154,7 @@
- Adjust API cloning now takes RPC filters from source into account
- Simplification of isPedantic checks and less overhead on StorageData types
- Cleanups and fixes around RPC and derive type definitions
- Fix `derive.imOnline.receivedHeatbeats` to query via indexes
- Fix `derive.imOnline.receivedHeartbeats` to query via indexes
- Adjustment of `api.derive.elections.{approvalsOf|approvalsOfAt}` to allow ss58 address input
- Cleanup `Enum` `.eq` handling to be more exhaustive
- Add documentation for custom extrinsic formats (advanced chains)
@@ -154,7 +188,7 @@
- Redeemed balance calculation if `api.derive` now returns the correct values again (bug fix)
- added the `yarn chain:info [--ws URL]` utility to extract a calls-only metadata version
- Missing types are now logged via a `console.warn`, not via `.error`
- `Extrinsic`, `ExtrinsicPayload` & `SignerPayload` is registered in the type registry and can be overriden now
- `Extrinsic`, `ExtrinsicPayload` & `SignerPayload` is registered in the type registry and can be overridden now
- **Breaking change** `SignerPayload` is renamed to `SignerPayloadJSON`
- **Breaking change** `SignerPayloadJSON`, `SignerPayloadRawBase` and `SignerPayloadRaw` are all moved to `@polkadot/types`
@@ -180,7 +214,7 @@ If you are upgrading form an older version, use the CHANGELOG hand-in-hand with
- Support for substrate 2.x (master) has been extended,
- Additional types have been addedd for the modules
- `api.derive.contract` is now `api.derive.contracts` to align with the substrate 2.x rename. (Feture detection is used so it supports both 1.x and 2.x chains)
- `api.derive.contract` is now `api.derive.contracts` to align with the substrate 2.x rename. (Feature detection is used so it supports both 1.x and 2.x chains)
- Addition of `api.derive.elections`
- Support latest substrate 2 v6 metadata with module constants using `api.consts`.
+1 -1
View File
@@ -27,7 +27,7 @@ The API is split up into a number of internal packages -
Type definitions for interfaces as exposed by Polkadot & Substrate clients -
- [@polkadot/jsonrpc](packages/type-jsonrpc/) Definitions for JSONRPC endpoints
- [@polkadot/jsonrpc](packages/jsonrpc/) Definitions for JSONRPC endpoints
- [@polkadot/types](packages/types/) Codecs for all Polkadot and Substrate primitives
## development
+1 -3
View File
@@ -1,3 +1 @@
module.exports = {
extends: '@polkadot/dev/config/babel'
};
module.exports = require('@polkadot/dev/config/babel');
+10 -9
View File
@@ -2,7 +2,7 @@
function copy_folder () {
SRC="packages/$1/build"
DST="../apps/node_modules/@polkadot/$2"
DST="../apps/node_modules/@polkadot/$1"
echo "** Copying $SRC to $DST"
@@ -12,11 +12,12 @@ function copy_folder () {
yarn polkadot-dev-build-ts
copy_folder "api" "api"
copy_folder "api-contract" "api-contract"
copy_folder "api-derive" "api-derive"
copy_folder "metadata" "metadata"
copy_folder "rpc-core" "rpc-core"
copy_folder "rpc-provider" "rpc-provider"
copy_folder "type-jsonrpc" "jsonrpc"
copy_folder "types" "types"
copy_folder "api"
copy_folder "api-contract"
copy_folder "api-derive"
copy_folder "metadata"
copy_folder "rpc-core"
copy_folder "rpc-provider"
copy_folder "jsonrpc"
copy_folder "types"
copy_folder "typegen"
+1
View File
@@ -43,6 +43,7 @@ module.exports = {
['start/api.tx.wrap.md', 'Complex transactions'],
['start/types.basics.md', 'Type basics'],
['start/types.extend.md', 'Extending types'],
['start/types.create.md', 'Creating types'],
['start/extrinsic.extend.md', 'Extending extrinsics'],
['start/typescript.md', 'TypeScript interfaces'],
['start/typescript.user.md', 'TypeScript user generated'],
@@ -13,13 +13,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 [previousNonce, { free: previousFree }] = await api.query.system.account(Alice);
let { nonce: previousNonce, data: { free: previousFree } } = 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, ([currentNonce, { free: currentFree }]) => {
api.query.system.account(Alice, ({ nonce: currentNonce, data: { free: currentFree } }) => {
// Calculate the delta
const change = currentFree.sub(previousFree);
@@ -16,7 +16,7 @@ async function main () {
// Subscribe and listen to several balance changes
api.query.system.account.multi([ALICE, BOB], (balances) => {
console.log('Change detected, new balances: ', balances.map(([, { free }]) => free));
console.log('Change detected, new balances: ', balances.map(({ data: { free } }) => free));
});
}
@@ -12,7 +12,7 @@ async function main () {
const api = await ApiPromise.create();
// Make our basic chain state/storage queries, all in one go
const [[accountNonce], now, validators] = await Promise.all([
const [{ nonce: accountNonce }, now, validators] = await Promise.all([
api.query.system.account(ALICE),
api.query.timestamp.now(),
api.query.session.validators()
@@ -32,8 +32,8 @@ async function main () {
// Print out the authorityIds and balances of all validators
console.log('validators', validators.map((authorityId, index) => ({
address: authorityId.toString(),
balance: validatorBalances[index][1].free.toString(),
nonce: validatorBalances[index][0].toString()
balance: validatorBalances[index].data.free.toHuman(),
nonce: validatorBalances[index].nonce.toHuman()
})));
}
}
@@ -21,12 +21,12 @@ async function main () {
// the format is always `.at(<blockhash>, ...params)`
const balance = await api.query.system.account.at(parentHash, ALICE);
console.log(`Alice's balance at ${parentHash.toHex()} was ${balance[1].free}`);
console.log(`Alice's balance at ${parentHash.toHex()} was ${balance.data.free}`);
// Now perform a multi query, returning multiple balances at once
const balances = await api.query.system.account.multi([ALICE, BOB]);
console.log(`Current balances for Alice and Bob are ${balances[0][1].free} and ${balances[1][1].free}`);
console.log(`Current balances for Alice and Bob are ${balances[0].data.free} and ${balances[1].data.free}`);
}
main().catch(console.error).finally(() => process.exit());
@@ -19,7 +19,7 @@ async function main () {
const alice = keyring.addFromUri('//Alice');
// Get nonce for account
const [nonce] = await api.query.system.account(alice.address);
const { nonce } = await api.query.system.account(alice.address);
// Get current block
const signedBlock = await api.rpc.chain.getBlock();
@@ -24,7 +24,7 @@ async function main () {
const keyring = testKeyring.default();
// Get the nonce for the admin key
const [nonce] = await api.query.system.account(ALICE);
const { nonce } = await api.query.system.account(ALICE);
// Find the actual keypair in the keyring
const alicePair = keyring.getPair(ALICE);
@@ -40,13 +40,15 @@ async function main () {
.signAndSend(alicePair, { nonce }, ({ events = [], status }) => {
console.log('Transaction status:', status.type);
if (status.isFinalized) {
console.log('Completed at block hash', status.asFinalized.toHex());
if (status.isInBlock) {
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
} else if (status.isFinalized) {
console.log('Finalized block hash', status.asFinalized.toHex());
process.exit(0);
}
@@ -39,15 +39,15 @@ async function main () {
.signAndSend(adminPair, ({ events = [], status }) => {
console.log('Proposal status:', status.type);
if (status.isFinalized) {
if (status.isInBlock) {
console.error('You have just upgraded your chain');
console.log('Completed at block hash', status.asFinalized.toHex());
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
console.log(JSON.stringify(events.toHuman(), null, 2));
} else if (status.isFinalized) {
console.log('Finalized block hash', status.asFinalized.toHex());
process.exit(0);
}
@@ -25,12 +25,12 @@ async function main () {
if (balance[0] === 'first') {
// Now we know that if the previous value emitted as balance[0] is `first`,
// then balance[1] is the initial value of Alice account.
console.log(`Alice ${Alice} has a balance of ${balance[1][1].free}`);
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;
}
const change = balance[1][1].free.sub(balance[0][1].free);
const change = balance[1].data.free.sub(balance[0].date.free);
// Only display value changes
if (!change.isZero()) {
+4 -4
View File
@@ -36,16 +36,16 @@ function main () {
})
)
// Then we're subscribing to the emitted results
.subscribe(([[accountNonce], blockPeriod, validators, validatorBalances]) => {
console.log(`accountNonce(${Alice}) ${accountNonce}`);
.subscribe(([{ nonce }, blockPeriod, validators, validatorBalances]) => {
console.log(`accountNonce(${Alice}) ${nonce}`);
console.log(`blockPeriod ${blockPeriod.toNumber()} seconds`);
if (validatorBalances) {
// And lastly we print out the authorityIds and balances of all validators
console.log('validators', validators.map((authorityId, index) => ({
address: authorityId.toString(),
balance: validatorBalances[index][1].free.toString(),
nonce: validatorBalances[index][0].toString()
balance: validatorBalances[index].data.free.toString(),
nonce: validatorBalances[index].data.toString()
})));
}
});
+7 -2
View File
@@ -25,9 +25,14 @@ async function main () {
.signAndSend(alice)
// Subscribe to the status updates of the transfer
.subscribe(({ status }) => {
if (status.isFinalized) {
console.log(`Successful transfer of 12345 from Alice to Bob with hash ${status.asFinalized.toHex()}`);
if (status.isInBlock) {
console.log(`Successful transfer of 12345 from Alice to Bob at block ${status.asInBlock.toHex()}`);
} else if (status.isFinalized) {
console.log('Finalized block hash', status.asFinalized.toHex());
subscription.unsubscribe();
process.exit(0);
} else {
console.log(`Status of transfer: ${status.type}`);
}
+6 -2
View File
@@ -44,13 +44,17 @@ async function main () {
console.log('Transfer status:', status.type);
// Log system events once the transfer is finalised
if (status.isFinalized) {
console.log('Completed at block hash', status.asFinalized.toHex());
if (status.isInBlock) {
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
} else if (status.isFinalized) {
console.log('Finalized block hash', status.asFinalized.toHex());
process.exit(0);
}
});
}
+5 -5
View File
@@ -40,16 +40,16 @@ async function main () {
// Log transfer events
console.log('Proposal status:', status.type);
if (status.isFinalized) {
if (status.isInBlock) {
console.error('You have just upgraded your chain');
console.log('Completed at block hash', status.asFinalized.toHex());
console.log('Included at block hash', status.asInBlock.toHex());
console.log('Events:');
// Log system events once the chain update is finalised
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
console.log(JSON.stringify(events.toHuman(), null, 2));
} else if (status.isFinalized) {
console.log('Finalized block hash', status.asFinalized.toHex());
process.exit(0);
}
+3 -1
View File
@@ -36,6 +36,8 @@ The length for this transaction validity is set to 50 blocks, which translates t
## My chain does not support system.account queries
The API always tracks the latest Substrate master in terms of examples. This means that nonce & balance queries are done via the `api.query.system.account(<account>)` which returns a Tuple `(Index, AccountData)` where the first is the nonce, the second a struct containing the free and reserved balances. As with all `api.query.*` endpoint, this is decorated based on what the chain you connect to support.
The API always tracks the latest Substrate master in terms of examples. This means that nonce & balance queries are done via the `api.query.system.account(<account>)` which returns a struct `{ nonce: Index, data: AccountData }` where the `data` is struct containing the free and reserved balances. As with all `api.query.*` endpoints, this is decorated based on what the chain you connect to support, via the metadata exchange.
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.
+2 -2
View File
@@ -17,7 +17,7 @@ const ADDR = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE';
const now = await api.query.timestamp.now();
// Retrieve the account balance & nonce via the system module
const [nonce, balance] = await api.query.system.account(ADDR);
const { nonce, data: balance } = await api.query.system.account(ADDR);
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
```
@@ -27,7 +27,7 @@ There have been some additions in the code above comparing with retrieving runti
```js
...
// Retrieve last block timestamp, account nonce & balances
const [now, [nonce, balances]] = await Promise.all([
const [now, { nonce, data: balances }] = await Promise.all([
api.query.timestamp.now(),
api.query.system.account(ADDR)
]);
+2 -2
View File
@@ -11,7 +11,7 @@ Where possible, the use of multi queries are encouraged since it tracks a number
// Subscribe to balance changes for 2 accounts, ADDR1 & ADDR2 (already defined)
const unsub = await api.query.system.account.multi([ADDR1, ADDR2], (balances) => {
const [[, balance1], [, balance2]] = balances;
const [{ data: balance1 }, { data: balance2 }] = balances;
console.log(`The balances are ${balance1.free} and ${balance2.free}`);
});
@@ -44,7 +44,7 @@ The previous `.multi` examples assumes that we do queries for the same types, i.
const unsub = await api.queryMulti([
api.query.timestamp.now,
[api.query.system.account, ADDR]
], ([now, [nonce, balance]]) => {
], ([now, { nonce, data: balance }]) => {
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
});
```
+1 -1
View File
@@ -13,7 +13,7 @@ Quite often is is useful (taking pruning into account, more on this later) to re
const lastHdr = await api.rpc.chain.getHeader();
// Retrieve the balance at both the current and the parent hashes
const [[, balanceNow], [, balancePrev]] = await Promise.all([
const [{ data: balanceNow }, { data: balancePrev }] = await Promise.all([
api.query.system.account.at(lastHdr.hash, ADDR),
api.query.system.account.at(lastHdr.parentHash, ADDR)
]);
+1 -1
View File
@@ -25,7 +25,7 @@ If we had a query with parameters, i.e. where we wish to perform a query for a s
...
// Subscribe to balance changes for our account
const unsub = await api.query.system.account(ADDR, ([nonce, balance]) => {
const unsub = await api.query.system.account(ADDR, ({ nonce, data: balance }) => {
console.log(`free balance is ${balance.freee} with ${balance.reserved} reserved and a nonce of ${nonce}`);
});
```
+1 -1
View File
@@ -28,7 +28,7 @@ The result for this call (we will deal with subscriptions in a short while), is
Despite the single-line format of `signAndSend`, there is a lot happening under the hood (and all of this can be manually provided) -
- Based on the sender, the API will retrieve the `system.accountNonce` to determine the next nonce to use
- Based on the sender, the API will query `system.account` (or `system.accountNonce` on older chains) to determine the next nonce to use
- The API will retrieve the current block hash and use it to create a mortal transaction, i.e. the transaction will only be valid for a limited number of blocks (by default this is 5 mins at 6s block times)
- It will construct a payload and sign this, this includes the `genesisHash`, the `blockHash` for the start of the mortal era as well as the current chain `specVersion`
- The transaction is submitted to the node
+5 -3
View File
@@ -18,8 +18,10 @@ const unsub = await api.tx.balances
.signAndSend(alice, (result) => {
console.log(`Current status is ${result.status}`);
if (result.status.isFinalized) {
console.log(`Transaction included at blockHash ${result.status.asFinalized}`);
if (result.status.isInBlock) {
console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
} else if (result.status.isFinalized) {
console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
unsub();
}
});
@@ -27,7 +29,7 @@ const unsub = await api.tx.balances
As per all previous subscriptions, the transaction subscription returns in `unsub()` and the actual method has a subscription callback. The `result` object has 2 parts, `events` (to to covered in the next section) and the `status` enum.
When the `status` enum is in `Finalized` state (checked via `isFinalized`), the underlying value contains the block hash of the block where the transaction has been included. This does not mean the block is finalized, but rather applies to the transaction state, as no further updates will be received for this subscription.
When the `status` enum is in `Finalized` state (checked via `isFinalized`), the underlying value contains the block hash of the block where the transaction has been finalized. `Finalized` will follow `InBlock`, which is the block where the transaction has been included. `InBlock` does not mean the block is finalized, but rather applies to the transaction state, where `Finalized` means that the transaction cannot be forked off the chain.
## Transaction events
+3 -1
View File
@@ -6,7 +6,7 @@ To unpack this, we will start with the Metadata and explain what it actually pro
## Metadata
When the API connects to a node, one of the first things it does is to retrieve the metadata. The metadata, effectively provides data in the form of `api.<type>.<module>.<section>` that fits into one of the following categories -
When the API connects to a node, one of the first things it does is to retrieve the metadata and decorate the API based on the metadata information. The metadata effectively provides data in the form of `api.<type>.<module>.<section>` that fits into one of the following categories -
- [consts](../substrate/constants.md) - All runtime constants, e.g. `api.consts.balances.existentialDeposit`. These are not functions, rather accessing the endpoint immediately yields the result as defined.
- [query](../substrate/storage.md) - All chain state, e.g. `api.query.system.account(<accountId>)`.
@@ -14,6 +14,8 @@ When the API connects to a node, one of the first things it does is to retrieve
Additionally the metadata also provides information on [events](../substrate/events.md), these are query-able via the `api.query.system.events()` interface and also appear on transactions... both these cases are detailed later.
None of the information contained within the `api.{consts, query, tx}.<module>.<method>` endpoints are hard coded in the API. Rather everything is fully decorated by what the metadata exposes and is therefore completely dynamic. This means that when you connect to different chains, the metadata and API decoration will change and the API interfaces will reflect what is available on the chain you are connected to.
## Types
The metadata defines the calls with all the type names used in the various interfaces. At the moment (this is undergoing investigations and could improve in future versions of metadata), this also means that the types between the API and the node need to be aligned. For instance, by default Substrate defines a `BlockNumber` type as a `u32` and the API follows the Substrate defaults - if a chain has a different definitions, the API needs to be aware of this so it can actually decode (and encode) the type.
+6
View File
@@ -68,6 +68,12 @@ await api.isReady;
console.log(api.genesisHash.toHex());
```
## Failures
In all cases the API will handle reconnections automatically. This means that when you connect and the endpoint is not (yet) ready, the promise will not resolve immediately, but rather when connected. The same applies to when connection is lost, the API will manage re-connections.
In cases where the API does not support the chain being connected to, such as it using an unknown metadata version, the ready promise will fail to resolve and instead reject.
## Advanced creation
There are more advanced cases where you would prefer to use the longer version, for instance: if you want to explicitly listen to events emitted, you probably want to attach to the API even before connecting to the chain. All API instances implement an `EventEmitter` interface, with `on` handlers, which emit `connected`, `disconnected`, `ready` and `error` events, allowing you to listen to events on the transport layer.
+3 -1
View File
@@ -27,7 +27,7 @@ For example:
```js
const { metadata } = await api.rpc.state.getMetadata();
const modules = metadata.asV3.modules;
const modules = metadata.asLatest.modules;
// This will not work, because `name` is an instance of `Text`, not a string
// const system = modules.find(m => m.name === 'system');
@@ -79,6 +79,8 @@ const [count, accountId] = tuple;
console.log(`${accountId} has ${count.toNumber()} values`);
```
When making a call that expect a `Tuple` input, pass it as an array, so to pass the example above into a call, it would be `.call([123, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'])`
## Extending types
For customized chains, the need exists to register types so the API is aware of how to decode values for those types. The next section will provide a [walk-through for the definition of custom types](types.extend.md) allowing the definition or re-definition of any type the API is aware of.
+54
View File
@@ -0,0 +1,54 @@
# Type creation
Circling back to metadata. There are two important things to remember when using the API to make queries or send transactions.
1. The functionality available, e.g. exposed on `api.query.*` is not hard-coded in the API, rather this is decorated from the chain metadata. So the metadata lets the API know which endpoints are available and what the type for those endpoints are.
2. When you supply a value to the API, internally it will convert that value to the correct type as expected by the chain, i.e. as determined by the metadata. This means that a function such as `balances.transfer(address: Address, value: Balance)` can take at least the following inputs, which are all converted to the correct types -
- `address` can be an `Address`, an `AccountId`, an `Uint8Array` publicKey, a hex publicKey or an ss58 formatted address;
- `value` can be a `Balance`, a value encoded in hex, a `BN` object, a base-10 string, a JS `number`, a JS `BigInt` or even a SCALE-encoded `Uint8Array`
In cases where a value is returned such as storage queries, the response from the chain is always encoded into the correct `Codec` type. This means that while the node may return an encoded block (with encoded extrinsics) via `api.rpc.chain.getBlock()`, this is decoded into a proper `SignedBlock` by the API. Outputting this value via `.toJSON()` will yield an encoding for RPC, so if you are not using TypeScript (which adds code helpers on decoded objects), a representation via `.toHuman()` will be more representative of the actual object fields, re-formatted for human consumption.
## Why create types
With the conversions done in the API, there are limited reasons to create types "manually". However, just because there are not thousands of reasons, does not mean it is not valid. For instance, you may retrieve an `Option` and for the sake of sanity would like to use `.unwrapOr()` on it, returning a `Codec` default value where the value `.isNone`.
```js
// type import for TypeScript
import type { Balance } from '@polkadot/types/interfaces';
...
// unwrap out option into a zero Balance whn not found
const balance: Balance = balanceOpt.unwrapOr(api.createType('Balance'));
```
In the example above, we introduced the `api.createType(<typeName>, [<value>])`. The same format is also exposed by the `TypeRegistry` (more on this in a short while) as well as `createType(...)` from the actual `@polkadot/types` package. All doing exactly the same.
## Choosing how to create
In most cases, you would always want to use the `api.createType` helper. What this does is call the underlying `@polkadot/types` `createType`, passing through the registry that is attached to the API. Registry? Yes, registry.
The registry contains a listing of all internal types and their classes that have been registered. So upon creation of an API instance, a `registry` object is attached to the API and this is passed through to all created types. This allows the type definitions to not pollute the global namespace, but rather be contained and able to reference one another.
As mentioned, the `createType` functions all do exactly the same, and it 99.99% of the cases you would be recommended to just forget about everything and use `api.createType` if and when required. In some cases, you may just have a type object and from that want to create another type instance. For that you can access the `registry` on the type object and call `createType` on it. (If this type object was created from an API instance, the registry on the type and on the API will point to the same instance.)
Basically, this means that we have equivalency in creation for all the items below, all creating on the same registry (containing all injected types), and all wrapping the same value -
```js
import { createType } from '@polkadot/types';
// via API (recommended)
api.createType('Balance', 123);
// via registry (`.registry` is on all API and Codec objects)
api.registry.createType('Balance', 123n);
// via the low-level approach
createType(api.registry, 'Balance', '123');
```
## Extending extrinsics
On customized chains, it is possible to [extend the format of the extrinsics and extrinsic payload for the chain](extrinsic.extend.md), next up we will look at this advanced use-case.
+2 -2
View File
@@ -137,6 +137,6 @@ const api = await ApiPromise.create({
`Balance` would be defined as an `u128` at the end. Effectively based on the flow it is first registered as a `u32`, then overridden as a `u64` and finally overridden once more as a `u128` by the chain types.
## Extending extrinsics
## Type creation
On customized chains, it is possible to [extend the format of the extrinsics and extrinsic payload as customized on the chain](extrinsic.extend.md), next up we will look at this advanced use-case.
While the API always converts all the inputs into the underlying type required by the operation, in some cases you may want to [cret an instance of a type](types.create.md) yourself.
+1 -8
View File
@@ -33,18 +33,11 @@ However, to make this sane from a developer perspective the injected methods are
import { AccountData, Index } from '@polkadot/types/interfaces';
...
const [nonce, balance] = await api.query.system.account<[Index, AccountData]>(ADDR);
const { nonce, data: balances } = await api.query.system.account<[Index, AccountData]>(ADDR);
```
In both these case we can instruct the TypeScript compiler that the type we are expecting in `Index` and `Balance` respectively, not just pure `Codec`. This means that functions like `.toNumber()` is available on both these types - as opposed to just the [general type defaults](types.basics.md#everything-is-a-type) with `.toHex()` and friends.
## Future work
As of this writing, there are still some gray areas to type detection, specifically around the following interfaces -
- `.at` & `.multi` on `api.query` does not (yet) have a `<TypeOverride>` interface. This means `as <TypeOverride>` casts are presently needed for these results
- `api.queryMulti` does not (yet) allow you to provide a hint to the types returned, this ties to the previous point
## Adding user types
In addition to the generated and available interfaces, there is also the ability to [create TypeScript interfaces from your own definitions and well as your on-chain modules](typescript.user.md).
+2 -2
View File
@@ -6,14 +6,14 @@ In the previous section we looked at the TypeScript definitions that are availab
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).
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.
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.
- `stuff/interfaces/<module>/definitions.ts` for each module (`types.ts` & `index.ts` will be generated)
- `stuff/interfaces/defnitions.ts` importing all sub-definitions`
With this structure setup, you can generate TypeScript defintions.
In the root of your project (with the `@polkadot/api`), you can run `yarn polkadot-types-from-defs --input ./stuff/interfaces --package @MeInc/stuff/interfaces` which will create `types.ts` and `index.ts` files with the generated types. You can use these in exactly the same way as you would use your types from `@polkadot/types/interfaces`.
In the root of your project (with the `@polkadot/typegen` package installed), you can run `yarn polkadot-types-from-defs --input ./stuff/interfaces --package @MeInc/stuff/interfaces` which will create `types.ts` and `index.ts` files with the generated types. You can use these in exactly the same way as you would use your types from `@polkadot/types/interfaces`.
## Chain modules
+2 -2
View File
@@ -7,19 +7,19 @@ module.exports = Object.assign({}, config, {
'@polkadot/api-contract(.*)$': '<rootDir>/packages/api-contract/src/$1',
'@polkadot/api-derive(.*)$': '<rootDir>/packages/api-derive/src/$1',
'@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/jsonrpc(.*)$': '<rootDir>/packages/type-jsonrpc/src/$1',
'@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/type-jsonrpc/build',
'<rootDir>/packages/types/build'
],
globals: {
+1 -1
View File
@@ -9,5 +9,5 @@
"packages": [
"packages/*"
],
"version": "1.2.1"
"version": "1.4.1"
}
+9 -9
View File
@@ -1,5 +1,5 @@
{
"version": "1.2.1",
"version": "1.4.1",
"private": true,
"engines": {
"yarn": "^1.10.1"
@@ -8,14 +8,13 @@
"packages/*"
],
"resolutions": {
"typescript": "^3.7.5"
"typescript": "^3.8.2"
},
"scripts": {
"build": "yarn build:interfaces && polkadot-dev-build-ts",
"build:interfaces": "node packages/types/src/scripts/interfacesTsWrapper.js",
"circular": "madge --circular --extensions ts ./",
"docs": "node packages/types/src/scripts/MetadataMdWrapper.js && polkadot-dev-build-docs",
"chain:info": "node packages/types/src/scripts/extractChainWrapper.js",
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
"build:interfaces": "polkadot-types-internal-interfaces",
"docs": "polkadot-types-internal-metadata && polkadot-dev-build-docs",
"chain:info": "polkadot-types-chain-info",
"lint": "polkadot-dev-run-lint",
"clean": "polkadot-dev-clean-build",
"postinstall": "polkadot-dev-yarn-only",
@@ -27,7 +26,8 @@
"@babel/core": "^7.8.4",
"@babel/register": "^7.8.3",
"@babel/runtime": "^7.8.4",
"@polkadot/dev": "^0.40.16",
"@polkadot/ts": "^0.2.3"
"@polkadot/dev": "^0.41.4",
"@polkadot/ts": "^0.2.3",
"copyfiles": "^2.2.0"
}
}
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-contract",
"version": "1.2.1",
"version": "1.4.1",
"description": "Interfaces for interacting with contracts and contract ABIs",
"main": "index.js",
"keywords": [
@@ -27,10 +27,10 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api": "^1.2.1",
"@polkadot/rpc-core": "^1.2.1",
"@polkadot/types": "^1.2.1",
"@polkadot/util": "^2.3.1",
"@polkadot/api": "1.4.1",
"@polkadot/rpc-core": "1.4.1",
"@polkadot/types": "1.4.1",
"@polkadot/util": "^2.5.1",
"bn.js": "^5.1.1",
"rxjs": "^6.5.4"
}
@@ -5,7 +5,7 @@
import { CodecArg, Constructor, Registry, TypeDef } from '@polkadot/types/types';
import { ContractABIArgBasePre, ContractABIContract, ContractABIContractPre, ContractABIEvent, ContractABIEventPre, ContractABIFn, ContractABIFnArg, ContractABIMessage, ContractABIMessageBase, ContractABIMessagePre, ContractABI, ContractABIMessageCommon, ContractABIPre, ContractABIRange, ContractABIRangePre, ContractABIStorage, ContractABIStorageLayout, ContractABIStorageLayoutPre, ContractABIStoragePre, ContractABIStorageStruct, ContractABIStorageStructPre, ContractABITypePre } from './types';
import { Compact, u32, createClass, createType, encodeType } from '@polkadot/types';
import { Compact, u32, createClass, encodeType } from '@polkadot/types';
import { assert, hexToU8a, isNumber, isString, isNull, isObject, isUndefined, stringCamelCase, isHex, hexToNumber } from '@polkadot/util';
import MetaRegistry from './MetaRegistry';
@@ -14,16 +14,16 @@ import MetaRegistry from './MetaRegistry';
// just catch everything (since this is now non-standard for u32 anyway)
function parseSelector (registry: Registry, fnname: string, input: ContractABIMessageCommon['selector']): u32 {
if (isNumber(input)) {
return createType(registry, 'u32', input);
return registry.createType('u32', input);
} else if (isHex(input)) {
return createType(registry, 'u32', hexToU8a(input));
return registry.createType('u32', hexToU8a(input));
} else if (typeof input === 'string') {
try {
const array = JSON.parse(input);
assert(array.length === 4, `${fnname}: Invalid selector length`);
return createType(registry, 'u32', Uint8Array.from(
return registry.createType('u32', Uint8Array.from(
// the as number[] is here to pacify TS, it doesn't quite know how to handle the cb
(array as number[]).map((value: string | number): number =>
isHex(value)
+1 -1
View File
@@ -260,7 +260,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
return {
info: TypeDefInfo.VecFixed,
ext: { length: vecLength, type },
length: vecLength, // ex: { type: type }
type: `[${type};${vecLength}]`,
sub: this.typeDefFromMetaTypeAt(vecTypeIndex)
};
+4 -5
View File
@@ -2,16 +2,15 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
import { IKeyringPair } from '@polkadot/types/types';
import { IKeyringPair, ISubmittableResult } from '@polkadot/types/types';
import { ApiObject, ContractABIPre } from '../types';
import BN from 'bn.js';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SubmittableResult } from '@polkadot/api';
import { createType } from '@polkadot/types';
import { assert } from '@polkadot/util';
import Abi from '../Abi';
@@ -27,7 +26,7 @@ export interface BlueprintCreate<ApiType extends ApiTypes> {
class BlueprintCreateResult<ApiType extends ApiTypes> extends SubmittableResult {
public readonly contract?: Contract<ApiType>;
constructor (result: SubmittableResultImpl, contract?: Contract<ApiType>) {
constructor (result: ISubmittableResult, contract?: Contract<ApiType>) {
super(result);
this.contract = contract;
@@ -41,7 +40,7 @@ export default class Blueprint<ApiType extends ApiTypes> extends BaseWithTx<ApiT
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, codeHash: string | Hash) {
super(api, abi, decorateMethod);
this.codeHash = createType(this.registry, 'Hash', codeHash);
this.codeHash = this.registry.createType('Hash', codeHash);
}
public deployContract (constructorIndex = 0, endowment: number | BN, maxGas: number | BN, ...params: any[]): BlueprintCreate<ApiType> {
+4 -4
View File
@@ -2,9 +2,9 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
import { IKeyringPair } from '@polkadot/types/types';
import { IKeyringPair, ISubmittableResult } from '@polkadot/types/types';
import { ApiObject, ContractABIPre } from '../types';
import BN from 'bn.js';
@@ -27,7 +27,7 @@ export interface CodePutCode<ApiType extends ApiTypes> {
class CodePutCodeResult<ApiType extends ApiTypes> extends SubmittableResult {
public readonly blueprint?: Blueprint<ApiType>;
constructor (result: SubmittableResultImpl, blueprint?: Blueprint<ApiType>) {
constructor (result: ISubmittableResult, blueprint?: Blueprint<ApiType>) {
super(result);
this.blueprint = blueprint;
@@ -55,7 +55,7 @@ export default class Code<ApiType extends ApiTypes> extends BaseWithTx<ApiType>
};
}
private createResult = (result: SubmittableResultImpl): CodePutCodeResult<ApiType> => {
private createResult = (result: ISubmittableResult): CodePutCodeResult<ApiType> => {
let blueprint: Blueprint<ApiType> | undefined;
if (result.isInBlock) {
+4 -5
View File
@@ -11,7 +11,6 @@ import BN from 'bn.js';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SubmittableResult } from '@polkadot/api';
import { createType } from '@polkadot/types';
import Abi from '../Abi';
import { formatData } from '../util';
import { BaseWithTxAndRpcCall } from './util';
@@ -44,7 +43,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
as === 'rpc' && this.hasRpcContractsCall
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> => {
return this.rpcContractsCall(
createType(this.registry, 'ContractCallRequest', {
this.registry.createType('ContractCallRequest', {
origin: account,
dest: this.address.toString(),
value,
@@ -54,7 +53,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
)
.pipe(
map((result: ContractExecResult): ContractCallOutcome =>
this.createOutcome(result, createType(this.registry, 'AccountId', account), def, params)
this.createOutcome(result, this.registry.createType('AccountId', account), def, params)
)
);
}
@@ -75,7 +74,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
output = message.returnType
? formatData(this.registry, data, message.returnType)
: createType(this.registry, 'Raw', data);
: this.registry.createType('Raw', data);
}
return {
@@ -92,6 +91,6 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, address: string | AccountId | Address) {
super(api, abi, decorateMethod);
this.address = createType(this.registry, 'Address', address);
this.address = this.registry.createType('Address', address);
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
import { AccountId, Address, ContractExecResult } from '@polkadot/types/interfaces';
import { Codec, CodecArg } from '@polkadot/types/types';
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/codec/create/types';
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/create/types';
// import { Observable } from 'rxjs';
import { ApiPromise, ApiRx } from '@polkadot/api';
+1 -2
View File
@@ -4,8 +4,7 @@
import { Codec, Registry, TypeDefInfo, TypeDef } from '@polkadot/types/types';
import { Option, Raw, createClass } from '@polkadot/types';
import { createTypeUnsafe } from '@polkadot/types/codec';
import { Option, Raw, createClass, createTypeUnsafe } from '@polkadot/types';
export function formatData (registry: Registry, data: Raw, { info, type }: TypeDef): Codec {
if (info === TypeDefInfo.Option) {
@@ -18,10 +18,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -71,10 +68,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -116,10 +110,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -153,10 +144,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -183,10 +171,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -223,10 +208,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -256,10 +238,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -295,10 +274,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -340,10 +316,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -381,10 +354,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -402,10 +372,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -439,10 +406,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -460,10 +424,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -506,10 +467,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -527,10 +485,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -566,10 +521,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -587,10 +539,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -628,10 +577,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -677,10 +623,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -708,10 +651,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -725,10 +665,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -757,10 +694,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -802,10 +736,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -839,10 +770,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -869,10 +797,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -909,10 +834,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -942,10 +864,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -969,10 +888,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -998,10 +914,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1047,10 +960,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1082,10 +992,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1119,10 +1026,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1149,10 +1053,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1189,10 +1090,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1230,10 +1128,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1260,10 +1155,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1300,10 +1192,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1331,10 +1220,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1361,10 +1247,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1400,10 +1283,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1445,10 +1325,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1486,10 +1363,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1507,10 +1381,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1544,10 +1415,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1565,10 +1433,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1611,10 +1476,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1632,10 +1494,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1671,10 +1530,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1692,10 +1548,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1725,10 +1578,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1746,10 +1596,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1773,10 +1620,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1814,10 +1658,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1835,10 +1676,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1872,10 +1710,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1893,10 +1728,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1939,10 +1771,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1960,10 +1789,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2007,10 +1833,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2028,10 +1851,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2065,10 +1885,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2086,10 +1903,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2132,10 +1946,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2153,10 +1964,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2190,10 +1998,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2211,10 +2016,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2248,10 +2050,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2269,10 +2068,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2305,10 +2101,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -2328,10 +2121,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -38,10 +38,7 @@
{
"info": 11,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": ""
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -89,10 +86,7 @@
{
"info": 11,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": ""
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -130,10 +124,7 @@
{
"info": 11,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": ""
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -153,10 +144,7 @@
{
"info": 11,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": ""
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -168,10 +156,7 @@
{
"info": 11,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": ""
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -181,4 +166,4 @@
"info": 6,
"type": "u8"
}
]
]
@@ -18,10 +18,7 @@
{
"info": 13,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 7,
"type": "u8"
@@ -71,10 +68,7 @@
{
"info": 13,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 7,
"type": "u8"
@@ -120,10 +114,7 @@
{
"info": 13,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 7,
"type": "u8"
@@ -151,10 +142,7 @@
{
"info": 13,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 7,
"type": "u8"
@@ -168,10 +156,7 @@
{
"info": 13,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 7,
"type": "u8"
@@ -185,4 +170,4 @@
"info": 7,
"type": "bool"
}
]
]
@@ -22,10 +22,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -67,10 +64,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -104,10 +98,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -167,10 +158,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -241,10 +229,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -308,10 +293,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -381,10 +363,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -426,10 +405,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -483,10 +459,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -528,10 +501,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -565,10 +535,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -628,10 +595,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -702,10 +666,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -769,10 +730,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -830,10 +788,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -847,10 +802,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -932,10 +884,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -977,10 +926,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1008,10 +954,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1033,10 +976,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1070,10 +1010,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1133,10 +1070,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1207,10 +1141,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1282,10 +1213,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1345,10 +1273,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1419,10 +1344,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1484,10 +1406,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1547,10 +1466,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1620,10 +1536,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1665,10 +1578,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -1714,10 +1624,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -22,10 +22,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -71,10 +68,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -288,10 +282,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -337,10 +328,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -438,10 +426,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -487,10 +472,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -518,10 +500,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -535,10 +514,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -563,10 +539,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
@@ -714,10 +687,7 @@
{
"info": 12,
"type": "[u8;32]",
"ext": {
"length": 32,
"type": "u8"
},
"length": 32,
"sub": {
"info": 6,
"type": "u8"
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-derive",
"version": "1.2.1",
"version": "1.4.1",
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
"main": "index.js",
"keywords": [
@@ -28,17 +28,17 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api": "^1.2.1",
"@polkadot/rpc-core": "^1.2.1",
"@polkadot/rpc-provider": "^1.2.1",
"@polkadot/types": "^1.2.1",
"@polkadot/util": "^2.3.1",
"@polkadot/util-crypto": "^2.3.1",
"@polkadot/api": "1.4.1",
"@polkadot/rpc-core": "1.4.1",
"@polkadot/rpc-provider": "1.4.1",
"@polkadot/types": "1.4.1",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"bn.js": "^5.1.1",
"memoizee": "^0.4.14",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.3.1"
"@polkadot/keyring": "^2.5.1"
}
}
@@ -8,7 +8,7 @@ import { ITuple } from '@polkadot/types/types';
import { Observable, of } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
import { ClassOf, Option, Vec, createType } from '@polkadot/types';
import { memo } from '../util';
+1 -1
View File
@@ -8,7 +8,7 @@ import { AccountIndexes } from '../types';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
import { Vec, createType } from '@polkadot/types';
import { memo } from '../util';
+10
View File
@@ -54,6 +54,16 @@ function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [Accou
email: dataAsString(info.email),
image: dataAsString(info.image),
legal: dataAsString(info.legal),
other: info.additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
const value = dataAsString(_value);
if (key && value) {
other[key] = value;
}
return other;
}, {}),
parent: superOf
? superOf[0]
: undefined,
+11 -5
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 { AccountId, AccountData, AccountIndex, Address, Balance, Index } from '@polkadot/types/interfaces';
import { AccountId, AccountData, AccountIndex, AccountInfo, Address, Balance, Index } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DerivedBalancesAccount } from '../types';
@@ -52,10 +52,16 @@ function queryBalancesAccount (api: ApiInterfaceRx, accountId: AccountId): Obser
}
function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Result> {
return api.query.system.account<ITuple<[Index, AccountData]>>(accountId).pipe(
map(([accountNonce, { free, reserved, miscFrozen, feeFrozen }]): Result =>
[free, reserved, feeFrozen, miscFrozen, accountNonce]
)
// 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
? (infoOrTuple as AccountInfo).data
: (infoOrTuple as [Index, AccountData])[1];
const accountNonce = (infoOrTuple as AccountInfo).nonce || (infoOrTuple as [Index, AccountData])[0];
return [free, reserved, feeFrozen, miscFrozen, accountNonce];
})
);
}
+10 -16
View File
@@ -12,21 +12,6 @@ import { createType } from '@polkadot/types';
import { memo } from '../util';
type Result = [Balance, Balance, Balance, Balance, Balance];
function query (api: ApiInterfaceRx): Observable<Result> {
return of([
// deprecated - remove
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
// current
api.consts.balances.existentialDeposit,
api.consts.transactionPayment.transactionBaseFee,
api.consts.transactionPayment.transactionByteFee
]);
}
/**
* @name fees
* @returns An object containing the combined results of the storage queries for
@@ -42,7 +27,16 @@ function query (api: ApiInterfaceRx): Observable<Result> {
*/
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
return memo((): Observable<DerivedFees> =>
query(api).pipe(
of([
// deprecated - remove
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
// current
api.consts.balances.existentialDeposit,
api.consts.transactionPayment.transactionBaseFee,
api.consts.transactionPayment.transactionByteFee
]).pipe(
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DerivedFees => ({
creationFee,
existentialDeposit,
+1
View File
@@ -46,6 +46,7 @@ const deriveAvail: Record<string, string[]> = {
democracy: ['democracy'],
elections: ['electionsPhragmen', 'elections'],
imOnline: ['imOnline'],
parachains: ['parachains', 'registrar'],
session: ['session'],
society: ['society'],
staking: ['staking'],
-120
View File
@@ -1,120 +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 { BlockNumber, CollatorId, ParaId, ParaInfo, Retriable, UpwardMessage } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveParachain, DeriveParachainActive } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Bytes, Option, Vec } from '@polkadot/types';
import { memo } from '../util';
type ParaIds = ParaId[];
type ParaInfoResult = Option<ParaInfo>;
type PendingSwap = Option<ParaId>;
type Active = ITuple<[ParaId, Option<ITuple<[CollatorId, Retriable]>>]>[];
type RetryQueue = ITuple<[ParaId, CollatorId]>[][]
type SelectedThreads = ITuple<[ParaId, CollatorId]>[][];
type Heads = Bytes;
type RelayDispatchQueue = Vec<UpwardMessage>
type Watermarks = Option<BlockNumber>;
type DidUpdate = Option<Vec<ParaId>>;
type Result = [
ParaId[],
[
Active,
RetryQueue,
SelectedThreads,
DidUpdate
],
ParaInfoResult[],
PendingSwap[],
Heads[],
RelayDispatchQueue[],
Watermarks[],
];
function parseActive (id: ParaId, active: Active): DeriveParachainActive | null {
const found = active.find(([paraId]): boolean => paraId === id);
if (found && found[1].isSome) {
const [collatorId, retriable] = found[1].unwrap();
return {
collatorId,
...(
retriable.isWithRetries
? {
isRetriable: true,
retries: retriable.asWithRetries.toNumber()
}
: {
isRetriable: false,
retries: 0
}
)
};
}
return null;
}
function parseCollators (id: ParaId, collatorQueue: SelectedThreads | RetryQueue): (CollatorId | null)[] {
return collatorQueue
.map((queue): CollatorId | null => {
const found = queue.find(([paraId]): boolean => paraId === id);
return found ? found[1] : null;
});
}
function parse ([ids, [active, retryQueue, selectedThreads, didUpdate], infos, pendingSwaps, heads, relayDispatchQueues, watermarks]: Result): DeriveParachain[] {
return ids.map((id, index): DeriveParachain => {
return {
active: parseActive(id, active),
didUpdate: didUpdate.isSome
? didUpdate.unwrap().some((paraId): boolean => paraId === id)
: false,
heads: heads[index],
id,
info: infos[index].unwrapOr(null),
pendingSwapId: pendingSwaps[index].unwrapOr(null),
relayDispatchQueue: relayDispatchQueues[index],
retryCollators: parseCollators(id, retryQueue),
selectedCollators: parseCollators(id, selectedThreads),
watermark: watermarks[index].unwrapOr(null)
};
});
}
export function all (api: ApiInterfaceRx): () => Observable<DeriveParachain[]> {
return memo((): Observable<DeriveParachain[]> =>
api.query.registrar?.parachains && api.query.parachains
? api.query.registrar.parachains<ParaIds>().pipe(
switchMap((paraIds) =>
combineLatest([
of(paraIds),
api.queryMulti([
api.query.registrar.active,
api.query.registrar.retryQueue,
api.query.registrar.selectedThreads,
api.query.parachains.didUpdate
]),
api.query.registrar.paras.multi<ParaInfo>(paraIds),
api.query.registrar.pendingSwap.multi<PendingSwap>(paraIds),
api.query.parachains.heads.multi<Heads>(paraIds),
api.query.parachains.relayDispatchQueue.multi<RelayDispatchQueue>(paraIds),
api.query.parachains.watermarks.multi<Watermarks>(paraIds)
]) as Observable<Result>
),
map((result: Result): DeriveParachain[] =>
parse(result)
)
)
: of([] as DeriveParachain[])
);
}
+2 -1
View File
@@ -2,4 +2,5 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './all';
export * from './info';
export * from './overview';
@@ -0,0 +1,99 @@
// 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 { CollatorId, ParaId } from '@polkadot/types/interfaces';
import { DeriveParachainInfo, DeriveParachainFull, DeriveParachainActive } from '../types';
import { Active, DidUpdate, Heads, ParaInfoResult, PendingSwap, RelayDispatchQueue, RetryQueue, SelectedThreads, Watermarks } from './types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType } from '@polkadot/types';
import { memo } from '../util';
type Result = [
Active,
RetryQueue,
SelectedThreads,
DidUpdate,
ParaInfoResult,
PendingSwap,
Heads,
RelayDispatchQueue,
Watermarks
];
function parseActive (id: ParaId, active: Active): DeriveParachainActive | null {
const found = active.find(([paraId]): boolean => paraId === id);
if (found && found[1].isSome) {
const [collatorId, retriable] = found[1].unwrap();
return {
collatorId,
...(
retriable.isWithRetries
? {
isRetriable: true,
retries: retriable.asWithRetries.toNumber()
}
: {
isRetriable: false,
retries: 0
}
)
};
}
return null;
}
function parseCollators (id: ParaId, collatorQueue: SelectedThreads | RetryQueue): (CollatorId | null)[] {
return collatorQueue
.map((queue): CollatorId | null => {
const found = queue.find(([paraId]): boolean => paraId === id);
return found ? found[1] : null;
});
}
function parse (id: ParaId, [active, retryQueue, selectedThreads, didUpdate, info, pendingSwap, heads, relayDispatchQueue, watermarks]: Result): DeriveParachainFull {
return {
active: parseActive(id, active),
didUpdate: didUpdate.isSome
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
: false,
heads,
id,
info: { id, ...info.unwrapOr(null) } as DeriveParachainInfo,
pendingSwapId: pendingSwap.unwrapOr(null),
relayDispatchQueue,
retryCollators: parseCollators(id, retryQueue),
selectedCollators: parseCollators(id, selectedThreads),
watermark: watermarks.unwrapOr(null)
};
}
export function info (api: ApiInterfaceRx): (id: ParaId | number) => Observable<DeriveParachainFull | null> {
return memo((id: ParaId | number): Observable<DeriveParachainFull | null> =>
api.query.registrar && api.query.parachains
? api.queryMulti<Result>([
api.query.registrar.active,
api.query.registrar.retryQueue,
api.query.registrar.selectedThreads,
api.query.parachains.didUpdate,
[api.query.registrar.paras, id],
[api.query.registrar.pendingSwap, id],
[api.query.parachains.heads, id],
[api.query.parachains.relayDispatchQueue, id],
[api.query.parachains.watermarks, id]
])
.pipe(
map((result: Result): DeriveParachainFull =>
parse(createType(api.registry, 'ParaId', id), result)
)
)
: of(null)
);
}
@@ -0,0 +1,59 @@
// 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 { ParaId } from '@polkadot/types/interfaces';
import { DeriveParachain, DeriveParachainInfo } from '../types';
import { DidUpdate, ParaInfoResult, PendingSwap, RelayDispatchQueueSize, Watermarks } from './types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
type Result = [
ParaId[],
DidUpdate,
ParaInfoResult[],
PendingSwap[],
RelayDispatchQueueSize[],
Watermarks[],
];
function parse ([ids, didUpdate, infos, pendingSwaps, relayDispatchQueueSizes, watermarks]: Result): DeriveParachain[] {
return ids.map((id, index): DeriveParachain => {
return {
didUpdate: didUpdate.isSome
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
: false,
id,
info: { id, ...infos[index].unwrapOr(null) } as DeriveParachainInfo,
pendingSwapId: pendingSwaps[index].unwrapOr(null),
relayDispatchQueueSize: relayDispatchQueueSizes[index][0].toNumber(),
watermark: watermarks[index].unwrapOr(null)
};
});
}
export function overview (api: ApiInterfaceRx): () => Observable<DeriveParachain[]> {
return memo((): Observable<DeriveParachain[]> =>
api.query.registrar?.parachains && api.query.parachains
? api.query.registrar.parachains<ParaId[]>().pipe(
switchMap((paraIds) =>
combineLatest([
of(paraIds),
api.query.parachains.didUpdate<DidUpdate>(),
api.query.registrar.paras.multi<ParaInfoResult>(paraIds),
api.query.registrar.pendingSwap.multi<PendingSwap>(paraIds),
api.query.parachains.relayDispatchQueueSize.multi<RelayDispatchQueueSize>(paraIds),
api.query.parachains.watermarks.multi<Watermarks>(paraIds)
])
),
map((result: Result): DeriveParachain[] =>
parse(result)
)
)
: of([] as DeriveParachain[])
);
}
@@ -0,0 +1,20 @@
// 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, CollatorId, ParaId, ParaInfo, Retriable, UpwardMessage } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { Bytes, Option, u32, Vec } from '@polkadot/types';
export type ParaInfoResult = Option<ParaInfo>;
export type PendingSwap = Option<ParaId>;
export type Active = Vec<ITuple<[ParaId, Option<ITuple<[CollatorId, Retriable]>>]>>;
export type RetryQueue = Vec<Vec<ITuple<[ParaId, CollatorId]>>>
export type SelectedThreads = Vec<Vec<ITuple<[ParaId, CollatorId]>>>
export type Code = Bytes;
export type Heads = Bytes;
export type RelayDispatchQueue = Vec<UpwardMessage>
export type RelayDispatchQueueSize = ITuple<[u32, u32]>;
export type Watermarks = Option<BlockNumber>;
export type DidUpdate = Option<Vec<ParaId>>;
+68 -14
View File
@@ -3,29 +3,83 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { EraIndex, SessionIndex } from '@polkadot/types/interfaces';
import { EraIndex, MomentOf, SessionIndex } from '@polkadot/types/interfaces';
import { DeriveSessionIndexes } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType, u32 as U32 } from '@polkadot/types';
import { createType, Option, u32 } from '@polkadot/types';
import { memo } from '../util';
type Result = [EraIndex, Option<MomentOf>, EraIndex, SessionIndex, u32];
// parse into Indexes
function parse ([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]: Result): DeriveSessionIndexes {
return {
activeEra,
activeEraStart,
currentEra,
currentIndex,
validatorCount
};
}
// query for previous V2
function queryNoActive (api: ApiInterfaceRx): Observable<Result> {
return api.queryMulti<[EraIndex, SessionIndex, u32]>([
api.query.staking.currentEra,
api.query.session.currentIndex,
api.query.staking.validatorCount
]).pipe(
map(([currentEra, currentIndex, validatorCount]): Result => [
currentEra,
createType(api.registry, 'Option<MomentOf>'),
currentEra,
currentIndex,
validatorCount
])
);
}
// query based on latest
function query (api: ApiInterfaceRx): Observable<Result> {
return api.queryMulti<[Option<EraIndex>, Option<MomentOf>, Option<EraIndex>, SessionIndex, u32]>([
api.query.staking.activeEra,
api.query.staking.activeEraStart,
api.query.staking.currentEra,
api.query.session.currentIndex,
api.query.staking.validatorCount
]).pipe(
map(([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]): Result => [
activeEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
activeEraStart,
currentEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
currentIndex,
validatorCount
])
);
}
// empty set when none is available
function empty (api: ApiInterfaceRx): Observable<Result> {
return of([
createType(api.registry, 'EraIndex', 1),
createType(api.registry, 'Option<MomentOf>'),
createType(api.registry, 'EraIndex', 1),
createType(api.registry, 'SessionIndex', 1),
createType(api.registry, 'u32')
]);
}
export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> {
return memo((): Observable<DeriveSessionIndexes> =>
(
// Some chains (eg. very limited node-template), does not have session
api.query.session && api.query.staking
? api.queryMulti<[SessionIndex, EraIndex, U32]>([
api.query.session.currentIndex,
api.query.staking.currentEra,
api.query.staking.validatorCount
])
: of([createType(api.registry, 'SessionIndex', 1), createType(api.registry, 'EraIndex', 1), createType(api.registry, 'u32')])
).pipe(
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
currentIndex, currentEra, validatorCount
}))
));
? api.query.staking.activeEra
? query(api)
: queryNoActive(api)
: empty(api)
).pipe(map(parse))
);
}
+61 -28
View File
@@ -5,23 +5,26 @@
import { SessionIndex } from '@polkadot/types/interfaces';
import { DerivedSessionInfo, DeriveSessionIndexes } from '../types';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { u64, createType } from '@polkadot/types';
import { createType, Option, u64 } from '@polkadot/types';
import { memo } from '../util';
type ResultSlots = [u64, u64, u64, SessionIndex];
type ResultSlots = [u64, u64, u64, Option<SessionIndex>];
type ResultSlotsFlat = [u64, u64, u64, SessionIndex];
type ResultType = [boolean, u64, SessionIndex];
type Result = [ResultType, DeriveSessionIndexes, ResultSlots];
type Result = [ResultType, DeriveSessionIndexes, ResultSlotsFlat];
function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
function createDerived (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { activeEra, activeEraStart, currentEra, currentIndex, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, activeEraStartSessionIndex]]: Result): DerivedSessionInfo {
const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
const sessionProgress = currentSlot.sub(epochStartSlot);
const eraProgress = currentIndex.sub(currentEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
const eraProgress = currentIndex.sub(activeEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
return {
activeEra,
activeEraStart,
currentEra,
currentIndex,
eraLength: createType(api.registry, 'BlockNumber', sessionsPerEra.mul(epochDuration)),
@@ -34,46 +37,76 @@ function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, ses
};
}
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
function queryAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
return api.derive.session.indexes().pipe(
map((indexes): DerivedSessionInfo =>
createDerivedLatest(api, [
[false, createType(api.registry, 'u64', 1), api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)],
createDerived(api, [
[
false,
createType(api.registry, 'u64', 1),
api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)
],
indexes,
[createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'SessionIndex', 1)]
[
createType(api.registry, 'u64', 1),
createType(api.registry, 'u64', 1),
createType(api.registry, 'u64', 1),
createType(api.registry, 'SessionIndex', 1)
]
])
)
);
}
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
function queryBabe (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
return api.derive.session.indexes().pipe(
switchMap((indexes): Observable<[DeriveSessionIndexes, ResultSlots]> =>
combineLatest([
of(indexes),
api.queryMulti<ResultSlots>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot,
[api.query.staking.erasStartSessionIndex, indexes.activeEra]
])
])
),
map(([indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex]]): [DeriveSessionIndexes, ResultSlotsFlat] => [
indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex.unwrapOr(createType(api.registry, 'SessionIndex', 1))]
])
);
}
function queryBabeNoHistory (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
return combineLatest([
api.derive.session.indexes(),
api.queryMulti<ResultSlots>([
api.queryMulti<ResultSlotsFlat>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot,
api.query.staking.currentEraStartSessionIndex
])
]).pipe(
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo =>
createDerivedLatest(api, [
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
indexes,
slots
])
)
);
]);
}
/**
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
* @description Retrieves all the session and era query and calculates specific values on it as the length of the session and eras
*/
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
const query = api.consts.babe
? infoLatestBabe // 2.x with Babe
: infoLatestAura; // 2.x with Aura (not all info there)
return memo((): Observable<DerivedSessionInfo> =>
query(api));
api.consts.babe
? (api.query.staking.erasStartSessionIndex
? queryBabe(api) // 2.x with Babe
: queryBabeNoHistory(api)
).pipe(
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlotsFlat]): DerivedSessionInfo =>
createDerived(api, [
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
indexes,
slots
])
)
)
: queryAura(api)
);
}
@@ -14,16 +14,17 @@ import { memo } from '../util';
export function electedInfo (api: ApiInterfaceRx): () => Observable<DerivedStakingElected> {
return memo((): Observable<DerivedStakingElected> =>
api.derive.staking.validators().pipe(
switchMap(({ currentElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
switchMap(({ nextElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
combineLatest([
of(currentElected),
combineLatest(currentElected.map((accountId): Observable<DerivedStakingQuery> =>
of(nextElected),
combineLatest(nextElected.map((accountId): Observable<DerivedStakingQuery> =>
api.derive.staking.query(accountId)
))
])
),
map(([currentElected, info]): DerivedStakingElected => ({
currentElected, info
map(([nextElected, info]): DerivedStakingElected => ({
info,
nextElected
}))
)
);
@@ -1,46 +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 { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
import { DerivedStakingStash } from '../types';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { memo } from '../util';
type Result = [Option<AccountId>, Nominations, RewardDestination, Exposure, ValidatorPrefs, Option<Keys>];
function parse (stashId: AccountId, [_controllerId, nominators, rewardDestination, stakers, validatorPrefs, _nextKeys]: Result): DerivedStakingStash {
return {
controllerId: _controllerId.unwrapOr(undefined),
nextKeys: _nextKeys.unwrapOr(undefined),
nominators: nominators.targets,
nominateAt: nominators.submittedIn,
rewardDestination,
stakers,
stashId,
validatorPrefs
};
}
function query (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
return api.queryMulti<Result>([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
]);
}
export function infoStash (api: ApiInterfaceRx): (stashId: AccountId) => Observable<DerivedStakingStash> {
return memo((stashId: AccountId): Observable<DerivedStakingStash> =>
query(api, stashId).pipe(
map((result): DerivedStakingStash => parse(stashId, result))
));
}
+24 -6
View File
@@ -2,15 +2,31 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { EraPoints } from '@polkadot/types/interfaces';
import { AccountId, EraIndex, EraPoints, EraRewardPoints, RewardPoint } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedStakingOverview } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { memo } from '../util';
function retrievePointsPrev (api: ApiInterfaceRx, activeEra: EraIndex, currentElected: AccountId[]): Observable<EraRewardPoints> {
return api.query.staking.currentEraPointsEarned<EraPoints>(activeEra).pipe(
map(({ individual, total }): EraRewardPoints =>
createType(api.registry, 'EraRewardPoints', {
total,
individual: new Map<AccountId, RewardPoint>(
individual
.map((points): RewardPoint => createType(api.registry, 'RewardPoint', points))
.map((points, index): [AccountId, RewardPoint] => [currentElected[index], points])
)
})
)
);
}
/**
* @description Retrieve the staking overview, including elected and points earned
*/
@@ -20,14 +36,16 @@ export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingO
api.derive.session.indexes(),
api.derive.staking.validators()
]).pipe(
switchMap(([{ currentEra, currentIndex, validatorCount }, { currentElected, validators }]) =>
switchMap(([indexes, { nextElected, validators }]) =>
combineLatest([
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
of({ ...indexes, nextElected, validators }),
api.query.staking.erasRewardPoints
? api.query.staking.erasRewardPoints<EraRewardPoints>(indexes.activeEra)
: retrievePointsPrev(api, indexes.activeEra, nextElected)
])
),
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
map(([info, eraPoints]): DerivedStakingOverview => ({
...info, eraPoints
}))
));
}
+54 -33
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, StakingLedger, ValidatorPrefs } from '@polkadot/types/interfaces';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DerivedStakingQuery } from '../types';
@@ -13,7 +13,7 @@ import { createType, Option, Vec } from '@polkadot/types';
import { memo } from '../util';
type MultiResultV2 = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>, Option<StakingLedger>];
type MultiResult = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, ITuple<[ValidatorPrefs]>, Option<Keys>, Exposure];
function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
@@ -27,20 +27,52 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][],
};
}
function retrieve (api: ApiInterfaceRx, stashId: AccountId): Observable<[Vec<ITuple<[AccountId, Keys]>>, MultiResultV2]> {
return combineLatest([
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.queryMulti([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
]) as Observable<MultiResultV2>
function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
return api.queryMulti<MultiResult>([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
[api.query.staking.stakers, stashId]
]);
}
function retrieveCurr (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
return api.derive.session.indexes().pipe(
switchMap(({ activeEra }) =>
api.queryMulti<MultiResult>([
[api.query.staking.bonded, stashId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
[api.query.staking.erasStakers, [activeEra, stashId]]
])
)
);
}
function retrieveController (api: ApiInterfaceRx, stashId: AccountId, [queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, [validatorPrefs], nextKeys, exposure]]: [Vec<ITuple<[AccountId, Keys]>>, MultiResult]): Observable<DerivedStakingQuery> {
const controllerId = controllerIdOpt.unwrapOr(null);
return controllerId
? api.query.staking.ledger(controllerId).pipe(
map((stakingLedgerOpt): DerivedStakingQuery => ({
accountId: stashId,
controllerId,
exposure,
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
rewardDestination,
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
stashId,
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
}))
)
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
}
/**
* @description From a stash, retrieve the controllerId and all relevant details
*/
@@ -48,26 +80,15 @@ export function query (api: ApiInterfaceRx): (accountId: Uint8Array | string) =>
return memo((accountId: Uint8Array | string): Observable<DerivedStakingQuery> => {
const stashId = createType(api.registry, 'AccountId', accountId);
return retrieve(api, stashId).pipe(
switchMap(([queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, stakers, [validatorPrefs], nextKeys]]): Observable<DerivedStakingQuery> => {
const controllerId = controllerIdOpt.unwrapOr(null);
return controllerId
? api.query.staking.ledger(controllerId).pipe(
map((stakingLedgerOpt): DerivedStakingQuery => ({
accountId: stashId,
controllerId,
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
rewardDestination,
stakers,
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
stashId,
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
}))
)
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
})
return combineLatest([
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.query.staking.erasStakers
? retrieveCurr(api, stashId)
: retrievePrev(api, stashId)
]).pipe(
switchMap((result): Observable<DerivedStakingQuery> =>
retrieveController(api, stashId, result)
)
);
});
}
@@ -22,12 +22,16 @@ export function validators (api: ApiInterfaceRx): () => Observable<DeriveStaking
api.query.session
? api.query.session.validators()
: of([]),
api.query.staking
? api.query.staking.currentElected()
// FIXME need a replacement for currentElected in new
api.query.staking?.currentElected
? api.query.staking.erasStakers
? of(null)
: api.query.staking.currentElected()
: of([])
]).pipe(
map(([validators, currentElected]): DeriveStakingValidators => ({
currentElected, validators
map(([validators, nextElected]): DeriveStakingValidators => ({
nextElected: nextElected || validators,
validators
}))
));
}
+18 -6
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Header } from '@polkadot/types/interfaces';
import { AnyJsonObject, Constructor, Registry } from '@polkadot/types/types';
import { AnyJson, Constructor, Registry } from '@polkadot/types/types';
import runtimeTypes from '@polkadot/types/interfaces/runtime/definitions';
import { Struct } from '@polkadot/types';
@@ -17,12 +17,12 @@ const _Header: Constructor<Header> = Struct.with(runtimeTypes.types.Header as an
* A [[Block]] header with an additional `author` field that indicates the block author
*/
export default class HeaderExtended extends _Header {
private _author?: AccountId;
readonly #author?: AccountId;
constructor (registry: Registry, header?: Header, sessionValidators?: AccountId[]) {
super(registry, header);
this._author = this.extractAuthor(sessionValidators);
this.#author = this.extractAuthor(sessionValidators);
}
private extractAuthor (sessionValidators: AccountId[] = []): AccountId | undefined {
@@ -51,15 +51,27 @@ export default class HeaderExtended extends _Header {
* @description Convenience method, returns the author for the block
*/
public get author (): AccountId | undefined {
return this._author;
return this.#author;
}
/**
* @description Creates a human-friendly JSON representation
*/
public toHuman (isExtended?: boolean): AnyJson {
return {
...super.toHuman(isExtended) as { [index: string]: AnyJson },
author: this.author
? this.author.toHuman()
: undefined
};
}
/**
* @description Creates the JSON representation
*/
public toJSON (): AnyJsonObject {
public toJSON (): AnyJson {
return {
...super.toJSON() as AnyJsonObject,
...super.toJSON() as { [index: string]: AnyJson },
author: this.author
? this.author.toJSON()
: undefined
@@ -3,11 +3,11 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ReferendumIndex, ReferendumInfo } from '@polkadot/types/interfaces/democracy';
import { AnyJsonObject, Constructor, Registry } from '@polkadot/types/types';
import { AnyJson, Constructor, Registry } from '@polkadot/types/types';
import BN from 'bn.js';
import democracyTypes from '@polkadot/types/interfaces/democracy/definitions';
import { Struct, createType } from '@polkadot/types';
import { Struct } from '@polkadot/types';
// We can ignore the properties, added via Struct.with
const _ReferendumInfo: Constructor<ReferendumInfo> = Struct.with(democracyTypes.types.ReferendumInfo as any) as any;
@@ -18,29 +18,39 @@ const _ReferendumInfo: Constructor<ReferendumInfo> = Struct.with(democracyTypes.
* A [[ReferendumInfo]] with an additional `index` field
*/
export default class ReferendumInfoExtended extends _ReferendumInfo {
private _index: ReferendumIndex;
readonly #index: ReferendumIndex;
constructor (registry: Registry, value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) {
super(registry, value);
this._index = value instanceof ReferendumInfoExtended
this.#index = value instanceof ReferendumInfoExtended
? value.index
: createType(registry, 'ReferendumIndex', index);
: registry.createType('ReferendumIndex', index);
}
/**
* @description Convenience getter, returns the referendumIndex
*/
public get index (): ReferendumIndex {
return this._index;
return this.#index;
}
/**
* @description Creates a human-friendly JSON representation
*/
public toHuman (isExtended?: boolean): AnyJson {
return {
...super.toHuman(isExtended) as { [index: string]: AnyJson },
index: this.index.toHuman(isExtended)
};
}
/**
* @description Creates the JSON representation
*/
public toJSON (): AnyJsonObject {
public toJSON (): AnyJson {
return {
...super.toJSON() as AnyJsonObject,
...super.toJSON() as { [index: string]: AnyJson },
index: this.index.toJSON()
};
}
+25 -11
View File
@@ -2,10 +2,10 @@
// 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, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraPoints, Exposure, Hash, Index, Keys, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
import { AccountId, AccountIndex, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraRewardPoints, Exposure, Hash, Index, Keys, MomentOf, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Bytes, u32, Vec } from '@polkadot/types';
import { Bytes, Option, u32, Vec } from '@polkadot/types';
export type AccountIndexes = Record<string, AccountIndex>;
@@ -15,6 +15,7 @@ export interface DeriveAccountRegistration {
email?: string;
image?: string;
legal?: string;
other?: Record<string, string>;
parent?: AccountId;
pgp?: string;
riot?: string;
@@ -113,17 +114,28 @@ export interface DeriveParachainActive {
retries: number;
}
export interface DeriveParachainInfo extends ParaInfo {
id: ParaId;
icon?: string;
name?: string;
owner?: string;
}
export interface DeriveParachain {
active: DeriveParachainActive | null;
didUpdate: boolean;
pendingSwapId: ParaId | null;
heads: Bytes | null;
id: ParaId;
info: ParaInfo | null;
info: DeriveParachainInfo | null;
relayDispatchQueueSize?: number;
watermark: BlockNumber | null;
}
export interface DeriveParachainFull extends DeriveParachain {
active: DeriveParachainActive | null;
heads: Bytes | null;
relayDispatchQueue: UpwardMessage[];
retryCollators: (CollatorId | null)[];
selectedCollators: (CollatorId | null)[];
watermark: BlockNumber | null;
}
export interface DeriveProposalPreImage {
@@ -159,6 +171,8 @@ export interface DerivedReferendumVote {
}
export interface DeriveSessionIndexes {
activeEra: EraIndex;
activeEraStart: Option<MomentOf>;
currentEra: EraIndex;
currentIndex: SessionIndex;
validatorCount: u32;
@@ -200,22 +214,22 @@ export interface DeriveSocietyMember {
}
export interface DerivedStakingElected {
currentElected: AccountId[];
nextElected: AccountId[];
info: DerivedStakingQuery[];
}
export interface DeriveStakingValidators {
currentElected: AccountId[];
nextElected: AccountId[];
validators: AccountId[];
}
export interface DerivedStakingStash {
controllerId?: AccountId;
exposure?: Exposure;
nominators?: AccountId[];
nominateAt?: EraIndex;
rewardDestination?: RewardDestination;
nextKeys?: Keys;
stakers?: Exposure;
stashId?: AccountId;
validatorPrefs?: ValidatorPrefs;
}
@@ -233,8 +247,8 @@ export interface DerivedStakingAccount extends DerivedStakingQuery {
}
export interface DerivedStakingOverview extends DeriveSessionIndexes {
currentElected: AccountId[];
eraPoints: EraPoints;
eraPoints: EraRewardPoints;
nextElected: AccountId[];
validators: AccountId[];
}
@@ -4,7 +4,7 @@
import { ApprovalFlag } from '@polkadot/types/interfaces';
import { createType, TypeRegistry } from '@polkadot/types';
import { TypeRegistry } from '@polkadot/types';
import { approvalFlagsToBools } from './approvalFlagsToBools';
@@ -20,7 +20,7 @@ describe('approvalFlagsToBools', (): void => {
it('translates a single input', (): void => {
expect(
approvalFlagsToBools([
createType(registry, 'ApprovalFlag', 0b1010)
registry.createType('ApprovalFlag', 0b1010)
])
).toEqual([false, true, false, true]);
});
@@ -28,8 +28,8 @@ describe('approvalFlagsToBools', (): void => {
it('translates multiple inputs', (): void => {
expect(
approvalFlagsToBools([
createType(registry, 'ApprovalFlag', 0b0000),
createType(registry, 'ApprovalFlag', 0b1100)
registry.createType('ApprovalFlag', 0b0000),
registry.createType('ApprovalFlag', 0b1100)
])
).toEqual([false, false, false, true, true]);
});
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api",
"version": "1.2.1",
"version": "1.4.1",
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
"main": "index.js",
"keywords": [
@@ -27,19 +27,19 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api-derive": "^1.2.1",
"@polkadot/keyring": "^2.3.1",
"@polkadot/metadata": "^1.2.1",
"@polkadot/rpc-core": "^1.2.1",
"@polkadot/rpc-provider": "^1.2.1",
"@polkadot/types": "^1.2.1",
"@polkadot/util": "^2.3.1",
"@polkadot/util-crypto": "^2.3.1",
"@polkadot/api-derive": "1.4.1",
"@polkadot/keyring": "^2.5.1",
"@polkadot/metadata": "1.4.1",
"@polkadot/rpc-core": "1.4.1",
"@polkadot/rpc-provider": "1.4.1",
"@polkadot/types": "1.4.1",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"bn.js": "^5.1.1",
"eventemitter3": "^4.0.0",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.3.1"
"@polkadot/keyring": "^2.5.1"
}
}
@@ -1,17 +1,18 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Codec } from '@polkadot/types/types';
import { Bytes, u32, u64 } from '@polkadot/types/primitive';
import { Balance, BalanceOf, BlockNumber, Moment, Percent, Permill } from '@polkadot/types/interfaces/runtime';
import { Gas } from '@polkadot/types/interfaces/contracts';
import { Balance, BalanceOf, BlockNumber, Moment, Percent, Permill } from '@polkadot/types/interfaces/runtime';
import { SessionIndex } from '@polkadot/types/interfaces/session';
import { EraIndex } from '@polkadot/types/interfaces/staking';
declare module '@polkadot/metadata/Decorated/consts/types' {
export interface Constants {
[index: string]: ModuleConstants;
babe: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The number of **slots** that an epoch takes. We couple sessions to
* epochs, i.e. we start a new session once the new epoch begins.
@@ -27,7 +28,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
expectedBlockTime: AugmentedConst<Moment>;
};
timestamp: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The minimum period between blocks. Beware that this is different to the *expected* period
* that the block production apparatus provides. Your chosen consensus system will generally
@@ -37,14 +38,14 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
minimumPeriod: AugmentedConst<Moment>;
};
balances: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The minimum amount required to keep an account open.
**/
existentialDeposit: AugmentedConst<Balance>;
};
transactionPayment: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The fee to be paid for making a transaction; the base.
**/
@@ -55,7 +56,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
transactionByteFee: AugmentedConst<BalanceOf>;
};
staking: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* Number of sessions per era.
**/
@@ -66,7 +67,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
bondingDuration: AugmentedConst<EraIndex>;
};
session: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* Used as first key for `NextKeys` and `KeyOwner` to put all the data into the same branch
* of the trie.
@@ -74,7 +75,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
dedupKeyPrefix: AugmentedConst<Bytes>;
};
democracy: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The minimum period of locking and the period between a proposal being approved and enacted.
* It should generally be a little more than the unstake period to ensure that
@@ -108,7 +109,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
preimageByteDeposit: AugmentedConst<BalanceOf>;
};
elections: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
candidacyBond: AugmentedConst<BalanceOf>;
votingBond: AugmentedConst<BalanceOf>;
desiredMembers: AugmentedConst<u32>;
@@ -116,7 +117,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
termDuration: AugmentedConst<BlockNumber>;
};
finalityTracker: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The number of recent samples to keep from this chain. Default is 101.
**/
@@ -127,7 +128,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
reportLatency: AugmentedConst<BlockNumber>;
};
treasury: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* Fraction of a proposal's value that should be bonded in order to place the proposal.
* An accepted proposal gets these back. A rejected proposal does not.
@@ -163,7 +164,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
tipReportDepositPerByte: AugmentedConst<BalanceOf>;
};
contracts: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* Number of block delay an extrinsic claim surcharge has.
* When claim surcharge is called by an extrinsic the rent is checked
@@ -236,7 +237,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
blockGasLimit: AugmentedConst<Gas>;
};
society: {
[index: string]: Codec;
[index: string]: AugmentedConst<object & Codec>;
/**
* The minimum amount of a deposit required for a bid to be made.
**/
@@ -1,10 +1,9 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { AnyNumber, ITuple } from '@polkadot/types/types';
import { Option, Raw, Vec } from '@polkadot/types/codec';
import { Option, U8aFixed, Vec } from '@polkadot/types/codec';
import { Bytes, Data, bool, u32, u64 } from '@polkadot/types/primitive';
import { AccountId, AccountIndex, Balance, BalanceOf, BlockNumber, Hash, Index, KeyTypeId, Moment, Perbill, ValidatorId, Weight } from '@polkadot/types/interfaces/runtime';
import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
import { BabeAuthorityWeight, MaybeVrf } from '@polkadot/types/interfaces/babe';
import { AccountData, BalanceLock } from '@polkadot/types/interfaces/balances';
@@ -18,6 +17,7 @@ import { RegistrarInfo, Registration } from '@polkadot/types/interfaces/identity
import { AuthIndex } from '@polkadot/types/interfaces/imOnline';
import { Kind, OffenceDetails, OpaqueTimeSlot, ReportIdOf } from '@polkadot/types/interfaces/offences';
import { ActiveRecovery, RecoveryConfig } from '@polkadot/types/interfaces/recovery';
import { AccountId, AccountIndex, Balance, BalanceOf, BlockNumber, Hash, Index, KeyTypeId, Moment, Perbill, ValidatorId, Weight } from '@polkadot/types/interfaces/runtime';
import { Keys, SessionIndex } from '@polkadot/types/interfaces/session';
import { Bid, BidKind, SocietyVote, StrikeCount, VouchingStatus } from '@polkadot/types/interfaces/society';
import { EraIndex, EraPoints, Exposure, Forcing, MomentOf, Nominations, RewardDestination, SlashingSpans, SpanIndex, SpanRecord, StakingLedger, UnappliedSlash, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
@@ -27,6 +27,7 @@ import { Multiplier } from '@polkadot/types/interfaces/txpayment';
import { Multisig } from '@polkadot/types/interfaces/utility';
import { VestingInfo } from '@polkadot/types/interfaces/vesting';
import { Observable } from 'rxjs';
import { ApiTypes } from '@polkadot/api/types';
declare module '@polkadot/api/types/storage' {
export interface AugmentedQueries<ApiType> {
@@ -97,7 +98,7 @@ declare module '@polkadot/api/types/storage' {
/**
* The set of open multisig operations.
**/
multisigs: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: Raw | string | Uint8Array) => Observable<Option<Multisig>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
multisigs: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: U8aFixed | string | Uint8Array) => Observable<Option<Multisig>>> & QueryableStorageEntry<ApiType>;
};
babe: {
[index: string]: QueryableStorageEntry<ApiType>;
@@ -128,11 +129,11 @@ declare module '@polkadot/api/types/storage' {
* used where a number is needed that cannot have been chosen by an
* adversary, for purposes such as public-coin zero-knowledge proofs.
**/
randomness: AugmentedQuery<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
randomness: AugmentedQuery<ApiType, () => Observable<U8aFixed>> & QueryableStorageEntry<ApiType>;
/**
* Next epoch randomness.
**/
nextRandomness: AugmentedQuery<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
nextRandomness: AugmentedQuery<ApiType, () => Observable<U8aFixed>> & QueryableStorageEntry<ApiType>;
/**
* Randomness under construction.
* We make a tradeoff between storage accesses and list length.
@@ -143,7 +144,7 @@ declare module '@polkadot/api/types/storage' {
* epoch.
**/
segmentIndex: AugmentedQuery<ApiType, () => Observable<u32>> & QueryableStorageEntry<ApiType>;
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<Raw>>> & QueryableStorageEntry<ApiType>;
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<U8aFixed>>> & QueryableStorageEntry<ApiType>;
/**
* Temporary value (cleared at block finalization) which is `Some`
* if per-block initialization has already been called for current block.
@@ -306,11 +307,11 @@ declare module '@polkadot/api/types/storage' {
* All slashing events on validators, mapped by era to the highest slash proportion
* and slash value of the era.
**/
validatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ITuple<[Perbill, BalanceOf]>>>, EraIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
validatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ITuple<[Perbill, BalanceOf]>>>> & QueryableStorageEntry<ApiType>;
/**
* All slashing events on nominators, mapped by era to the highest slash value of the era.
**/
nominatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<BalanceOf>>, EraIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
nominatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<BalanceOf>>> & QueryableStorageEntry<ApiType>;
/**
* Slashing spans for stash accounts.
**/
@@ -319,7 +320,7 @@ declare module '@polkadot/api/types/storage' {
* Records information about the maximum slash of a stash within a slashing span,
* as well as how much reward has been paid out.
**/
spanSlash: AugmentedQuery<ApiType, (arg: ITuple<[AccountId, SpanIndex]>) => Observable<SpanRecord>> & QueryableStorageEntry<ApiType>;
spanSlash: AugmentedQuery<ApiType, (arg: ITuple<[AccountId, SpanIndex]> | [AccountId | string | Uint8Array, SpanIndex | AnyNumber | Uint8Array]) => Observable<SpanRecord>> & QueryableStorageEntry<ApiType>;
/**
* The earliest era for which we have a pending, unapplied slash.
**/
@@ -355,13 +356,13 @@ declare module '@polkadot/api/types/storage' {
* The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
* the trie. Having all data in the same branch should prevent slowing down other queries.
**/
nextKeys: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<Option<Keys>>, Bytes | string | Uint8Array> & QueryableStorageEntry<ApiType>;
nextKeys: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<Option<Keys>>> & QueryableStorageEntry<ApiType>;
/**
* The owner of a key. The second key is the `KeyTypeId` + the encoded key.
* The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
* the trie. Having all data in the same branch should prevent slowing down other queries.
**/
keyOwner: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ITuple<[KeyTypeId, Bytes]>) => Observable<Option<ValidatorId>>, Bytes | string | Uint8Array> & QueryableStorageEntry<ApiType>;
keyOwner: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ITuple<[KeyTypeId, Bytes]> | [KeyTypeId | AnyNumber | Uint8Array, Bytes | string | Uint8Array]) => Observable<Option<ValidatorId>>> & QueryableStorageEntry<ApiType>;
};
democracy: {
[index: string]: QueryableStorageEntry<ApiType>;
@@ -409,7 +410,7 @@ declare module '@polkadot/api/types/storage' {
* default `Vote` value otherwise). If you don't want to check `voters_for`, then you can
* also check for simple existence with `VoteOf::contains_key` first.
**/
voteOf: AugmentedQuery<ApiType, (arg: ITuple<[ReferendumIndex, AccountId]>) => Observable<Vote>> & QueryableStorageEntry<ApiType>;
voteOf: AugmentedQuery<ApiType, (arg: ITuple<[ReferendumIndex, AccountId]> | [ReferendumIndex | AnyNumber | Uint8Array, AccountId | string | Uint8Array]) => Observable<Vote>> & QueryableStorageEntry<ApiType>;
/**
* Who is able to vote for whom. Value is the fund-holding account, key is the
* vote-transaction-sending account.
@@ -643,12 +644,12 @@ declare module '@polkadot/api/types/storage' {
* For each session index, we keep a mapping of `AuthIndex`
* to `offchain::OpaqueNetworkState`.
**/
receivedHeartbeats: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: AuthIndex | AnyNumber | Uint8Array) => Observable<Option<Bytes>>, SessionIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
receivedHeartbeats: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: AuthIndex | AnyNumber | Uint8Array) => Observable<Option<Bytes>>> & QueryableStorageEntry<ApiType>;
/**
* For each session index, we keep a mapping of `T::ValidatorId` to the
* number of blocks authored by the given authority.
**/
authoredBlocks: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<u32>, SessionIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
authoredBlocks: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<u32>> & QueryableStorageEntry<ApiType>;
};
offences: {
[index: string]: QueryableStorageEntry<ApiType>;
@@ -659,7 +660,7 @@ declare module '@polkadot/api/types/storage' {
/**
* A vector of reports of the same kind that happened at the same time slot.
**/
concurrentReportsIndex: AugmentedQueryDoubleMap<ApiType, (key1: Kind | string | Uint8Array, key2: OpaqueTimeSlot | string | Uint8Array) => Observable<Vec<ReportIdOf>>, Kind | string | Uint8Array> & QueryableStorageEntry<ApiType>;
concurrentReportsIndex: AugmentedQueryDoubleMap<ApiType, (key1: Kind | string | Uint8Array, key2: OpaqueTimeSlot | string | Uint8Array) => Observable<Vec<ReportIdOf>>> & QueryableStorageEntry<ApiType>;
/**
* Enumerates all reports of a kind along with the time they happened.
* All reports are sorted by the time of offence.
@@ -754,7 +755,7 @@ declare module '@polkadot/api/types/storage' {
/**
* Double map from Candidate -> Voter -> (Maybe) Vote.
**/
votes: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<SocietyVote>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
votes: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<SocietyVote>>> & QueryableStorageEntry<ApiType>;
/**
* The defending member currently being challenged.
**/
@@ -779,7 +780,7 @@ declare module '@polkadot/api/types/storage' {
* First account is the account to be recovered, and the second account
* is the user trying to recover the account.
**/
activeRecoveries: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ActiveRecovery>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
activeRecoveries: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ActiveRecovery>>> & QueryableStorageEntry<ApiType>;
/**
* The final list of recovered accounts.
* Map from the recovered account to the user who can access it.
@@ -794,4 +795,8 @@ declare module '@polkadot/api/types/storage' {
vesting: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<VestingInfo>>> & QueryableStorageEntry<ApiType>;
};
}
export interface QueryableStorage<ApiType extends ApiTypes> extends AugmentedQueries<ApiType> {
[index: string]: QueryableModuleStorage<ApiType>;
}
}
@@ -1,13 +1,14 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { AnyNumber, Codec, IExtrinsic } from '@polkadot/types/types';
import { Option, Vec } from '@polkadot/types/codec';
import { Bytes, H256, StorageData, StorageKey, Text, bool, u32, u64 } from '@polkadot/types/primitive';
import { Bytes, StorageKey, Text, bool, u32, u64 } from '@polkadot/types/primitive';
import { Metadata } from '@polkadot/types';
import { AccountId, BlockNumber, Extrinsic, Hash, Header, Index, SignedBlock } from '@polkadot/types/interfaces/runtime';
import { ContractCallRequest, ContractExecResult } from '@polkadot/types/interfaces/contracts';
import { Extrinsic } from '@polkadot/types/interfaces/extrinsics';
import { BlockHash, ChainProperties, ExtrinsicOrHash, ExtrinsicStatus, Health, NetworkState, PeerInfo, RpcMethods, RuntimeDispatchInfo, RuntimeVersion, StorageChangeSet } from '@polkadot/types/interfaces/rpc';
import { AccountId, BlockNumber, H256, Hash, Header, Index, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
import { Observable } from 'rxjs';
declare module '@polkadot/rpc-core/types.jsonrpc' {
@@ -69,6 +70,10 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
* Retrieves the header for a specific block
**/
getHeader(hash?: BlockHash | string | Uint8Array): Observable<Header>;
/**
* Retrieves the newest header via subscription
**/
subscribeAllHeads(): Observable<Header>;
/**
* Retrieves the best finalized header via subscription
**/
@@ -1,22 +1,23 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { AnyNumber, ITuple } from '@polkadot/types/types';
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
import { Bytes, Data, IdentityFields, bool, u16, u32, u64 } from '@polkadot/types/primitive';
import { AccountId, AccountIndex, Address, Balance, BalanceOf, BlockNumber, Call, ChangesTrieConfiguration, Hash, Header, KeyValue, LookupSource, Moment, Signature } from '@polkadot/types/interfaces/runtime';
import { Compact, Option, U8aFixed, Vec } from '@polkadot/types/codec';
import { Bytes, Data, bool, u16, u32, u64 } from '@polkadot/types/primitive';
import { MemberCount, ProposalIndex } from '@polkadot/types/interfaces/collective';
import { CodeHash, Gas, Schedule } from '@polkadot/types/interfaces/contracts';
import { Conviction, PropIndex, Proposal, ReferendumIndex } from '@polkadot/types/interfaces/democracy';
import { Vote } from '@polkadot/types/interfaces/elections';
import { IdentityInfo, IdentityJudgement, RegistrarIndex } from '@polkadot/types/interfaces/identity';
import { Signature } from '@polkadot/types/interfaces/extrinsics';
import { IdentityFields, IdentityInfo, IdentityJudgement, RegistrarIndex } from '@polkadot/types/interfaces/identity';
import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
import { AccountId, AccountIndex, Address, Balance, BalanceOf, BlockNumber, Call, ChangesTrieConfiguration, Hash, Header, KeyValue, LookupSource, Moment } from '@polkadot/types/interfaces/runtime';
import { Keys } from '@polkadot/types/interfaces/session';
import { SocietyJudgement } from '@polkadot/types/interfaces/society';
import { EraIndex, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
import { Key } from '@polkadot/types/interfaces/system';
import { Timepoint } from '@polkadot/types/interfaces/utility';
import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
import { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';
declare module '@polkadot/api/types/submittable' {
export interface AugmentedSubmittables<ApiType> {
@@ -151,7 +152,7 @@ declare module '@polkadot/api/types/submittable' {
* `MultisigDepositBase + threshold * MultisigDepositFactor`.
* # </weight>
**/
approveAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], maybeTimepoint: Option<Timepoint> | null | object | string | Uint8Array, callHash: Raw | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
approveAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], maybeTimepoint: Option<Timepoint> | null | object | string | Uint8Array, callHash: U8aFixed | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously
* for this operation will be unreserved on success.
@@ -173,7 +174,7 @@ declare module '@polkadot/api/types/submittable' {
* - Storage: removes one item.
* # </weight>
**/
cancelAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], timepoint: Timepoint | { height?: any; index?: any } | string | Uint8Array, callHash: Raw | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
cancelAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], timepoint: Timepoint | { height?: any; index?: any } | string | Uint8Array, callHash: U8aFixed | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
};
timestamp: {
[index: string]: SubmittableExtrinsicFunction<ApiType>;
@@ -1621,4 +1622,9 @@ declare module '@polkadot/api/types/submittable' {
vestOther: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
};
}
export interface SubmittableExtrinsics<ApiType extends ApiTypes> extends AugmentedSubmittables<ApiType> {
(extrinsic: Uint8Array | string): SubmittableExtrinsic<ApiType>;
[index: string]: SubmittableModuleExtrinsics<ApiType>;
}
}
+43 -12
View File
@@ -4,7 +4,6 @@
import { Constants, Storage } from '@polkadot/metadata/Decorated/types';
import { RpcInterface } from '@polkadot/rpc-core/types';
import { InterfaceRegistry } from '@polkadot/types/interfaceRegistry';
import { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { AnyFunction, CallFunction, Codec, CodecArg as Arg, ITuple, InterfaceTypes, ModulesWithCalls, Registry, RegistryTypes } from '@polkadot/types/types';
import { SubmittableExtrinsic } from '../submittable/types';
@@ -14,17 +13,19 @@ import BN from 'bn.js';
import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import decorateDerive, { ExactDerive } from '@polkadot/api-derive';
import DecoratedMeta from '@polkadot/metadata/Decorated';
import getHasher from '@polkadot/metadata/Decorated/storage/fromMetadata/getHasher';
import RpcCore from '@polkadot/rpc-core';
import { WsProvider } from '@polkadot/rpc-provider';
import { Metadata, Null, Option, TypeRegistry, u64, Vec } from '@polkadot/types';
import { Metadata, Null, Option, Text, TypeRegistry, u64, Vec } from '@polkadot/types';
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/primitive/Extrinsic/constants';
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
import StorageKey, { StorageEntry } from '@polkadot/types/primitive/StorageKey';
import { assert, compactStripLength, isNull, isUndefined, u8aConcat, u8aToHex } from '@polkadot/util';
import { createSubmittable } from '../submittable';
import { decorateSections, DeriveAllSections } from '../util/decorate';
import augmentObject from '../util/augmentObject';
import Events from './Events';
interface MetaDecoration {
@@ -43,11 +44,11 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
// HACK Use BN import so decorateDerive works... yes, wtf.
protected __phantom = new BN(0);
protected _consts?: Constants;
protected _consts: Constants = {} as Constants;
protected _derive?: ReturnType<Decorate<ApiType>['decorateDerive']>;
protected _extrinsics?: SubmittableExtrinsics<ApiType>;
protected _extrinsics: SubmittableExtrinsics<ApiType> = {} as SubmittableExtrinsics<ApiType>;
protected _extrinsicType: number = EXTRINSIC_DEFAULT_VERSION;
@@ -59,7 +60,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
protected readonly _options: ApiOptions;
protected _query?: QueryableStorage<ApiType>;
protected _query: QueryableStorage<ApiType> = {} as QueryableStorage<ApiType>;
protected _queryMulti?: QueryableStorageMulti<ApiType>;
@@ -67,11 +68,17 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
protected _rpcCore: RpcCore;
protected _runtimeChain?: Text;
protected _runtimeMetadata?: Metadata;
protected _runtimeVersion?: RuntimeVersion;
protected _rx: Partial<ApiInterfaceRx> = {};
protected _rx: ApiInterfaceRx = {
consts: {} as Constants,
query: {} as QueryableStorage<'rxjs'>,
tx: {} as SubmittableExtrinsics<'rxjs'>
} as ApiInterfaceRx;
protected _type: ApiTypes;
@@ -129,9 +136,19 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
this._rx.registry = this.registry;
}
public abstract createType <K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K];
/**
* @description Creates an instance of a type as registered
*/
public createType <K extends keyof InterfaceTypes> (type: K, ...params: any[]): InterfaceTypes[K] {
return this.registry.createType(type, ...params);
}
public abstract registerTypes (types?: RegistryTypes): void;
/**
* @description Register additional user-defined of chain-specific types in the type registry
*/
public registerTypes (types?: RegistryTypes): void {
types && this.registry.register(types);
}
/**
* @returns `true` if the API operates with subscriptions
@@ -140,6 +157,20 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
return this._rpcCore.provider.hasSubscriptions;
}
public injectMetadata (metadata: Metadata, fromEmpty?: boolean): void {
const decoratedMeta = new DecoratedMeta(this.registry, metadata);
// this API
augmentObject('tx', this.decorateExtrinsics(decoratedMeta.tx, this.decorateMethod), this._extrinsics, fromEmpty);
augmentObject('query', this.decorateStorage(decoratedMeta.query, this.decorateMethod), this._query, fromEmpty);
augmentObject('consts', decoratedMeta.consts, this._consts, fromEmpty);
// rx
augmentObject('', this.decorateExtrinsics(decoratedMeta.tx, this.rxDecorateMethod), this._rx.tx, fromEmpty);
augmentObject('', this.decorateStorage(decoratedMeta.query, this.rxDecorateMethod), this._rx.query, fromEmpty);
augmentObject('', decoratedMeta.consts, this._rx.consts, fromEmpty);
}
private decorateFunctionMeta (input: MetaDecoration, output: MetaDecoration): MetaDecoration {
output.meta = input.meta;
output.method = input.method;
@@ -219,7 +250,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
}
protected decorateExtrinsics<ApiType extends ApiTypes> (extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
const creator = createSubmittable(this._type, this._rx as ApiInterfaceRx, decorateMethod);
const creator = createSubmittable(this._type, this._rx, decorateMethod);
return Object.entries(extrinsics).reduce((out, [name, section]): SubmittableExtrinsics<ApiType> => {
out[name] = Object.entries(section).reduce((out, [name, method]): SubmittableModuleExtrinsics<ApiType> => {
@@ -411,13 +442,13 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
protected decorateDeriveRx (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<'rxjs', ExactDerive> {
// Pull in derive from api-derive
const derive = decorateDerive(this._rx as ApiInterfaceRx, this._options.derives);
const derive = decorateDerive(this._rx, this._options.derives);
return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod);
}
protected decorateDerive (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive> {
return decorateSections<ApiType, ExactDerive>(this._rx.derive as DeriveAllSections<'rxjs', ExactDerive>, decorateMethod);
return decorateSections<ApiType, ExactDerive>(this._rx.derive, decorateMethod);
}
/**
+5 -5
View File
@@ -7,10 +7,10 @@ import { ApiInterfaceEvents } from '../types';
import EventEmitter from 'eventemitter3';
export default class Events {
private _eventemitter = new EventEmitter();
#eventemitter = new EventEmitter();
protected emit (type: ApiInterfaceEvents, ...args: any[]): boolean {
return this._eventemitter.emit(type, ...args);
return this.#eventemitter.emit(type, ...args);
}
/**
@@ -33,7 +33,7 @@ export default class Events {
* ```
*/
public on (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
this._eventemitter.on(type, handler);
this.#eventemitter.on(type, handler);
return this;
}
@@ -60,7 +60,7 @@ export default class Events {
* ```
*/
public off (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
this._eventemitter.removeListener(type, handler);
this.#eventemitter.removeListener(type, handler);
return this;
}
@@ -85,7 +85,7 @@ export default class Events {
* ```
*/
public once (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
this._eventemitter.once(type, handler);
this.#eventemitter.once(type, handler);
return this;
}
+88 -46
View File
@@ -2,31 +2,33 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { SignedBlock } from '@polkadot/types/interfaces';
import { SignedBlock, RuntimeVersion } from '@polkadot/types/interfaces';
import { ApiBase, ApiOptions, ApiTypes, DecorateMethod } from '../types';
import DecoratedMeta from '@polkadot/metadata/Decorated';
import { Metadata, u32 as U32 } from '@polkadot/types';
import { getChainTypes, getMetadataTypes } from '@polkadot/types/known';
import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/primitive/Extrinsic/Extrinsic';
import { Subscription, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Metadata, Text } from '@polkadot/types';
import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/extrinsic/Extrinsic';
import { getMetadataTypes, getSpecTypes, getUserTypes } from '@polkadot/types/known';
import { logger } from '@polkadot/util';
import { cryptoWaitReady, setSS58Format } from '@polkadot/util-crypto';
import addressDefaults from '@polkadot/util-crypto/address/defaults';
import { cryptoWaitReady } from '@polkadot/util-crypto';
import Decorate from './Decorate';
const KEEPALIVE_INTERVAL = 15000;
const l = logger('api/decorator');
const l = logger('api/init');
export default abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
private _healthTimer: NodeJS.Timeout | null = null;
#healthTimer: NodeJS.Timeout | null = null;
#updateSub?: Subscription;
constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
super(options, type, decorateMethod);
if (!this.hasSubscriptions) {
console.warn('Api will be available in a limited mode since the provider does not support subscriptions');
l.warn('Api will be available in a limited mode since the provider does not support subscriptions');
}
// We only register the types (global) if this is not a cloned instance.
@@ -42,28 +44,43 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
this._rx.queryMulti = this.decorateMulti(this.rxDecorateMethod);
this._rx.signer = options.signer;
this._rpcCore.provider.on('disconnected', this._onProviderDisconnect);
this._rpcCore.provider.on('error', this._onProviderError);
this._rpcCore.provider.on('connected', this._onProviderConnect);
this._rpcCore.provider.on('disconnected', this.#onProviderDisconnect);
this._rpcCore.provider.on('error', this.#onProviderError);
this._rpcCore.provider.on('connected', this.#onProviderConnect);
// If the provider was instantiated earlier, and has already emitted a
// 'connected' event, then the `on('connected')` won't fire anymore. To
// cater for this case, we call manually `this._onProviderConnect`.
if (this._rpcCore.provider.isConnected()) {
this._onProviderConnect();
this.#onProviderConnect();
}
}
protected async loadMeta (): Promise<boolean> {
const genesisHash = await this._rpcCore.chain.getBlockHash(0).toPromise();
// on re-connection to the same chain, we don't want to re-do everything from chain again
if (this._isReady && !this._options.source && genesisHash.eq(this._genesisHash)) {
return true;
}
if (this._genesisHash) {
l.warn('Connection to new genesis detected, re-initializing');
}
this._genesisHash = genesisHash;
if (this.#updateSub) {
this.#updateSub.unsubscribe();
}
const { metadata = {} } = this._options;
// only load from on-chain if we are not a clone (default path), alternatively
// just use the values from the source instance provided
if (!this._options.source || !this._options.source._isReady) {
this._runtimeMetadata = await this.metaFromChain(metadata);
} else {
this._runtimeMetadata = await this.metaFromSource(this._options.source);
}
this._runtimeMetadata = this._options.source?._isReady
? await this.metaFromSource(this._options.source)
: await this.metaFromChain(metadata);
return this.initFromMeta(this._runtimeMetadata);
}
@@ -73,6 +90,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
this._extrinsicType = source.extrinsicVersion;
this._runtimeVersion = source.runtimeVersion;
this._genesisHash = source.genesisHash;
this.registry.setChainProperties(source.registry.getChainProperties());
const methods: string[] = [];
@@ -89,34 +107,64 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
return source.runtimeMetadata;
}
// subscribe to metadata updates, inject the types on changes
private subscribeUpdates (): void {
if (this.#updateSub) {
return;
}
this.#updateSub = this._rpcCore.state.subscribeRuntimeVersion().pipe(
switchMap((version: RuntimeVersion) =>
combineLatest(
of(version),
this._rpcCore.state.getMetadata()
)
),
map(([version, metadata]: [RuntimeVersion, Metadata]): boolean => {
if (this._runtimeVersion?.specVersion.eq(version.specVersion)) {
return false;
}
l.log(`Runtime version updated to ${version.specVersion}`);
this._runtimeMetadata = metadata;
this._runtimeVersion = version;
this.registerTypes(getSpecTypes(this._runtimeChain as Text, version));
this.injectMetadata(metadata, false);
return true;
})
).subscribe();
}
private async metaFromChain (optMetadata: Record<string, string>): Promise<Metadata> {
const { typesChain, typesSpec } = this._options;
const [genesisHash, runtimeVersion, chain, chainProps] = await Promise.all([
this._rpcCore.chain.getBlockHash(0).toPromise(),
const [runtimeVersion, chain, chainProps] = await Promise.all([
this._rpcCore.state.getRuntimeVersion().toPromise(),
this._rpcCore.system.chain().toPromise(),
this._rpcCore.system.properties().toPromise()
]);
// based on the node spec & chain, inject specific type overrides
this.registerTypes(getChainTypes(chain, runtimeVersion, typesChain, typesSpec));
// set our chain version & genesisHash as returned
this._runtimeChain = chain;
this._runtimeVersion = runtimeVersion;
// do the setup for the specific chain
this.registry.setChainProperties(chainProps);
this.registerTypes(getSpecTypes(chain, runtimeVersion));
this.registerTypes(getUserTypes(chain, runtimeVersion, typesChain, typesSpec));
this.subscribeUpdates();
// filter the RPC methods (this does an rpc-methods call)
await this.filterRpc();
// retrieve metadata, either from chain or as pass-in via options
const metadataKey = `${genesisHash}-${runtimeVersion.specVersion}`;
const metadataKey = `${this._genesisHash}-${runtimeVersion.specVersion}`;
const metadata = metadataKey in optMetadata
? new Metadata(this.registry, optMetadata[metadataKey])
: await this._rpcCore.state.getMetadata().toPromise();
// set our chain version & genesisHash as returned
this._genesisHash = genesisHash;
this._runtimeVersion = runtimeVersion;
// set the global ss58Format as detected by the chain
setSS58Format(chainProps.ss58Format.unwrapOr(new U32(this.registry, addressDefaults.prefix)).toNumber());
// get unique types & validate
metadata.getUniqTypes(false);
@@ -127,7 +175,6 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
// inject types based on metadata, if applicable
this.registerTypes(getMetadataTypes(metadata.version));
const decoratedMeta = new DecoratedMeta(this.registry, metadata);
const metaExtrinsic = metadata.asLatest.extrinsic;
// only inject if we are not a clone (global init)
@@ -141,16 +188,11 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
this._extrinsicType = firstTx ? firstTx.type : LATEST_EXTRINSIC_VERSION;
}
this._extrinsics = this.decorateExtrinsics(decoratedMeta.tx, this.decorateMethod);
this._query = this.decorateStorage(decoratedMeta.query, this.decorateMethod);
this._consts = decoratedMeta.consts;
this._rx.extrinsicType = this._extrinsicType;
this._rx.genesisHash = this._genesisHash;
this._rx.runtimeVersion = this._runtimeVersion;
this._rx.tx = this.decorateExtrinsics(decoratedMeta.tx, this.rxDecorateMethod);
this._rx.query = this.decorateStorage(decoratedMeta.query, this.rxDecorateMethod);
this._rx.consts = decoratedMeta.consts;
this.injectMetadata(metadata, true);
// derive is last, since it uses the decorated rx
this._rx.derive = this.decorateDeriveRx(this.rxDecorateMethod);
@@ -159,7 +201,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
return true;
}
private _onProviderConnect = async (): Promise<void> => {
#onProviderConnect = async (): Promise<void> => {
this.emit('connected');
this._isConnected.next(true);
@@ -175,7 +217,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
this.emit('ready', this);
}
this._healthTimer = setInterval((): void => {
this.#healthTimer = setInterval((): void => {
this._rpcCore.system.health().toPromise().catch((): void => {
// ignore
});
@@ -189,17 +231,17 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
}
}
private _onProviderDisconnect = (): void => {
#onProviderDisconnect = (): void => {
this.emit('disconnected');
this._isConnected.next(false);
if (this._healthTimer) {
clearInterval(this._healthTimer);
this._healthTimer = null;
if (this.#healthTimer) {
clearInterval(this.#healthTimer);
this.#healthTimer = null;
}
};
private _onProviderError = (error: Error): void => {
#onProviderError = (error: Error): void => {
this.emit('error', error);
};
}
+15 -24
View File
@@ -5,11 +5,10 @@
import { Constants } from '@polkadot/metadata/Decorated/types';
import { RpcInterface } from '@polkadot/rpc-core/types';
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { InterfaceRegistry } from '@polkadot/types/interfaceRegistry';
import { CallFunction, InterfaceTypes, RegistryError, RegistryTypes, SignerPayloadRawBase } from '@polkadot/types/types';
import { CallFunction, RegistryError, SignerPayloadRawBase } from '@polkadot/types/types';
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecorateMethod, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics, Signer } from '../types';
import { Metadata, createType } from '@polkadot/types';
import { Metadata } from '@polkadot/types';
import { assert, isString, isUndefined, u8aToHex, u8aToU8a } from '@polkadot/util';
import Init from './Init';
@@ -22,15 +21,21 @@ interface SignerRawOptions {
signer?: Signer;
}
let pkgJson: { name: string; version: string };
try {
pkgJson = require('../package.json');
} catch (error) {
// development environment
pkgJson = { name: '@polkadot/api', version: '-' };
interface PkgJson {
name: string;
version: string;
}
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
import('../package.json')
.then((_pkgJson: any): void => {
pkgJson = _pkgJson;
})
.catch((): void => {
// ignore
});
function assertResult<T> (value: T | undefined): T {
assert(!isUndefined(value), 'Api needs to be initialized before using, listen on \'ready\'');
@@ -228,13 +233,6 @@ export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<Api
return assertResult(this._extrinsics);
}
/**
* @description Creates an instance of a type as registered
*/
public createType = <K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K] => {
return createType(this.registry, type, ...params);
}
/**
* @description Disconnect from the underlying provider, halting all network traffic
*/
@@ -256,13 +254,6 @@ export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<Api
return this.registry.findMetaError(u8aToU8a(errorIndex));
}
/**
* @description Register additional user-defined of chain-specific types in the type registry
*/
public registerTypes (types?: RegistryTypes): void {
types && this.registry.register(types);
}
/**
* @description Set an external signer which will be used to sign extrinsic when account passed in is not KeyringPair
*/
+10 -9
View File
@@ -10,7 +10,7 @@ import { IExtrinsic, IMethod } from '@polkadot/types/types';
import { ApiPromise } from '@polkadot/api';
import { HeaderExtended } from '@polkadot/api-derive';
import testKeyring, { TestKeyringMap } from '@polkadot/keyring/testingPairs';
import { createType, createTypeUnsafe, TypeRegistry } from '@polkadot/types/codec';
import { createTypeUnsafe, TypeRegistry } from '@polkadot/types';
import { SubmittableResult } from './';
@@ -75,21 +75,22 @@ async function rpc (api: ApiPromise): Promise<void> {
});
}
function types (): void {
function types (api: ApiPromise): void {
// check correct types with `createType`
const balance = createType(registry, 'Balance', 2);
const gas = createType(registry, 'Gas', 2);
const compact = createType(registry, 'Compact<u32>', 2);
// const random = createType(registry, 'RandomType', 2); // This one should deliberately show a TS error
const balance = registry.createType('Balance', 2);
const gas = registry.createType('Gas', 2);
const compact = registry.createType('Compact<u32>', 2);
// const random = registry.createType('RandomType', 2); // This one should deliberately show a TS error
const gasUnsafe = createTypeUnsafe(registry, 'Gas', [2]);
const overriddenUnsafe = createTypeUnsafe<Header>(registry, 'Gas', [2]);
console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe);
console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe, api.createType('AccountData'));
}
async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
const transfer = api.tx.balances.transfer(keyring.bob.address, 12345);
// transfer, also allows for BigInt inputs here
const transfer = api.tx.balances.transfer(keyring.bob.address, 123_456_789n);
console.log('transfer as Call', transfer as IMethod);
console.log('transfer as Extrinsic', transfer as IExtrinsic);
@@ -138,7 +139,7 @@ async function main (): Promise<void> {
derive(api);
query(api, keyring);
rpc(api);
types();
types(api);
tx(api, keyring);
}
+3 -7
View File
@@ -4,13 +4,9 @@
import { detectPackage } from '@polkadot/util';
// eslint-disable-next-line no-useless-catch
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
detectPackage(require('./package.json'), __dirname);
} catch (error) {
throw error;
}
// FIXME This really should be `import(...).then(...)`, but need to check rejections
// eslint-disable-next-line @typescript-eslint/no-var-requires
detectPackage(require('./package.json'), __dirname);
export { Keyring } from '@polkadot/keyring';
export { WsProvider } from '@polkadot/rpc-provider';
+6 -8
View File
@@ -7,7 +7,7 @@ import { ApiOptions } from '../types';
import createPair from '@polkadot/keyring/pair';
import testKeyring from '@polkadot/keyring/testing';
import Mock from '@polkadot/rpc-provider/mock/index';
import { createType, TypeRegistry } from '@polkadot/types';
import { TypeRegistry } from '@polkadot/types';
import { hexToU8a } from '@polkadot/util';
import { SingleAccountSigner } from '../../test/util';
@@ -17,7 +17,8 @@ describe('ApiPromise', (): void => {
const registry = new TypeRegistry();
const keyring = testKeyring({ type: 'ed25519' });
const aliceEd = keyring.addPair(
createPair('ed25519', {
// eslint-disable-next-line @typescript-eslint/unbound-method
createPair({ toSS58: keyring.encodeAddress, type: 'ed25519' }, {
secretKey: hexToU8a('0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a7690911588dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee'),
publicKey: hexToU8a('0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee')
})
@@ -32,7 +33,7 @@ describe('ApiPromise', (): void => {
describe('initialization', (): void => {
it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async (): Promise<void> => {
const rpcData = await provider.send('state_getMetadata', []);
const genesisHash = createType(registry, 'Hash', await provider.send('chain_getBlockHash', [])).toHex();
const genesisHash = registry.createType('Hash', await provider.send('chain_getBlockHash', [])).toHex();
const specVersion = 0;
const metadata: any = {};
const key = `${genesisHash}-${specVersion}`;
@@ -120,15 +121,12 @@ describe('ApiPromise', (): void => {
const signer = new SingleAccountSigner(registry, aliceEd);
const api = await ApiPromise.create({ provider, registry, signer });
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 12345);
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 321_564_789_876_512_345n);
await transfer.signAsync(aliceEd.address, {});
expect(transfer.signature.toHex()).toEqual(
// v1 extrinsic
// '0x6b9ccc95afbd4e916d30c65c720f4f7b70a77db545735b48a763844aa5210e695aa346686bad1224af77d00bcfbf6fc8d2c216a60731027835d5a414186a2607'
// v4 extrinsic
'0x0716cbdc3b649dad8741238bcc8e4336f859c518cf2b17a3427b2f5d0b8a79cf518da71b9ac71d92c517342e0978f297f5e05362babf5987d3f1c5ba3314af08'
'0x62bfcd07a9f50ba32ed9e2c41ca11267ac62a24c95949e25efdccc4989d48573f84754dbbaa1d0937ceb888ad8a2cf71daced1545a839d9d6cceac33a5771401'
);
});
});
+3 -3
View File
@@ -173,7 +173,7 @@ export function decorateMethod<Method extends AnyFunction> (method: Method, opti
* ```
*/
export default class ApiPromise extends ApiBase<'promise'> {
private _isReadyPromise: Promise<ApiPromise>;
#isReadyPromise: Promise<ApiPromise>;
/**
* @description Creates an ApiPromise instance using the supplied provider. Returns an Promise containing the actual Api instance.
@@ -216,7 +216,7 @@ export default class ApiPromise extends ApiBase<'promise'> {
constructor (options?: ApiOptions) {
super(options, 'promise', decorateMethod);
this._isReadyPromise = new Promise((resolve, reject): void => {
this.#isReadyPromise = new Promise((resolve, reject): void => {
super.once('ready', (): void => {
resolve(this);
});
@@ -230,7 +230,7 @@ export default class ApiPromise extends ApiBase<'promise'> {
* @description Promise that returns the first time we are connected and loaded
*/
public get isReady (): Promise<ApiPromise> {
return this._isReadyPromise;
return this.#isReadyPromise;
}
/**
+21 -21
View File
@@ -13,31 +13,31 @@ export interface CombinatorFunction {
}
export default class Combinator {
protected _allHasFired = false;
#allHasFired = false;
protected _callback: CombinatorCallback;
#callback: CombinatorCallback;
protected _fired: boolean[] = [];
#fired: boolean[] = [];
protected _fns: CombinatorFunction[] = [];
#fns: CombinatorFunction[] = [];
protected _isActive = true;
#isActive = true;
protected _results: any[] = [];
#results: any[] = [];
protected _subscriptions: UnsubscribePromise[] = [];
#subscriptions: UnsubscribePromise[] = [];
constructor (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback) {
this._callback = callback;
this.#callback = callback;
// eslint-disable-next-line @typescript-eslint/require-await
this._subscriptions = fns.map(async (input, index): UnsubscribePromise => {
this.#subscriptions = fns.map(async (input, index): UnsubscribePromise => {
const [fn, ...args] = Array.isArray(input)
? input
: [input];
this._fired.push(false);
this._fns.push(fn);
this.#fired.push(false);
this.#fns.push(fn);
// Not quite 100% how to have a variable number at the front here
return (fn as Function)(...args, this.createCallback(index));
@@ -45,43 +45,43 @@ export default class Combinator {
}
protected allHasFired (): boolean {
if (!this._allHasFired) {
this._allHasFired = this._fired.filter((hasFired): boolean => !hasFired).length === 0;
if (!this.#allHasFired) {
this.#allHasFired = this.#fired.filter((hasFired): boolean => !hasFired).length === 0;
}
return this._allHasFired;
return this.#allHasFired;
}
protected createCallback (index: number): (value: any) => void {
return (value: any): void => {
this._fired[index] = true;
this._results[index] = value;
this.#fired[index] = true;
this.#results[index] = value;
this.triggerUpdate();
};
}
protected triggerUpdate (): void {
if (!this._isActive || !isFunction(this._callback) || !this.allHasFired()) {
if (!this.#isActive || !isFunction(this.#callback) || !this.allHasFired()) {
return;
}
try {
this._callback(this._results);
this.#callback(this.#results);
} catch (error) {
// swallow, we don't want the handler to trip us up
}
}
public unsubscribe (): void {
if (!this._isActive) {
if (!this.#isActive) {
return;
}
this._isActive = false;
this.#isActive = false;
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this._subscriptions.forEach(async (subscription): Promise<void> => {
this.#subscriptions.forEach(async (subscription): Promise<void> => {
try {
const unsubscribe = await subscription;
+3 -3
View File
@@ -114,7 +114,7 @@ export function decorateMethod <Method extends AnyFunction> (method: Method): Me
* ```
*/
export default class ApiRx extends ApiBase<'rxjs'> {
private _isReadyRx: Observable<ApiRx>;
#isReadyRx: Observable<ApiRx>;
/**
* @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
@@ -163,7 +163,7 @@ export default class ApiRx extends ApiBase<'rxjs'> {
constructor (options?: ApiOptions) {
super(options, 'rxjs', decorateMethod);
this._isReadyRx = from(
this.#isReadyRx = from(
// You can create an observable from an event, however my mind groks this form better
new Promise((resolve): void => {
super.on('ready', (): void => {
@@ -184,7 +184,7 @@ export default class ApiRx extends ApiBase<'rxjs'> {
* @description Observable that returns the first time we are connected and loaded
*/
public get isReady (): Observable<ApiRx> {
return this._isReadyRx;
return this.#isReadyRx;
}
/**
+13 -2
View File
@@ -3,9 +3,10 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ExtrinsicStatus, EventRecord } from '@polkadot/types/interfaces';
import { SubmittableResultImpl, SubmittableResultValue } from './types';
import { AnyJson, ISubmittableResult } from '@polkadot/types/types';
import { SubmittableResultValue } from './types';
export default class SubmittableResult implements SubmittableResultImpl {
export default class SubmittableResult implements ISubmittableResult {
public readonly events: EventRecord[];
public readonly status: ExtrinsicStatus;
@@ -48,4 +49,14 @@ export default class SubmittableResult implements SubmittableResultImpl {
event.section === section && event.method === method
);
}
/**
* @description Creates a human representation of the output
*/
public toHuman (isExtended?: boolean): AnyJson {
return {
events: this.events.map((event) => event.toHuman(isExtended)),
status: this.status.toHuman(isExtended)
};
}
}
+145 -158
View File
@@ -3,14 +3,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountData, Address, Call, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { Callback, Codec, Constructor, IKeyringPair, ITuple, Registry, SignatureOptions } from '@polkadot/types/types';
import { Address, Call, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { Callback, Codec, Constructor, IKeyringPair, Registry, SignatureOptions, ISubmittableResult } from '@polkadot/types/types';
import { ApiInterfaceRx, ApiTypes, SignerResult } from '../types';
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultImpl, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
import { Observable, combineLatest, of } from 'rxjs';
import { first, map, mapTo, mergeMap, switchMap, tap } from 'rxjs/operators';
import { createType, ClassOf } from '@polkadot/types';
import { ClassOf } from '@polkadot/types';
import { assert, isBn, isFunction, isNumber, isUndefined } from '@polkadot/util';
import { filterEvents, isKeyringPair } from '../util';
@@ -35,38 +35,32 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
const Extrinsic = ClassOf(api.registry, 'Extrinsic');
return class Submittable extends Extrinsic implements SubmittableExtrinsic<ApiType> {
private readonly _api: ApiInterfaceRx;
private readonly _decorateMethod: ApiBase<ApiType>['decorateMethod'];
private readonly _ignoreStatusCb: boolean;
readonly #ignoreStatusCb: boolean;
constructor (registry: Registry, extrinsic: Call | Uint8Array | string) {
super(registry, extrinsic, { version: api.extrinsicType });
this._api = api;
this._decorateMethod = decorateMethod;
this._ignoreStatusCb = apiType === 'rxjs';
this.#ignoreStatusCb = apiType === 'rxjs';
}
// calculate the payment info for this transaction (if signed and submitted)
public paymentInfo (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittablePaymentResult<ApiType> {
const [allOptions] = this._makeSignAndSendOptions(options);
const [allOptions] = this.#makeSignAndSendOptions(options);
const address = isKeyringPair(account) ? account.address : account.toString();
return this._decorateMethod(
return decorateMethod(
(): Observable<RuntimeDispatchInfo> =>
this._getPrelimState(address, allOptions).pipe(
this.#getPrelimState(address, allOptions).pipe(
first(),
switchMap(([nonce, header]): Observable<RuntimeDispatchInfo> => {
// setup our options (same way as in signAndSend)
const eraOptions = this._makeEraOptions(allOptions, { header, nonce });
const signOptions = this._makeSignOptions(eraOptions, {});
const eraOptions = this.#makeEraOptions(allOptions, { header, nonce });
const signOptions = this.#makeSignOptions(eraOptions, {});
// add a fake signature to the extrinsic
this.signFake(address, signOptions);
return this._api.rpc.payment.queryInfo(this.toHex());
return api.rpc.payment.queryInfo(this.toHex());
})
)
)();
@@ -74,7 +68,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
// sign a transaction, returning the this to allow chaining, i.e. .sign(...).send()
public sign (account: IKeyringPair, optionsOrNonce: Partial<SignerOptions>): this {
super.sign(account, this._makeSignOptions(this._optionsOrNonce(optionsOrNonce), {}));
super.sign(account, this.#makeSignOptions(this.#optionsOrNonce(optionsOrNonce), {}));
return this;
}
@@ -83,9 +77,9 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
//
// also supports signing through external signers
public signAsync (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
return this._decorateMethod(
return decorateMethod(
(): Observable<this> =>
this._signObservable(account, optionsOrNonce).pipe(mapTo(this))
this.#observeSign(account, optionsOrNonce).pipe(mapTo(this))
)();
}
@@ -93,23 +87,23 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
public signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
// signAndSend with a subscription, i.e. callback provided
public signAndSend (account: AddressOrPair, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
public signAndSend (account: AddressOrPair, statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
// signAndSend with options and a callback
public signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
public signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
// signAndSend implementation for all 3 cases above
public signAndSend (account: AddressOrPair, optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, optionalStatusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const [options, statusCb] = this._makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
public signAndSend (account: AddressOrPair, optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, optionalStatusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const [options, statusCb] = this.#makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
return this._decorateMethod(
return decorateMethod(
(): Observable<Codec> => (
this._signObservable(account, options).pipe(
switchMap((updateId: number | undefined): Observable<SubmittableResultImpl> | Observable<Hash> =>
this.#observeSign(account, options).pipe(
switchMap((updateId: number | undefined): Observable<ISubmittableResult> | Observable<Hash> =>
isSubscription
? this._subscribeObservable(updateId)
: this._sendObservable(updateId)
? this.#observeSubscribe(updateId)
: this.#observeSend(updateId)
)
) as Observable<Codec>) // FIXME This is wrong, SubmittableResult is _not_ a codec
)(statusCb);
@@ -119,20 +113,69 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
public send (): SubmittableResultResult<ApiType>;
// send with a status callback
public send (statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
// send implementation for both immediate Hash and statusCb variants
public send (statusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
return this._decorateMethod(
return decorateMethod(
isSubscription
? this._subscribeObservable
: this._sendObservable
? this.#observeSubscribe
: this.#observeSend
)(statusCb);
}
private _makeSignAndSendOptions (optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, statusCb?: Callback<SubmittableResultImpl>): [Partial<SignerOptions>, Callback<SubmittableResultImpl>?] {
#getPrelimState = (address: string, options: Partial<SignerOptions>): Observable<[Index, Header | null]> => {
return combineLatest([
// if we have a nonce already, don't retrieve the latest, use what is there
isUndefined(options.nonce)
? api.derive.balances.account(address).pipe(
map(({ accountNonce }): Index => accountNonce)
)
: of(this.registry.createType('Index', options.nonce)),
// if we have an era provided already or eraLength is <= 0 (immortal)
// don't get the latest block, just pass null, handle in mergeMap
(isUndefined(options.era) || (isNumber(options.era) && options.era > 0))
? api.rpc.chain.getHeader()
: of(null)
]);
}
#makeEraOptions = (options: Partial<SignerOptions>, { header, nonce }: { header: Header | null; nonce: Index }): SignatureOptions => {
if (!header) {
if (isNumber(options.era)) {
// since we have no header, it is immortal, remove any option overrides
// so we only supply the genesisHash and no era to the construction
delete options.era;
delete options.blockHash;
}
return this.#makeSignOptions(options, { nonce });
}
return this.#makeSignOptions(options, {
blockHash: header.hash,
era: this.registry.createType('ExtrinsicEra', {
current: header.number,
period: options.era || DEFAULT_MORTAL_LENGTH
}),
nonce
});
}
#makeSignOptions = (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions => {
return {
blockHash: api.genesisHash,
...options,
...extras,
genesisHash: api.genesisHash,
runtimeVersion: api.runtimeVersion,
version: api.extrinsicType
} as SignatureOptions;
}
#makeSignAndSendOptions = (optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, statusCb?: Callback<ISubmittableResult>): [Partial<SignerOptions>, Callback<ISubmittableResult>?] => {
let options: Partial<SignerOptions> = {};
if (isFunction(optionsOrStatus)) {
@@ -144,32 +187,85 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
return [options, statusCb];
}
private _signObservable (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): Observable<number | undefined> {
#observeSign = (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): Observable<number | undefined> => {
const address = isKeyringPair(account) ? account.address : account.toString();
const options = this._optionsOrNonce(optionsOrNonce);
const options = this.#optionsOrNonce(optionsOrNonce);
let updateId: number | undefined;
return this._getPrelimState(address, options).pipe(
return this.#getPrelimState(address, options).pipe(
first(),
mergeMap(async ([nonce, header]): Promise<void> => {
const eraOptions = this._makeEraOptions(options, { header, nonce });
const eraOptions = this.#makeEraOptions(options, { header, nonce });
if (isKeyringPair(account)) {
this.sign(account, eraOptions);
} else {
updateId = await this._signViaSigner(address, eraOptions, header);
updateId = await this.#signViaSigner(address, eraOptions, header);
}
}),
mapTo(updateId)
);
}
private async _signViaSigner (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> {
const signer = options.signer || this._api.signer;
#observeStatus = (status: ExtrinsicStatus): Observable<ISubmittableResult> => {
if (!status.isFinalized && !status.isInBlock) {
return of(new SubmittableResult({ status }));
}
const blockHash = status.isInBlock
? status.asInBlock
: status.asFinalized;
return combineLatest([
api.rpc.chain.getBlock(blockHash),
api.query.system.events.at(blockHash)
]).pipe(
map(([signedBlock, allEvents]): ISubmittableResult =>
new SubmittableResult({
events: filterEvents(this.hash, signedBlock, allEvents, status),
status
})
)
);
}
#observeSend = (updateId = -1): Observable<Hash> => {
return api.rpc.author
.submitExtrinsic(this)
.pipe(
tap((hash): void => {
this.#updateSigner(updateId, hash);
})
);
}
#observeSubscribe = (updateId = -1): Observable<ISubmittableResult> => {
return api.rpc.author
.submitAndWatchExtrinsic(this)
.pipe(
switchMap((status): Observable<ISubmittableResult> =>
this.#observeStatus(status)
),
tap((status): void => {
this.#updateSigner(updateId, status);
})
);
}
// NOTE here we actually override nonce if it was specified (backwards compat for
// the previous signature - don't let userspace break, but allow then time to upgrade)
#optionsOrNonce = (optionsOrNonce: Partial<SignerOptions>): Partial<SignerOptions> => {
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
? { nonce: optionsOrNonce }
: optionsOrNonce;
}
#signViaSigner = async (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> => {
const signer = options.signer || api.signer;
assert(signer, 'No signer specified, either via api.setSigner or via sign options');
const payload = createType(this.registry, 'SignerPayload', {
const payload = this.registry.createType('SignerPayload', {
...options,
address,
method: this.method,
@@ -193,119 +289,10 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
return result.id;
}
private _makeSignOptions (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions {
return {
blockHash: this._api.genesisHash,
...options,
...extras,
genesisHash: this._api.genesisHash,
runtimeVersion: this._api.runtimeVersion,
version: this._api.extrinsicType
} as SignatureOptions;
}
private _makeEraOptions (options: Partial<SignerOptions>, { header, nonce }: { header: Header | null; nonce: Index }): SignatureOptions {
if (!header) {
if (isNumber(options.era)) {
// since we have no header, it is immortal, remove any option overrides
// so we only supply the genesisHash and no era to the construction
delete options.era;
delete options.blockHash;
}
return this._makeSignOptions(options, { nonce });
#updateSigner = (updateId: number, status: Hash | ISubmittableResult): void => {
if ((updateId !== -1) && api.signer && api.signer.update) {
api.signer.update(updateId, status);
}
return this._makeSignOptions(options, {
blockHash: header.hash,
era: createType(this.registry, 'ExtrinsicEra', {
current: header.number,
period: options.era || DEFAULT_MORTAL_LENGTH
}),
nonce
});
}
private _getPrelimState (address: string, options: Partial<SignerOptions>): Observable<[Index, Header | null]> {
return combineLatest([
// if we have a nonce already, don't retrieve the latest, use what is there
isUndefined(options.nonce)
// FIXME This apparently is having issues on latest Kusama for nonce retrieval,
// hence we are using the accountNonce only
// ? this._api.rpc.account.nextIndex
// ? this._api.rpc.account.nextIndex(address)
// : this._api.query.system.accountNonce(address)
? this._api.query.system.account
? this._api.query.system.account<ITuple<[Index, AccountData]>>(address).pipe(
map(([nonce]): Index => nonce)
)
: this._api.query.system.accountNonce<Index>(address)
: of(createType(this.registry, 'Index', options.nonce)),
// if we have an era provided already or eraLength is <= 0 (immortal)
// don't get the latest block, just pass null, handle in mergeMap
(isUndefined(options.era) || (isNumber(options.era) && options.era > 0))
? this._api.rpc.chain.getHeader()
: of(null)
]);
}
private _updateSigner (updateId: number, status: Hash | SubmittableResultImpl): void {
if ((updateId !== -1) && this._api.signer && this._api.signer.update) {
this._api.signer.update(updateId, status);
}
}
private _statusObservable (status: ExtrinsicStatus): Observable<SubmittableResultImpl> {
if (!status.isFinalized && !status.isInBlock) {
return of(new SubmittableResult({ status }));
}
const blockHash = status.isInBlock
? status.asInBlock
: status.asFinalized;
return combineLatest([
this._api.rpc.chain.getBlock(blockHash),
this._api.query.system.events.at(blockHash)
]).pipe(
map(([signedBlock, allEvents]): SubmittableResultImpl =>
new SubmittableResult({
events: filterEvents(this.hash, signedBlock, allEvents),
status
})
)
);
}
private _sendObservable = (updateId = -1): Observable<Hash> => {
return this._api.rpc.author
.submitExtrinsic(this)
.pipe(
tap((hash): void => {
this._updateSigner(updateId, hash);
})
);
}
private _subscribeObservable = (updateId = -1): Observable<SubmittableResultImpl> => {
return this._api.rpc.author
.submitAndWatchExtrinsic(this)
.pipe(
switchMap((status): Observable<SubmittableResultImpl> =>
this._statusObservable(status)
),
tap((status): void => {
this._updateSigner(updateId, status);
})
);
}
// NOTE here we actually override nonce if it was specified (backwards compat for
// the previous signature - don't let userspace break, but allow then time to upgrade)
private _optionsOrNonce = (optionsOrNonce: Partial<SignerOptions>): Partial<SignerOptions> => {
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
? { nonce: optionsOrNonce }
: optionsOrNonce;
}
};
}
+7 -19
View File
@@ -3,23 +3,11 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Address, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions } from '@polkadot/types/types';
import { ApiTypes, Signer } from '../types';
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions, Signer, ISubmittableResult } from '@polkadot/types/types';
import { ApiTypes } from '../types';
import { Observable } from 'rxjs';
export interface SubmittableResultImpl {
readonly events: EventRecord[];
readonly status: ExtrinsicStatus;
readonly isCompleted: boolean;
readonly isError: boolean;
readonly isFinalized: boolean;
readonly isInBlock: boolean;
filterRecords (section: string, method: string): EventRecord[];
findRecord (section: string, method: string): EventRecord | undefined;
}
export interface SubmittableResultValue {
events?: EventRecord[];
status: ExtrinsicStatus;
@@ -32,12 +20,12 @@ export type SubmittablePaymentResult<ApiType extends ApiTypes> =
export type SubmittableResultResult<ApiType extends ApiTypes> =
ApiType extends 'rxjs'
? Observable<SubmittableResultImpl>
? Observable<ISubmittableResult>
: Promise<Hash>;
export type SubmittableResultSubscription<ApiType extends ApiTypes> =
ApiType extends 'rxjs'
? Observable<SubmittableResultImpl>
? Observable<ISubmittableResult>
: Promise<() => void>;
export type SubmittableThis<ApiType extends ApiTypes, THIS> =
@@ -60,7 +48,7 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrins
send(): SubmittableResultResult<ApiType>;
send(statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
send(statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
sign(account: IKeyringPair, _options: Partial<SignatureOptions>): this;
@@ -68,7 +56,7 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrins
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
signAndSend(account: AddressOrPair, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
signAndSend(account: AddressOrPair, statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
}
+6 -36
View File
@@ -2,8 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Module augmentation so that `api.{consts,query,rpc,tx}.*.*` work
import './augment';
// Augment the modules
import '@polkadot/api/augment';
import BN from 'bn.js';
import { DeriveCustom, ExactDerive } from '@polkadot/api-derive';
@@ -11,10 +11,9 @@ import { Constants } from '@polkadot/metadata/Decorated/types';
import { RpcInterface, UserRpc } from '@polkadot/rpc-core/types';
import { Metadata } from '@polkadot/types';
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { RegistryTypes, SignatureOptions, SignerPayloadJSON, SignerPayloadRaw, Registry } from '@polkadot/types/types';
import { RegistryTypes, Signer, SignerResult, SignatureOptions, Registry } from '@polkadot/types/types';
import ApiBase from '../base';
import { SubmittableResultImpl } from '../submittable/types';
import { DeriveAllSections } from '../util/decorate';
import { DecoratedRpc } from './rpc';
import { QueryableStorage, QueryableStorageMulti } from './storage';
@@ -79,11 +78,11 @@ export interface ApiInterfaceRx {
// TODO This needs to be typed correctly
derive: DeriveAllSections<'rxjs', ExactDerive>;
extrinsicType: number;
genesisHash: Hash;
genesisHash?: Hash;
hasSubscriptions: boolean;
registry: Registry;
runtimeMetadata: Metadata;
runtimeVersion: RuntimeVersion;
runtimeVersion?: RuntimeVersion;
query: QueryableStorage<'rxjs'>;
queryMulti: QueryableStorageMulti<'rxjs'>;
rpc: DecoratedRpc<'rxjs', RpcInterface>;
@@ -98,33 +97,4 @@ export interface SignerOptions extends SignatureOptions {
genesisHash: Hash;
}
export interface SignerResult {
/**
* @description The id for this request
*/
id: number;
/**
* @description The resulting signature in hex
*/
signature: string;
}
export interface Signer {
/**
* @description signs an extrinsic payload from a serialized form
*/
signPayload?: (payload: SignerPayloadJSON) => Promise<SignerResult>;
/**
* @description signs a raw payload, only the bytes data as supplied
*/
signRaw?: (raw: SignerPayloadRaw) => Promise<SignerResult>;
/**
* @description Receives an update for the extrinsic signed by a `signer.sign`
*/
update?: (id: number, status: Hash | SubmittableResultImpl) => void;
}
export { ApiBase };
export { ApiBase, Signer, SignerResult };
+3 -7
View File
@@ -15,7 +15,7 @@ export interface AugmentedQueries<ApiType extends ApiTypes> { }
export type AugmentedQuery<ApiType extends ApiTypes, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryBase<ApiType, F>
export type AugmentedQueryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction, FirstKeyType = any> = MethodResult<ApiType, F> & StorageEntryDoubleMap<ApiType, F, FirstKeyType>
export type AugmentedQueryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryDoubleMap<ApiType, F>
// This is the most generic typings we can have for a storage entry function
type GenericStorageEntryFunction = (arg1?: CodecArg, arg2?: CodecArg) => Observable<Codec>
@@ -36,8 +36,8 @@ export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunctio
multi: ApiType extends 'rxjs' ? StorageEntryObservableMulti : StorageEntryPromiseMulti;
}
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction, FirstKeyType> extends StorageEntryBase<ApiType, F> {
entries: (arg?: FirstKeyType) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> extends StorageEntryBase<ApiType, F> {
entries: (arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
}
interface StorageEntryObservableMulti {
@@ -77,7 +77,3 @@ export type QueryableStorageMulti<ApiType extends ApiTypes> =
ApiType extends 'rxjs'
? QueryableStorageMultiBase<ApiType>
: QueryableStorageMultiPromise<ApiType>;
export interface QueryableStorage<ApiType extends ApiTypes> extends AugmentedQueries<ApiType> {
[index: string]: QueryableModuleStorage<ApiType>;
}
-5
View File
@@ -19,8 +19,3 @@ export interface SubmittableExtrinsicFunction<ApiType extends ApiTypes> extends
export interface SubmittableModuleExtrinsics<ApiType extends ApiTypes> {
[index: string]: SubmittableExtrinsicFunction<ApiType>;
}
export interface SubmittableExtrinsics<ApiType extends ApiTypes> extends AugmentedSubmittables<ApiType> {
(extrinsic: Uint8Array | string): SubmittableExtrinsic<ApiType>;
[index: string]: SubmittableModuleExtrinsics<ApiType>;
}
@@ -0,0 +1,53 @@
// 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.
import augmentObject from './augmentObject';
describe('augmentObject', (): void => {
let spy: any;
beforeEach((): void => {
spy = jest.spyOn(console, 'warn');
});
afterEach((): void => {
spy.mockClear();
});
it('logs added/removed sections and methods', (): void => {
augmentObject(
'test',
{ foo: { f: 1, d: 1 }, bar: { b: 1 }, new: { z: 1 } },
{ foo: { f: 1, c: 1 }, bar: { a: 1, c: 1 }, baz: { a: 1 } }
);
expect(spy).toHaveBeenCalledWith(
expect.anything(),
expect.stringContaining('API/AUGMENT'),
'api.test: Found 1 added and 1 removed modules:\n\t added: new\n\tremoved: baz'
);
expect(spy).toHaveBeenCalledWith(
expect.anything(),
expect.stringContaining('API/AUGMENT'),
'api.test: Found 2 added and 3 removed calls:\n\t added: bar.b, foo.d\n\tremoved: bar.a, bar.c, foo.c'
);
});
it('copies sections to the dest', (): void => {
const src = { foo: { a: 1 }, bar: { b: 1 } };
expect(augmentObject('test', src, {})).toEqual(src);
});
it('adds fields to existing sections', (): void => {
const src = { foo: { a: 1 }, bar: { b: 1 } };
const dst = { foo: { b: 2 }, baz: { c: 1 } };
expect(augmentObject('test', src, dst)).toEqual({
foo: { b: 2, a: 1 },
bar: { b: 1 },
baz: { c: 1 }
});
});
});
+107
View File
@@ -0,0 +1,107 @@
// 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.
import { logger } from '@polkadot/util';
type StringsStrings = [string[], string[]];
const l = logger('api/augment');
function logLength (type: 'added' | 'removed', values: string[], and: string[] = []): string {
return values.length
? ` ${values.length} ${type}${and.length ? ' and' : ''}`
: '';
}
function logValues (type: 'added' | 'removed', values: string[]): string {
return values.length
? `\n\t${type.padStart(7)}: ${values.sort().join(', ')}`
: '';
}
// log details to console
function warn (prefix: string, type: 'calls' | 'modules', [added, removed]: StringsStrings): void {
if (added.length || removed.length) {
l.warn(`api.${prefix}: Found${logLength('added', added, removed)}${logLength('removed', removed)} ${type}:${logValues('added', added)}${logValues('removed', removed)}`);
}
}
function extractKeys (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
return [Object.keys(src), Object.keys(dst)];
}
function findSectionExcludes (a: string[], b: string[]): string[] {
return a.filter((section): boolean => !b.includes(section));
}
function extractSections (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
const [srcSections, dstSections] = extractKeys(src, dst);
return [
findSectionExcludes(srcSections, dstSections),
findSectionExcludes(dstSections, srcSections)
];
}
function findMethodExcludes (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): string[] {
const srcSections = Object.keys(src);
const dstSections = Object.keys(dst);
return dstSections
.filter((section): boolean => srcSections.includes(section))
.reduce((rmMethods: string[], section): string[] => {
const srcMethods = Object.keys(src[section]);
return rmMethods.concat(
...Object
.keys(dst[section])
.filter((method): boolean => !srcMethods.includes(method))
.map((method): string => `${section}.${method}`)
);
}, []);
}
function extractMethods (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
return [
findMethodExcludes(dst, src),
findMethodExcludes(src, dst)
];
}
/**
* Takes a decorated api section (e.g. api.tx) and augment it with the details. It does not override what is
* already available, but rather just adds new missing ites into the result object.
* @internal
*/
export default function augmentObject (prefix: string, src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>, fromEmpty = false): Record<string, Record<string, any>> {
if (fromEmpty) {
Object.keys(dst).forEach((key): void => {
delete dst[key];
});
}
if (prefix && Object.keys(dst).length) {
warn(prefix, 'modules', extractSections(src, dst));
warn(prefix, 'calls', extractMethods(src, dst));
}
return Object
.keys(src)
.reduce((newSection, sectionName): Record<string, Record<string, any>> => {
const section = src[sectionName];
newSection[sectionName] = Object
.keys(section)
.reduce((result, methodName): Record<string, any> => {
// TODO When it does match, check the actual details and warn when there are differences
if (!result[methodName]) {
result[methodName] = section[methodName];
}
return result;
}, dst[sectionName] || {});
return newSection;
}, dst);
}
+6 -5
View File
@@ -2,13 +2,11 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { EventRecord, SignedBlock } from '@polkadot/types/interfaces';
import { Raw } from '@polkadot/types';
import { EventRecord, ExtrinsicStatus, H256, SignedBlock } from '@polkadot/types/interfaces';
import l from './logging';
export default function filterEvents (extHash: Raw, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[]): EventRecord[] | undefined {
export default function filterEvents (extHash: H256, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[], status: ExtrinsicStatus): EventRecord[] | undefined {
// extrinsics to hashes
const myHash = extHash.toHex();
const allHashes = extrinsics.map((ext): string => ext.hash.toHex());
@@ -18,7 +16,10 @@ export default function filterEvents (extHash: Raw, { block: { extrinsics, heade
// if we do get the block after finalized, it _should_ be there
if (index === -1) {
l.warn(`block ${header.hash}: Unable to find extrinsic ${myHash} inside ${allHashes}`);
// only warn on filtering with isInBlock (finalization finalizes after)
if (status.isInBlock) {
l.warn(`block ${header.hash}: Unable to find extrinsic ${myHash} inside ${allHashes}`);
}
return;
}
@@ -6,7 +6,6 @@ import { Signer, SignerResult } from '@polkadot/api/types';
import { KeyringPair } from '@polkadot/keyring/types';
import { Registry, SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types';
import { createType } from '@polkadot/types';
import { hexToU8a, u8aToHex } from '@polkadot/util';
let id = 0;
@@ -31,7 +30,7 @@ export class SingleAccountSigner implements Signer {
return new Promise((resolve): void => {
setTimeout((): void => {
const signed = createType(this.registry, 'ExtrinsicPayload', payload, { version: payload.version }).sign(this.keyringPair);
const signed = this.registry.createType('ExtrinsicPayload', payload, { version: payload.version }).sign(this.keyringPair);
resolve({
id: ++id,

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