Skip to content

Commit

Permalink
Fix starknet transaction fields types (#22)
Browse files Browse the repository at this point in the history
* Fix starknet transaction fields types

* Update changelog
  • Loading branch information
stwiname authored Feb 26, 2025
1 parent 62f44b9 commit 101143a
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/node/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Dictionary network family being invalid (#21)
- Block finalization with devnets (#21)
- Transaction hash possibly being undefined (#22)

## [5.7.2] - 2025-02-03
### Fixed
Expand Down
24 changes: 24 additions & 0 deletions packages/node/src/starknet/api.starknet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,30 @@ describe('Api.starknet', () => {
).toEqual('object');
});

// Validate some of the variations from different transaction types
it('should correctly format a transaction', async () => {
const tx_invoke_v3 = blockData.transactions[0];

expect(tx_invoke_v3.hash).toBeDefined();
expect(tx_invoke_v3.nonce).toBeDefined();
expect(typeof tx_invoke_v3.nonce).toBe('string');
expect(tx_invoke_v3.maxFee).toBeUndefined();

const tx_invoke_v1 = blockData.transactions[5];

expect(tx_invoke_v1.hash).toBeDefined();
expect(tx_invoke_v1.maxFee).toBeDefined();
expect(typeof tx_invoke_v1.maxFee).toBe('string');

const block = await fetchBlock(1407);
// TX HASH 0x65e9ac447be4bbd256c407703c8baf9c4e862195d924a5fe3c42d138f3a0d38
const declare_tx = block.transactions[11];

expect(declare_tx).toBeDefined();
expect(declare_tx.maxFee).not.toBeDefined();
expect(declare_tx.nonce).not.toBeDefined();
});

//https://starkscan.co/tx/0x0153a20567e66728f3c4ba60913a6011b9c73db9ea4d960e959923ed5afd8a24
it('Decode logs', async () => {
const tx = blockData.transactions.find(
Expand Down
63 changes: 45 additions & 18 deletions packages/node/src/starknet/utils.starknet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,49 @@ export function formatLog(
* entryPointSelector is the method been called
*/
export function formatTransaction(
tx: Record<string, any>,
tx: {
transaction: SPEC.TXN;
receipt: SPEC.TXN_RECEIPT;
},
block:
| StarknetBlock
| (Omit<StarknetBlock, 'transactions'> & {
transactions: StarknetTransactionRaw[];
}),
txIndex: number,
): StarknetTransaction {
// Any type specific properties are cast here, this should hopefully find any types issues int he future.
const transaction = {
...tx.transaction,
hash: tx.transaction.transaction_hash,
hash: tx.receipt.transaction_hash,
type: tx.transaction.type,
version: tx.transaction.version,
nonce: tx.transaction.nonce,
maxFee: tx.transaction.max_fee,
nonce: (
tx.transaction as Exclude<
SPEC.TXN,
SPEC.DECLARE_TXN_V0 | SPEC.INVOKE_TXN_V0 | SPEC.DEPLOY_TXN
>
).nonce,
maxFee: (
tx.transaction as Exclude<
SPEC.TXN,
| SPEC.DECLARE_TXN_V3
| SPEC.INVOKE_TXN_V3
| SPEC.BROADCASTED_DECLARE_TXN_V3
| SPEC.DEPLOY_ACCOUNT_TXN_V3
| SPEC.L1_HANDLER_TXN
| SPEC.DEPLOY_TXN
>
).max_fee,
from: getTxContractAddress(tx.transaction),
calldata: tx.transaction.calldata,
calldata: (tx.transaction as SPEC.INVOKE_TXN).calldata ?? [],
blockHash: block.blockHash,
blockNumber: block.blockNumber,
blockTimestamp: block.timestamp,
transactionIndex: txIndex,
entryPointSelector: tx.transaction.entry_point_selector,
contractAddress: tx.transaction.contract_address,
entryPointSelector: (tx.transaction as SPEC.INVOKE_TXN_V0)
.entry_point_selector,
contractAddress: (tx.transaction as SPEC.INVOKE_TXN_V0).contract_address,
receipt: formatReceipt(tx.receipt),
parseCallData(): StarknetContractCall[] | undefined {
if (this.decodedCalls) {
Expand Down Expand Up @@ -166,11 +186,11 @@ export function formatTransaction(
toJSON(): string {
return JSON.stringify(omit(this, ['receipt', 'toJSON']));
},
} as StarknetTransaction;
} satisfies StarknetTransaction & { toJSON: () => string };
return transaction;
}

export function getTxContractAddress(tx: Record<string, any>): string {
export function getTxContractAddress(tx: SPEC.TXN): string {
if (tx.type === 'DEPLOY' || tx.type === 'DEPLOY_ACCOUNT') {
const result = hash.calculateContractAddressFromHash(
tx.contract_address_salt,
Expand All @@ -180,12 +200,21 @@ export function getTxContractAddress(tx: Record<string, any>): string {
);
return result;
}
return tx.contract_address ?? tx.sender_address;
return (
(tx as SPEC.INVOKE_TXN_V0 | SPEC.L1_HANDLER_TXN).contract_address ??
(
tx as Exclude<
SPEC.TXN,
| SPEC.INVOKE_TXN_V0
| SPEC.L1_HANDLER_TXN
| SPEC.DEPLOY_TXN
| SPEC.DEPLOY_ACCOUNT_TXN
>
).sender_address
);
}

export function formatReceipt(
receipt: Record<string, any>,
): TransactionReceipt {
export function formatReceipt(receipt: SPEC.TXN_RECEIPT): TransactionReceipt {
return {
...receipt,
toJSON(): string {
Expand All @@ -208,12 +237,10 @@ export function starknetBlockToHeader(
};
}

export function starknetBlockHeaderToHeader(
block: Partial<SPEC.BLOCK_HEADER>,
): Header {
export function starknetBlockHeaderToHeader(block: SPEC.BLOCK_HEADER): Header {
return {
blockHeight: block.block_number!,
blockHash: block.block_hash!,
blockHeight: block.block_number,
blockHash: block.block_hash,
parentHash: block.parent_hash,
};
}
Expand Down
2 changes: 2 additions & 0 deletions packages/types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- Transction nonce and maxFee types (#22)

## [1.0.2] - 2025-02-03
### Fixed
Expand Down
4 changes: 2 additions & 2 deletions packages/types/src/starknet/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ export interface StarknetContractCall<DA = Record<string, any>> {
export type StarknetTransaction = {
type: SPEC.TXN_TYPE;
hash: string;
nonce: number;
maxFee: number;
nonce?: Felt;
maxFee?: Felt;
// This is sender_address or contract_address
from: string;
blockHash: string;
Expand Down

0 comments on commit 101143a

Please sign in to comment.