Skip to content

Commit

Permalink
Add support for coin lockup txn types
Browse files Browse the repository at this point in the history
  • Loading branch information
Lazy Nina authored and lazynina committed Jan 29, 2024
1 parent d0618a9 commit 8479427
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 6 deletions.
92 changes: 87 additions & 5 deletions src/app/approve/approve.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ import {
TransactionMetadataUnstake,
TransactionMetadataUnlockStake,
TransactionMetadataUnjailValidator,
TransactionMetadataCoinLockup,
TransactionMetadataUpdateCoinLockupParams,
TransactionMetadataCoinLockupTransfer,
TransactionMetadataCoinUnlock,
} from '../../lib/deso/transaction';
import { ExtraData } from '../../types/identity';
import { AccountService } from '../account.service';
Expand Down Expand Up @@ -310,12 +314,12 @@ export class ApproveComponent implements OnInit {
);
publicKeys = [daoCoinPublicKey];
if (daoCoinMetadata.operationType === 0) {
const mintAmount = this.hexNanosToUnitString(
const mintAmount = this.hexBaseUnitsToUnitString(
daoCoinMetadata.coinsToMintNanos
);
description = `mint ${mintAmount} ${daoCoinPublicKey} DAO coins`;
} else if (daoCoinMetadata.operationType === 1) {
const burnAmount = this.hexNanosToUnitString(
const burnAmount = this.hexBaseUnitsToUnitString(
daoCoinMetadata.coinsToBurnNanos
);
description = `burn ${burnAmount} ${daoCoinPublicKey} DAO coins`;
Expand All @@ -328,7 +332,7 @@ export class ApproveComponent implements OnInit {
case TransactionMetadataTransferDAOCoin:
const daoCoinTransferMetadata = this.transaction
.metadata as TransactionMetadataTransferDAOCoin;
const daoCoinTransferAmount = this.hexNanosToUnitString(
const daoCoinTransferAmount = this.hexBaseUnitsToUnitString(
daoCoinTransferMetadata.daoCoinToTransferNanos
);
const daoCoinTransferPublicKey = this.base58KeyCheck(
Expand Down Expand Up @@ -394,6 +398,7 @@ export class ApproveComponent implements OnInit {
this.hexScaledExchangeRateToFloat(
daoCoinLimitOrderMetadata.scaledExchangeRateCoinsToSellPerCoinToBuy
);
// TODO: figure out if we need to use hexBaseUnitsToUnitString here.
const quantityToFill = this.hexNanosToUnitString(
daoCoinLimitOrderMetadata.quantityToFillInBaseUnits
);
Expand Down Expand Up @@ -639,6 +644,75 @@ export class ApproveComponent implements OnInit {
case TransactionMetadataUnjailValidator:
description = 'unjail your validator';
break;
case TransactionMetadataCoinLockup:
// NOTE: we don't need a special case for DESO right now
// as lockups are not allowed for DESO at this time.
const coinLockupMetadata = this.transaction
.metadata as TransactionMetadataCoinLockup;
const lockupAmount = this.hexBaseUnitsToUnitString(
coinLockupMetadata.lockupAmountBaseUnits
);
const lockupProfilePubKey = this.base58KeyCheck(
coinLockupMetadata.profilePublicKey
);
const lockUpRecipientPubKey = this.base58KeyCheck(
coinLockupMetadata.recipientPublicKey
);
publicKeys = [lockupProfilePubKey, lockUpRecipientPubKey];
description = `lockup ${lockupAmount} of your ${lockupProfilePubKey} coins`;
break;
case TransactionMetadataUpdateCoinLockupParams:
const updateCoinLockupParamsMetadata = this.transaction
.metadata as TransactionMetadataUpdateCoinLockupParams;
description =
`update your coin lockup params\n` +
`${
updateCoinLockupParamsMetadata.removeYieldCurvePoint
? 'Remove'
: 'Add'
} yield curve point with
${
updateCoinLockupParamsMetadata.lockupYieldAPYBasisPoints / 100
}% APY for a lockup of
${
updateCoinLockupParamsMetadata.lockupYieldDurationNanoSecs
} nanoseconds
${
!updateCoinLockupParamsMetadata.newLockupTransferRestrictions
? ''
: 'and update your lockup transfer restrictions'
}`;

break;
case TransactionMetadataCoinLockupTransfer:
// NOTE: we don't need a special case for DESO right now
// as lockups are not allowed for DESO at this time.
const coinLockupTransferMetadata = this.transaction
.metadata as TransactionMetadataCoinLockupTransfer;
const lockupTransferAmount = this.hexBaseUnitsToUnitString(
coinLockupTransferMetadata.lockedCoinsToTransferBaseUnits
);
const lockupTransferProfilePubKey = this.base58KeyCheck(
coinLockupTransferMetadata.profilePublicKey
);
const lockupTransferRecipientPubKey = this.base58KeyCheck(
coinLockupTransferMetadata.recipientPublicKey
);
publicKeys = [
lockupTransferProfilePubKey,
lockupTransferRecipientPubKey,
];
description = `transfer ${lockupTransferAmount} of your locked ${lockupTransferProfilePubKey} coins to ${lockupTransferRecipientPubKey}`;
break;
case TransactionMetadataCoinUnlock:
const coinUnlockMetadata = this.transaction
.metadata as TransactionMetadataCoinUnlock;
const unlockProfilePubKey = this.base58KeyCheck(
coinUnlockMetadata.profilePublicKey
);
publicKeys = [unlockProfilePubKey];
description = `unlock your locked ${unlockProfilePubKey} coins`;
break;
}

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

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

// unit256 to base unit conversions.
hexBaseUnitsToUnitString(baseUnits: Buffer): string {
return this.baseUnitsToUnitString(parseInt(baseUnits.toString('hex'), 16));
}

nanosToUnitString(nanos: number): string {
return this.toFixedLengthDecimalString(nanos / 1e9);
}

baseUnitsToUnitString(baseUnits: number): string {
return this.toFixedLengthDecimalString(baseUnits / 1e18);
}

hexScaledExchangeRateToFloat(hex: Buffer): number {
return parseInt(hex.toString('hex'), 16) / 1e38;
}
Expand Down
8 changes: 8 additions & 0 deletions src/app/identity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ import {
TransactionMetadataUnstake,
TransactionMetadataUnlockStake,
TransactionMetadataUnjailValidator,
TransactionMetadataCoinLockup,
TransactionMetadataUpdateCoinLockupParams,
TransactionMetadataCoinLockupTransfer,
TransactionMetadataCoinUnlock,
} from '../lib/deso/transaction';
import { SwalHelper } from '../lib/helpers/swal-helper';
import { AccessLevel, PublicUserInfo } from '../types/identity';
Expand Down Expand Up @@ -529,6 +533,10 @@ export class IdentityService {
case TransactionMetadataStake:
case TransactionMetadataUnstake:
case TransactionMetadataUnlockStake:
case TransactionMetadataCoinLockup:
case TransactionMetadataUpdateCoinLockupParams:
case TransactionMetadataCoinLockupTransfer:
case TransactionMetadataCoinUnlock:
return AccessLevel.Full;

case TransactionMetadataFollow:
Expand Down
12 changes: 11 additions & 1 deletion src/lib/bindata/transcoders.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { bufToUvarint64, uvarint64ToBuf } from './util';
import {
bufToUvarint64,
bufToVarint64,
uvarint64ToBuf,
varint64ToBuf,
} from './util';
import { TransactionNonce } from '../deso/transaction';

export interface Transcoder<T> {
Expand All @@ -19,6 +24,11 @@ export const Uvarint64: Transcoder<number> = {
write: (uint) => uvarint64ToBuf(uint),
};

export const Varint64: Transcoder<number> = {
read: (bytes) => bufToVarint64(bytes),
write: (int) => varint64ToBuf(int),
};

export const Boolean: Transcoder<boolean> = {
read: (bytes) => [bytes.readUInt8(0) != 0, bytes.slice(1)],
write: (bool) => {
Expand Down
18 changes: 18 additions & 0 deletions src/lib/bindata/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,21 @@ export const uint64ToBufBigEndian = (uint: number): Buffer => {

return new Buffer(result.reverse());
};

// TODO: Verify these are correct....
export const varint64ToBuf = (int: number): Buffer => {
let ux = BigInt(int) << BigInt(1);
if (int < 0) {
ux = ~ux;
}
return uvarint64ToBuf(Number(ux));
};

export const bufToVarint64 = (buffer: Buffer): [number, Buffer] => {
const [ux, n] = bufToUvarint64(buffer);
let x = BigInt(ux) >> BigInt(1);
if (ux & 1) {
x = ~x;
}
return [Number(x), n];
};
60 changes: 60 additions & 0 deletions src/lib/deso/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Uvarint64,
VarBuffer,
VarBufferArray,
Varint64,
} from '../bindata/transcoders';

export class TransactionInput extends BinaryRecord {
Expand Down Expand Up @@ -644,6 +645,61 @@ export class TransactionMetadataUnlockStake extends TransactionMetadata {

export class TransactionMetadataUnjailValidator extends TransactionMetadata {}

export class TransactionMetadataCoinLockup extends TransactionMetadata {
@Transcode(VarBuffer)
profilePublicKey: Buffer = Buffer.alloc(0);

@Transcode(VarBuffer)
recipientPublicKey: Buffer = Buffer.alloc(0);

@Transcode(Varint64)
unlockTimestampNanoSecs: number = 0;

@Transcode(Varint64)
vestingEndTimestampNanoSecs: number = 0;

// TODO: We may want a better way to handle uint256s.
@Transcode(BoolOptional(VarBuffer))
lockupAmountBaseUnits: Buffer = Buffer.alloc(0);
}

export class TransactionMetadataUpdateCoinLockupParams extends TransactionMetadata {
@Transcode(Varint64)
lockupYieldDurationNanoSecs: number = 0;

@Transcode(Uvarint64)
lockupYieldAPYBasisPoints: number = 0;

@Transcode(Boolean)
removeYieldCurvePoint: boolean = false;

@Transcode(Boolean)
newLockupTransferRestrictions: boolean = false;

@Transcode(Uint8)
lockupTransferRestrictionStatus: number = 0;
}

export class TransactionMetadataCoinLockupTransfer extends TransactionMetadata {
@Transcode(VarBuffer)
recipientPublicKey: Buffer = Buffer.alloc(0);

@Transcode(VarBuffer)
profilePublicKey: Buffer = Buffer.alloc(0);

@Transcode(Varint64)
unlockTimestampNanoSecs: number = 0;

// TODO: We may want a better way to handle uint256s.
@Transcode(BoolOptional(VarBuffer))
lockedCoinsToTransferBaseUnits: Buffer = Buffer.alloc(0);
}

export class TransactionMetadataCoinUnlock extends TransactionMetadata {
@Transcode(VarBuffer)
profilePublicKey: Buffer = Buffer.alloc(0);
}

export const TransactionTypeMetadataMap = {
1: TransactionMetadataBlockReward,
2: TransactionMetadataBasicTransfer,
Expand Down Expand Up @@ -683,6 +739,10 @@ export const TransactionTypeMetadataMap = {
37: TransactionMetadataUnstake,
38: TransactionMetadataUnlockStake,
39: TransactionMetadataUnjailValidator,
40: TransactionMetadataCoinLockup,
41: TransactionMetadataUpdateCoinLockupParams,
42: TransactionMetadataCoinLockupTransfer,
43: TransactionMetadataCoinUnlock,
};

export class Transaction extends BinaryRecord {
Expand Down

0 comments on commit 8479427

Please sign in to comment.