@vultisig/core-chain 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/chains/solana/staking/config.d.ts +75 -0
- package/dist/chains/solana/staking/config.d.ts.map +1 -0
- package/dist/chains/solana/staking/config.js +75 -0
- package/dist/chains/solana/staking/config.js.map +1 -0
- package/dist/chains/solana/staking/cooldownGate.d.ts +34 -0
- package/dist/chains/solana/staking/cooldownGate.d.ts.map +1 -0
- package/dist/chains/solana/staking/cooldownGate.js +32 -0
- package/dist/chains/solana/staking/cooldownGate.js.map +1 -0
- package/dist/chains/solana/staking/models/stakeAccount.d.ts +102 -0
- package/dist/chains/solana/staking/models/stakeAccount.d.ts.map +1 -0
- package/dist/chains/solana/staking/models/stakeAccount.js +85 -0
- package/dist/chains/solana/staking/models/stakeAccount.js.map +1 -0
- package/dist/chains/solana/staking/models/validator.d.ts +62 -0
- package/dist/chains/solana/staking/models/validator.d.ts.map +1 -0
- package/dist/chains/solana/staking/models/validator.js +34 -0
- package/dist/chains/solana/staking/models/validator.js.map +1 -0
- package/dist/chains/solana/staking/rpc.d.ts +49 -0
- package/dist/chains/solana/staking/rpc.d.ts.map +1 -0
- package/dist/chains/solana/staking/rpc.js +112 -0
- package/dist/chains/solana/staking/rpc.js.map +1 -0
- package/package.json +26 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @vultisig/core-chain
|
|
2
2
|
|
|
3
|
+
## 2.20.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#900](https://github.com/vultisig/vultisig-sdk/pull/900) [`9e72781`](https://github.com/vultisig/vultisig-sdk/commit/9e7278125bd8bc722a26ab3a1f91ba1be03054d1) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(solana): staking foundation — models + RPC read layer
|
|
8
|
+
|
|
9
|
+
Phase 1 of Solana native staking. Adds the chain-layer read foundation under
|
|
10
|
+
`@vultisig/core-chain/chains/solana/staking`: config, stake-account/validator
|
|
11
|
+
models (jsonParsed parsing + activation-state derivation), the RPC read layer
|
|
12
|
+
(getVoteAccounts / stake-account scan / epoch / rent / inflation / supply), and
|
|
13
|
+
the withdraw cooldown gate. No UI, no signing, no validator-metadata source.
|
|
14
|
+
|
|
3
15
|
## 2.19.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for Solana native staking (Stake program) reads.
|
|
3
|
+
*
|
|
4
|
+
* The Stake-program account layout and the staker-authority memcmp offset are
|
|
5
|
+
* protocol facts, not per-chain config, so this is a single flat constant set.
|
|
6
|
+
*
|
|
7
|
+
* The min-delegation RPC (`getStakeMinimumDelegation`) is blocked by the
|
|
8
|
+
* Vultisig proxy. The 1 SOL program minimum delegation is active on mainnet and
|
|
9
|
+
* is enforced by the Stake program — a delegation below it reverts with
|
|
10
|
+
* `StakeError.InsufficientDelegation`. Since the RPC is blocked, the delegation
|
|
11
|
+
* floor uses the documented `minDelegationFloorLamports` constant below plus the
|
|
12
|
+
* live rent-exempt reserve (active stake = funding − rent, so the funding floor
|
|
13
|
+
* is 1 SOL + rent).
|
|
14
|
+
*
|
|
15
|
+
* Port of iOS `SolanaStakingConfig`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const solanaStakingConfig: {
|
|
18
|
+
/**
|
|
19
|
+
* The on-chain Stake program. Every stake account is owned by this program;
|
|
20
|
+
* it is also the `programId` argument to the stake-filtered
|
|
21
|
+
* `getProgramAccounts` scan.
|
|
22
|
+
*/
|
|
23
|
+
readonly stakeProgramId: "Stake11111111111111111111111111111111111111";
|
|
24
|
+
/**
|
|
25
|
+
* Byte size of a fully-initialized stake account (`StakeStateV2`). The
|
|
26
|
+
* `getProgramAccounts` scan filters on `dataSize: 200` to exclude
|
|
27
|
+
* uninitialized / rewards-pool accounts before the memcmp narrows to the
|
|
28
|
+
* owner's accounts.
|
|
29
|
+
*/
|
|
30
|
+
readonly stakeStateSize: 200;
|
|
31
|
+
/**
|
|
32
|
+
* Offset of the staker authority pubkey inside the stake-account data, used
|
|
33
|
+
* as the `memcmp` offset to fetch only a given owner's stake accounts.
|
|
34
|
+
* Layout: 4-byte state enum discriminant + 8-byte `rentExemptReserve` = 12
|
|
35
|
+
* bytes precede `Meta.authorized.staker`.
|
|
36
|
+
*/
|
|
37
|
+
readonly stakerMemcmpOffset: 12;
|
|
38
|
+
/**
|
|
39
|
+
* Offset of the delegation `voter` (vote account) pubkey inside the
|
|
40
|
+
* stake-account data. Available for vote-account-scoped scans; the
|
|
41
|
+
* owner-scoped read uses `stakerMemcmpOffset`.
|
|
42
|
+
*/
|
|
43
|
+
readonly voterMemcmpOffset: 124;
|
|
44
|
+
/**
|
|
45
|
+
* Documented substitute for the blocked min-delegation RPC. 1 SOL in
|
|
46
|
+
* lamports — the historical program minimum. Used together with the live
|
|
47
|
+
* rent-exempt reserve as the delegation floor.
|
|
48
|
+
*/
|
|
49
|
+
readonly minDelegationFloorLamports: 1000000000n;
|
|
50
|
+
/** Lamports per SOL (9 decimals). Shared by the staking read/format layer. */
|
|
51
|
+
readonly lamportsPerSol: 1000000000n;
|
|
52
|
+
/**
|
|
53
|
+
* Rent-exempt reserve for a 200-byte stake account (`StakeStateV2`), in
|
|
54
|
+
* lamports. Deterministic from the rent rate + account size, so it serves as
|
|
55
|
+
* the pre-load default before the live `getMinimumBalanceForRentExemption`
|
|
56
|
+
* read returns.
|
|
57
|
+
*/
|
|
58
|
+
readonly rentExemptReserveLamports: 2282880n;
|
|
59
|
+
/**
|
|
60
|
+
* Mainnet schedule: 432,000 slots per epoch (~2 days). Informational — the
|
|
61
|
+
* live value is read from `getEpochInfo.slotsInEpoch`; this is the documented
|
|
62
|
+
* fallback for activation/cooldown copy.
|
|
63
|
+
*/
|
|
64
|
+
readonly slotsPerEpoch: 432000n;
|
|
65
|
+
/**
|
|
66
|
+
* `u64::MAX` sentinel the Stake program writes into `deactivationEpoch` while
|
|
67
|
+
* a delegation is active (not deactivating). Parsed stake accounts carry this
|
|
68
|
+
* verbatim; the activation-state derivation treats it as "no deactivation
|
|
69
|
+
* scheduled".
|
|
70
|
+
*/
|
|
71
|
+
readonly epochSentinel: 18446744073709551615n;
|
|
72
|
+
};
|
|
73
|
+
/** SOL decimals — used by the staking format layer. */
|
|
74
|
+
export declare const solDecimals = 9;
|
|
75
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB;IAC9B;;;;OAIG;;IAGH;;;;;OAKG;;IAGH;;;;;OAKG;;IAGH;;;;OAIG;;IAGH;;;;OAIG;;IAGH,8EAA8E;;IAG9E;;;;;OAKG;;IAGH;;;;OAIG;;IAGH;;;;;OAKG;;CAEK,CAAA;AAEV,uDAAuD;AACvD,eAAO,MAAM,WAAW,IAAI,CAAA"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for Solana native staking (Stake program) reads.
|
|
3
|
+
*
|
|
4
|
+
* The Stake-program account layout and the staker-authority memcmp offset are
|
|
5
|
+
* protocol facts, not per-chain config, so this is a single flat constant set.
|
|
6
|
+
*
|
|
7
|
+
* The min-delegation RPC (`getStakeMinimumDelegation`) is blocked by the
|
|
8
|
+
* Vultisig proxy. The 1 SOL program minimum delegation is active on mainnet and
|
|
9
|
+
* is enforced by the Stake program — a delegation below it reverts with
|
|
10
|
+
* `StakeError.InsufficientDelegation`. Since the RPC is blocked, the delegation
|
|
11
|
+
* floor uses the documented `minDelegationFloorLamports` constant below plus the
|
|
12
|
+
* live rent-exempt reserve (active stake = funding − rent, so the funding floor
|
|
13
|
+
* is 1 SOL + rent).
|
|
14
|
+
*
|
|
15
|
+
* Port of iOS `SolanaStakingConfig`.
|
|
16
|
+
*/
|
|
17
|
+
export const solanaStakingConfig = {
|
|
18
|
+
/**
|
|
19
|
+
* The on-chain Stake program. Every stake account is owned by this program;
|
|
20
|
+
* it is also the `programId` argument to the stake-filtered
|
|
21
|
+
* `getProgramAccounts` scan.
|
|
22
|
+
*/
|
|
23
|
+
stakeProgramId: 'Stake11111111111111111111111111111111111111',
|
|
24
|
+
/**
|
|
25
|
+
* Byte size of a fully-initialized stake account (`StakeStateV2`). The
|
|
26
|
+
* `getProgramAccounts` scan filters on `dataSize: 200` to exclude
|
|
27
|
+
* uninitialized / rewards-pool accounts before the memcmp narrows to the
|
|
28
|
+
* owner's accounts.
|
|
29
|
+
*/
|
|
30
|
+
stakeStateSize: 200,
|
|
31
|
+
/**
|
|
32
|
+
* Offset of the staker authority pubkey inside the stake-account data, used
|
|
33
|
+
* as the `memcmp` offset to fetch only a given owner's stake accounts.
|
|
34
|
+
* Layout: 4-byte state enum discriminant + 8-byte `rentExemptReserve` = 12
|
|
35
|
+
* bytes precede `Meta.authorized.staker`.
|
|
36
|
+
*/
|
|
37
|
+
stakerMemcmpOffset: 12,
|
|
38
|
+
/**
|
|
39
|
+
* Offset of the delegation `voter` (vote account) pubkey inside the
|
|
40
|
+
* stake-account data. Available for vote-account-scoped scans; the
|
|
41
|
+
* owner-scoped read uses `stakerMemcmpOffset`.
|
|
42
|
+
*/
|
|
43
|
+
voterMemcmpOffset: 124,
|
|
44
|
+
/**
|
|
45
|
+
* Documented substitute for the blocked min-delegation RPC. 1 SOL in
|
|
46
|
+
* lamports — the historical program minimum. Used together with the live
|
|
47
|
+
* rent-exempt reserve as the delegation floor.
|
|
48
|
+
*/
|
|
49
|
+
minDelegationFloorLamports: 1000000000n,
|
|
50
|
+
/** Lamports per SOL (9 decimals). Shared by the staking read/format layer. */
|
|
51
|
+
lamportsPerSol: 1000000000n,
|
|
52
|
+
/**
|
|
53
|
+
* Rent-exempt reserve for a 200-byte stake account (`StakeStateV2`), in
|
|
54
|
+
* lamports. Deterministic from the rent rate + account size, so it serves as
|
|
55
|
+
* the pre-load default before the live `getMinimumBalanceForRentExemption`
|
|
56
|
+
* read returns.
|
|
57
|
+
*/
|
|
58
|
+
rentExemptReserveLamports: 2282880n,
|
|
59
|
+
/**
|
|
60
|
+
* Mainnet schedule: 432,000 slots per epoch (~2 days). Informational — the
|
|
61
|
+
* live value is read from `getEpochInfo.slotsInEpoch`; this is the documented
|
|
62
|
+
* fallback for activation/cooldown copy.
|
|
63
|
+
*/
|
|
64
|
+
slotsPerEpoch: 432000n,
|
|
65
|
+
/**
|
|
66
|
+
* `u64::MAX` sentinel the Stake program writes into `deactivationEpoch` while
|
|
67
|
+
* a delegation is active (not deactivating). Parsed stake accounts carry this
|
|
68
|
+
* verbatim; the activation-state derivation treats it as "no deactivation
|
|
69
|
+
* scheduled".
|
|
70
|
+
*/
|
|
71
|
+
epochSentinel: 18446744073709551615n,
|
|
72
|
+
};
|
|
73
|
+
/** SOL decimals — used by the staking format layer. */
|
|
74
|
+
export const solDecimals = 9;
|
|
75
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC;;;;OAIG;IACH,cAAc,EAAE,6CAA6C;IAE7D;;;;;OAKG;IACH,cAAc,EAAE,GAAG;IAEnB;;;;;OAKG;IACH,kBAAkB,EAAE,EAAE;IAEtB;;;;OAIG;IACH,iBAAiB,EAAE,GAAG;IAEtB;;;;OAIG;IACH,0BAA0B,EAAE,WAAc;IAE1C,8EAA8E;IAC9E,cAAc,EAAE,WAAc;IAE9B;;;;;OAKG;IACH,yBAAyB,EAAE,QAAU;IAErC;;;;OAIG;IACH,aAAa,EAAE,OAAQ;IAEvB;;;;;OAKG;IACH,aAAa,EAAE,qBAA2B;CAClC,CAAA;AAEV,uDAAuD;AACvD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SolanaStakeAccount } from './models/stakeAccount.js';
|
|
2
|
+
/**
|
|
3
|
+
* Gates a stake-account withdraw on the deactivation cooldown. After a
|
|
4
|
+
* deactivate, the stake cools down for ~1 epoch: the lamports become
|
|
5
|
+
* withdrawable only once the network epoch has advanced PAST the account's
|
|
6
|
+
* `deactivationEpoch`. Evaluating this before a withdraw keysign avoids
|
|
7
|
+
* surprising the user with a transaction the Stake program would reject.
|
|
8
|
+
*
|
|
9
|
+
* Port of iOS `SolanaEpochCooldownGate`.
|
|
10
|
+
*/
|
|
11
|
+
export type SolanaEpochCooldownState = {
|
|
12
|
+
status: 'available';
|
|
13
|
+
} | {
|
|
14
|
+
status: 'blocked';
|
|
15
|
+
unlocksAtEpoch: bigint;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Evaluates whether `account`'s deactivated stake can be withdrawn at
|
|
19
|
+
* `currentEpoch`. Pure function over the parsed delegation + the live epoch.
|
|
20
|
+
*
|
|
21
|
+
* - A non-deactivating account (sentinel `deactivationEpoch`) is `available` —
|
|
22
|
+
* there is nothing cooling down.
|
|
23
|
+
* - A deactivating account unlocks once the network advances past its
|
|
24
|
+
* deactivation epoch, i.e. at `deactivationEpoch + 1`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const evaluateCooldown: (account: SolanaStakeAccount, currentEpoch: bigint) => SolanaEpochCooldownState;
|
|
27
|
+
/**
|
|
28
|
+
* Approximate mainnet epoch length in days. Informational copy only — the
|
|
29
|
+
* authoritative withdraw gate is `evaluateCooldown`, which uses the live epoch.
|
|
30
|
+
*/
|
|
31
|
+
export declare const approximateDaysPerEpoch = 2;
|
|
32
|
+
/** Approximate calendar days for `epochs` epochs of cooldown. */
|
|
33
|
+
export declare const approximateCooldownDays: (epochs: number) => number;
|
|
34
|
+
//# sourceMappingURL=cooldownGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cooldownGate.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/cooldownGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAElF;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9G;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,kBAAkB,EAAE,cAAc,MAAM,KAAG,wBAapF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,KAAG,MAAuD,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isDeactivationSentinel } from './models/stakeAccount.js';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluates whether `account`'s deactivated stake can be withdrawn at
|
|
4
|
+
* `currentEpoch`. Pure function over the parsed delegation + the live epoch.
|
|
5
|
+
*
|
|
6
|
+
* - A non-deactivating account (sentinel `deactivationEpoch`) is `available` —
|
|
7
|
+
* there is nothing cooling down.
|
|
8
|
+
* - A deactivating account unlocks once the network advances past its
|
|
9
|
+
* deactivation epoch, i.e. at `deactivationEpoch + 1`.
|
|
10
|
+
*/
|
|
11
|
+
export const evaluateCooldown = (account, currentEpoch) => {
|
|
12
|
+
const { delegation } = account;
|
|
13
|
+
if (!delegation) {
|
|
14
|
+
return { status: 'available' };
|
|
15
|
+
}
|
|
16
|
+
if (isDeactivationSentinel(delegation)) {
|
|
17
|
+
return { status: 'available' };
|
|
18
|
+
}
|
|
19
|
+
if (currentEpoch > delegation.deactivationEpoch) {
|
|
20
|
+
return { status: 'available' };
|
|
21
|
+
}
|
|
22
|
+
// `deactivationEpoch` is < sentinel here, so +1 is safe.
|
|
23
|
+
return { status: 'blocked', unlocksAtEpoch: delegation.deactivationEpoch + 1n };
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Approximate mainnet epoch length in days. Informational copy only — the
|
|
27
|
+
* authoritative withdraw gate is `evaluateCooldown`, which uses the live epoch.
|
|
28
|
+
*/
|
|
29
|
+
export const approximateDaysPerEpoch = 2;
|
|
30
|
+
/** Approximate calendar days for `epochs` epochs of cooldown. */
|
|
31
|
+
export const approximateCooldownDays = (epochs) => Math.max(0, epochs) * approximateDaysPerEpoch;
|
|
32
|
+
//# sourceMappingURL=cooldownGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cooldownGate.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/cooldownGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAsB,MAAM,uBAAuB,CAAA;AAalF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA2B,EAAE,YAAoB,EAA4B,EAAE;IAC9G,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;IAC9B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;IAChC,CAAC;IACD,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;IAChC,CAAC;IACD,IAAI,YAAY,GAAG,UAAU,CAAC,iBAAiB,EAAE,CAAC;QAChD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;IAChC,CAAC;IACD,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,CAAC,iBAAiB,GAAG,EAAE,EAAE,CAAA;AACjF,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAExC,iEAAiE;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed Solana stake account — the read-side model the staking UI binds to
|
|
3
|
+
* (delegation amount, validator, activation state, withdraw authority). One
|
|
4
|
+
* stake account delegates to exactly one validator; a wallet can hold N.
|
|
5
|
+
*
|
|
6
|
+
* Decoded from a `getAccountInfo` / `getProgramAccounts` `jsonParsed` row
|
|
7
|
+
* (`value.data.parsed.info.{meta,stake}`). The on-chain numbers
|
|
8
|
+
* (`activationEpoch`, `deactivationEpoch`, `stake`, `rentExemptReserve`) are
|
|
9
|
+
* serialized as decimal STRINGS in jsonParsed — they're u64 and exceed JSON's
|
|
10
|
+
* safe-integer range — so they are converted to `bigint` here.
|
|
11
|
+
*
|
|
12
|
+
* Port of iOS `SolanaStakeAccount`.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Activation lifecycle of a stake delegation, derived from the account's
|
|
16
|
+
* `activationEpoch` / `deactivationEpoch` relative to the current epoch.
|
|
17
|
+
* Solana stake activates at the next epoch boundary and cools down ~1 epoch
|
|
18
|
+
* after a deactivate before the funds can be withdrawn.
|
|
19
|
+
*/
|
|
20
|
+
export type SolanaStakeActivationState = 'activating' | 'active' | 'deactivating' | 'inactive';
|
|
21
|
+
export type SolanaStakeDelegation = {
|
|
22
|
+
/** Vote account this stake is delegated to. */
|
|
23
|
+
votePubkey: string;
|
|
24
|
+
/** Epoch the delegation began activating. */
|
|
25
|
+
activationEpoch: bigint;
|
|
26
|
+
/**
|
|
27
|
+
* Epoch the delegation began deactivating, or `epochSentinel` (`u64::MAX`)
|
|
28
|
+
* while active (the Stake program's "not deactivating" sentinel).
|
|
29
|
+
*/
|
|
30
|
+
deactivationEpoch: bigint;
|
|
31
|
+
/** Delegated lamports. */
|
|
32
|
+
stake: bigint;
|
|
33
|
+
};
|
|
34
|
+
export type SolanaStakeAccount = {
|
|
35
|
+
/** Stake account address (its own pubkey, not the owner's). */
|
|
36
|
+
pubkey: string;
|
|
37
|
+
/**
|
|
38
|
+
* The account's total lamports (delegated stake + rent reserve + any
|
|
39
|
+
* undelegated lamports).
|
|
40
|
+
*/
|
|
41
|
+
lamports: bigint;
|
|
42
|
+
/**
|
|
43
|
+
* Rent-exempt reserve held by the account — not part of the delegated /
|
|
44
|
+
* withdrawable stake.
|
|
45
|
+
*/
|
|
46
|
+
rentExemptReserve: bigint;
|
|
47
|
+
/** Authority allowed to delegate / deactivate the stake. */
|
|
48
|
+
staker: string;
|
|
49
|
+
/** Authority allowed to withdraw the stake. */
|
|
50
|
+
withdrawer: string;
|
|
51
|
+
/**
|
|
52
|
+
* The delegation, or `undefined` for an initialized-but-undelegated account
|
|
53
|
+
* (`parsed.type == "initialized"`, no `stake.delegation`).
|
|
54
|
+
*/
|
|
55
|
+
delegation?: SolanaStakeDelegation;
|
|
56
|
+
};
|
|
57
|
+
/** `true` when no deactivation has been scheduled on the delegation. */
|
|
58
|
+
export declare const isDeactivationSentinel: (delegation: SolanaStakeDelegation) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Derives the lifecycle state from the current epoch. Pure so the cooldown gate
|
|
61
|
+
* and the UI share one definition.
|
|
62
|
+
*
|
|
63
|
+
* - activating: delegation began this epoch and is not deactivating.
|
|
64
|
+
* - deactivating: a deactivation was scheduled and the current epoch has not
|
|
65
|
+
* yet passed it.
|
|
66
|
+
* - active: delegated in a prior epoch and not deactivating.
|
|
67
|
+
* - inactive: no delegation, or the deactivation epoch has passed.
|
|
68
|
+
*/
|
|
69
|
+
export declare const stakeActivationState: (account: SolanaStakeAccount, currentEpoch: bigint) => SolanaStakeActivationState;
|
|
70
|
+
/**
|
|
71
|
+
* Mirrors the `jsonParsed` Stake-program account `info` shape. u64 fields arrive
|
|
72
|
+
* as decimal strings (or numbers); `toBigInt` coerces both.
|
|
73
|
+
*/
|
|
74
|
+
type ParsedStakeInfo = {
|
|
75
|
+
meta?: {
|
|
76
|
+
rentExemptReserve?: string | number;
|
|
77
|
+
authorized?: {
|
|
78
|
+
staker?: string;
|
|
79
|
+
withdrawer?: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
stake?: {
|
|
83
|
+
delegation?: {
|
|
84
|
+
voter?: string;
|
|
85
|
+
stake?: string | number;
|
|
86
|
+
activationEpoch?: string | number;
|
|
87
|
+
deactivationEpoch?: string | number;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Builds the model from a decoded jsonParsed Stake-program account. Returns
|
|
93
|
+
* `undefined` when the account is not a parsed stake account (e.g. a non-stake
|
|
94
|
+
* program account or a base64/dataSliced row with no `parsed` tree).
|
|
95
|
+
*/
|
|
96
|
+
export declare const parseStakeAccount: ({ pubkey, lamports, parsedInfo, }: {
|
|
97
|
+
pubkey: string;
|
|
98
|
+
lamports: bigint;
|
|
99
|
+
parsedInfo: ParsedStakeInfo | undefined;
|
|
100
|
+
}) => SolanaStakeAccount | undefined;
|
|
101
|
+
export {};
|
|
102
|
+
//# sourceMappingURL=stakeAccount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stakeAccount.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/staking/models/stakeAccount.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,YAAY,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA;AAE9F,MAAM,MAAM,qBAAqB,GAAG;IAClC,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB,6CAA6C;IAC7C,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAA;CACnC,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,GAAI,YAAY,qBAAqB,KAAG,OACP,CAAA;AAEpE;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,kBAAkB,EAAE,cAAc,MAAM,KAAG,0BAcxF,CAAA;AAID;;;GAGG;AACH,KAAK,eAAe,GAAG;IACrB,IAAI,CAAC,EAAE;QACL,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;QACnC,UAAU,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACtD,CAAA;IACD,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE;YACX,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;YACvB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;YACjC,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;SACpC,CAAA;KACF,CAAA;CACF,CAAA;AAaD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,mCAI/B;IACD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAA;CACxC,KAAG,kBAAkB,GAAG,SA4CxB,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { solanaStakingConfig } from '../config.js';
|
|
2
|
+
/** `true` when no deactivation has been scheduled on the delegation. */
|
|
3
|
+
export const isDeactivationSentinel = (delegation) => delegation.deactivationEpoch === solanaStakingConfig.epochSentinel;
|
|
4
|
+
/**
|
|
5
|
+
* Derives the lifecycle state from the current epoch. Pure so the cooldown gate
|
|
6
|
+
* and the UI share one definition.
|
|
7
|
+
*
|
|
8
|
+
* - activating: delegation began this epoch and is not deactivating.
|
|
9
|
+
* - deactivating: a deactivation was scheduled and the current epoch has not
|
|
10
|
+
* yet passed it.
|
|
11
|
+
* - active: delegated in a prior epoch and not deactivating.
|
|
12
|
+
* - inactive: no delegation, or the deactivation epoch has passed.
|
|
13
|
+
*/
|
|
14
|
+
export const stakeActivationState = (account, currentEpoch) => {
|
|
15
|
+
const { delegation } = account;
|
|
16
|
+
if (!delegation) {
|
|
17
|
+
return 'inactive';
|
|
18
|
+
}
|
|
19
|
+
if (!isDeactivationSentinel(delegation)) {
|
|
20
|
+
// A deactivation is scheduled. Still cooling down until the current epoch
|
|
21
|
+
// passes the deactivation epoch; inactive afterwards.
|
|
22
|
+
return currentEpoch <= delegation.deactivationEpoch ? 'deactivating' : 'inactive';
|
|
23
|
+
}
|
|
24
|
+
// No deactivation scheduled — activating in its first epoch, active after.
|
|
25
|
+
return currentEpoch <= delegation.activationEpoch ? 'activating' : 'active';
|
|
26
|
+
};
|
|
27
|
+
const toBigInt = (value) => {
|
|
28
|
+
if (value === undefined) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return BigInt(typeof value === 'number' ? Math.trunc(value) : value);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Builds the model from a decoded jsonParsed Stake-program account. Returns
|
|
40
|
+
* `undefined` when the account is not a parsed stake account (e.g. a non-stake
|
|
41
|
+
* program account or a base64/dataSliced row with no `parsed` tree).
|
|
42
|
+
*/
|
|
43
|
+
export const parseStakeAccount = ({ pubkey, lamports, parsedInfo, }) => {
|
|
44
|
+
// Reject partially-malformed payloads rather than coercing them into
|
|
45
|
+
// fabricated zero/empty values — a bogus `0n` stake or empty authority would
|
|
46
|
+
// surface downstream as wrong balances or a falsely inactive/available state.
|
|
47
|
+
const meta = parsedInfo?.meta;
|
|
48
|
+
if (!meta?.authorized?.staker || !meta.authorized.withdrawer) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const rentExemptReserve = toBigInt(meta.rentExemptReserve);
|
|
52
|
+
if (rentExemptReserve === undefined) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const delegationInfo = parsedInfo?.stake?.delegation;
|
|
56
|
+
let delegation;
|
|
57
|
+
if (delegationInfo) {
|
|
58
|
+
// A delegation object with no `voter` is a malformed row, not an
|
|
59
|
+
// undelegated account — reject it rather than fabricating "inactive".
|
|
60
|
+
if (!delegationInfo.voter) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const activationEpoch = toBigInt(delegationInfo.activationEpoch);
|
|
64
|
+
const deactivationEpoch = toBigInt(delegationInfo.deactivationEpoch);
|
|
65
|
+
const stake = toBigInt(delegationInfo.stake);
|
|
66
|
+
if (activationEpoch === undefined || deactivationEpoch === undefined || stake === undefined) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
delegation = {
|
|
70
|
+
votePubkey: delegationInfo.voter,
|
|
71
|
+
activationEpoch,
|
|
72
|
+
deactivationEpoch,
|
|
73
|
+
stake,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
pubkey,
|
|
78
|
+
lamports,
|
|
79
|
+
rentExemptReserve,
|
|
80
|
+
staker: meta.authorized.staker,
|
|
81
|
+
withdrawer: meta.authorized.withdrawer,
|
|
82
|
+
delegation,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=stakeAccount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stakeAccount.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/staking/models/stakeAccount.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A validator row from `getVoteAccounts` plus an optional metadata enrichment
|
|
3
|
+
* struct (name / logo / APY / score) populated by the metadata-provider seam.
|
|
4
|
+
* The base row is decoded straight off the RPC; `ValidatorMetadata` starts
|
|
5
|
+
* empty so the read layer can ship before the enrichment source is wired.
|
|
6
|
+
*
|
|
7
|
+
* Port of iOS `SolanaValidator` / `ValidatorMetadata`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Off-chain enrichment for a validator. All optional — populated from a
|
|
11
|
+
* metadata source; the base read layer leaves it empty.
|
|
12
|
+
*/
|
|
13
|
+
export type ValidatorMetadata = {
|
|
14
|
+
name?: string;
|
|
15
|
+
logoUrl?: string;
|
|
16
|
+
/** Estimated APY as a fraction (e.g. 0.067 for 6.7%). */
|
|
17
|
+
apyEstimate?: number;
|
|
18
|
+
/** A 0–100 quality score from the metadata source. */
|
|
19
|
+
score?: number;
|
|
20
|
+
};
|
|
21
|
+
export type SolanaValidator = {
|
|
22
|
+
/** Vote account address — the delegation target a stake account points at. */
|
|
23
|
+
votePubkey: string;
|
|
24
|
+
/** The validator's identity (node) pubkey. */
|
|
25
|
+
nodePubkey: string;
|
|
26
|
+
/**
|
|
27
|
+
* Total active stake delegated to this validator, in lamports. Sourced from
|
|
28
|
+
* `getVoteAccounts`, which serializes it as a JSON number — so for very large
|
|
29
|
+
* validators this is already an approximate (>2^53) value. Kept as `number`
|
|
30
|
+
* rather than dressed up as an exact `bigint`; it drives sort / voting-power
|
|
31
|
+
* display only, never balance math.
|
|
32
|
+
*/
|
|
33
|
+
activatedStake: number;
|
|
34
|
+
/** Commission percentage (0–100) the validator takes from rewards. */
|
|
35
|
+
commission: number;
|
|
36
|
+
/** Whether this vote account has voted in the current epoch. */
|
|
37
|
+
epochVoteAccount: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* `true` when the validator is in the delinquent set (not voting). Carried
|
|
40
|
+
* from which `getVoteAccounts` bucket the row came from, not the wire.
|
|
41
|
+
*/
|
|
42
|
+
isDelinquent: boolean;
|
|
43
|
+
/** Enrichment from the metadata provider — name, logo, APY estimate, score. */
|
|
44
|
+
metadata: ValidatorMetadata;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* `prefix…suffix` form of a base58 pubkey for compact display. Returns the
|
|
48
|
+
* input unchanged when it is too short to truncate meaningfully.
|
|
49
|
+
*/
|
|
50
|
+
export declare const truncatedPubkey: (pubkey: string, prefix?: number, suffix?: number) => string;
|
|
51
|
+
/**
|
|
52
|
+
* Name to show in the picker: the enriched metadata name when present,
|
|
53
|
+
* otherwise a truncated vote pubkey. Keeps the display layer independent of
|
|
54
|
+
* whether the metadata provider returned anything.
|
|
55
|
+
*/
|
|
56
|
+
export declare const validatorDisplayName: (validator: SolanaValidator) => string;
|
|
57
|
+
/**
|
|
58
|
+
* The validator logo URL, or `undefined` when no metadata source supplied one —
|
|
59
|
+
* the display layer then renders a deterministic placeholder.
|
|
60
|
+
*/
|
|
61
|
+
export declare const validatorLogoUrl: (validator: SolanaValidator) => string | undefined;
|
|
62
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/staking/models/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,gEAAgE;IAChE,gBAAgB,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAA;IACrB,+EAA+E;IAC/E,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,EAAE,eAAU,EAAE,eAAU,KAAG,MAC6B,CAAA;AAEtG;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,WAAW,eAAe,KAAG,MAMjE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,WAAW,eAAe,KAAG,MAAM,GAAG,SAGtE,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A validator row from `getVoteAccounts` plus an optional metadata enrichment
|
|
3
|
+
* struct (name / logo / APY / score) populated by the metadata-provider seam.
|
|
4
|
+
* The base row is decoded straight off the RPC; `ValidatorMetadata` starts
|
|
5
|
+
* empty so the read layer can ship before the enrichment source is wired.
|
|
6
|
+
*
|
|
7
|
+
* Port of iOS `SolanaValidator` / `ValidatorMetadata`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* `prefix…suffix` form of a base58 pubkey for compact display. Returns the
|
|
11
|
+
* input unchanged when it is too short to truncate meaningfully.
|
|
12
|
+
*/
|
|
13
|
+
export const truncatedPubkey = (pubkey, prefix = 4, suffix = 4) => pubkey.length > prefix + suffix + 1 ? `${pubkey.slice(0, prefix)}…${pubkey.slice(-suffix)}` : pubkey;
|
|
14
|
+
/**
|
|
15
|
+
* Name to show in the picker: the enriched metadata name when present,
|
|
16
|
+
* otherwise a truncated vote pubkey. Keeps the display layer independent of
|
|
17
|
+
* whether the metadata provider returned anything.
|
|
18
|
+
*/
|
|
19
|
+
export const validatorDisplayName = (validator) => {
|
|
20
|
+
const name = validator.metadata.name?.trim();
|
|
21
|
+
if (name) {
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
24
|
+
return truncatedPubkey(validator.votePubkey);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The validator logo URL, or `undefined` when no metadata source supplied one —
|
|
28
|
+
* the display layer then renders a deterministic placeholder.
|
|
29
|
+
*/
|
|
30
|
+
export const validatorLogoUrl = (validator) => {
|
|
31
|
+
const raw = validator.metadata.logoUrl?.trim();
|
|
32
|
+
return raw ? raw : undefined;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/staking/models/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyCH;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAc,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAU,EAAE,CAChF,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;AAEtG;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAA0B,EAAU,EAAE;IACzE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAA;IAC5C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;AAC9C,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAA0B,EAAsB,EAAE;IACjF,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,CAAA;IAC9C,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAC9B,CAAC,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SolanaStakeAccount } from './models/stakeAccount.js';
|
|
2
|
+
import { SolanaValidator } from './models/validator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Read-side Solana RPC for native staking. Thin wrappers over the shared
|
|
5
|
+
* `@solana/web3.js` connection (`getSolanaClient`) so the staking read layer
|
|
6
|
+
* stays one call away from the rest of the Solana chain code.
|
|
7
|
+
*
|
|
8
|
+
* Port of the Solana staking reads in iOS `SolanaService` / `SolanaAPI`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Lists every validator from `getVoteAccounts`, tagging each with the
|
|
12
|
+
* delinquent flag derived from its bucket (`current` vs `delinquent`). The base
|
|
13
|
+
* metadata is left empty — the metadata-provider seam enriches it later.
|
|
14
|
+
*/
|
|
15
|
+
export declare const fetchSolanaValidators: () => Promise<SolanaValidator[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Fetches the owner's stake accounts via a Stake-program `getProgramAccounts`
|
|
18
|
+
* scan filtered on `dataSize: 200` (fully-initialized stake accounts) and a
|
|
19
|
+
* memcmp on the staker authority at offset 12. Uncached at the call site — the
|
|
20
|
+
* staking view must reflect just-submitted txs and newly accrued rewards.
|
|
21
|
+
*/
|
|
22
|
+
export declare const fetchSolanaStakeAccounts: (owner: string) => Promise<SolanaStakeAccount[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Fetches a single stake account's parsed state by address. Used by the
|
|
25
|
+
* unstake / withdraw / move flows that operate on a known account.
|
|
26
|
+
*/
|
|
27
|
+
export declare const fetchSolanaStakeAccount: (pubkey: string) => Promise<SolanaStakeAccount | undefined>;
|
|
28
|
+
export type SolanaEpochInfo = {
|
|
29
|
+
epoch: bigint;
|
|
30
|
+
slotIndex: bigint;
|
|
31
|
+
slotsInEpoch: bigint;
|
|
32
|
+
};
|
|
33
|
+
/** Current epoch info — drives activation-state derivation and cooldown copy. */
|
|
34
|
+
export declare const fetchSolanaEpochInfo: () => Promise<SolanaEpochInfo>;
|
|
35
|
+
/**
|
|
36
|
+
* The rent-exempt reserve for a 200-byte stake account, in lamports. The new
|
|
37
|
+
* stake account must be funded with this on top of the delegated amount.
|
|
38
|
+
*/
|
|
39
|
+
export declare const fetchSolanaRentReserve: () => Promise<bigint>;
|
|
40
|
+
/** Network inflation rate (total) — drives the on-chain APY fallback. */
|
|
41
|
+
export declare const fetchSolanaInflationRate: () => Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Total SOL supply in lamports — the denominator for the staked fraction in the
|
|
44
|
+
* APY fallback. `getSupply` returns a JSON number that exceeds 2^53, so it is
|
|
45
|
+
* already approximate; kept as `number` (the ratio it feeds only needs ~2dp),
|
|
46
|
+
* not minted into a falsely-exact bigint.
|
|
47
|
+
*/
|
|
48
|
+
export declare const fetchSolanaTotalSupply: () => Promise<number>;
|
|
49
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/rpc.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEpD;;;;;;GAMG;AAEH;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,eAAe,EAAE,CAiBvE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,kBAAkB,EAAE,CAqB1F,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAWpG,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,eAAe,CAQpE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,MAAM,CAI7D,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,MAAM,CAI/D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,MAAM,CAI7D,CAAA"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { getSolanaClient } from '../client.js';
|
|
3
|
+
import { solanaStakingConfig } from './config.js';
|
|
4
|
+
import { parseStakeAccount } from './models/stakeAccount.js';
|
|
5
|
+
/**
|
|
6
|
+
* Read-side Solana RPC for native staking. Thin wrappers over the shared
|
|
7
|
+
* `@solana/web3.js` connection (`getSolanaClient`) so the staking read layer
|
|
8
|
+
* stays one call away from the rest of the Solana chain code.
|
|
9
|
+
*
|
|
10
|
+
* Port of the Solana staking reads in iOS `SolanaService` / `SolanaAPI`.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Lists every validator from `getVoteAccounts`, tagging each with the
|
|
14
|
+
* delinquent flag derived from its bucket (`current` vs `delinquent`). The base
|
|
15
|
+
* metadata is left empty — the metadata-provider seam enriches it later.
|
|
16
|
+
*/
|
|
17
|
+
export const fetchSolanaValidators = async () => {
|
|
18
|
+
const client = getSolanaClient();
|
|
19
|
+
const { current, delinquent } = await client.getVoteAccounts();
|
|
20
|
+
const toValidator = (account, isDelinquent) => ({
|
|
21
|
+
votePubkey: account.votePubkey,
|
|
22
|
+
nodePubkey: account.nodePubkey,
|
|
23
|
+
// `activatedStake` arrives from the RPC as a JSON number — keep it as-is
|
|
24
|
+
// rather than minting a falsely-exact bigint from an already-lossy value.
|
|
25
|
+
activatedStake: account.activatedStake,
|
|
26
|
+
commission: account.commission,
|
|
27
|
+
epochVoteAccount: account.epochVoteAccount,
|
|
28
|
+
isDelinquent,
|
|
29
|
+
metadata: {},
|
|
30
|
+
});
|
|
31
|
+
return [...current.map(a => toValidator(a, false)), ...delinquent.map(a => toValidator(a, true))];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Fetches the owner's stake accounts via a Stake-program `getProgramAccounts`
|
|
35
|
+
* scan filtered on `dataSize: 200` (fully-initialized stake accounts) and a
|
|
36
|
+
* memcmp on the staker authority at offset 12. Uncached at the call site — the
|
|
37
|
+
* staking view must reflect just-submitted txs and newly accrued rewards.
|
|
38
|
+
*/
|
|
39
|
+
export const fetchSolanaStakeAccounts = async (owner) => {
|
|
40
|
+
const client = getSolanaClient();
|
|
41
|
+
const rows = await client.getParsedProgramAccounts(new PublicKey(solanaStakingConfig.stakeProgramId), {
|
|
42
|
+
filters: [
|
|
43
|
+
{ dataSize: solanaStakingConfig.stakeStateSize },
|
|
44
|
+
{ memcmp: { offset: solanaStakingConfig.stakerMemcmpOffset, bytes: owner } },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
return rows.flatMap(({ pubkey, account }) => {
|
|
48
|
+
const { data } = account;
|
|
49
|
+
if (!('parsed' in data)) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const parsed = parseStakeAccount({
|
|
53
|
+
pubkey: pubkey.toBase58(),
|
|
54
|
+
lamports: BigInt(account.lamports),
|
|
55
|
+
parsedInfo: data.parsed?.info,
|
|
56
|
+
});
|
|
57
|
+
return parsed ? [parsed] : [];
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Fetches a single stake account's parsed state by address. Used by the
|
|
62
|
+
* unstake / withdraw / move flows that operate on a known account.
|
|
63
|
+
*/
|
|
64
|
+
export const fetchSolanaStakeAccount = async (pubkey) => {
|
|
65
|
+
const client = getSolanaClient();
|
|
66
|
+
const { value } = await client.getParsedAccountInfo(new PublicKey(pubkey));
|
|
67
|
+
if (!value || !('parsed' in value.data)) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
return parseStakeAccount({
|
|
71
|
+
pubkey,
|
|
72
|
+
lamports: BigInt(value.lamports),
|
|
73
|
+
parsedInfo: value.data.parsed?.info,
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
/** Current epoch info — drives activation-state derivation and cooldown copy. */
|
|
77
|
+
export const fetchSolanaEpochInfo = async () => {
|
|
78
|
+
const client = getSolanaClient();
|
|
79
|
+
const info = await client.getEpochInfo();
|
|
80
|
+
return {
|
|
81
|
+
epoch: BigInt(info.epoch),
|
|
82
|
+
slotIndex: BigInt(info.slotIndex),
|
|
83
|
+
slotsInEpoch: BigInt(info.slotsInEpoch),
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* The rent-exempt reserve for a 200-byte stake account, in lamports. The new
|
|
88
|
+
* stake account must be funded with this on top of the delegated amount.
|
|
89
|
+
*/
|
|
90
|
+
export const fetchSolanaRentReserve = async () => {
|
|
91
|
+
const client = getSolanaClient();
|
|
92
|
+
const lamports = await client.getMinimumBalanceForRentExemption(solanaStakingConfig.stakeStateSize);
|
|
93
|
+
return BigInt(lamports);
|
|
94
|
+
};
|
|
95
|
+
/** Network inflation rate (total) — drives the on-chain APY fallback. */
|
|
96
|
+
export const fetchSolanaInflationRate = async () => {
|
|
97
|
+
const client = getSolanaClient();
|
|
98
|
+
const { total } = await client.getInflationRate();
|
|
99
|
+
return total;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Total SOL supply in lamports — the denominator for the staked fraction in the
|
|
103
|
+
* APY fallback. `getSupply` returns a JSON number that exceeds 2^53, so it is
|
|
104
|
+
* already approximate; kept as `number` (the ratio it feeds only needs ~2dp),
|
|
105
|
+
* not minted into a falsely-exact bigint.
|
|
106
|
+
*/
|
|
107
|
+
export const fetchSolanaTotalSupply = async () => {
|
|
108
|
+
const client = getSolanaClient();
|
|
109
|
+
const { value } = await client.getSupply();
|
|
110
|
+
return value.total;
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/staking/rpc.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/core-chain",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "Blockchain chain logic shared across Vultisig clients",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -680,6 +680,31 @@
|
|
|
680
680
|
"import": "./dist/chains/solana/spl/getSplAssociatedAccount.js",
|
|
681
681
|
"default": "./dist/chains/solana/spl/getSplAssociatedAccount.js"
|
|
682
682
|
},
|
|
683
|
+
"./chains/solana/staking/config": {
|
|
684
|
+
"types": "./dist/chains/solana/staking/config.d.ts",
|
|
685
|
+
"import": "./dist/chains/solana/staking/config.js",
|
|
686
|
+
"default": "./dist/chains/solana/staking/config.js"
|
|
687
|
+
},
|
|
688
|
+
"./chains/solana/staking/cooldownGate": {
|
|
689
|
+
"types": "./dist/chains/solana/staking/cooldownGate.d.ts",
|
|
690
|
+
"import": "./dist/chains/solana/staking/cooldownGate.js",
|
|
691
|
+
"default": "./dist/chains/solana/staking/cooldownGate.js"
|
|
692
|
+
},
|
|
693
|
+
"./chains/solana/staking/models/stakeAccount": {
|
|
694
|
+
"types": "./dist/chains/solana/staking/models/stakeAccount.d.ts",
|
|
695
|
+
"import": "./dist/chains/solana/staking/models/stakeAccount.js",
|
|
696
|
+
"default": "./dist/chains/solana/staking/models/stakeAccount.js"
|
|
697
|
+
},
|
|
698
|
+
"./chains/solana/staking/models/validator": {
|
|
699
|
+
"types": "./dist/chains/solana/staking/models/validator.d.ts",
|
|
700
|
+
"import": "./dist/chains/solana/staking/models/validator.js",
|
|
701
|
+
"default": "./dist/chains/solana/staking/models/validator.js"
|
|
702
|
+
},
|
|
703
|
+
"./chains/solana/staking/rpc": {
|
|
704
|
+
"types": "./dist/chains/solana/staking/rpc.d.ts",
|
|
705
|
+
"import": "./dist/chains/solana/staking/rpc.js",
|
|
706
|
+
"default": "./dist/chains/solana/staking/rpc.js"
|
|
707
|
+
},
|
|
683
708
|
"./chains/sui/buildTransactionFromJson": {
|
|
684
709
|
"types": "./dist/chains/sui/buildTransactionFromJson.d.ts",
|
|
685
710
|
"import": "./dist/chains/sui/buildTransactionFromJson.js",
|