Anchor instruction decoding
This commit is contained in:
parent
9baece02d5
commit
a223aa0193
|
@ -7,7 +7,7 @@
|
|||
"@material-ui/core": "^4.11.4",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@material-ui/lab": "^4.0.0-alpha.58",
|
||||
"@project-serum/anchor": "^0.7.0",
|
||||
"@project-serum/anchor": "^0.8.0",
|
||||
"@project-serum/serum": "^0.13.33",
|
||||
"@project-serum/swap-ui": "^0.1.3",
|
||||
"@solana/spl-token-registry": "^0.2.102",
|
||||
|
|
|
@ -1,8 +1,44 @@
|
|||
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();
|
||||
|
||||
// Fetch the anchor IDL and generate a client. If the IDL isn't on chain,
|
||||
// do nothing.
|
||||
useEffect(() => {
|
||||
const provider = new Provider(connection, wallet, {});
|
||||
Program.at(instruction.programId, provider)
|
||||
.then(setAnchorProgram)
|
||||
.catch((err) => {});
|
||||
}, [connection, wallet, instruction, setAnchorProgram]);
|
||||
|
||||
// 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
|
||||
|
@ -10,11 +46,13 @@ export default function UnknownInstruction({ instruction, onOpenAddress }) {
|
|||
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}
|
||||
|
@ -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())}
|
||||
|
@ -37,9 +81,50 @@ export default function UnknownInstruction({ instruction, onOpenAddress }) {
|
|||
</>
|
||||
);
|
||||
})}
|
||||
<Typography style={{ wordBreak: 'break-all' }}>
|
||||
Data: {instruction.rawData}
|
||||
{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);
|
||||
}
|
||||
|
|
47
yarn.lock
47
yarn.lock
|
@ -1892,13 +1892,13 @@
|
|||
schema-utils "^2.6.5"
|
||||
source-map "^0.7.3"
|
||||
|
||||
"@project-serum/anchor@^0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.7.0.tgz#ef48b8233c0fbe6763699451eccfc5402503b012"
|
||||
integrity sha512-SwY5OxJ6mYO3tTsYr3uQjlRX8tmb0P00u8T4ORWiYVz491fTcWIrGzqcrMHCvq9JFHMPvS6OR8BM0mfefx/DWw==
|
||||
"@project-serum/anchor@^0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.8.0.tgz#4172fa1c5f6680286a328d83d59f4f9139e058ee"
|
||||
integrity sha512-fiwmtd2Q7ZbjapY8aZ9F3E1/0evB5HoOooBheFSkBYAFyQbh1T3YIf60hEdxHT6+YAEDhkkGLLMwrlAWGl28VA==
|
||||
dependencies:
|
||||
"@project-serum/borsh" "^0.2.2"
|
||||
"@solana/web3.js" "^1.11.0"
|
||||
"@solana/web3.js" "^1.17.0"
|
||||
base64-js "^1.5.1"
|
||||
bn.js "^5.1.2"
|
||||
bs58 "^4.0.1"
|
||||
|
@ -2047,7 +2047,7 @@
|
|||
tweetnacl "^1.0.0"
|
||||
ws "^7.0.0"
|
||||
|
||||
"@solana/web3.js@^1.10.1", "@solana/web3.js@^1.11.0", "@solana/web3.js@^1.9.1":
|
||||
"@solana/web3.js@^1.10.1", "@solana/web3.js@^1.9.1":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.11.0.tgz#1cc9a25381687c82e444ad0633f028e050a06753"
|
||||
integrity sha512-kmngWxntzp0HNhWInd7/3g2uqxdOrahvaHOyjilcRe+WCiC777gERz3+eIAbxIYx2zAZPjy02MZzLgoRHccZoQ==
|
||||
|
@ -2066,6 +2066,26 @@
|
|||
superstruct "^0.14.2"
|
||||
tweetnacl "^1.0.0"
|
||||
|
||||
"@solana/web3.js@^1.17.0":
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.18.0.tgz#f4c422a843aa57a1366d98b06cb6b45441644d59"
|
||||
integrity sha512-ijAoRd4Sje1QYoPAwDr7KYlDK40FE7tAUa2V3wT4PGKatWf4ETDXoyYlW89J6vrqOT+mV3GUuaVC76tOFlrXyA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
bn.js "^5.0.0"
|
||||
borsh "^0.4.0"
|
||||
bs58 "^4.0.1"
|
||||
buffer "6.0.1"
|
||||
buffer-layout "^1.2.0"
|
||||
crypto-hash "^1.2.2"
|
||||
jayson "^3.4.4"
|
||||
js-sha3 "^0.8.0"
|
||||
node-fetch "^2.6.1"
|
||||
rpc-websockets "^7.4.2"
|
||||
secp256k1 "^4.0.2"
|
||||
superstruct "^0.14.2"
|
||||
tweetnacl "^1.0.0"
|
||||
|
||||
"@surma/rollup-plugin-off-main-thread@^1.1.1":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58"
|
||||
|
@ -3610,6 +3630,16 @@ boolbase@^1.0.0, boolbase@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
borsh@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.4.0.tgz#9dd6defe741627f1315eac2a73df61421f6ddb9f"
|
||||
integrity sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==
|
||||
dependencies:
|
||||
"@types/bn.js" "^4.11.5"
|
||||
bn.js "^5.0.0"
|
||||
bs58 "^4.0.0"
|
||||
text-encoding-utf-8 "^1.0.2"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
|
@ -12755,6 +12785,11 @@ test-exclude@^6.0.0:
|
|||
glob "^7.1.4"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
text-encoding-utf-8@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13"
|
||||
integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==
|
||||
|
||||
text-table@0.2.0, text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
|
Loading…
Reference in New Issue