Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix starknet transaction fields types #22

Merged
merged 2 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading