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

release: v1.14.1 #792

Merged
merged 2 commits into from
Oct 14, 2024
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: 6 additions & 2 deletions __tests__/integration/hathorwallet_facade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,9 @@ describe('mintTokens', () => {
const { hash: tokenUid } = await createTokenHelper(hWallet, 'Token to Mint', 'TMINT', 100);

// Should not mint more tokens than the HTR funds allow
await expect(hWallet.mintTokens(tokenUid, 9000)).rejects.toThrow('HTR tokens');
await expect(hWallet.mintTokens(tokenUid, 9000)).rejects.toThrow(
/^Not enough HTR tokens for deposit: 90 required, \d+ available$/
);

// Minting more of the tokens
const mintAmount = getRandomInt(100, 50);
Expand Down Expand Up @@ -2183,7 +2185,9 @@ describe('meltTokens', () => {
const { hash: tokenUid } = await createTokenHelper(hWallet, 'Token to Melt', 'TMELT', 500);

// Should not melt more than there is available
await expect(hWallet.meltTokens(tokenUid, 999)).rejects.toThrow('Not enough tokens to melt');
await expect(hWallet.meltTokens(tokenUid, 999)).rejects.toThrow(
'Not enough tokens to melt: 999 requested, 500 available'
);

// Melting some tokens
const meltAmount = getRandomInt(99, 10);
Expand Down
82 changes: 82 additions & 0 deletions __tests__/new/hathorwallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,42 @@ describe('prepare transactions without signature', () => {
);
});

test('prepareMintTokensData with over available tokens amount', async () => {
const amountAvailable = 1;
const amountOverAvailable = 1000;
// fake stuff to support the test
const fakeMintAuthority = [
{
txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f',
index: 0,
value: 1,
token: '01',
address: fakeAddress.base58,
authorities: TOKEN_MINT_MASK,
timelock: null,
locked: false,
},
];

// wallet and mocks
const hWallet = new FakeHathorWallet();
hWallet.storage = getStorage({
readOnly: false,
currentAddress: fakeAddress.base58,
selectUtxos: generateSelectUtxos({ ...fakeTokenToDepositUtxo, value: amountAvailable }),
});
jest.spyOn(hWallet, 'getMintAuthority').mockReturnValue(fakeMintAuthority);

// prepare mint
await expect(
hWallet.prepareMintTokensData('01', amountOverAvailable, {
address: fakeAddress.base58,
pinCode: '1234',
signTx: false, // skip the signature
})
).rejects.toThrow('Not enough HTR tokens for deposit: 10 required, 1 available');
});

test('prepareMeltTokensData', async () => {
// fake stuff to support the test
const fakeTokenToMeltUtxo = {
Expand Down Expand Up @@ -1279,6 +1315,52 @@ describe('prepare transactions without signature', () => {
])
);
});

test('prepareMeltTokensData with over available tokens amount', async () => {
const availableToken = 10;
const amountOverAvailable = 100;
// fake stuff to support the test
const fakeTokenToMeltUtxo = {
txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f',
index: 0,
value: availableToken,
token: '01',
address: fakeAddress.base58,
authorities: 0,
timelock: null,
locked: false,
};
const fakeMeltAuthority = [
{
txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f',
index: 0,
value: 1,
token: '01',
address: fakeAddress.base58,
authorities: TOKEN_MELT_MASK,
timelock: null,
locked: false,
},
];

// wallet and mocks
const hWallet = new FakeHathorWallet();
hWallet.storage = getStorage({
readOnly: false,
currentAddress: fakeAddress.base58,
selectUtxos: generateSelectUtxos(fakeTokenToMeltUtxo),
});
jest.spyOn(hWallet, 'getMeltAuthority').mockReturnValue(fakeMeltAuthority);

// prepare melt
await expect(
hWallet.prepareMeltTokensData('01', amountOverAvailable, {
address: fakeAddress.base58,
pinCode: '1234',
signTx: false, // skip the signature
})
).rejects.toThrow('Not enough tokens to melt: 100 requested, 10 available');
});
});

test('setExternalTxSigningMethod', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export type UtxoSelectionAlgorithm = (
storage: IStorage,
token: string,
amount: OutputValueType
) => Promise<{ utxos: IUtxo[]; amount: OutputValueType }>;
) => Promise<{ utxos: IUtxo[]; amount: OutputValueType; available?: OutputValueType }>;

export interface IUtxoSelectionOptions {
token?: string;
Expand Down
6 changes: 4 additions & 2 deletions src/utils/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,9 @@ const tokens = {
}

if (foundAmount < depositAmount) {
const availableAmount = selectedUtxos.available ?? 0;
throw new InsufficientFundsError(
`Not enough HTR tokens for deposit: ${depositAmount} required, ${foundAmount} available`
`Not enough HTR tokens for deposit: ${depositAmount} required, ${availableAmount} available`
);
}

Expand Down Expand Up @@ -510,8 +511,9 @@ const tokens = {
}

if (foundAmount < amount) {
const availableAmount = selectedUtxos.available ?? 0;
throw new InsufficientFundsError(
`Not enough tokens to melt: ${amount} requested, ${foundAmount} available`
`Not enough tokens to melt: ${amount} requested, ${availableAmount} available`
);
}

Expand Down
10 changes: 6 additions & 4 deletions src/utils/utxo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ export function getAlgorithmFromEnum(algorithm: UtxoSelection): UtxoSelectionAlg
* @param {IStorage} storage The wallet storage to select the utxos
* @param {string} token The token uid to select the utxos
* @param {OutputValueType} amount The target amount of tokens required
* @returns {Promise<{ utxos: IUtxo[], utxosAmount: OutputValueType}>
* @returns {Promise<{ utxos: IUtxo[], amount: OutputValueType, available?: OutputValueType }>}
*/
export async function fastUtxoSelection(
storage: IStorage,
token: string,
amount: OutputValueType
): Promise<{ utxos: IUtxo[]; amount: OutputValueType }> {
): Promise<{ utxos: IUtxo[]; amount: OutputValueType; available?: OutputValueType }> {
const utxos: IUtxo[] = [];
let utxosAmount = 0;

Expand All @@ -72,6 +72,7 @@ export async function fastUtxoSelection(
return {
utxos: [],
amount: 0,
available: utxosAmount,
};
}

Expand All @@ -87,13 +88,13 @@ export async function fastUtxoSelection(
* @param {IStorage} storage The wallet storage to select the utxos
* @param {string} token The token uid to select the utxos
* @param {OutputValueType} amount The target amount of tokens required
* @returns {Promise<{ utxos: IUtxo[], utxosAmount: OutputValueType}>
* @returns {Promise<{ utxos: IUtxo[], amount: OutputValueType, available?: OutputValueType }>}
*/
export async function bestUtxoSelection(
storage: IStorage,
token: string,
amount: OutputValueType
): Promise<{ utxos: IUtxo[]; amount: OutputValueType }> {
): Promise<{ utxos: IUtxo[]; amount: OutputValueType; available?: OutputValueType }> {
const utxos: IUtxo[] = [];
let utxosAmount = 0;
let selectedUtxo: IUtxo | null = null;
Expand Down Expand Up @@ -150,6 +151,7 @@ export async function bestUtxoSelection(
return {
utxos: [],
amount: 0,
available: utxosAmount,
};
}
// We need to ensure we use the smallest number of utxos and avoid hitting the maximum number of inputs
Expand Down
Loading