Skip to content

Commit

Permalink
fix: test getBlock('latest')
Browse files Browse the repository at this point in the history
  • Loading branch information
tabaktoni committed Aug 29, 2022
1 parent 1097d7c commit 2c92f79
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ npm-debug.log
.env
.DS_Store
.eslintcache
.vscode
coverage
yarn.lock
10 changes: 10 additions & 0 deletions __tests__/defaultProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ describe('defaultProvider', () => {
test(`getBlock(blockHash=${exampleBlockHash}, blockNumber=undefined)`, () => {
return expect(testProvider.getBlock(exampleBlockHash)).resolves.not.toThrow();
});
test('getBlock(blockIdentifier=latest)', async () => {
expect(exampleBlock).not.toBeNull();

const { block_number, timestamp } = exampleBlock;

expect(typeof block_number).toEqual('number');

return expect(typeof timestamp).toEqual('number');
});

test('getBlock() -> { blockNumber }', async () => {
const block = await testProvider.getBlock();
return expect(block).toHaveProperty('block_number');
Expand Down
17 changes: 1 addition & 16 deletions __tests__/rpcProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GetBlockResponse, RpcProvider } from '../src';
import { RpcProvider } from '../src';
import { describeIfRpc, getTestProvider } from './fixtures';

describeIfRpc('RPCProvider', () => {
Expand All @@ -14,19 +14,4 @@ describeIfRpc('RPCProvider', () => {
expect(chainId).toBe('0x534e5f474f45524c49');
});
});

describe('divergence from Provider methods', () => {
let exampleBlock: GetBlockResponse;

beforeAll(async () => {
exampleBlock = await rpcProvider.getBlock('latest');
});

test('getBlock(blockIdentifier=latest)', async () => {
expect(exampleBlock).not.toBeNull();
const { block_number, accepted_time } = exampleBlock;
expect(typeof block_number).toEqual('number');
return expect(typeof accepted_time).toEqual('number');
});
});
});
19 changes: 1 addition & 18 deletions __tests__/sequencerProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Contract, GetBlockResponse, Provider, SequencerProvider, stark } from '../src';
import { Contract, Provider, SequencerProvider, stark } from '../src';
import { toBN } from '../src/utils/number';
import {
compiledErc20,
Expand Down Expand Up @@ -74,20 +74,3 @@ describeIfSequencer('SequencerProvider', () => {
});
});
});

describe('divergence from Provider methods', () => {
let exampleBlock: GetBlockResponse;
let sequencerProvider: SequencerProvider;

beforeAll(async () => {
sequencerProvider = getTestProvider() as SequencerProvider;
exampleBlock = await sequencerProvider.getBlock('latest');
});

test('getBlock(blockIdentifier=latest)', async () => {
expect(exampleBlock).not.toBeNull();
const { block_number, accepted_time } = exampleBlock;
expect(typeof block_number).toEqual('number');
return expect(typeof accepted_time).toEqual('number');
});
});
17 changes: 12 additions & 5 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,27 @@ export class RpcProvider implements ProviderInterface {
return this.fetchEndpoint('starknet_chainId');
}

// Common Interface
public async getBlock(blockIdentifier: BlockIdentifier = 'pending'): Promise<GetBlockResponse> {
return this.getBlockWithTxHashes(blockIdentifier).then(
this.responseParser.parseGetBlockResponse
);
}

public async getBlockWithTxHashes(
blockIdentifier: BlockIdentifier = 'pending'
): Promise<RPC.getBlockWithTxHashesResponse> {
const blockIdentifierGetter = new BlockIdentifierClass(blockIdentifier);
return this.fetchEndpoint('starknet_getBlockWithTxHashes', [
blockIdentifierGetter.getIdentifier(),
]).then(this.responseParser.parseGetBlockResponse);
]);
}

public async getBlockWithTxs(
blockIdentifier: BlockIdentifier = 'pending'
): Promise<GetBlockResponse> {
): Promise<RPC.getBlockWithTxs> {
const blockIdentifierGetter = new BlockIdentifierClass(blockIdentifier);
return this.fetchEndpoint('starknet_getBlockWithTxs', [
blockIdentifierGetter.getIdentifier(),
]).then(this.responseParser.parseGetBlockResponse);
return this.fetchEndpoint('starknet_getBlockWithTxs', [blockIdentifierGetter.getIdentifier()]);
}

public async getNonce(contractAddress: string): Promise<any> {
Expand Down
148 changes: 148 additions & 0 deletions src/types/api/openrpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* Starknet RPC version 0.1.0
* starknet_api_openrpc version 0.31.0
*
* TypeScript Representation of OpenRpc protocol types
*/

/**
* "type": "string",
* "title": "Field element",
* "$comment": "A field element, represented as a string of hex digits",
* "description": "A field element. Represented as up to 63 hex digits and leading 4 bits zeroed.",
* "pattern": "^0x0[a-fA-F0-9]{1,63}$"
*/
type FELT = string;
type BLOCK_NUMBER = number;
type BLOCK_HASH = FELT;
type TXN_HASH = FELT;
type TXN_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
type TXN_TYPE = 'DECLARE' | 'DEPLOY' | 'INVOKE' | 'L1_HANDLER';
type MSG_TO_L1 = {
to_address: FELT;
payload: Array<FELT>;
};
type EVENT = {
from_address: FELT;
keys: Array<FELT>;
data: Array<FELT>;
};
type COMMON_RECEIPT_PROPERTIES = {
transaction_hash: TXN_HASH;
actual_fee: FELT;
status: TXN_STATUS;
block_hash: BLOCK_HASH;
block_number: BLOCK_NUMBER;
type?: TXN_TYPE;
};
type INVOKE_TXN_RECEIPT_PROPERTIES = {
messages_sent: MSG_TO_L1;
events: EVENT;
};
type PENDING_COMMON_RECEIPT_PROPERTIES = {
transaction_hash: TXN_HASH;
actual_fee: FELT;
type?: TXN_TYPE;
};
type INVOKE_TXN_RECEIPT = COMMON_RECEIPT_PROPERTIES & INVOKE_TXN_RECEIPT_PROPERTIES;
type L1_HANDLER_TXN_RECEIPT = COMMON_RECEIPT_PROPERTIES;
type DECLARE_TXN_RECEIPT = COMMON_RECEIPT_PROPERTIES;
type DEPLOY_TXN_RECEIPT = COMMON_RECEIPT_PROPERTIES;
type PENDING_INVOKE_TXN_RECEIPT = PENDING_COMMON_RECEIPT_PROPERTIES & INVOKE_TXN_RECEIPT_PROPERTIES;
type PENDING_TXN_RECEIPT = PENDING_INVOKE_TXN_RECEIPT | PENDING_COMMON_RECEIPT_PROPERTIES;
type TXN_RECEIPT =
| INVOKE_TXN_RECEIPT
| L1_HANDLER_TXN_RECEIPT
| DECLARE_TXN_RECEIPT
| DEPLOY_TXN_RECEIPT
| PENDING_TXN_RECEIPT;

export namespace RPC_1 {
export type GetTransactionReceiptResponse = TXN_RECEIPT;

export type Methods = {
starknet_getTransactionReceipt: {
QUERY: never;
REQUEST: any[];
RESPONSE: GetTransactionReceiptResponse;
};
};
}

// starknet_getBlockWithTxHashes
type BLOCK_HEADER = {
block_hash: BLOCK_HASH;
parent_hash: BLOCK_HASH;
block_number: BLOCK_NUMBER;
new_root: FELT;
timestamp: number;
sequencer_address: FELT;
};
type BLOCK_BODY_WITH_TX_HASHES = {
transactions: Array<TXN_HASH>;
};
type BLOCK_WITH_TX_HASHES = {
status: TXN_STATUS;
} & BLOCK_HEADER &
BLOCK_BODY_WITH_TX_HASHES;
type PENDING_BLOCK_WITH_TX_HASHES = BLOCK_BODY_WITH_TX_HASHES & {
timestamp: number;
sequencer_address: FELT;
parent_hash: BLOCK_HASH;
};

// starknet_getBlockWithTx
type BLOCK_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
/**
* "title": "An integer number in hex format (0x...)",
* "pattern": "^0x[a-fA-F0-9]+$"
*/
type NUM_AS_HEX = string;
type SIGNATURE = Array<FELT>;
type COMMON_TXN_PROPERTIES = {
transaction_hash: TXN_HASH;
max_fee: FELT;
version: NUM_AS_HEX;
signature: SIGNATURE;
nonce: FELT;
type: TXN_TYPE;
};
type ADDRESS = FELT;
type FUNCTION_CALL = {
contract_address: ADDRESS;
entry_point_selector: FELT;
calldata: Array<FELT>;
};
type INVOKE_TXN = COMMON_TXN_PROPERTIES & FUNCTION_CALL;
type DECLARE_TXN = COMMON_TXN_PROPERTIES & {
class_hash: FELT;
sender_address: ADDRESS;
};
type DEPLOY_TXN = {
transaction_hash: TXN_HASH;
class_hash: FELT;
version: NUM_AS_HEX;
type: TXN_TYPE;
contract_address: FELT;
contract_address_salt: FELT;
constructor_calldata: Array<FELT>;
};
type TXN = INVOKE_TXN | DECLARE_TXN | DEPLOY_TXN;
type BLOCK_BODY_WITH_TXS = {
transactions: Array<TXN>;
};
type BLOCK_WITH_TXS = {
status: BLOCK_STATUS;
} & BLOCK_HEADER &
BLOCK_BODY_WITH_TXS;

type PENDING_BLOCK_WITH_TXS = BLOCK_BODY_WITH_TXS & {
timestamp: number;
sequencer_address: FELT;
parent_hash: BLOCK_HASH;
};

export namespace OPENRPC {
export type getBlockWithTxHashesResponse = BLOCK_WITH_TX_HASHES | PENDING_BLOCK_WITH_TX_HASHES;
export type getBlockWithTxs = BLOCK_WITH_TXS | PENDING_BLOCK_WITH_TXS;
}
11 changes: 7 additions & 4 deletions src/types/api/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { StarknetChainId } from '../../constants';
import { BlockIdentifier } from '../../provider/utils';
import { Status } from '../lib';
import { OPENRPC } from './openrpc';

export namespace RPC {
export type Response = {
Expand Down Expand Up @@ -33,7 +34,9 @@ export namespace RPC {
gas_price: number;
};

export type GetBlockResponse = {
export type getBlockWithTxHashesResponse = OPENRPC.getBlockWithTxHashesResponse;
export type getBlockWithTxs = OPENRPC.getBlockWithTxs;
/* {
block_hash: string;
parent_hash: string;
block_number: number;
Expand All @@ -44,7 +47,7 @@ export namespace RPC {
timestamp: number;
gas_price: string;
transactions: string[];
};
}; */

export type GetCodeResponse = {
bytecode: string[];
Expand Down Expand Up @@ -147,12 +150,12 @@ export namespace RPC {
starknet_getBlockWithTxHashes: {
QUERY: never;
REQUEST: any[];
RESPONSE: GetBlockResponse;
RESPONSE: getBlockWithTxHashesResponse;
};
starknet_getBlockWithTxs: {
QUERY: never;
REQUEST: any[];
RESPONSE: GetBlockResponse;
RESPONSE: getBlockWithTxs;
};
starknet_getNonce: {
QUERY: never;
Expand Down
11 changes: 5 additions & 6 deletions src/types/provider.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
/**
* Common interface response
* Intersection (sequencer response ∩ (∪ rpc responses))
*/
import BN from 'bn.js';

import { Abi, CompressedProgram, EntryPointsByType, RawCalldata, Signature, Status } from './lib';

export interface GetBlockResponse {
accepted_time?: number;
timestamp?: number;
timestamp: number;
block_hash: string;
block_number: number;
gas_price: string;
new_root: string;
old_root?: string;
parent_hash: string;
sequencer: string;
status: Status;
transactions: Array<string>;
starknet_version?: string;
}

export interface GetCodeResponse {
Expand Down
13 changes: 9 additions & 4 deletions src/utils/responseParser/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Map RPC Response to common interface response
* Intersection (sequencer response ∩ (∪ rpc responses))
*/
import {
CallContractResponse,
DeclareContractResponse,
Expand All @@ -12,17 +16,18 @@ import { RPC } from '../../types/api';
import { toBN } from '../number';
import { ResponseParser } from '.';

type RpcGetBlockResponse = RPC.getBlockWithTxHashesResponse & {
[key: string]: any;
};

export class RPCResponseParser extends ResponseParser {
public parseGetBlockResponse(res: RPC.GetBlockResponse): GetBlockResponse {
public parseGetBlockResponse(res: RpcGetBlockResponse): GetBlockResponse {
return {
timestamp: res.timestamp,
block_hash: res.block_hash,
block_number: res.block_number,
gas_price: res.gas_price,
new_root: res.new_root,
old_root: res.old_root,
parent_hash: res.parent_hash,
sequencer: res.sequencer,
status: res.status,
transactions: res.transactions,
};
Expand Down
9 changes: 5 additions & 4 deletions src/utils/responseParser/sequencer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Map Sequencer Response to common interface response
* Intersection (sequencer response ∩ (∪ rpc responses))
*/
import {
CallContractResponse,
DeclareContractResponse,
Expand All @@ -15,14 +19,11 @@ import { ResponseParser } from '.';
export class SequencerAPIResponseParser extends ResponseParser {
public parseGetBlockResponse(res: Sequencer.GetBlockResponse): GetBlockResponse {
return {
accepted_time: res.timestamp,
timestamp: res.timestamp,
block_hash: res.block_hash,
block_number: res.block_number,
gas_price: res.gas_price,
new_root: res.state_root,
old_root: undefined,
parent_hash: res.parent_block_hash,
sequencer: res.sequencer_address,
status: res.status,
transactions: Object.values(res.transactions)
.map((value) => 'transaction_hash' in value && value.transaction_hash)
Expand Down

0 comments on commit 2c92f79

Please sign in to comment.