Skip to content

Commit fb5e76a

Browse files
committed
feat(sdk-coin-ton): SC-5234 vest depo builder
1 parent 82e8bf9 commit fb5e76a

File tree

7 files changed

+185
-0
lines changed

7 files changed

+185
-0
lines changed

modules/sdk-coin-ton/src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export { TokenTransferBuilder } from './tokenTransferBuilder';
88
export { TransactionBuilder } from './transactionBuilder';
99
export { TransferBuilder } from './transferBuilder';
1010
export { TransactionBuilderFactory } from './transactionBuilderFactory';
11+
export { TonWhalesVestingDepositBuilder } from './tonWhalesVestingDepositBuilder';
1112
export { Interface, Utils };
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { BaseCoin as CoinConfig } from '@bitgo/statics';
2+
import { Recipient, TransactionType } from '@bitgo/sdk-core';
3+
import { TransactionBuilder } from './transactionBuilder';
4+
import { Transaction } from './transaction';
5+
6+
export class TonWhalesVestingDepositBuilder extends TransactionBuilder {
7+
constructor(_coinConfig: Readonly<CoinConfig>) {
8+
super(_coinConfig);
9+
this._transaction = new Transaction(_coinConfig);
10+
}
11+
protected get transactionType(): TransactionType {
12+
return TransactionType.TonWhalesVestingDeposit;
13+
}
14+
setDepositMessage(): TonWhalesVestingDepositBuilder {
15+
this.transaction.message = 'Deposit';
16+
return this;
17+
}
18+
19+
setDepositAmount(amount: string): TonWhalesVestingDepositBuilder {
20+
if (!this.transaction.recipient) {
21+
this.transaction.recipient = { address: '', amount: amount };
22+
} else {
23+
this.transaction.recipient.amount = amount;
24+
}
25+
return this;
26+
}
27+
28+
send(recipient: Recipient): TonWhalesVestingDepositBuilder {
29+
this.transaction.recipient = recipient;
30+
return this;
31+
}
32+
setMessage(msg: string): TonWhalesVestingDepositBuilder {
33+
throw new Error('Method not implemented. Use setDepositMessage() instead.');
34+
}
35+
}

modules/sdk-coin-ton/src/lib/transaction.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ export class Transaction extends BaseTransaction {
355355
if (opcode === 0) {
356356
const payloadBytes = order.loadBits(order.getFreeBits());
357357
payload = new TextDecoder().decode(payloadBytes);
358+
if (payload === 'Deposit') {
359+
this.transactionType = TransactionType.TonWhalesVestingDeposit;
360+
} else if (payload === 'Withdraw') {
361+
this.transactionType = TransactionType.TonWhalesVestingWithdrawal;
362+
}
358363
} else if (opcode === 4096) {
359364
const queryId = order.loadUint(64).toNumber();
360365
withdrawAmount = order.loadCoins().toNumber().toString();

modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TokenTransferBuilder } from './tokenTransferBuilder';
88
import { TokenTransaction } from './tokenTransaction';
99
import { TonWhalesDepositBuilder } from './tonWhalesDepositBuilder';
1010
import { TonWhalesWithdrawalBuilder } from './tonWhalesWithdrawalBuilder';
11+
import { TonWhalesVestingDepositBuilder } from './tonWhalesVestingDepositBuilder';
1112

1213
export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
1314
constructor(_coinConfig: Readonly<CoinConfig>) {
@@ -45,6 +46,11 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
4546
case TransactionType.TonWhalesWithdrawal:
4647
builder = this.getTonWhalesWithdrawalBuilder();
4748
break;
49+
case TransactionType.TonWhalesVestingDeposit:
50+
builder = this.getTonWhalesVestingDepositBuilder();
51+
break;
52+
case TransactionType.TonWhalesVestingWithdrawal:
53+
throw new InvalidTransactionError('TonWhalesVestingWithdrawal builder not implemented yet');
4854
default:
4955
throw new InvalidTransactionError('unsupported transaction');
5056
}
@@ -86,4 +92,8 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
8692
getTonWhalesWithdrawalBuilder(): TonWhalesWithdrawalBuilder {
8793
return new TonWhalesWithdrawalBuilder(this._coinConfig);
8894
}
95+
96+
getTonWhalesVestingDepositBuilder(): TonWhalesVestingDepositBuilder {
97+
return new TonWhalesVestingDepositBuilder(this._coinConfig);
98+
}
8999
}

modules/sdk-coin-ton/test/resources/ton.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,15 @@ export const getMemberStackFixture = {
206206
rawAddress: '0:640f9d8b0023711a06a80319b9361b3448dea083c84d69c78d6227debfcf18ee',
207207
boc: 'te6cckEBAQEAJAAAQ4AMgfOxYARuI0DVAGM3JsNmiRvUEHkJrTjxrET71/njHdDqtWeh',
208208
};
209+
210+
export const tonWhalesVestingDepositFixture = {
211+
recipient: {
212+
address: 'EQDr9Sq482A6ikIUh5mUUjJaBUUJBrye13CJiDB-R31_lwIq',
213+
amount: '10000000000',
214+
},
215+
sender: 'EQBkD52LACNxGgaoAxm5Nhs0SN6gg8hNaceNYifev88Y7qoZ',
216+
publicKey: '9d6d3714aeb1f007f6e6aa728f79fdd005ea2c7ad459b2f54d73f9e672426230',
217+
seqno: 0,
218+
expireTime: 1234567890,
219+
bounceable: true,
220+
};
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import should from 'should';
2+
import { TransactionType } from '@bitgo/sdk-core';
3+
import { TransactionBuilderFactory } from '../../src';
4+
import { coins } from '@bitgo/statics';
5+
import * as testData from '../resources/ton';
6+
7+
describe('Ton Whales Vesting Deposit Builder', () => {
8+
const factory = new TransactionBuilderFactory(coins.get('tton'));
9+
const fixture = testData.tonWhalesVestingDepositFixture;
10+
11+
it('should build an unsigned vesting deposit transaction', async function () {
12+
const txBuilder = factory.getTonWhalesVestingDepositBuilder();
13+
14+
txBuilder.sender(fixture.sender);
15+
txBuilder.publicKey(fixture.publicKey);
16+
txBuilder.sequenceNumber(fixture.seqno);
17+
txBuilder.expireTime(fixture.expireTime);
18+
txBuilder.bounceable(fixture.bounceable);
19+
20+
txBuilder.send({
21+
address: fixture.recipient.address,
22+
amount: fixture.recipient.amount,
23+
});
24+
txBuilder.setDepositAmount(fixture.recipient.amount);
25+
txBuilder.setDepositMessage();
26+
27+
const tx = await txBuilder.build();
28+
29+
should.equal(tx.type, TransactionType.TonWhalesVestingDeposit);
30+
should.equal(tx.toJson().bounceable, fixture.bounceable);
31+
should.equal(tx.toJson().destination, fixture.recipient.address);
32+
should.equal(tx.toJson().amount, fixture.recipient.amount);
33+
34+
tx.inputs.length.should.equal(1);
35+
tx.inputs[0].should.deepEqual({
36+
address: fixture.sender,
37+
value: fixture.recipient.amount,
38+
coin: 'tton',
39+
});
40+
41+
tx.outputs.length.should.equal(1);
42+
tx.outputs[0].should.deepEqual({
43+
address: fixture.recipient.address,
44+
value: fixture.recipient.amount,
45+
coin: 'tton',
46+
});
47+
});
48+
49+
it('should build and parse a vesting deposit transaction', async function () {
50+
const txBuilder = factory.getTonWhalesVestingDepositBuilder();
51+
52+
txBuilder.sender(fixture.sender);
53+
txBuilder.publicKey(fixture.publicKey);
54+
txBuilder.sequenceNumber(fixture.seqno);
55+
txBuilder.expireTime(fixture.expireTime);
56+
txBuilder.bounceable(fixture.bounceable);
57+
58+
txBuilder.send({
59+
address: fixture.recipient.address,
60+
amount: fixture.recipient.amount,
61+
});
62+
txBuilder.setDepositAmount(fixture.recipient.amount);
63+
txBuilder.setDepositMessage();
64+
65+
const tx = await txBuilder.build();
66+
const rawTx = tx.toBroadcastFormat();
67+
68+
const txBuilder2 = factory.from(rawTx);
69+
const tx2 = await txBuilder2.build();
70+
71+
should.equal(tx2.type, TransactionType.TonWhalesVestingDeposit);
72+
should.equal(tx2.toBroadcastFormat(), rawTx);
73+
});
74+
75+
it('should set the correct message for vesting deposit', async function () {
76+
const txBuilder = factory.getTonWhalesVestingDepositBuilder();
77+
78+
txBuilder.sender(fixture.sender);
79+
txBuilder.publicKey(fixture.publicKey);
80+
txBuilder.sequenceNumber(fixture.seqno);
81+
txBuilder.expireTime(fixture.expireTime);
82+
txBuilder.bounceable(fixture.bounceable);
83+
84+
txBuilder.send({
85+
address: fixture.recipient.address,
86+
amount: fixture.recipient.amount,
87+
});
88+
txBuilder.setDepositAmount(fixture.recipient.amount);
89+
txBuilder.setDepositMessage();
90+
91+
const tx = await txBuilder.build();
92+
const message = tx['message'];
93+
should.equal(message, 'Deposit');
94+
});
95+
96+
it('should support vesting contract specific flags', async function () {
97+
const txBuilder = factory.getTonWhalesVestingDepositBuilder();
98+
99+
txBuilder.sender(fixture.sender);
100+
txBuilder.publicKey(fixture.publicKey);
101+
txBuilder.sequenceNumber(fixture.seqno);
102+
txBuilder.expireTime(fixture.expireTime);
103+
txBuilder.bounceable(true);
104+
txBuilder.isV3ContractMessage(true);
105+
txBuilder.subWalletId(268);
106+
107+
txBuilder.send({
108+
address: fixture.recipient.address,
109+
amount: fixture.recipient.amount,
110+
});
111+
txBuilder.setDepositAmount(fixture.recipient.amount);
112+
txBuilder.setDepositMessage();
113+
114+
const tx = await txBuilder.build();
115+
116+
should.equal(tx.type, TransactionType.TonWhalesVestingDeposit);
117+
should.equal(tx.toJson().bounceable, true);
118+
should.equal(tx.toJson().sub_wallet_id, 268);
119+
});
120+
});

modules/sdk-core/src/account-lib/baseCoin/enum.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export enum TransactionType {
123123
// ton whales
124124
TonWhalesDeposit,
125125
TonWhalesWithdrawal,
126+
TonWhalesVestingDeposit,
127+
TonWhalesVestingWithdrawal,
126128
}
127129

128130
/**

0 commit comments

Comments
 (0)