Skip to content
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
8 changes: 7 additions & 1 deletion __tests__/integration/hathorwallet_facade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { TransactionTemplateBuilder } from '../../src/template/transaction';
import FeeHeader from '../../src/headers/fee';
import Header from '../../src/headers/base';
import CreateTokenTransaction from '../../src/models/create_token_transaction';
import WalletConnection from '../../src/new/connection';

const fakeTokenUid = '008a19f84f2ae284f19bf3d03386c878ddd15b8b0b604a3a3539aa9d714686e1';
const sampleNftData =
Expand Down Expand Up @@ -362,7 +363,12 @@ describe('start', () => {
() =>
new HathorWallet({
seed: walletData.words,
connection: { state: ConnectionState.CONNECTED },
connection: {
state: ConnectionState.CONNECTED,
getState(): ConnectionState {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you already added the getState in the connectionFile. What about use it here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mock object to test the wallet start edge cases without actually connecting.

This should be moved to the unit tests suite later: there should be no mocks on integration tests.

return ConnectionState.CONNECTED;
},
} as Partial<WalletConnection>,
password: DEFAULT_PASSWORD,
pinCode: DEFAULT_PIN_CODE,
})
Expand Down
27 changes: 19 additions & 8 deletions __tests__/new/hathorwallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
} from '../../src/constants';
import { MemoryStore, Storage } from '../../src/storage';
import Queue from '../../src/models/queue';
import { WalletType } from '../../src/types';
import { IHistoryTx, WalletType } from '../../src/types';
import { WalletWebSocketData } from '../../src/new/types';
import txApi from '../../src/api/txApi';
import * as addressUtils from '../../src/utils/address';
import walletUtils from '../../src/utils/wallet';
Expand Down Expand Up @@ -370,13 +371,17 @@ test('processTxQueue', async () => {
};

// wsTxQueue is not part of the prototype so it won't be faked on FakeHathorWallet
hWallet.wsTxQueue = new Queue();
hWallet.wsTxQueue.enqueue(1);
hWallet.wsTxQueue.enqueue(2);
hWallet.wsTxQueue.enqueue(3);
hWallet.wsTxQueue = new Queue<WalletWebSocketData>();
hWallet.wsTxQueue.enqueue({ type: 'fakeType' });
hWallet.wsTxQueue.enqueue({ type: 'fakeType' });
hWallet.wsTxQueue.enqueue({ type: 'fakeType' });

await hWallet.processTxQueue();
expect(processedTxs).toStrictEqual([1, 2, 3]);
expect(processedTxs).toStrictEqual([
{ type: 'fakeType' },
{ type: 'fakeType' },
{ type: 'fakeType' },
]);
});

test('handleWebsocketMsg', async () => {
Expand All @@ -389,8 +394,11 @@ test('handleWebsocketMsg', async () => {
});

// wsTxQueue is not part of the prototype so it won't be faked on FakeHathorWallet
hWallet.wsTxQueue = new Queue();
hWallet.wsTxQueue.enqueue({ type: 'wallet:address_history', history: [1] });
hWallet.wsTxQueue = new Queue<WalletWebSocketData>();
hWallet.wsTxQueue.enqueue({
type: 'wallet:address_history',
history: [1] as unknown as IHistoryTx,
});
Comment on lines +397 to +401
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's check if the files exist and their basic structure
echo "=== Checking file existence ==="
git ls-files | grep -E "(types\.ts|wallet\.ts|hathorwallet\.test\.ts)"

echo -e "\n=== Searching for WalletWebSocketData interface ==="
rg -n -C4 'interface WalletWebSocketData|history\?' src/new/types.ts 2>/dev/null || echo "Pattern not found or file doesn't exist in src/new/"

echo -e "\n=== Searching for websocket handling patterns ==="
rg -n -C4 'handleWebsocketMsg|onNewTx|wsTxQueue|wallet:address_history|history' src/new/wallet.ts __tests__/new/hathorwallet.test.ts 2>/dev/null || echo "Patterns not found or files don't exist"

Repository: HathorNetwork/hathor-wallet-lib

Length of output: 20607


Use the correct shape for websocket history in test fixtures instead of unsafe double-cast.

The interface defines history?: IHistoryTx as a single object, but the test passes [1] as unknown as IHistoryTx (an array). This double-cast masks a real type mismatch. The onNewTx method validates wsData.history with IHistoryTxSchema.safeParse(wsData.history), expecting a single object. Update the fixture to pass a properly typed IHistoryTx object directly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/new/hathorwallet.test.ts` around lines 397 - 401, The test uses an
unsafe double-cast to supply websocket history as an array; replace the enqueue
payload with a properly shaped IHistoryTx object so onNewTx's
IHistoryTxSchema.safeParse(wsData.history) receives the expected single-object
shape. Locate the test code setting hWallet.wsTxQueue.enqueue and change the
history property to a valid IHistoryTx instance (matching the IHistoryTx
type/fields used by IHistoryTxSchema) instead of `[1] as unknown as IHistoryTx`,
ensuring WalletWebSocketData.history conforms to IHistoryTx.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware of this. Please keep raising this point in other PRs, but the context of this specific PR is only to change the typings, and not the code or the tests.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tuliomir, understood! I appreciate the clarification on the scope. Since this PR focuses exclusively on adding type definitions without altering test or code behavior, I'll note this issue for future PRs where test fixture corrections would be in scope.

I'll continue to flag this type mismatch when reviewing related changes. Thank you for keeping me informed about the boundaries of this effort! 👍

hWallet.newTxPromise = Promise.resolve();

hWallet.state = HathorWallet.PROCESSING;
Expand Down Expand Up @@ -559,6 +567,7 @@ test('getAddressPrivKey', async () => {
getCurrentServer: jest.fn().mockReturnValue('https://fullnode'),
on: jest.fn(),
start: jest.fn(),
getCurrentNetwork: jest.fn().mockReturnValue('testnet'),
};

jest.spyOn(versionApi, 'getVersion').mockImplementation(resolve => {
Expand Down Expand Up @@ -596,6 +605,7 @@ test('signMessageWithAddress', async () => {
getCurrentServer: jest.fn().mockReturnValue('https://fullnode'),
on: jest.fn(),
start: jest.fn(),
getCurrentNetwork: jest.fn().mockReturnValue('testnet'),
};

jest.spyOn(versionApi, 'getVersion').mockImplementation(resolve => {
Expand Down Expand Up @@ -725,6 +735,7 @@ test('start', async () => {
getCurrentServer: jest.fn().mockReturnValue('https://fullnode'),
on: jest.fn(),
start: jest.fn(),
getCurrentNetwork: jest.fn().mockReturnValue('testnet'),
};

jest.spyOn(versionApi, 'getVersion').mockImplementation(resolve => {
Expand Down
6 changes: 3 additions & 3 deletions jest-integration.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ module.exports = {
},
// We need a high coverage for the HathorWallet class
'./src/new/wallet.ts': {
statements: 92,
branches: 85,
statements: 90,
branches: 83,
functions: 90,
lines: 92,
lines: 90,
Comment on lines -28 to +31
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that most of the code changed did not have tests initially, but I don't think we should lower the standards without an approval from @pedroferreira1

Maybe we can add some tests for the new error cases to increase the line coverage?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main objective for these PRs is not to change code logic, so adding more tests are not within this scope here, precisely for us to feel safer when having to change settings like this one.

With the amount of lines that I'm changing, those coverage bars are sure to be changed. I agree we should wait for Pedro on this one.

},
},
};
7 changes: 7 additions & 0 deletions src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ abstract class Connection extends EventEmitter {
this.emit('state', state);
}

/**
* Get current connection state
*/
getState(): ConnectionState {
return this.state;
}
Comment on lines +118 to +120
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All code used to access state directly up until now. With Typescript this direct access is no longer permitted, so a getter method was created.


/**
* Connect to the server and start emitting events.
* */
Expand Down
4 changes: 2 additions & 2 deletions src/new/sendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function isDataOutput(output: ISendOutput): output is ISendDataOutput {
}

export interface ISendTokenOutput {
type: OutputType.P2PKH | OutputType.P2SH;
type: OutputType.P2PKH | OutputType.P2SH; // XXX: This type is ignored in the only place it is used
address: string;
value: OutputValueType;
token: string;
Expand Down Expand Up @@ -506,7 +506,7 @@ export default class SendTransaction extends EventEmitter {
// This just returns if the transaction is not a CREATE_TOKEN_TX
await addCreatedTokenFromTx(transaction as CreateTokenTransaction, storage);
// Add new transaction to the wallet's storage.
wallet.enqueueOnNewTx({ history: historyTx });
wallet.enqueueOnNewTx({ type: '', history: historyTx }); // FIXME: Add a type here
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type expected from the fullnode is 'wallet:address_history'.

But I think we can change it to lib:pushed-tx to mark it as a wallet-lib generated event and that it came from pushing a transaction to the network.
This is because we want to update the balance, mark utxos as spent as soon as the tx is sent, this makes it possible to send another transaction (and choose utxos for this new tx safely) faster.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since i'm just adding types and not changing code, I'd prefer leaving the type as empty and the fixme command.

The correct behavior here would be to enqueueOnNewTx reject the missing type, and both those elements reinforce that it needs attention. There are many other similar "FixMe" clauses on those fullnode typings prs with that intention.

})(this.wallet, this.storage, this.transaction);
}
this.emit('send-tx-success', this.transaction);
Expand Down
Loading
Loading