Repository: 0xs34n/starknet.js (ts)

Issue:
Support `get_block_traces`
Cairo version v0.9.1 introduces `get_block_traces` endpoint, which given a block identifier, returns the traces of all the transactions within that block.

This should be supported by both `SequencerProvider` and `RpcProvider` from the #243.

I'm not sure if this should be a new method or if the `getBlock` should receive an option to return traces.

Pull request description:
Feat: support get_block_traces in sequencer provider
## Motivation and Resolution

Close #253 
Add support for `get_block_traces` endpoint in Sequencer Provider. 

## Checklist:

- [x] Performed a self-review of the code
- [x] Rebased to the last commit of the target branch (or merged it into my branch)
- [x] Linked the issues which this PR resolves
- [x] Documented the changes
- [x] Updated the docs (www)
- [x] Updated the tests
- [x] All tests are passing


Patch:
diff --git a/src/provider/sequencer.ts b/src/provider/sequencer.ts
index 3c123457..24f47750 100644
--- a/src/provider/sequencer.ts
+++ b/src/provider/sequencer.ts
@@ -597,4 +597,12 @@ export class SequencerProvider implements ProviderInterface {
       this.responseParser.parseGetStateUpdateResponse
     );
   }
+
+  // consider adding an optional trace retrieval parameter to the getBlock method
+  public async getBlockTraces(
+    blockIdentifier: BlockIdentifier = this.blockIdentifier
+  ): Promise<Sequencer.BlockTransactionTracesResponse> {
+    const args = new Block(blockIdentifier).sequencerIdentifier;
+    return this.fetchEndpoint('get_block_traces', { ...args });
+  }
 }
diff --git a/src/types/api/sequencer.ts b/src/types/api/sequencer.ts
index ae712dbd..9fb08c61 100644
--- a/src/types/api/sequencer.ts
+++ b/src/types/api/sequencer.ts
@@ -282,6 +282,10 @@ export namespace Sequencer {
 
   export type EstimateFeeResponseBulk = AllowArray<EstimateFeeResponse>;
 
+  export type BlockTransactionTracesResponse = {
+    traces: Array<TransactionTraceResponse & { transaction_hash: string }>;
+  };
+
   export type StateUpdateResponse = {
     block_hash: string;
     new_root: string;
@@ -431,5 +435,13 @@ export namespace Sequencer {
       REQUEST: EstimateFeeRequestBulk;
       RESPONSE: EstimateFeeResponseBulk;
     };
+    get_block_traces: {
+      QUERY: {
+        blockHash?: string;
+        blockNumber?: BlockNumber;
+      };
+      REQUEST: never;
+      RESPONSE: BlockTransactionTracesResponse;
+    };
   };
 }
diff --git a/www/docs/API/Provider/sequencerProvider.md b/www/docs/API/Provider/sequencerProvider.md
index e754ee3f..f9ae551d 100644
--- a/www/docs/API/Provider/sequencerProvider.md
+++ b/www/docs/API/Provider/sequencerProvider.md
@@ -156,3 +156,46 @@ Gets the transaction trace from a tx hash.
   };
 }
 ```
+
+---
+
+### getBlockTraces()
+
+provider.**getBlockTraces**(blockIdentifier) => _Promise < BlockTransactionTracesResponse >_
+
+Gets the transaction traces of an entire block
+
+###### _BlockTransactionTracesResponse_
+
+```typescript
+
+{
+    traces: Array<TransactionTraceResponse & { transaction_hash: string }>;
+}
+
+{
+  TransactionTraceResponse: {
+    validate_invocation?: FunctionInvocation;
+    function_invocation?: FunctionInvocation;
+    fee_transfer_invocation?: FunctionInvocation;
+    signature: Signature;
+  };
+
+  FunctionInvocation: {
+    caller_address: string;
+    contract_address: string;
+    calldata: {
+      [inputName: string]: string | string[] | { type: 'struct'; [k: string]: BigNumberish };
+    };
+    call_type?: string;
+    class_hash?: string;
+    selector?: string;
+    entry_point_type?: EntryPointType;
+    result: Array<any>;
+    execution_resources: ExecutionResources;
+    internal_calls: Array<FunctionInvocation>;
+    events: Array<any>;
+    messages: Array<any>;
+  };
+}
+```


Test patch:
diff --git a/__tests__/sequencerProvider.test.ts b/__tests__/sequencerProvider.test.ts
index 96739c8d..0662b3d5 100644
--- a/__tests__/sequencerProvider.test.ts
+++ b/__tests__/sequencerProvider.test.ts
@@ -1,4 +1,11 @@
-import { Contract, Provider, SequencerProvider, stark } from '../src';
+import {
+  BlockNumber,
+  Contract,
+  GetBlockResponse,
+  Provider,
+  SequencerProvider,
+  stark,
+} from '../src';
 import { toBN } from '../src/utils/number';
 import { encodeShortString } from '../src/utils/shortString';
 import {
@@ -16,6 +23,15 @@ describeIfSequencer('SequencerProvider', () => {
   const account = getTestAccount(sequencerProvider);
   let customSequencerProvider: Provider;
   let exampleContractAddress: string;
+  let exampleBlock: GetBlockResponse;
+  let exampleBlockNumber: BlockNumber;
+  let exampleBlockHash: string;
+
+  beforeAll(async () => {
+    exampleBlock = await sequencerProvider.getBlock('latest');
+    exampleBlockHash = exampleBlock.block_hash;
+    exampleBlockNumber = exampleBlock.block_number;
+  });
 
   describe('Gateway specific methods', () => {
     let exampleTransactionHash: string;
@@ -123,4 +139,26 @@ describeIfSequencer('SequencerProvider', () => {
       expect(res).toStrictEqual(result.balance);
     });
   });
+
+  describe('getBlockTraces', () => {
+    test(`getBlockTraces(blockHash=${exampleBlockHash}, blockNumber=undefined)`, async () => {
+      const blockTraces = await sequencerProvider.getBlockTraces(exampleBlockHash);
+      expect(blockTraces).toHaveProperty('traces');
+      expect(blockTraces.traces[0]).toHaveProperty('validate_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('function_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('fee_transfer_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('signature');
+      expect(blockTraces.traces[0]).toHaveProperty('transaction_hash');
+    });
+
+    test(`getBlockTraces(blockHash=undefined, blockNumber=${exampleBlockNumber})`, async () => {
+      const blockTraces = await sequencerProvider.getBlockTraces(exampleBlockNumber);
+      expect(blockTraces).toHaveProperty('traces');
+      expect(blockTraces.traces[0]).toHaveProperty('validate_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('function_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('fee_transfer_invocation');
+      expect(blockTraces.traces[0]).toHaveProperty('signature');
+      expect(blockTraces.traces[0]).toHaveProperty('transaction_hash');
+    });
+  });
 });