Add set authority transaction type
This commit is contained in:
parent
2d76e541fa
commit
0171f2e946
|
@ -41,6 +41,7 @@ import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||||
import ListItem from "@material-ui/core/ListItem";
|
import ListItem from "@material-ui/core/ListItem";
|
||||||
import ListItemText from "@material-ui/core/ListItemText";
|
import ListItemText from "@material-ui/core/ListItemText";
|
||||||
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
|
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
|
||||||
|
import FaceIcon from "@material-ui/icons/Face";
|
||||||
import BN from "bn.js";
|
import BN from "bn.js";
|
||||||
import {
|
import {
|
||||||
Account,
|
Account,
|
||||||
|
@ -314,7 +315,9 @@ export function NewMultisigDialog({
|
||||||
label="Max Number of Participants (cannot grow the owner set past this)"
|
label="Max Number of Participants (cannot grow the owner set past this)"
|
||||||
value={maxParticipantLength}
|
value={maxParticipantLength}
|
||||||
type="number"
|
type="number"
|
||||||
onChange={(e) => setMaxParticipantLength(parseInt(e.target.value) as number)}
|
onChange={(e) =>
|
||||||
|
setMaxParticipantLength(parseInt(e.target.value) as number)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{participants.map((p, idx) => (
|
{participants.map((p, idx) => (
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -592,13 +595,20 @@ function TxListItem({
|
||||||
function ixLabel(tx: any, multisigClient: any) {
|
function ixLabel(tx: any, multisigClient: any) {
|
||||||
if (tx.account.programId.equals(BPF_LOADER_UPGRADEABLE_PID)) {
|
if (tx.account.programId.equals(BPF_LOADER_UPGRADEABLE_PID)) {
|
||||||
// Upgrade instruction.
|
// Upgrade instruction.
|
||||||
if (tx.account.data.equals(Buffer.from([3, 0, 0, 0]))) {
|
if (tx.account.data.equals(upgradeData())) {
|
||||||
return (
|
return (
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary="Program upgrade"
|
primary="Program upgrade"
|
||||||
secondary={tx.publicKey.toString()}
|
secondary={tx.publicKey.toString()}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} else if (tx.account.data.equals(setAuthorityData())) {
|
||||||
|
return (
|
||||||
|
<ListItemText
|
||||||
|
primary="Set Authority"
|
||||||
|
secondary={tx.publicKey.toString()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tx.account.programId.equals(multisigClient.programId)) {
|
if (tx.account.programId.equals(multisigClient.programId)) {
|
||||||
|
@ -762,12 +772,152 @@ function AddTransactionDialog({
|
||||||
multisig={multisig}
|
multisig={multisig}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
/>
|
/>
|
||||||
|
<SetAuthorityListItem
|
||||||
|
didAddTransaction={didAddTransaction}
|
||||||
|
multisig={multisig}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
</List>
|
</List>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SetAuthorityListItem({
|
||||||
|
multisig,
|
||||||
|
onClose,
|
||||||
|
didAddTransaction,
|
||||||
|
}: {
|
||||||
|
multisig: PublicKey;
|
||||||
|
onClose: Function;
|
||||||
|
didAddTransaction: (tx: PublicKey) => void;
|
||||||
|
}) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ListItem button onClick={() => setOpen((open) => !open)}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<FaceIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={"Set Authority"} />
|
||||||
|
{open ? <ExpandLess /> : <ExpandMore />}
|
||||||
|
</ListItem>
|
||||||
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
|
<SetAuthorityListItemDetails
|
||||||
|
didAddTransaction={didAddTransaction}
|
||||||
|
multisig={multisig}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
</Collapse>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetAuthorityListItemDetails({
|
||||||
|
multisig,
|
||||||
|
onClose,
|
||||||
|
didAddTransaction,
|
||||||
|
}: {
|
||||||
|
multisig: PublicKey;
|
||||||
|
onClose: Function;
|
||||||
|
didAddTransaction: (tx: PublicKey) => void;
|
||||||
|
}) {
|
||||||
|
// @ts-ignore
|
||||||
|
const [newAuthority, setNewAuthority] = useState(new PublicKey());
|
||||||
|
// @ts-ignore
|
||||||
|
const [bufferAccount, setBufferAccount] = useState(new PublicKey());
|
||||||
|
const { multisigClient } = useWallet();
|
||||||
|
// @ts-ignore
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const setAuthority = async () => {
|
||||||
|
enqueueSnackbar("Creating set authority transaction", {
|
||||||
|
variant: "info",
|
||||||
|
});
|
||||||
|
const data = setAuthorityData();
|
||||||
|
const [multisigSigner] = await PublicKey.findProgramAddress(
|
||||||
|
[multisig.toBuffer()],
|
||||||
|
multisigClient.programId
|
||||||
|
);
|
||||||
|
const accounts = [
|
||||||
|
{
|
||||||
|
pubkey: bufferAccount,
|
||||||
|
isWritable: true,
|
||||||
|
isSigner: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pubkey: multisigSigner,
|
||||||
|
isWritable: false,
|
||||||
|
isSigner: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pubkey: newAuthority,
|
||||||
|
isWritable: false,
|
||||||
|
isSigner: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const transaction = new Account();
|
||||||
|
const txSize = 1000; // todo
|
||||||
|
const tx = await multisigClient.rpc.createTransaction(
|
||||||
|
BPF_LOADER_UPGRADEABLE_PID,
|
||||||
|
accounts,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
accounts: {
|
||||||
|
multisig,
|
||||||
|
transaction: transaction.publicKey,
|
||||||
|
proposer: multisigClient.provider.wallet.publicKey,
|
||||||
|
rent: SYSVAR_RENT_PUBKEY,
|
||||||
|
},
|
||||||
|
signers: [transaction],
|
||||||
|
instructions: [
|
||||||
|
await multisigClient.account.transaction.createInstruction(
|
||||||
|
transaction,
|
||||||
|
// @ts-ignore
|
||||||
|
txSize
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
enqueueSnackbar("Transaction created", {
|
||||||
|
variant: "success",
|
||||||
|
action: <ViewTransactionOnExplorerButton signature={tx} />,
|
||||||
|
});
|
||||||
|
didAddTransaction(transaction.publicKey);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: "#f1f0f0",
|
||||||
|
paddingLeft: "24px",
|
||||||
|
paddingRight: "24px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
style={{ marginTop: "16px" }}
|
||||||
|
label="Buffer or Program Data Account"
|
||||||
|
value={bufferAccount}
|
||||||
|
onChange={(e) => {
|
||||||
|
setBufferAccount(new PublicKey(e.target.value as string));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
style={{ marginTop: "16px" }}
|
||||||
|
label="New Authority"
|
||||||
|
value={newAuthority}
|
||||||
|
onChange={(e) => {
|
||||||
|
setNewAuthority(new PublicKey(e.target.value as string));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||||
|
<Button onClick={() => setAuthority()}>Set Authority</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function ChangeThresholdListItem({
|
function ChangeThresholdListItem({
|
||||||
multisig,
|
multisig,
|
||||||
onClose,
|
onClose,
|
||||||
|
@ -1220,7 +1370,7 @@ function UpgradeProgramListItemDetails({
|
||||||
const programAddr = new PublicKey(programId as string);
|
const programAddr = new PublicKey(programId as string);
|
||||||
const bufferAddr = new PublicKey(buffer as string);
|
const bufferAddr = new PublicKey(buffer as string);
|
||||||
// Hard code serialization.
|
// Hard code serialization.
|
||||||
const data = Buffer.from([3, 0, 0, 0]);
|
const data = upgradeData();
|
||||||
|
|
||||||
const programAccount = await (async () => {
|
const programAccount = await (async () => {
|
||||||
const programAccount = await multisigClient.provider.connection.getAccountInfo(
|
const programAccount = await multisigClient.provider.connection.getAccountInfo(
|
||||||
|
@ -1324,7 +1474,11 @@ function UpgradeProgramListItemDetails({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
function icon(tx, multisigClient) {
|
function icon(tx, multisigClient) {
|
||||||
if (tx.account.programId.equals(BPF_LOADER_UPGRADEABLE_PID)) {
|
if (tx.account.programId.equals(BPF_LOADER_UPGRADEABLE_PID)) {
|
||||||
|
if (tx.account.data[0] === 3) {
|
||||||
return <BuildIcon />;
|
return <BuildIcon />;
|
||||||
|
} else if (tx.account.data[0] === 4) {
|
||||||
|
return <FaceIcon />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tx.account.programId.equals(multisigClient.programId)) {
|
if (tx.account.programId.equals(multisigClient.programId)) {
|
||||||
const setThresholdSighash = multisigClient.coder.sighash(
|
const setThresholdSighash = multisigClient.coder.sighash(
|
||||||
|
@ -1361,3 +1515,11 @@ function setOwnersData(multisigClient, owners) {
|
||||||
owners,
|
owners,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAuthorityData(): Buffer {
|
||||||
|
return Buffer.from([4, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgradeData(): Buffer {
|
||||||
|
return Buffer.from([3, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue