Skip to content

Commit e09319f

Browse files
committed
feat: fee tokens in tx template
fee token tests using tx template
1 parent 578d9ba commit e09319f

File tree

12 files changed

+734
-122
lines changed

12 files changed

+734
-122
lines changed

__tests__/integration/hathorwallet_facade.test.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,15 +2342,9 @@ describe('mintTokens', () => {
23422342
const expectedAmount5 = expectedAmount4 + 100n;
23432343
expect(tokenBalance5[0]).toHaveProperty('balance.unlocked', expectedAmount5);
23442344

2345-
const dataOutput5 = mintResponse5.outputs.filter(
2346-
o => o.getType(hWallet.getNetworkObject()) === 'data'
2347-
);
2348-
expect(dataOutput5).toHaveLength(1);
2349-
expect(dataOutput5[0]).toHaveProperty('value', 1n);
2350-
expect(dataOutput5[0]).toHaveProperty(
2351-
'script',
2352-
Buffer.from([6, 102, 111, 111, 98, 97, 114, 172])
2353-
);
2345+
const dataOutput5 = mintResponse5.outputs[mintResponse5.outputs.length - 1];
2346+
expect(dataOutput5).toHaveProperty('value', 1n);
2347+
expect(dataOutput5).toHaveProperty('script', Buffer.from([6, 102, 111, 111, 98, 97, 114, 172]));
23542348

23552349
const mintResponse6 = await hWallet.mintTokens(tokenUid, 100n, {
23562350
unshiftData: true,

__tests__/integration/template/transaction/template.test.ts

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import transactionUtils from '../../../../src/utils/transaction';
1212
import { TransactionTemplateBuilder } from '../../../../src/template/transaction/builder';
1313
import { WalletTxTemplateInterpreter } from '../../../../src/template/transaction/interpreter';
1414
import { TOKEN_AUTHORITY_MASK, TOKEN_MELT_MASK, TOKEN_MINT_MASK } from '../../../../src/constants';
15+
import { TokenVersion } from '../../../../src/types';
1516

1617
const DEBUG = true;
1718

@@ -438,3 +439,159 @@ describe('Template execution', () => {
438439
);
439440
});
440441
});
442+
443+
describe.skip('Template execution with fee tokens', () => {
444+
let hWallet: HathorWallet;
445+
let interpreter: WalletTxTemplateInterpreter;
446+
let tokenUid: string;
447+
448+
beforeAll(async () => {
449+
hWallet = await generateWalletHelper(null);
450+
interpreter = new WalletTxTemplateInterpreter(hWallet);
451+
const address = await hWallet.getAddressAtIndex(0);
452+
await GenesisWalletHelper.injectFunds(hWallet, address, 10n, {});
453+
});
454+
455+
afterAll(async () => {
456+
await hWallet.stop();
457+
await stopAllWallets();
458+
await GenesisWalletHelper.clearListeners();
459+
});
460+
461+
it('should be not able to create a custom fee token without providing a fee header', async () => {
462+
const template = new TransactionTemplateBuilder()
463+
.addConfigAction({
464+
createToken: true,
465+
tokenName: 'Tmpl Test Fee Token 01',
466+
tokenSymbol: 'TTT01',
467+
tokenVersion: TokenVersion.FEE,
468+
})
469+
.addSetVarAction({ name: 'addr', call: { method: 'get_wallet_address' } })
470+
.addUtxoSelect({ fill: 5 })
471+
.addTokenOutput({ address: '{addr}', amount: 100, useCreatedToken: true })
472+
.addTokenOutput({ address: '{addr}', amount: 100, useCreatedToken: true })
473+
.addTokenOutput({ address: '{addr}', amount: 100, useCreatedToken: true })
474+
.addTokenOutput({ address: '{addr}', amount: 100, useCreatedToken: true })
475+
.build();
476+
477+
const tx = await interpreter.build(template, DEBUG);
478+
479+
expect(tx.outputs).toHaveLength(2);
480+
481+
// HTR change
482+
expect(tx.outputs[0].tokenData).toBe(0);
483+
expect(tx.outputs[0].value).toBe(9n);
484+
485+
// Created token
486+
expect(tx.outputs[1].tokenData).toBe(1);
487+
expect(tx.outputs[1].value).toBe(9999999n);
488+
489+
// Not have a fee header
490+
expect(tx.headers).toHaveLength(0);
491+
492+
// after validate send the tx to the mining service
493+
await transactionUtils.signTransaction(tx, hWallet.storage, DEFAULT_PIN_CODE);
494+
tx.prepareToSend();
495+
const sendTx = new SendTransaction({ storage: hWallet.storage, transaction: tx });
496+
await sendTx.runFromMining();
497+
expect(tx.hash).not.toBeNull();
498+
if (tx.hash === null) {
499+
throw new Error('Transaction does not have a hash');
500+
}
501+
await waitForTxReceived(hWallet, tx.hash, undefined);
502+
});
503+
504+
it('should be able to create a custom fee token providing a fee header', async () => {
505+
const template = new TransactionTemplateBuilder()
506+
.addConfigAction({
507+
createToken: true,
508+
tokenName: 'Tmpl Test Fee Token 01',
509+
tokenSymbol: 'TTT01',
510+
tokenVersion: TokenVersion.FEE,
511+
})
512+
.addSetVarAction({ name: 'addr', call: { method: 'get_wallet_address' } })
513+
.addUtxoSelect({ fill: 1 })
514+
.addTokenOutput({ address: '{addr}', amount: 9999999, useCreatedToken: true })
515+
.addFee({ amount: 1 })
516+
.build();
517+
518+
const tx = await interpreter.build(template, DEBUG);
519+
520+
expect(tx.outputs).toHaveLength(2);
521+
522+
// HTR change
523+
expect(tx.outputs[0].tokenData).toBe(0);
524+
expect(tx.outputs[0].value).toBe(9n);
525+
526+
// Created token
527+
expect(tx.outputs[1].tokenData).toBe(1);
528+
expect(tx.outputs[1].value).toBe(9999999n);
529+
530+
// Have a fee header
531+
expect(tx.headers).toHaveLength(1);
532+
expect(tx.getFeeHeader()).not.toBeNull();
533+
expect(tx.getFeeHeader()!.entries).toHaveLength(1);
534+
expect(tx.getFeeHeader()!.entries[0].tokenIndex).toBe(0);
535+
expect(tx.getFeeHeader()!.entries[0].amount).toBe(1n);
536+
537+
// after validate send the tx to the mining service
538+
await transactionUtils.signTransaction(tx, hWallet.storage, DEFAULT_PIN_CODE);
539+
tx.prepareToSend();
540+
const sendTx = new SendTransaction({ storage: hWallet.storage, transaction: tx });
541+
await sendTx.runFromMining();
542+
expect(tx.hash).not.toBeNull();
543+
if (tx.hash === null) {
544+
throw new Error('Transaction does not have a hash');
545+
}
546+
tokenUid = tx.hash;
547+
await waitForTxReceived(hWallet, tx.hash, undefined);
548+
});
549+
it('should be able to complete the fees of a transaction', async () => {
550+
const template = new TransactionTemplateBuilder()
551+
.addConfigAction({
552+
createToken: true,
553+
tokenName: 'Tmpl Test Fee Token 01',
554+
tokenSymbol: 'TTT01',
555+
tokenVersion: TokenVersion.FEE,
556+
})
557+
.addSetVarAction({ name: 'addr', call: { method: 'get_wallet_address' } })
558+
.addUtxoSelect({ fill: 5 })
559+
.addTokenOutput({ address: '{addr}', amount: 9999999, useCreatedToken: true })
560+
.addTokenOutput({ address: '{addr}', amount: 9999999, useCreatedToken: true })
561+
.addTokenOutput({ address: '{addr}', amount: 9999999, useCreatedToken: true })
562+
.addTokenOutput({ address: '{addr}', amount: 9999999, useCreatedToken: true })
563+
.addCompleteAction({ calculateFee: true, token: '00' })
564+
.build();
565+
566+
const tx = await interpreter.build(template, DEBUG);
567+
568+
expect(tx.outputs).toHaveLength(6);
569+
570+
// HTR change
571+
expect(tx.outputs[0].tokenData).toBe(0);
572+
expect(tx.outputs[0].value).toBe(9n);
573+
574+
// Created token
575+
expect(tx.outputs[1].tokenData).toBe(1);
576+
expect(tx.outputs[1].value).toBe(9999999n);
577+
578+
// Have a fee header
579+
expect(tx.headers).toHaveLength(1);
580+
expect(tx.getFeeHeader()).not.toBeNull();
581+
expect(tx.getFeeHeader()!.entries).toHaveLength(1);
582+
expect(tx.getFeeHeader()!.entries[0].tokenIndex).toBe(0);
583+
expect(tx.getFeeHeader()!.entries[0].amount).toBe(4n);
584+
585+
// after validate send the tx to the mining service
586+
await transactionUtils.signTransaction(tx, hWallet.storage, DEFAULT_PIN_CODE);
587+
tx.prepareToSend();
588+
const sendTx = new SendTransaction({ storage: hWallet.storage, transaction: tx });
589+
await sendTx.runFromMining();
590+
expect(tx.hash).not.toBeNull();
591+
if (tx.hash === null) {
592+
throw new Error('Transaction does not have a hash');
593+
}
594+
595+
await waitForTxReceived(hWallet, tx.hash, undefined);
596+
});
597+
});

0 commit comments

Comments
 (0)