-
Notifications
You must be signed in to change notification settings - Fork 577
feat: improve component to display information about AssociatedTokenProgram instruction at inspector #484
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ngundotra
merged 40 commits into
solana-foundation:master
from
rogaldh:feat/decode-ata-data-at-inspector
Mar 14, 2025
Merged
feat: improve component to display information about AssociatedTokenProgram instruction at inspector #484
Changes from 14 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
f5cc5b6
feat: use ComputeBudgetDetailsCard to decode ComputeBudgetProgram dat…
rogaldh 4e8731f
fix: reuse base card for instruction
rogaldh 896a188
fix: misc
rogaldh bd5c446
fix: misc
rogaldh f59d496
WIP
rogaldh 7d2382a
WIP
rogaldh 3d9d0a7
WIP
rogaldh 86f1c70
chore: remove forgotten console.log
rogaldh 45e643c
chore: improve mocks
rogaldh 73b4891
chore: improve existing tests according improved mocks
rogaldh e1c3617
feat: add AssociatedTokenDetailsCard to inspector
rogaldh 72efc05
feat: highlight "raw" button at instruction card to make it visible
rogaldh fd58154
fix: ellipsis
rogaldh 8150f18
chore: remove not needed jest-mock & update testing-library/react to …
rogaldh 8989c78
feat: add support for create & recoverNested instructions
rogaldh 83302ab
feat: use @solana-program/token to get proper discriminators
rogaldh 769e679
fix: minor changes
rogaldh f030396
WIP
rogaldh 21660ce
feat: use AddressLookupTable component to resolve addresses properly
rogaldh 5223be4
fix: replace factory with separate methods
rogaldh d74a1ff
feat: wrap AnchorProgram card with boundary
rogaldh 08bd1af
Merge branch 'master' into feat/decode-ata-data-at-inspector
rogaldh 3fe3e8a
WIP
rogaldh 0d21d50
WIP
rogaldh ebdc0d7
WIP
rogaldh 8eabc41
WIP
rogaldh 4a0c74f
feat: improve CreateIdempotentDetailsCard
rogaldh 7c533e1
feat: improve tests to check for needed fields for each AssociatedTok…
rogaldh 2a2045e
improve props
rogaldh c52a012
chore: improve tests to handle address-lookup-table addresses
rogaldh 86f81ed
chore: improve types to allow code to be buildable
rogaldh f0266fd
misc
rogaldh bd18bf1
sync account labels
rogaldh dfa4bcb
chore: replace @solana/kit with web3js-experimental
rogaldh 70faa6a
fix: override @solana/addresses version to 2.1.0 to resolve issues wi…
rogaldh eadf497
feat: make CreateDetailsCard similar
rogaldh bf86d1e
misc
rogaldh 08c05a6
fix: remove unused component
rogaldh 45461e5
fix: code-review
rogaldh 705c9ec
fix: enrich account data to make cards similar
rogaldh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /** | ||
| * Contains serialized VersionedMessages which can be viewed at the inspector by related URLs | ||
| */ | ||
|
|
||
| // stub a test to not allow passing without tests | ||
| test('stub', () => expect(true).toBeTruthy()); | ||
|
|
||
| // Message with computeBudget instructions | ||
| // http://localhost:3000/tx/inspector?message=gAIABgwLFFx82WdzBluGohZnk8TmXq%252F0pUUnxhpjxSNMraGelLVLQTka3xzxe6hY3Q5dyh8MwvAULx%252BJiPZjdz6%252FaB0L9Lqt3uRNrVn1pxcSD2DLOW0u7YcBbR9bqZdxSdFeT%252FwUlFkNon7Uoh%252BC72aIW5YavKARbD1UjdRpAiXrDl0ryvzVcRVtGJcJNXfKuwGjzfmQhFehPY9M8ebYtDAMvSK8srY9g9IH4ppqsXreT6D%252BTmlKdu2JXmEcnGtzHE8Q9OIDBkZv5SEXMv%252Fsrbpyw5vnvIzlu8X3EmssQ5s6QAAAAIyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqQR51VvyMcBu7nTFbs5oFQf9sbLeo%252FSOUQKxzaJWvBOPtD%252F6J%252FXX9kp0wJsfKVh53ksJqzbfyd1RSzIap7OM5eicyfP%252FJFK6VWlYc2EGEyE78uvE0UgAvaW5%252BvYLw8BggAYGAAkDZK1tAAAAAAAGAAUCEmACAAcGAAIBEggJAQEHBgADARMICQEBCi0JAQQCChIFCwoUCQ8VDxARDw8PDw8PDw8EAwEUCQwVDA0ODAwMDAwMDAwDAgEn5RfLl3rjrSoCAAAAB2QAAQdkAQIAypo7AAAAAKeXKAIAAAAAlgBVCQMDAQEBCQLiCK3IP8r%252FwRrlsnWHJ6M%252FxtgYtM4dwqjJg6tYf5r2EgMfIKEE2QYREMI4UPEU19u%252Bw1q7jjS3B54B4IVrQrOf4fF1hSod0iZUA1eTUwA%253D | ||
| export const computeBudgetMsg = '{"header":{"numRequiredSignatures":2,"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":6},"staticAccountKeys":["kFVZ5bdn3c9tMoY4ibqsLDNd6vxt3HwHVcZC5b6ra1y","DChMF3Q8TKaRFCk6LYHcJp8w4pyHKkLjfTYCmR7iyfox","HUKaYJCzbTXN7JzgtQhGGUThmES3NeksNcbyzD4QoBoh","2PLMWNViAaRdNnBvB6zutQ9Cg5bMyWtX7BEYb15XzE8R","J1xWWZPTZDWVydStvZwVgpt2VmqqbUKGLJuP7FajGu2T","D2ckBJDNmnJJkZSz1qDLCXjhcuBiY4T9tPJZ9cpbHZ3o","ComputeBudget111111111111111111111111111111","ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL","11111111111111111111111111111111","TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4","D8cy77BBepLMngZx6ZukaTff5hCt1HrWyKk3Hnd9oitf"],"recentBlockhash":"BZ3D8mjoY3Exwh31DpPzAze1aH9hRMunJg9xrT8aTnCo","compiledInstructions":[{"programIdIndex":6,"accountKeyIndexes":[],"data":{"0":3,"1":100,"2":173,"3":109,"4":0,"5":0,"6":0,"7":0,"8":0}},{"programIdIndex":6,"accountKeyIndexes":[],"data":{"0":2,"1":18,"2":96,"3":2,"4":0}},{"programIdIndex":7,"accountKeyIndexes":[0,2,1,18,8,9],"data":{"0":1}},{"programIdIndex":7,"accountKeyIndexes":[0,3,1,19,8,9],"data":{"0":1}},{"programIdIndex":10,"accountKeyIndexes":[9,1,4,2,10,18,5,11,10,20,9,15,21,15,16,17,15,15,15,15,15,15,15,15,4,3,1,20,9,12,21,12,13,14,12,12,12,12,12,12,12,12,3,2,1],"data":{"0":229,"1":23,"2":203,"3":151,"4":122,"5":227,"6":173,"7":42,"8":2,"9":0,"10":0,"11":0,"12":7,"13":100,"14":0,"15":1,"16":7,"17":100,"18":1,"19":2,"20":0,"21":202,"22":154,"23":59,"24":0,"25":0,"26":0,"27":0,"28":167,"29":151,"30":40,"31":2,"32":0,"33":0,"34":0,"35":0,"36":150,"37":0,"38":85}},{"programIdIndex":9,"accountKeyIndexes":[3,1,1],"data":{"0":9}}],"addressTableLookups":[{"accountKey":"GDLpHg53y5sufRSftvZscFMwdSqP8kHaLwhsT4ZwYSaV","writableIndexes":[31,32,161],"readonlyIndexes":[217,6,17,16]},{"accountKey":"E59uBXGqn83xN17kMbBVfU1M7T4wHG91eiygHb88Aovb","writableIndexes":[87,147,83],"readonlyIndexes":[]}]}'; | ||
|
|
||
| // Transaction with AssociatedToken instruction | ||
| // http://localhost:3000/tx/Nwa7VZEfhbPV2MmW4dQNebj6Pw1TrJH9j2G3pL7Vt4Hr2rTzyEPdh1LBd4SKtzEBhC1MKMDEeaQuz96FZzQSyYk/inspect | ||
| export const aTokenMsg = '{"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":6,"numRequiredSignatures":1},"staticAccountKeys":["EzdQH5zUfTMGb3vwU4oumxjVcxKMDpJ6dB78pbjfHmmb","2qZ3FFpD9kPVS3MRYQNDGqfrh6JzjNpqXNp5kopv2PMk","3wrAqm2ouWgzVnk7Cxv2GbM6VUeGBtZuSEakApjQk4VZ","4ahjvr2TN7yViD8b54S1TCC2CokRfSBYErYT3Zd7rK9u","6LXAHyQ9AZs8LcQoUqpj6RswaZGxkM6vmx9CPDoiy8cd","8DKit81gfTDtTYN4SMWHwAc3UJywbHNEJThXjLrzb17s","8czgpWaHCjyXpLAUqqZqWZEw4ZYrAonfaKyLCRN2M58X","9hDBGGCrLwQtdxbw2TUzpzLEZM8psxVBhBpbJDAMibq6","9jPRczqDFNkuQyF6MBhnsZqyURUzNJzGXpNM1NxxocQF","AUN7WQptCU5qSgmDSDtiSzQivQVhmTfDndJgEtj2RDD6","AZYJEfo2mjqLV3PsCPcDjmgyDnyq9ur5KCgbpCJokXLf","Big1xZ1pnMdrjkF3buyJTC2kfKgmrRVgBN7dpekF5LCd","ENE5MsxSPqoKVg2TH2QabAKRBRwdsAq2cMiqydsnSN4s","F3AwqJLiqFUGQnfq8QVEtJQWRPztq2WmuFEgfE1L2Nb7","Fv8YYjF2DUqj9RZhyXNzXa4yR9nHHwjg5bFjA82UidF1","GjFdibHr9YDtqnKW3pc7ChzmsqWeptvVwQijAnY3LkLb","Guo7CcsFvD8BrRPppdGZ9cRjXqjNYD33nHiN2gdijzdj","Ht7TduEGJjBMDXXozEUMJPq592r8x33UXuLdD5uPFc5m","11111111111111111111111111111111","ComputeBudget111111111111111111111111111111","JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4","74SBV4zDXxTRgv1pEMoECskKBkZHc2yGPnc7GYVepump","ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL","D8cy77BBepLMngZx6ZukaTff5hCt1HrWyKk3Hnd9oitf"],"recentBlockhash":"9W45XzEpCW1PNZY6xpixc1AGTSTe1DVxA3PXaBvc6met","compiledInstructions":[{"programIdIndex":19,"accountKeyIndexes":[],"data":{"type":"Buffer","data":[2,160,247,3,0]}},{"programIdIndex":22,"accountKeyIndexes":[0,14,0,21,18,26],"data":{"type":"Buffer","data":[1]}},{"programIdIndex":20,"accountKeyIndexes":[26,0,1,1,20,25,20,23,20,24,3,24,8,7,1,14,21,25,16,24,0,26,26,28,24,4,11,9,20,27,0,29,12,14,1,13,15,2,26,17,10,6,20],"data":{"type":"Buffer","data":[229,23,203,151,122,227,173,42,2,0,0,0,38,100,0,1,26,100,1,0,128,240,250,2,0,0,0,0,176,101,251,2,0,0,0,0,0,0,0]}},{"programIdIndex":18,"accountKeyIndexes":[0,5],"data":{"type":"Buffer","data":[2,0,0,0,104,243,33,0,0,0,0,0]}}],"addressTableLookups":[{"accountKey":"EDDSpjZHrsFKYTMJDcBqXAjkLcu9EKdvrQR4XnqsXErH","readonlyIndexes":[89,123,69,80,90,94],"writableIndexes":[]}]}'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import { MessageCompiledInstruction, MessageV0, PublicKey, VersionedMessage } from "@solana/web3.js"; | ||
| import { useSearchParams } from 'next/navigation'; | ||
|
|
||
| // stub a test to not allow passing without tests | ||
| test('stub', () => expect(true).toBeTruthy()); | ||
|
|
||
| jest.mock('next/navigation'); | ||
| export function mockUseSearchParams(cluster = 'mainnet-beta', customUrl?: string) { | ||
| // @ts-expect-error mockReturnValue is not present | ||
| useSearchParams.mockReturnValue({ | ||
| get: (param: string) => { | ||
| if (param === 'cluster') return cluster; | ||
| return null; | ||
| }, | ||
| has: (param: string) => { | ||
| if (param === 'customUrl' && customUrl) return true; | ||
| return false; | ||
| }, | ||
| toString: () => { | ||
| let clusterString; | ||
| if (cluster !== 'mainnet-beta') clusterString = `cluster=${cluster}`; | ||
| if (customUrl) { | ||
| return `customUrl=${customUrl}${clusterString ? `&${clusterString}` : ''}`; | ||
| } | ||
| return clusterString ?? ''; | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| export function deserializeMessageV0(message: string): VersionedMessage { | ||
rogaldh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const m = JSON.parse(message); | ||
| const vm = new MessageV0({ | ||
| addressTableLookups: m.addressTableLookups.map((atl: { | ||
| accountKey: string, | ||
| writableIndexes: number[], | ||
| readonlyIndexes: number[], | ||
| }) => { | ||
| return { | ||
| accountKey: new PublicKey(atl.accountKey), | ||
| readonlyIndexes: atl.readonlyIndexes, | ||
| writableIndexes: atl.writableIndexes, | ||
| }; | ||
| }), | ||
| compiledInstructions: m.compiledInstructions.map((ci: { | ||
| programIdIndex: number, | ||
| accountKeyIndexes: number[], | ||
| data: { [key: string]: number } | { type: 'Buffer', data: number[] } | ||
| }) => { | ||
| let data: Uint8Array; | ||
| if ('type' in ci.data) { | ||
| data = Uint8Array.from(ci.data.data as number[]); | ||
| } else { | ||
| data = new Uint8Array([...Object.values(ci.data)]); | ||
| } | ||
|
|
||
| return { | ||
| accountKeyIndexes: ci.accountKeyIndexes, | ||
| data: data, | ||
| programIdIndex: ci.programIdIndex, | ||
| }; | ||
| }), | ||
| header: m.header, | ||
| recentBlockhash: m.recentBlockhash, | ||
| staticAccountKeys: m.staticAccountKeys.map((sak: string) => new PublicKey(sak)), | ||
| }); | ||
|
|
||
| return vm; | ||
| } | ||
|
|
||
| export function deserializeInstruction(instruction: string): MessageCompiledInstruction { | ||
| const data = JSON.parse(instruction); | ||
| data.data = Uint8Array.from(data.data.data); | ||
|
|
||
| return data; | ||
| } | ||
64 changes: 64 additions & 0 deletions
64
app/components/common/__tests__/BaseInstructionCard.spec.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import { intoTransactionInstructionFromVersionedMessage } from '@components/inspector/utils'; | ||
| import { ASSOCIATED_TOKEN_PROGRAM_ID } from '@solana/spl-token'; | ||
| import { render, screen } from '@testing-library/react'; | ||
|
|
||
| import * as stubs from '@/app/__tests__/mock-stubs'; | ||
| import * as mock from '@/app/__tests__/mocks'; | ||
| import { ClusterProvider } from '@/app/providers/cluster'; | ||
| import { ScrollAnchorProvider } from '@/app/providers/scroll-anchor'; | ||
|
|
||
| import { BaseInstructionCard } from '../BaseInstructionCard'; | ||
|
|
||
| describe('BaseInstructionCard', () => { | ||
| beforeEach(() => { | ||
| mock.mockUseSearchParams(); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| test('should render "BaseInstructionCard"', async () => { | ||
| const index = 1; | ||
| const m = mock.deserializeMessageV0(stubs.aTokenMsg); | ||
| const ti = intoTransactionInstructionFromVersionedMessage(m.compiledInstructions[index], m); | ||
| expect(ti.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)).toBeTruthy(); | ||
|
|
||
| // check that component is rendered properly | ||
| render( | ||
| <ScrollAnchorProvider> | ||
| <ClusterProvider> | ||
| <BaseInstructionCard ix={ti} index={index} title="Program: Instruction" result={{ err: null }} /> | ||
| </ClusterProvider> | ||
| </ScrollAnchorProvider> | ||
| ); | ||
| // check that card is rendered with proper title | ||
| expect(screen.getByText(/Program: Instruction/)).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| test('should render "BaseInstructionCard" with raw data', async () => { | ||
| const index = 1; | ||
| const m = mock.deserializeMessageV0(stubs.aTokenMsg); | ||
| const ti = intoTransactionInstructionFromVersionedMessage(m.compiledInstructions[index], m); | ||
| expect(ti.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)).toBeTruthy(); | ||
|
|
||
| // check that component is rendered properly | ||
| render( | ||
| <ScrollAnchorProvider> | ||
| <ClusterProvider> | ||
| <BaseInstructionCard | ||
| ix={ti} | ||
| index={index} | ||
| title="Program: Instruction" | ||
| result={{ err: null }} | ||
| defaultRaw | ||
| /> | ||
| </ClusterProvider> | ||
| </ScrollAnchorProvider> | ||
| ); | ||
| // instruction should relate to specific program | ||
| expect(await screen.findAllByText(/Associated Token Program/)).toHaveLength(2); | ||
| // we expect specific internal component to be rendered with "defaultRaw" | ||
| expect(screen.getByText('Instruction Data')).toBeInTheDocument(); | ||
| }); | ||
| }); |
35 changes: 35 additions & 0 deletions
35
app/components/common/instruction/BaseUnknownDetailsCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { BaseInstructionCard } from '@components/common/BaseInstructionCard'; | ||
| import { useCluster } from '@providers/cluster'; | ||
| import { ParsedInstruction, SignatureResult, TransactionInstruction } from '@solana/web3.js'; | ||
| import { getProgramName } from '@utils/tx'; | ||
| import React from 'react'; | ||
|
|
||
| export function BaseUnknownDetailsCard({ | ||
| ix, | ||
| index, | ||
| result, | ||
| innerCards, | ||
| childIndex, | ||
| InstructionCardComponent = BaseInstructionCard, | ||
| }: { | ||
| ix: TransactionInstruction | ParsedInstruction; | ||
| index: number; | ||
| result: SignatureResult; | ||
| innerCards?: JSX.Element[]; | ||
| childIndex?: number; | ||
| InstructionCardComponent?: React.FC<Parameters<typeof BaseInstructionCard>[0]>; | ||
| }) { | ||
| const { cluster } = useCluster(); | ||
| const programName = getProgramName(ix.programId.toBase58(), cluster); | ||
| return ( | ||
| <InstructionCardComponent | ||
| ix={ix} | ||
| index={index} | ||
| result={result} | ||
| title={`${programName}: Unknown Instruction`} | ||
| innerCards={innerCards} | ||
| childIndex={childIndex} | ||
| defaultRaw | ||
| /> | ||
| ); | ||
| } |
46 changes: 46 additions & 0 deletions
46
app/components/common/instruction/associated-token/BaseCreateDetailsCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { Address } from '@components/common/Address'; | ||
| import { BaseInstructionCard } from '@components/common/BaseInstructionCard'; | ||
| import { ParsedInstruction, SignatureResult, TransactionInstruction } from '@solana/web3.js'; | ||
| import React from 'react'; | ||
|
|
||
| import { BaseRawDetails } from '../../BaseRawDetails'; | ||
|
|
||
| export function BaseCreateDetailsCard({ | ||
| ix, | ||
| index, | ||
| raw, | ||
| result, | ||
| innerCards, | ||
| childIndex, | ||
| children, | ||
| InstructionCardComponent = BaseInstructionCard, | ||
| }: { | ||
| ix: ParsedInstruction; | ||
| index: number; | ||
| raw: TransactionInstruction; | ||
| result: SignatureResult; | ||
| innerCards?: JSX.Element[]; | ||
| childIndex?: number; | ||
| children?: React.ReactNode; | ||
| InstructionCardComponent?: React.FC<Parameters<typeof BaseInstructionCard>[0]>; | ||
| }) { | ||
| return ( | ||
| <InstructionCardComponent | ||
| ix={ix} | ||
| index={index} | ||
| raw={raw} | ||
| result={result} | ||
| title="Associated Token Program: Create" | ||
| innerCards={innerCards} | ||
| childIndex={childIndex} | ||
| > | ||
| <tr> | ||
| <td>Program</td> | ||
| <td className="text-lg-end"> | ||
| <Address pubkey={ix.programId} alignRight link /> | ||
| </td> | ||
| </tr> | ||
| {children ? children : <BaseRawDetails ix={raw} />} | ||
| </InstructionCardComponent> | ||
| ); | ||
| } |
43 changes: 43 additions & 0 deletions
43
app/components/common/instruction/associated-token/BaseCreateIdempotentDetailsCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { BaseInstructionCard } from '@components/common/BaseInstructionCard'; | ||
| import { ParsedInstruction, SignatureResult, TransactionInstruction } from '@solana/web3.js'; | ||
| import React from 'react'; | ||
|
|
||
| import { BaseRawDetails } from '../../BaseRawDetails'; | ||
| import { CreateIdempotentInfo } from './types'; | ||
|
|
||
| export function BaseCreateIdempotentDetailsCard(props: { | ||
| ix: ParsedInstruction; | ||
| index: number; | ||
| raw: TransactionInstruction; | ||
| result: SignatureResult; | ||
| info?: CreateIdempotentInfo; | ||
| innerCards?: JSX.Element[]; | ||
| childIndex?: number; | ||
| children?: React.ReactNode; | ||
| InstructionCardComponent?: React.FC<Parameters<typeof BaseInstructionCard>[0]>; | ||
| }) { | ||
| const { | ||
| ix, | ||
| index, | ||
| raw, | ||
| result, | ||
| children, | ||
| innerCards, | ||
| childIndex, | ||
| InstructionCardComponent = BaseInstructionCard, | ||
| } = props; | ||
|
|
||
| return ( | ||
| <InstructionCardComponent | ||
| ix={ix} | ||
| index={index} | ||
| raw={raw} | ||
| result={result} | ||
| title="Associated Token Program: Create Idempotent" | ||
| innerCards={innerCards} | ||
| childIndex={childIndex} | ||
| > | ||
| {children ? children : <BaseRawDetails ix={raw} />} | ||
| </InstructionCardComponent> | ||
| ); | ||
| } |
43 changes: 43 additions & 0 deletions
43
app/components/common/instruction/associated-token/BaseRecoverNestedDetailsCard.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { BaseInstructionCard } from '@components/common/BaseInstructionCard'; | ||
| import { ParsedInstruction, SignatureResult, TransactionInstruction } from '@solana/web3.js'; | ||
| import React from 'react'; | ||
|
|
||
| import { BaseRawDetails } from '../../BaseRawDetails'; | ||
| import { RecoverNestedInfo } from './types'; | ||
|
|
||
| export function BaseRecoverNestedDetailsCard(props: { | ||
| ix: ParsedInstruction; | ||
| index: number; | ||
| raw: TransactionInstruction; | ||
| result: SignatureResult; | ||
| info?: RecoverNestedInfo; | ||
| innerCards?: JSX.Element[]; | ||
| childIndex?: number; | ||
| children?: React.ReactNode; | ||
| InstructionCardComponent?: React.FC<Parameters<typeof BaseInstructionCard>[0]>; | ||
| }) { | ||
| const { | ||
| ix, | ||
| index, | ||
| raw, | ||
| result, | ||
| children, | ||
| innerCards, | ||
| childIndex, | ||
| InstructionCardComponent = BaseInstructionCard, | ||
| } = props; | ||
|
|
||
| return ( | ||
| <InstructionCardComponent | ||
| ix={ix} | ||
| index={index} | ||
| raw={raw} | ||
| result={result} | ||
| title="Associated Token Program: Recover Nested" | ||
| innerCards={innerCards} | ||
| childIndex={childIndex} | ||
| > | ||
| {children ? children : <BaseRawDetails ix={raw} />} | ||
| </InstructionCardComponent> | ||
| ); | ||
| } |
28 changes: 28 additions & 0 deletions
28
app/components/common/instruction/associated-token/types.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| /* eslint-disable @typescript-eslint/no-redeclare */ | ||
|
|
||
| import { PublicKeyFromString } from '@validators/pubkey'; | ||
| import { enums, Infer, type } from 'superstruct'; | ||
|
|
||
| export type CreateIdempotentInfo = Infer<typeof CreateIdempotentInfo>; | ||
| export const CreateIdempotentInfo = type({ | ||
| account: PublicKeyFromString, | ||
| mint: PublicKeyFromString, | ||
| source: PublicKeyFromString, | ||
| systemProgram: PublicKeyFromString, | ||
| tokenProgram: PublicKeyFromString, | ||
| wallet: PublicKeyFromString, | ||
| }); | ||
|
|
||
| export type RecoverNestedInfo = Infer<typeof RecoverNestedInfo>; | ||
| export const RecoverNestedInfo = type({ | ||
| destination: PublicKeyFromString, | ||
| nestedMint: PublicKeyFromString, | ||
| nestedOwner: PublicKeyFromString, | ||
| nestedSource: PublicKeyFromString, | ||
| ownerMint: PublicKeyFromString, | ||
| tokenProgram: PublicKeyFromString, | ||
| wallet: PublicKeyFromString, | ||
| }); | ||
|
|
||
| export type SystemInstructionType = Infer<typeof SystemInstructionType>; | ||
| export const SystemInstructionType = enums(['create', 'createIdempotent', 'recoverNested']); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.