@tenderly/sdk
Version:
816 lines (791 loc) • 26.6 kB
TypeScript
import axios, { AxiosResponse } from 'axios';
type Path = string;
type Web3Address = string;
declare enum Network {
MAINNET = 1,
OPTIMISTIC = 10,
RSK = 30,
RSK_TESTNET = 31,
BINANCE = 56,
RIALTO_BINANCE = 97,
GNOSIS_CHAIN = 100,
BOB_SEPOLIA = 111,
POLYGON = 137,
FRAXTAL = 252,
BOBA_ETHEREUM = 288,
WORLDCHAIN = 480,
MODE_SEPOLIA = 919,
LISK = 1135,
MOONBEAM = 1284,
MOONRIVER = 1285,
MOONBASE_ALPHA = 1287,
SEI_ATLANTIC_2 = 1328,
SEI_PACIFIC_1 = 1329,
FRAXTAL_HOLESKY = 2522,
MORPH_HOLESKY = 2810,
LISK_SEPOLIA = 4202,
GOLD = 4653,
WORLDCHAIN_SEPOLIA = 4801,
MANTLE = 5000,
MANTLE_SEPOLIA = 5003,
ZETACHAIN = 7000,
ZETACHAIN_TESTNET = 7001,
KINTO = 7887,
POLYNOMIAL = 8008,
BASE = 8453,
BOBA_BINANCE_RIALTO = 9728,
INTERVAL_TESTNET = 11069,
IMMUTABLE = 13371,
IMMUTABLE_TESTNET = 13473,
HOLESKY = 17000,
UNREAL = 18233,
CONCRETE_TESTNET = 18291,
BOBA_SEPOLIA = 28882,
APECHAIN_CURTIS = 33111,
APECHAIN = 33139,
MODE = 34443,
ARBITRUM_ONE = 42161,
ARBITRUM_NOVA = 42170,
AVALANCHE_FUJI = 43113,
AVALANCHE = 43114,
BOBA_BINANCE = 56288,
LINEA_SEPOLIA = 59141,
LINEA = 59144,
BOB = 60808,
POLYGON_AMOY = 80002,
POLYNOMIAL_SEPOLIA = 80008,
BLAST = 81457,
BASE_SEPOLIA = 84532,
REAL = 111188,
TAIKO = 167000,
TAIKO_HEKLA = 167009,
ARBITRUM_SEPOLIA = 421614,
ZORA = 7777777,
SEPOLIA = 11155111,
OPTIMISTIC_SEPOLIA = 11155420,
ZORA_SEPOLIA = 999999999
}
type TenderlyConfiguration = {
accountName: string;
projectName: string;
accessKey: string;
network: Network | number;
};
type WithRequired<T, K extends keyof T> = T & {
[P in K]-?: T[P];
};
type EmptyObject = Record<PropertyKey, never>;
interface Repository<T> {
get: (uniqueId: string) => Promise<T | undefined>;
add: (uniqueId: string, data: Partial<T>) => Promise<T | undefined>;
remove: (uniqueId: string) => Promise<void>;
update: (uniqueId: string, data: never) => Promise<unknown | undefined>;
getBy: (queryObject: never) => Promise<T[] | undefined>;
getAll: () => Promise<T[] | undefined>;
}
interface Contract {
address: string;
network: Network;
displayName?: string;
tags?: string[];
}
type TenderlyContract = Contract;
interface ContractRequest {
address: string;
network_id: string;
display_name?: string;
}
type GetByParams = {
tags?: string[];
displayNames?: string[];
};
type ContractResponse = {
id: string;
account_type: 'contract';
contract: InternalContract;
display_name: string;
tags?: {
tag: string;
}[];
};
interface InternalContract {
id: string;
contract_id: string;
balance: string;
network_id: string;
public: boolean;
export: boolean;
verified_by: string;
verification_date: string | null;
address: string;
contract_name: string;
ens_domain: string | null;
type: string;
standard: string;
standards: string[];
token_data: {
symbol: string;
name: string;
main: boolean;
};
evm_version: string;
compiler_version: string;
optimizations_used: boolean;
optimization_runs: number;
libraries: null;
data: {
main_contract: number;
contract_info: {
id: number;
path: string;
name: string;
source: string;
abi: unknown[];
raw_abi: unknown[];
states: unknown[];
} | null;
creation_block: number;
creation_tx: string;
creator_address: string;
created_at: string;
number_of_watches: null;
language: string;
in_project: boolean;
number_of_files: number;
};
account: {
id: string;
contract_id: string;
balance: string;
network_id: string;
public: boolean;
export: boolean;
verified_by: string;
verification_date: string | null;
address: string;
contract_name: string;
ens_domain: string | null;
type: string;
standard: string;
standards: string[];
evm_version: string;
compiler_version: string;
optimizations_used: boolean;
optimization_runs: number;
libraries: null;
data: null;
creation_block: number;
creation_tx: string;
creator_address: string;
created_at: string;
number_of_watches: null;
language: string;
in_project: boolean;
number_of_files: number;
};
project_id: string;
added_by_id: string;
previous_versions: unknown[];
details_visible: boolean;
include_in_transaction_listing: boolean;
display_name: string;
account_type: string;
verification_type: string;
added_at: string;
}
type UpdateContractRequest = {
displayName?: string;
appendTags?: string[];
};
type SolidityCompilerVersions = `v${number}.${number}.${number}`;
type SolcConfig = {
version: SolidityCompilerVersions;
sources: Record<Path, {
content: string;
}>;
settings: unknown;
};
type TenderlySolcConfigLibraries = Record<string, {
addresses: Record<string, string>;
}>;
type VerificationRequest = {
contractToVerify: string;
solc: SolcConfig;
config: {
mode: 'private' | 'public';
};
};
type VerificationResponse = {
compilation_errors: CompilationErrorResponse[];
results: VerificationResult[];
};
type CompilationErrorResponse = {
source_location: SourceLocation;
error_ype: string;
component: string;
message: string;
formatted_message: string;
};
interface SourceLocation {
file: string;
start: number;
end: number;
}
interface VerificationResult {
bytecode_mismatch_error: BytecodeMismatchErrorResponse;
verified_contract: InternalContract;
}
type BytecodeMismatchErrorResponse = {
contract_id: string;
expected: string;
got: string;
similarity: number;
assumed_reason: string;
};
type ApiVersion = 'v1' | 'v2';
declare class ApiClient {
private readonly api;
/**
* @param apiKey API key to be used for the requests.
* Can be generated in the Tenderly dashboard: https://dashboard.tenderly.co/account/authorization
* @param version API version to be used for the requests. Defaults to 'v1'
*/
constructor({ apiKey, version }: {
apiKey: string;
version?: ApiVersion;
});
/**
*
* @param path url path to the resource
* @param params url query params
* @returns Promise with AxiosResponse that
* contains the response data model with a type of a given generic parameter
*/
get<ResponseModel>(path: string, params?: Record<string, string | string[]>): Promise<axios.AxiosResponse<ResponseModel, any>>;
/**
*
* @param path url path to the resource
* @param data data to be sent to the server. Type of data expected can be specified with a second generic parameter
* @returns Promise with AxiosResponse that
* contains the response data model with a type of a second generic parameter
*/
post<RequestModel, ResponseModel>(path: string, data?: RequestModel): Promise<axios.AxiosResponse<ResponseModel, any>>;
/**
*
* @param path url path to the resource
* @param data data to be sent to the server in order to update the model.
* Type of data expected can be specified with a second generic parameter
* @param params url query params
* @returns Promise with AxiosResponse that contains the response data model with a type of a second generic parameter
*/
put<RequestModel, ResponseModel>(path: string, data?: RequestModel, params?: Record<string, string>): Promise<axios.AxiosResponse<ResponseModel, any>>;
/**
* @param path url path to the resource
* @param data data to be sent to the server in order to remove the model.
* @returns AxiosResponse
*/
delete(path: string, data?: Record<string, unknown>): Promise<AxiosResponse>;
}
declare class ApiClientProvider {
static instance: ApiClientProvider;
private readonly apiKey;
private readonly apiClients;
constructor({ apiKey }: {
apiKey: string;
});
getApiClient({ version }: {
version: ApiVersion;
}): ApiClient;
}
declare class ContractRepository implements Repository<TenderlyContract> {
private readonly apiV1;
private readonly apiV2;
private readonly configuration;
constructor({ apiProvider, configuration, }: {
apiProvider: ApiClientProvider;
configuration: TenderlyConfiguration;
});
/**
* Get a contract by address if it exists in the Tenderly's instances' project
* @param address - The address of the contract
* @returns The contract object in a plain format
* @example
* const contract = await tenderly.contracts.get('0x1234567890');
*/
get(address: string): Promise<Contract | undefined>;
/**
* Add a contract to the Tenderly's instances' project
* @param address - The address of the contract
* @param contractData - The data of the contract
* @returns The contract object in a plain format
* @example
* const contract = await tenderly.contracts.add('0x1234567890');
* // or
* const contract = await tenderly.contracts.add('0x1234567890', { displayName: 'MyContract' });
*/
add(address: string, contractData?: {
displayName?: string;
}): Promise<Contract | undefined>;
/**
* Remove a contract from the Tenderly's instances' project
* @param address - The address of the contract
* @returns The contract object in a plain format
* @example
* await tenderly.contracts.remove('0x1234567890');
*/
remove(address: string): Promise<void>;
/**
* Update a contract in the Tenderly's instances' project
* @param address - The address of the contract
* @param payload - The data of the contract
* @returns The contract object in a plain format
* @example
* const contract = await tenderly.contracts.update('0x1234567890', { displayName: 'MyContract' });
* // or
* const contract = await tenderly.contracts.update('0x1234567890', { tags: ['my-tag'] });
* // or
* const contract = await tenderly.contracts.update('0x1234567890', {
* displayName: 'MyContract',
* appendTags: ['my-tag']
* });
* // or
* const contract = await tenderly.contracts.update('0x1234567890', { appendTags: ['my-tag'] });
*/
update(address: string, payload: UpdateContractRequest): Promise<Contract | undefined>;
getAll(): Promise<Contract[] | undefined>;
/**
* Get all contracts in the Tenderly's instances' project
* @param queryObject - The query object
* @returns The contract objects in a plain format
* @example
* const contracts = await tenderly.contracts.getBy();
* const contracts = await tenderly.contracts.getBy({
* tags: ['my-tag'],
* displayName: ['MyContract']
* });
*/
getBy(queryObject?: GetByParams): Promise<TenderlyContract[] | undefined>;
private buildQueryParams;
/**Verifies a contract on Tenderly by submitting a verification request with
* the provided address and verification details.
* @param {string} address - The address of the contract to be verified.
* @param {VerificationRequest} verificationRequest - Details of the verification request.
* @returns {Promise<TenderlyContract>} - A Promise that resolves to a TenderlyContract
* object representing the verified contract.
*/
verify(address: string, verificationRequest: VerificationRequest): Promise<TenderlyContract | undefined>;
_mapSolcSourcesToTenderlySources(sources: Record<Path, {
name?: string;
content: string;
}>): Record<string, {
name?: string | undefined;
code: string;
}>;
_repackLibraries(solcConfig: SolcConfig): Omit<SolcConfig, "sources">;
_isFullyQualifiedContractName(contractName: string): boolean;
_copySolcConfigToTenderlySolcConfig(solcConfig: SolcConfig): Omit<SolcConfig, 'sources'>;
}
interface Wallet {
address: string;
displayName?: string;
tags?: string[];
network: Network;
}
type TenderlyWallet = Wallet;
type WalletRequest = {
address: string;
display_name: string;
network_ids: string[];
};
type WalletResponse = {
id: string;
account_type: 'wallet';
display_name: string;
account: {
id: string;
contract_id: string;
balance: string;
network_id: string;
address: string;
};
contract?: {
id: string;
contract_id: string;
balance: string;
network_id: string;
address: string;
};
wallet?: {
id: string;
contract_id: string;
balance: string;
network_id: string;
address: string;
};
tags?: {
tag: string;
}[];
};
type UpdateWalletRequest = {
displayName?: string;
appendTags?: string[];
};
declare class WalletRepository implements Repository<TenderlyWallet> {
private readonly apiV1;
private readonly apiV2;
private readonly configuration;
constructor({ apiProvider, configuration, }: {
apiProvider: ApiClientProvider;
configuration: TenderlyConfiguration;
});
/**
* Get a contract by address if it exists in the Tenderly's instances' project
* @param address - The address of the contract
* @returns The contract object in a plain format
* @example
* const contract = await tenderly.contracts.get('0x1234567890');
*/
get(address: string): Promise<Wallet | undefined>;
/**
* Add a wallet to the project.
* @param address - The address of the wallet
* @param walletData - Values to populate the displayName
* @returns The wallet object in a plain format
* @example
* const wallet = await tenderly.contracts.add('0x1234567890', { displayName: 'My Wallet' });
*/
add(address: string, walletData?: {
displayName?: string;
}): Promise<Wallet | undefined>;
/**
* Remove a wallet from the Tenderly instances' project.
* @param address - The address of the wallet
* @returns {Promise<void>}
* @example
* await tenderly.contracts.remove('0x1234567890');
*/
remove(address: string): Promise<void>;
/**
* Update a wallet's displayName and/or tags.
* @param address - The address of the wallet
* @param payload - The values to update the wallet with
* @returns The wallet object in a plain format
* @example
* const wallet = await tenderly.contracts.update('0x1234567890', {
* displayName: 'My Wallet',
* appendTags: ['my-tag']
* });
* const wallet = await tenderly.contracts.update('0x1234567890', { displayName: 'My Wallet' });
* const wallet = await tenderly.contracts.update('0x1234567890', { appendTags: ['my-tag'] });
*/
update(address: string, payload: UpdateWalletRequest): Promise<Wallet | undefined>;
/**
* Get all wallets in the Tenderly instances' project.
*
*/
getAll(): Promise<Wallet[] | undefined>;
/**
* Get all wallets in the Tenderly instances' project.
* @param queryObject - The query object to filter the wallets with
* @returns An array of wallets in a plain format
* @example
* const wallets = await tenderly.contracts.getBy();
* const wallets = await tenderly.contracts.getBy({
* displayName: 'My Wallet',
* tags: ['my-tag']
* });
*/
getBy(queryObject?: GetByParams): Promise<TenderlyWallet[] | undefined>;
private buildQueryParams;
}
type TransactionParameters = {
from: Web3Address;
to: Web3Address;
input: string;
gas: number;
gas_price: string;
max_fee_per_gas?: number;
max_priority_fee_per_gas?: number;
value: string | number;
access_list?: AccessList;
};
type AccessList = {
value_address: string;
value_storage_keys: string[];
}[];
type SimulationRequestOverrides = {
[contractAddress: Web3Address]: SimulationRequestOverride;
};
type SimulationRequestOverride = {
nonce?: number;
code?: string;
balance?: string;
state_diff?: {
[storageKey: string]: string | unknown;
};
};
type SimulationRequest = {
network_id: string;
call_args: SimulationCallArguments;
block_number_or_hash: {
blockNumber: number;
};
overrides?: SimulationRequestOverrides | null;
};
type SimulationBundleRequest = {
network_id: string;
call_args: SimulationCallArguments[];
block_number_or_hash: {
blockNumber: number;
};
overrides?: SimulationRequestOverrides | null;
};
type SimulationCallArguments = {
from: string;
to: string;
gas: number;
gas_price?: string;
max_fee_per_gas?: number;
max_priority_fee_per_gas?: number;
value: string | number;
data: string;
access_list?: AccessList;
};
type SimulationBundleDetails = {
transactions: TransactionParameters[];
blockNumber: number;
overrides?: SimulationParametersOverrides | null;
};
type SimulationParametersOverrides = {
[contractAddress: Web3Address]: SimulationParametersOverride;
};
type SimulationParametersOverride = {
nonce?: number;
code?: string;
balance?: string;
state?: {
[property: string]: unknown;
};
};
type SimulationParameters = {
transaction: TransactionParameters;
blockNumber: number;
overrides?: SimulationParametersOverrides | null;
};
type SimulationOutput = {
status?: boolean;
gasUsed?: number;
cumulativeGasUsed?: number;
blockNumber?: number;
type?: number;
logsBloom?: Uint8Array;
logs?: SimulateSimpleResponse_DecodedLog[];
trace?: SimulateSimpleResponse_TraceResponse[];
};
interface SimulateBundleResponse {
simulations: SimulateSimpleResponse[];
}
interface SimulateSimpleResponse {
status?: boolean;
gas_used?: number;
cumulative_gas_used?: number;
block_number?: number;
type?: number;
logs_bloom?: Uint8Array;
logs?: SimulateSimpleResponse_DecodedLog[];
trace?: SimulateSimpleResponse_TraceResponse[];
}
type StateOverride = Record<Web3Address, {
value: Record<string, unknown>;
}>;
type EncodeStateRequest = {
networkID: string;
stateOverrides: StateOverride;
};
type EncodedStateOverride = Record<Web3Address, Record<string, unknown>>;
interface SimulateSimpleResponse_DecodedLog {
name?: string;
anonymous?: boolean;
inputs?: SimulateSimpleResponse_DecodedArgument[];
raw?: RawEvent;
}
interface SimulateSimpleResponse_DecodedArgument {
value?: unknown;
type?: string;
name?: string;
}
interface RawEvent {
address?: string;
topics: string[];
data: string;
}
interface SimulateSimpleResponse_TraceResponse {
type?: string;
from?: string;
to?: string;
gas?: number;
gas_used?: number;
address?: string | null;
balance?: number | null;
refund_address?: string | null;
value?: number | null;
error?: string | null;
/**
* @deprecated Use {@link error_reason} instead
*/
error_messages?: string | null;
error_reason?: string | null;
input?: string | null;
decoded_input?: SimulateSimpleResponse_DecodedArgument[];
method?: string | null;
output?: string | null;
decoded_output?: SimulateSimpleResponse_DecodedArgument[];
subtraces?: number;
trace_address?: number[];
}
declare class Simulator {
private readonly apiV1;
private readonly configuration;
private readonly apiV2;
constructor({ apiProvider, configuration, }: {
apiProvider: ApiClientProvider;
configuration: TenderlyConfiguration;
});
private mapStateOverridesToEncodeStateRequest;
private mapToEncodedOverrides;
private replaceJSONOverridesWithEncodedOverrides;
private buildSimulationBundleRequest;
private buildSimpleSimulationRequest;
private encodeOverrideRequest;
private encodeStateOverrides;
private executeSimpleSimulationRequest;
private executeSimulationBundleRequest;
/**
* Simulates a transaction by encoding overrides, building a request body, and executing a simulation request.
* @async
* @function
* @param {SimulationParameters} simulationParams - Parameters for the transaction simulation.
* @param {object} simulationParams.transaction - The transaction object to be simulated.
* @param {number} simulationParams.blockNumber - The block number for the simulation.
* @param {object} simulationParams.overrides - Overrides for the transaction simulation.
* @returns {Promise<SimulationOutput>} - A Promise that resolves to a simulation output.
*/
simulateTransaction({ transaction, blockNumber, overrides, }: SimulationParameters): Promise<SimulationOutput | undefined>;
/**
* Simulates a bundle of transactions by encoding overrides, building a request body,
* and executing a simulation bundle request.
* @async
* @function
* @param {SimulationBundleDetails} params - Details of the transaction bundle simulation.
* @param {object[]} params.transactions - An array of transaction objects to be simulated.
* @param {object} params.overrides - Overrides for the transaction bundle simulation.
* @param {number} params.blockNumber - The block number for the simulation bundle.
* @returns {Promise<SimulationOutput[]>} - A Promise that resolves to an array of simulation result objects.
*/
simulateBundle({ transactions, overrides, blockNumber }: SimulationBundleDetails): Promise<SimulationOutput[] | undefined>;
}
/**
* The main class of the Tenderly SDK
* Instantiate this class with your config, and you're ready to go
* @example
* const tenderly = new Tenderly({
* accountName: 'my-account',
* projectName: 'my-project',
* accessKey: 'my-access-key',
* network: Network.Mainnet,
* })
*/
declare class Tenderly {
readonly configuration: TenderlyConfiguration;
/**
* Contract repository - used for managing contracts on your project
*/
readonly contracts: ContractRepository & {
verify: (address: string, verificationRequest: VerificationRequest) => Promise<unknown>;
};
/**
* Wallet repository - used for managing wallets on your project
*/
readonly wallets: WalletRepository;
/**
* Simulator - used for simulating transactions
*/
readonly simulator: Simulator;
private readonly apiClientProvider;
/**
* The main class of the Tenderly SDK
* Instantiate this class with your config, and you're ready to go
* @example
* const tenderly = new Tenderly({
* accountName: 'my-account',
* projectName: 'my-project',
* accessKey: 'my-access-key',
* network: Network.Mainnet,
* })
*/
constructor(configuration: TenderlyConfiguration);
/**
* Create a new Tenderly instance with the provided configuration override
* @param configurationOverride - The configuration override
* @returns The new Tenderly instance
* @example
* const tenderly = new Tenderly({
* accountName: 'my-account',
* projectName: 'my-project',
* );
*/
with(configurationOverride: Partial<TenderlyConfiguration>): Tenderly;
checkConfiguration(configuration: TenderlyConfiguration): void;
}
interface TenderlyError {
readonly id?: string;
readonly message: string;
readonly slug: string;
}
declare abstract class GeneralError<T = unknown> extends Error implements TenderlyError {
readonly id?: string;
readonly message: string;
readonly slug: string;
readonly data?: T;
constructor({ id, message, slug, data }: TenderlyError & {
data?: T;
});
static handle(error: Error | unknown): void;
}
declare class ApiError extends GeneralError {
readonly status: number;
constructor({ status, ...error }: {
status: number;
} & TenderlyError);
static handle(error: Error | unknown): void;
}
declare class BytecodeMismatchError extends GeneralError<BytecodeMismatchErrorResponse> {
constructor(message: string, data?: BytecodeMismatchErrorResponse);
}
declare class CompilationError extends GeneralError<CompilationErrorResponse[]> {
constructor(message: string, data?: CompilationErrorResponse[]);
}
declare class EncodingError extends GeneralError {
constructor(error: TenderlyError);
}
declare class InvalidArgumentsError extends GeneralError {
constructor(message: string);
}
declare class InvalidResponseError extends GeneralError {
constructor(message: string);
}
declare class NotFoundError extends GeneralError {
constructor(message: string);
}
declare class UnexpectedVerificationError extends GeneralError {
constructor(message: string);
}
declare function handleError(error: Error | unknown): void;
type TenderlyEnvVariables = {
TENDERLY_ACCESS_KEY: string;
TENDERLY_ACCOUNT_NAME: string;
TENDERLY_PROJECT_NAME: string;
TENDERLY_GET_BY_PROJECT_NAME: string;
};
declare function getEnvironmentVariables(): TenderlyEnvVariables;
export { ApiError, BytecodeMismatchError, BytecodeMismatchErrorResponse, CompilationError, CompilationErrorResponse, Contract, ContractRequest, ContractResponse, EmptyObject, EncodeStateRequest, EncodedStateOverride, EncodingError, GeneralError, GetByParams, InvalidArgumentsError, InvalidResponseError, Network, NotFoundError, Path, RawEvent, SimulateBundleResponse, SimulateSimpleResponse, SimulateSimpleResponse_TraceResponse, SimulationBundleDetails, SimulationBundleRequest, SimulationCallArguments, SimulationOutput, SimulationParameters, SimulationParametersOverride, SimulationParametersOverrides, SimulationRequest, SimulationRequestOverride, SimulationRequestOverrides, SolcConfig, SolidityCompilerVersions, StateOverride, Tenderly, TenderlyConfiguration, TenderlyContract, TenderlyError, TenderlySolcConfigLibraries, TenderlyWallet, TransactionParameters, UnexpectedVerificationError, UpdateContractRequest, UpdateWalletRequest, VerificationRequest, VerificationResponse, Wallet, WalletRequest, WalletResponse, Web3Address, WithRequired, getEnvironmentVariables, handleError };