Skip to content
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

Integrate chopsticks #9965

Merged
merged 30 commits into from Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
07e2942
fork locally feature
qiweiii Oct 9, 2023
4946520
use chopsticks provider
qiweiii Oct 9, 2023
b43da87
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 11, 2023
9027c8f
update
qiweiii Oct 11, 2023
d2ce9df
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 16, 2023
f332584
test locally
qiweiii Oct 16, 2023
60d8a0c
update provider usage
qiweiii Oct 20, 2023
7c16658
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 20, 2023
20c82ff
upgrade chospticks
qiweiii Oct 23, 2023
c54e8f7
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 23, 2023
c265656
upgrade chopsticks
qiweiii Oct 24, 2023
b6f520b
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 24, 2023
4e6c5fa
fix lint
qiweiii Oct 24, 2023
2a1d1e7
remove extra code
qiweiii Oct 24, 2023
dbeea2a
add setStorage back with alice
qiweiii Oct 25, 2023
792cf95
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 26, 2023
c340295
update chopsticks
qiweiii Oct 31, 2023
99eafd0
Merge branch 'master' into integrate-chopsticks
qiweiii Oct 31, 2023
d100d3e
update chopsticks
qiweiii Nov 8, 2023
32d1312
Merge branch 'master' into integrate-chopsticks
qiweiii Nov 8, 2023
2db1477
Merge branch 'master' into integrate-chopsticks
qiweiii Nov 29, 2023
51e829f
updade chospticks version
qiweiii Nov 29, 2023
537d25d
Merge branch 'master' into integrate-chopsticks
qiweiii Feb 18, 2024
11df4be
fix: chopsticks version
qiweiii Feb 18, 2024
71de8e4
fix: update and testing
qiweiii Feb 18, 2024
b87ad7c
Merge branch 'master' into integrate-chopsticks
qiweiii Feb 22, 2024
44c2383
Merge branch 'master' into integrate-chopsticks
qiweiii Feb 22, 2024
b406ad6
Merge branch 'master' into integrate-chopsticks
qiweiii Feb 26, 2024
75735bd
Merge branch 'master' into integrate-chopsticks
qiweiii Feb 26, 2024
451c223
fix: remove isLocalFork from global var
qiweiii Feb 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/apps/package.json
Expand Up @@ -16,6 +16,7 @@
"type": "module",
"version": "0.133.2-96-x",
"dependencies": {
"@acala-network/chopsticks-core": "^0.9.8",
"@polkadot/apps-config": "^0.133.2-96-x",
"@polkadot/apps-routing": "^0.133.2-96-x",
"@polkadot/dev": "^0.78.4",
Expand Down
2 changes: 2 additions & 0 deletions packages/apps/public/locales/en/apps.json
Expand Up @@ -2,8 +2,10 @@
"Accounts": "Accounts",
"Developer": "Developer",
"Files": "Files",
"Fork Locally": "Fork Locally",
"Governance": "Governance",
"Initializing connection": "Initializing connection",
"Local fork powered by ": "Local fork powered by ",
"Network": "Network",
"Relay chain": "Relay chain",
"Settings": "Settings",
Expand Down
2 changes: 2 additions & 0 deletions packages/apps/public/locales/en/translation.json
Expand Up @@ -277,6 +277,7 @@
"Forget": "",
"Forget this account": "",
"Forget this address": "",
"Fork Locally": "",
"Forks": "",
"Free balance": "",
"From JSON": "",
Expand Down Expand Up @@ -338,6 +339,7 @@
"Lifetime (# of blocks)": "",
"Light theme": "",
"Loading": "",
"Local fork powered by ": "",
"Locked funds (e.g. for staking) are counted.": "",
"Locked1x": "",
"Locked2x": "",
Expand Down
1 change: 1 addition & 0 deletions packages/apps/public/locales/zh/translation.json
Expand Up @@ -215,6 +215,7 @@
"Forget this asset": "忘记这个资产",
"Forget this code hash": "忘记这个代码哈希",
"Forget this contract": "忘记该合约",
"Fork Locally": "本地分叉",
"Forks": "(Forks)分叉",
"Full Legal Name": "法定全称",
"Future versions of the web-only interface will drop support for non-external accounts, much like the IPFS version.": "未来版本的纯 web 界面将不再支持非外部帐户,这与 IPFS 版本非常相似。",
Expand Down
4 changes: 2 additions & 2 deletions packages/apps/src/Apps.tsx
Expand Up @@ -12,8 +12,8 @@ import Signer from '@polkadot/react-signer';

import Content from './Content/index.js';
import Menu from './Menu/index.js';
import BottomOverlay from './overlays/Bottom.js';
import ConnectingOverlay from './overlays/Connecting.js';
import DotAppsOverlay from './overlays/DotApps.js';
import WarmUp from './WarmUp.js';

export const PORTAL_ID = 'portals';
Expand All @@ -39,7 +39,7 @@ function Apps ({ className = '' }: Props): React.ReactElement<Props> {
<Content />
</Signer>
<ConnectingOverlay />
<DotAppsOverlay />
<BottomOverlay />
<div id={PORTAL_ID} />
</AccountSidebar>
</StyledDiv>
Expand Down
60 changes: 57 additions & 3 deletions packages/apps/src/Endpoints/index.tsx
Expand Up @@ -120,7 +120,11 @@ function loadAffinities (groups: Group[]): Record<string, string> {

function isSwitchDisabled (hasUrlChanged: boolean, apiUrl: string, isUrlValid: boolean): boolean {
if (!hasUrlChanged) {
return true;
if (store.get('isLocalFork')) {
return false;
} else {
return true;
}
} else if (apiUrl.startsWith('light://')) {
return false;
} else if (isUrlValid) {
Expand All @@ -130,6 +134,22 @@ function isSwitchDisabled (hasUrlChanged: boolean, apiUrl: string, isUrlValid: b
return true;
}

function isLocalForkDisabled (hasUrlChanged: boolean, apiUrl: string, isUrlValid: boolean): boolean {
if (!hasUrlChanged) {
if (store.get('isLocalFork')) {
return true;
} else {
return false;
}
} else if (apiUrl.startsWith('light://')) {
return true;
} else if (isUrlValid) {
return false;
}

return true;
}

function Endpoints ({ className = '', offset, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const linkOptions = createWsEndpoints(t);
Expand Down Expand Up @@ -223,12 +243,32 @@ function Endpoints ({ className = '', offset, onClose }: Props): React.ReactElem

const _onApply = useCallback(
(): void => {
store.set('isLocalFork', false);
settings.set({ ...(settings.get()), apiUrl });
window.location.assign(`${window.location.origin}${window.location.pathname}?rpc=${encodeURIComponent(apiUrl)}${window.location.hash}`);

if (!hasUrlChanged) {
window.location.reload();
}

onClose();
},
[apiUrl, onClose, hasUrlChanged]
);

const _onLocalFork = useCallback(
(): void => {
store.set('isLocalFork', true);
settings.set({ ...(settings.get()), apiUrl });
window.location.assign(`${window.location.origin}${window.location.pathname}?rpc=${encodeURIComponent(apiUrl)}${window.location.hash}`);
// window.location.reload();

if (!hasUrlChanged) {
window.location.reload();
}

onClose();
},
[apiUrl, onClose]
[apiUrl, onClose, hasUrlChanged]
);

const _saveApiEndpoint = useCallback(
Expand All @@ -249,6 +289,11 @@ function Endpoints ({ className = '', offset, onClose }: Props): React.ReactElem
[hasUrlChanged, apiUrl, isUrlValid]
);

const canLocalFork = useMemo(
() => isLocalForkDisabled(hasUrlChanged, apiUrl, isUrlValid),
[hasUrlChanged, apiUrl, isUrlValid]
);

return (
<StyledSidebar
button={
Expand All @@ -263,6 +308,15 @@ function Endpoints ({ className = '', offset, onClose }: Props): React.ReactElem
offset={offset}
onClose={onClose}
position='left'
secondaryButton={
<Button
icon='code-fork'
isDisabled={canLocalFork}
label={t('Fork Locally')}
onClick={_onLocalFork}
tooltip='fork-locally-btn'
/>
}
sidebarRef={sidebarRef}
>
{groups.map((group, index): React.ReactNode => (
Expand Down
4 changes: 2 additions & 2 deletions packages/apps/src/overlays/Base.tsx
Expand Up @@ -60,8 +60,8 @@ const StyledDiv = styled.div`
z-index: 500;

&.isBottom {
bottom: 0.75rem;
top: auto;
position: static;
z-index: 0;
}

&.isFull {
Expand Down
40 changes: 40 additions & 0 deletions packages/apps/src/overlays/Bottom.tsx
@@ -0,0 +1,40 @@
// Copyright 2017-2024 @polkadot/apps authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React from 'react';

import { styled } from '@polkadot/react-components';

import DotApps from './DotApps.js';
import LocalFork from './LocalFork.js';

interface Props {
className?: string;
}

function Bottom ({ className }: Props): React.ReactElement<Props> | null {
return (
<StyledDiv className={className}>
<LocalFork />
<DotApps />
</StyledDiv>
);
}

const StyledDiv = styled.div`
position: fixed;
bottom: 0.75rem;
right: 0.75rem;
left: 0.75rem;
top: auto;
padding: 1rem;
z-index: 500;
display: flex;
flex-direction: column;
row-gap: 0.75rem;;
div.isInfo:before {
content: none;
}
`;

export default React.memo(Bottom);
44 changes: 44 additions & 0 deletions packages/apps/src/overlays/LocalFork.tsx
@@ -0,0 +1,44 @@
// Copyright 2017-2024 @polkadot/apps authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React from 'react';
import store from 'store';

import { useTranslation } from '../translate.js';
import BaseOverlay from './Base.js';

interface Props {
className?: string;
}

function LocalFork ({ className }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();

if (store.get('isLocalFork')) {
return (
<BaseOverlay
className={className}
icon='link'
isBottom
isFull
type='info'
>
<div>
{t('Local fork powered by ')}
<a
href='https://github.com/AcalaNetwork/chopsticks'
rel='noreferrer'
target='_blank'
>
Chopsticks
</a>
.
</div>
</BaseOverlay>
);
}

return null;
}

export default React.memo(LocalFork);
30 changes: 24 additions & 6 deletions packages/react-api/src/Api.tsx
Expand Up @@ -7,6 +7,7 @@ import type { ChainProperties, ChainType } from '@polkadot/types/interfaces';
import type { KeyringStore } from '@polkadot/ui-keyring/types';
import type { ApiProps, ApiState } from './types.js';

import { ChopsticksProvider, setStorage } from '@acala-network/chopsticks-core';
import * as Sc from '@substrate/connect';
import React, { useEffect, useMemo, useState } from 'react';
import store from 'store';
Expand Down Expand Up @@ -232,11 +233,23 @@ async function getLightProvider (chain: string): Promise<ScProvider> {
async function createApi (apiUrl: string, signer: ApiSigner, onError: (error: unknown) => void): Promise<Record<string, Record<string, string>>> {
const types = getDevTypes();
const isLight = apiUrl.startsWith('light://');
let provider;

try {
const provider = isLight
? await getLightProvider(apiUrl.replace('light://', ''))
: new WsProvider(apiUrl);
if (isLight) {
provider = await getLightProvider(apiUrl.replace('light://', ''));
} else if (store.get('isLocalFork')) {
provider = await ChopsticksProvider.fromEndpoint(apiUrl);
await setStorage(provider.chain, {
System: {
Account: [
[['5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'], { data: { free: 1000 * 1e12 }, providers: 1 }]
]
}
});
} else {
provider = new WsProvider(apiUrl);
}

statics.api = new ApiPromise({
provider,
Expand All @@ -257,7 +270,7 @@ async function createApi (apiUrl: string, signer: ApiSigner, onError: (error: un
return types;
}

export function ApiCtxRoot ({ apiUrl, children, isElectron, store }: Props): React.ReactElement<Props> | null {
export function ApiCtxRoot ({ apiUrl, children, isElectron, store: keyringStore }: Props): React.ReactElement<Props> | null {
const { queuePayload, queueSetTxStatus } = useQueue();
const [state, setState] = useState<ApiState>(EMPTY_STATE);
const [isApiConnected, setIsApiConnected] = useState(false);
Expand Down Expand Up @@ -303,15 +316,20 @@ export function ApiCtxRoot ({ apiUrl, children, isElectron, store }: Props): Rea

const urlIsEthereum = !!location.href.includes('keyring-type=ethereum');

loadOnReady(statics.api, apiEndpoint, injectedPromise, store, types, urlIsEthereum)
loadOnReady(statics.api, apiEndpoint, injectedPromise, keyringStore, types, urlIsEthereum)
.then(setState)
.catch(onError);
});

if (store.get('isLocalFork')) {
statics.api.connect()
.catch(onError);
}

setIsApiInitialized(true);
})
.catch(onError);
}, [apiEndpoint, apiUrl, queuePayload, queueSetTxStatus, store]);
}, [apiEndpoint, apiUrl, queuePayload, queueSetTxStatus, keyringStore]);

if (!value.isApiInitialized) {
return null;
Expand Down
4 changes: 3 additions & 1 deletion packages/react-components/src/Sidebar.tsx
Expand Up @@ -8,6 +8,7 @@ import { styled } from './styled.js';

interface Props {
button?: React.ReactNode;
secondaryButton?: React.ReactNode;
children: React.ReactNode;
className?: string;
dataTestId?: string;
Expand All @@ -17,7 +18,7 @@ interface Props {
sidebarRef: React.RefObject<HTMLDivElement>;
}

function Sidebar ({ button, children, className = '', dataTestId = '', onClose, position, sidebarRef }: Props): React.ReactElement<Props> {
function Sidebar ({ button, children, className = '', dataTestId = '', onClose, position, secondaryButton, sidebarRef }: Props): React.ReactElement<Props> {
return (
<StyledDiv
className={`${className} ui--Sidebar ${position}Position`}
Expand All @@ -26,6 +27,7 @@ function Sidebar ({ button, children, className = '', dataTestId = '', onClose,
>
<Button.Group className='ui--Sidebar-buttons'>
{button}
{secondaryButton}
<Button
dataTestId='close-sidebar-button'
icon='times'
Expand Down