Skip to content

Commit

Permalink
feat: implement support for bigint output values (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
glevco authored Dec 17, 2024
1 parent 4edac36 commit d7eec44
Show file tree
Hide file tree
Showing 27 changed files with 346 additions and 159 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"**/*.js"
],
"env": {
"es2020": true,
"jest": true
}
}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:

strategy:
matrix:
node-version: [20.x, 22.x]
node-version: [22.x]

steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
timeout-minutes: 10
strategy:
matrix:
node-version: [20.x, 22.x]
node-version: [22.x]
steps:
# https://github.com/actions/checkout/releases/tag/v4.1.7
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
timeout-minutes: 40 # default is 360
strategy:
matrix:
node-version: [20.x, 22.x]
node-version: [22.x]
steps:
- name: Checkout
# https://github.com/actions/checkout/releases/tag/v4.1.7
Expand Down
84 changes: 83 additions & 1 deletion __tests__/__fixtures__/http-fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ export default {
tokens: ['04']
},
],
has_more: false,
},
'/v1a/push_tx': {
success: true,
Expand Down Expand Up @@ -1018,9 +1019,64 @@ export default {
'/transaction': {
success: true,
tx: {
hash: '00000008707722cde59ac9e7f4d44efbd3a5bd5f244223816ee676d328943b1b'
hash: '00000008707722cde59ac9e7f4d44efbd3a5bd5f244223816ee676d328943b1b',
version: 4,
nc_blueprint_id: '3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595',
nonce: '0',
timestamp: 1572636346,
weight: 1,
signal_bits: 0,
parents: ['1234', '5678'],
inputs: [],
outputs: [
{
value: 6400,
token_data: 0,
script: 'dqkUsmE9zshkgB58piBD7ETUV0e/NgmIrA==',
decoded: {
type: 'P2PKH',
address: 'WewDeXWyvHP7jJTs7tjLoQfoB72LLxJQqN',
timelock: null,
value: 6400,
},
token: '00',
spent_by: null,
selected_as_input: false,
},
{
value: 6400,
token_data: 0,
script: 'qRTqJUJmzEmBNvhkmDuZ4JxcMh5/ioc=',
decoded: {
type: 'MultiSig',
address: 'wgyUgNjqZ18uYr4YfE2ALW6tP5hd8MumH5',
timelock: null,
value: 6400,
},
token: '00',
spent_by: null,
selected_as_input: false,
},
],
tokens: [],
raw: '',
},
spent_outputs: {},
meta: {
hash: '5c02adea056d7b43e83171a0e2d226d564c791d583b32e9a404ef53a2e1b363a',
spent_outputs: [],
received_by: [],
children: [],
conflict_with: [],
voided_by: [],
twins: [],
accumulated_weight: 1,
score: 0,
height: 0,
min_height: 0,
feature_activation_bit_counts: null,
first_block: null,
validation: 'full',
first_block_height: 1234,
},
},
Expand All @@ -1030,6 +1086,32 @@ export default {
hash: '5c02adea056d7b43e83171a0e2d226d564c791d583b32e9a404ef53a2e1b363a',
version: 4,
nc_blueprint_id: '3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595',
nonce: '0',
timestamp: 1572636346,
weight: 1,
signal_bits: 0,
parents: ['1234', '5678'],
inputs: [],
outputs: [],
tokens: [],
raw: '',
},
spent_outputs: {},
meta: {
hash: '5c02adea056d7b43e83171a0e2d226d564c791d583b32e9a404ef53a2e1b363a',
spent_outputs: [],
received_by: [],
children: [],
conflict_with: [],
voided_by: [],
twins: [],
accumulated_weight: 1,
score: 0,
height: 0,
min_height: 0,
feature_activation_bit_counts: null,
first_block: null,
validation: 'full'
},
},
'/getmininginfo': {
Expand Down
4 changes: 2 additions & 2 deletions __tests__/atomic-swap/get-my-signatures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ describe('get-my-signatures api', () => {
fromPartialTxSpy.mockImplementation((pt, storage) => createProposal(
storage,
[
new ProposalInput(fakeTxId, 0, 10, TestUtils.addresses[0]),
new ProposalInput(fakeTxId, 0, 10n, TestUtils.addresses[0]),
],
[
new ProposalOutput(10, scriptFromAddress(TestUtils.addresses[1])),
new ProposalOutput(10n, scriptFromAddress(TestUtils.addresses[1])),
],
));

Expand Down
6 changes: 3 additions & 3 deletions __tests__/atomic-swap/tx-proposal-create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ describe('create tx-proposal api', () => {
index: 0,
token: hathorLib.constants.NATIVE_TOKEN_UID,
address: TestUtils.addresses[0],
value: 10,
authorities: 0,
value: 10n,
authorities: 0n,
timelock: null,
type: 1,
height: null,
Expand Down Expand Up @@ -238,7 +238,7 @@ describe('create tx-proposal api', () => {
index: 1,
token: fakeUid,
address: TestUtils.addresses[0],
value: 10,
value: 10n,
authorities: 0,
timelock: null,
type: 1,
Expand Down
18 changes: 5 additions & 13 deletions __tests__/decode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,36 +146,27 @@ describe('decode api', () => {
let script = new P2PKH(address);
partialTx.outputs.push(
new ProposalOutput(
10,
10n,
script.createScript(),
{ token: fakeToken1, tokenData: 1 }
)
);

address = new Address(TestUtils.addresses[1]);
script = new P2PKH(address);
partialTx.outputs.push(new ProposalOutput(20, script.createScript()));
partialTx.outputs.push(new ProposalOutput(20n, script.createScript()));

partialTx.inputs.push(
new ProposalInput(
fakeInputHash,
1,
30,
30n,
TestUtils.addresses[2],
{ token: fakeToken2, tokenData: 1 },
)
);

const txHistoryResponse = httpFixtures['/thin_wallet/address_history'];
const txHistory = txHistoryResponse.history;
const fakeTx = txHistory[0];
const fakeTxResponse = {
success: true,
tx: fakeTx,
meta: {
first_block_height: 1234,
},
};
const fakeTxResponse = httpFixtures['/transaction'];
TestUtils.httpMock.onGet('/transaction').reply(200, fakeTxResponse);

// 1 input, 2 outputs
Expand All @@ -199,6 +190,7 @@ describe('decode api', () => {
address: 'wgyUgNjqZ18uYr4YfE2ALW6tP5hd8MumH5',
type: 'MultiSig',
timelock: null,
value: 6400,
},
script: expect.any(String),
token: '00',
Expand Down
12 changes: 6 additions & 6 deletions __tests__/integration/atomic-swap.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -865,8 +865,8 @@ describe('send tx (HTR)', () => {
outputs: [expect.objectContaining({ // only 1 output
isChange: true,
token: '00',
value: 2,
authorities: 0,
value: 2n,
authorities: 0n,
decodedScript: expect.objectContaining({
address: expect.objectContaining({ base58: changeAddr }),
}),
Expand Down Expand Up @@ -905,8 +905,8 @@ describe('send tx (HTR)', () => {
outputs: [expect.objectContaining({ // only 1 output
isChange: true,
token: '00',
value: 2,
authorities: 0,
value: 2n,
authorities: 0n,
decodedScript: expect.objectContaining({
address: expect.objectContaining({
base58: expect.toBeInArray(wallet1.addresses),
Expand Down Expand Up @@ -936,8 +936,8 @@ describe('send tx (HTR)', () => {
outputs: [expect.objectContaining({
isChange: false,
token: '00',
value: 4,
authorities: 0,
value: 4n,
authorities: 0n,
decodedScript: expect.objectContaining({
address: expect.objectContaining({ base58: recvAddr }),
}),
Expand Down
16 changes: 8 additions & 8 deletions __tests__/integration/create-nft.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('create-nft routes', () => {
// Validating authority tokens
const authorityOutputs = nftTx.outputs.filter(o => TOKEN_DATA.isAuthorityToken(o.token_data));
expect(authorityOutputs.length).toBe(1);
expect(authorityOutputs[0].value).toBe(AUTHORITY_VALUE.MINT);
expect(BigInt(authorityOutputs[0].value)).toBe(AUTHORITY_VALUE.MINT);
});

it('should create nft with melt authority', async () => {
Expand All @@ -193,7 +193,7 @@ describe('create-nft routes', () => {
// Validating authority tokens
const authorityOutputs = nftTx.outputs.filter(o => TOKEN_DATA.isAuthorityToken(o.token_data));
expect(authorityOutputs.length).toBe(1);
expect(authorityOutputs[0].value).toBe(AUTHORITY_VALUE.MELT);
expect(BigInt(authorityOutputs[0].value)).toBe(AUTHORITY_VALUE.MELT);
});

it('should create nft with mint and melt authorities', async () => {
Expand All @@ -217,8 +217,8 @@ describe('create-nft routes', () => {
// Validating authority tokens
const authorityOutputs = nftTx.outputs.filter(o => TOKEN_DATA.isAuthorityToken(o.token_data));
expect(authorityOutputs.length).toBe(2);
expect(authorityOutputs.find(o => o.value === AUTHORITY_VALUE.MINT)).toBeTruthy();
expect(authorityOutputs.find(o => o.value === AUTHORITY_VALUE.MELT)).toBeTruthy();
expect(authorityOutputs.find(o => BigInt(o.value) === AUTHORITY_VALUE.MINT)).toBeTruthy();
expect(authorityOutputs.find(o => BigInt(o.value) === AUTHORITY_VALUE.MELT)).toBeTruthy();
});

it('should create the NFT and send authority outputs to the correct address', async () => {
Expand Down Expand Up @@ -248,14 +248,14 @@ describe('create-nft routes', () => {
);
expect(authorityOutputs).toHaveLength(2);
const mintOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MINT_MASK
o => BigInt(o.value) === constants.TOKEN_MINT_MASK
);
const mintP2pkh = scriptsUtils.parseP2PKH(Buffer.from(mintOutput[0].script.data), network);
// Validate that the mint output was sent to the correct address
expect(mintP2pkh.address.base58).toEqual(address0);

const meltOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MELT_MASK
o => BigInt(o.value) === constants.TOKEN_MELT_MASK
);
const meltP2pkh = scriptsUtils.parseP2PKH(Buffer.from(meltOutput[0].script.data), network);
// Validate that the melt output was sent to the correct address
Expand Down Expand Up @@ -320,14 +320,14 @@ describe('create-nft routes', () => {
);
expect(authorityOutputs).toHaveLength(2);
const mintOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MINT_MASK
o => BigInt(o.value) === constants.TOKEN_MINT_MASK
);
const mintP2pkh = scriptsUtils.parseP2PKH(Buffer.from(mintOutput[0].script.data), network);
// Validate that the mint output was sent to the correct address
expect(mintP2pkh.address.base58).toEqual(address2idx0);

const meltOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MELT_MASK
o => BigInt(o.value) === constants.TOKEN_MELT_MASK
);
const meltP2pkh = scriptsUtils.parseP2PKH(Buffer.from(meltOutput[0].script.data), network);
// Validate that the melt output was sent to the correct address
Expand Down
16 changes: 8 additions & 8 deletions __tests__/integration/create-token.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ describe('create token', () => {
o => transactionUtils.isAuthorityOutput({ token_data: o.tokenData })
);
expect(authorityOutputs.length).toBe(1);
expect(authorityOutputs[0].value).toBe(constants.TOKEN_MINT_MASK);
expect(BigInt(authorityOutputs[0].value)).toBe(constants.TOKEN_MINT_MASK);
});

it('should create token with only melt authority', async () => {
Expand All @@ -319,7 +319,7 @@ describe('create token', () => {
o => transactionUtils.isAuthorityOutput({ token_data: o.tokenData })
);
expect(authorityOutputs.length).toBe(1);
expect(authorityOutputs[0].value).toBe(constants.TOKEN_MELT_MASK);
expect(BigInt(authorityOutputs[0].value)).toBe(constants.TOKEN_MELT_MASK);
});

it('should create token with mint and melt authorities', async () => {
Expand All @@ -346,8 +346,8 @@ describe('create token', () => {
o => transactionUtils.isAuthorityOutput({ token_data: o.tokenData })
);
expect(authorityOutputs.length).toBe(2);
expect(authorityOutputs.find(o => o.value === constants.TOKEN_MINT_MASK)).toBeTruthy();
expect(authorityOutputs.find(o => o.value === constants.TOKEN_MELT_MASK)).toBeTruthy();
expect(authorityOutputs.find(o => BigInt(o.value) === constants.TOKEN_MINT_MASK)).toBeTruthy();
expect(authorityOutputs.find(o => BigInt(o.value) === constants.TOKEN_MELT_MASK)).toBeTruthy();
});

it('should create the token and send authority outputs to the correct address', async () => {
Expand Down Expand Up @@ -378,14 +378,14 @@ describe('create token', () => {
);
expect(authorityOutputs).toHaveLength(2);
const mintOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MINT_MASK
o => BigInt(o.value) === constants.TOKEN_MINT_MASK
);
const mintP2pkh = scriptsUtils.parseP2PKH(Buffer.from(mintOutput[0].script.data), network);
// Validate that the mint output was sent to the correct address
expect(mintP2pkh.address.base58).toEqual(address0);

const meltOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MELT_MASK
o => BigInt(o.value) === constants.TOKEN_MELT_MASK
);
const meltP2pkh = scriptsUtils.parseP2PKH(Buffer.from(meltOutput[0].script.data), network);
// Validate that the melt output was sent to the correct address
Expand Down Expand Up @@ -454,14 +454,14 @@ describe('create token', () => {
);
expect(authorityOutputs).toHaveLength(2);
const mintOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MINT_MASK
o => BigInt(o.value) === constants.TOKEN_MINT_MASK
);
const mintP2pkh = scriptsUtils.parseP2PKH(Buffer.from(mintOutput[0].script.data), network);
// Validate that the mint output was sent to the correct address
expect(mintP2pkh.address.base58).toEqual(address2idx0);

const meltOutput = authorityOutputs.filter(
o => o.value === constants.TOKEN_MELT_MASK
o => BigInt(o.value) === constants.TOKEN_MELT_MASK
);
const meltP2pkh = scriptsUtils.parseP2PKH(Buffer.from(meltOutput[0].script.data), network);
// Validate that the melt output was sent to the correct address
Expand Down
Loading

0 comments on commit d7eec44

Please sign in to comment.