Skip to content

Commit

Permalink
Anchor instruction decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Jun 11, 2021
1 parent 68d477d commit fe45856
Showing 1 changed file with 92 additions and 7 deletions.
99 changes: 92 additions & 7 deletions src/components/instructions/UnknownInstruction.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,58 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import LabelValue from './LabelValue';
import {
Table,
TableRow,
TableHead,
TableCell,
TableBody,
} from '@material-ui/core';
import Typography from '@material-ui/core/Typography';
import { Program, Provider } from '@project-serum/anchor';
import { useWallet } from '../../utils/wallet';
import { useConnection } from '../../utils/connection';

export default function UnknownInstruction({ instruction, onOpenAddress }) {
const [anchorProgram, setAnchorProgram] = useState(null);
const connection = useConnection();
const wallet = useWallet();
const provider = new Provider(connection, wallet, {});

// Fetch the anchor IDL and generate a client. If the IDL isn't on chain,
// do nothing.
useEffect(() => {
Program.at(instruction.programId, provider)
.then(setAnchorProgram)
.catch((err) => {});
}, [instruction, setAnchorProgram, provider]);

// Format all the fields of the instruction.
let formattedIx = null,
ix = null;
if (anchorProgram) {
ix = anchorProgram.coder.instruction.decode(instruction.rawData);
if (ix !== null) {
formattedIx = anchorProgram.coder.instruction.format(
ix,
instruction.accountMetas,
);
}
}

return (
<>
<Typography
variant="subtitle1"
style={{ fontWeight: 'bold' }}
gutterBottom
>
Unknown instruction:
{formattedIx && ix.name
? sentenceCase(ix.name)
: 'Unknown instruction:'}
</Typography>
<LabelValue
key="Program"
label="Program"
label={<b>Program</b>}
value={instruction.programId?.toBase58()}
link={true}
gutterBottom={true}
Expand All @@ -26,7 +64,13 @@ export default function UnknownInstruction({ instruction, onOpenAddress }) {
<>
<LabelValue
key={index + ''}
label={'Account #' + (index + 1)}
label={
<b>
{formattedIx && formattedIx.accounts[index].name
? sentenceCase(formattedIx.accounts[index].name)
: 'Account #' + (index + 1)}
</b>
}
value={accountMeta.publicKey.toBase58()}
link={true}
onClick={() => onOpenAddress(accountMeta.publicKey.toBase58())}
Expand All @@ -37,9 +81,50 @@ export default function UnknownInstruction({ instruction, onOpenAddress }) {
</>
);
})}
<Typography style={{ wordBreak: 'break-all' }}>
Data: {instruction.rawData}
</Typography>
{formattedIx ? (
<>
<Typography style={{ wordBreak: 'breaking-all' }}>
<b>Data:</b>
</Typography>
<DecodedInstruction formattedFields={formattedIx.args} />
</>
) : (
<Typography style={{ wordBreak: 'breaking-all' }}>
<b>Data:</b> {instruction.rawData}
</Typography>
)}
</>
);
}

function DecodedInstruction({ formattedFields }) {
return (
<Table>
<TableHead>
<TableRow>
<TableCell>#</TableCell>
<TableCell>Name</TableCell>
<TableCell>Type</TableCell>
<TableCell>Data</TableCell>
</TableRow>
</TableHead>
<TableBody>
{formattedFields.map((field, idx) => {
return (
<TableRow>
<TableCell>{idx.toString()}</TableCell>
<TableCell>{field.name}</TableCell>
<TableCell>{field.type}</TableCell>
<TableCell>{field.data}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
}

function sentenceCase(field: string): string {
const result = field.replace(/([A-Z])/g, ' $1');
return result.charAt(0).toUpperCase() + result.slice(1);
}

0 comments on commit fe45856

Please sign in to comment.