Parse instructions based on program id

This commit is contained in:
Nishad 2020-09-23 02:13:33 +08:00
parent 18ca87638e
commit 340621918e
4 changed files with 46 additions and 51 deletions

View File

@ -21,7 +21,7 @@ const DATA_LABELS = {
export default function DexInstruction({ instruction, onOpenAddress }) { export default function DexInstruction({ instruction, onOpenAddress }) {
const wallet = useWallet(); const wallet = useWallet();
const [publicKeys] = useWalletPublicKeys(); const [publicKeys] = useWalletPublicKeys();
const { type, data, market, marketInfo, knownProgramId } = instruction; const { type, data, market, marketInfo } = instruction;
const marketLabel = const marketLabel =
(marketInfo && (marketInfo &&
@ -44,7 +44,7 @@ export default function DexInstruction({ instruction, onOpenAddress }) {
style={{ fontWeight: 'bold' }} style={{ fontWeight: 'bold' }}
gutterBottom gutterBottom
> >
{TYPE_LABELS[type]} {!knownProgramId ? '(Unknown DEX program)' : null} {TYPE_LABELS[type]}
</Typography> </Typography>
<LabelValue <LabelValue
label="Market" label="Market"

View File

@ -5,7 +5,7 @@ import { useWallet } from '../../utils/wallet';
export default function Neworder({ instruction, onOpenAddress }) { export default function Neworder({ instruction, onOpenAddress }) {
const wallet = useWallet(); const wallet = useWallet();
const { data, market, marketInfo, knownProgramId } = instruction; const { data, market, marketInfo } = instruction;
const { side, limitPrice, maxQuantity, orderType, ownerPubkey } = data; const { side, limitPrice, maxQuantity, orderType, ownerPubkey } = data;
const marketLabel = const marketLabel =
@ -26,7 +26,7 @@ export default function Neworder({ instruction, onOpenAddress }) {
style={{ fontWeight: 'bold' }} style={{ fontWeight: 'bold' }}
gutterBottom gutterBottom
> >
Place an order {!knownProgramId ? '(Unknown DEX program)' : null} Place an order
</Typography> </Typography>
<LabelValue <LabelValue
label="Market" label="Market"

View File

@ -293,16 +293,6 @@ function isSafeInstruction(publicKeys, owner, instructions) {
if (!instruction) { if (!instruction) {
unsafe = true; unsafe = true;
} else { } else {
if (
['cancelOrder', 'matchOrders', 'newOrder', 'settleFunds'].includes(
instruction.type,
)
) {
// Verify that the DEX program ID is known
if (!instruction.knownProgramId) {
unsafe = true;
}
}
if (['cancelOrder', 'matchOrders'].includes(instruction.type)) { if (['cancelOrder', 'matchOrders'].includes(instruction.type)) {
// It is always considered safe to cancel orders, match orders // It is always considered safe to cancel orders, match orders
} else if (instruction.type === 'systemCreate') { } else if (instruction.type === 'systemCreate') {

View File

@ -1,5 +1,5 @@
import bs58 from 'bs58'; import bs58 from 'bs58';
import { Message, SystemInstruction } from '@solana/web3.js'; import { Message, SystemInstruction, SystemProgram } from '@solana/web3.js';
import { import {
decodeInstruction, decodeInstruction,
decodeTokenInstructionData, decodeTokenInstructionData,
@ -11,6 +11,7 @@ import {
NEW_ORDER_OPEN_ORDERS_INDEX, NEW_ORDER_OPEN_ORDERS_INDEX,
NEW_ORDER_OWNER_INDEX, NEW_ORDER_OWNER_INDEX,
} from '@project-serum/serum'; } from '@project-serum/serum';
import { TOKEN_PROGRAM_ID } from './tokens/instructions';
const marketCache = {}; const marketCache = {};
let marketCacheConnection = null; let marketCacheConnection = null;
@ -52,51 +53,58 @@ const toInstruction = async (
instruction, instruction,
index, index,
) => { ) => {
if (!instruction?.data || !instruction?.accounts) { if (
!instruction?.data ||
!instruction?.accounts ||
!instruction?.programIdIndex
) {
return; return;
} }
// get instruction data // get instruction data
const decoded = bs58.decode(instruction.data); const decoded = bs58.decode(instruction.data);
let decodedInstruction;
// try dex instruction decoding const programId = getAccountByIndex(
try { [instruction.programIdIndex],
decodedInstruction = decodeInstruction(decoded); accountKeys,
console.log('[' + index + '] Handled as dex instruction'); 0,
return await handleDexInstruction( );
connection, if (!programId) {
instruction, return null;
accountKeys, }
decodedInstruction,
);
} catch {}
// try token decoding
try { try {
decodedInstruction = decodeTokenInstruction(decoded); if (programId.equals(SystemProgram.programId)) {
console.log('[' + index + '] Handled as token instruction'); console.log('[' + index + '] Handled as system instruction');
return handleTokenInstruction( return handleSystemInstruction(publicKey, instruction, accountKeys);
publicKey, } else if (programId.equals(TOKEN_PROGRAM_ID)) {
instruction.accounts, console.log('[' + index + '] Handled as token instruction');
decodedInstruction, let decodedInstruction = decodeTokenInstruction(decoded);
accountKeys, return handleTokenInstruction(
); publicKey,
} catch {} instruction.accounts,
decodedInstruction,
// try system instruction decoding accountKeys,
try { );
const systemInstruction = handleSystemInstruction( } else if (
publicKey, MARKETS.some(
instruction, (market) => market.programId && market.programId.equals(programId),
accountKeys, )
); ) {
console.log('[' + index + '] Handled as system instruction'); console.log('[' + index + '] Handled as dex instruction');
return systemInstruction; let decodedInstruction = decodeInstruction(decoded);
return await handleDexInstruction(
connection,
instruction,
accountKeys,
decodedInstruction,
);
}
} catch {} } catch {}
// all decodings failed // all decodings failed
console.log('[' + index + '] Failed, data: ' + JSON.stringify(decoded)); console.log('[' + index + '] Failed, data: ' + JSON.stringify(decoded));
return; return;
}; };
@ -171,9 +179,6 @@ const handleDexInstruction = async (
data = { ...data, ...newOrderData }; data = { ...data, ...newOrderData };
} }
return { return {
knownProgramId: MARKETS.some(
({ programId }) => programIdAddress && programIdAddress.equals(programId),
),
type, type,
data, data,
market, market,