diff --git a/src/provider/default.ts b/src/provider/default.ts index f675d08b0..43f956fe9 100644 --- a/src/provider/default.ts +++ b/src/provider/default.ts @@ -22,15 +22,15 @@ import { RPCProvider, RpcProviderOptions } from './rpc'; import { BlockIdentifier } from './utils'; export interface ProviderOptions { - gateway: GatewayProviderOptions; - rpc: RpcProviderOptions; + gateway?: GatewayProviderOptions; + rpc?: RpcProviderOptions; } export class Provider implements ProviderInterface { private provider!: ProviderInterface; constructor(options?: ProviderOptions) { - if (options && 'rpc' in options) { + if (options && options.rpc) { this.provider = new RPCProvider(options.rpc); } diff --git a/src/provider/gateway.ts b/src/provider/gateway.ts index 371bae436..bb28c3d34 100644 --- a/src/provider/gateway.ts +++ b/src/provider/gateway.ts @@ -4,7 +4,6 @@ import { ONE, StarknetChainId, ZERO } from '../constants'; import { Call, CallContractResponse, - CompiledContract, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, @@ -25,20 +24,15 @@ import { import { getSelectorFromName } from '../utils/hash'; import { parse, parseAlwaysAsBig, stringify } from '../utils/json'; import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN, toHex } from '../utils/number'; +import { parseContract, wait } from '../utils/provider'; import { GatewayAPIResponseParser } from '../utils/responseParser/gateway'; -import { compressProgram, randomAddress } from '../utils/stark'; +import { randomAddress } from '../utils/stark'; import { GatewayError, HttpError } from './errors'; import { ProviderInterface } from './interface'; import { BlockIdentifier, getFormattedBlockIdentifier } from './utils'; type NetworkName = 'mainnet-alpha' | 'goerli-alpha'; -function wait(delay: number) { - return new Promise((res) => { - setTimeout(res, delay); - }); -} - function isEmptyQueryObject(obj?: Record): obj is undefined { return ( obj === undefined || @@ -254,13 +248,7 @@ export class GatewayProvider implements ProviderInterface { blockIdentifier: BlockIdentifier = 'pending' ): Promise { return this.fetchEndpoint('get_full_contract', { blockIdentifier, contractAddress }).then( - (res) => { - const parsedContract = typeof res === 'string' ? (parse(res) as CompiledContract) : res; - return { - ...parsedContract, - program: compressProgram(parsedContract.program), - }; - } + parseContract ); } @@ -280,18 +268,11 @@ export class GatewayProvider implements ProviderInterface { } public async deployContract({ - contract: compiledContract, + contract, constructorCalldata, addressSalt, }: DeployContractPayload): Promise { - const parsedContract = - typeof compiledContract === 'string' - ? (parse(compiledContract) as CompiledContract) - : compiledContract; - const contractDefinition = { - ...parsedContract, - program: compressProgram(parsedContract.program), - }; + const contractDefinition = parseContract(contract); return this.fetchEndpoint('add_transaction', undefined, { type: 'DEPLOY', @@ -302,16 +283,9 @@ export class GatewayProvider implements ProviderInterface { } public async declareContract({ - contract: compiledContract, + contract, }: DeclareContractPayload): Promise { - const parsedContract = - typeof compiledContract === 'string' - ? (parse(compiledContract) as CompiledContract) - : compiledContract; - const contractDefinition = { - ...parsedContract, - program: compressProgram(parsedContract.program), - }; + const contractDefinition = parseContract(contract); return this.fetchEndpoint('add_transaction', undefined, { type: 'DECLARE', diff --git a/src/provider/rpc.ts b/src/provider/rpc.ts index 31802019b..6355b5d96 100644 --- a/src/provider/rpc.ts +++ b/src/provider/rpc.ts @@ -4,7 +4,6 @@ import { StarknetChainId } from '../constants'; import { Call, CallContractResponse, - CompiledContract, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, @@ -20,7 +19,7 @@ import { Signature, } from '../types'; import { getSelectorFromName } from '../utils/hash'; -import { parse, stringify } from '../utils/json'; +import { stringify } from '../utils/json'; import { BigNumberish, bigNumberishArrayToDecimalStringArray, @@ -28,17 +27,12 @@ import { toBN, toHex, } from '../utils/number'; +import { parseCalldata, parseContract, wait } from '../utils/provider'; import { RPCResponseParser } from '../utils/responseParser/rpc'; -import { compressProgram, randomAddress } from '../utils/stark'; +import { randomAddress } from '../utils/stark'; import { ProviderInterface } from './interface'; import { BlockIdentifier } from './utils'; -function wait(delay: number) { - return new Promise((res) => { - setTimeout(res, delay); - }); -} - export type RpcProviderOptions = { nodeUrl: string }; export class RPCProvider implements ProviderInterface { @@ -140,35 +134,21 @@ export class RPCProvider implements ProviderInterface { blockIdentifier: BlockIdentifier = 'pending', _signature: Signature = [] ): Promise { - const parsedCalldata = call.calldata?.map((data) => { - if (typeof data === 'string' && isHex(data as string)) { - return data; - } - return toHex(toBN(data)); - }); - return this.fetchEndpoint('starknet_estimateFee', [ { contract_address: call.contractAddress, entry_point_selector: getSelectorFromName(call.entrypoint), - calldata: parsedCalldata, + calldata: parseCalldata(call.calldata), }, blockIdentifier, ]).then(this.responseParser.parseFeeEstimateResponse); } public async declareContract({ - contract: compiledContract, + contract, version, }: DeclareContractPayload): Promise { - const parsedContract = - typeof compiledContract === 'string' - ? (parse(compiledContract) as CompiledContract) - : compiledContract; - const contractDefinition = { - ...parsedContract, - program: compressProgram(parsedContract.program), - }; + const contractDefinition = parseContract(contract); return this.fetchEndpoint('starknet_addDeclareTransaction', [ { @@ -184,12 +164,7 @@ export class RPCProvider implements ProviderInterface { constructorCalldata, addressSalt, }: DeployContractPayload): Promise { - const parsedContract = - typeof contract === 'string' ? (parse(contract) as CompiledContract) : contract; - const contractDefinition = { - ...parsedContract, - program: compressProgram(parsedContract.program), - }; + const contractDefinition = parseContract(contract); return this.fetchEndpoint('starknet_addDeployTransaction', [ addressSalt ?? randomAddress(), @@ -205,18 +180,11 @@ export class RPCProvider implements ProviderInterface { functionInvocation: Invocation, details: InvocationsDetails ): Promise { - const parsedCalldata = functionInvocation.calldata?.map((data) => { - if (typeof data === 'string' && isHex(data as string)) { - return data; - } - return toHex(toBN(data)); - }); - return this.fetchEndpoint('starknet_addInvokeTransaction', [ { contract_address: functionInvocation.contractAddress, entry_point_selector: getSelectorFromName(functionInvocation.entrypoint), - calldata: parsedCalldata, + calldata: parseCalldata(functionInvocation.calldata), }, functionInvocation.signature, details.maxFee, @@ -228,18 +196,11 @@ export class RPCProvider implements ProviderInterface { call: Call, blockIdentifier: BlockIdentifier = 'pending' ): Promise { - const parsedCalldata = call.calldata?.map((data) => { - if (typeof data === 'string' && isHex(data as string)) { - return data; - } - return toHex(toBN(data)); - }); - const result = await this.fetchEndpoint('starknet_call', [ { contract_address: call.contractAddress, entry_point_selector: getSelectorFromName(call.entrypoint), - calldata: parsedCalldata, + calldata: parseCalldata(call.calldata), }, blockIdentifier, ]); diff --git a/src/utils/provider.ts b/src/utils/provider.ts new file mode 100644 index 000000000..d938bde02 --- /dev/null +++ b/src/utils/provider.ts @@ -0,0 +1,28 @@ +import { CompiledContract, RawCalldata } from '../types'; +import { parse } from './json'; +import { isHex, toBN, toHex } from './number'; +import { compressProgram } from './stark'; + +export function wait(delay: number) { + return new Promise((res) => { + setTimeout(res, delay); + }); +} + +export function parseCalldata(calldata: RawCalldata = []) { + return calldata.map((data) => { + if (typeof data === 'string' && isHex(data as string)) { + return data; + } + return toHex(toBN(data)); + }); +} + +export function parseContract(contract: CompiledContract | string) { + const parsedContract = + typeof contract === 'string' ? (parse(contract) as CompiledContract) : contract; + return { + ...parsedContract, + program: compressProgram(parsedContract.program), + }; +}