Enable "Chain Specific App" setting (#1445)
* Allow for use of chain specific app * Cleanup ordering of metadata check * Update ui to 3.9.1 * Add error for when chain is null * Add setbusy
This commit is contained in:
parent
c5d0fc1b7d
commit
61060c669d
@ -30,8 +30,8 @@
|
||||
"@polkadot/phishing": "^0.23.3",
|
||||
"@polkadot/rpc-provider": "^12.3.1",
|
||||
"@polkadot/types": "^12.3.1",
|
||||
"@polkadot/ui-keyring": "^3.8.3",
|
||||
"@polkadot/ui-settings": "^3.8.3",
|
||||
"@polkadot/ui-keyring": "^3.9.1",
|
||||
"@polkadot/ui-settings": "^3.9.1",
|
||||
"@polkadot/util": "^13.0.2",
|
||||
"@polkadot/util-crypto": "^13.0.2",
|
||||
"eventemitter3": "^5.0.1",
|
||||
|
||||
@ -32,12 +32,12 @@
|
||||
"@polkadot/hw-ledger": "^13.0.2",
|
||||
"@polkadot/keyring": "^13.0.2",
|
||||
"@polkadot/networks": "^13.0.2",
|
||||
"@polkadot/react-identicon": "^3.8.3",
|
||||
"@polkadot/react-qr": "^3.8.3",
|
||||
"@polkadot/react-identicon": "^3.9.1",
|
||||
"@polkadot/react-qr": "^3.9.1",
|
||||
"@polkadot/types": "^12.3.1",
|
||||
"@polkadot/types-augment": "^12.3.1",
|
||||
"@polkadot/ui-keyring": "^3.8.3",
|
||||
"@polkadot/ui-settings": "^3.8.3",
|
||||
"@polkadot/ui-keyring": "^3.9.1",
|
||||
"@polkadot/ui-settings": "^3.9.1",
|
||||
"@polkadot/util": "^13.0.2",
|
||||
"@polkadot/util-crypto": "^13.0.2",
|
||||
"file-saver": "^2.0.5",
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
// Copyright 2019-2024 @polkadot/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/* eslint-disable deprecation/deprecation */
|
||||
|
||||
import type { Chain } from '@polkadot/extension-chains/types';
|
||||
import type { Ledger, LedgerGeneric } from '@polkadot/hw-ledger';
|
||||
import type { ExtrinsicPayload } from '@polkadot/types/interfaces';
|
||||
import type { SignerPayloadJSON } from '@polkadot/types/types';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
@ -23,8 +27,9 @@ interface Props {
|
||||
className?: string;
|
||||
error: string | null;
|
||||
genesisHash?: string;
|
||||
onSignature?: ({ signature }: { signature: HexString }, signedTransaction: HexString) => void;
|
||||
payload?: SignerPayloadJSON;
|
||||
onSignature?: ({ signature }: { signature: HexString }, signedTransaction?: HexString) => void;
|
||||
payloadJson?: SignerPayloadJSON;
|
||||
payloadExt?: ExtrinsicPayload
|
||||
setError: (value: string | null) => void;
|
||||
}
|
||||
|
||||
@ -50,7 +55,7 @@ function getMetadataProof (chain: Chain, payload: SignerPayloadJSON) {
|
||||
};
|
||||
}
|
||||
|
||||
function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHash, onSignature, payload, setError }: Props): React.ReactElement<Props> {
|
||||
function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHash, onSignature, payloadExt, payloadJson, setError }: Props): React.ReactElement<Props> {
|
||||
const [isBusy, setIsBusy] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const chain = useMetadata(genesisHash);
|
||||
@ -69,43 +74,61 @@ function LedgerSign ({ accountIndex, addressOffset, className, error, genesisHas
|
||||
|
||||
const _onSignLedger = useCallback(
|
||||
(): void => {
|
||||
if (!ledger || !payload || !onSignature || !chain) {
|
||||
if (!ledger || !payloadJson || !onSignature || !chain || !payloadExt) {
|
||||
if (!chain) {
|
||||
setError('No chain information found. You may need to update/upload the metadata.');
|
||||
setIsBusy(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chain?.definition.rawMetadata) {
|
||||
setError('No metadata found for this chain. You must upload the metadata to the extension in order to use Ledger.');
|
||||
}
|
||||
|
||||
const { raw, txMetadata } = getMetadataProof(chain, payload);
|
||||
|
||||
const metaBuff = Buffer.from(txMetadata);
|
||||
|
||||
setError(null);
|
||||
setIsBusy(true);
|
||||
ledger.signWithMetadata(raw.toU8a(true), accountIndex, addressOffset, { metadata: metaBuff })
|
||||
.then((signature) => {
|
||||
const extrinsic = chain.registry.createType(
|
||||
'Extrinsic',
|
||||
{ method: raw.method },
|
||||
{ version: 4 }
|
||||
);
|
||||
|
||||
ledger.getAddress(chain.ss58Format, false, accountIndex, addressOffset)
|
||||
.then(({ address }) => {
|
||||
extrinsic.addSignature(address, signature.signature, raw.toHex());
|
||||
onSignature(signature, extrinsic.toHex());
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
setError(e.message);
|
||||
setIsBusy(false);
|
||||
});
|
||||
}).catch((e: Error) => {
|
||||
setError(e.message);
|
||||
setIsBusy(false);
|
||||
});
|
||||
const currApp = settings.get().ledgerApp;
|
||||
|
||||
if (currApp === 'generic' || currApp === 'migration') {
|
||||
if (!chain?.definition.rawMetadata) {
|
||||
setError('No metadata found for this chain. You must upload the metadata to the extension in order to use Ledger.');
|
||||
}
|
||||
|
||||
const { raw, txMetadata } = getMetadataProof(chain, payloadJson);
|
||||
|
||||
const metaBuff = Buffer.from(txMetadata);
|
||||
|
||||
(ledger as LedgerGeneric).signWithMetadata(raw.toU8a(true), accountIndex, addressOffset, { metadata: metaBuff })
|
||||
.then((signature) => {
|
||||
const extrinsic = chain.registry.createType(
|
||||
'Extrinsic',
|
||||
{ method: raw.method },
|
||||
{ version: 4 }
|
||||
);
|
||||
|
||||
(ledger as LedgerGeneric).getAddress(chain.ss58Format, false, accountIndex, addressOffset)
|
||||
.then(({ address }) => {
|
||||
extrinsic.addSignature(address, signature.signature, raw.toHex());
|
||||
onSignature(signature, extrinsic.toHex());
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
setError(e.message);
|
||||
setIsBusy(false);
|
||||
});
|
||||
}).catch((e: Error) => {
|
||||
setError(e.message);
|
||||
setIsBusy(false);
|
||||
});
|
||||
} else if (currApp === 'chainSpecific') {
|
||||
(ledger as Ledger).sign(payloadExt.toU8a(true), accountIndex, addressOffset)
|
||||
.then((signature) => {
|
||||
onSignature(signature);
|
||||
}).catch((e: Error) => {
|
||||
setError(e.message);
|
||||
setIsBusy(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
[accountIndex, addressOffset, chain, ledger, onSignature, payload, setError]
|
||||
[accountIndex, addressOffset, chain, ledger, onSignature, payloadJson, payloadExt, setError]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -117,7 +117,8 @@ export default function Request ({ account: { accountIndex, addressOffset, genes
|
||||
error={error}
|
||||
genesisHash={json.genesisHash}
|
||||
onSignature={_onSignature}
|
||||
payload={json}
|
||||
payloadExt={payload}
|
||||
payloadJson={json}
|
||||
setError={setError}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -10,7 +10,7 @@ import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { LedgerGeneric } from '@polkadot/hw-ledger';
|
||||
import { Ledger, LedgerGeneric } from '@polkadot/hw-ledger';
|
||||
import { knownLedger } from '@polkadot/networks/defaults';
|
||||
import { settings } from '@polkadot/ui-settings';
|
||||
import { assert } from '@polkadot/util';
|
||||
@ -29,7 +29,7 @@ interface State extends StateBase {
|
||||
error: string | null;
|
||||
isLoading: boolean;
|
||||
isLocked: boolean;
|
||||
ledger: LedgerGeneric | null;
|
||||
ledger: LedgerGeneric | Ledger | null;
|
||||
refresh: () => void;
|
||||
warning: string | null;
|
||||
}
|
||||
@ -47,8 +47,8 @@ function getState (): StateBase {
|
||||
};
|
||||
}
|
||||
|
||||
function retrieveLedger (genesis: string): LedgerGeneric {
|
||||
let ledger: LedgerGeneric | null = null;
|
||||
function retrieveLedger (genesis: string): LedgerGeneric | Ledger {
|
||||
let ledger: LedgerGeneric | Ledger | null = null;
|
||||
|
||||
const currApp = settings.get().ledgerApp;
|
||||
|
||||
@ -72,6 +72,8 @@ function retrieveLedger (genesis: string): LedgerGeneric {
|
||||
ledger = new LedgerGeneric('webusb', def.network, knownLedger['polkadot']);
|
||||
} else if (currApp === 'migration') {
|
||||
ledger = new LedgerGeneric('webusb', def.network, knownLedger[def.network]);
|
||||
} else if (currApp === 'chainSpecific') {
|
||||
ledger = new Ledger('webusb', def.network);
|
||||
} else {
|
||||
// This will never get touched since it will always hit the above two. This satisfies the compiler.
|
||||
ledger = new LedgerGeneric('webusb', def.network, knownLedger['polkadot']);
|
||||
@ -89,6 +91,28 @@ export default function useLedger (genesis?: string | null, accountIndex = 0, ad
|
||||
const [address, setAddress] = useState<string | null>(null);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleGetAddressError = (e: Error, genesis: string) => {
|
||||
setIsLoading(false);
|
||||
const { network } = getNetwork(genesis) || { network: 'unknown network' };
|
||||
|
||||
const warningMessage = e.message.includes('Code: 26628')
|
||||
? t('Is your ledger locked?')
|
||||
: null;
|
||||
|
||||
const errorMessage = e.message.includes('App does not seem to be open')
|
||||
? t('App "{{network}}" does not seem to be open', { replace: { network } })
|
||||
: e.message;
|
||||
|
||||
setIsLocked(true);
|
||||
setWarning(warningMessage);
|
||||
setError(t(
|
||||
'Ledger error: {{errorMessage}}',
|
||||
{ replace: { errorMessage } }
|
||||
));
|
||||
console.error(e);
|
||||
setAddress(null);
|
||||
};
|
||||
|
||||
const ledger = useMemo(() => {
|
||||
setError(null);
|
||||
setIsLocked(false);
|
||||
@ -131,31 +155,25 @@ export default function useLedger (genesis?: string | null, accountIndex = 0, ad
|
||||
// Just in case, but this shouldn't be triggered
|
||||
assert(chosenNetwork, t('This network is not available, please report an issue to update the known chains'));
|
||||
|
||||
ledger.getAddress(chosenNetwork.ss58Format, false, accountIndex, addressOffset)
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
setAddress(res.address);
|
||||
}).catch((e: Error) => {
|
||||
setIsLoading(false);
|
||||
const { network } = getNetwork(genesis) || { network: 'unknown network' };
|
||||
const currApp = settings.get().ledgerApp;
|
||||
|
||||
const warningMessage = e.message.includes('Code: 26628')
|
||||
? t('Is your ledger locked?')
|
||||
: null;
|
||||
|
||||
const errorMessage = e.message.includes('App does not seem to be open')
|
||||
? t('App "{{network}}" does not seem to be open', { replace: { network } })
|
||||
: e.message;
|
||||
|
||||
setIsLocked(true);
|
||||
setWarning(warningMessage);
|
||||
setError(t(
|
||||
'Ledger error: {{errorMessage}}',
|
||||
{ replace: { errorMessage } }
|
||||
));
|
||||
console.error(e);
|
||||
setAddress(null);
|
||||
});
|
||||
if (currApp === 'generic' || currApp === 'migration') {
|
||||
(ledger as LedgerGeneric).getAddress(chosenNetwork.ss58Format, false, accountIndex, addressOffset)
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
setAddress(res.address);
|
||||
}).catch((e: Error) => {
|
||||
handleGetAddressError(e, genesis);
|
||||
});
|
||||
} else if (currApp === 'chainSpecific') {
|
||||
(ledger as Ledger).getAddress(false, accountIndex, addressOffset)
|
||||
.then((res) => {
|
||||
setIsLoading(false);
|
||||
setAddress(res.address);
|
||||
}).catch((e: Error) => {
|
||||
handleGetAddressError(e, genesis);
|
||||
});
|
||||
}
|
||||
// If the dependency array is exhaustive, with t, the translation function, it
|
||||
// triggers a useless re-render when ledger device is connected.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
60
yarn.lock
60
yarn.lock
@ -929,8 +929,8 @@ __metadata:
|
||||
"@polkadot/phishing": "npm:^0.23.3"
|
||||
"@polkadot/rpc-provider": "npm:^12.3.1"
|
||||
"@polkadot/types": "npm:^12.3.1"
|
||||
"@polkadot/ui-keyring": "npm:^3.8.3"
|
||||
"@polkadot/ui-settings": "npm:^3.8.3"
|
||||
"@polkadot/ui-keyring": "npm:^3.9.1"
|
||||
"@polkadot/ui-settings": "npm:^3.9.1"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
"@polkadot/util-crypto": "npm:^13.0.2"
|
||||
eventemitter3: "npm:^5.0.1"
|
||||
@ -1036,12 +1036,12 @@ __metadata:
|
||||
"@polkadot/hw-ledger": "npm:^13.0.2"
|
||||
"@polkadot/keyring": "npm:^13.0.2"
|
||||
"@polkadot/networks": "npm:^13.0.2"
|
||||
"@polkadot/react-identicon": "npm:^3.8.3"
|
||||
"@polkadot/react-qr": "npm:^3.8.3"
|
||||
"@polkadot/react-identicon": "npm:^3.9.1"
|
||||
"@polkadot/react-qr": "npm:^3.9.1"
|
||||
"@polkadot/types": "npm:^12.3.1"
|
||||
"@polkadot/types-augment": "npm:^12.3.1"
|
||||
"@polkadot/ui-keyring": "npm:^3.8.3"
|
||||
"@polkadot/ui-settings": "npm:^3.8.3"
|
||||
"@polkadot/ui-keyring": "npm:^3.9.1"
|
||||
"@polkadot/ui-settings": "npm:^3.9.1"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
"@polkadot/util-crypto": "npm:^13.0.2"
|
||||
"@types/enzyme": "npm:^3.10.18"
|
||||
@ -1165,13 +1165,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/react-identicon@npm:^3.8.3":
|
||||
version: 3.8.3
|
||||
resolution: "@polkadot/react-identicon@npm:3.8.3"
|
||||
"@polkadot/react-identicon@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@polkadot/react-identicon@npm:3.9.1"
|
||||
dependencies:
|
||||
"@polkadot/keyring": "npm:^13.0.2"
|
||||
"@polkadot/ui-settings": "npm:3.8.3"
|
||||
"@polkadot/ui-shared": "npm:3.8.3"
|
||||
"@polkadot/ui-settings": "npm:3.9.1"
|
||||
"@polkadot/ui-shared": "npm:3.9.1"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
"@polkadot/util-crypto": "npm:^13.0.2"
|
||||
ethereum-blockies-base64: "npm:^1.0.2"
|
||||
@ -1186,15 +1186,15 @@ __metadata:
|
||||
react: "*"
|
||||
react-dom: "*"
|
||||
react-is: "*"
|
||||
checksum: 10/6dddfca42732d141acd2e460d25635845287e0e8bfae6c170f72a691c49b1f34d08e1e975d1a2c2216e1814f1928a29982b806d6bc30f3f08ddddad214b91867
|
||||
checksum: 10/6a3ad4e129af15e2d6833def626085e392c960211935cf901560f434247560ae6dcfb8d8ecde38b56f317ac3e0d84653ef9c5b68e258c2791467b1339b595bef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/react-qr@npm:^3.8.3":
|
||||
version: 3.8.3
|
||||
resolution: "@polkadot/react-qr@npm:3.8.3"
|
||||
"@polkadot/react-qr@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@polkadot/react-qr@npm:3.9.1"
|
||||
dependencies:
|
||||
"@polkadot/ui-settings": "npm:3.8.3"
|
||||
"@polkadot/ui-settings": "npm:3.9.1"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
"@polkadot/util-crypto": "npm:^13.0.2"
|
||||
"@zxing/browser": "npm:^0.1.5"
|
||||
@ -1208,7 +1208,7 @@ __metadata:
|
||||
react: "*"
|
||||
react-dom: "*"
|
||||
react-is: "*"
|
||||
checksum: 10/1afb77b45a4b6bf0cb110dbf405bfd8a1edbabb9e4639e3b34f0f7f0c1c706799f462b1590e18da8d8de369172f075bdbc9800e7d54e9b48041724203294c600
|
||||
checksum: 10/f196e19e6d5c11ef7f7824fa67ad41fcde790ad6505113a2e8383c4c79c5c2a8947a619c0513709d9983679ff60af7f8c0811e1a232772fb5438dcbecd442e21
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1337,12 +1337,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/ui-keyring@npm:^3.8.3":
|
||||
version: 3.8.3
|
||||
resolution: "@polkadot/ui-keyring@npm:3.8.3"
|
||||
"@polkadot/ui-keyring@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@polkadot/ui-keyring@npm:3.9.1"
|
||||
dependencies:
|
||||
"@polkadot/keyring": "npm:^13.0.2"
|
||||
"@polkadot/ui-settings": "npm:3.8.3"
|
||||
"@polkadot/ui-settings": "npm:3.9.1"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
"@polkadot/util-crypto": "npm:^13.0.2"
|
||||
mkdirp: "npm:^3.0.1"
|
||||
@ -1353,13 +1353,13 @@ __metadata:
|
||||
"@polkadot/keyring": "*"
|
||||
"@polkadot/ui-settings": "*"
|
||||
"@polkadot/util": "*"
|
||||
checksum: 10/d8b3ebf3da39ebbcabe1e0c41c9ed731a14c186c1698c598b4aac6217162c7174453860d06582200b10bc687fc75ec713238ce1687efb4672de989ab728ee99f
|
||||
checksum: 10/eec438ef2ad9363d77f51d60df9802f1cad3379661883a9412f9ca1af44e31444fc7c04eec1ec7ecf2ae76af1718ffce8e335dcf572d89a6ffc6403bf6c36423
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/ui-settings@npm:3.8.3, @polkadot/ui-settings@npm:^3.8.3":
|
||||
version: 3.8.3
|
||||
resolution: "@polkadot/ui-settings@npm:3.8.3"
|
||||
"@polkadot/ui-settings@npm:3.9.1, @polkadot/ui-settings@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@polkadot/ui-settings@npm:3.9.1"
|
||||
dependencies:
|
||||
"@polkadot/networks": "npm:^13.0.2"
|
||||
"@polkadot/util": "npm:^13.0.2"
|
||||
@ -1369,20 +1369,20 @@ __metadata:
|
||||
peerDependencies:
|
||||
"@polkadot/networks": "*"
|
||||
"@polkadot/util": "*"
|
||||
checksum: 10/be6d9f5111ba94b9e86b3348bd0f7e68008611b54fcc159b3a163d7331b345f1552b2d1ba7b6b763387607110e06eecd799b7ad61ee4d5847056b128a85bfdcf
|
||||
checksum: 10/d3a28af0233f2ee9a8453501de3dd2fabc46bc98cb4c0e46a79654c87a0a41f3148dd6949b796932a4c12fc974b2b924d9eb0e76f91f7ce9ea27e5012e1e606a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/ui-shared@npm:3.8.3":
|
||||
version: 3.8.3
|
||||
resolution: "@polkadot/ui-shared@npm:3.8.3"
|
||||
"@polkadot/ui-shared@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@polkadot/ui-shared@npm:3.9.1"
|
||||
dependencies:
|
||||
colord: "npm:^2.9.3"
|
||||
tslib: "npm:^2.6.2"
|
||||
peerDependencies:
|
||||
"@polkadot/util": "*"
|
||||
"@polkadot/util-crypto": "*"
|
||||
checksum: 10/a7cbeed7ccbe2f3212d20155787d3a7f4ec2a5662dfb950d965a1ac8ea05fd380f3b9456147cf2e15dc5adbf0df71eedfd94c0707db44a16f1bf2f84c0ebf01c
|
||||
checksum: 10/80a3a59ca25ed0e572a2eb85533f54f9714c6fd21f85fcf46775fc57c5d55c048049378c94372260df9d860569197ea38dbf3a24cc8ed1e416f67c69408f3789
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user