mango-token-sale/models/errors.ts

147 lines
8.1 KiB
TypeScript

import { TransactionError } from '@solana/web3.js'
export class SendTransactionError extends Error {
txError: TransactionError
txId: string
constructor(message: string, txId: string, txError: TransactionError) {
super(message)
this.txError = txError
this.txId = txId
}
}
export const GovernanceError: Record<number, string> = [
'Invalid instruction passed to program', // InvalidInstruction
'Realm with the given name and governing mints already exists', // RealmAlreadyExists
'Invalid realm', // InvalidRealm
'Invalid Governing Token Mint', // InvalidGoverningTokenMint
'Governing Token Owner must sign transaction', // GoverningTokenOwnerMustSign
'Governing Token Owner or Delegate must sign transaction', // GoverningTokenOwnerOrDelegateMustSign
'All votes must be relinquished to withdraw governing tokens', // AllVotesMustBeRelinquishedToWithdrawGoverningTokens
'Invalid Token Owner Record account address', // InvalidTokenOwnerRecordAccountAddress
'Invalid GoverningMint for TokenOwnerRecord', // InvalidGoverningMintForTokenOwnerRecord
'Invalid Realm for TokenOwnerRecord', // InvalidRealmForTokenOwnerRecord
'Invalid Proposal for ProposalInstruction', // InvalidProposalForProposalInstruction
'Invalid Signatory account address', // InvalidSignatoryAddress
'Signatory already signed off', // SignatoryAlreadySignedOff
'Signatory must sign', // SignatoryMustSign
'Invalid Proposal Owner', //InvalidProposalOwnerAccount
'Invalid Proposal for VoterRecord', // InvalidProposalForVoterRecord
'Invalid GoverningTokenOwner for VoteRecord', // InvalidGoverningTokenOwnerForVoteRecord
'Invalid Governance config: Vote threshold percentage out of range', // InvalidVoteThresholdPercentage
'Proposal for the given Governance, Governing Token Mint and index already exists', // ProposalAlreadyExists
'Token Owner already voted on the Proposal', // VoteAlreadyExists
"Owner doesn't have enough governing tokens to create Proposal", // NotEnoughTokensToCreateProposal
"Invalid State: Can't edit Signatories", // InvalidStateCannotEditSignatories
'Invalid Proposal state', // InvalidProposalState
"Invalid State: Can't edit instructions", // InvalidStateCannotEditInstructions
"Invalid State: Can't execute instruction", // InvalidStateCannotExecuteInstruction
"Can't execute instruction within its hold up time", // CannotExecuteInstructionWithinHoldUpTime
'Instruction already executed', // InstructionAlreadyExecuted
'Invalid Instruction index', // InvalidInstructionIndex
'Instruction hold up time is below the min specified by Governance', // InstructionHoldUpTimeBelowRequiredMin
'Instruction at the given index for the Proposal already exists', // InstructionAlreadyExists
"Invalid State: Can't sign off", // InvalidStateCannotSignOff
"Invalid State: Can't vote", // InvalidStateCannotVote
"Invalid State: Can't finalize vote", // InvalidStateCannotFinalize
"Invalid State: Can't cancel Proposal", // InvalidStateCannotCancelProposal
'Vote already relinquished', // VoteAlreadyRelinquished
"Can't finalize vote. Voting still in progress", // CannotFinalizeVotingInProgress
'Proposal voting time expired', // ProposalVotingTimeExpired
'Invalid Signatory Mint', // InvalidSignatoryMint
'Invalid account owner', // InvalidAccountOwner
"Account doesn't exist", // AccountDoesNotExist
'Invalid Account type', // InvalidAccountType
'Proposal does not belong to the given Governance', // InvalidGovernanceForProposal
'Proposal does not belong to given Governing Mint', // InvalidGoverningMintForProposal
'Current mint authority must sign transaction', // MintAuthorityMustSign
'Invalid mint authority', // InvalidMintAuthority
'Mint has no authority', // MintHasNoAuthority
'Invalid Token account owner', // SplTokenAccountWithInvalidOwner
'Invalid Mint account owner', // SplTokenMintWithInvalidOwner
'Token Account is not initialized', // SplTokenAccountNotInitialized
"Token Account doesn't exist", // SplTokenAccountDoesNotExist
'Token account data is invalid', // SplTokenInvalidTokenAccountData
'Token mint account data is invalid', // SplTokenInvalidMintAccountData
'Token Mint account is not initialized', // SplTokenMintNotInitialized
"Token Mint account doesn't exist", // SplTokenMintDoesNotExist
'Invalid ProgramData account address', // InvalidProgramDataAccountAddress
'Invalid ProgramData account Data', // InvalidProgramDataAccountData
"Provided upgrade authority doesn't match current program upgrade authority", // InvalidUpgradeAuthority
'Current program upgrade authority must sign transaction', // UpgradeAuthorityMustSign
'Given program is not upgradable', //ProgramNotUpgradable
'Invalid token owner', //InvalidTokenOwner
'Current token owner must sign transaction', // TokenOwnerMustSign
'Given VoteThresholdPercentageType is not supported', //VoteThresholdPercentageTypeNotSupported
'Given VoteWeightSource is not supported', //VoteWeightSourceNotSupported
'Proposal cool off time is not supported', // ProposalCoolOffTimeNotSupported
'Governance PDA must sign', // GovernancePdaMustSign
'Instruction already flagged with error', // InstructionAlreadyFlaggedWithError
'Invalid Realm for Governance', // InvalidRealmForGovernance
'Invalid Authority for Realm', // InvalidAuthorityForRealm
'Realm has no authority', // RealmHasNoAuthority
'Realm authority must sign', // RealmAuthorityMustSign
'Invalid governing token holding account', // InvalidGoverningTokenHoldingAccount
'Realm council mint change is not supported', // RealmCouncilMintChangeIsNotSupported
'Not supported mint max vote weight source', // MintMaxVoteWeightSourceNotSupported
'Invalid max vote weight supply fraction', // InvalidMaxVoteWeightSupplyFraction
"Owner doesn't have enough governing tokens to create Governance", // NotEnoughTokensToCreateGovernance
]
export const TokenError: Record<number, string> = [
'Lamport balance below rent-exempt threshold', // NotRentExempt
'Insufficient funds', // InsufficientFunds
'Invalid Mint', // InvalidMint
'Account not associated with this Mint', // MintMismatch,
'Owner does not match', // OwnerMismatch,
'Fixed supply', // FixedSupply,
'Already in use', // AlreadyInUse,
'Invalid number of provided signers', // InvalidNumberOfProvidedSigners,
'Invalid number of required signers', // InvalidNumberOfRequiredSigners,
'State is uninitialized', // UninitializedState,
'Instruction does not support native tokens', // NativeNotSupported,
'Non-native account can only be closed if its balance is zero', // NonNativeHasBalance,
'Invalid instruction', // InvalidInstruction,
'State is invalid for requested operation', // InvalidState,
'Operation overflowed', // Overflow,
'Account does not support specified authority type', // AuthorityTypeNotSupported,
'This token mint cannot freeze accounts', // MintCannotFreeze,
'Account is frozen', // AccountFrozen,
'The provided decimals value different from the Mint decimals', // MintDecimalsMismatch,
]
const governanceErrorOffset = 500
export function getTransactionErrorMsg(error: SendTransactionError) {
try {
const instructionError = (error.txError as any).InstructionError[1]
if (instructionError.Custom !== undefined) {
if (instructionError.Custom >= governanceErrorOffset) {
return GovernanceError[instructionError.Custom - governanceErrorOffset]
} else {
// If the error is not from the Governance error space then it's ambiguous because the custom errors share the same space
// And we can only use some heuristics here to guess what program returned the error
// For now the most common scenario is an error returned from the token program so I'm mapping the custom errors to it with the 'possible' warning
return `Possible error: ${TokenError[instructionError.Custom]}`
}
} else {
return instructionError
}
} catch {
return JSON.stringify(error)
}
}
export class WalletNotConnectedError extends Error {
constructor() {
super('Wallet is not connected.')
}
}
export function isWalletNotConnectedError(
error: any
): error is WalletNotConnectedError {
return error instanceof WalletNotConnectedError
}