diff --git a/packages/api-observable/src/Base.ts b/packages/api-observable/src/Base.ts index 229f70f4e1..0c000539cd 100644 --- a/packages/api-observable/src/Base.ts +++ b/packages/api-observable/src/Base.ts @@ -5,8 +5,13 @@ import { RxApiInterface, RxApiInterface$Method, RxApiInterface$Section } from '@polkadot/api-rx/types'; import { Method } from '@polkadot/jsonrpc/types'; -import { Observable, combineLatest } from 'rxjs'; +import { Observable, combineLatest, from } from 'rxjs'; import { defaultIfEmpty, map } from 'rxjs/operators'; +import extrinsicsFromMeta from '@polkadot/extrinsics/fromMetadata'; +import extrinsicsStatic from '@polkadot/extrinsics/static'; +import storageFromMeta from '@polkadot/storage/fromMetadata'; +import storageStatic from '@polkadot/storage/static'; +import { Hash } from '@polkadot/types/index'; import { StorageFunction } from '@polkadot/types/StorageKey'; import assert from '@polkadot/util/assert'; import isUndefined from '@polkadot/util/is/undefined'; @@ -19,10 +24,47 @@ const defaultMapFn = (result: any): any => // Raw base implementation for the observable API. It simply provides access to raw calls, allowing // decendants to make direct queries to either API methods or actual storage export default class ApiBase { - protected api: RxApiInterface; + protected _api: RxApiInterface; + protected _genesisHash: Hash; + + // Observable that returns the first time we are connected and loaded + whenReady: Observable; constructor (api: RxApiInterface) { - this.api = api; + this._api = api; + this._genesisHash = new Hash(); + this.whenReady = from(this.init()); + } + + static extrinsics = extrinsicsStatic; + static storage = storageStatic; + + private init (): Promise { + let isReady: boolean = false; + + return new Promise((resolveReady) => { + // On connection, load data from chain + this.isConnected().subscribe(async (isConnected) => { + if (!isConnected) { + return; + } + + try { + const meta = await this._api.state.getMetadata().toPromise(); + + this._genesisHash = await this._api.state.getBlockHash(0).toPromise(); + ApiBase.extrinsics = extrinsicsFromMeta(meta); + ApiBase.storage = storageFromMeta(meta); + + if (!isReady) { + isReady = true; + resolveReady(true); + } + } catch (error) { + // swallow + } + }); + }); } protected combine = (observables: Array>, mapfn: MapFn = defaultMapFn): Observable => { @@ -33,12 +75,16 @@ export default class ApiBase { ); } + get genesisHash (): Hash { + return this._genesisHash; + } + isConnected = (): Observable => { - return this.api.isConnected(); + return this._api.isConnected(); } rawCall = ({ method, section }: Method, ...params: Array): Observable => { - const apiSection = this.api[section as keyof RxApiInterface] as RxApiInterface$Section; + const apiSection = this._api[section as keyof RxApiInterface] as RxApiInterface$Section; assert(apiSection, `Unable to find 'api.${section}'`); @@ -61,7 +107,7 @@ export default class ApiBase { } rawStorageMulti = (...keys: Array<[StorageFunction] | [StorageFunction, any]>): Observable => { - return this.api.state + return this._api.state .storage(keys) .pipe( map((result?: any) => diff --git a/packages/api-observable/src/Calls.ts b/packages/api-observable/src/Calls.ts index 62b2d0660d..11fda12810 100644 --- a/packages/api-observable/src/Calls.ts +++ b/packages/api-observable/src/Calls.ts @@ -23,11 +23,11 @@ export default class ApiCalls extends ApiQueries { } chainGetBlock = (hash: Uint8Array): Observable => { - return this.api.chain.getBlock(hash); + return this._api.chain.getBlock(hash); } chainNewHead = (): Observable
=> { - return this.api.chain.newHead().pipe( + return this._api.chain.newHead().pipe( defaultIfEmpty() ); } diff --git a/packages/api-observable/src/Queries.ts b/packages/api-observable/src/Queries.ts index e4acb80a06..7fd1855c17 100644 --- a/packages/api-observable/src/Queries.ts +++ b/packages/api-observable/src/Queries.ts @@ -7,9 +7,9 @@ import { RxFees } from './types'; import BN from 'bn.js'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import storage from '@polkadot/storage/static'; import { AccountId, Balance, Bool, BlockNumber, Index, Moment, Perbill, PropIndex, ReferendumIndex, u32 } from '@polkadot/types/index'; import { Tuple } from '@polkadot/types/codec'; -import storage from '@polkadot/storage/testing'; import ApiBase from './Base'; import { RxProposal, RxProposalDeposits, RxReferendum } from './classes'; diff --git a/packages/api-provider/src/mock/mocks.ts b/packages/api-provider/src/mock/mocks.ts index 56c8326506..92aea6e252 100644 --- a/packages/api-provider/src/mock/mocks.ts +++ b/packages/api-provider/src/mock/mocks.ts @@ -10,8 +10,8 @@ import { ProviderInterface$Emitted } from '../types'; import { MockState, MockState$Db, MockState$Subscriptions } from './types'; import BN from 'bn.js'; +import storage from '@polkadot/storage/static'; import Header from '@polkadot/types/Header'; -import storage from '@polkadot/storage/testing'; import bnToU8a from '@polkadot/util/bn/toU8a'; import u8aToHex from '@polkadot/util/u8a/toHex'; import randomAsU8a from '@polkadot/util-crypto/random/asU8a'; diff --git a/packages/api-rx/test/e2e/subscribe.test.js b/packages/api-rx/test/e2e/subscribe.test.js index a0deadb1e1..710ccf2112 100644 --- a/packages/api-rx/test/e2e/subscribe.test.js +++ b/packages/api-rx/test/e2e/subscribe.test.js @@ -2,8 +2,8 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import storage from '@polkadot/storage/testing'; import Ws from '@polkadot/api-provider/ws'; +import storage from '@polkadot/storage/static'; import RxApi from '../../src'; diff --git a/packages/api/src/formatting.spec.js b/packages/api/src/formatting.spec.js index a87756d306..299ca8e14a 100644 --- a/packages/api/src/formatting.spec.js +++ b/packages/api/src/formatting.spec.js @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import storage from '@polkadot/storage/testing'; +import storage from '@polkadot/storage/static'; import Api from './index'; diff --git a/packages/api/test/e2e/state.test.js b/packages/api/test/e2e/state.test.js index a70cf4a2af..4041c993b3 100644 --- a/packages/api/test/e2e/state.test.js +++ b/packages/api/test/e2e/state.test.js @@ -2,8 +2,8 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import storage from '@polkadot/storage/testing'; import Ws from '@polkadot/api-provider/ws'; +import storage from '@polkadot/storage/static'; import Api from '../../src'; diff --git a/packages/api/test/e2e/subscribe.test.js b/packages/api/test/e2e/subscribe.test.js index 61481eb1a1..bea59b4c05 100644 --- a/packages/api/test/e2e/subscribe.test.js +++ b/packages/api/test/e2e/subscribe.test.js @@ -2,8 +2,8 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import storage from '@polkadot/storage/testing'; import Ws from '@polkadot/api-provider/ws'; +import storage from '@polkadot/storage/static'; import Api from '../../src'; diff --git a/packages/type-extrinsics/src/fromMetadata.spec.js b/packages/type-extrinsics/src/fromMetadata.spec.js index d17c41f3be..5b92ba60ce 100644 --- a/packages/type-extrinsics/src/fromMetadata.spec.js +++ b/packages/type-extrinsics/src/fromMetadata.spec.js @@ -9,7 +9,7 @@ import fromMetadata from './fromMetadata'; // Use the pre-generated metadata const metadata = new Metadata().fromJSON(json); -const newExtrinsics = fromMetadata({}, metadata); +const newExtrinsics = fromMetadata(metadata); describe('fromMetadata', () => { it('should throw if an incorrect number of args is supplied', () => { diff --git a/packages/type-extrinsics/src/fromMetadata.ts b/packages/type-extrinsics/src/fromMetadata.ts index 4ce70df116..3f3391b161 100644 --- a/packages/type-extrinsics/src/fromMetadata.ts +++ b/packages/type-extrinsics/src/fromMetadata.ts @@ -7,6 +7,7 @@ import Metadata, { RuntimeModuleMetadata } from '@polkadot/types/Metadata'; import createUnchecked from './utils/createUnchecked'; import { Extrinsics, ModuleExtrinsics } from './types'; +import extrinsics from './index'; /** * Extend a storage object with the storage modules & module functions present @@ -15,7 +16,7 @@ import { Extrinsics, ModuleExtrinsics } from './types'; * @param extrinsics - An extrinsics object to be extended. * @param metadata - The metadata to extend the storage object against. */ -export default function fromMetadata (extrinsics: Extrinsics, metadata: Metadata) { +export default function fromMetadata (metadata: Metadata): Extrinsics { // Dont' clobber the input, create new const result = Object.keys(extrinsics).reduce((result, key) => { result[key] = extrinsics[key]; diff --git a/packages/type-extrinsics/src/index.spec.js b/packages/type-extrinsics/src/index.spec.js index 019583cb10..25099e30dd 100644 --- a/packages/type-extrinsics/src/index.spec.js +++ b/packages/type-extrinsics/src/index.spec.js @@ -5,7 +5,7 @@ import hexToU8a from '@polkadot/util/hex/toU8a'; import testingPairs from '@polkadot/util-keyring/testingPairs'; -import extrinsics from './testing'; +import extrinsics from './static'; const keyring = testingPairs(); diff --git a/packages/type-extrinsics/src/testing.ts b/packages/type-extrinsics/src/static.ts similarity index 89% rename from packages/type-extrinsics/src/testing.ts rename to packages/type-extrinsics/src/static.ts index 7bf03e97b1..394d61dbf9 100644 --- a/packages/type-extrinsics/src/testing.ts +++ b/packages/type-extrinsics/src/static.ts @@ -5,10 +5,8 @@ import metadataRpc from '@polkadot/types/Metadata.rpc'; import Metadata from '@polkadot/types/Metadata'; -import extrinsics from './index'; import fromMetadata from './fromMetadata'; export default fromMetadata( - extrinsics, new Metadata().fromJSON(metadataRpc) ); diff --git a/packages/type-extrinsics/test/e2e/transfer.spec.js b/packages/type-extrinsics/test/e2e/transfer.spec.js index b36783c617..68138d3b84 100644 --- a/packages/type-extrinsics/test/e2e/transfer.spec.js +++ b/packages/type-extrinsics/test/e2e/transfer.spec.js @@ -6,7 +6,7 @@ import Api from '@polkadot/api'; import testingPairs from '@polkadot/util-keyring/testingPairs'; import Ws from '@polkadot/api-provider/ws'; -import extrinsics from '../../src/testing'; +import extrinsics from '../../src/static'; const keyring = testingPairs(); diff --git a/packages/type-storage/src/fromMetadata.spec.js b/packages/type-storage/src/fromMetadata.spec.js index 06c39734ee..2f156b517c 100644 --- a/packages/type-storage/src/fromMetadata.spec.js +++ b/packages/type-storage/src/fromMetadata.spec.js @@ -9,7 +9,7 @@ import fromMetadata from './fromMetadata'; // Use the pre-generated metadata const metadata = new Metadata().fromJSON(json); -const newStorage = fromMetadata({}, metadata); +const newStorage = fromMetadata(metadata); describe('fromMetadata', () => { it('should throw if the storage function expects an argument', () => { diff --git a/packages/type-storage/src/fromMetadata.ts b/packages/type-storage/src/fromMetadata.ts index ac529a84a1..d0337cebd5 100644 --- a/packages/type-storage/src/fromMetadata.ts +++ b/packages/type-storage/src/fromMetadata.ts @@ -8,6 +8,7 @@ import Metadata from '@polkadot/types/Metadata'; import { stringLowerFirst } from '@polkadot/util/string'; import createFunction from './utils/createFunction'; +import storage from './index'; /** * Extend a storage object with the storage modules & module functions present @@ -16,7 +17,7 @@ import createFunction from './utils/createFunction'; * @param storage - A storage object to be extended. * @param metadata - The metadata to extend the storage object against. */ -export default function fromMetadata (storage: Storage, metadata: Metadata) { +export default function fromMetadata (metadata: Metadata): Storage { const result = Object.keys(storage).reduce((result, key) => { result[key] = storage[key]; diff --git a/packages/type-storage/src/testing.ts b/packages/type-storage/src/static.ts similarity index 90% rename from packages/type-storage/src/testing.ts rename to packages/type-storage/src/static.ts index ec0c2d376b..0cb5e69af9 100644 --- a/packages/type-storage/src/testing.ts +++ b/packages/type-storage/src/static.ts @@ -5,10 +5,8 @@ import metadataRpc from '@polkadot/types/Metadata.rpc'; import Metadata from '@polkadot/types/Metadata'; -import storage from './index'; import fromMetadata from './fromMetadata'; export default fromMetadata( - storage, new Metadata().fromJSON(metadataRpc) );