1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.ApiRx = void 0;
|
7 |
|
8 | var _rxjs = require("rxjs");
|
9 |
|
10 | var _util = require("@polkadot/util");
|
11 |
|
12 | var _base = require("../base");
|
13 |
|
14 | var _decorateMethod = require("./decorateMethod");
|
15 |
|
16 | // Copyright 2017-2022 @polkadot/api authors & contributors
|
17 | // SPDX-License-Identifier: Apache-2.0
|
18 |
|
19 | /**
|
20 | * # @polkadot/api/rx
|
21 | *
|
22 | * ## Overview
|
23 | *
|
24 | * @name ApiRx
|
25 | *
|
26 | * @description
|
27 | * ApiRx is a powerful RxJS Observable wrapper around the RPC and interfaces on the Polkadot network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values.
|
28 | *
|
29 | * The API is well suited to real-time applications where the latest state is needed, unlocking the subscription-based features of Polkadot (and Substrate) clients. Some familiarity with RxJS is a requirement to use the API, however just understanding `.subscribe` and `.pipe` on Observables will unlock full-scale use thereof.
|
30 | *
|
31 | * @see [[ApiPromise]]
|
32 | *
|
33 | * ## Usage
|
34 | *
|
35 | * Making rpc calls -
|
36 | * <BR>
|
37 | *
|
38 | * ```javascript
|
39 | * import ApiRx from '@polkadot/api/rx';
|
40 | *
|
41 | * // initialize via Promise & static create
|
42 | * const api = await ApiRx.create().toPromise();
|
43 | *
|
44 | * // make a call to retrieve the current network head
|
45 | * api.rpc.chain.subscribeNewHeads().subscribe((header) => {
|
46 | * console.log(`Chain is at #${header.number}`);
|
47 | * });
|
48 | * ```
|
49 | * <BR>
|
50 | *
|
51 | * Subscribing to chain state -
|
52 | * <BR>
|
53 | *
|
54 | * ```javascript
|
55 | * import { combineLatest, pairwise, switchMap } from 'rxjs';
|
56 | * import { ApiRx, WsProvider } from '@polkadot/api';
|
57 | *
|
58 | *
|
59 | * // initialize a provider with a specific endpoint
|
60 | * const provider = new WsProvider('wss://example.com:9944')
|
61 | *
|
62 | * // initialize via isReady & new with specific provider
|
63 | * new ApiRx({ provider })
|
64 | * .isReady
|
65 | * .pipe(
|
66 | * switchMap((api) =>
|
67 | * combineLatest([
|
68 | * api.query.timestamp.blockPeriod(),
|
69 | * api.query.timestamp.now().pipe(pairwise())
|
70 | * ])
|
71 | * )
|
72 | * )
|
73 | * .subscribe(([blockPeriod, timestamp]) => {
|
74 | * const elapsed = timestamp[1].toNumber() - timestamp[0].toNumber();
|
75 | * console.log(`timestamp ${timestamp[1]} \nelapsed ${elapsed} \n(${blockPeriod}s target)`);
|
76 | * });
|
77 | * ```
|
78 | * <BR>
|
79 | *
|
80 | * Submitting a transaction -
|
81 | * <BR>
|
82 | *
|
83 | * ```javascript
|
84 | * import { first, switchMap } from 'rxjs';
|
85 | * import ApiRx from '@polkadot/api/rx';
|
86 | *
|
87 | * // import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
|
88 | * import testingPairs from '@polkadot/keyring/testingPairs';
|
89 | * const keyring = testingPairs();
|
90 | *
|
91 | * // get api via Promise
|
92 | * const api = await ApiRx.create().toPromise();
|
93 | *
|
94 | * // retrieve nonce for the account
|
95 | * api.query.system
|
96 | * .account(keyring.alice.address)
|
97 | * .pipe(
|
98 | * first(),
|
99 | * // pipe nonce into transfer
|
100 | * switchMap(([nonce]) =>
|
101 | * api.tx.balances
|
102 | * // create transfer
|
103 | * .transfer(keyring.bob.address, 12345)
|
104 | * // sign the transaction
|
105 | * .sign(keyring.alice, { nonce })
|
106 | * // send the transaction
|
107 | * .send()
|
108 | * )
|
109 | * )
|
110 | * // subscribe to overall result
|
111 | * .subscribe(({ status }) => {
|
112 | * if (status.isInBlock) {
|
113 | * console.log('Completed at block hash', status.asFinalized.toHex());
|
114 | * }
|
115 | * });
|
116 | * ```
|
117 | */
|
118 | class ApiRx extends _base.ApiBase {
|
119 | #isReadyRx;
|
120 | /**
|
121 | * @description Create an instance of the ApiRx class
|
122 | * @param options Options to create an instance. Can be either [[ApiOptions]] or [[WsProvider]]
|
123 | * @example
|
124 | * <BR>
|
125 | *
|
126 | * ```javascript
|
127 | * import { switchMap } from 'rxjs';
|
128 | * import Api from '@polkadot/api/rx';
|
129 | *
|
130 | * new Api().isReady
|
131 | * .pipe(
|
132 | * switchMap((api) =>
|
133 | * api.rpc.chain.subscribeNewHeads()
|
134 | * ))
|
135 | * .subscribe((header) => {
|
136 | * console.log(`new block #${header.number.toNumber()}`);
|
137 | * });
|
138 | * ```
|
139 | */
|
140 |
|
141 | constructor(options) {
|
142 | super(options, 'rxjs', _decorateMethod.toRxMethod);
|
143 | this.#isReadyRx = (0, _rxjs.from)( // You can create an observable from an event, however my mind groks this form better
|
144 | new Promise(resolve => {
|
145 | super.on('ready', () => resolve(this));
|
146 | }));
|
147 | }
|
148 | /**
|
149 | * @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
|
150 | * @param options options that is passed to the class constructor. Can be either [[ApiOptions]] or [[WsProvider]]
|
151 | * @example
|
152 | * <BR>
|
153 | *
|
154 | * ```javascript
|
155 | * import { switchMap } from 'rxjs';
|
156 | * import Api from '@polkadot/api/rx';
|
157 | *
|
158 | * Api.create()
|
159 | * .pipe(
|
160 | * switchMap((api) =>
|
161 | * api.rpc.chain.subscribeNewHeads()
|
162 | * ))
|
163 | * .subscribe((header) => {
|
164 | * console.log(`new block #${header.number.toNumber()}`);
|
165 | * });
|
166 | * ```
|
167 | */
|
168 |
|
169 |
|
170 | static create(options) {
|
171 | return new ApiRx(options).isReady;
|
172 | }
|
173 | /**
|
174 | * @description Observable that returns the first time we are connected and loaded
|
175 | */
|
176 |
|
177 |
|
178 | get isReady() {
|
179 | return this.#isReadyRx;
|
180 | }
|
181 | /**
|
182 | * @description Returns a clone of this ApiRx instance (new underlying provider connection)
|
183 | */
|
184 |
|
185 |
|
186 | clone() {
|
187 | return new ApiRx((0, _util.objectSpread)({}, this._options, {
|
188 | source: this
|
189 | }));
|
190 | }
|
191 |
|
192 | }
|
193 |
|
194 | exports.ApiRx = ApiRx; |
\ | No newline at end of file |