Skip to content

Commit 0e1bdcc

Browse files
committed
Check in progress on add txn construction
1 parent a774058 commit 0e1bdcc

File tree

7 files changed

+700
-10
lines changed

7 files changed

+700
-10
lines changed

src/backend-types/deso-types.ts

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4616,6 +4616,42 @@ export interface AccessGroupMemberLimitMapItem {
46164616
OpCount: number;
46174617
}
46184618

4619+
export type StakeLimitMapItem = {
4620+
ValidatorPublicKeyBase58Check: string;
4621+
StakeLimit: string; // Hex string
4622+
};
4623+
4624+
export type UnstakeLimitMapItem = {
4625+
ValidatorPublicKeyBase58Check: string;
4626+
UnstakeLimit: string; // Hex string
4627+
};
4628+
4629+
export type UnlockStakeLimitMapItem = {
4630+
ValidatorPublicKeyBase58Check: string;
4631+
OpCount: number;
4632+
};
4633+
4634+
export enum LockupLimitScopeType {
4635+
ANY = 'AnyCoins',
4636+
SCOPED = 'ScopedCoins',
4637+
}
4638+
4639+
export enum LockupLimitOperationString {
4640+
ANY = 'Any',
4641+
COIN_LOCKUP = 'CoinLockup',
4642+
UPDATE_COIN_LOCKUP_YIELD_CURVE = 'UpdateCoinLockupYieldCurve',
4643+
UPDATE_COIN_LOCKUP_TRANSFER_RESTRICTIONS = 'UpdateCoinLockupTransferRestrictions',
4644+
COIN_LOCKUP_TRANSFER = 'CoinLockupTransferOperationString',
4645+
COIN_UNLOCK = 'CoinLockupUnlock',
4646+
}
4647+
4648+
export type LockupLimitMapItem = {
4649+
ProfilePublicKeyBase58Check: string;
4650+
ScopeType: LockupLimitScopeType;
4651+
Operation: LockupLimitOperationString;
4652+
OpCount: number;
4653+
};
4654+
46194655
// struct2ts:types/generated/types.TransactionSpendingLimitResponse
46204656
export interface TransactionSpendingLimitResponse {
46214657
GlobalDESOLimit?: number;
@@ -4627,6 +4663,10 @@ export interface TransactionSpendingLimitResponse {
46274663
AssociationLimitMap?: AssociationLimitMapItem[];
46284664
AccessGroupLimitMap?: AccessGroupLimitMapItem[];
46294665
AccessGroupMemberLimitMap?: AccessGroupMemberLimitMapItem[];
4666+
StakeLimitMap?: StakeLimitMapItem[];
4667+
UnstakeLimitMap?: UnstakeLimitMapItem[];
4668+
UnlockStakeLimitMap?: UnlockStakeLimitMapItem[];
4669+
LockupLimitMap?: LockupLimitMapItem[];
46304670
IsUnlimited?: boolean;
46314671
}
46324672

@@ -5587,3 +5627,104 @@ export interface GetVideoStatusResponse {
55875627
}
55885628

55895629
export type DiamondLevelString = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8';
5630+
5631+
export interface RegisterAsValidatorRequest {
5632+
TransactorPublicKeyBase58Check: string;
5633+
Domains: string[];
5634+
DelegatedStakeCommissionBasisPoints: number;
5635+
DisableDelegatedStake: boolean;
5636+
VotingPublicKey: string;
5637+
VotingAuthorization: string;
5638+
ExtraData: Record<string, string>;
5639+
MinFeeRateNanosPerKB: number;
5640+
TransactionFees: TransactionFee[];
5641+
}
5642+
5643+
export interface UnregisterAsValidatorRequest {
5644+
TransactorPublicKeyBase58Check: string;
5645+
ExtraData: Record<string, string>;
5646+
MinFeeRateNanosPerKB: number;
5647+
TransactionFees: TransactionFee[];
5648+
}
5649+
5650+
export interface UnjailValidatorRequest {
5651+
TransactorPublicKeyBase58Check: string;
5652+
ExtraData: Record<string, string>;
5653+
MinFeeRateNanosPerKB: number;
5654+
TransactionFees: TransactionFee[];
5655+
}
5656+
5657+
export interface ValidatorTxnResponse {
5658+
SpendAmountNanos: number;
5659+
TotalInputNanos: number;
5660+
ChangeAmountNanos: number;
5661+
FeeNanos: number;
5662+
Transaction: MsgDeSoTxn;
5663+
TransactionHex: string;
5664+
TxnHashHex: string;
5665+
}
5666+
5667+
export interface ValidatorResponse {
5668+
ValidatorPublicKeyBase58Check: string;
5669+
Domains: string[];
5670+
DisableDelegatedStake: boolean;
5671+
VotingPublicKey: string;
5672+
VotingAuthorization: string;
5673+
TotalStakeAmountNanos: string; // HEX STRING
5674+
Status: string;
5675+
LastActiveAtEpochNumber: number;
5676+
JailedAtEpochNumber: number;
5677+
ExtraData: Record<string, string>;
5678+
}
5679+
5680+
export enum StakeRewardMethod {
5681+
PayToBalance = 'PAY_TO_BALANCE',
5682+
Restake = 'RESTAKE',
5683+
}
5684+
5685+
export interface StakeRequest {
5686+
TransactorPublicKeyBase58Check: string;
5687+
ValidatorPublicKeyBase58Check: string;
5688+
RewardMethod: StakeRewardMethod;
5689+
StakeAmountNanos: string; // HEX STRING
5690+
ExtraData: Record<string, string>;
5691+
MinFeeRateNanosPerKB: number;
5692+
TransactionFees: TransactionFee[];
5693+
}
5694+
5695+
export interface UnstakeRequest {
5696+
TransactorPublicKeyBase58Check: string;
5697+
ValidatorPublicKeyBase58Check: string;
5698+
UnstakeAmountNanos: string; // HEX STRING
5699+
ExtraData: Record<string, string>;
5700+
MinFeeRateNanosPerKB: number;
5701+
TransactionFees: TransactionFee[];
5702+
}
5703+
5704+
export interface UnlockStakeRequest {
5705+
TransactorPublicKeyBase58Check: string;
5706+
ValidatorPublicKeyBase58Check: string;
5707+
StartEpochNumber: number;
5708+
EndEpochNumber: number;
5709+
ExtraData: Record<string, string>;
5710+
MinFeeRateNanosPerKB: number;
5711+
TransactionFees: TransactionFee[];
5712+
}
5713+
5714+
export interface StakeTxnResponse {
5715+
SpendAmountNanos: number;
5716+
TotalInputNanos: number;
5717+
ChangeAmountNanos: number;
5718+
FeeNanos: number;
5719+
Transaction: MsgDeSoTxn;
5720+
TransactionHex: string;
5721+
TxnHashHex: string;
5722+
}
5723+
5724+
export interface StakeEntryResponse {
5725+
StakerPublicKeyBase58Check: string;
5726+
ValidatorPublicKeyBase58Check: string;
5727+
RewardMethod: StakeRewardMethod;
5728+
StakeAmountNanos: string; // HEX string
5729+
ExtraData: Record<string, string>;
5730+
}

src/identity/permissions-utils.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,79 @@ export function compareTransactionSpendingLimits(
9494
: ['NFTOperationLimitMap', '', '0', path[path.length - 1]];
9595
}
9696
break;
97+
// TODO: support for making sure a derived key has these limits...
98+
// @jacksondean - this is a little more annoying since
99+
// stake and unstake limits don't have an op count, but rather a deso limit.
100+
case 'StakeLimitMap':
101+
if (
102+
actualPermissions?.StakeLimitMap?.find((map) => {
103+
return (
104+
map.ValidatorPublicKeyBase58Check === '' &&
105+
expectedPermissions?.StakeLimitMap?.[Number(path[1])]
106+
?.StakeLimit &&
107+
parseInt(map.StakeLimit, 16) >=
108+
parseInt(
109+
expectedPermissions?.StakeLimitMap?.[Number(path[1])]
110+
?.StakeLimit,
111+
16
112+
)
113+
);
114+
})
115+
) {
116+
return;
117+
}
118+
break;
119+
case 'UnstakeLimitMap':
120+
if (
121+
actualPermissions?.UnstakeLimitMap?.find((map) => {
122+
return (
123+
map.ValidatorPublicKeyBase58Check === '' &&
124+
expectedPermissions?.UnstakeLimitMap?.[Number(path[1])]
125+
?.UnstakeLimit &&
126+
parseInt(map.UnstakeLimit, 16) >=
127+
parseInt(
128+
expectedPermissions?.UnstakeLimitMap?.[Number(path[1])]
129+
?.UnstakeLimit,
130+
16
131+
)
132+
);
133+
})
134+
) {
135+
return;
136+
}
137+
break;
138+
case 'UnlockStakeLimitMap':
139+
if (
140+
actualPermissions?.UnlockStakeLimitMap?.find((map) => {
141+
return (
142+
map.ValidatorPublicKeyBase58Check === '' &&
143+
map.OpCount >=
144+
normalizeCount(
145+
expectedPermissions?.UnlockStakeLimitMap?.[Number(path[1])]
146+
?.OpCount
147+
)
148+
);
149+
})
150+
) {
151+
return;
152+
}
153+
break;
154+
case 'LockupLimitMap':
155+
if (
156+
actualPermissions?.LockupLimitMap?.find((map) => {
157+
return (
158+
map.ProfilePublicKeyBase58Check === '' &&
159+
map.OpCount >=
160+
normalizeCount(
161+
expectedPermissions?.LockupLimitMap?.[Number(path[1])]
162+
?.OpCount
163+
)
164+
);
165+
})
166+
) {
167+
return;
168+
}
169+
break;
97170
}
98171

99172
const actualVal = getDeepValue(actualPermissions, path);
@@ -166,6 +239,7 @@ export function buildTransactionSpendingLimitResponse(
166239
}
167240
});
168241
}
242+
// TODO: support for new PoS Spending limits maps.
169243

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

src/identity/transaction-transcoders.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
VarBuffer,
2323
instanceToType,
2424
VarBufferArray,
25+
BoolOptional,
2526
} from './transcoders.js';
2627
export class TransactionInput extends BinaryRecord {
2728
@Transcode(FixedBuffer(32))
@@ -602,7 +603,7 @@ export class TransactionMetadataNewMessage extends BinaryRecord {
602603

603604
export class TransactionMetadataRegisterAsValidator extends BinaryRecord {
604605
@Transcode(VarBufferArray)
605-
domains: Buffer[] = [];
606+
domains: Uint8Array[] = [];
606607

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

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

628629
export class TransactionMetadataUnregisterAsValidator extends BinaryRecord {}
629630

630631
export class TransactionMetadataStake extends BinaryRecord {
631632
@Transcode(VarBuffer)
632-
validatorPublicKey: Buffer = Buffer.alloc(0);
633+
validatorPublicKey: Uint8Array = new Uint8Array(0);
633634

634635
@Transcode(Uint8)
635636
rewardMethod = 0;
636637

637638
// TODO: We may want a better way to handle uint256s.
638-
@Transcode(Optional(VarBuffer))
639-
stakeAmountNanos: Buffer = Buffer.alloc(0);
639+
@Transcode(BoolOptional(VarBuffer))
640+
stakeAmountNanos: Uint8Array = new Uint8Array(0);
640641
}
641642

642643
export class TransactionMetadataUnstake extends BinaryRecord {
643644
@Transcode(VarBuffer)
644-
validatorPublicKey: Buffer = Buffer.alloc(0);
645+
validatorPublicKey: Uint8Array = new Uint8Array(0);
645646

646647
// TODO: We may want a better way to handle uint256s.
647-
@Transcode(Optional(VarBuffer))
648-
unstakeAmountNanos: Buffer = Buffer.alloc(0);
648+
@Transcode(BoolOptional(VarBuffer))
649+
unstakeAmountNanos: Uint8Array = new Uint8Array(0);
649650
}
650651

651652
export class TransactionMetadataUnlockStake extends BinaryRecord {
652653
@Transcode(VarBuffer)
653-
validatorPublicKey: Buffer = Buffer.alloc(0);
654+
validatorPublicKey: Uint8Array = new Uint8Array(0);
654655

655656
@Transcode(Uvarint64)
656657
startEpochNumber = 0;

src/identity/transcoders.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,26 @@ export function Optional<T>(transcoder: Transcoder<T>): Transcoder<T | null> {
143143
};
144144
}
145145

146+
export function BoolOptional<T>(
147+
transcoder: Transcoder<T>
148+
): Transcoder<T | null> {
149+
return {
150+
read: (bytes: Uint8Array) => {
151+
const existence = bytes.at(0) != 0;
152+
if (!existence) {
153+
return [null, bytes.slice(1)];
154+
}
155+
return transcoder.read(bytes.slice(1));
156+
},
157+
write: (value: T | null) => {
158+
if (value === null) {
159+
return Uint8Array.from([0]);
160+
}
161+
return concatUint8Arrays([Uint8Array.from([1]), transcoder.write(value)]);
162+
},
163+
};
164+
}
165+
146166
export const ChunkBuffer = (width: number): Transcoder<Uint8Array[]> => ({
147167
read: (bytes) => {
148168
const countAndBuffer = bufToUvarint64(bytes);

src/identity/types.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import {
22
AccessGroupLimitMapItem,
33
AccessGroupMemberLimitMapItem,
44
AssociationLimitMapItem,
5+
LockupLimitMapItem,
6+
StakeLimitMapItem,
57
TransactionSpendingLimitResponse,
68
TransactionType,
9+
UnlockStakeLimitMapItem,
10+
UnstakeLimitMapItem,
711
} from '../backend-types/index.js';
812
export type Network = 'mainnet' | 'testnet';
913

@@ -61,6 +65,18 @@ export interface TransactionSpendingLimitResponseOptions {
6165
AccessGroupMemberLimitMapItem,
6266
'OpCount'
6367
> & { OpCount: number | 'UNLIMITED' })[];
68+
StakeLimitMap?: (Omit<StakeLimitMapItem, 'StakeLimit'> & {
69+
StakeLimit: string | 'UNLIMITED'; // TODO: handle unlimited for DESO limit.
70+
})[];
71+
UnstakeLimitMap?: (Omit<UnstakeLimitMapItem, 'UnstakeLimit'> & {
72+
UnstakeLimit: string | 'UNLIMITED'; // TODO: handle unlimited for DESO limit.
73+
})[];
74+
UnlockStakeLimitMap?: (Omit<UnlockStakeLimitMapItem, 'OpCount'> & {
75+
OpCount: number | 'UNLIMITED';
76+
})[];
77+
LockupLimitMap?: (Omit<LockupLimitMapItem, 'OpCount'> & {
78+
OpCount: number | 'UNLIMITED';
79+
})[];
6480
IsUnlimited?: boolean;
6581
}
6682

0 commit comments

Comments
 (0)