diff --git a/__tests__/account.test.ts b/__tests__/account.test.ts index e2001b7f6..8ad3849c0 100644 --- a/__tests__/account.test.ts +++ b/__tests__/account.test.ts @@ -26,7 +26,6 @@ import { compiledOpenZeppelinAccount, compiledTestDapp, describeIfDevnet, - describeIfDevnetSequencer, erc20ClassHash, getTestAccount, getTestProvider, @@ -113,7 +112,7 @@ describe('deploy and test Wallet', () => { // this is tested indirectly true declareAndDeploy while declaring }); - describeIfDevnetSequencer('Test on Devnet Sequencer', () => { + describeIfDevnet('Test on Devnet', () => { test('deployAccount with rawArgs - test on devnet', async () => { const priKey = stark.randomAddress(); const pubKey = ec.starkCurve.getStarkKey(priKey); @@ -195,7 +194,6 @@ describe('deploy and test Wallet', () => { describe('simulate transaction - single transaction S0.11.2', () => { test('simulate INVOKE Cairo 0', async () => { - // INFO: Sequencer S0.11.2 support only one transaction per simulate request const res = await account.simulateTransaction([ { type: TransactionType.INVOKE, @@ -206,7 +204,6 @@ describe('deploy and test Wallet', () => { amount: uint256(10), }, }, - // This transaction will be skipped on sequencer { type: TransactionType.INVOKE, contractAddress: erc20Address, @@ -753,7 +750,7 @@ describe('deploy and test Wallet', () => { }); describe('unit', () => { - describeIfDevnetSequencer('devnet sequencer', () => { + describeIfDevnet('Devnet', () => { initializeMatcher(expect); const provider = getTestProvider(); const account = getTestAccount(provider); diff --git a/__tests__/cairo1.test.ts b/__tests__/cairo1.test.ts index 684b43f2c..87680558a 100644 --- a/__tests__/cairo1.test.ts +++ b/__tests__/cairo1.test.ts @@ -1,15 +1,15 @@ +import type { Abi } from 'abi-wan-kanabi'; import { - Abi, + type BigNumberish, + type Calldata, + type CompiledSierra, + type DeclareDeployUDCResponse, + type RawArgsArray, + type RawArgsObject, Account, - BigNumberish, CallData, - Calldata, - CompiledSierra, Contract, ContractFactory, - DeclareDeployUDCResponse, - RawArgsArray, - RawArgsObject, cairo, ec, hash, @@ -26,7 +26,7 @@ import { compiledHelloSierra, compiledHelloSierraCasm, describeIfDevnet, - describeIfSequencerGoerli, + describeIfTestnet, getTestAccount, getTestProvider, } from './config/fixtures'; @@ -550,8 +550,8 @@ describeIfDevnet('Cairo 1 Devnet', () => { }); }); -describeIfSequencerGoerli('Cairo1 Testnet', () => { - describe('Sequencer API - C1 Testnet C:0x00305e...', () => { +describeIfTestnet('Testnet', () => { + describe('TS validation for testnet', () => { const provider = getTestProvider(); const account = getTestAccount(provider); const classHash: any = '0x022332bb9c1e22ae13ae7fd9f3101eced4644533c6bfe51a25cf8dea028e5045'; diff --git a/__tests__/config/constants.ts b/__tests__/config/constants.ts index 532688142..9807bd944 100644 --- a/__tests__/config/constants.ts +++ b/__tests__/config/constants.ts @@ -1,2 +1,10 @@ /* Default test config based on run `starknet-devnet --seed 0` */ export const GS_DEFAULT_TEST_PROVIDER_URL = 'http://127.0.0.1:5050/'; + +export const LOCAL_DEVNET_NOT_RUNNING_MESSAGE = ` +Local devnet is not running. In order to properly run it you need to do the following: \n + - Go to the: https://hub.docker.com/r/shardlabs/starknet-devnet-rs/tags + - Find the latest tag and copy the "docker pull" command + - Run Docker on your machine + - Run the command: "docker pull shardlabs/starknet-devnet-rs:latest" +`; diff --git a/__tests__/config/fixtures.ts b/__tests__/config/fixtures.ts index ff4d9b2ad..bb8132383 100644 --- a/__tests__/config/fixtures.ts +++ b/__tests__/config/fixtures.ts @@ -80,7 +80,7 @@ export function getTestProvider(isProvider: boolean = true): ProviderInterface | ? new Provider({ nodeUrl: process.env.TEST_RPC_URL }) : new RpcProvider({ nodeUrl: process.env.TEST_RPC_URL }); - if (process.env.IS_LOCALHOST_DEVNET === 'true') { + if (process.env.IS_DEVNET === 'true') { // accelerate the tests when running locally const originalWaitForTransaction = provider.waitForTransaction.bind(provider); provider.waitForTransaction = (txHash: string, options: waitForTransactionOptions = {}) => { @@ -104,18 +104,15 @@ export const getTestAccount = (provider: ProviderInterface) => { }; export const createBlockForDevnet = async (): Promise => { - if (!(process.env.IS_RPC_DEVNET === 'true')) return; + if (!(process.env.IS_DEVNET === 'true')) return; await fetch(new URL('/create_block', process.env.TEST_RPC_URL), { method: 'POST' }); }; const describeIf = (condition: boolean) => (condition ? describe : describe.skip); -export const describeIfSequencer = describeIf(process.env.IS_SEQUENCER === 'true'); export const describeIfRpc = describeIf(process.env.IS_RPC === 'true'); -export const describeIfNotDevnet = describeIf(process.env.IS_LOCALHOST_DEVNET === 'false'); -export const describeIfDevnet = describeIf(process.env.IS_LOCALHOST_DEVNET === 'true'); -export const describeIfDevnetRpc = describeIf(process.env.IS_RPC_DEVNET === 'true'); -export const describeIfDevnetSequencer = describeIf(process.env.IS_SEQUENCER_DEVNET === 'true'); -export const describeIfSequencerGoerli = describeIf(process.env.IS_SEQUENCER_GOERLI === 'true'); +export const describeIfNotDevnet = describeIf(process.env.IS_DEVNET === 'false'); +export const describeIfDevnet = describeIf(process.env.IS_DEVNET === 'true'); +export const describeIfTestnet = describeIf(process.env.IS_TESTNET === 'true'); export const erc20ClassHash = '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a'; export const wrongClassHash = '0x000000000000000000000000000000000000000000000000000000000000000'; diff --git a/__tests__/config/helpers/accountResolver.ts b/__tests__/config/helpers/accountResolver.ts new file mode 100644 index 000000000..72ce83a1c --- /dev/null +++ b/__tests__/config/helpers/accountResolver.ts @@ -0,0 +1,64 @@ +/* eslint-disable no-console */ +import { GS_DEFAULT_TEST_PROVIDER_URL } from '../constants'; + +class AccountResolver { + get providedUrl() { + return process.env.TEST_RPC_URL; + } + + get hasAllAccountEnvs() { + return process.env.TEST_ACCOUNT_ADDRESS && process.env.TEST_ACCOUNT_PRIVATE_KEY; + } + + get hasPartialAccountEnvs() { + return process.env.TEST_ACCOUNT_ADDRESS || process.env.TEST_ACCOUNT_PRIVATE_KEY; + } + + private async fetchAccount(url: string) { + const response = await fetch(`${url}predeployed_accounts`); + const [account] = await response.json(); + const { address, private_key, initial_balance } = account; + process.env.TEST_ACCOUNT_ADDRESS = address; + process.env.TEST_ACCOUNT_PRIVATE_KEY = private_key; + process.env.INITIAL_BALANCE = initial_balance; + } + + private async isAccountSet(isDevnet: boolean): Promise { + if (this.hasAllAccountEnvs) { + return true; + } + if (this.hasPartialAccountEnvs) { + throw new Error( + 'If you are providing one of you need to provide both: TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY' + ); + } + if (isDevnet) { + // get account from devnet + try { + await this.fetchAccount(GS_DEFAULT_TEST_PROVIDER_URL); + return true; + } catch (error) { + console.error('Fetching account from devnet failed'); + } + } else if (this.providedUrl) { + // try to get it from remote devnet + try { + await this.fetchAccount(this.providedUrl); + return true; + } catch (error) { + console.error(`Fetching account from provided url ${this.providedUrl} failed`); + } + } + + throw new Error( + 'Setting Account using all known strategies failed, provide basic test parameters' + ); + } + + async execute(isDevnet: boolean): Promise { + const isAccountSet = await this.isAccountSet(isDevnet); + if (isAccountSet) console.log('Detected Account'); + } +} + +export default new AccountResolver(); diff --git a/__tests__/config/helpers/localDevnetDetector.ts b/__tests__/config/helpers/localDevnetDetector.ts deleted file mode 100644 index 8d9e1147e..000000000 --- a/__tests__/config/helpers/localDevnetDetector.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable no-console */ -import { GS_DEFAULT_TEST_PROVIDER_URL } from '../constants'; -import { setIfNullish } from './env'; - -export type DevnetStrategy = Record<'isDevnet' | 'isRS', boolean>; - -const LOCAL_DEVNET_NOT_RUNNING_MESSAGE = ` -Local devnet is not running. In order to properly run it you need to do the following: \n - - Go to the: https://hub.docker.com/r/shardlabs/starknet-devnet-rs/tags - - Find the latest tag and copy the "docker pull" command - - Run Docker on your machine - - Run the command: "docker pull shardlabs/starknet-devnet-rs:latest" -`; - -class LocalDevnetDetector { - private strategy: DevnetStrategy = { isDevnet: false, isRS: false }; - - get isDevnet() { - return this.strategy.isDevnet; - } - - get isRS() { - return this.strategy.isRS; - } - - private setup() { - setIfNullish('IS_LOCALHOST_DEVNET', this.isDevnet); - setIfNullish('IS_RPC_DEVNET', this.isDevnet && (this.isRS || !!process.env.TEST_RPC_URL)); - setIfNullish('IS_SEQUENCER_DEVNET', this.isDevnet && process.env.IS_RPC_DEVNET === 'false'); - return this.strategy; - } - - private async isLocalDevnet(): Promise { - // if is_alive work it is local devnet - const devnetResult = await fetch(`${GS_DEFAULT_TEST_PROVIDER_URL}is_alive`) - .then((res) => res.text()) - .catch(() => null); - - return devnetResult === 'Alive!!!'; - } - - private async isRsDevnet(): Promise { - const response = await fetch(GS_DEFAULT_TEST_PROVIDER_URL, { - method: 'POST', - headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, - body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'starknet_syncing' }), - }); - const { jsonrpc } = await response.json(); - return jsonrpc === '2.0'; - } - - async execute() { - this.strategy.isDevnet = await this.isLocalDevnet(); - - if (!this.strategy.isDevnet) { - console.log('\x1b[36m%s\x1b[0m', LOCAL_DEVNET_NOT_RUNNING_MESSAGE); - this.setup(); - throw new Error('Local devnet is not Running. Please follow the devnet setup instructions.'); - } - - // if on base url RPC endpoint work it is devnet-rs else it devnet-py - try { - this.strategy.isRS = await this.isRsDevnet(); - if (this.isRS) console.log('Detected Devnet-RS'); - } catch (error) { - return this.setup(); - } - - return this.setup(); - } -} - -export default new LocalDevnetDetector(); diff --git a/__tests__/config/helpers/strategyResolver.ts b/__tests__/config/helpers/strategyResolver.ts new file mode 100644 index 000000000..c30155cb3 --- /dev/null +++ b/__tests__/config/helpers/strategyResolver.ts @@ -0,0 +1,131 @@ +/* eslint-disable no-console */ +import accountResolver from './accountResolver'; +import { GS_DEFAULT_TEST_PROVIDER_URL, LOCAL_DEVNET_NOT_RUNNING_MESSAGE } from '../constants'; +import { setIfNullish } from './env'; +import { BaseUrl } from '../../../src/constants'; + +class StrategyResolver { + private isDevnet = false; + + private isRpcNode = false; + + get isRpcDevnet() { + return this.isDevnet || !!process.env.TEST_RPC_URL; + } + + get isTestnet() { + return process.env.TEST_RPC_URL?.includes(BaseUrl.SN_SEPOLIA); + } + + get hasAllAccountEnvs() { + const { TEST_ACCOUNT_ADDRESS, TEST_ACCOUNT_PRIVATE_KEY } = process.env; + return !!(TEST_ACCOUNT_PRIVATE_KEY && TEST_ACCOUNT_ADDRESS); + } + + private async isRsDevnet(): Promise { + const response = await fetch(GS_DEFAULT_TEST_PROVIDER_URL, { + method: 'POST', + headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, + body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'starknet_syncing' }), + }); + const { jsonrpc } = await response.json(); + return jsonrpc === '2.0'; + } + + async detectDevnet(): Promise { + // if on base url RPC endpoint work it is devnet-rs else it devnet-py + try { + this.isDevnet = await this.isRsDevnet(); + if (this.isDevnet) console.log('Detected Devnet-RS'); + } catch (error) { + console.log('\x1b[36m%s\x1b[0m', LOCAL_DEVNET_NOT_RUNNING_MESSAGE); + throw new Error( + 'Local RS devnet is not Running. Please follow the devnet setup instructions.' + ); + } + + setIfNullish('IS_DEVNET', this.isRpcDevnet); + } + + resolveRpc(): void { + const hasRpcUrl = !!process.env.TEST_RPC_URL; + + this.isRpcNode = hasRpcUrl || this.isDevnet; + + if (!hasRpcUrl && this.isDevnet) { + process.env.TEST_RPC_URL = GS_DEFAULT_TEST_PROVIDER_URL; + } + + setIfNullish('IS_RPC', this.isRpcNode); + setIfNullish('IS_TESTNET', this.isTestnet); + + console.log('Detected RPC'); + } + + private logConfigInfo(): void { + console.table({ + TEST_ACCOUNT_ADDRESS: process.env.TEST_ACCOUNT_ADDRESS, + TEST_ACCOUNT_PRIVATE_KEY: '****', + INITIAL_BALANCE: process.env.INITIAL_BALANCE, + TEST_RPC_URL: process.env.TEST_RPC_URL, + TX_VERSION: process.env.TX_VERSION === 'v3' ? 'v3' : 'v2', + }); + + console.table({ + IS_DEVNET: process.env.IS_DEVNET, + IS_RPC: process.env.IS_RPC, + IS_TESTNET: process.env.IS_TESTNET, + }); + + console.log('Global Test Environment is Ready'); + } + + private verifyAccountData(shouldThrow?: boolean): void { + const { TEST_ACCOUNT_ADDRESS, TEST_ACCOUNT_PRIVATE_KEY } = process.env; + if (!TEST_ACCOUNT_ADDRESS) { + if (shouldThrow) throw new Error('TEST_ACCOUNT_ADDRESS env is not provided'); + console.log('\x1b[33m', 'TEST_ACCOUNT_ADDRESS env is not provided!'); + delete process.env.TEST_ACCOUNT_ADDRESS; + } + if (!TEST_ACCOUNT_PRIVATE_KEY) { + if (shouldThrow) throw new Error('TEST_ACCOUNT_PRIVATE_KEY env is not provided'); + console.log('\x1b[33m', 'TEST_ACCOUNT_PRIVATE_KEY env is not provided!', '\x1b[0m'); + delete process.env.TEST_ACCOUNT_PRIVATE_KEY; + } + } + + private useProvidedSetup(): void { + setIfNullish('IS_DEVNET', false); + setIfNullish('IS_RPC', !!process.env.TEST_RPC_URL); + setIfNullish('IS_TESTNET', this.isTestnet); + + this.logConfigInfo(); + + console.log('Using Provided Test Setup'); + } + + async execute(): Promise { + // 1. Assume setup is provided and ready; + console.log('Global Test Setup Started'); + this.verifyAccountData(); + + if (this.hasAllAccountEnvs) { + this.useProvidedSetup(); + return; + } + + // 2. Try to detect devnet setup + console.log('Basic test parameters are missing, Auto Setup Started'); + + await this.detectDevnet(); + this.resolveRpc(); + await accountResolver.execute(this.isDevnet); + + this.verifyAccountData(true); + if (!this.hasAllAccountEnvs) console.error('Test Setup Environment is NOT Ready'); + + this.logConfigInfo(); + } +} + +export default new StrategyResolver(); diff --git a/__tests__/config/jestGlobalSetup.ts b/__tests__/config/jestGlobalSetup.ts index 41c6fdbb9..c804681c7 100644 --- a/__tests__/config/jestGlobalSetup.ts +++ b/__tests__/config/jestGlobalSetup.ts @@ -5,176 +5,12 @@ * ref: order of execution jestGlobalSetup.ts -> jest.setup.ts -> fixtures.ts */ -import { BaseUrl } from '../../src/constants'; -import localDevnetDetector, { type DevnetStrategy } from './helpers/localDevnetDetector'; -import { GS_DEFAULT_TEST_PROVIDER_URL } from './constants'; -import { setIfNullish } from './helpers/env'; - -type ProviderType = Record<'sequencer' | 'rpc', boolean>; +import strategyResolver from './helpers/strategyResolver'; /** * Global Setup Fixtures */ -const sequencerOrRpc = async (devnetStrategy?: DevnetStrategy) => { - const setup = (providerType: ProviderType) => { - setIfNullish('IS_SEQUENCER', providerType.sequencer); - setIfNullish('IS_RPC', providerType.rpc); - setIfNullish( - 'IS_SEQUENCER_GOERLI', - (process.env.TEST_PROVIDER_BASE_URL || process.env.TEST_RPC_URL || '').includes( - BaseUrl.SN_GOERLI - ) - ); - return providerType; - }; - let result: ProviderType = { sequencer: false, rpc: false }; - if (process.env.TEST_PROVIDER_BASE_URL) { - return setup({ ...result, sequencer: true }); - } - if (process.env.TEST_RPC_URL) { - return setup({ ...result, rpc: true }); - } - // nor sequencer nor rpc provided, try with local devnet strategy - if (devnetStrategy && devnetStrategy.isDevnet) { - result = { sequencer: !devnetStrategy.isRS, rpc: devnetStrategy.isRS }; - if (result.sequencer) { - process.env.TEST_PROVIDER_BASE_URL = GS_DEFAULT_TEST_PROVIDER_URL; - } else if (result.rpc) { - process.env.TEST_RPC_URL = GS_DEFAULT_TEST_PROVIDER_URL; - } - } - return setup(result); -}; - -const setAccount = async (devnetStrategy: DevnetStrategy) => { - const fetchAccount = async (URL: string) => { - const response = await fetch(`${URL}predeployed_accounts`); - const accounts = await response.json(); - process.env.TEST_ACCOUNT_ADDRESS = accounts[0].address; - process.env.TEST_ACCOUNT_PRIVATE_KEY = accounts[0].private_key; - process.env.INITIAL_BALANCE = accounts[0].initial_balance; - }; - - if (process.env.TEST_ACCOUNT_ADDRESS && process.env.TEST_ACCOUNT_PRIVATE_KEY) { - return true; - } - if (process.env.TEST_ACCOUNT_ADDRESS || process.env.TEST_ACCOUNT_PRIVATE_KEY) { - throw new Error( - 'If you are providing one of you need to provide both: TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY' - ); - } - const providedURL = process.env.TEST_PROVIDER_BASE_URL || process.env.TEST_RPC_URL; - if (devnetStrategy.isDevnet) { - // get account from devnet - try { - await fetchAccount(GS_DEFAULT_TEST_PROVIDER_URL); - return true; - } catch (error) { - console.error('Fetching account from devnet failed'); - } - } else if (providedURL) { - // try to get it from remote devnet - try { - await fetchAccount(providedURL); - return true; - } catch (error) { - console.error(`Fetching account from provided url ${providedURL} failed`); - } - } - - throw new Error( - 'Setting Account using all known strategies failed, provide basic test parameters' - ); -}; - -const verifySetup = (final?: boolean) => { - const warnings: string[] = []; - if (!process.env.TEST_ACCOUNT_ADDRESS) { - if (final) throw new Error('TEST_ACCOUNT_ADDRESS env is not provided'); - else warnings.push('TEST_ACCOUNT_ADDRESS env is not provided!'); - } - if (!process.env.TEST_ACCOUNT_PRIVATE_KEY) { - if (final) throw new Error('TEST_ACCOUNT_PRIVATE_KEY env is not provided'); - else warnings.push('TEST_ACCOUNT_PRIVATE_KEY env is not provided!'); - } - // TODO: revise after Sequencer removal - // if (!process.env.TEST_RPC_URL) { - // process.env.TEST_RPC_URL = getDefaultNodeUrl(); - // console.warn('TEST_RPC_URL env is not provided'); - // } - - if (warnings.length > 0) { - console.log('\x1b[33m', warnings.join('\n'), '\x1b[0m'); - delete process.env.TEST_ACCOUNT_ADDRESS; - delete process.env.TEST_ACCOUNT_PRIVATE_KEY; - return false; - } - - if (!final) { - setIfNullish('IS_LOCALHOST_DEVNET', false); - setIfNullish('IS_RPC_DEVNET', false); - setIfNullish('IS_SEQUENCER_DEVNET', false); - setIfNullish('IS_RPC', !!process.env.TEST_RPC_URL); - setIfNullish('IS_SEQUENCER', !!process.env.TEST_PROVIDER_BASE_URL); - setIfNullish( - 'IS_SEQUENCER_GOERLI', - (process.env.TEST_PROVIDER_BASE_URL || process.env.TEST_RPC_URL || '').includes( - BaseUrl.SN_GOERLI - ) - ); - } - - console.table({ - TEST_ACCOUNT_ADDRESS: process.env.TEST_ACCOUNT_ADDRESS, - TEST_ACCOUNT_PRIVATE_KEY: '****', - INITIAL_BALANCE: process.env.INITIAL_BALANCE, - TEST_PROVIDER_BASE_URL: process.env.TEST_PROVIDER_BASE_URL, - TEST_RPC_URL: process.env.TEST_RPC_URL, - TX_VERSION: process.env.TX_VERSION === 'v3' ? 'v3' : 'v2', - }); - - console.table({ - IS_LOCALHOST_DEVNET: process.env.IS_LOCALHOST_DEVNET, - IS_RPC_DEVNET: process.env.IS_RPC_DEVNET, - IS_SEQUENCER_DEVNET: process.env.IS_SEQUENCER_DEVNET, - IS_RPC: process.env.IS_RPC, - IS_SEQUENCER: process.env.IS_SEQUENCER, - IS_SEQUENCER_GOERLI: process.env.IS_SEQUENCER_GOERLI, - }); - - console.log('Global Test Environment is Ready'); - return true; -}; - -const executeStrategy = async () => { - // 1. Assume setup is provided and ready; - console.log('Global Test Setup Started'); - if (verifySetup()) { - console.log('Using Provided Test Setup'); - return true; - } - - // 2. Try to detect devnet setup - console.log('Basic test parameters are missing, Auto Setup Started'); - const devnetStrategy = await localDevnetDetector.execute(); - - const providerType = await sequencerOrRpc(devnetStrategy); - if (providerType.sequencer) { - console.log('Detected Sequencer'); - } else if (providerType.rpc) { - console.log('Detected RPC'); - } - - const isAccountSet = await setAccount(devnetStrategy); - if (isAccountSet) { - console.log('Detected Account'); - } - - return verifySetup(true); -}; - export default async (_globalConfig: any, _projectConfig: any) => { - const isSet = await executeStrategy(); - if (!isSet) console.error('Test Setup Environment is NOT Ready'); + await strategyResolver.execute(); }; diff --git a/__tests__/config/schema.ts b/__tests__/config/schema.ts index b6d20820f..6fea89e58 100644 --- a/__tests__/config/schema.ts +++ b/__tests__/config/schema.ts @@ -6,10 +6,9 @@ import componentSchemas from '../schemas/component.json'; import libSchemas from '../schemas/lib.json'; import providerSchemas from '../schemas/provider.json'; import rpcSchemas from '../schemas/rpc.json'; -import sequencerSchemas from '../schemas/sequencer.json'; import { isBigInt } from '../../src/utils/num'; -const matcherSchemas = [accountSchemas, libSchemas, providerSchemas, rpcSchemas, sequencerSchemas]; +const matcherSchemas = [accountSchemas, libSchemas, providerSchemas, rpcSchemas]; const schemas = [...matcherSchemas, componentSchemas]; const jestJsonMatchers = matchersWithOptions({ schemas }, (ajv: any) => { // @ts-ignore @@ -39,7 +38,6 @@ export const initializeMatcher = (expect: jest.Expect) => { expect(libSchemas).toBeValidSchema(); expect(providerSchemas).toBeValidSchema(); expect(rpcSchemas).toBeValidSchema(); - expect(sequencerSchemas).toBeValidSchema(); }; declare global { diff --git a/__tests__/rpcProvider.test.ts b/__tests__/rpcProvider.test.ts index 6c2fe6835..6aa109f3d 100644 --- a/__tests__/rpcProvider.test.ts +++ b/__tests__/rpcProvider.test.ts @@ -24,9 +24,9 @@ import { compiledL1L2, compiledOpenZeppelinAccount, createBlockForDevnet, - describeIfDevnet, - describeIfNotDevnet, describeIfRpc, + describeIfNotDevnet, + describeIfDevnet, getTestAccount, getTestProvider, } from './config/fixtures'; diff --git a/__tests__/schemas/sequencer.json b/__tests__/schemas/sequencer.json deleted file mode 100644 index a31843f42..000000000 --- a/__tests__/schemas/sequencer.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "$id": "sequencerSchemas", - "definitions": { - "TransactionTraceResponse": { - "type": "object", - "properties": { - "validate_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "function_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "fee_transfer_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "signature": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["signature"] - }, - "BlockTransactionTracesResponse": { - "type": "object", - "properties": { - "traces": { - "type": "array", - "items": { - "type": "object", - "properties": { - "validate_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "function_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "fee_transfer_invocation": { - "$ref": "sequencerSchemas#/definitions/FunctionInvocation" - }, - "signature": { - "type": "array", - "items": { - "type": "string" - } - }, - "transaction_hash": { - "type": "string" - } - }, - "required": ["signature", "transaction_hash"] - } - } - }, - "required": ["traces"] - }, - "ExecutionResources": { - "type": "object", - "properties": { - "n_steps": { - "type": "number" - }, - "builtin_instance_counter": { - "$ref": "sequencerSchemas#/definitions/BuiltinInstanceCounter" - }, - "n_memory_holes": { - "type": "number" - } - }, - "required": ["n_steps", "builtin_instance_counter", "n_memory_holes"] - }, - "BuiltinInstanceCounter": { - "type": "object", - "properties": { - "pedersen_builtin": { - "type": "number" - }, - "range_check_builtin": { - "type": "number" - }, - "bitwise_builtin": { - "type": "number" - }, - "output_builtin": { - "type": "number" - }, - "ecdsa_builtin": { - "type": "number" - }, - "ec_op_builtin": { - "type": "number" - } - } - }, - "FunctionInvocation": { - "type": "object", - "properties": { - "caller_address": { - "type": "string" - }, - "contract_address": { - "type": "string" - }, - "calldata": { - "type": "array" - }, - "call_type": { - "type": "string" - }, - "class_hash": { - "type": "string" - }, - "selector": { - "type": "string" - }, - "entry_point_type": { - "type": "string", - "enum": ["EXTERNAL", "CONSTRUCTOR", "L1_HANDLER"] - }, - "result": { - "type": "array" - }, - "execution_resources": { - "$ref": "sequencerSchemas#/definitions/ExecutionResources" - }, - "internal_calls": { - "type": "array" - }, - "events": { - "type": "array" - }, - "messages": { - "type": "array" - } - }, - "required": [ - "caller_address", - "contract_address", - "calldata", - "result", - "execution_resources", - "internal_calls", - "events", - "messages" - ] - } - } -} diff --git a/__tests__/sequencerService.ts b/__tests__/sequencerService.ts deleted file mode 100644 index ce39604b6..000000000 --- a/__tests__/sequencerService.ts +++ /dev/null @@ -1,187 +0,0 @@ -/* import { - BlockNumber, - Contract, - GatewayError, - GetBlockResponse, - HttpError, - Provider, - stark, -} from '../src'; -import * as fetchModule from '../src/utils/fetchPonyfill'; -import { stringify } from '../src/utils/json'; -import { encodeShortString } from '../src/utils/shortString'; -import { - compiledErc20, - compiledL1L2, - describeIfDevnet, - describeIfNotDevnet, - describeIfSequencer, - getTestAccount, - getTestProvider, -} from './fixtures'; -import { initializeMatcher } from './schema'; - -describeIfSequencer('sequencerService', () => { - // todo: disabled from testing - // todo: refactor to test Sequencer service - // todo: before it refactor sequencer service - const sequencerService = getTestProvider(); - const account = getTestAccount(sequencerService); - let exampleBlock: GetBlockResponse; - let exampleBlockNumber: BlockNumber; - let exampleBlockHash: string; - initializeMatcher(expect); - - beforeAll(async () => { - exampleBlock = await sequencerService.getBlock('latest'); - exampleBlockHash = exampleBlock.block_hash; - exampleBlockNumber = exampleBlock.block_number; - }); - - describe('Generic fetch', () => { - const fetchSpy = jest.spyOn(fetchModule, 'default'); - const generateMockResponse = (ok: boolean, text: any): any => ({ - ok, - text: async () => text, - }); - - afterAll(() => { - fetchSpy.mockRestore(); - }); - - test('fetch unexpected error', async () => { - fetchSpy.mockResolvedValueOnce(generateMockResponse(false, 'null')); - await expect(sequencerService.fetch('')).rejects.toThrow(/^Could not GET from endpoint/); - }); - - test('fetch http error', async () => { - fetchSpy.mockResolvedValueOnce(generateMockResponse(false, 'wrong')); - await expect(sequencerService.fetch('')).rejects.toThrow(HttpError); - }); - - test('fetch gateway error', async () => { - fetchSpy.mockResolvedValueOnce(generateMockResponse(false, stringify({}))); - await expect(sequencerService.fetch('')).rejects.toThrow(GatewayError); - }); - - test('fetch success', async () => { - fetchSpy.mockResolvedValueOnce(generateMockResponse(true, stringify({ success: '' }))); - await expect(sequencerService.fetch('')).resolves.toHaveProperty('success'); - }); - }); - - describe('Gateway specific methods', () => { - let exampleContractAddress: string; - - let exampleTransactionHash: string; - - beforeAll(async () => { - const { deploy } = await account.declareAndDeploy({ - contract: compiledErc20, - constructorCalldata: [ - encodeShortString('Token'), - encodeShortString('ERC20'), - account.address, - ], - }); - - exampleTransactionHash = deploy.transaction_hash; - exampleContractAddress = deploy.contract_address; - }); - - test('getTransactionStatus()', async () => { - return expect( - sequencerService.getTransactionStatus(exampleTransactionHash) - ).resolves.not.toThrow(); - }); - - test('transaction trace', async () => { - const transactionTrace = await sequencerService.getTransactionTrace(exampleTransactionHash); - // TODO test optional properties - expect(transactionTrace).toMatchSchemaRef('TransactionTraceResponse'); - }); - - test('getCode() -> { bytecode }', async () => { - const code = await sequencerService.getCode(exampleContractAddress); - return expect(Array.isArray(code.bytecode)).toBe(true); - }); - - describeIfNotDevnet('which are not available on devnet', () => { - test('getContractAddresses()', async () => { - const { GpsStatementVerifier, Starknet } = await sequencerService.getContractAddresses(); - expect(typeof GpsStatementVerifier).toBe('string'); - expect(typeof Starknet).toBe('string'); - }); - }); - }); - - describe('Test Estimate message fee', () => { - const L1_ADDRESS = '0x8359E4B0152ed5A731162D3c7B0D8D56edB165A0'; - let l1l2ContractAddress: string; - - beforeAll(async () => { - const { deploy } = await account.declareAndDeploy({ - contract: compiledL1L2, - }); - l1l2ContractAddress = deploy.contract_address; - }); - - test('estimate message fee', async () => { - const estimation = await sequencerService.estimateMessageFee({ - from_address: L1_ADDRESS, - to_address: l1l2ContractAddress, - entry_point_selector: 'deposit', - payload: ['556', '123'], - }); - expect(estimation).toEqual( - expect.objectContaining({ - overall_fee: expect.anything(), - gas_price: expect.anything(), - gas_usage: expect.anything(), - unit: 'wei', - }) - ); - }); - }); - - describeIfDevnet('Test calls with Custom Devnet Sequencer Provider', () => { - let customsequencerService: Provider; - let erc20: Contract; - const wallet = stark.randomAddress(); - - beforeAll(async () => { - customsequencerService = new Provider({ - sequencer: { - baseUrl: 'http://127.0.0.1:5050/', - feederGatewayUrl: 'feeder_gateway', - gatewayUrl: 'gateway', - }, - }); - const accountCustom = getTestAccount(customsequencerService); - const { deploy } = await accountCustom.declareAndDeploy({ - contract: compiledErc20, - constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), wallet], - }); - - erc20 = new Contract(compiledErc20.abi, deploy.contract_address, customsequencerService); - }); - - test('Check ERC20 balance using Custom Sequencer Provider', async () => { - const { balance } = await erc20.balanceOf(wallet); - expect(balance.low).toStrictEqual(BigInt(1000)); - }); - }); - - describe('getBlockTraces', () => { - test(`getBlockTraces(blockHash=${exampleBlockHash}, blockNumber=undefined)`, async () => { - const blockTraces = await sequencerService.getBlockTraces(exampleBlockHash); - expect(blockTraces).toMatchSchemaRef('BlockTransactionTracesResponse'); - }); - - test(`getBlockTraces(blockHash=undefined, blockNumber=${exampleBlockNumber})`, async () => { - const blockTraces = await sequencerService.getBlockTraces(exampleBlockNumber); - expect(blockTraces).toMatchSchemaRef('BlockTransactionTracesResponse'); - }); - }); -}); -*/ diff --git a/src/account/default.ts b/src/account/default.ts index 02c372340..0a43d0a8a 100644 --- a/src/account/default.ts +++ b/src/account/default.ts @@ -100,7 +100,7 @@ export class Account extends Provider implements AccountInterface { } protected async getNonceSafe(nonce?: BigNumberish) { - // Patch DEPLOY_ACCOUNT: RPC getNonce for non-existing address will result in error, on Sequencer it is '0x0' + // Patch DEPLOY_ACCOUNT: RPC getNonce for non-existing address will result in error try { return toBigInt(nonce ?? (await this.getNonce())); } catch (error) { diff --git a/src/channel/rpc_0_6.ts b/src/channel/rpc_0_6.ts index f89ce7eff..a4c66ca00 100644 --- a/src/channel/rpc_0_6.ts +++ b/src/channel/rpc_0_6.ts @@ -626,7 +626,7 @@ export class RpcChannel { if (invocation.type === TransactionType.INVOKE) { return { // v0 v1 v3 - type: RPC.ETransactionType.INVOKE, // TODO: Diff between sequencer and rpc invoke type + type: RPC.ETransactionType.INVOKE, sender_address: invocation.contractAddress, calldata: CallData.toHex(invocation.calldata), version: toHex(invocation.version || defaultVersions.v3), diff --git a/src/channel/rpc_0_7.ts b/src/channel/rpc_0_7.ts index 741ecd5ef..53e51aed2 100644 --- a/src/channel/rpc_0_7.ts +++ b/src/channel/rpc_0_7.ts @@ -631,7 +631,7 @@ export class RpcChannel { if (invocation.type === TransactionType.INVOKE) { return { // v0 v1 v3 - type: RPC.ETransactionType.INVOKE, // TODO: Diff between sequencer and rpc invoke type + type: RPC.ETransactionType.INVOKE, sender_address: invocation.contractAddress, calldata: CallData.toHex(invocation.calldata), version: toHex(invocation.version || defaultVersions.v3), diff --git a/src/service/_sequencer.ts b/src/service/_sequencer.ts deleted file mode 100644 index f958a3e6e..000000000 --- a/src/service/_sequencer.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO: add sequencer as a service diff --git a/src/utils/provider.ts b/src/utils/provider.ts index 99ea9f4c4..d76e99218 100644 --- a/src/utils/provider.ts +++ b/src/utils/provider.ts @@ -72,9 +72,10 @@ export function parseContract(contract: CompiledContract | string): ContractClas * @returns default node url */ export const getDefaultNodeUrl = (networkName?: NetworkName, mute: boolean = false): string => { - if (!mute) + if (!mute) { // eslint-disable-next-line no-console console.warn('Using default public node url, please provide nodeUrl in provider options!'); + } const nodes = RPC_NODES[networkName ?? NetworkName.SN_SEPOLIA]; const randIdx = Math.floor(Math.random() * nodes.length); return nodes[randIdx]; @@ -162,12 +163,6 @@ export class Block { valueOf = () => this.number; toString = () => this.hash; - - /* get sequencerIdentifier(): SequencerIdentifier { - return this.hash !== null - ? { blockHash: this.hash as string } - : { blockNumber: (this.number ?? this.tag) as BlockNumber }; - } */ } export function isV3Tx(details: InvocationsDetailsWithNonce): details is V3TransactionDetails {