Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/contract/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,11 @@ export abstract class ContractInterface {
*/
public abstract getVersion(): Promise<ContractVersion>;

/**
* Returns a typed instance of ContractV2 based on the supplied ABI.
*
* @param {TAbi} tAbi - The ABI (Abstract Binary Interface) of the ContractV2.
* @return {TypedContractV2<TAbi>} - A typed instance of ContractV2.
*/
public abstract typedv2<TAbi extends AbiKanabi>(tAbi: TAbi): TypedContractV2<TAbi>;
}
9 changes: 8 additions & 1 deletion src/utils/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ export function validateAndParseAddress(address: BigNumberish): string {
return result;
}

// from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
/**
* Computes the checksum address for the given Starknet address.
*
* From https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
* @param {BigNumberish} address - The address to compute the checksum for.
*
* @returns {string} The checksum address.
*/
export function getChecksumAddress(address: BigNumberish): string {
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split('');
const hex = removeHexPrefix(keccakBn(address));
Expand Down
6 changes: 6 additions & 0 deletions src/utils/assert.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* Asserts that the given condition is true, otherwise throws an error with an optional message.
* @param {any} condition - The condition to check.
* @param {string} [message] - The optional message to include in the error.
* @throws {Error} Throws an error if the condition is false.
*/
export default function assert(condition: any, message?: string): asserts condition {
if (!condition) {
throw new Error(message || 'Assertion failure');
Expand Down
109 changes: 109 additions & 0 deletions src/utils/calldata/cairo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,141 @@ import { CairoUint256 } from '../cairoDataTypes/uint256';
import { CairoUint512 } from '../cairoDataTypes/uint512';

// Intended for internal usage, maybe should be exported somewhere else and not exported to utils
/**
* Checks if the given name ends with "_len".
*
* @param {string} name - The name to be checked.
* @returns - True if the name ends with "_len", false otherwise.
*/
export const isLen = (name: string) => /_len$/.test(name);
/**
* Checks if a given type is felt.
*
* @param {string} type - The type to check.
* @returns - True if the type is felt, false otherwise.
*/
export const isTypeFelt = (type: string) => type === 'felt' || type === 'core::felt252';
/**
* Checks if the given type is an array type.
*
* @param {string} type - The type to check.
* @returns - `true` if the type is an array type, `false` otherwise.
*/
export const isTypeArray = (type: string) =>
/\*/.test(type) ||
type.startsWith('core::array::Array::') ||
type.startsWith('core::array::Span::');
/**
* Checks if the given type is a tuple type.
*
* @param {string} type - The type to be checked.
* @returns - `true` if the type is a tuple type, otherwise `false`.
*/
export const isTypeTuple = (type: string) => /^\(.*\)$/i.test(type);
/**
* Checks whether a given type is a named tuple.
*
* @param {string} type - The type to be checked.
* @returns - True if the type is a named tuple, false otherwise.
*/
export const isTypeNamedTuple = (type: string) => /\(.*\)/i.test(type) && type.includes(':');
/**
* Checks if a given type is a struct.
*
* @param {string} type - The type to check for existence.
* @param {AbiStructs} structs - The collection of structs to search in.
* @returns - True if the type exists in the structs, false otherwise.
*/
export const isTypeStruct = (type: string, structs: AbiStructs) => type in structs;
/**
* Checks if a given type is an enum.
*
* @param {string} type - The type to check.
* @param {AbiEnums} enums - The enumeration to search in.
* @returns - True if the type exists in the enumeration, otherwise false.
*/
export const isTypeEnum = (type: string, enums: AbiEnums) => type in enums;
/**
* Determines if the given type is an Option type.
*
* @param {string} type - The type to check.
* @returns - True if the type is an Option type, false otherwise.
*/
export const isTypeOption = (type: string) => type.startsWith('core::option::Option::');
/**
* Checks whether a given type starts with 'core::result::Result::'.
*
* @param {string} type - The type to check.
* @returns - True if the type starts with 'core::result::Result::', false otherwise.
*/
export const isTypeResult = (type: string) => type.startsWith('core::result::Result::');
/**
* Checks if the given value is a valid Uint type.
*
* @param {string} type - The value to check.
* @returns - Returns true if the value is a valid Uint type, otherwise false.
*/
export const isTypeUint = (type: string) => Object.values(Uint).includes(type as Uint);
// Legacy Export
/**
* Checks if the given type is `uint256`.
*
* @param {string} type - The type to be checked.
* @returns - Returns true if the type is `uint256`, otherwise false.
*/
export const isTypeUint256 = (type: string) => CairoUint256.isAbiType(type);
/**
* Checks if the given type is a literal type.
*
* @param {string} type - The type to check.
* @returns - True if the type is a literal type, false otherwise.
*/
export const isTypeLiteral = (type: string) => Object.values(Literal).includes(type as Literal);
/**
* Checks if the given type is a boolean type.
*
* @param {string} type - The type to be checked.
* @returns - Returns true if the type is a boolean type, otherwise false.
*/
export const isTypeBool = (type: string) => type === 'core::bool';
/**
* Checks if the provided type is equal to 'core::starknet::contract_address::ContractAddress'.
* @param {string} type - The type to be checked.
* @returns - true if the type matches 'core::starknet::contract_address::ContractAddress', false otherwise.
*/
export const isTypeContractAddress = (type: string) =>
type === 'core::starknet::contract_address::ContractAddress';
/**
* Determines if the given type is an Ethereum address type.
*
* @param {string} type - The type to check.
* @returns - Returns true if the given type is 'core::starknet::eth_address::EthAddress', otherwise false.
*/
export const isTypeEthAddress = (type: string) =>
type === 'core::starknet::eth_address::EthAddress';
/**
* Checks if the given type is 'core::bytes_31::bytes31'.
*
* @param {string} type - The type to check.
* @returns - True if the type is 'core::bytes_31::bytes31', false otherwise.
*/
export const isTypeBytes31 = (type: string) => type === 'core::bytes_31::bytes31';
/**
* Checks if the given type is equal to the 'core::byte_array::ByteArray'.
*
* @param {string} type - The type to check.
* @returns - True if the given type is equal to 'core::byte_array::ByteArray', false otherwise.
*/
export const isTypeByteArray = (type: string) => type === 'core::byte_array::ByteArray';
export const isTypeSecp256k1Point = (type: string) =>
type === 'core::starknet::secp256k1::Secp256k1Point';
export const isCairo1Type = (type: string) => type.includes('::');
/**
* Retrieves the array type from the given type string.
*
* @param {string} type - The type string.
* @returns - The array type.
*/
export const getArrayType = (type: string) => {
if (isCairo1Type(type)) {
return type.substring(type.indexOf('<') + 1, type.lastIndexOf('>'));
Expand Down
8 changes: 8 additions & 0 deletions src/utils/calldata/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ const guard = {
},
};

/**
* Formats the given data based on the provided type definition.
*
* @param {any} data - The data to be formatted.
* @param {any} type - The type definition for the data.
* @param {any} [sameType] - The same type definition to be used (optional).
* @returns - The formatted data.
*/
export default function formatter(data: any, type: any, sameType?: any) {
// match data element with type element
return Object.entries(data).reduce((acc, [key, value]: [any, any]) => {
Expand Down
1 change: 1 addition & 0 deletions src/utils/calldata/responseParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ function parseBaseTypes(type: string, it: Iterator<string>) {
* @param responseIterator - iterator of the response
* @param element - element of the field {name: string, type: string}
* @param structs - structs from abi
* @param enums
* @return {any} - parsed arguments in format that contract is expecting
*/
function parseResponseValue(
Expand Down
15 changes: 15 additions & 0 deletions src/utils/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,28 @@ import { decompressProgram } from './stark';

import { isString } from './shortString';

/**
* Checks if a given contract is in Sierra (Safe Intermediate Representation) format.
*
* @param {CairoContract | string} contract - The contract to check. Can be either a CairoContract object or a string representation of the contract.
* @return {boolean} - Returns true if the contract is a Sierra contract, otherwise false.
*/
export function isSierra(
contract: CairoContract | string
): contract is SierraContractClass | CompiledSierra {
const compiledContract = isString(contract) ? parse(contract) : contract;
return 'sierra_program' in compiledContract;
}

/**
* Extracts contract hashes from `DeclareContractPayload`.
*
* @param {DeclareContractPayload} payload - The payload containing contract information.
*
* @return {CompleteDeclareContractPayload} - The `CompleteDeclareContractPayload` with extracted contract hashes.
*
* @throws {Error} - If extraction of compiledClassHash or classHash fails.
*/
export function extractContractHashes(
payload: DeclareContractPayload
): CompleteDeclareContractPayload {
Expand Down
7 changes: 7 additions & 0 deletions src/utils/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import responseParser from '../calldata/responseParser';
import { starkCurve } from '../ec';
import { addHexPrefix, utf8ToArray } from '../encode';

/**
* Retrieves the events from the given ABI.
*
* @param {Abi} abi - The ABI to extract events from.
* @return {AbiEvents} - An object containing the extracted events.
*/
export function getAbiEvents(abi: Abi): AbiEvents {
return abi
.filter((abiEntry) => abiEntry.type === 'event' && (abiEntry.size || abiEntry.kind !== 'enum'))
Expand All @@ -33,6 +39,7 @@ export function getAbiEvents(abi: Abi): AbiEvents {
* @param providerReceivedEvents ProviderEvent[] - Array of raw events
* @param abiEvents AbiEvents - Events defined in the abi
* @param abiStructs AbiStructs - Structs defined in the abi
* @param abiEnums
* @return ParsedEvents - parsed events corresponding to the abi
*/
export function parseEvents(
Expand Down
15 changes: 14 additions & 1 deletion src/utils/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class Block {

tag: BlockIdentifier = null;

private setIdentifier(__identifier: BlockIdentifier) {
private setIdentifier(__identifier: BlockIdentifier): void {
if (isString(__identifier)) {
if (isHex(__identifier)) {
this.hash = __identifier;
Expand Down Expand Up @@ -170,11 +170,24 @@ export class Block {
} */
}

/**
* Check if the given transaction details is a V3 transaction.
*
* @param {InvocationsDetailsWithNonce} details - The transaction details to be checked.
* @return {boolean} - Returns true if the transaction is a V3 transaction, otherwise false.
*/
export function isV3Tx(details: InvocationsDetailsWithNonce): details is V3TransactionDetails {
const version = details.version ? toHex(details.version) : ETransactionVersion.V3;
return version === ETransactionVersion.V3 || version === ETransactionVersion.F3;
}

/**
* Determines if the given response matches the specified version.
*
* @param {('0.5' | '0.6' | '0.7')} version - The version to compare against the response.
* @param {string} response - The response to check against the version.
* @returns {boolean} - True if the response matches the version, false otherwise.
*/
export function isVersion(version: '0.5' | '0.6' | '0.7', response: string) {
const [majorS, minorS] = version.split('.');
const [majorR, minorR] = response.split('.');
Expand Down
22 changes: 22 additions & 0 deletions src/utils/stark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ export function estimatedFeeToMaxFee(
return addPercent(estimatedFee, overhead);
}

/**
* Calculates the maximum resource bounds for fee estimation.
*
* @param {FeeEstimate|0n} estimate - The estimate for the fee. If a BigInt is provided,
* the returned bounds will be set to '0x0'.
* @param {number} [amountOverhead=feeMarginPercentage.L1_BOUND_MAX_AMOUNT] - The percentage
* overhead added to
* the gas consumed or
* overall fee amount.
* @param {number} [priceOverhead=feeMarginPercentage.L1_BOUND_MAX_PRICE_PER_UNIT] - The percentage
* overhead added to
* the gas price per unit.
* @throws {Error} If the estimate object is undefined or does not have the required properties.
* @returns {ResourceBounds} The maximum resource bounds for fee estimation.
*/
export function estimateFeeToBounds(
estimate: FeeEstimate | 0n,
amountOverhead: number = feeMarginPercentage.L1_BOUND_MAX_AMOUNT,
Expand Down Expand Up @@ -131,6 +146,13 @@ export function estimateFeeToBounds(
};
}

/**
* Converts the data availability mode from EDataAvailabilityMode to EDAMode.
*
* @param {EDataAvailabilityMode} dam - The data availability mode to be converted.
* @return {EDAMode} The converted data availability mode.
* @throws {Error} If the data availability mode is not a valid value.
*/
export function intDAM(dam: EDataAvailabilityMode) {
if (dam === EDataAvailabilityMode.L1) return EDAMode.L1;
if (dam === EDataAvailabilityMode.L2) return EDAMode.L2;
Expand Down
Loading