Skip to content

Commit e03869f

Browse files
committed
feat(tests): add tests for unstaking builders
Ticket: SC-2626
1 parent 5bc9b59 commit e03869f

File tree

2 files changed

+263
-0
lines changed

2 files changed

+263
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import should from 'should';
2+
import { TransactionType } from '@bitgo/sdk-core';
3+
import { coins } from '@bitgo/statics';
4+
import { TransactionBuilderFactory } from '../../src';
5+
import { BurnNftTransaction } from '../../src/lib/transaction/burnNftTransaction';
6+
import * as testData from '../resources/vet';
7+
import { BURN_NFT_METHOD_ID, STARGATE_NFT_ADDRESS } from '../../src/lib/constants';
8+
9+
describe('Vet Burn NFT Transaction', () => {
10+
const factory = new TransactionBuilderFactory(coins.get('tvet'));
11+
12+
describe('Build and Sign', () => {
13+
it('should build a burn NFT transaction', async function () {
14+
const tokenId = '123456';
15+
const txBuilder = factory.getBurnNftBuilder();
16+
17+
txBuilder.sender(testData.addresses.validAddresses[0]);
18+
txBuilder.tokenId(tokenId);
19+
txBuilder.nftContract(); // Use default address
20+
txBuilder.gas(21000);
21+
txBuilder.nonce('64248');
22+
txBuilder.blockRef('0x014ead140e77bbc1');
23+
txBuilder.expiration(64);
24+
txBuilder.gasPriceCoef(128);
25+
26+
const tx = (await txBuilder.build()) as BurnNftTransaction;
27+
28+
should.equal(tx.sender, testData.addresses.validAddresses[0]);
29+
should.equal(tx.tokenId, tokenId);
30+
should.equal(tx.contract, STARGATE_NFT_ADDRESS);
31+
should.equal(tx.gas, 21000);
32+
should.equal(tx.nonce, '64248');
33+
should.equal(tx.expiration, 64);
34+
should.equal(tx.type, TransactionType.StakingWithdraw);
35+
36+
// Verify the transaction data contains the correct method ID
37+
tx.clauses[0].data.should.startWith(BURN_NFT_METHOD_ID);
38+
39+
// Verify the transaction has the correct structure
40+
tx.clauses.length.should.equal(1);
41+
should.equal(tx.clauses[0].to, STARGATE_NFT_ADDRESS);
42+
should.equal(tx.clauses[0].value, '0x0');
43+
});
44+
45+
it('should build a burn NFT transaction with custom contract address', async function () {
46+
const tokenId = '123456';
47+
const customContractAddress = '0x1234567890123456789012345678901234567890';
48+
const txBuilder = factory.getBurnNftBuilder();
49+
50+
txBuilder.sender(testData.addresses.validAddresses[0]);
51+
txBuilder.tokenId(tokenId);
52+
txBuilder.nftContract(customContractAddress);
53+
txBuilder.gas(21000);
54+
txBuilder.nonce('64248');
55+
txBuilder.blockRef('0x014ead140e77bbc1');
56+
txBuilder.expiration(64);
57+
txBuilder.gasPriceCoef(128);
58+
59+
const tx = (await txBuilder.build()) as BurnNftTransaction;
60+
61+
should.equal(tx.contract, customContractAddress);
62+
should.equal(tx.clauses[0].to, customContractAddress);
63+
});
64+
65+
it('should deserialize and reserialize a signed burn NFT transaction', async function () {
66+
// Create a mock serialized transaction for burn NFT
67+
const tokenId = '123456';
68+
const txBuilder = factory.getBurnNftBuilder();
69+
70+
txBuilder.sender(testData.addresses.validAddresses[0]);
71+
txBuilder.tokenId(tokenId);
72+
txBuilder.nftContract();
73+
txBuilder.gas(21000);
74+
txBuilder.nonce('64248');
75+
txBuilder.blockRef('0x014ead140e77bbc1');
76+
txBuilder.expiration(64);
77+
txBuilder.gasPriceCoef(128);
78+
79+
const tx = (await txBuilder.build()) as BurnNftTransaction;
80+
const serializedTx = tx.toBroadcastFormat();
81+
82+
// Now deserialize and check
83+
const deserializedBuilder = factory.from(serializedTx);
84+
const deserializedTx = (await deserializedBuilder.build()) as BurnNftTransaction;
85+
86+
should.equal(deserializedTx.type, TransactionType.StakingWithdraw);
87+
should.equal(deserializedTx.tokenId, tokenId);
88+
should.equal(deserializedTx.contract, STARGATE_NFT_ADDRESS);
89+
});
90+
91+
it('should validate the transaction data structure', async function () {
92+
const txBuilder = factory.getBurnNftBuilder();
93+
94+
// Should throw error when building without required fields
95+
await should(txBuilder.build()).be.rejectedWith('transaction not defined');
96+
97+
txBuilder.sender(testData.addresses.validAddresses[0]);
98+
await should(txBuilder.build()).be.rejectedWith('NFT contract address is required');
99+
100+
txBuilder.nftContract();
101+
await should(txBuilder.build()).be.rejectedWith('Token ID is required');
102+
103+
// Now add the token ID and it should build successfully
104+
txBuilder.tokenId('123456');
105+
txBuilder.gas(21000);
106+
txBuilder.nonce('64248');
107+
txBuilder.blockRef('0x014ead140e77bbc1');
108+
109+
const tx = await txBuilder.build();
110+
should.exist(tx);
111+
});
112+
});
113+
114+
describe('Validation', () => {
115+
it('should fail with invalid contract address', function () {
116+
const txBuilder = factory.getBurnNftBuilder();
117+
should(() => txBuilder.nftContract('invalid-address')).throwError('Invalid address invalid-address');
118+
});
119+
120+
it('should fail with invalid token ID', async function () {
121+
const txBuilder = factory.getBurnNftBuilder();
122+
txBuilder.sender(testData.addresses.validAddresses[0]);
123+
txBuilder.nftContract();
124+
txBuilder.tokenId('');
125+
126+
await should(txBuilder.build()).be.rejectedWith('Token ID is required');
127+
});
128+
});
129+
});
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import should from 'should';
2+
import { TransactionType } from '@bitgo/sdk-core';
3+
import { coins } from '@bitgo/statics';
4+
import { TransactionBuilderFactory } from '../../src';
5+
import { ExitDelegationTransaction } from '../../src/lib/transaction/exitDelegation';
6+
import * as testData from '../resources/vet';
7+
import { EXIT_DELEGATION_METHOD_ID, STARGATE_DELEGATION_ADDRESS } from '../../src/lib/constants';
8+
9+
describe('Vet Exit Delegation Transaction', () => {
10+
const factory = new TransactionBuilderFactory(coins.get('tvet'));
11+
12+
describe('Build and Sign', () => {
13+
it('should build an exit delegation transaction', async function () {
14+
const tokenId = '123456';
15+
const txBuilder = factory.getExitDelegationBuilder();
16+
17+
txBuilder.sender(testData.addresses.validAddresses[0]);
18+
txBuilder.tokenId(tokenId);
19+
txBuilder.delegationContract(); // Use default address
20+
txBuilder.gas(21000);
21+
txBuilder.nonce('64248');
22+
txBuilder.blockRef('0x014ead140e77bbc1');
23+
txBuilder.expiration(64);
24+
txBuilder.gasPriceCoef(128);
25+
26+
const tx = (await txBuilder.build()) as ExitDelegationTransaction;
27+
28+
should.equal(tx.sender, testData.addresses.validAddresses[0]);
29+
should.equal(tx.tokenId, tokenId);
30+
should.equal(tx.contract, STARGATE_DELEGATION_ADDRESS);
31+
should.equal(tx.gas, 21000);
32+
should.equal(tx.nonce, '64248');
33+
should.equal(tx.expiration, 64);
34+
should.equal(tx.type, TransactionType.StakingUnlock);
35+
36+
// Verify the transaction data contains the correct method ID and tokenId
37+
tx.clauses[0].data.should.startWith(EXIT_DELEGATION_METHOD_ID);
38+
39+
// Verify the transaction has the correct structure
40+
tx.clauses.length.should.equal(1);
41+
should.exist(tx.clauses[0]);
42+
should.exist(tx.clauses[0].to);
43+
tx.clauses[0]?.to?.should.equal(STARGATE_DELEGATION_ADDRESS);
44+
should.exist(tx.clauses[0].value);
45+
tx.clauses[0].value.should.equal('0x0');
46+
});
47+
48+
it('should build an exit delegation transaction with custom contract address', async function () {
49+
const tokenId = '123456';
50+
const customContractAddress = '0x1234567890123456789012345678901234567890';
51+
const txBuilder = factory.getExitDelegationBuilder();
52+
53+
txBuilder.sender(testData.addresses.validAddresses[0]);
54+
txBuilder.tokenId(tokenId);
55+
txBuilder.delegationContract(customContractAddress);
56+
txBuilder.gas(21000);
57+
txBuilder.nonce('64248');
58+
txBuilder.blockRef('0x014ead140e77bbc1');
59+
txBuilder.expiration(64);
60+
txBuilder.gasPriceCoef(128);
61+
62+
const tx = (await txBuilder.build()) as ExitDelegationTransaction;
63+
64+
should.equal(tx.contract, customContractAddress);
65+
should.exist(tx.clauses[0]);
66+
should.exist(tx.clauses[0].to);
67+
tx.clauses[0]?.to?.should.equal(customContractAddress);
68+
});
69+
70+
it('should deserialize and reserialize a signed exit delegation transaction', async function () {
71+
// Create a mock serialized transaction for exit delegation
72+
const tokenId = '123456';
73+
const txBuilder = factory.getExitDelegationBuilder();
74+
75+
txBuilder.sender(testData.addresses.validAddresses[0]);
76+
txBuilder.tokenId(tokenId);
77+
txBuilder.delegationContract();
78+
txBuilder.gas(21000);
79+
txBuilder.nonce('64248');
80+
txBuilder.blockRef('0x014ead140e77bbc1');
81+
txBuilder.expiration(64);
82+
txBuilder.gasPriceCoef(128);
83+
84+
const tx = (await txBuilder.build()) as ExitDelegationTransaction;
85+
const serializedTx = tx.toBroadcastFormat();
86+
87+
// Now deserialize and check
88+
const deserializedBuilder = factory.from(serializedTx);
89+
const deserializedTx = (await deserializedBuilder.build()) as ExitDelegationTransaction;
90+
91+
should.equal(deserializedTx.type, TransactionType.StakingUnlock);
92+
should.equal(deserializedTx.tokenId, tokenId);
93+
should.equal(deserializedTx.contract, STARGATE_DELEGATION_ADDRESS);
94+
});
95+
96+
it('should validate the transaction data structure', async function () {
97+
const txBuilder = factory.getExitDelegationBuilder();
98+
99+
// Should throw error when building without required fields
100+
await should(txBuilder.build()).be.rejectedWith('transaction not defined');
101+
102+
txBuilder.sender(testData.addresses.validAddresses[0]);
103+
await should(txBuilder.build()).be.rejectedWith('Delegation contract address is required');
104+
105+
txBuilder.delegationContract();
106+
await should(txBuilder.build()).be.rejectedWith('Token ID is required');
107+
108+
// Now add the token ID and it should build successfully
109+
txBuilder.tokenId('123456');
110+
txBuilder.gas(21000);
111+
txBuilder.nonce('64248');
112+
txBuilder.blockRef('0x014ead140e77bbc1');
113+
114+
const tx = await txBuilder.build();
115+
should.exist(tx);
116+
});
117+
});
118+
119+
describe('Validation', () => {
120+
it('should fail with invalid contract address', function () {
121+
const txBuilder = factory.getExitDelegationBuilder();
122+
should(() => txBuilder.delegationContract('invalid-address')).throwError('Invalid address invalid-address');
123+
});
124+
125+
it('should fail with invalid token ID', async function () {
126+
const txBuilder = factory.getExitDelegationBuilder();
127+
txBuilder.sender(testData.addresses.validAddresses[0]);
128+
txBuilder.delegationContract();
129+
txBuilder.tokenId('');
130+
131+
await should(txBuilder.build()).be.rejectedWith('Token ID is required');
132+
});
133+
});
134+
});

0 commit comments

Comments
 (0)