accounts
Version:
Tempo Accounts SDK
170 lines • 7.88 kB
JavaScript
import { decodeErrorResult } from 'viem';
import { Abis } from 'viem/tempo';
/** Human-readable messages keyed by ABI error name. */
export const messages = {
AddressAlreadyHasValidator: 'This address already has a validator.',
AddressNotReserved: 'Address is not reserved.',
AddressReserved: 'Address is reserved.',
AlreadyInitialized: 'Already initialized.',
BelowMinimumOrderSize: 'Order size is below the minimum allowed ({0}).',
CallNotAllowed: 'This call is not allowed.',
CannotChangeWithPendingFees: 'Cannot change while fees are pending.',
CannotChangeWithinBlock: 'Cannot change within the same block.',
ContractPaused: 'Contract is paused.',
DivisionByZero: 'Division by zero.',
EmptyV1ValidatorSet: 'Validator set is empty.',
ExpiringNonceReplay: 'Expiring nonce has already been used.',
ExpiringNonceSetFull: 'Expiring nonce set is full.',
ExpiryInPast: 'Expiry is in the past.',
IdenticalAddresses: 'Addresses must be different.',
IdenticalTokens: 'Cannot swap a token for itself — input and output tokens must be different.',
IncompatiblePolicyType: 'Incompatible policy type.',
IngressAlreadyExists: 'Ingress "{0}" already exists.',
InsufficientAllowance: 'Insufficient allowance.',
InsufficientBalance: 'Insufficient balance. Required: {1}, available: {0}.',
InsufficientFeeTokenBalance: 'Insufficient fee token balance.',
InsufficientLiquidity: 'Not enough liquidity in the order book to fill this trade.',
InsufficientOutput: 'The output amount is below the slippage minimum — try increasing slippage tolerance.',
InsufficientReserves: 'Insufficient reserves.',
InternalError: 'Internal error.',
InvalidAmount: 'Invalid amount.',
InvalidBaseToken: 'This token is not a valid base token for the requested pair.',
InvalidCallScope: 'Invalid call scope.',
InvalidCurrency: 'Invalid currency.',
InvalidExpiringNonceExpiry: 'Invalid expiring nonce expiry.',
InvalidFlipTick: 'The flip-order price tick is invalid.',
InvalidFormat: 'Invalid format.',
InvalidMasterAddress: 'Invalid master address.',
InvalidMigrationIndex: 'Invalid migration index.',
InvalidNonceKey: 'Invalid nonce key.',
InvalidOwner: 'Invalid owner.',
InvalidPayload: 'Invalid payload.',
InvalidPolicyType: 'Invalid policy type.',
InvalidPublicKey: 'Invalid public key.',
InvalidQuoteToken: 'Invalid quote token.',
InvalidRecipient: 'Invalid recipient.',
InvalidSignature: 'Invalid signature.',
InvalidSignatureFormat: 'Invalid signature format.',
InvalidSignatureType: 'Invalid signature type.',
InvalidSpendingLimit: 'Invalid spending limit.',
InvalidSupplyCap: 'Invalid supply cap.',
InvalidSwapCalculation: 'Invalid swap calculation.',
InvalidTick: 'The price tick is invalid.',
InvalidToken: 'This token is not supported on the exchange.',
InvalidTransferPolicyId: 'Invalid transfer policy.',
InvalidValidatorAddress: 'Invalid validator address.',
KeyAlreadyExists: 'Key already exists.',
KeyAlreadyRevoked: 'Key has already been revoked.',
KeyExpired: 'Key has expired.',
KeyNotFound: 'Key not found.',
LegacyAuthorizeKeySelectorChanged: 'Legacy authorize key selector changed to {0}.',
MasterIdCollision: 'Master ID collision with {0}.',
MaxInputExceeded: 'The required input exceeds the slippage maximum — try increasing slippage tolerance.',
MigrationNotComplete: 'Migration is not complete.',
NoOptedInSupply: 'No opted-in supply.',
NonceOverflow: 'Nonce overflow.',
NotHostPort: '"{1}" is not a valid host:port for {0}.',
NotInitialized: 'Not initialized.',
NotIp: '"{0}" is not a valid IP address.',
NotIpPort: '"{1}" is not a valid IP:port for {0}.',
OnlySystemContract: 'Only callable by system contract.',
OnlyValidator: 'Only callable by a validator.',
OrderDoesNotExist: 'No order exists with the given ID.',
OrderNotStale: 'This order is not yet eligible for stale-cleanup.',
PairAlreadyExists: 'A trading pair for these tokens has already been created.',
PairDoesNotExist: 'No trading pair exists for these tokens.',
PermitExpired: 'Permit has expired.',
PolicyForbids: 'Forbidden by policy.',
PolicyNotFound: 'Policy not found.',
PolicyNotSimple: 'Policy is not a simple policy.',
PoolDoesNotExist: 'Pool does not exist.',
ProofOfWorkFailed: 'Proof of work failed.',
ProtectedAddress: 'Address is protected.',
ProtocolNonceNotSupported: 'Protocol nonce is not supported.',
PublicKeyAlreadyExists: 'Public key already exists.',
SignatureTypeMismatch: 'Signature type mismatch. Expected {0}, got {1}.',
SpendingLimitExceeded: 'Spending limit exceeded.',
StringTooLong: 'String is too long.',
SupplyCapExceeded: 'Supply cap exceeded.',
TickOutOfBounds: 'Price tick {0} is outside the allowed range.',
TokenAlreadyExists: 'Token {0} already exists.',
TokenPolicyForbids: 'Forbidden by token policy.',
TransfersDisabled: 'Transfers are disabled.',
Unauthorized: 'Unauthorized.',
UnauthorizedCaller: 'Unauthorized caller.',
Uninitialized: 'Uninitialized.',
ValidatorAlreadyDeactivated: 'Validator is already deactivated.',
ValidatorAlreadyExists: 'Validator already exists.',
ValidatorNotFound: 'Validator not found.',
VirtualAddressNotAllowed: 'Virtual address is not allowed.',
VirtualAddressUnregistered: 'Virtual address is not registered.',
ZeroPublicKey: 'Public key cannot be zero.',
};
/** Interpolate `{0}`, `{1}`, … placeholders with args. */
function interpolate(template, args) {
if (!args)
return template;
return template.replace(/\{(\d+)\}/g, (_, i) => {
const v = args[Number(i)];
return v === undefined ? `{${i}}` : String(v);
});
}
/** Parse a viem error into a structured execution error. */
export function parse(error) {
const raw = error.details ??
error.shortMessage ??
error.message;
const data = extractRevertData(error);
if (data) {
try {
const decoded = decodeErrorResult({ abi: Abis.abis, data });
const template = messages[decoded.errorName];
return {
...decoded,
data,
message: template
? interpolate(template, decoded.args)
: raw.replace(/^execution reverted:\s*/i, ''),
};
}
catch { }
}
// Fallback: extract error name from human-readable revert message.
const nameMatch = /:\s*(\w+)\(\w+/.exec(raw);
const errorName = nameMatch?.[1];
if (errorName && errorName in messages)
return { errorName: 'unknown', message: messages[errorName] };
return {
errorName: 'unknown',
message: raw.replace(/^execution reverted:\s*/i, ''),
};
}
/** Serializes an ExecutionError for RPC transport (bigints/numbers → hex). */
export function serialize(preimage) {
if (preimage.errorName === 'unknown')
return { errorName: 'unknown', message: preimage.message };
return {
errorName: preimage.errorName,
abiItem: preimage.abiItem,
message: preimage.message,
data: preimage.data,
};
}
function extractRevertData(error) {
if (!error || typeof error !== 'object')
return null;
const e = error;
if (typeof e.data === 'string' && e.data.startsWith('0x'))
return e.data;
if (e.cause)
return extractRevertData(e.cause);
if (e.error)
return extractRevertData(e.error);
if (typeof e.walk === 'function') {
const inner = e.walk((e) => typeof e.data === 'string');
if (inner)
return extractRevertData(inner);
}
return null;
}
//# sourceMappingURL=ExecutionError.js.map