diff --git a/__tests__/account.test.ts b/__tests__/account.test.ts index 2570a7bb3..b5b7b52cf 100644 --- a/__tests__/account.test.ts +++ b/__tests__/account.test.ts @@ -24,7 +24,6 @@ describe('deploy and test Wallet', () => { beforeAll(async () => { expect(account).toBeInstanceOf(Account); - // New Stuff const declareDeploy = await account.declareDeploy({ contract: compiledErc20, classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', diff --git a/__tests__/contract.test.ts b/__tests__/contract.test.ts index e196d4684..1e56bcdd3 100644 --- a/__tests__/contract.test.ts +++ b/__tests__/contract.test.ts @@ -1,15 +1,15 @@ import { isBN } from 'bn.js'; import { Contract, ContractFactory, stark } from '../src'; -import { DeployContractPayload } from '../src/types/lib'; import { getSelectorFromName } from '../src/utils/hash'; import { BigNumberish, toBN } from '../src/utils/number'; +import { encodeShortString } from '../src/utils/shortString'; import { compileCalldata } from '../src/utils/stark'; import { compiledErc20, compiledMulticall, compiledTypeTransformation, - getERC20DeployPayload, + getTestAccount, getTestProvider, } from './fixtures'; @@ -17,45 +17,46 @@ const provider = getTestProvider(); describe('class Contract {}', () => { const wallet = stark.randomAddress(); + const account = getTestAccount(provider); describe('Basic Interaction', () => { - let erc20: Contract; - let contract: Contract; + let erc20Contract: Contract; + let multicallContract: Contract; beforeAll(async () => { - const erc20DeployPayload = getERC20DeployPayload(wallet); - - const { contract_address, transaction_hash } = await provider.deployContract( - erc20DeployPayload - ); - - erc20 = new Contract(compiledErc20.abi, contract_address!, provider); - await provider.waitForTransaction(transaction_hash); - // Deploy Multicall + const { deploy } = await account.declareDeploy({ + contract: compiledErc20, + classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', + constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), wallet], + }); - const { transaction_hash: m_transaction_hash, contract_address: multicallAddress } = - await provider.deployContract({ - contract: compiledMulticall, - }); + erc20Contract = new Contract(compiledErc20.abi, deploy.contract_address!, provider); - contract = new Contract(compiledMulticall.abi, multicallAddress!, provider); + const { deploy: multicallDeploy } = await account.declareDeploy({ + contract: compiledMulticall, + classHash: '0x06f94f3229a8d9c1d51cb84f1f5ec306c8552a805e307540727dda53c4936b43', + }); - await provider.waitForTransaction(m_transaction_hash); + multicallContract = new Contract( + compiledMulticall.abi, + multicallDeploy.contract_address!, + provider + ); }); test('populate transaction for initial balance of that account', async () => { - const res = await erc20.populateTransaction.balanceOf(wallet); + const res = await erc20Contract.populateTransaction.balanceOf(wallet); expect(res).toHaveProperty('contractAddress'); expect(res).toHaveProperty('entrypoint'); expect(res).toHaveProperty('calldata'); }); test('estimate gas fee for `mint` should fail when connected to the provider', async () => { - expect(erc20.estimateFee.mint(wallet, ['10', '0'])).rejects.toThrow(); + expect(erc20Contract.estimateFee.mint(wallet, ['10', '0'])).rejects.toThrow(); }); test('read initial balance of that account', async () => { - const result = await erc20.balanceOf(wallet); + const result = await erc20Contract.balanceOf(wallet); const [res] = result; expect(res.low).toStrictEqual(toBN(1000)); expect(res).toStrictEqual(result.balance); @@ -65,17 +66,17 @@ describe('class Contract {}', () => { const args1 = { user: wallet }; const args2 = {}; const calls = [ - erc20.address, + erc20Contract.address, getSelectorFromName('balanceOf'), Object.keys(args1).length, ...compileCalldata(args1), - erc20.address, + erc20Contract.address, getSelectorFromName('decimals'), Object.keys(args2).length, ...compileCalldata(args2), ]; - const result = await contract.aggregate(calls); + const result = await multicallContract.aggregate(calls); const [block_number, res] = result; expect(isBN(block_number)); expect(Array.isArray(res)); @@ -86,36 +87,43 @@ describe('class Contract {}', () => { }); describe('Type Transformation', () => { - let contract: Contract; + let typeTransContract: Contract; beforeAll(async () => { - const { transaction_hash, contract_address } = await provider.deployContract({ + const { deploy } = await account.declareDeploy({ contract: compiledTypeTransformation, + classHash: '0x022a0e662b13d18a2aaa3ee54ae290de6569621b549022c18169c6e7893809ea', }); - contract = new Contract(compiledTypeTransformation.abi, contract_address!, provider); - await provider.waitForTransaction(transaction_hash); + + typeTransContract = new Contract( + compiledTypeTransformation.abi, + deploy.contract_address!, + provider + ); }); describe('Request Type Transformation', () => { test('Parsing the felt in request', async () => { - return expect(contract.request_felt(3)).resolves.not.toThrow(); + return expect(typeTransContract.request_felt(3)).resolves.not.toThrow(); }); test('Parsing the array of felt in request', async () => { - return expect(contract.request_array_of_felts([1, 2])).resolves.not.toThrow(); + return expect(typeTransContract.request_array_of_felts([1, 2])).resolves.not.toThrow(); }); test('Parsing the struct in request', async () => { - return expect(contract.request_struct({ x: 1, y: 2 })).resolves.not.toThrow(); + return expect(typeTransContract.request_struct({ x: 1, y: 2 })).resolves.not.toThrow(); }); test('Parsing the array of structs in request', async () => { - return expect(contract.request_array_of_structs([{ x: 1, y: 2 }])).resolves.not.toThrow(); + return expect( + typeTransContract.request_array_of_structs([{ x: 1, y: 2 }]) + ).resolves.not.toThrow(); }); test('Parsing the nested structs in request', async () => { return expect( - contract.request_nested_structs({ + typeTransContract.request_nested_structs({ p1: { x: 1, y: 2 }, p2: { x: 3, y: 4 }, extra: 5, @@ -124,43 +132,45 @@ describe('class Contract {}', () => { }); test('Parsing the tuple in request', async () => { - return expect(contract.request_tuple([1, 2])).resolves.not.toThrow(); + return expect(typeTransContract.request_tuple([1, 2])).resolves.not.toThrow(); }); test('Parsing the multiple types in request', async () => { - return expect(contract.request_mixed_types(2, { x: 1, y: 2 }, [1])).resolves.not.toThrow(); + return expect( + typeTransContract.request_mixed_types(2, { x: 1, y: 2 }, [1]) + ).resolves.not.toThrow(); }); }); describe('Response Type Transformation', () => { test('Parsing the felt in response', async () => { - const { res } = await contract.get_felt(); + const { res } = await typeTransContract.get_felt(); expect(res).toStrictEqual(toBN(4)); }); test('Parsing the array of felt in response', async () => { - const result = await contract.get_array_of_felts(); + const result = await typeTransContract.get_array_of_felts(); const [res] = result; expect(res).toStrictEqual([toBN(4), toBN(5)]); expect(res).toStrictEqual(result.res); }); test('Parsing the array of structs in response', async () => { - const result = await contract.get_struct(); + const result = await typeTransContract.get_struct(); const [res] = result; expect(res).toStrictEqual({ x: toBN(1), y: toBN(2) }); expect(res).toStrictEqual(result.res); }); test('Parsing the array of structs in response', async () => { - const result = await contract.get_array_of_structs(); + const result = await typeTransContract.get_array_of_structs(); const [res] = result; expect(res).toStrictEqual([{ x: toBN(1), y: toBN(2) }]); expect(res).toStrictEqual(result.res); }); test('Parsing the nested structs in response', async () => { - const result = await contract.get_nested_structs(); + const result = await typeTransContract.get_nested_structs(); const [res] = result; expect(res).toStrictEqual({ p1: { x: toBN(1), y: toBN(2) }, @@ -171,14 +181,14 @@ describe('class Contract {}', () => { }); test('Parsing the tuple in response', async () => { - const result = await contract.get_tuple(); + const result = await typeTransContract.get_tuple(); const [res] = result; expect(res).toStrictEqual([toBN(1), toBN(2), toBN(3)]); expect(res).toStrictEqual(result.res); }); test('Parsing the multiple types in response', async () => { - const result = await contract.get_mixed_types(); + const result = await typeTransContract.get_mixed_types(); const [tuple, number, array, point] = result; expect(tuple).toStrictEqual([toBN(1), toBN(2)]); expect(number).toStrictEqual(toBN(3)); @@ -196,26 +206,26 @@ describe('class Contract {}', () => { describe('class ContractFactory {}', () => { let erc20Address: string; const wallet = stark.randomAddress(); - let erc20DeployPayload: DeployContractPayload; + const account = getTestAccount(provider); + let constructorCalldata; beforeAll(async () => { - erc20DeployPayload = getERC20DeployPayload(wallet); - - const { contract_address, transaction_hash } = await provider.deployContract( - erc20DeployPayload - ); + constructorCalldata = [encodeShortString('Token'), encodeShortString('ERC20'), wallet]; - await provider.waitForTransaction(transaction_hash); - erc20Address = contract_address; + await account.declareDeploy({ + contract: compiledErc20, + classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', + constructorCalldata, + }); }); test('deployment of new contract', async () => { const factory = new ContractFactory(compiledErc20, provider); - const erc20 = await factory.deploy(erc20DeployPayload.constructorCalldata); + const erc20 = await factory.deploy(constructorCalldata); expect(erc20 instanceof Contract); }); test('wait for deployment transaction', async () => { const factory = new ContractFactory(compiledErc20, provider); - const contract = await factory.deploy(erc20DeployPayload.constructorCalldata); + const contract = await factory.deploy(constructorCalldata); expect(contract.deployed()).resolves.not.toThrow(); }); test('attach new contract', async () => { diff --git a/__tests__/defaultProvider.test.ts b/__tests__/defaultProvider.test.ts index b1a7b6e72..4b051ba2d 100644 --- a/__tests__/defaultProvider.test.ts +++ b/__tests__/defaultProvider.test.ts @@ -1,6 +1,7 @@ import { BlockNumber, GetBlockResponse, stark } from '../src'; import { toBN } from '../src/utils/number'; -import { erc20ClassHash, getERC20DeployPayload, getTestProvider } from './fixtures'; +import { encodeShortString } from '../src/utils/shortString'; +import { compiledErc20, erc20ClassHash, getTestAccount, getTestProvider } from './fixtures'; const { compileCalldata } = stark; @@ -9,21 +10,21 @@ const testProvider = getTestProvider(); describe('defaultProvider', () => { let exampleTransactionHash: string; let erc20ContractAddress: string; - let exampleBlock: GetBlockResponse; let exampleBlockNumber: BlockNumber; let exampleBlockHash: string; const wallet = stark.randomAddress(); + const account = getTestAccount(testProvider); beforeAll(async () => { - const erc20DeployPayload = getERC20DeployPayload(wallet); + const { deploy } = await account.declareDeploy({ + contract: compiledErc20, + classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', + constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), wallet], + }); - const { contract_address, transaction_hash } = await testProvider.deployContract( - erc20DeployPayload - ); - await testProvider.waitForTransaction(transaction_hash); - exampleTransactionHash = transaction_hash; - erc20ContractAddress = contract_address; + exampleTransactionHash = deploy.transaction_hash; + erc20ContractAddress = deploy.contract_address; exampleBlock = await testProvider.getBlock('latest'); exampleBlockHash = exampleBlock.block_hash; @@ -31,7 +32,7 @@ describe('defaultProvider', () => { }); describe('endpoints', () => { - test('deployContract()', () => { + test('declareDeploy()', () => { expect(erc20ContractAddress).toBeTruthy(); expect(exampleTransactionHash).toBeTruthy(); }); @@ -76,7 +77,7 @@ describe('defaultProvider', () => { test('getNonce()', async () => { const nonce = await testProvider.getNonce(erc20ContractAddress); - return expect(nonce).toEqual('0x0'); + return expect(toBN(nonce)).toEqual(toBN('0x0')); }); test('getClassAt(contractAddress, blockNumber="latest")', async () => { diff --git a/__tests__/fixtures.ts b/__tests__/fixtures.ts index 2aebc7d83..8258eb751 100644 --- a/__tests__/fixtures.ts +++ b/__tests__/fixtures.ts @@ -13,29 +13,33 @@ export const compiledTypeTransformation = readContract('contract'); export const compiledMulticall = readContract('multicall'); export const compiledTestDapp = readContract('TestDapp'); -const DEFAULT_TEST_PROVIDER_BASE_URL = 'http://127.0.0.1:5050/'; -const DEFAULT_TEST_ACCOUNT_ADDRESS = // run `starknet-devnet --seed 0` and this will be the first account +/* Default test config based on run `starknet-devnet --seed 0` */ +const DEFAULT_TEST_PROVIDER_SEQUENCER_URL = 'http://127.0.0.1:5050/'; +const DEFAULT_TEST_ACCOUNT_ADDRESS = '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a'; const DEFAULT_TEST_ACCOUNT_PRIVATE_KEY = '0xe3e70682c2094cac629f6fbed82c07cd'; -const BASE_URL = process.env.TEST_PROVIDER_BASE_URL || DEFAULT_TEST_PROVIDER_BASE_URL; +/* User defined config or default one */ +const BASE_URL = process.env.TEST_PROVIDER_BASE_URL || DEFAULT_TEST_PROVIDER_SEQUENCER_URL; const RPC_URL = process.env.TEST_RPC_URL; -const IS_RPC = !!RPC_URL; -const IS_RPC_DEVNET = Boolean( - RPC_URL && (RPC_URL.includes('localhost') || RPC_URL.includes('127.0.0.1')) -); -const IS_SEQUENCER = !IS_RPC; -const IS_SEQUENCER_DEVNET = !BASE_URL.includes('starknet.io'); -export const IS_SEQUENCER_GOERLI = BASE_URL === 'https://alpha4-2.starknet.io'; -export const IS_DEVNET = IS_SEQUENCER ? IS_SEQUENCER_DEVNET : IS_RPC_DEVNET; +/* Detect user defined node or sequencer, if none default to sequencer if both default to node */ +const PROVIDER_URL = RPC_URL || BASE_URL; + +/* Detect is localhost devnet */ +export const IS_LOCALHOST_DEVNET = + PROVIDER_URL.includes('localhost') || PROVIDER_URL.includes('127.0.0.1'); + +/* Definitions */ +export const IS_RPC = !!RPC_URL; +export const IS_SEQUENCER = !RPC_URL; export const getTestProvider = (): ProviderInterface => { const provider = RPC_URL ? new RpcProvider({ nodeUrl: RPC_URL }) : new SequencerProvider({ baseUrl: BASE_URL }); - if (IS_DEVNET) { + if (IS_LOCALHOST_DEVNET) { // accelerate the tests when running locally const originalWaitForTransaction = provider.waitForTransaction.bind(provider); provider.waitForTransaction = (txHash, retryInterval) => { @@ -51,11 +55,10 @@ export const getTestAccount = (provider: ProviderInterface) => { let testAccountAddress = process.env.TEST_ACCOUNT_ADDRESS; let testAccountPrivateKey = process.env.TEST_ACCOUNT_PRIVATE_KEY; - if (!IS_DEVNET) { + if (!IS_LOCALHOST_DEVNET) { if (!testAccountPrivateKey) { throw new Error('TEST_ACCOUNT_PRIVATE_KEY is not set'); } - if (!testAccountAddress) { throw new Error('TEST_ACCOUNT_ADDRESS is not set'); } @@ -68,8 +71,9 @@ export const getTestAccount = (provider: ProviderInterface) => { }; const describeIf = (condition: boolean) => (condition ? describe : describe.skip); -export const describeIfSequencer = describeIf(IS_DEVNET); +export const describeIfSequencer = describeIf(IS_SEQUENCER); export const describeIfRpc = describeIf(IS_RPC); -export const describeIfNotDevnet = describeIf(!IS_DEVNET); +export const describeIfNotDevnet = describeIf(!IS_LOCALHOST_DEVNET); +export const describeIfDevnet = describeIf(IS_LOCALHOST_DEVNET); export const erc20ClassHash = '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a'; diff --git a/__tests__/rpcProvider.test.ts b/__tests__/rpcProvider.test.ts index 13d1c8e88..9097fe9a6 100644 --- a/__tests__/rpcProvider.test.ts +++ b/__tests__/rpcProvider.test.ts @@ -8,15 +8,12 @@ import { } from './fixtures'; describeIfRpc('RPCProvider', () => { - let rpcProvider: RpcProvider; + const rpcProvider = getTestProvider() as RpcProvider; + const account = getTestAccount(rpcProvider); let accountPublicKey: string; beforeAll(async () => { - rpcProvider = getTestProvider() as RpcProvider; - const account = getTestAccount(rpcProvider); - expect(account).toBeInstanceOf(Account); - const accountKeyPair = ec.genKeyPair(); accountPublicKey = ec.getStarkKey(accountKeyPair); }); @@ -28,7 +25,8 @@ describeIfRpc('RPCProvider', () => { ); }); - test('getPendingTransactions', async () => { + xtest('getPendingTransactions', async () => { + // devnet not implement const transactions = await rpcProvider.getPendingTransactions(); expect(Array.isArray(transactions)).toBe(true); }); @@ -90,15 +88,18 @@ describeIfRpc('RPCProvider', () => { let transaction_hash; beforeAll(async () => { - ({ contract_address, transaction_hash } = await rpcProvider.deployContract({ + const { deploy } = await account.declareDeploy({ contract: compiledOpenZeppelinAccount, + classHash: '0x03fcbf77b28c96f4f2fb5bd2d176ab083a12a5e123adeb0de955d7ee228c9854', constructorCalldata: [accountPublicKey], - addressSalt: accountPublicKey, - })); - await rpcProvider.waitForTransaction(transaction_hash); + salt: accountPublicKey, + }); + + contract_address = deploy.contract_address; + transaction_hash = deploy.transaction_hash; }); - test('deployContract result', () => { + test('declareDeploy()', () => { expect(contract_address).toBeTruthy(); expect(transaction_hash).toBeTruthy(); }); diff --git a/__tests__/sequencerProvider.test.ts b/__tests__/sequencerProvider.test.ts index d1027287f..70a54d1c6 100644 --- a/__tests__/sequencerProvider.test.ts +++ b/__tests__/sequencerProvider.test.ts @@ -1,46 +1,35 @@ import { Contract, Provider, SequencerProvider, stark } from '../src'; import { toBN } from '../src/utils/number'; +import { encodeShortString } from '../src/utils/shortString'; import { - IS_SEQUENCER_GOERLI, compiledErc20, compiledL1L2, + describeIfDevnet, describeIfNotDevnet, describeIfSequencer, - getERC20DeployPayload, + getTestAccount, getTestProvider, } from './fixtures'; -// Run only if Devnet Sequencer describeIfSequencer('SequencerProvider', () => { - let sequencerProvider: SequencerProvider; + const sequencerProvider = getTestProvider() as SequencerProvider; + const account = getTestAccount(sequencerProvider); let customSequencerProvider: Provider; let exampleContractAddress: string; - beforeAll(async () => { - sequencerProvider = getTestProvider() as SequencerProvider; - customSequencerProvider = new Provider({ - sequencer: { - baseUrl: 'http://127.0.0.1:5050/', - feederGatewayUrl: 'feeder_gateway', - gatewayUrl: 'gateway', - }, // Similar to arguements used in docs - }); - }); - describe('Gateway specific methods', () => { let exampleTransactionHash: string; const wallet = stark.randomAddress(); beforeAll(async () => { - const erc20DeployPayload = getERC20DeployPayload(wallet); - - const { contract_address, transaction_hash } = await sequencerProvider.deployContract( - erc20DeployPayload - ); + const { deploy } = await account.declareDeploy({ + contract: compiledErc20, + classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', + constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), wallet], + }); - await sequencerProvider.waitForTransaction(transaction_hash); - exampleTransactionHash = transaction_hash; - exampleContractAddress = contract_address; + exampleTransactionHash = deploy.transaction_hash; + exampleContractAddress = deploy.contract_address; }); test('getTransactionStatus()', async () => { @@ -69,43 +58,16 @@ describeIfSequencer('SequencerProvider', () => { }); }); - describe('Test calls with Custom Sequencer Provider', () => { - let erc20: Contract; - const wallet = stark.randomAddress(); - - beforeAll(async () => { - const erc20DeployPayload = getERC20DeployPayload(wallet); - - const { contract_address, transaction_hash } = await customSequencerProvider.deployContract( - erc20DeployPayload - ); - - await customSequencerProvider.waitForTransaction(transaction_hash); - erc20 = new Contract(compiledErc20.abi, contract_address, customSequencerProvider); - }); - - test('Check ERC20 balance using Custom Sequencer Provider', async () => { - const result = await erc20.balanceOf(wallet); - const [res] = result; - expect(res.low).toStrictEqual(toBN(1000)); - expect(res).toStrictEqual(result.balance); - }); - }); - describe('Test Estimate message fee', () => { const L1_ADDRESS = '0x8359E4B0152ed5A731162D3c7B0D8D56edB165A0'; let l1l2ContractAddress: string; beforeAll(async () => { - if (IS_SEQUENCER_GOERLI) { - l1l2ContractAddress = '0x2863141e0d9a74e9b484c1f5b1e3a2f6cbb6b84df8233c7c1cbe31334d9aed8'; - } else { - const { transaction_hash, contract_address } = await sequencerProvider.deployContract({ - contract: compiledL1L2, - }); - await sequencerProvider.waitForTransaction(transaction_hash); - l1l2ContractAddress = contract_address; - } + const { deploy } = await account.declareDeploy({ + contract: compiledL1L2, + classHash: '0x028d1671fb74ecb54d848d463cefccffaef6df3ae40db52130e19fe8299a7b43', + }); + l1l2ContractAddress = deploy.contract_address; }); test('estimate message fee', async () => { @@ -128,4 +90,34 @@ describeIfSequencer('SequencerProvider', () => { ); }); }); + + describeIfDevnet('Test calls with Custom Devnet Sequencer Provider', () => { + let erc20: Contract; + const wallet = stark.randomAddress(); + + beforeAll(async () => { + customSequencerProvider = new Provider({ + sequencer: { + baseUrl: 'http://127.0.0.1:5050/', + feederGatewayUrl: 'feeder_gateway', + gatewayUrl: 'gateway', + }, + }); + const accountCustom = getTestAccount(customSequencerProvider); + const { deploy } = await accountCustom.declareDeploy({ + contract: compiledErc20, + classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a', + constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), wallet], + }); + + erc20 = new Contract(compiledErc20.abi, deploy.contract_address, customSequencerProvider); + }); + + test('Check ERC20 balance using Custom Sequencer Provider', async () => { + const result = await erc20.balanceOf(wallet); + const [res] = result; + expect(res.low).toStrictEqual(toBN(1000)); + expect(res).toStrictEqual(result.balance); + }); + }); }); diff --git a/__tests__/utils/utils.test.ts b/__tests__/utils/utils.test.ts index 55d4ec347..d47414204 100644 --- a/__tests__/utils/utils.test.ts +++ b/__tests__/utils/utils.test.ts @@ -27,12 +27,21 @@ describe('compressProgram()', () => { expect(compressed).toMatchSnapshot(); }); }); + describe('hexToDecimalString()', () => { test('parse 0xa23', () => { expect(number.hexToDecimalString('0xa23')).toBe('2595'); }); }); +describe('cleanHex()', () => { + test('parse 0xa23', () => { + expect(number.cleanHex('0x023Ab')).toBe('0x23ab'); + expect(number.cleanHex('0x000023Ab')).toBe('0x23ab'); + expect(number.cleanHex('0x23Ab')).toBe('0x23ab'); + }); +}); + describe('makeAddress()', () => { test('test on eth address', () => { const ethAddress = '0xdFD0F27FCe99b50909de0bDD328Aed6eAbe76BC5'; @@ -42,6 +51,7 @@ describe('makeAddress()', () => { expect(starkAddress).toBe('0xdfd0f27fce99b50909de0bdd328aed6eabe76bc5'); }); }); + describe('getSelectorFromName()', () => { test('hash works for value="test"', () => { expect(hash.getSelectorFromName('test')).toBe( diff --git a/src/account/default.ts b/src/account/default.ts index fec1b2711..a60a62352 100644 --- a/src/account/default.ts +++ b/src/account/default.ts @@ -28,7 +28,7 @@ import { feeTransactionVersion, transactionVersion, } from '../utils/hash'; -import { BigNumberish, toBN, toCairoBool } from '../utils/number'; +import { BigNumberish, cleanHex, toBN, toCairoBool } from '../utils/number'; import { parseContract } from '../utils/provider'; import { compileCalldata, estimatedFeeToMaxFee, randomAddress } from '../utils/stark'; import { fromCallsToExecuteCalldata } from '../utils/transaction'; @@ -329,7 +329,11 @@ export class Account extends Provider implements AccountInterface { */ public getUDCResponse(txReceipt: InvokeTransactionReceiptResponse | void) { if (txReceipt && txReceipt.events) { - const event = txReceipt.events.find((it) => it.from_address === UDC.ADDRESS) || { data: [] }; + const event = txReceipt.events.find( + (it) => cleanHex(it.from_address) === cleanHex(UDC.ADDRESS) + ) || { + data: [], + }; return { transaction_hash: txReceipt.transaction_hash, contract_address: event.data[0], @@ -345,10 +349,13 @@ export class Account extends Provider implements AccountInterface { return new Error("UDC didn't emmit event"); } - public async declareDeploy({ classHash, contract, constructorCalldata }: any) { - const { transaction_hash } = await this.declare({ contract, classHash }); + public async declareDeploy( + { classHash, contract, constructorCalldata }: any, + details?: InvocationsDetails + ) { + const { transaction_hash } = await this.declare({ contract, classHash }, details); const declare = await this.waitForTransaction(transaction_hash); - const deploy = await this.deployContract2({ classHash, constructorCalldata }); + const deploy = await this.deployContract2({ classHash, constructorCalldata }, details); return { declare: { ...declare, class_hash: classHash }, deploy }; } diff --git a/src/account/interface.ts b/src/account/interface.ts index 103446cde..ffea74163 100644 --- a/src/account/interface.ts +++ b/src/account/interface.ts @@ -131,7 +131,6 @@ export abstract class AccountInterface extends ProviderInterface { * @param contractPayload transaction payload to be deployed containing: - contract: compiled contract code - classHash: computed class hash of compiled contract - - signature * @param transactionsDetail Invocation Details containing: - optional nonce - optional version diff --git a/src/provider/default.ts b/src/provider/default.ts index 0fd18e9cb..ab3f90b09 100644 --- a/src/provider/default.ts +++ b/src/provider/default.ts @@ -35,11 +35,14 @@ export class Provider implements ProviderInterface { private provider!: ProviderInterface; constructor(providerOrOptions?: ProviderOptions | ProviderInterface) { - if ( + if (providerOrOptions instanceof Provider) { + // providerOrOptions is Provider + this.provider = providerOrOptions.provider; + } else if ( providerOrOptions instanceof RpcProvider || providerOrOptions instanceof SequencerProvider ) { - // providerOrOptions is provider + // providerOrOptions is SequencerProvider or RpcProvider this.provider = providerOrOptions; } else if (providerOrOptions && 'rpc' in providerOrOptions) { // providerOrOptions is rpc option diff --git a/src/provider/rpc.ts b/src/provider/rpc.ts index 92c410244..ccd696b19 100644 --- a/src/provider/rpc.ts +++ b/src/provider/rpc.ts @@ -407,7 +407,7 @@ export class RpcProvider implements ProviderInterface { public async waitForTransaction(txHash: string, retryInterval: number = 8000) { let { retries } = this; let onchain = false; - let res; + let txReceipt; while (!onchain) { const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING']; @@ -417,19 +417,19 @@ export class RpcProvider implements ProviderInterface { await wait(retryInterval); try { // eslint-disable-next-line no-await-in-loop - res = await this.getTransactionReceipt(txHash); + txReceipt = await this.getTransactionReceipt(txHash); - if (!('status' in res)) { + if (!('status' in txReceipt)) { const error = new Error('pending transaction'); throw error; } - if (res.status && successStates.includes(res.status)) { + if (txReceipt.status && successStates.includes(txReceipt.status)) { onchain = true; - } else if (res.status && errorStates.includes(res.status)) { - const message = res.status; + } else if (txReceipt.status && errorStates.includes(txReceipt.status)) { + const message = txReceipt.status; const error = new Error(message) as Error & { response: any }; - error.response = res; + error.response = txReceipt; throw error; } } catch (error: unknown) { @@ -446,7 +446,7 @@ export class RpcProvider implements ProviderInterface { } await wait(retryInterval); - return res; + return txReceipt; } /** diff --git a/src/provider/sequencer.ts b/src/provider/sequencer.ts index 9fc77c0a6..0a6f55feb 100644 --- a/src/provider/sequencer.ts +++ b/src/provider/sequencer.ts @@ -472,7 +472,8 @@ export class SequencerProvider implements ProviderInterface { throw error; } } - return res; + const txReceipt = await this.getTransactionReceipt(txHash); + return txReceipt; } /** diff --git a/src/utils/number.ts b/src/utils/number.ts index a6747ec93..81d5c85fe 100644 --- a/src/utils/number.ts +++ b/src/utils/number.ts @@ -34,6 +34,12 @@ export function toFelt(num: BigNumberish): string { return toBN(num).toString(); } +/** + * Remove hex string leading zero and lower case '0x01A'.. -> '0x1a..' + * @param hex string + */ +export const cleanHex = (hex: string) => hex.toLowerCase().replace(/^(0x)0+/, '$1'); + /* Asserts input is equal to or greater then lowerBound and lower then upperBound. Assert message specifies inputName.