Skip to content

Commit fc3b484

Browse files
committed
feat: add account rpc tests
1 parent 2fac438 commit fc3b484

File tree

6 files changed

+100
-16
lines changed

6 files changed

+100
-16
lines changed

__tests__/fixtures.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,30 @@ export const getTestProvider = () => {
3535
};
3636

3737
// test account with fee token balance
38-
export const getTestAccount = () => {
39-
const provider = getTestProvider();
38+
export const getTestAccount = (provider = getTestProvider(), isDevnet = false) => {
39+
if (!isDevnet) {
40+
if (!process.env.TEST_ACCOUNT_PRIVATE_KEY) {
41+
throw new Error('TEST_ACCOUNT_PRIVATE_KEY is not set');
42+
}
4043

41-
const testAccountAddress = process.env.TEST_ACCOUNT_ADDRESS || DEFAULT_TEST_ACCOUNT_ADDRESS;
42-
const testAccountPrivateKey =
43-
process.env.TEST_ACCOUNT_PRIVATE_KEY || DEFAULT_TEST_ACCOUNT_PRIVATE_KEY;
44+
if (!process.env.TEST_ACCOUNT_ADDRESS) {
45+
throw new Error('TEST_ACCOUNT_ADDRESS is not set');
46+
}
47+
}
48+
49+
const testAccountAddress = isDevnet
50+
? DEFAULT_TEST_ACCOUNT_ADDRESS
51+
: (process.env.TEST_ACCOUNT_ADDRESS as string);
52+
const testAccountPrivateKey = isDevnet
53+
? DEFAULT_TEST_ACCOUNT_PRIVATE_KEY
54+
: (process.env.TEST_ACCOUNT_PRIVATE_KEY as string);
4455

4556
return new Account(provider, testAccountAddress, ec.getKeyPair(testAccountPrivateKey));
4657
};
4758

4859
export const testIf = (condition: boolean) => (condition ? test : test.skip);
60+
export const describeIf = (condition: boolean) => (condition ? describe : describe.skip);
4961
export const testIfDevnet = testIf(IS_DEVNET);
5062
export const testIfNotDevnet = testIf(!IS_DEVNET);
63+
export const describeIfDevnet = describeIf(IS_DEVNET);
64+
export const describeIfNotDevnet = describeIf(!IS_DEVNET);

__tests__/rpcProvider.test.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { DeployContractResponse, RPCProvider } from '../src';
1+
import { isBN } from 'bn.js';
2+
3+
import { Account, Contract, DeployContractResponse, Provider, RPCProvider } from '../src';
4+
import { toBN } from '../src/utils/number';
25
import { compileCalldata } from '../src/utils/stark';
3-
import { compiledErc20 } from './fixtures';
6+
import { compiledErc20, describeIfNotDevnet, getTestAccount } from './fixtures';
47

58
const { TEST_RPC_URL } = process.env;
69

@@ -191,4 +194,55 @@ describe('RPCProvider', () => {
191194
expect(chainId).toBe('0x534e5f474f45524c49');
192195
});
193196
});
197+
198+
describeIfNotDevnet('Account', () => {
199+
let account: Account;
200+
let erc20Address!: string;
201+
let erc20: Contract;
202+
203+
beforeAll(async () => {
204+
const rpcProvider = new Provider({ rpc: { nodeUrl: TEST_RPC_URL } });
205+
account = getTestAccount(rpcProvider, false);
206+
expect(account).toBeInstanceOf(Account);
207+
208+
// Using predeployed contract as RPC node has issues with using recent deployed contracts
209+
erc20Address = '0x649c8b8dbb19009551120c364208bad865f06d4b12ecd3e7109421d8b22968e';
210+
erc20 = new Contract(compiledErc20.abi, erc20Address, provider);
211+
212+
const mintResponse = await account.execute({
213+
contractAddress: erc20Address,
214+
entrypoint: 'mint',
215+
calldata: [account.address, '1000'],
216+
});
217+
218+
await provider.waitForTransaction(mintResponse.transaction_hash);
219+
});
220+
221+
test('estimate fee', async () => {
222+
const { overall_fee } = await account.estimateFee({
223+
contractAddress: erc20Address,
224+
entrypoint: 'transfer',
225+
calldata: [erc20.address, '10'],
226+
});
227+
228+
console.log({ overall_fee });
229+
expect(isBN(overall_fee)).toBe(true);
230+
});
231+
232+
test('execute by wallet owner', async () => {
233+
const { res: before } = await erc20.balance_of(account.address);
234+
235+
const { transaction_hash } = await account.execute({
236+
contractAddress: erc20Address,
237+
entrypoint: 'transfer',
238+
calldata: [erc20.address, '10'],
239+
});
240+
241+
await account.waitForTransaction(transaction_hash);
242+
243+
const { res: after } = await erc20.balance_of(account.address);
244+
245+
expect(toBN(before).sub(toBN(after)).toString(10)).toBe('10');
246+
});
247+
});
194248
});

src/account/default.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class Account extends Provider implements AccountInterface {
4343

4444
public async estimateFee(
4545
calls: Call | Call[],
46-
{ nonce: providedNonce, blockIdentifier = 'pending' }: EstimateFeeDetails = {}
46+
{ nonce: providedNonce, blockIdentifier }: EstimateFeeDetails = {}
4747
): Promise<EstimateFee> {
4848
const transactions = Array.isArray(calls) ? calls : [calls];
4949
const nonce = providedNonce ?? (await this.getNonce());

src/provider/default.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ export class Provider implements ProviderInterface {
5555

5656
public async getEstimateFee(
5757
invocation: Invocation,
58-
blockIdentifier: BlockIdentifier,
59-
invocationDetails?: InvocationsDetails
58+
blockIdentifier: BlockIdentifier = 'latest', // 'pending' is not working on the RPC node
59+
invocationDetails: InvocationsDetails = {}
6060
): Promise<EstimateFeeResponse> {
6161
return this.provider.getEstimateFee(invocation, blockIdentifier, invocationDetails);
6262
}

src/provider/rpc.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,16 @@ export class RPCProvider implements ProviderInterface {
130130

131131
public async getEstimateFee(
132132
invocation: Invocation,
133-
blockIdentifier: BlockIdentifier = 'pending',
134-
_invocationDetails: InvocationsDetails = {}
133+
blockIdentifier: BlockIdentifier = 'latest',
134+
invocationDetails: InvocationsDetails = {}
135135
): Promise<EstimateFeeResponse> {
136136
return this.fetchEndpoint('starknet_estimateFee', [
137137
{
138138
contract_address: invocation.contractAddress,
139139
entry_point_selector: getSelectorFromName(invocation.entrypoint),
140140
calldata: parseCalldata(invocation.calldata),
141+
signature: bigNumberishArrayToDecimalStringArray(invocation.signature || []),
142+
version: toHex(toBN(invocationDetails?.version || 0)),
141143
},
142144
blockIdentifier,
143145
]).then(this.responseParser.parseFeeEstimateResponse);
@@ -179,15 +181,26 @@ export class RPCProvider implements ProviderInterface {
179181
functionInvocation: Invocation,
180182
details: InvocationsDetails
181183
): Promise<InvokeFunctionResponse> {
184+
console.log([
185+
{
186+
contract_address: functionInvocation.contractAddress,
187+
entry_point_selector: getSelectorFromName(functionInvocation.entrypoint),
188+
calldata: parseCalldata(functionInvocation.calldata),
189+
},
190+
bigNumberishArrayToDecimalStringArray(functionInvocation.signature || []),
191+
toHex(toBN(details.maxFee || 0)),
192+
toHex(toBN(details.version || 0)),
193+
]);
194+
182195
return this.fetchEndpoint('starknet_addInvokeTransaction', [
183196
{
184197
contract_address: functionInvocation.contractAddress,
185198
entry_point_selector: getSelectorFromName(functionInvocation.entrypoint),
186199
calldata: parseCalldata(functionInvocation.calldata),
187200
},
188-
functionInvocation.signature,
189-
details.maxFee,
190-
details.version,
201+
bigNumberishArrayToDecimalStringArray(functionInvocation.signature || []),
202+
toHex(toBN(details.maxFee || 0)),
203+
toHex(toBN(details.version || 0)),
191204
]).then(this.responseParser.parseInvokeFunctionResponse);
192205
}
193206

@@ -221,6 +234,7 @@ export class RPCProvider implements ProviderInterface {
221234
try {
222235
// eslint-disable-next-line no-await-in-loop
223236
const res = await this.getTransactionReceipt(txHash);
237+
console.log({ res });
224238

225239
if (successStates.includes(res.status)) {
226240
onchain = true;
@@ -231,6 +245,7 @@ export class RPCProvider implements ProviderInterface {
231245
throw error;
232246
}
233247
} catch (error: unknown) {
248+
console.log(error);
234249
if (error instanceof Error && errorStates.includes(error.message)) {
235250
throw error;
236251
}

src/utils/responseParser/rpc.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
InvokeFunctionResponse,
1010
RPC,
1111
} from '../../types';
12+
import { toBN } from '../number';
1213
import { ResponseParser } from '.';
1314

1415
export class RPCResponseParser extends ResponseParser {
@@ -68,7 +69,7 @@ export class RPCResponseParser extends ResponseParser {
6869

6970
public parseFeeEstimateResponse(res: RPC.EstimateFeeResponse): EstimateFeeResponse {
7071
return {
71-
overall_fee: res.overall_fee,
72+
overall_fee: toBN(res.overall_fee),
7273
};
7374
}
7475

0 commit comments

Comments
 (0)