Skip to content

feature: custom rpc #267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions docs/directory-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ Polymesh models and business logic.
├── background
│   ├── handlers:
│   │   ├── Extension.ts // Handles requests from extension popup such as: account data queries, currently selected network and user, request approval or rejection...etc.
│   │   ├── State.ts // In memory queue of dapp requests such as data provision requests.
│   │   ├── Tabs.ts // Handlers for dapp requests.
│   │   ├── index.ts
│   │   ├── subscriptions.ts
│   │   └── utils.ts
│   └── types.ts
├── constants.ts
├── external // Data fetching data from chain
Expand All @@ -38,9 +36,6 @@ Polymesh models and business logic.
│   ├── index.ts
│   ├── polyNetworkGet.ts
│   ├── polyNetworkSubscribe.ts
│   └── schema // Storage of chain schema as well as utilities to load schema from Github.
│   ├── fallback.ts
│   └── index.ts
├── index.ts
├── page // API injected in browser page.
│   ├── Network.ts // Network API methods
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"@babel/runtime": "^7.14.6",
"@polymathnetwork/confidential-identity": "1.0.1",
"@polymeshassociation/polymesh-types": "^5.6.0",
"@reduxjs/toolkit": "^1.5.1",
"@types/crypto-js": "^4.0.1",
"@types/lodash-es": "^4.17.3",
Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/background/handlers/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import {
import { KeyringPair } from '@polkadot/keyring/types';
import keyring from '@polkadot/ui-keyring';
import { callDetails } from '@polymeshassociation/extension-core/external';
import { getNetwork } from '@polymeshassociation/extension-core/store/getters';
import { getNetworkUrl } from '@polymeshassociation/extension-core/store/getters';
import {
renameIdentity,
setNetwork,
setCustomNetworkUrl,
setSelectedAccount,
toggleIsDeveloper,
} from '@polymeshassociation/extension-core/store/setters';
Expand All @@ -34,6 +35,7 @@ import {
RequestPolyGlobalChangePass,
RequestPolyIdentityRename,
RequestPolyNetworkSet,
RequestPolyCustomNetworkUrlSet,
RequestPolySelectedAccountSet,
RequestPolyValidatePassword,
ResponsePolyCallDetails,
Expand Down Expand Up @@ -134,6 +136,12 @@ export default class Extension extends DotExtension {
return true;
}

private polyCustomNetworkUrlSet({ customNetworkUrl }: RequestPolyCustomNetworkUrlSet): boolean {
setCustomNetworkUrl(customNetworkUrl);

return true;
}

private polyIdentityRename({
did,
name,
Expand All @@ -155,9 +163,9 @@ export default class Extension extends DotExtension {
private polyCallDetailsGet({
request,
}: RequestPolyCallDetails): Promise<ResponsePolyCallDetails> {
const network = getNetwork();
const networkUrl = getNetworkUrl();

return callDetails(request, network);
return callDetails(request, networkUrl);
}

private polyIsDevToggle(): boolean {
Expand Down Expand Up @@ -303,6 +311,9 @@ export default class Extension extends DotExtension {
case 'poly:pri(network.set)':
return this.polyNetworkSet(request as RequestPolyNetworkSet);

case 'poly:pri(network.setCustomNetworkUrl)':
return this.polyCustomNetworkUrlSet(request as RequestPolyCustomNetworkUrlSet);

case 'poly:pri(selectedAccount.subscribe)':
return this.polySelectedAccountSubscribe(id, port);

Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/background/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export type RequestPolyAccountsSubscribe = null;

export type RequestPolyNetworkSubscribe = null;

export type RequestPolyCustomNetworkUrlSubscribe = null;

export type RequestPolySelectedAccountSubscribe = null;

export type RequestPolyStatusSubscribe = null;
Expand All @@ -50,6 +52,10 @@ export interface RequestPolyNetworkSet {
network: NetworkName;
}

export interface RequestPolyCustomNetworkUrlSet {
customNetworkUrl: string;
}

export interface RequestPolyValidatePassword {
password: string;
}
Expand Down Expand Up @@ -92,6 +98,11 @@ export interface PolyRequestSignatures extends DotRequestSignatures {
boolean,
NetworkName
];
'poly:pri(customNetworkUrl.subscribe)': [
RequestPolyCustomNetworkUrlSubscribe,
boolean,
string
];
'poly:pri(selectedAccount.subscribe)': [
RequestPolySelectedAccountSubscribe,
boolean,
Expand All @@ -103,6 +114,7 @@ export interface PolyRequestSignatures extends DotRequestSignatures {
StoreStatus
];
'poly:pri(network.set)': [RequestPolyNetworkSet, boolean];
'poly:pri(network.setCustomNetworkUrl)': [RequestPolyCustomNetworkUrlSet, boolean],
'poly:pri(isDev.toggle)': [RequestPolyIsDevToggle, boolean];
'poly:pri(selectedAccount.set)': [RequestPolySelectedAccountSet, boolean];
'poly:pri(callDetails.get)': [
Expand Down
25 changes: 12 additions & 13 deletions packages/core/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import { LinkName, NetworkName, NetworkState } from './types';

export const networkURLs: Record<NetworkName, string> = {
mainnet: 'wss://mainnet-rpc.polymesh.network',
testnet: 'wss://testnet-rpc.polymesh.live',
staging: 'wss://staging-rpc.polymesh.live',
local: 'ws://localhost:9944',
mainnet: 'wss://mainnet-rpc.polymesh.network/',
testnet: 'wss://testnet-rpc.polymesh.live/',
staging: 'wss://staging-rpc.polymesh.live/',
local: 'ws://localhost:9944/',
custom: ''
};

export const networkLabels: Record<NetworkName, string> = {
mainnet: 'Mainnet',
testnet: 'Testnet',
staging: 'Staging',
local: 'Local node',
custom: 'Custom',
};

export const networkIsDev: Record<NetworkName, boolean> = {
mainnet: false,
testnet: false,
staging: true,
local: true,
};

export const dynamicSchemaEnabled: Record<NetworkName, boolean> = {
mainnet: true,
testnet: true,
staging: true,
local: false,
custom: true,
};

export const networkLinks: Record<NetworkName, Record<LinkName, string>> = {
Expand All @@ -45,6 +41,10 @@ export const networkLinks: Record<NetworkName, Record<LinkName, string>> = {
dashboard: 'http://localhost:3000/',
explorer: '',
},
custom: {
dashboard: 'https://portal.polymesh.live/',
explorer: '',
},
};

export const defaultNetwork: NetworkName = NetworkName.mainnet;
Expand All @@ -61,8 +61,6 @@ export const messages = [
'pub(metadata.list)',
];

export const polySchemaUrl = 'https://schema.polymesh.live/';

export const populatedDelay = 1000;

export const apiConnTimeout = 3500;
Expand All @@ -73,6 +71,7 @@ export const defaultNetworkState: NetworkState = {
selected: defaultNetwork,
ss58Format: defaultSs58Format,
isDeveloper: false,
customNetworkUrl: '',
};

export const PORTS = {
Expand Down
23 changes: 10 additions & 13 deletions packages/core/src/external/apiPromise/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { ApiPromise, WsProvider } from '@polkadot/api';
import { typesBundle } from '@polymeshassociation/polymesh-types';

import { apiConnTimeout, networkURLs } from '../../constants';
import { NetworkName } from '../../types';
import SchemaService from '../schema';
import { apiConnTimeout } from '../../constants';

let api: ApiPromise | null = null;
let provider: WsProvider;
let currentNetwork: NetworkName;
let currentNetworkUrl: string;

const metadata: Record<string, `0x${string}`> = {};

async function apiPromise(network: NetworkName): Promise<ApiPromise> {
const shouldReinitialize = currentNetwork !== network;
async function apiPromise(networkUrl: string): Promise<ApiPromise> {
const shouldReinitialize = currentNetworkUrl !== networkUrl;

if (!shouldReinitialize && api && provider?.isConnected) return api;

currentNetwork = network;
currentNetworkUrl = networkUrl;

// 'false' means to not retry connection if it fails. We need to report
// connection issues to the user instead of retrying connection for minutes.
provider = new WsProvider(networkURLs[network], false);
provider = new WsProvider(networkUrl, false);

await provider.connect();

Expand All @@ -34,7 +33,7 @@ async function apiPromise(network: NetworkName): Promise<ApiPromise> {
// B) A second later, if connection is not up, we throw an error.
await new Promise<void>((resolve, reject) => {
const handle = setTimeout(() => {
reject(new Error(`Failed to connect to ${networkURLs[network]}`));
reject(new Error(`Failed to connect to ${networkUrl}`));
}, apiConnTimeout);

unsubscribe = provider.on('connected', () => {
Expand All @@ -45,13 +44,11 @@ async function apiPromise(network: NetworkName): Promise<ApiPromise> {

unsubscribe();

const { rpc, types } = SchemaService.get(network);

api = await ApiPromise.create({
provider,
rpc,
types,
typesBundle,
metadata,
noInitWarn: true,
});

await api.isReadyOrError;
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/external/callDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { AnyJson, SignerPayloadJSON } from '@polkadot/types/types';
import { ResponsePolyCallDetails } from '@polymeshassociation/extension-core/background/types';
import { upperFirst } from 'lodash-es';

import { NetworkName } from '../types';
import apiPromise from './apiPromise';

async function callDetails(
request: SignerPayloadJSON,
network: NetworkName
networkUrl: string
): Promise<ResponsePolyCallDetails> {
const api = await apiPromise(network);
const api = await apiPromise(networkUrl);
let protocolFee = '0';
let networkFee = '0';

Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/external/polyNetworkGet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { networkLabels, networkURLs } from '../constants';
import { getNetwork } from '../store/getters';
import { networkLabels } from '../constants';
import { getNetwork, getNetworkUrl } from '../store/getters';
import { NetworkMeta } from '../types';

export default function (): NetworkMeta {
const network = getNetwork();
const wssUrl = getNetworkUrl();

return {
name: network,
label: networkLabels[network],
wssUrl: networkURLs[network],
wssUrl,
};
}
41 changes: 36 additions & 5 deletions packages/core/src/external/polyNetworkSubscribe.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,51 @@
import { Unsubscribe } from '@reduxjs/toolkit';

import { networkLabels, networkURLs } from '../constants';
import { networkLabels } from '../constants';
import reduxSubscribe from '../store/reduxSubscribe';
import { selectedNetwork } from '../store/selectors';
import { customNetworkUrl, selectedNetwork } from '../store/selectors';
import { NetworkMeta, NetworkName } from '../types';
import { getNetwork, getNetworkUrl } from '../store/getters';

export default function (cb: (networkMeta: NetworkMeta) => void): Unsubscribe {
const innerCb = (networkName: NetworkName) => {
let firstCall = true;

const onNetworkNameUpdate = (networkName: NetworkName) => {
const wssUrl = getNetworkUrl();

const networkMeta = {
name: networkName,
label: networkLabels[networkName],
wssUrl,
};

cb(networkMeta);
};

const onCustomUrlUpdate = () => {
// Skip the first callback so the subscription doesn't return twice initially.
if (firstCall) {
firstCall = false;
return;
}
const networkName = getNetwork();
const wssUrl = getNetworkUrl();

const networkMeta = {
name: networkName,
label: networkLabels[networkName],
wssUrl: networkURLs[networkName],
wssUrl,
};

cb(networkMeta);
};

return reduxSubscribe(selectedNetwork, innerCb);
const networkUnsub = reduxSubscribe(selectedNetwork, onNetworkNameUpdate);
const customUrlUnsub = reduxSubscribe(customNetworkUrl, onCustomUrlUpdate);

const unsubAll: Unsubscribe = () => {
customUrlUnsub();
networkUnsub();
};

return unsubAll;
}
21 changes: 0 additions & 21 deletions packages/core/src/external/schema/fallback.ts

This file was deleted.

Loading