Skip to content
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
100 changes: 28 additions & 72 deletions packages/page-claims/src/Attest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,101 +2,50 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { Signer } from '@polkadot/api/types';
import { web3FromSource } from '@polkadot/extension-dapp';
import { KeyringPair } from '@polkadot/keyring/types';
import { Button, Card } from '@polkadot/react-components';
import keyring from '@polkadot/ui-keyring';
import { stringToHex, stringToU8a, u8aToHex } from '@polkadot/util';

import React, { useCallback, useEffect, useState } from 'react';
import React from 'react';
import styled from 'styled-components';
import { Button, Card, TxButton } from '@polkadot/react-components';

import { useTranslation } from './translate';
import { addrToChecksum } from './util';

interface Props {
accountId: string;
className?: string;
data: string;
onNextStep: (signature: string) => void;
}

function Attest ({ accountId, className, data, onNextStep }: Props): React.ReactElement<Props> | null {
function Attest ({ accountId, className }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
// const [attestSignature, setAttestSignature] = useState<string | null>(null);
const [currentPair, setCurrentPair] = useState<KeyringPair | null>(null);
const [signer, setSigner] = useState<Signer | null >(null);

useEffect((): void => {
const isInjected = currentPair?.meta.isInjected || false;

// for injected, retrieve the signer
if (currentPair && isInjected) {
const { meta: { source } } = currentPair;

web3FromSource(source)
.catch((): null => null)
.then((injected): void => setSigner(
injected?.signer || null
));
}
}, [currentPair]);

useEffect(() => {
setCurrentPair(keyring.getPair(accountId || ''));
}, [accountId]);

const _signAttest = useCallback(
(): void => {
if (!currentPair) {
return;
}

if (signer?.signRaw) {
signer
.signRaw({
address: currentPair.address,
data: stringToHex(data),
type: 'bytes'
})
.then(({ signature }): void => onNextStep(signature));
} else {
onNextStep(u8aToHex(
currentPair.sign(stringToU8a(data))
));
}
},
[currentPair, data, onNextStep, signer]
);

return (
<Card className={className}>
<h3>{t('3. Sign attestation')}</h3>
<div>
{t('Clicking the following button will let you sign the hash of the attestation available at the following address: XXX')}
:
<Card>
<div className={className}>
{t('By signing this transaction, you agree with attestation available at the following address: XXX')}
<h3>{addrToChecksum(accountId)}</h3>
<Button.Group>
<TxButton
accountId={accountId}
icon='send'
isPrimary
label={t('Attest')}
params={['Default']} // Replace with actual
tx='claims.attest'
/>
</Button.Group>
</div>
<Button.Group>
<Button
icon='sign-in'
isDisabled={!accountId}
label={t('Sign attestation')}
onClick={_signAttest}
/>
</Button.Group>

</Card>
);
}

// FIXME Same styles as ./Claim.tsx
export default React.memo(styled(Attest)`
/* font-size: 1.15rem;
font-size: 1.15rem;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 12rem;
align-items: center;
margin: 0 1rem; */
margin: 0 1rem;

h3 {
font-family: monospace;
Expand All @@ -107,4 +56,11 @@ export default React.memo(styled(Attest)`
text-overflow: ellipsis;
white-space: nowrap;
}

h2 {
margin: 0.5rem 0 2rem;
font-family: monospace;
font-size: 2.5rem;
font-weight: 200;
}
`);
30 changes: 26 additions & 4 deletions packages/page-claims/src/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,34 @@ import { BalanceOf, EthereumAddress } from '@polkadot/types/interfaces';

import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { Button, Card } from '@polkadot/react-components';
import { Button, Card, TxButton } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import { FormatBalance } from '@polkadot/react-query';

import { useTranslation } from './translate';
import { addrToChecksum } from './util';

interface Props {
button: React.ReactNode;
accountId: string;
className?: string;
ethereumAddress: EthereumAddress | null;
ethereumSignature: string | null;
// Do we sign with `claims.claimAttest` instead of `claims.claim`?
isClaimAttest: boolean;
}

function Claim ({ button, className, ethereumAddress }: Props): React.ReactElement<Props> | null {
// Depending on isClaimAttest, construct the correct tx.
function constructTx (accountId: string, ethereumSignature: string | null, isClaimAttest: boolean): {
params: any[];
tx: string;
} {
return isClaimAttest
// FIXME How to get the StatementKind?
? { params: [accountId, ethereumSignature, 'Default'], tx: 'claims.claimAttest' }
: { params: [accountId, ethereumSignature], tx: 'claims.claimAttest' };
}

function Claim ({ accountId, className, ethereumAddress, ethereumSignature, isClaimAttest }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const [claimValue, setClaimValue] = useState<BalanceOf | null>(null);
Expand Down Expand Up @@ -67,7 +81,15 @@ function Claim ({ button, className, ethereumAddress }: Props): React.ReactEleme
<>
{t('has a valid claim for')}
<h2><FormatBalance value={claimValue} /></h2>
<Button.Group>{button}</Button.Group>
<Button.Group>
<TxButton
accountId={accountId}
icon='send'
isPrimary
label={t('Claim')}
{...constructTx(accountId, ethereumSignature, isClaimAttest)}
/>
</Button.Group>
</>
)
: (
Expand Down
17 changes: 11 additions & 6 deletions packages/page-claims/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import CopyToClipboard from 'react-copy-to-clipboard';
import { withApi, withMulti } from '@polkadot/react-api/hoc';
import { Button, Card, Columar, Column, InputAddress, Tooltip } from '@polkadot/react-components';
import { TokenUnit } from '@polkadot/react-components/InputNumber';
import TxModal, { TxModalState, TxModalProps } from '@polkadot/react-components/TxModal';
import { u8aToHex, u8aToString } from '@polkadot/util';
import { decodeAddress } from '@polkadot/util-crypto';

import AttestDisplay from './Attest';
import ClaimDisplay from './Claim';
import { recoverFromJSON } from './util';
import translate, { useTranslation } from './translate';
Expand All @@ -30,7 +30,7 @@ enum Step {
Claim = 2,
}

interface Props extends AppProps, ApiProps, I18nProps, TxModalProps { }
interface Props extends AppProps, ApiProps, I18nProps { }

// FIXME no embedded components (hossible to tweak)
const Payload = styled.pre`
Expand Down Expand Up @@ -203,10 +203,15 @@ const ClaimsApp = (props: Props): React.ReactElement => {
</Column>
<Column showEmptyText={false}>
{(step >= Step.Claim) && (
<ClaimDisplay
// button={this.renderTxButton()}
ethereumAddress={ethereumAddress}
/>
isPreclaimed
? <AttestDisplay accountId={accountId} />
: <ClaimDisplay
accountId={accountId}
ethereumAddress={ethereumAddress}
ethereumSignature={signature}
// Use claims.claimAttest is chain supports it
isClaimAttest={!!api.query.claims.claimAttest}
/>
)}
</Column>
</Columar>
Expand Down