Store the genesisHash along with code & contracts (load check) (#982)
* Store the genesisHash along with code & contracts (load check) * Cleanup hanging promises * contract:contract: -> contract:address: (storage) * Update store.ts
This commit is contained in:
parent
8e77bcf8c8
commit
26ff33678e
@ -225,7 +225,10 @@ class Deploy extends React.PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
store.saveCode(new Hash(codeHash), { abi, name });
|
||||
store.saveCode(new Hash(codeHash), { abi, name }).catch((error) => {
|
||||
console.error('Unable to save code', error);
|
||||
});
|
||||
|
||||
this.redirect();
|
||||
}
|
||||
|
||||
@ -240,7 +243,10 @@ class Deploy extends React.PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
store.saveCode(codeHash as Hash, { abi, name });
|
||||
store.saveCode(codeHash as Hash, { abi, name }).catch((error) => {
|
||||
console.error('Unable to save code', error);
|
||||
});
|
||||
|
||||
this.redirect();
|
||||
});
|
||||
}
|
||||
|
||||
@ -329,7 +329,10 @@ class Create extends React.PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
store.saveContract(new AccountId(address), { abi, name });
|
||||
store.saveContract(new AccountId(address), { abi, name }).catch((error) => {
|
||||
console.error('Unable to save contract', error);
|
||||
});
|
||||
|
||||
this.redirect();
|
||||
}
|
||||
|
||||
@ -344,7 +347,10 @@ class Create extends React.PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
store.saveContract(address as AccountId, { abi, name });
|
||||
store.saveContract(address as AccountId, { abi, name }).catch((error) => {
|
||||
console.error('Unable to save contract', error);
|
||||
});
|
||||
|
||||
this.redirect();
|
||||
});
|
||||
}
|
||||
|
||||
@ -34,6 +34,11 @@ class App extends React.PureComponent<Props, State> {
|
||||
store.on('new-code', this.triggerUpdate);
|
||||
store.on('new-contract', this.triggerUpdate);
|
||||
|
||||
// since we have a dep on the async API, we load here
|
||||
store.loadAll().catch(() => {
|
||||
// noop, handled internally
|
||||
});
|
||||
|
||||
this.state = {
|
||||
tabs: [
|
||||
{
|
||||
|
||||
@ -7,9 +7,11 @@ import { CodeJson, ContractJson } from './types';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import store from 'store';
|
||||
import { AccountId, ContractAbi, Hash } from '@polkadot/types';
|
||||
import { api } from '@polkadot/ui-api';
|
||||
|
||||
const KEY_CODE = 'contract:code:';
|
||||
const KEY_CONTRACT = 'contract:contract:';
|
||||
const PREFIX = 'contract:';
|
||||
const KEY_CODE = `${PREFIX}code:`;
|
||||
const KEY_CONTRACT = `${PREFIX}addr:`;
|
||||
|
||||
const codeRegex = new RegExp(`^${KEY_CODE}`, '');
|
||||
const contractRegex = new RegExp(`^${KEY_CONTRACT}`, '');
|
||||
@ -21,18 +23,6 @@ class Store extends EventEmitter {
|
||||
private allCode: { [index: string]: CodeStored } = {};
|
||||
private allContracts: { [index: string]: ContractStored } = {};
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
|
||||
store.each((json: CodeJson | ContractJson, key: string) => {
|
||||
if (codeRegex.test(key)) {
|
||||
this.addCode(json as CodeJson);
|
||||
} else if (contractRegex.test(key)) {
|
||||
this.addContract(json as ContractJson);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get hasCode (): boolean {
|
||||
return Object.keys(this.allCode).length !== 0;
|
||||
}
|
||||
@ -57,22 +47,56 @@ class Store extends EventEmitter {
|
||||
return this.allContracts[address];
|
||||
}
|
||||
|
||||
saveCode (codeHash: Hash, partial: Partial<CodeJson>) {
|
||||
const json = { ...partial, codeHash: codeHash.toHex() } as CodeJson;
|
||||
async saveCode (codeHash: Hash, partial: Partial<CodeJson>) {
|
||||
await api.isReady;
|
||||
|
||||
const json = {
|
||||
...partial,
|
||||
codeHash: codeHash.toHex(),
|
||||
genesisHash: api.genesisHash.toHex()
|
||||
} as CodeJson;
|
||||
|
||||
store.set(`${KEY_CODE}${json.codeHash}`, json);
|
||||
|
||||
this.addCode(json);
|
||||
}
|
||||
|
||||
saveContract (address: AccountId, partial: Partial<ContractJson>) {
|
||||
const json = { ...partial, address: address.toString() } as ContractJson;
|
||||
async saveContract (address: AccountId, partial: Partial<ContractJson>) {
|
||||
await api.isReady;
|
||||
|
||||
const json = {
|
||||
...partial,
|
||||
address: address.toString(),
|
||||
genesisHash: api.genesisHash.toHex()
|
||||
} as ContractJson;
|
||||
|
||||
store.set(`${KEY_CONTRACT}${address}`, json);
|
||||
|
||||
this.addContract(json);
|
||||
}
|
||||
|
||||
async loadAll () {
|
||||
try {
|
||||
await api.isReady;
|
||||
|
||||
const genesisHash = api.genesisHash.toHex();
|
||||
|
||||
store.each((json: CodeJson | ContractJson, key: string) => {
|
||||
if (json && json.genesisHash !== genesisHash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (codeRegex.test(key)) {
|
||||
this.addCode(json as CodeJson);
|
||||
} else if (contractRegex.test(key)) {
|
||||
this.addContract(json as ContractJson);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Unable to load contracts', error);
|
||||
}
|
||||
}
|
||||
|
||||
private addCode (json: CodeJson) {
|
||||
try {
|
||||
this.allCode[json.codeHash] = {
|
||||
|
||||
@ -12,14 +12,17 @@ export type LocationProps = {
|
||||
|
||||
export type ComponentProps = AppProps & LocationProps;
|
||||
|
||||
export type CodeJson = {
|
||||
abi?: string | null,
|
||||
codeHash: string,
|
||||
name: string
|
||||
type BaseInfo = {
|
||||
name: string,
|
||||
genesisHash: string
|
||||
};
|
||||
|
||||
export type ContractJson = {
|
||||
abi: string,
|
||||
address: string,
|
||||
name: string
|
||||
export type CodeJson = BaseInfo & {
|
||||
abi?: string | null,
|
||||
codeHash: string
|
||||
};
|
||||
|
||||
export type ContractJson = BaseInfo & {
|
||||
abi: string,
|
||||
address: string
|
||||
};
|
||||
|
||||
@ -18,6 +18,8 @@ import { formatBalance, isTestChain } from '@polkadot/util';
|
||||
|
||||
import ApiContext from './ApiContext';
|
||||
|
||||
let api: ApiPromise;
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode,
|
||||
queueExtrinsic: QueueTx$ExtrinsicAdd,
|
||||
@ -29,6 +31,8 @@ type State = ApiProps & {
|
||||
chain?: string
|
||||
};
|
||||
|
||||
export { api };
|
||||
|
||||
export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
state: State = {} as State;
|
||||
|
||||
@ -40,7 +44,7 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
const signer = new ApiSigner(queueExtrinsic, queueSetTxStatus);
|
||||
|
||||
const setApi = (provider: ProviderInterface): void => {
|
||||
const api = new ApiPromise({ provider, signer });
|
||||
api = new ApiPromise({ provider, signer });
|
||||
|
||||
this.setState({ api }, () => {
|
||||
this.subscribeEvents();
|
||||
@ -49,10 +53,12 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
const setApiUrl = (url: string = defaults.WS_URL): void =>
|
||||
setApi(new WsProvider(url));
|
||||
|
||||
api = new ApiPromise({ provider, signer });
|
||||
|
||||
this.state = {
|
||||
isApiConnected: false,
|
||||
isApiReady: false,
|
||||
api: new ApiPromise({ provider, signer }),
|
||||
api,
|
||||
setApiUrl
|
||||
} as State;
|
||||
}
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import Api from './Api';
|
||||
import Api, { api } from './Api';
|
||||
import ApiContext from './ApiContext';
|
||||
|
||||
export * from './with';
|
||||
|
||||
export {
|
||||
api,
|
||||
Api,
|
||||
ApiContext
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user