Skip to content

Commit 53f407e

Browse files
Lazy Ninalazynina
authored andcommitted
Add support for coin lockup txn types
1 parent 8991b03 commit 53f407e

File tree

5 files changed

+180
-6
lines changed

5 files changed

+180
-6
lines changed

src/app/approve/approve.component.ts

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ import {
4343
TransactionMetadataUnstake,
4444
TransactionMetadataUnlockStake,
4545
TransactionMetadataUnjailValidator,
46+
TransactionMetadataCoinLockup,
47+
TransactionMetadataUpdateCoinLockupParams,
48+
TransactionMetadataCoinLockupTransfer,
49+
TransactionMetadataCoinUnlock,
4650
} from '../../lib/deso/transaction';
4751
import { ExtraData } from '../../types/identity';
4852
import { AccountService } from '../account.service';
@@ -310,12 +314,12 @@ export class ApproveComponent implements OnInit {
310314
);
311315
publicKeys = [daoCoinPublicKey];
312316
if (daoCoinMetadata.operationType === 0) {
313-
const mintAmount = this.hexNanosToUnitString(
317+
const mintAmount = this.hexBaseUnitsToUnitString(
314318
daoCoinMetadata.coinsToMintNanos
315319
);
316320
description = `mint ${mintAmount} ${daoCoinPublicKey} DAO coins`;
317321
} else if (daoCoinMetadata.operationType === 1) {
318-
const burnAmount = this.hexNanosToUnitString(
322+
const burnAmount = this.hexBaseUnitsToUnitString(
319323
daoCoinMetadata.coinsToBurnNanos
320324
);
321325
description = `burn ${burnAmount} ${daoCoinPublicKey} DAO coins`;
@@ -328,7 +332,7 @@ export class ApproveComponent implements OnInit {
328332
case TransactionMetadataTransferDAOCoin:
329333
const daoCoinTransferMetadata = this.transaction
330334
.metadata as TransactionMetadataTransferDAOCoin;
331-
const daoCoinTransferAmount = this.hexNanosToUnitString(
335+
const daoCoinTransferAmount = this.hexBaseUnitsToUnitString(
332336
daoCoinTransferMetadata.daoCoinToTransferNanos
333337
);
334338
const daoCoinTransferPublicKey = this.base58KeyCheck(
@@ -394,6 +398,7 @@ export class ApproveComponent implements OnInit {
394398
this.hexScaledExchangeRateToFloat(
395399
daoCoinLimitOrderMetadata.scaledExchangeRateCoinsToSellPerCoinToBuy
396400
);
401+
// TODO: figure out if we need to use hexBaseUnitsToUnitString here.
397402
const quantityToFill = this.hexNanosToUnitString(
398403
daoCoinLimitOrderMetadata.quantityToFillInBaseUnits
399404
);
@@ -639,6 +644,76 @@ export class ApproveComponent implements OnInit {
639644
case TransactionMetadataUnjailValidator:
640645
description = 'unjail your validator';
641646
break;
647+
case TransactionMetadataCoinLockup:
648+
// TODO: enhanced description for coin lockup.
649+
// Do we need to special case lock ups of DESO?
650+
const coinLockupMetadata = this.transaction
651+
.metadata as TransactionMetadataCoinLockup;
652+
const lockupAmount = this.hexBaseUnitsToUnitString(
653+
coinLockupMetadata.lockupAmountBaseUnits
654+
);
655+
const lockupProfilePubKey = this.base58KeyCheck(
656+
coinLockupMetadata.profilePublicKey
657+
);
658+
const lockUpRecipientPubKey = this.base58KeyCheck(
659+
coinLockupMetadata.recipientPublicKey
660+
);
661+
publicKeys = [lockupProfilePubKey, lockUpRecipientPubKey];
662+
description = `lockup ${lockupAmount} of your ${lockupProfilePubKey} coins`;
663+
break;
664+
case TransactionMetadataUpdateCoinLockupParams:
665+
// TODO: enhanced description for coin lockup params
666+
const updateCoinLockupParamsMetadata = this.transaction
667+
.metadata as TransactionMetadataUpdateCoinLockupParams;
668+
description =
669+
`update your coin lockup params\n` +
670+
`${
671+
updateCoinLockupParamsMetadata.removeYieldCurvePoint
672+
? 'Remove'
673+
: 'Add'
674+
} yield curve point with
675+
${
676+
updateCoinLockupParamsMetadata.lockupYieldAPYBasisPoints / 100
677+
}% APY for a lockup of
678+
${
679+
updateCoinLockupParamsMetadata.lockupYieldDurationNanoSecs
680+
} nanoseconds
681+
${
682+
!updateCoinLockupParamsMetadata.newLockupTransferRestrictions
683+
? ''
684+
: 'and update your lockup transfer restrictions'
685+
}`;
686+
687+
break;
688+
case TransactionMetadataCoinLockupTransfer:
689+
// TODO: enhanced description for coin lockup transfer
690+
// Do we need a special case for DESO?
691+
const coinLockupTransferMetadata = this.transaction
692+
.metadata as TransactionMetadataCoinLockupTransfer;
693+
const lockupTransferAmount = this.hexBaseUnitsToUnitString(
694+
coinLockupTransferMetadata.lockedCoinsToTransferBaseUnits
695+
);
696+
const lockupTransferProfilePubKey = this.base58KeyCheck(
697+
coinLockupTransferMetadata.profilePublicKey
698+
);
699+
const lockupTransferRecipientPubKey = this.base58KeyCheck(
700+
coinLockupTransferMetadata.recipientPublicKey
701+
);
702+
publicKeys = [
703+
lockupTransferProfilePubKey,
704+
lockupTransferRecipientPubKey,
705+
];
706+
description = `transfer ${lockupTransferAmount} of your locked ${lockupTransferProfilePubKey} coins to ${lockupTransferRecipientPubKey}`;
707+
break;
708+
case TransactionMetadataCoinUnlock:
709+
const coinUnlockMetadata = this.transaction
710+
.metadata as TransactionMetadataCoinUnlock;
711+
const unlockProfilePubKey = this.base58KeyCheck(
712+
coinUnlockMetadata.profilePublicKey
713+
);
714+
publicKeys = [unlockProfilePubKey];
715+
description = `unlock your locked ${unlockProfilePubKey} coins`;
716+
break;
642717
}
643718

644719
// Set the transaction description based on the description populated with public keys.
@@ -659,16 +734,24 @@ export class ApproveComponent implements OnInit {
659734
return bs58check.encode(Buffer.from([...prefix, ...keyBytes]));
660735
}
661736

662-
// TODO: create hexBaseUnitsToUnitString function to support proper
663-
// DAO Coin base unit conversions.
737+
// uint256 to DESO nano conversions.
664738
hexNanosToUnitString(nanos: Buffer): string {
665739
return this.nanosToUnitString(parseInt(nanos.toString('hex'), 16));
666740
}
667741

742+
// unit256 to base unit conversions.
743+
hexBaseUnitsToUnitString(baseUnits: Buffer): string {
744+
return this.baseUnitsToUnitString(parseInt(baseUnits.toString('hex'), 16));
745+
}
746+
668747
nanosToUnitString(nanos: number): string {
669748
return this.toFixedLengthDecimalString(nanos / 1e9);
670749
}
671750

751+
baseUnitsToUnitString(baseUnits: number): string {
752+
return this.toFixedLengthDecimalString(baseUnits / 1e18);
753+
}
754+
672755
hexScaledExchangeRateToFloat(hex: Buffer): number {
673756
return parseInt(hex.toString('hex'), 16) / 1e38;
674757
}

src/app/identity.service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ import {
4141
TransactionMetadataUnstake,
4242
TransactionMetadataUnlockStake,
4343
TransactionMetadataUnjailValidator,
44+
TransactionMetadataCoinLockup,
45+
TransactionMetadataUpdateCoinLockupParams,
46+
TransactionMetadataCoinLockupTransfer,
47+
TransactionMetadataCoinUnlock,
4448
} from '../lib/deso/transaction';
4549
import { SwalHelper } from '../lib/helpers/swal-helper';
4650
import { AccessLevel, PublicUserInfo } from '../types/identity';
@@ -529,6 +533,10 @@ export class IdentityService {
529533
case TransactionMetadataStake:
530534
case TransactionMetadataUnstake:
531535
case TransactionMetadataUnlockStake:
536+
case TransactionMetadataCoinLockup:
537+
case TransactionMetadataUpdateCoinLockupParams:
538+
case TransactionMetadataCoinLockupTransfer:
539+
case TransactionMetadataCoinUnlock:
532540
return AccessLevel.Full;
533541

534542
case TransactionMetadataFollow:

src/lib/bindata/transcoders.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { bufToUvarint64, uvarint64ToBuf } from './util';
1+
import { bufToUvarint64, bufToVarint64, uvarint64ToBuf, varint64ToBuf } from './util';
22
import { TransactionNonce } from '../deso/transaction';
33

44
export interface Transcoder<T> {
@@ -19,6 +19,11 @@ export const Uvarint64: Transcoder<number> = {
1919
write: (uint) => uvarint64ToBuf(uint),
2020
};
2121

22+
export const Varint64: Transcoder<number> = {
23+
read: (bytes) => bufToVarint64(bytes),
24+
write: (int) => varint64ToBuf(int),
25+
};
26+
2227
export const Boolean: Transcoder<boolean> = {
2328
read: (bytes) => [bytes.readUInt8(0) != 0, bytes.slice(1)],
2429
write: (bool) => {

src/lib/bindata/util.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,21 @@ export const uint64ToBufBigEndian = (uint: number): Buffer => {
5050

5151
return new Buffer(result.reverse());
5252
};
53+
54+
// TODO: Verify these are correct....
55+
export const varint64ToBuf = (int: number): Buffer => {
56+
let ux = BigInt(int) << BigInt(1);
57+
if (int < 0) {
58+
ux = ~ux;
59+
}
60+
return uvarint64ToBuf(Number(ux));
61+
};
62+
63+
export const bufToVarint64 = (buffer: Buffer): [number, Buffer] => {
64+
const [ux, n] = bufToUvarint64(buffer);
65+
let x = BigInt(ux) >> BigInt(1);
66+
if (ux & 1) {
67+
x = ~x;
68+
}
69+
return [Number(x), n];
70+
};

src/lib/deso/transaction.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Uvarint64,
1313
VarBuffer,
1414
VarBufferArray,
15+
Varint64,
1516
} from '../bindata/transcoders';
1617

1718
export class TransactionInput extends BinaryRecord {
@@ -643,6 +644,61 @@ export class TransactionMetadataUnlockStake extends TransactionMetadata {
643644

644645
export class TransactionMetadataUnjailValidator extends TransactionMetadata {}
645646

647+
export class TransactionMetadataCoinLockup extends TransactionMetadata {
648+
@Transcode(VarBuffer)
649+
profilePublicKey: Buffer = Buffer.alloc(0);
650+
651+
@Transcode(VarBuffer)
652+
recipientPublicKey: Buffer = Buffer.alloc(0);
653+
654+
@Transcode(Varint64)
655+
unlockTimestampNanoSecs: number = 0;
656+
657+
@Transcode(Varint64)
658+
vestingEndTimestampNanoSecs: number = 0;
659+
660+
// TODO: We may want a better way to handle uint256s.
661+
@Transcode(BoolOptional(VarBuffer))
662+
lockupAmountBaseUnits: Buffer = Buffer.alloc(0);
663+
}
664+
665+
export class TransactionMetadataUpdateCoinLockupParams extends TransactionMetadata {
666+
@Transcode(Varint64)
667+
lockupYieldDurationNanoSecs: number = 0;
668+
669+
@Transcode(Uvarint64)
670+
lockupYieldAPYBasisPoints: number = 0;
671+
672+
@Transcode(Boolean)
673+
removeYieldCurvePoint: boolean = false;
674+
675+
@Transcode(Boolean)
676+
newLockupTransferRestrictions: boolean = false;
677+
678+
@Transcode(Uint8)
679+
lockupTransferRestrictionStatus: number = 0;
680+
}
681+
682+
export class TransactionMetadataCoinLockupTransfer extends TransactionMetadata {
683+
@Transcode(VarBuffer)
684+
recipientPublicKey: Buffer = Buffer.alloc(0);
685+
686+
@Transcode(VarBuffer)
687+
profilePublicKey: Buffer = Buffer.alloc(0);
688+
689+
@Transcode(Varint64)
690+
unlockTimestampNanoSecs: number = 0;
691+
692+
// TODO: We may want a better way to handle uint256s.
693+
@Transcode(BoolOptional(VarBuffer))
694+
lockedCoinsToTransferBaseUnits: Buffer = Buffer.alloc(0);
695+
}
696+
697+
export class TransactionMetadataCoinUnlock extends TransactionMetadata {
698+
@Transcode(VarBuffer)
699+
profilePublicKey: Buffer = Buffer.alloc(0);
700+
}
701+
646702
export const TransactionTypeMetadataMap = {
647703
1: TransactionMetadataBlockReward,
648704
2: TransactionMetadataBasicTransfer,
@@ -682,6 +738,10 @@ export const TransactionTypeMetadataMap = {
682738
37: TransactionMetadataUnstake,
683739
38: TransactionMetadataUnlockStake,
684740
39: TransactionMetadataUnjailValidator,
741+
40: TransactionMetadataCoinLockup,
742+
41: TransactionMetadataUpdateCoinLockupParams,
743+
42: TransactionMetadataCoinLockupTransfer,
744+
43: TransactionMetadataCoinUnlock,
685745
};
686746

687747
export class Transaction extends BinaryRecord {

0 commit comments

Comments
 (0)