diff --git a/src/contract/interface.ts b/src/contract/interface.ts index 9a2f53e0b..b04ae9fe5 100644 --- a/src/contract/interface.ts +++ b/src/contract/interface.ts @@ -162,5 +162,11 @@ export abstract class ContractInterface { */ public abstract getVersion(): Promise; + /** + * Returns a typed instance of ContractV2 based on the supplied ABI. + * + * @param {TAbi} tAbi - The ABI (Abstract Binary Interface) of the ContractV2. + * @return {TypedContractV2} - A typed instance of ContractV2. + */ public abstract typedv2(tAbi: TAbi): TypedContractV2; } diff --git a/src/utils/address.ts b/src/utils/address.ts index 7cfbe2860..a611d627f 100644 --- a/src/utils/address.ts +++ b/src/utils/address.ts @@ -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)); diff --git a/src/utils/assert.ts b/src/utils/assert.ts index f32cc5bc4..4d0830ebb 100644 --- a/src/utils/assert.ts +++ b/src/utils/assert.ts @@ -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'); diff --git a/src/utils/calldata/cairo.ts b/src/utils/calldata/cairo.ts index d105e7462..09b419703 100644 --- a/src/utils/calldata/cairo.ts +++ b/src/utils/calldata/cairo.ts @@ -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('>')); diff --git a/src/utils/calldata/formatter.ts b/src/utils/calldata/formatter.ts index 19d152531..a0adc3a68 100644 --- a/src/utils/calldata/formatter.ts +++ b/src/utils/calldata/formatter.ts @@ -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]) => { diff --git a/src/utils/calldata/responseParser.ts b/src/utils/calldata/responseParser.ts index 298bfa711..fbf7fd433 100644 --- a/src/utils/calldata/responseParser.ts +++ b/src/utils/calldata/responseParser.ts @@ -84,6 +84,7 @@ function parseBaseTypes(type: string, it: Iterator) { * @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( diff --git a/src/utils/contract.ts b/src/utils/contract.ts index 09d51301a..1fb6a5315 100644 --- a/src/utils/contract.ts +++ b/src/utils/contract.ts @@ -13,6 +13,12 @@ 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 { @@ -20,6 +26,15 @@ export function isSierra( 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 { diff --git a/src/utils/events/index.ts b/src/utils/events/index.ts index d6d623575..9d0b3614c 100644 --- a/src/utils/events/index.ts +++ b/src/utils/events/index.ts @@ -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')) @@ -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( diff --git a/src/utils/provider.ts b/src/utils/provider.ts index 6f10ac51d..2facfe6b9 100644 --- a/src/utils/provider.ts +++ b/src/utils/provider.ts @@ -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; @@ -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('.'); diff --git a/src/utils/stark.ts b/src/utils/stark.ts index 65955fc6b..28e295d81 100644 --- a/src/utils/stark.ts +++ b/src/utils/stark.ts @@ -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, @@ -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; diff --git a/src/utils/starknetId.ts b/src/utils/starknetId.ts index b8f5e0c70..ad643b486 100644 --- a/src/utils/starknetId.ts +++ b/src/utils/starknetId.ts @@ -20,6 +20,11 @@ function extractStars(str: string): [string, number] { return [str, k]; } +/** + * Decodes an array of BigInts into a string using the given algorithm. + * @param {bigint[]} encoded - The encoded array of BigInts. + * @return {string} The decoded string. + */ export function useDecoded(encoded: bigint[]): string { let decoded = ''; @@ -61,6 +66,12 @@ export function useDecoded(encoded: bigint[]): string { return decoded.concat('stark'); } +/** + * Encodes a string into a bigint value. + * + * @param {string} decoded - The string to be encoded. + * @returns {bigint} - The encoded bigint value. + */ export function useEncoded(decoded: string): bigint { let encoded = BigInt(0); let multiplier = BigInt(1); @@ -109,6 +120,13 @@ export const enum StarknetIdContract { TESTNET_SEPOLIA = '0x0707f09bc576bd7cfee59694846291047e965f4184fe13dac62c56759b3b6fa7', } +/** + * Returns the Starknet ID contract address based on the provided chain ID. + * + * @param {StarknetChainId} chainId - The chain ID of the Starknet network. + * @return {string} The Starknet ID contract address. + * @throws {Error} Throws an error if the Starknet ID contract is not deployed on the network. + */ export function getStarknetIdContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -131,6 +149,15 @@ export const enum StarknetIdIdentityContract { TESTNET_SEPOLIA = '0x070DF8B4F5cb2879f8592849fA8f3134da39d25326B8558cc9C8FE8D47EA3A90', } +/** + * Returns the Starknet ID identity contract address for the given chain ID. + * + * @param {StarknetChainId} chainId - The chain ID for the specified network. + * + * @return {string} - The Starknet ID identity contract address for the specified network. + * + * @throws {Error} - If the Starknet ID verifier contract is not deployed on the network. + */ export function getStarknetIdIdentityContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -150,6 +177,13 @@ export function getStarknetIdIdentityContract(chainId: StarknetChainId): string export const StarknetIdMulticallContract = '0x034ffb8f4452df7a613a0210824d6414dbadcddce6c6e19bf4ddc9e22ce5f970'; +/** + * Returns the Starknet.id multicall contract address based on the provided chainId. + * + * @param {StarknetChainId} chainId - The chainId of the network. + * @return {string} - The address of the Starknet.id multicall contract. + * @throws {Error} - If the Starknet.id multicall contract is not deployed on the network. + */ export function getStarknetIdMulticallContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -172,6 +206,13 @@ export const enum StarknetIdVerifierContract { TESTNET_SEPOLIA = '0x0182EcE8173C216A395f4828e1523541b7e3600bf190CB252E1a1A0cE219d184', } +/** + * Returns the address of the Starknet ID Verifier contract based on the specified chain ID. + * + * @param {StarknetChainId} chainId - The ID of the Starknet chain. + * @return {string} - The address of the Starknet ID Verifier contract. + * @throws {Error} - If the Starknet ID Verifier contract is not deployed on the specified network. + */ export function getStarknetIdVerifierContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -194,6 +235,13 @@ export const enum StarknetIdPfpContract { TESTNET_SEPOLIA = '0x058061bb6bdc501eE215172c9f87d557C1E0f466dC498cA81b18f998Bf1362b2', } +/** + * Retrieves the contract address of the Starknet.id profile picture verifier contract based on the given chain ID. + * + * @param {StarknetChainId} chainId - The chain ID of the network. + * @returns {string} - The contract address of the Starknet.id profile picture verifier contract. + * @throws {Error} - Throws an error if the Starknet.id profile picture verifier contract is not yet deployed on the network. + */ export function getStarknetIdPfpContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -218,6 +266,13 @@ export const enum StarknetIdPopContract { TESTNET_SEPOLIA = '0x0023FE3b845ed5665a9eb3792bbB17347B490EE4090f855C1298d03BB5F49B49', } +/** + * Retrieves the Starknet ID Proof of Personhood (IdPop) verifier contract address for the given chain ID. + * + * @param {StarknetChainId} chainId - The chain ID of the Starknet network. + * @return {string} - The Starknet ID Pop contract address. + * @throws {Error} - If the Starknet ID Pop contract is not deployed on the specified network. + */ export function getStarknetIdPopContract(chainId: StarknetChainId): string { switch (chainId) { case StarknetChainId.SN_MAIN: @@ -236,7 +291,15 @@ export function getStarknetIdPopContract(chainId: StarknetChainId): string { } } -// Functions to build CairoCustomEnum for multicall contracts +/** + * Executes a method and returns a CairoCustomEnum object. + * + * Functions to build CairoCustomEnum for multicall contracts + * @param {Object} staticEx - An optional object defining the "Static" value of the CairoCustomEnum. + * @param {number[]} ifEqual - An optional array defining the "IfEqual" value of the CairoCustomEnum. + * @param {number[]} ifNotEqual - An optional array defining the "IfNotEqual" value of the CairoCustomEnum. + * @return {CairoCustomEnum} - The created CairoCustomEnum object. + */ export function execution( staticEx: {} | undefined, ifEqual: number[] | undefined = undefined, @@ -249,6 +312,13 @@ export function execution( }); } +/** + * Creates a new instance of CairoCustomEnum. + * + * @param {BigNumberish | undefined} hardcoded - The hardcoded value for the CairoCustomEnum. + * @param {number[] | undefined} reference - The reference array for the CairoCustomEnum. + * @returns {CairoCustomEnum} The new instance of CairoCustomEnum. + */ export function dynamicFelt( hardcoded: BigNumberish | undefined, reference: number[] | undefined = undefined @@ -259,6 +329,13 @@ export function dynamicFelt( }); } +/** + * Creates a new instance of CairoCustomEnum with the given parameters. + * @param {BigNumberish | undefined} hardcoded - The hardcoded value. + * @param {BigNumberish[] | undefined} [reference] - The reference value (optional). + * @param {BigNumberish[] | undefined} [arrayReference] - The array reference value (optional). + * @return {CairoCustomEnum} - The new instance of CairoCustomEnum. + */ export function dynamicCallData( hardcoded: BigNumberish | undefined, reference: BigNumberish[] | undefined = undefined, diff --git a/src/utils/transaction.ts b/src/utils/transaction.ts index 2daf8da92..308290223 100644 --- a/src/utils/transaction.ts +++ b/src/utils/transaction.ts @@ -98,6 +98,14 @@ export const getExecuteCalldata = (calls: Call[], cairoVersion: CairoVersion = ' return fromCallsToExecuteCalldata(calls); }; +/** + * Builds a UDCCall object. + * + * @param {UniversalDeployerContractPayload | UniversalDeployerContractPayload[]} payload - The payload data for the UDCCall. Can be a single payload object or an array of payload objects + *. + * @param {string} address - The address to be used in the UDCCall. + * @returns {{ calls: Array, addresses: Array }} - The UDCCall object containing an array of calls and an array of addresses. + */ export function buildUDCCall( payload: UniversalDeployerContractPayload | UniversalDeployerContractPayload[], address: string diff --git a/src/utils/typedData.ts b/src/utils/typedData.ts index 9a62b06b5..18ca08240 100644 --- a/src/utils/typedData.ts +++ b/src/utils/typedData.ts @@ -103,10 +103,23 @@ function validateTypedData(data: unknown): data is TypedData { ); } +/** + * Prepares the selector for use. + * + * @param {string} selector - The selector to be prepared. + * @returns {string} The prepared selector. + */ export function prepareSelector(selector: string): string { return isHex(selector) ? selector : getSelectorFromName(selector); } +/** + * Checks if the given Starknet type is a Merkle tree type. + * + * @param {StarknetType} type - The StarkNet type to check. + * + * @returns {boolean} - True if the type is a Merkle tree type, false otherwise. + */ export function isMerkleTreeType(type: StarknetType): type is StarknetMerkleType { return type.type === 'merkletree'; } diff --git a/src/utils/url.ts b/src/utils/url.ts index e18c4da08..9f1bb47ce 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -46,6 +46,14 @@ export function isUrl(s?: string): boolean { return false; } +/** + * Builds a URL using the provided base URL, default path, and optional URL or path. + * + * @param {string} baseUrl - The base URL of the URL being built. + * @param {string} defaultPath - The default path to use if no URL or path is provided. + * @param {string} [urlOrPath] - The optional URL or path to append to the base URL. + * @return {string} The built URL. + */ export function buildUrl(baseUrl: string, defaultPath: string, urlOrPath?: string) { return isUrl(urlOrPath) ? urlOrPath! : urljoin(baseUrl, urlOrPath ?? defaultPath); } diff --git a/src/wallet/connect.ts b/src/wallet/connect.ts index 02a50da7a..68f24dc22 100644 --- a/src/wallet/connect.ts +++ b/src/wallet/connect.ts @@ -153,10 +153,32 @@ export function supportedSpecs(swo: StarknetWindowObject) { return swo.request({ type: 'starknet_supportedSpecs' }); } -export function onAccountChange(swo: StarknetWindowObject, callback: AccountChangeEventHandler) { +/** + * Attaches an event handler function to the "accountsChanged" event of a StarknetWindowObject. + * When the accounts are changed, the specified callback function will be called. + * + * @param {StarknetWindowObject} swo - The StarknetWindowObject to attach the event handler to. + * @param {AccountChangeEventHandler} callback - The function to be called when the accounts are changed. + * It will receive the changed accounts as a parameter. + * @returns {void} + */ +export function onAccountChange( + swo: StarknetWindowObject, + callback: AccountChangeEventHandler +): void { swo.on('accountsChanged', callback); } -export function onNetworkChanged(swo: StarknetWindowObject, callback: NetworkChangeEventHandler) { +/** + * Register a callback function to be called when the network is changed. + * + * @param {StarknetWindowObject} swo - The StarknetWindowObject instance. + * @param {NetworkChangeEventHandler} callback - The callback function to be called when the network is changed. + * @return {void} + */ +export function onNetworkChanged( + swo: StarknetWindowObject, + callback: NetworkChangeEventHandler +): void { swo.on('networkChanged', callback); }