Skip to content
This repository has been archived by the owner on Jul 13, 2022. It is now read-only.

Commit

Permalink
CU-2mk06uu_Check-if-there-is-an-multisigMultisigExecutied_Aleksandr-M…
Browse files Browse the repository at this point in the history
…akhnyov (#98)

* feat: check final approve
* feat: multisig approve fee
  • Loading branch information
Asmadek authored Jun 20, 2022
1 parent 368b9da commit 345eb6c
Show file tree
Hide file tree
Showing 10 changed files with 374 additions and 173 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
"@hookform/resolvers": "^2.8.8",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
"@polkadot/react-identicon": "^2.0.1",
"@polkadot/react-qr": "^2.0.1",
"@polkadot/react-qr": "^2.5.1",
"autoprefixer": "^10.4.0",
"bignumber.js": "^9.0.2",
"classnames": "^2.3.1",
Expand Down
4 changes: 4 additions & 0 deletions release/app/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


9 changes: 7 additions & 2 deletions src/renderer/components/Actions/Transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { useMatrix } from '../Providers/MatrixProvider';
import { HexString } from '../../../common/types';
import {
getExistingMstTransactions,
getTxExtrinsic,
getTransferExtrinsic,
} from '../../utils/transactions';
import InputSelect from '../../ui/InputSelect';
import Fee from '../../ui/Fee';
Expand Down Expand Up @@ -92,7 +92,7 @@ const Transfer: React.FC = () => {
isValid &&
firstWallet
) {
const transferExtrinsic = getTxExtrinsic(
const transferExtrinsic = getTransferExtrinsic(
currentNetwork,
currentAsset,
watchAddress,
Expand Down Expand Up @@ -349,6 +349,11 @@ const Transfer: React.FC = () => {
The amount is not valid, please type it again
</ErrorMessage>
<Fee
type={
isMultisig(firstWallet)
? TransactionType.MULTISIG_TRANSFER
: TransactionType.TRANSFER
}
wallet={firstWallet}
connection={currentNetwork}
address={watchAddress}
Expand Down
254 changes: 128 additions & 126 deletions src/renderer/components/ScanCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
TransactionType,
MultisigWallet,
} from '../db/types';
import { isFinalApprove } from '../utils/transactions';
import { getAddressFromWallet, toPublicKey } from '../utils/account';
import { useMatrix } from './Providers/MatrixProvider';
import Shimmer from '../ui/Shimmer';
Expand Down Expand Up @@ -105,136 +104,139 @@ const ScanCode: React.FC = () => {
metadataRpc: metadataRpc.toHex(),
registry,
});
try {
network.api.rpc.author.submitAndWatchExtrinsic(tx, async (result) => {
if (!result.isInBlock) return;

let actualTxHash = result.inner;

const signedBlock = await network.api.rpc.chain.getBlock();
const apiAt = await network.api.at(signedBlock.block.header.hash);
const allRecords = await apiAt.query.system.events();
let isFinalApprove = false;
let isSuccessExtrinsic = false;

// the information for each of the contained extrinsics
signedBlock.block.extrinsics.forEach(
({ method: { method, section }, signer, args, hash }, index) => {
if (
method !== tx.method.method ||
section !== tx.method.section ||
signer.toHex() !== tx.signer.toHex() ||
args[0]?.toString() !== tx.args[0]?.toString() ||
args[1]?.toString() !== tx.args[1]?.toString() ||
args[2]?.toString() !== tx.args[2]?.toString()
) {
return;
}

allRecords
.filter(
({ phase }) =>
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index),
)
.forEach(({ event }) => {
if (network.api.events.multisig.MultisigExecuted.is(event)) {
isFinalApprove = true;
}

network.api.rpc.author.submitAndWatchExtrinsic(tx, async (result) => {
if (!result.isInBlock) return;

let actualTxHash = result.inner;

const signedBlock = await network.api.rpc.chain.getBlock();
const apiAt = await network.api.at(signedBlock.block.header.hash);
const allRecords = await apiAt.query.system.events();

// the information for each of the contained extrinsics
signedBlock.block.extrinsics.forEach(
({ method: { method, section }, signer, args, hash }, index) => {
if (
method !== tx.method.method ||
section !== tx.method.section ||
signer.toHex() !== tx.signer.toHex() ||
args[0]?.toString() !== tx.args[0]?.toString() ||
args[1]?.toString() !== tx.args[1]?.toString() ||
args[2]?.toString() !== tx.args[2]?.toString()
) {
return;
}
if (network.api.events.system.ExtrinsicSuccess.is(event)) {
actualTxHash = hash;
isSuccessExtrinsic = true;
}

allRecords
.filter(
({ phase }) =>
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index),
)
.forEach(({ event }) => {
if (network.api.events.system.ExtrinsicSuccess.is(event)) {
actualTxHash = hash;
if (!actualTxHash || !transaction.id) return;

const extrinsicHash = actualTxHash.toHex();

if (transaction.type === TransactionType.TRANSFER) {
db.transactions.update(transaction.id, {
...transaction,
transactionHash: actualTxHash.toHex(),
status: TransactionStatus.CONFIRMED,
});
} else if (
transaction.type === TransactionType.MULTISIG_TRANSFER
) {
const transactionStatus = isFinalApprove(transaction)
? TransactionStatus.CONFIRMED
: TransactionStatus.PENDING;

const publicKey = toPublicKey(
signWith?.mainAccounts[0].accountId || '',
);

const { approvals } = transaction.data;
const approvalsPayload = {
...approvals,
[publicKey]: {
...approvals[publicKey],
fromMatrix: true,
fromBlockChain: true,
extrinsicHash,
},
};

db.transactions.update(transaction.id, {
status: transactionStatus,
data: {
...transaction.data,
approvals: approvalsPayload,
},
});

const multisigWallet = transaction.wallet as MultisigWallet;
if (signWith && multisigWallet.matrixRoomId) {
matrix.setRoom(multisigWallet.matrixRoomId);

if (transactionStatus === TransactionStatus.CONFIRMED) {
matrix.mstFinalApprove({
senderAddress: getAddressFromWallet(
signWith,
network.network,
),
salt: transaction.data.salt,
extrinsicHash,
chainId: network.network.chainId,
callHash: transaction.data.callHash,
});
}

if (transactionStatus === TransactionStatus.PENDING) {
matrix.mstApprove({
senderAddress: getAddressFromWallet(
signWith,
network.network,
),
salt: transaction.data.salt,
extrinsicHash,
chainId: network.network.chainId,
callHash: transaction.data.callHash,
});
}
if (network.api.events.system.ExtrinsicFailed.is(event)) {
const [dispatchError] = event.data;
let errorInfo;

if (dispatchError.isModule) {
const decoded = network.api.registry.findMetaError(
dispatchError.asModule,
);

errorInfo = `${decoded.name
.split(/(?=[A-Z])/)
.map((w) => w.toLowerCase())
.join(' ')}`;
} else {
errorInfo = dispatchError.toString();
}
setError(capitalize(errorInfo));
setDialogOpen(true);
}
});
},
);

if (!isSuccessExtrinsic || !actualTxHash || !transaction.id) return;

const extrinsicHash = actualTxHash.toHex();

if (transaction.type === TransactionType.TRANSFER) {
db.transactions.update(transaction.id, {
...transaction,
transactionHash: actualTxHash.toHex(),
status: TransactionStatus.CONFIRMED,
});
} else if (transaction.type === TransactionType.MULTISIG_TRANSFER) {
const transactionStatus = isFinalApprove
? TransactionStatus.CONFIRMED
: TransactionStatus.PENDING;

const publicKey = toPublicKey(
signWith?.mainAccounts[0].accountId || '',
);

const { approvals } = transaction.data;
const approvalsPayload = {
...approvals,
[publicKey]: {
...approvals[publicKey],
fromMatrix: true,
fromBlockChain: true,
extrinsicHash,
},
};

db.transactions.update(transaction.id, {
status: transactionStatus,
data: {
...transaction.data,
approvals: approvalsPayload,
},
});

const multisigWallet = transaction.wallet as MultisigWallet;
if (signWith && multisigWallet.matrixRoomId) {
matrix.setRoom(multisigWallet.matrixRoomId);

const matrixEventData = {
senderAddress: getAddressFromWallet(signWith, network.network),
salt: transaction.data.salt,
extrinsicHash,
chainId: network.network.chainId,
callHash: transaction.data.callHash,
};

if (transactionStatus === TransactionStatus.CONFIRMED) {
matrix.mstFinalApprove(matrixEventData);
}

if (transactionStatus === TransactionStatus.PENDING) {
matrix.mstApprove(matrixEventData);
}
}
}

history.push(withId(Routes.TRANSFER_DETAILS, transaction.id));
}
if (network.api.events.system.ExtrinsicFailed.is(event)) {
actualTxHash = hash;
const [dispatchError] = event.data;
let errorInfo;

if (dispatchError.isModule) {
const decoded = network.api.registry.findMetaError(
dispatchError.asModule,
);

errorInfo = `${decoded.name
.split(/(?=[A-Z])/)
.map((w) => w.toLowerCase())
.join(' ')}`;
} else {
errorInfo = dispatchError.toString();
}
setError(capitalize(errorInfo));
setDialogOpen(true);
}
});
},
);
});
history.push(withId(Routes.TRANSFER_DETAILS, transaction.id));
});
} catch (e) {
let message = 'Unknown error';
if (e instanceof Error) message = e.message;

setError(capitalize(message));
setDialogOpen(true);
}
};

return (
Expand Down
55 changes: 27 additions & 28 deletions src/renderer/components/ShowCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,38 +156,35 @@ const ShowCode: React.FC = () => {
: [];
const { threshold } = transaction.wallet as MultisigWallet;

const approveData = {
threshold,
otherSignatories,
maybeTimepoint: when,
callHash: transaction.data.callHash,
maxWeight: MAX_WEIGHT,
call: transaction.data.callData,
storeCall: false,
};

const multisig = {
approve: () => {
return methods.multisig.asMulti(
{
threshold,
otherSignatories,
maybeTimepoint: when,
callHash: transaction.data.callHash,
maxWeight: MAX_WEIGHT,
call: transaction.data.callData,
storeCall: false,
},
info,
options,
return methods.multisig.asMulti(approveData, info, options);
},
cancel: () => {
return (
when &&
methods.multisig.cancelAsMulti(
{
threshold,
otherSignatories,
timepoint: when,
callHash: transaction.data.callHash,
},
info,
options,
)
);
},
// TODO: Use it for cancel transaction
// cancel: () => {
// return (
// when &&
// methods.multisig.cancelAsMulti(
// {
// threshold,
// otherSignatories,
// timepoint: when,
// callHash: transaction.data.callHash,
// },
// info,
// options,
// )
// );
// },
};
let unsignedAction = transfers[asset?.type || DEFAULT];

Expand Down Expand Up @@ -246,6 +243,8 @@ const ShowCode: React.FC = () => {
<Fee
wallet={signWith || transaction.wallet}
connection={connection}
type={transaction.type}
transaction={transaction}
address={transaction.data.address}
amount={transaction.data.amount}
withTransferable
Expand Down
Loading

0 comments on commit 345eb6c

Please sign in to comment.