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

feat: query multisig account from subql #140

Merged
merged 6 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 11 additions & 0 deletions src/config/query.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
export const MULTISIG_ACCOUNT_DETAIL_QUERY = `
query multisigAccount($account: String!) {
multisigAccount(id: $account) {
id
threshold
members
}
}
`;

export const MULTISIG_RECORD_COUNT_QUERY = `
query multisigRecords($account: String!, $status: String!) {
multisigRecords(filter: { multisigAccountId: { equalTo: $account}, status: {equalTo: $status}}) {
totalCount
}
}
`;

export const MULTISIG_RECORD_QUERY = `
query multisigRecords($account: String!, $status: String!,$offset: Int, $limit: Int) {
multisigRecords(offset: $offset, last: $limit, filter: { multisigAccountId: { equalTo: $account }, status: {equalTo: $status}}, orderBy: TIMESTAMP_DESC) {
Expand Down
13 changes: 4 additions & 9 deletions src/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,21 @@ export const routes: RouteProps[] = [
{
exact: true,
path: '/',
children: Home,
component: Home,
},
{
exact: true,
path: '/wallet',
children: Wallet,
component: Wallet,
},
{
exact: true,
path: '/account/:account',
children: Extrinsic,
},
{
exact: true,
path: '/404',
children: null,
component: Extrinsic,
},
{
exact: true,
path: '*',
children: Home,
component: Home,
},
];
11 changes: 7 additions & 4 deletions src/hooks/multisig.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { AnyJson } from '@polkadot/types/types';
import keyring from '@polkadot/ui-keyring';
import { KeyringAddress, KeyringJson } from '@polkadot/ui-keyring/types';
import { encodeAddress } from '@polkadot/util-crypto';
import { difference, intersection } from 'lodash';
import { useCallback, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { convertToSS58 } from '../utils';
import { Entry } from '../model';
import { convertToSS58 } from '../utils';
import { useApi } from './api';

export function useMultisig(acc?: string) {
const [multisigAccount, setMultisigAccount] = useState<KeyringAddress | null>(null);
const { api, networkStatus, network, chain } = useApi();
const { api, networkStatus, chain } = useApi();
const { account } = useParams<{ account: string }>();
const ss58Account = encodeAddress(account, Number(chain.ss58Format));

const [inProgress, setInProgress] = useState<Entry[]>([]);
const [loadingInProgress, setLoadingInProgress] = useState(false);
const queryInProgress = useCallback(async () => {
Expand All @@ -21,7 +24,7 @@ export function useMultisig(acc?: string) {

setLoadingInProgress(true);

const multisig = keyring.getAccount(acc ?? account);
const multisig = keyring.getAccount(acc ?? ss58Account);
// Use different ss58 addresses
(multisig?.meta.addressPair as KeyringJson[])?.forEach((key) => {
key.address = convertToSS58(key.address, Number(chain.ss58Format));
Expand Down Expand Up @@ -64,7 +67,7 @@ export function useMultisig(acc?: string) {
setMultisigAccount(multisig || null);
setInProgress(calls || []);
setLoadingInProgress(false);
}, [api, acc, account, network]);
}, [api, acc, ss58Account, chain]);

useEffect(() => {
if (networkStatus !== 'success') {
Expand Down
77 changes: 76 additions & 1 deletion src/pages/Extrinsic.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,84 @@
import { Card } from 'antd';
import { encodeAddress } from '@polkadot/util-crypto';
import keyring from '@polkadot/ui-keyring';
import { KeyringAddress } from '@polkadot/ui-keyring/types';
import { Card, Spin } from 'antd';
import { useManualQuery } from 'graphql-hooks';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { MULTISIG_ACCOUNT_DETAIL_QUERY } from 'src/config';
import { ShareScope } from 'src/model';
import { updateMultiAccountScope } from 'src/utils';
import { ExtrinsicRecords } from '../components/ExtrinsicRecords';
import { WalletState } from '../components/WalletState';
import { useApi } from '../hooks';
import { EntriesProvider } from '../providers/multisig-provider';

export function Extrinsic() {
const { api, network, chain } = useApi();
const { account } = useParams<{ account: string }>();
const ss58Account = encodeAddress(account, Number(chain.ss58Format));
const [multisig, setMultisig] = useState<KeyringAddress | undefined>();

const [fetchMultisigDetail, { data: multisigDetail }] = useManualQuery<{
multisigAccount: { id: string; threshold: number; members: string[] };
}>(MULTISIG_ACCOUNT_DETAIL_QUERY, {
variables: { ss58Account },
skipCache: true,
});

useEffect(() => {
const localMultisig = keyring.getAccount(ss58Account);

if (!localMultisig) {
fetchMultisigDetail({ variables: { ss58Account }, skipCache: true });
} else {
setMultisig(keyring.getAccount(ss58Account));
}
}, [ss58Account, fetchMultisigDetail]);

useEffect(() => {
const localMultisig = keyring.getAccount(ss58Account);

if (!localMultisig && multisigDetail && multisigDetail.multisigAccount) {
const addressPair = multisigDetail.multisigAccount.members.map((address, index) => ({
name: 'member' + (index + 1),
address,
}));

const snapshotLength = 3;
const walletName = `wallet ${ss58Account.substring(0, snapshotLength)}...${ss58Account.substring(
ss58Account.length - snapshotLength
)}`;

keyring.addMultisig(multisigDetail.multisigAccount.members, multisigDetail.multisigAccount.threshold, {
name: walletName,
addressPair,
genesisHash: api?.genesisHash.toHex(),
});

updateMultiAccountScope(
{
name: walletName,
share: ShareScope.all,
members: addressPair,
threshold: multisigDetail.multisigAccount.threshold,
rememberExternal: false,
},
network
);

setMultisig(keyring.getAccount(ss58Account));
}
}, [ss58Account, multisigDetail, api, network]);

if (!multisig) {
return (
<div className="flex justify-center pt-7">
<Spin size="large" spinning={true}></Spin>
</div>
);
}

return (
<EntriesProvider>
<Card
Expand Down
1 change: 1 addition & 0 deletions src/providers/multisig-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const EntriesProvider = ({ children }: React.PropsWithChildren<unknown>)
const { rpc } = useApi();
const value = useMultisig();
const { account } = useParams<{ account: string }>();

const [fetchData, { data }] = useManualQuery<{ multisigRecords: { totalCount: number } }>(
MULTISIG_RECORD_COUNT_QUERY,
{
Expand Down