Skip to content
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
1 change: 1 addition & 0 deletions modules/sdk-coin-ton/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export { TokenTransferBuilder } from './tokenTransferBuilder';
export { TransactionBuilder } from './transactionBuilder';
export { TransferBuilder } from './transferBuilder';
export { TransactionBuilderFactory } from './transactionBuilderFactory';
export { TonWhalesVestingDepositBuilder } from './tonWhalesVestingDepositBuilder';
export { Interface, Utils };
35 changes: 35 additions & 0 deletions modules/sdk-coin-ton/src/lib/tonWhalesVestingDepositBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { Recipient, TransactionType } from '@bitgo/sdk-core';
import { TransactionBuilder } from './transactionBuilder';
import { Transaction } from './transaction';

export class TonWhalesVestingDepositBuilder extends TransactionBuilder {
constructor(_coinConfig: Readonly<CoinConfig>) {
super(_coinConfig);
this._transaction = new Transaction(_coinConfig);
}
protected get transactionType(): TransactionType {
return TransactionType.TonWhalesVestingDeposit;
}
setDepositMessage(): TonWhalesVestingDepositBuilder {
this.transaction.message = 'Deposit';
return this;
}

setDepositAmount(amount: string): TonWhalesVestingDepositBuilder {
if (!this.transaction.recipient) {
this.transaction.recipient = { address: '', amount: amount };
} else {
this.transaction.recipient.amount = amount;
}
return this;
}

send(recipient: Recipient): TonWhalesVestingDepositBuilder {
this.transaction.recipient = recipient;
return this;
}
setMessage(msg: string): TonWhalesVestingDepositBuilder {
throw new Error('Method not implemented. Use setDepositMessage() instead.');
}
}
5 changes: 5 additions & 0 deletions modules/sdk-coin-ton/src/lib/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ export class Transaction extends BaseTransaction {
if (opcode === 0) {
const payloadBytes = order.loadBits(order.getFreeBits());
payload = new TextDecoder().decode(payloadBytes);
if (payload === 'Deposit') {
this.transactionType = TransactionType.TonWhalesVestingDeposit;
} else if (payload === 'Withdraw') {
this.transactionType = TransactionType.TonWhalesVestingWithdrawal;
}
} else if (opcode === 4096) {
const queryId = order.loadUint(64).toNumber();
withdrawAmount = order.loadCoins().toNumber().toString();
Expand Down
10 changes: 10 additions & 0 deletions modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { TokenTransferBuilder } from './tokenTransferBuilder';
import { TokenTransaction } from './tokenTransaction';
import { TonWhalesDepositBuilder } from './tonWhalesDepositBuilder';
import { TonWhalesWithdrawalBuilder } from './tonWhalesWithdrawalBuilder';
import { TonWhalesVestingDepositBuilder } from './tonWhalesVestingDepositBuilder';

export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
constructor(_coinConfig: Readonly<CoinConfig>) {
Expand Down Expand Up @@ -45,6 +46,11 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
case TransactionType.TonWhalesWithdrawal:
builder = this.getTonWhalesWithdrawalBuilder();
break;
case TransactionType.TonWhalesVestingDeposit:
builder = this.getTonWhalesVestingDepositBuilder();
break;
case TransactionType.TonWhalesVestingWithdrawal:
throw new InvalidTransactionError('TonWhalesVestingWithdrawal builder not implemented yet');
default:
throw new InvalidTransactionError('unsupported transaction');
}
Expand Down Expand Up @@ -86,4 +92,8 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
getTonWhalesWithdrawalBuilder(): TonWhalesWithdrawalBuilder {
return new TonWhalesWithdrawalBuilder(this._coinConfig);
}

getTonWhalesVestingDepositBuilder(): TonWhalesVestingDepositBuilder {
return new TonWhalesVestingDepositBuilder(this._coinConfig);
}
}
12 changes: 12 additions & 0 deletions modules/sdk-coin-ton/test/resources/ton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,15 @@ export const getMemberStackFixture = {
rawAddress: '0:640f9d8b0023711a06a80319b9361b3448dea083c84d69c78d6227debfcf18ee',
boc: 'te6cckEBAQEAJAAAQ4AMgfOxYARuI0DVAGM3JsNmiRvUEHkJrTjxrET71/njHdDqtWeh',
};

export const tonWhalesVestingDepositFixture = {
recipient: {
address: 'EQDr9Sq482A6ikIUh5mUUjJaBUUJBrye13CJiDB-R31_lwIq',
amount: '10000000000',
},
sender: 'EQBkD52LACNxGgaoAxm5Nhs0SN6gg8hNaceNYifev88Y7qoZ',
publicKey: '9d6d3714aeb1f007f6e6aa728f79fdd005ea2c7ad459b2f54d73f9e672426230',
seqno: 0,
expireTime: 1234567890,
bounceable: true,
};
120 changes: 120 additions & 0 deletions modules/sdk-coin-ton/test/unit/tonWhalesVestingDepositBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import should from 'should';
import { TransactionType } from '@bitgo/sdk-core';
import { TransactionBuilderFactory } from '../../src';
import { coins } from '@bitgo/statics';
import * as testData from '../resources/ton';

describe('Ton Whales Vesting Deposit Builder', () => {
const factory = new TransactionBuilderFactory(coins.get('tton'));
const fixture = testData.tonWhalesVestingDepositFixture;

it('should build an unsigned vesting deposit transaction', async function () {
const txBuilder = factory.getTonWhalesVestingDepositBuilder();

txBuilder.sender(fixture.sender);
txBuilder.publicKey(fixture.publicKey);
txBuilder.sequenceNumber(fixture.seqno);
txBuilder.expireTime(fixture.expireTime);
txBuilder.bounceable(fixture.bounceable);

txBuilder.send({
address: fixture.recipient.address,
amount: fixture.recipient.amount,
});
txBuilder.setDepositAmount(fixture.recipient.amount);
txBuilder.setDepositMessage();

const tx = await txBuilder.build();

should.equal(tx.type, TransactionType.TonWhalesVestingDeposit);
should.equal(tx.toJson().bounceable, fixture.bounceable);
should.equal(tx.toJson().destination, fixture.recipient.address);
should.equal(tx.toJson().amount, fixture.recipient.amount);

tx.inputs.length.should.equal(1);
tx.inputs[0].should.deepEqual({
address: fixture.sender,
value: fixture.recipient.amount,
coin: 'tton',
});

tx.outputs.length.should.equal(1);
tx.outputs[0].should.deepEqual({
address: fixture.recipient.address,
value: fixture.recipient.amount,
coin: 'tton',
});
});

it('should build and parse a vesting deposit transaction', async function () {
const txBuilder = factory.getTonWhalesVestingDepositBuilder();

txBuilder.sender(fixture.sender);
txBuilder.publicKey(fixture.publicKey);
txBuilder.sequenceNumber(fixture.seqno);
txBuilder.expireTime(fixture.expireTime);
txBuilder.bounceable(fixture.bounceable);

txBuilder.send({
address: fixture.recipient.address,
amount: fixture.recipient.amount,
});
txBuilder.setDepositAmount(fixture.recipient.amount);
txBuilder.setDepositMessage();

const tx = await txBuilder.build();
const rawTx = tx.toBroadcastFormat();

const txBuilder2 = factory.from(rawTx);
const tx2 = await txBuilder2.build();

should.equal(tx2.type, TransactionType.TonWhalesVestingDeposit);
should.equal(tx2.toBroadcastFormat(), rawTx);
});

it('should set the correct message for vesting deposit', async function () {
const txBuilder = factory.getTonWhalesVestingDepositBuilder();

txBuilder.sender(fixture.sender);
txBuilder.publicKey(fixture.publicKey);
txBuilder.sequenceNumber(fixture.seqno);
txBuilder.expireTime(fixture.expireTime);
txBuilder.bounceable(fixture.bounceable);

txBuilder.send({
address: fixture.recipient.address,
amount: fixture.recipient.amount,
});
txBuilder.setDepositAmount(fixture.recipient.amount);
txBuilder.setDepositMessage();

const tx = await txBuilder.build();
const message = tx['message'];
should.equal(message, 'Deposit');
});

it('should support vesting contract specific flags', async function () {
const txBuilder = factory.getTonWhalesVestingDepositBuilder();

txBuilder.sender(fixture.sender);
txBuilder.publicKey(fixture.publicKey);
txBuilder.sequenceNumber(fixture.seqno);
txBuilder.expireTime(fixture.expireTime);
txBuilder.bounceable(true);
txBuilder.isV3ContractMessage(true);
txBuilder.subWalletId(268);

txBuilder.send({
address: fixture.recipient.address,
amount: fixture.recipient.amount,
});
txBuilder.setDepositAmount(fixture.recipient.amount);
txBuilder.setDepositMessage();

const tx = await txBuilder.build();

should.equal(tx.type, TransactionType.TonWhalesVestingDeposit);
should.equal(tx.toJson().bounceable, true);
should.equal(tx.toJson().sub_wallet_id, 268);
});
});
2 changes: 2 additions & 0 deletions modules/sdk-core/src/account-lib/baseCoin/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export enum TransactionType {
// ton whales
TonWhalesDeposit,
TonWhalesWithdrawal,
TonWhalesVestingDeposit,
TonWhalesVestingWithdrawal,
}

/**
Expand Down