UNPKG

@aibtc/types

Version:

TypeScript types for AIBTC

232 lines (231 loc) 11.1 kB
import { CONTRACT_NAMES, } from "./utilities/contract-types"; import * as ClarityErrors from "./clarity-contract-errors"; const errorDefinitions = { AGENT: { AGENT_ACCOUNT: { enumObject: ClarityErrors.ErrCodeAgentAccount, descriptions: { ERR_UNAUTHORIZED: "Sender is not authorized to perform this action.", ERR_UNKNOWN_ASSET: "The specified asset is not recognized or supported.", ERR_OPERATION_FAILED: "The requested operation failed to complete.", ERR_BUY_SELL_NOT_ALLOWED: "Buying or selling is not currently allowed by the agent.", }, }, }, BASE: { DAO: { enumObject: ClarityErrors.ErrCodeBaseDao, descriptions: { ERR_UNAUTHORIZED: "Sender is not authorized to perform this action.", ERR_ALREADY_EXECUTED: "The proposal has already been executed.", ERR_INVALID_EXTENSION: "The specified extension is not valid or recognized.", ERR_NO_EMPTY_LISTS: "Input lists cannot be empty.", ERR_DAO_ALREADY_CONSTRUCTED: "The DAO has already been constructed/initialized.", }, }, }, EXTENSIONS: { ACTION_PROPOSAL_VOTING: { enumObject: ClarityErrors.ErrCodeActionProposalVoting, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_FETCHING_TOKEN_DATA: "Failed to fetch on-chain token data.", ERR_INSUFFICIENT_BALANCE: "Insufficient DAO token balance to create the proposal.", ERR_PROPOSAL_NOT_FOUND: "The specified proposal ID was not found.", ERR_PROPOSAL_VOTING_ACTIVE: "Voting on the proposal is still active.", ERR_PROPOSAL_EXECUTION_DELAY: "Proposal execution delay has not passed.", ERR_PROPOSAL_RATE_LIMIT: "Proposal creation rate limit exceeded (only 1 per Bitcoin block).", ERR_SAVING_PROPOSAL: "Failed to save the proposal details.", ERR_PROPOSAL_ALREADY_CONCLUDED: "The proposal has already been concluded.", ERR_RETRIEVING_START_BLOCK_HASH: "Failed to retrieve start block hash for voting.", ERR_VOTE_TOO_SOON: "Vote cast before voting period started, or veto cast before veto period started.", ERR_VOTE_TOO_LATE: "Vote cast after voting period ended, or veto cast after veto period ended.", ERR_ALREADY_VOTED: "The voter has already cast a veto vote on this proposal.", ERR_INVALID_ACTION: "This contract or the proposed action contract is not an extension in the DAO.", }, }, DAO_CHARTER: { enumObject: ClarityErrors.ErrCodeDaoCharter, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_SAVING_CHARTER: "Failed to save the DAO charter.", ERR_CHARTER_TOO_SHORT: "The provided charter is too short.", ERR_CHARTER_TOO_LONG: "The provided charter is too long.", }, }, DAO_USERS: { enumObject: ClarityErrors.ErrCodeDaoUsers, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_USER_NOT_FOUND: "The specified user was not found.", }, }, ONCHAIN_MESSAGING: { enumObject: ClarityErrors.ErrCodeOnchainMessaging, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_INVALID_INPUT: "The input provided for messaging is invalid.", ERR_FETCHING_TOKEN_DATA: "Failed to fetch token data for messaging conditions.", }, }, REWARDS_ACCOUNT: { enumObject: ClarityErrors.ErrCodeRewardsAccount, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_INSUFFICIENT_BALANCE: "Insufficient balance in the rewards account.", }, }, TOKEN_OWNER: { enumObject: ClarityErrors.ErrCodeTokenOwner, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", }, }, TREASURY: { enumObject: ClarityErrors.ErrCodeTreasury, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_ASSET_NOT_ALLOWED: "The specified asset is not allowed in the treasury.", }, }, }, ACTIONS: { SEND_MESSAGE: { enumObject: ClarityErrors.ErrCodeActionSendMessage, descriptions: { ERR_NOT_DAO_OR_EXTENSION: "Caller is not the DAO or an authorized extension.", ERR_INVALID_PARAMETERS: "Invalid parameters provided for sending a message.", }, }, }, }; const allErrorDetailsList = []; function initializeErrorService() { for (const typeKey in errorDefinitions) { const contractType = typeKey; const subtypesOfType = errorDefinitions[contractType]; if (subtypesOfType) { for (const subtypeKey in subtypesOfType) { const contractSubtype = subtypeKey; // The type assertion here is necessary because TypeScript can't infer // that subtypeKey is a valid key for subtypesOfType within this generic loop. const definition = subtypesOfType[contractSubtype]; if (definition) { const officialContractName = CONTRACT_NAMES[contractType]?.[contractSubtype] || `${contractType}-${contractSubtype}-UnknownName`; for (const enumMemberName in definition.enumObject) { if (isNaN(Number(enumMemberName))) { // Filter out reverse numeric mappings from enums const numericCode = definition.enumObject[enumMemberName]; allErrorDetailsList.push({ contractType: contractType, contractSubtype: contractSubtype, contractName: officialContractName, code: numericCode, name: enumMemberName, description: definition.descriptions[enumMemberName] || "No description available.", }); } } } } } } } initializeErrorService(); // Populate the list on module load /** * Retrieves all known error details. * @returns A shallow copy of the list of all enriched error code details. */ export function getAllErrorDetails() { return [...allErrorDetailsList]; } /** * Retrieves error details for a specific contract type and subtype. * @param params Parameters to filter errors by. * @param params.type The contract type. * @param params.subtype The contract subtype. * @returns An array of enriched error code details matching the contract type and subtype. */ export function getErrorsByContractDetails(params) { return allErrorDetailsList.filter((detail) => detail.contractType === params.type && detail.contractSubtype === params.subtype); } /** * Finds error details based on various criteria. * This is a flexible search function. * @param params Parameters to filter errors by. * @param params.identifier Optional. Error name (string) or code (number or "u" prefixed string like "u1234"). * @param params.contractType Optional. The contract type to scope the search. * @param params.contractSubtype Optional. The contract subtype to scope the search. * @returns An array of enriched error code details matching the criteria. */ export function findErrorDetails(params) { let results = [...allErrorDetailsList]; if (params.contractType) { results = results.filter((detail) => detail.contractType === params.contractType); if (params.contractSubtype) { results = results.filter((detail) => detail.contractSubtype === params.contractSubtype); } } if (params.identifier !== undefined) { let numericCode; let searchName; if (typeof params.identifier === "number") { numericCode = params.identifier; } else if (typeof params.identifier === "string") { if (params.identifier.toLowerCase().startsWith("u")) { const potentialCode = parseInt(params.identifier.substring(1), 10); if (!isNaN(potentialCode)) { numericCode = potentialCode; } else { searchName = params.identifier; // Not a 'uXXXX' format, treat as name } } else { // If it's a string that can be parsed as a number, treat it as a code. const potentialCode = parseInt(params.identifier, 10); if (!isNaN(potentialCode) && String(potentialCode) === params.identifier) { numericCode = potentialCode; } else { searchName = params.identifier; // Treat as name } } } if (numericCode !== undefined) { results = results.filter((detail) => detail.code === numericCode); } else if (searchName) { results = results.filter((detail) => detail.name === searchName); } } return results; } /** * Retrieves the description for a specific error. * For reliable results when using an error name as an identifier, * contractType and contractSubtype should be provided to ensure uniqueness. * @param params Parameters to identify the error. * @param params.identifier Error name (string) or code (number or "u" prefixed string). * @param params.contractType Required when identifier is a name to ensure uniqueness. Recommended for code. * @param params.contractSubtype Required when identifier is a name to ensure uniqueness. Recommended for code. * @returns The error description if a unique match is found, otherwise undefined. */ export function getErrorDescription(params) { const matchingDetails = findErrorDetails({ identifier: params.identifier, contractType: params.contractType, contractSubtype: params.contractSubtype, }); if (matchingDetails.length === 1) { return matchingDetails[0].description; } // If 0 or more than 1 match (ambiguous), return undefined. // This enforces that the caller provides enough specificity. return undefined; }