type CustomProgramError = number;

// Keep synced with RPC source: https://github.com/anza-xyz/solana-sdk/blob/master/instruction-error/src/lib.rs
type InstructionError =
    | 'AccountAlreadyInitialized'
    | 'AccountBorrowFailed'
    | 'AccountBorrowOutstanding'
    | 'AccountDataSizeChanged'
    | 'AccountDataTooSmall'
    | 'AccountNotExecutable'
    | 'AccountNotRentExempt'
    | 'ArithmeticOverflow'
    | 'BorshIoError' // SDKv3 has a fieldless `BorshIoError`
    | 'BuiltinProgramsMustConsumeComputeUnits'
    | 'CallDepth'
    | 'ComputationalBudgetExceeded'
    | 'DuplicateAccountIndex'
    | 'DuplicateAccountOutOfSync'
    | 'ExecutableAccountNotRentExempt'
    | 'ExecutableDataModified'
    | 'ExecutableLamportChange'
    | 'ExecutableModified'
    | 'ExternalAccountDataModified'
    | 'ExternalAccountLamportSpend'
    | 'GenericError'
    | 'IllegalOwner'
    | 'Immutable'
    | 'IncorrectAuthority'
    | 'IncorrectProgramId'
    | 'InsufficientFunds'
    | 'InvalidAccountData'
    | 'InvalidAccountOwner'
    | 'InvalidArgument'
    | 'InvalidError'
    | 'InvalidInstructionData'
    | 'InvalidRealloc'
    | 'InvalidSeeds'
    | 'MaxAccountsDataAllocationsExceeded'
    | 'MaxAccountsExceeded'
    | 'MaxInstructionTraceLengthExceeded'
    | 'MaxSeedLengthExceeded'
    | 'MissingAccount'
    | 'MissingRequiredSignature'
    | 'ModifiedProgramId'
    | 'NotEnoughAccountKeys'
    | 'PrivilegeEscalation'
    | 'ProgramEnvironmentSetupFailure'
    | 'ProgramFailedToCompile'
    | 'ProgramFailedToComplete'
    | 'ReadonlyDataModified'
    | 'ReadonlyLamportChange'
    | 'ReentrancyNotAllowed'
    | 'RentEpochModified'
    | 'UnbalancedInstruction'
    | 'UninitializedAccount'
    | 'UnsupportedProgramId'
    | 'UnsupportedSysvar'
    | { Custom: CustomProgramError };

type InstructionIndex = number;
type AccountIndex = number;

// Keep synced with RPC source: https://github.com/anza-xyz/agave/blob/master/sdk/src/transaction/error.rs
export type TransactionError =
    | 'AccountBorrowOutstanding'
    | 'AccountInUse'
    | 'AccountLoadedTwice'
    | 'AccountNotFound'
    | 'AddressLookupTableNotFound'
    | 'AlreadyProcessed'
    | 'BlockhashNotFound'
    | 'CallChainTooDeep'
    | 'ClusterMaintenance'
    | 'InsufficientFundsForFee'
    | 'InvalidAccountForFee'
    | 'InvalidAccountIndex'
    | 'InvalidAddressLookupTableData'
    | 'InvalidAddressLookupTableIndex'
    | 'InvalidAddressLookupTableOwner'
    | 'InvalidLoadedAccountsDataSizeLimit'
    | 'InvalidProgramForExecution'
    | 'InvalidRentPayingAccount'
    | 'InvalidWritableAccount'
    | 'MaxLoadedAccountsDataSizeExceeded'
    | 'MissingSignatureForFee'
    | 'ProgramAccountNotFound'
    | 'ResanitizationNeeded'
    | 'SanitizeFailure'
    | 'SignatureFailure'
    | 'TooManyAccountLocks'
    | 'UnbalancedTransaction'
    | 'UnsupportedVersion'
    | 'WouldExceedAccountDataBlockLimit'
    | 'WouldExceedAccountDataTotalLimit'
    | 'WouldExceedMaxAccountCostLimit'
    | 'WouldExceedMaxBlockCostLimit'
    | 'WouldExceedMaxVoteCostLimit'
    | { DuplicateInstruction: InstructionIndex }
    | { InstructionError: [InstructionIndex, InstructionError] }
    | { InsufficientFundsForRent: { account_index: AccountIndex } }
    | { ProgramExecutionTemporarilyRestricted: { account_index: AccountIndex } };
