Skip to content

Commit

Permalink
Check in progress on add txn construction
Browse files Browse the repository at this point in the history
  • Loading branch information
lazynina committed Feb 14, 2024
1 parent 08826c8 commit c77a5be
Show file tree
Hide file tree
Showing 7 changed files with 700 additions and 10 deletions.
141 changes: 141 additions & 0 deletions src/backend-types/deso-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4616,6 +4616,42 @@ export interface AccessGroupMemberLimitMapItem {
OpCount: number;
}

export type StakeLimitMapItem = {
ValidatorPublicKeyBase58Check: string;
StakeLimit: string; // Hex string
};

export type UnstakeLimitMapItem = {
ValidatorPublicKeyBase58Check: string;
UnstakeLimit: string; // Hex string
};

export type UnlockStakeLimitMapItem = {
ValidatorPublicKeyBase58Check: string;
OpCount: number;
};

export enum LockupLimitScopeType {
ANY = 'AnyCoins',
SCOPED = 'ScopedCoins',
}

export enum LockupLimitOperationString {
ANY = 'Any',
COIN_LOCKUP = 'CoinLockup',
UPDATE_COIN_LOCKUP_YIELD_CURVE = 'UpdateCoinLockupYieldCurve',
UPDATE_COIN_LOCKUP_TRANSFER_RESTRICTIONS = 'UpdateCoinLockupTransferRestrictions',
COIN_LOCKUP_TRANSFER = 'CoinLockupTransferOperationString',
COIN_UNLOCK = 'CoinLockupUnlock',
}

export type LockupLimitMapItem = {
ProfilePublicKeyBase58Check: string;
ScopeType: LockupLimitScopeType;
Operation: LockupLimitOperationString;
OpCount: number;
};

// struct2ts:types/generated/types.TransactionSpendingLimitResponse
export interface TransactionSpendingLimitResponse {
GlobalDESOLimit?: number;
Expand All @@ -4627,6 +4663,10 @@ export interface TransactionSpendingLimitResponse {
AssociationLimitMap?: AssociationLimitMapItem[];
AccessGroupLimitMap?: AccessGroupLimitMapItem[];
AccessGroupMemberLimitMap?: AccessGroupMemberLimitMapItem[];
StakeLimitMap?: StakeLimitMapItem[];
UnstakeLimitMap?: UnstakeLimitMapItem[];
UnlockStakeLimitMap?: UnlockStakeLimitMapItem[];
LockupLimitMap?: LockupLimitMapItem[];
IsUnlimited?: boolean;
}

Expand Down Expand Up @@ -5587,3 +5627,104 @@ export interface GetVideoStatusResponse {
}

export type DiamondLevelString = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8';

export interface RegisterAsValidatorRequest {
TransactorPublicKeyBase58Check: string;
Domains: string[];
DelegatedStakeCommissionBasisPoints: number;
DisableDelegatedStake: boolean;
VotingPublicKey: string;
VotingAuthorization: string;
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface UnregisterAsValidatorRequest {
TransactorPublicKeyBase58Check: string;
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface UnjailValidatorRequest {
TransactorPublicKeyBase58Check: string;
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface ValidatorTxnResponse {
SpendAmountNanos: number;
TotalInputNanos: number;
ChangeAmountNanos: number;
FeeNanos: number;
Transaction: MsgDeSoTxn;
TransactionHex: string;
TxnHashHex: string;
}

export interface ValidatorResponse {
ValidatorPublicKeyBase58Check: string;
Domains: string[];
DisableDelegatedStake: boolean;
VotingPublicKey: string;
VotingAuthorization: string;
TotalStakeAmountNanos: string; // HEX STRING
Status: string;
LastActiveAtEpochNumber: number;
JailedAtEpochNumber: number;
ExtraData: Record<string, string>;
}

export enum StakeRewardMethod {
PayToBalance = 'PAY_TO_BALANCE',
Restake = 'RESTAKE',
}

export interface StakeRequest {
TransactorPublicKeyBase58Check: string;
ValidatorPublicKeyBase58Check: string;
RewardMethod: StakeRewardMethod;
StakeAmountNanos: string; // HEX STRING
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface UnstakeRequest {
TransactorPublicKeyBase58Check: string;
ValidatorPublicKeyBase58Check: string;
UnstakeAmountNanos: string; // HEX STRING
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface UnlockStakeRequest {
TransactorPublicKeyBase58Check: string;
ValidatorPublicKeyBase58Check: string;
StartEpochNumber: number;
EndEpochNumber: number;
ExtraData: Record<string, string>;
MinFeeRateNanosPerKB: number;
TransactionFees: TransactionFee[];
}

export interface StakeTxnResponse {
SpendAmountNanos: number;
TotalInputNanos: number;
ChangeAmountNanos: number;
FeeNanos: number;
Transaction: MsgDeSoTxn;
TransactionHex: string;
TxnHashHex: string;
}

export interface StakeEntryResponse {
StakerPublicKeyBase58Check: string;
ValidatorPublicKeyBase58Check: string;
RewardMethod: StakeRewardMethod;
StakeAmountNanos: string; // HEX string
ExtraData: Record<string, string>;
}
74 changes: 74 additions & 0 deletions src/identity/permissions-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,79 @@ export function compareTransactionSpendingLimits(
: ['NFTOperationLimitMap', '', '0', path[path.length - 1]];
}
break;
// TODO: support for making sure a derived key has these limits...
// @jacksondean - this is a little more annoying since
// stake and unstake limits don't have an op count, but rather a deso limit.
case 'StakeLimitMap':
if (
actualPermissions?.StakeLimitMap?.find((map) => {
return (
map.ValidatorPublicKeyBase58Check === '' &&
expectedPermissions?.StakeLimitMap?.[Number(path[1])]
?.StakeLimit &&
parseInt(map.StakeLimit, 16) >=
parseInt(
expectedPermissions?.StakeLimitMap?.[Number(path[1])]
?.StakeLimit,
16
)
);
})
) {
return;
}
break;
case 'UnstakeLimitMap':
if (
actualPermissions?.UnstakeLimitMap?.find((map) => {
return (
map.ValidatorPublicKeyBase58Check === '' &&
expectedPermissions?.UnstakeLimitMap?.[Number(path[1])]
?.UnstakeLimit &&
parseInt(map.UnstakeLimit, 16) >=
parseInt(
expectedPermissions?.UnstakeLimitMap?.[Number(path[1])]
?.UnstakeLimit,
16
)
);
})
) {
return;
}
break;
case 'UnlockStakeLimitMap':
if (
actualPermissions?.UnlockStakeLimitMap?.find((map) => {
return (
map.ValidatorPublicKeyBase58Check === '' &&
map.OpCount >=
normalizeCount(
expectedPermissions?.UnlockStakeLimitMap?.[Number(path[1])]
?.OpCount
)
);
})
) {
return;
}
break;
case 'LockupLimitMap':
if (
actualPermissions?.LockupLimitMap?.find((map) => {
return (
map.ProfilePublicKeyBase58Check === '' &&
map.OpCount >=
normalizeCount(
expectedPermissions?.LockupLimitMap?.[Number(path[1])]
?.OpCount
)
);
})
) {
return;
}
break;
}

const actualVal = getDeepValue(actualPermissions, path);
Expand Down Expand Up @@ -166,6 +239,7 @@ export function buildTransactionSpendingLimitResponse(
}
});
}
// TODO: support for new PoS Spending limits maps.

result.TransactionCountLimitMap = result.TransactionCountLimitMap ?? {};

Expand Down
21 changes: 11 additions & 10 deletions src/identity/transaction-transcoders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
VarBuffer,
instanceToType,
VarBufferArray,
BoolOptional,
} from './transcoders.js';
export class TransactionInput extends BinaryRecord {
@Transcode(FixedBuffer(32))
Expand Down Expand Up @@ -602,7 +603,7 @@ export class TransactionMetadataNewMessage extends BinaryRecord {

export class TransactionMetadataRegisterAsValidator extends BinaryRecord {
@Transcode(VarBufferArray)
domains: Buffer[] = [];
domains: Uint8Array[] = [];

@Transcode(Boolean)
disableDelegatedStake = false;
Expand All @@ -615,42 +616,42 @@ export class TransactionMetadataRegisterAsValidator extends BinaryRecord {
// The challenge is converting this into something human
// readable in the UI.
@Transcode(VarBuffer)
votingPublicKey: Buffer = Buffer.alloc(0);
votingPublicKey: Uint8Array = new Uint8Array(0);

// TODO: Technically this is a bls signature,
// but under the hood it's really just a byte array.
// The challenge is converting this into something human
// readable in the UI.
@Transcode(VarBuffer)
votingAuthorization: Buffer = Buffer.alloc(0);
votingAuthorization: Uint8Array = new Uint8Array(0);
}

export class TransactionMetadataUnregisterAsValidator extends BinaryRecord {}

export class TransactionMetadataStake extends BinaryRecord {
@Transcode(VarBuffer)
validatorPublicKey: Buffer = Buffer.alloc(0);
validatorPublicKey: Uint8Array = new Uint8Array(0);

@Transcode(Uint8)
rewardMethod = 0;

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

export class TransactionMetadataUnstake extends BinaryRecord {
@Transcode(VarBuffer)
validatorPublicKey: Buffer = Buffer.alloc(0);
validatorPublicKey: Uint8Array = new Uint8Array(0);

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

export class TransactionMetadataUnlockStake extends BinaryRecord {
@Transcode(VarBuffer)
validatorPublicKey: Buffer = Buffer.alloc(0);
validatorPublicKey: Uint8Array = new Uint8Array(0);

@Transcode(Uvarint64)
startEpochNumber = 0;
Expand Down
20 changes: 20 additions & 0 deletions src/identity/transcoders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,26 @@ export function Optional<T>(transcoder: Transcoder<T>): Transcoder<T | null> {
};
}

export function BoolOptional<T>(
transcoder: Transcoder<T>
): Transcoder<T | null> {
return {
read: (bytes: Uint8Array) => {
const existence = bytes.at(0) != 0;
if (!existence) {
return [null, bytes.slice(1)];
}
return transcoder.read(bytes.slice(1));
},
write: (value: T | null) => {
if (value === null) {
return Uint8Array.from([0]);
}
return concatUint8Arrays([Uint8Array.from([1]), transcoder.write(value)]);
},
};
}

export const ChunkBuffer = (width: number): Transcoder<Uint8Array[]> => ({
read: (bytes) => {
const countAndBuffer = bufToUvarint64(bytes);
Expand Down
16 changes: 16 additions & 0 deletions src/identity/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import {
AccessGroupLimitMapItem,
AccessGroupMemberLimitMapItem,
AssociationLimitMapItem,
LockupLimitMapItem,
StakeLimitMapItem,
TransactionSpendingLimitResponse,
TransactionType,
UnlockStakeLimitMapItem,
UnstakeLimitMapItem,
} from '../backend-types/index.js';
export type Network = 'mainnet' | 'testnet';

Expand Down Expand Up @@ -61,6 +65,18 @@ export interface TransactionSpendingLimitResponseOptions {
AccessGroupMemberLimitMapItem,
'OpCount'
> & { OpCount: number | 'UNLIMITED' })[];
StakeLimitMap?: (Omit<StakeLimitMapItem, 'StakeLimit'> & {
StakeLimit: string | 'UNLIMITED'; // TODO: handle unlimited for DESO limit.
})[];
UnstakeLimitMap?: (Omit<UnstakeLimitMapItem, 'UnstakeLimit'> & {
UnstakeLimit: string | 'UNLIMITED'; // TODO: handle unlimited for DESO limit.
})[];
UnlockStakeLimitMap?: (Omit<UnlockStakeLimitMapItem, 'OpCount'> & {
OpCount: number | 'UNLIMITED';
})[];
LockupLimitMap?: (Omit<LockupLimitMapItem, 'OpCount'> & {
OpCount: number | 'UNLIMITED';
})[];
IsUnlimited?: boolean;
}

Expand Down
Loading

0 comments on commit c77a5be

Please sign in to comment.