@sly-rentals/core 1.1.2 → 1.2.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.
Files changed (61) hide show
  1. package/dist/api.json +8611 -6670
  2. package/dist/cjs/instructions/acceptRental.js +39 -53
  3. package/dist/cjs/instructions/acceptRental.js.map +1 -1
  4. package/dist/cjs/instructions/closeContract.js +15 -13
  5. package/dist/cjs/instructions/closeContract.js.map +1 -1
  6. package/dist/cjs/instructions/closeRental.js +19 -15
  7. package/dist/cjs/instructions/closeRental.js.map +1 -1
  8. package/dist/cjs/instructions/reserveRental.js +34 -46
  9. package/dist/cjs/instructions/reserveRental.js.map +1 -1
  10. package/dist/cjs/legacy/index.js +1 -0
  11. package/dist/cjs/legacy/index.js.map +1 -1
  12. package/dist/cjs/package.json +1 -1
  13. package/dist/cjs/utils/bidMath.js +6 -115
  14. package/dist/cjs/utils/bidMath.js.map +1 -1
  15. package/dist/cjs/utils/contractSnapshot.js +207 -0
  16. package/dist/cjs/utils/contractSnapshot.js.map +1 -0
  17. package/dist/cjs/utils/contractSnapshot.test.js +247 -0
  18. package/dist/cjs/utils/contractSnapshot.test.js.map +1 -0
  19. package/dist/cjs/utils/index.js +8 -3
  20. package/dist/cjs/utils/index.js.map +1 -1
  21. package/dist/cjs/version.js +1 -1
  22. package/dist/esm/instructions/acceptRental.js +40 -54
  23. package/dist/esm/instructions/acceptRental.js.map +1 -1
  24. package/dist/esm/instructions/closeContract.js +15 -13
  25. package/dist/esm/instructions/closeContract.js.map +1 -1
  26. package/dist/esm/instructions/closeRental.js +20 -16
  27. package/dist/esm/instructions/closeRental.js.map +1 -1
  28. package/dist/esm/instructions/reserveRental.js +34 -46
  29. package/dist/esm/instructions/reserveRental.js.map +1 -1
  30. package/dist/esm/legacy/index.js +1 -0
  31. package/dist/esm/legacy/index.js.map +1 -1
  32. package/dist/esm/package.json +1 -1
  33. package/dist/esm/utils/bidMath.js +6 -114
  34. package/dist/esm/utils/bidMath.js.map +1 -1
  35. package/dist/esm/utils/contractSnapshot.js +201 -0
  36. package/dist/esm/utils/contractSnapshot.js.map +1 -0
  37. package/dist/esm/utils/contractSnapshot.test.js +245 -0
  38. package/dist/esm/utils/contractSnapshot.test.js.map +1 -0
  39. package/dist/esm/utils/index.js +4 -2
  40. package/dist/esm/utils/index.js.map +1 -1
  41. package/dist/esm/version.js +1 -1
  42. package/dist/types/instructions/acceptRental.d.ts +8 -0
  43. package/dist/types/instructions/acceptRental.d.ts.map +1 -1
  44. package/dist/types/instructions/closeContract.d.ts +9 -0
  45. package/dist/types/instructions/closeContract.d.ts.map +1 -1
  46. package/dist/types/instructions/closeRental.d.ts +8 -0
  47. package/dist/types/instructions/closeRental.d.ts.map +1 -1
  48. package/dist/types/instructions/reserveRental.d.ts +8 -0
  49. package/dist/types/instructions/reserveRental.d.ts.map +1 -1
  50. package/dist/types/legacy/index.d.ts +1 -0
  51. package/dist/types/legacy/index.d.ts.map +1 -1
  52. package/dist/types/utils/bidMath.d.ts +6 -44
  53. package/dist/types/utils/bidMath.d.ts.map +1 -1
  54. package/dist/types/utils/contractSnapshot.d.ts +123 -0
  55. package/dist/types/utils/contractSnapshot.d.ts.map +1 -0
  56. package/dist/types/utils/contractSnapshot.test.d.ts +2 -0
  57. package/dist/types/utils/contractSnapshot.test.d.ts.map +1 -0
  58. package/dist/types/utils/index.d.ts +2 -1
  59. package/dist/types/utils/index.d.ts.map +1 -1
  60. package/dist/types/version.d.ts +1 -1
  61. package/package.json +1 -1
@@ -1,23 +1,15 @@
1
1
  "use strict";
2
2
  /**
3
- * @purpose Reservation bid math helpers
3
+ * @purpose Reservation bid math (pure formula + type)
4
4
  *
5
- * Pure-math + on-chain-fetch helpers for computing the contest minimum-bid
6
- * floor that a challenger must clear to take an existing reservation.
7
- * Mirrors the on-chain `ConfigState::bid_min_stardust` formula so client UIs
8
- * (and on-chain-aware tooling) can preview the floor without hitting an RPC
9
- * for every keystroke.
5
+ * Mirror of the on-chain `ConfigState::bid_min_stardust` formula so UIs
6
+ * can preview the contest minimum-bid floor without hitting an RPC for
7
+ * every keystroke. Fetch-aware helpers (`getMinimumBid`,
8
+ * `computeMinimumBidFromSnapshot`) live in `./contractSnapshot` they
9
+ * call into the pure formula here.
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.computeMinimumBid = computeMinimumBid;
13
- exports.getMinimumBid = getMinimumBid;
14
- const config_1 = require("../accounts/config");
15
- const contract_1 = require("../accounts/contract");
16
- const rental_1 = require("../accounts/rental");
17
- const srsly_1 = require("../pda/srsly");
18
- const config_2 = require("./config");
19
- const rpc_1 = require("./rpc");
20
- const SYSTEM_PROGRAM_ID = '11111111111111111111111111111111';
21
13
  /**
22
14
  * Pure math: contest minimum-bid floor in stardust.
23
15
  *
@@ -46,105 +38,4 @@ function computeMinimumBid(args) {
46
38
  const base = args.rateStardust > defenderBid ? args.rateStardust : defenderBid;
47
39
  return (base * effBps) / 10000n;
48
40
  }
49
- /**
50
- * High-level helper: compute the contest minimum bid for a contract right
51
- * now (or at `now + delaySeconds`).
52
- *
53
- * Fetches `ConfigState`, `ContractState`, and the active/queued `RentalState`
54
- * accounts, derives `closeness` from the active rental window, and returns
55
- * the floor a challenger must clear plus enough context to render a UI.
56
- *
57
- * @example
58
- * ```ts
59
- * const floor = await getMinimumBid({ contractAddress: 'Abc...' });
60
- * console.log('Bid at least', floor.minBidStardust, 'stardust');
61
- *
62
- * // Preview the floor 4 hours from now (snipe-window pricing):
63
- * const later = await getMinimumBid({
64
- * contractAddress: 'Abc...',
65
- * delaySeconds: 4 * 60 * 60,
66
- * });
67
- * ```
68
- *
69
- * If the contract has no active rental yet, closeness = 0 and the floor
70
- * collapses to the rate-bump floor (`rate × captureRate`).
71
- */
72
- async function getMinimumBid(args) {
73
- const rpcUrl = args.rpcUrl ?? (0, config_2.getRpcUrl)();
74
- const rpc = (0, rpc_1.createRpc)(rpcUrl);
75
- const cfgPromise = (0, config_1.fetchConfig)(rpcUrl);
76
- const contractPromise = (0, contract_1.fetchContract)(args.contractAddress, rpcUrl);
77
- const [cfg, contract] = await Promise.all([cfgPromise, contractPromise]);
78
- const cfgData = cfg.data;
79
- const contractData = contract.data;
80
- const rateStardust = BigInt(contractData.rate);
81
- const atlasPerPoint = args.atlasPerPoint ?? BigInt(cfgData.atlasPerPoint);
82
- const stardustPerAtlas = BigInt(cfgData.stardustToAtlas);
83
- const activeAddr = await (0, srsly_1.deriveActiveRental)(contract.address);
84
- const queuedAddr = await (0, srsly_1.deriveQueuedRental)(contract.address);
85
- // Active rental — only meaningful if the contract field points at it.
86
- let activeStart = null;
87
- let activeEnd = null;
88
- if (contractData.activeRental && contractData.activeRental.toString() !== SYSTEM_PROGRAM_ID) {
89
- try {
90
- const active = await (0, rental_1.fetchRental)(activeAddr, rpcUrl);
91
- const a = active.data;
92
- activeStart = Number(a.startTime);
93
- activeEnd = Number(a.endTime);
94
- }
95
- catch {
96
- // Account missing despite contract pointer — treat as no active rental.
97
- }
98
- }
99
- // Queued rental — defender bid lives here if a reservation exists.
100
- let defenderBidStardust = 0n;
101
- if (contractData.queuedRental && contractData.queuedRental.toString() !== SYSTEM_PROGRAM_ID) {
102
- try {
103
- const queued = await (0, rental_1.fetchRental)(queuedAddr, rpcUrl);
104
- const q = queued.data;
105
- const bidAtlas = BigInt(q.bidAtlas);
106
- const bidPoints = BigInt(q.bidPoints);
107
- // Points are 8-decimal dust; converting to stardust requires the same
108
- // 8-decimal precision: stardust = points_dust * atlasPerPoint *
109
- // stardustPerAtlas / 1e8. With both at 1e8 precision this collapses
110
- // to points_dust * atlasPerPoint.
111
- const pointsAsStardust = bidPoints > 0n ? (bidPoints * atlasPerPoint * stardustPerAtlas) / 100000000n : 0n;
112
- defenderBidStardust = bidAtlas + pointsAsStardust;
113
- }
114
- catch {
115
- // Missing queued account — leave defenderBidStardust = 0.
116
- }
117
- }
118
- const evaluatedAtSeconds = args.nowSeconds !== undefined
119
- ? Math.floor(args.nowSeconds)
120
- : Math.floor(Date.now() / 1000) + Math.max(0, args.delaySeconds ?? 0);
121
- let closeness = 0;
122
- if (activeStart !== null && activeEnd !== null && activeEnd > activeStart) {
123
- const span = activeEnd - activeStart;
124
- const elapsed = evaluatedAtSeconds - activeStart;
125
- closeness = Math.max(0, Math.min(1, elapsed / span));
126
- }
127
- const minBidStardust = computeMinimumBid({
128
- rateStardust,
129
- defenderBidStardust,
130
- contestedMultiplierMaxBps: cfgData.contestedMultiplierMaxBps,
131
- captureRateBps: BigInt(cfgData.captureRateBps),
132
- closenessFraction: closeness,
133
- });
134
- const baseStardust = rateStardust > defenderBidStardust ? rateStardust : defenderBidStardust;
135
- const rampMultiplier = baseStardust > 0n ? Number(minBidStardust) / Number(baseStardust) : 1;
136
- // RPC reference kept to match the codebase pattern even when unused;
137
- // future refinements (e.g. fetching chain time) can plug in here.
138
- void rpc;
139
- return {
140
- minBidStardust,
141
- defenderBidStardust,
142
- rateStardust,
143
- closenessFraction: closeness,
144
- rampMultiplier,
145
- evaluatedAtSeconds,
146
- activeEndSeconds: activeEnd,
147
- activeStartSeconds: activeStart,
148
- };
149
- }
150
41
  //# sourceMappingURL=bidMath.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bidMath.js","sourceRoot":"","sources":["../../../src/utils/bidMath.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bidMath.js","sourceRoot":"","sources":["../../../src/utils/bidMath.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAiBH,8CAkBC;AAjCD;;;;;;;;;;;;;;GAcG;AACH,SAAgB,iBAAiB,CAAC,IAMjC;IACC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,kEAAkE;IAClE,MAAM,SAAS,GAAG,MAAO,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,GAAG,MAAO,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAO,CAAC;IAC7E,MAAM,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;IAC/E,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,MAAO,CAAC;AACnC,CAAC"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * @purpose Aggregated point-in-time view of a contract and its rentals
4
+ *
5
+ * One-shot fetch that pulls every on-chain account relevant to a single
6
+ * contract — `ConfigState`, `ContractState`, and the active / queued
7
+ * `RentalState`s (when they exist) — and also computes the contest
8
+ * minimum-bid floor evaluated at "now". The raw account states are
9
+ * exposed verbatim so callers decide what matters; `minimumBid` is the
10
+ * one piece of derived data that nearly every consumer of this snapshot
11
+ * needs.
12
+ *
13
+ * Granular `fetchConfig` / `fetchContract` / `fetchRental` remain
14
+ * available for narrow lookups that don't need the whole picture.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getContractSnapshot = getContractSnapshot;
18
+ exports.resolveContractSnapshot = resolveContractSnapshot;
19
+ exports.computeMinimumBidFromSnapshot = computeMinimumBidFromSnapshot;
20
+ exports.getMinimumBid = getMinimumBid;
21
+ const kit_1 = require("@solana/kit");
22
+ const config_1 = require("../accounts/config");
23
+ const contract_1 = require("../accounts/contract");
24
+ const rental_1 = require("../accounts/rental");
25
+ const srsly_1 = require("../pda/srsly");
26
+ const config_2 = require("./config");
27
+ const bidMath_1 = require("./bidMath");
28
+ const SYSTEM_PROGRAM_ID = '11111111111111111111111111111111';
29
+ /**
30
+ * Fetch a contract and every account directly attached to it in one shot,
31
+ * then derive the contest minimum-bid floor at "now".
32
+ *
33
+ * Strategy: fetch `ConfigState` and `ContractState` in parallel, then read
34
+ * the contract's `activeRental` / `queuedRental` pointers and fetch
35
+ * whichever ones exist (in parallel). Pointers that equal SystemProgram
36
+ * are skipped without an RPC call. The bid floor is computed locally
37
+ * once all states are in.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const snap = await getContractSnapshot({ contractAddress: 'Abc...' });
42
+ * const rate = snap.contract.data.rate;
43
+ * const defenderBid = snap.queuedRental?.data.bidAtlas ?? 0n;
44
+ * const floorNow = snap.minimumBid.minBidStardust;
45
+ *
46
+ * // Project the floor 4 hours forward without re-fetching:
47
+ * const floorLater = computeMinimumBidFromSnapshot(snap, {
48
+ * delaySeconds: 4 * 60 * 60,
49
+ * });
50
+ * ```
51
+ */
52
+ async function getContractSnapshot(args) {
53
+ const rpcUrl = args.rpcUrl ?? (0, config_2.getRpcUrl)();
54
+ const [config, contract] = await Promise.all([
55
+ (0, config_1.fetchConfig)(rpcUrl),
56
+ (0, contract_1.fetchContract)(args.contractAddress, rpcUrl),
57
+ ]);
58
+ const contractData = contract.data;
59
+ const activePromise = contractData.activeRental && contractData.activeRental.toString() !== SYSTEM_PROGRAM_ID
60
+ ? (0, srsly_1.deriveActiveRental)(contract.address)
61
+ .then(addr => (0, rental_1.fetchRental)(addr, rpcUrl))
62
+ .catch(() => null)
63
+ : Promise.resolve(null);
64
+ const queuedPromise = contractData.queuedRental && contractData.queuedRental.toString() !== SYSTEM_PROGRAM_ID
65
+ ? (0, srsly_1.deriveQueuedRental)(contract.address)
66
+ .then(addr => (0, rental_1.fetchRental)(addr, rpcUrl))
67
+ .catch(() => null)
68
+ : Promise.resolve(null);
69
+ const [activeRental, queuedRental] = await Promise.all([activePromise, queuedPromise]);
70
+ const partialSnap = { config, contract, activeRental, queuedRental };
71
+ const minimumBid = computeMinimumBidFromSnapshot(partialSnap);
72
+ return { ...partialSnap, minimumBid };
73
+ }
74
+ /**
75
+ * Resolve a `ContractSnapshot` from caller-supplied data or fetch fresh.
76
+ *
77
+ * Designed for callers (e.g. UIs) that already have a snapshot in hand and
78
+ * want to skip the RPC roundtrip when building an instruction. Behavior:
79
+ *
80
+ * 1. If no snapshot is supplied → fetch a fresh one.
81
+ * 2. If snapshot's contract address doesn't match `contractAddress` →
82
+ * throw immediately (programmer error).
83
+ * 3. If snapshot's rental fields are stale relative to the contract's
84
+ * pointers (contract says a rental exists but snapshot has `null` —
85
+ * typical when the snapshot was fetched mid-state-change) → lazy
86
+ * refetch the snapshot once.
87
+ * 4. If still stale after the refetch → throw. The on-chain reality
88
+ * conflicts with itself; let the caller decide how to recover.
89
+ */
90
+ async function resolveContractSnapshot(args) {
91
+ if (!args.snapshot) {
92
+ return getContractSnapshot({
93
+ contractAddress: args.contractAddress,
94
+ rpcUrl: args.rpcUrl,
95
+ });
96
+ }
97
+ const requested = (0, kit_1.address)(args.contractAddress);
98
+ if (args.snapshot.contract.address !== requested) {
99
+ throw new Error(`Provided snapshot is for contract ${args.snapshot.contract.address}, expected ${requested}`);
100
+ }
101
+ if (!isSnapshotStale(args.snapshot)) {
102
+ return args.snapshot;
103
+ }
104
+ const fresh = await getContractSnapshot({
105
+ contractAddress: args.contractAddress,
106
+ rpcUrl: args.rpcUrl,
107
+ });
108
+ if (isSnapshotStale(fresh)) {
109
+ throw new Error(`Contract ${requested} has a rental pointer set but the rental account could not be loaded after lazy refetch`);
110
+ }
111
+ return fresh;
112
+ }
113
+ function isSnapshotStale(snap) {
114
+ const activeStale = snap.contract.data.activeRental.toString() !== SYSTEM_PROGRAM_ID && !snap.activeRental;
115
+ const queuedStale = snap.contract.data.queuedRental.toString() !== SYSTEM_PROGRAM_ID && !snap.queuedRental;
116
+ return activeStale || queuedStale;
117
+ }
118
+ /**
119
+ * Pure derivation of `MinimumBid` from an already-fetched snapshot. No RPC.
120
+ *
121
+ * Use when the caller has a snapshot and wants the floor at a custom time
122
+ * projection (`delaySeconds` / `nowSeconds`) or with an overridden
123
+ * `atlasPerPoint` ratio. For the at-fetch-time floor, read
124
+ * `snap.minimumBid` directly.
125
+ */
126
+ function computeMinimumBidFromSnapshot(snap, opts = {}) {
127
+ const cfgData = snap.config.data;
128
+ const contractData = snap.contract.data;
129
+ const rateStardust = BigInt(contractData.rate);
130
+ const atlasPerPoint = opts.atlasPerPoint ?? BigInt(cfgData.atlasPerPoint);
131
+ const stardustPerAtlas = BigInt(cfgData.stardustToAtlas);
132
+ const activeStart = snap.activeRental ? Number(snap.activeRental.data.startTime) : null;
133
+ const activeEnd = snap.activeRental ? Number(snap.activeRental.data.endTime) : null;
134
+ let defenderBidStardust = 0n;
135
+ if (snap.queuedRental) {
136
+ const q = snap.queuedRental.data;
137
+ const bidAtlas = BigInt(q.bidAtlas);
138
+ const bidPoints = BigInt(q.bidPoints);
139
+ // Points are 8-decimal dust; converting to stardust requires the same
140
+ // 8-decimal precision: stardust = points_dust * atlasPerPoint *
141
+ // stardustPerAtlas / 1e8. With both at 1e8 precision this collapses
142
+ // to points_dust * atlasPerPoint.
143
+ const pointsAsStardust = bidPoints > 0n ? (bidPoints * atlasPerPoint * stardustPerAtlas) / 100000000n : 0n;
144
+ defenderBidStardust = bidAtlas + pointsAsStardust;
145
+ }
146
+ const evaluatedAtSeconds = opts.nowSeconds !== undefined
147
+ ? Math.floor(opts.nowSeconds)
148
+ : Math.floor(Date.now() / 1000) + Math.max(0, opts.delaySeconds ?? 0);
149
+ let closeness = 0;
150
+ if (activeStart !== null && activeEnd !== null && activeEnd > activeStart) {
151
+ const span = activeEnd - activeStart;
152
+ const elapsed = evaluatedAtSeconds - activeStart;
153
+ closeness = Math.max(0, Math.min(1, elapsed / span));
154
+ }
155
+ const minBidStardust = (0, bidMath_1.computeMinimumBid)({
156
+ rateStardust,
157
+ defenderBidStardust,
158
+ contestedMultiplierMaxBps: cfgData.contestedMultiplierMaxBps,
159
+ captureRateBps: BigInt(cfgData.captureRateBps),
160
+ closenessFraction: closeness,
161
+ });
162
+ const baseStardust = rateStardust > defenderBidStardust ? rateStardust : defenderBidStardust;
163
+ const rampMultiplier = baseStardust > 0n ? Number(minBidStardust) / Number(baseStardust) : 1;
164
+ return {
165
+ minBidStardust,
166
+ defenderBidStardust,
167
+ rateStardust,
168
+ closenessFraction: closeness,
169
+ rampMultiplier,
170
+ evaluatedAtSeconds,
171
+ activeEndSeconds: activeEnd,
172
+ activeStartSeconds: activeStart,
173
+ };
174
+ }
175
+ /**
176
+ * Convenience wrapper: fetch a snapshot and return only its `minimumBid`.
177
+ *
178
+ * Same fetches as `getContractSnapshot` — if you need the contract / rental
179
+ * states too, call `getContractSnapshot` directly so you don't fetch twice.
180
+ *
181
+ * For time-projected floors, pass `delaySeconds` or `nowSeconds`; the
182
+ * underlying fetch is identical.
183
+ */
184
+ async function getMinimumBid(args) {
185
+ if (args.snapshot) {
186
+ return computeMinimumBidFromSnapshot(args.snapshot, {
187
+ delaySeconds: args.delaySeconds,
188
+ nowSeconds: args.nowSeconds,
189
+ atlasPerPoint: args.atlasPerPoint,
190
+ });
191
+ }
192
+ const snap = await getContractSnapshot({
193
+ contractAddress: args.contractAddress,
194
+ rpcUrl: args.rpcUrl,
195
+ });
196
+ if (args.delaySeconds === undefined &&
197
+ args.nowSeconds === undefined &&
198
+ args.atlasPerPoint === undefined) {
199
+ return snap.minimumBid;
200
+ }
201
+ return computeMinimumBidFromSnapshot(snap, {
202
+ delaySeconds: args.delaySeconds,
203
+ nowSeconds: args.nowSeconds,
204
+ atlasPerPoint: args.atlasPerPoint,
205
+ });
206
+ }
207
+ //# sourceMappingURL=contractSnapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractSnapshot.js","sourceRoot":"","sources":["../../../src/utils/contractSnapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ vitest_1.vi.mock('../accounts/config', () => ({
5
+ fetchConfig: vitest_1.vi.fn(),
6
+ }));
7
+ vitest_1.vi.mock('../accounts/contract', () => ({
8
+ fetchContract: vitest_1.vi.fn(),
9
+ }));
10
+ vitest_1.vi.mock('../accounts/rental', () => ({
11
+ fetchRental: vitest_1.vi.fn(),
12
+ }));
13
+ vitest_1.vi.mock('../pda/srsly', () => ({
14
+ deriveActiveRental: vitest_1.vi.fn(),
15
+ deriveQueuedRental: vitest_1.vi.fn(),
16
+ }));
17
+ vitest_1.vi.mock('./config', () => ({
18
+ getRpcUrl: () => 'http://localhost:8899',
19
+ }));
20
+ const config_1 = require("../accounts/config");
21
+ const contract_1 = require("../accounts/contract");
22
+ const rental_1 = require("../accounts/rental");
23
+ const srsly_1 = require("../pda/srsly");
24
+ const contractSnapshot_1 = require("./contractSnapshot");
25
+ const SYSTEM = '11111111111111111111111111111111';
26
+ // Real validated 32-byte base58 addresses for test fixtures.
27
+ const CONTRACT_ADDR = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
28
+ const ACTIVE_ADDR = 'So11111111111111111111111111111111111111112';
29
+ const QUEUED_ADDR = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
30
+ const OTHER_ADDR = 'BPFLoader2111111111111111111111111111111111';
31
+ const VAULT_ADDR = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
32
+ const makeConfig = (overrides = {}) => ({
33
+ stardustToAtlas: 100000000n,
34
+ atlasPerPoint: 100n,
35
+ captureRateBps: 10500n,
36
+ contestedMultiplierMaxBps: 465,
37
+ slyvault: VAULT_ADDR,
38
+ atlasMint: VAULT_ADDR,
39
+ ...overrides,
40
+ });
41
+ const makeContract = (overrides = {}) => ({
42
+ rate: 100000000n,
43
+ activeRental: SYSTEM,
44
+ queuedRental: SYSTEM,
45
+ fleet: VAULT_ADDR,
46
+ gameId: VAULT_ADDR,
47
+ thread: SYSTEM,
48
+ ...overrides,
49
+ });
50
+ const makeRental = (overrides = {}) => ({
51
+ bidAtlas: 0n,
52
+ bidPoints: 0n,
53
+ startTime: 0n,
54
+ endTime: 0n,
55
+ ...overrides,
56
+ });
57
+ (0, vitest_1.beforeEach)(() => {
58
+ vitest_1.vi.clearAllMocks();
59
+ vitest_1.vi.mocked(srsly_1.deriveActiveRental).mockResolvedValue(ACTIVE_ADDR);
60
+ vitest_1.vi.mocked(srsly_1.deriveQueuedRental).mockResolvedValue(QUEUED_ADDR);
61
+ });
62
+ (0, vitest_1.describe)('getContractSnapshot', () => {
63
+ (0, vitest_1.it)('returns null rentals when contract pointers are SystemProgram', async () => {
64
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
65
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
66
+ data: makeContract(),
67
+ address: CONTRACT_ADDR,
68
+ });
69
+ const snap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
70
+ (0, vitest_1.expect)(snap.activeRental).toBeNull();
71
+ (0, vitest_1.expect)(snap.queuedRental).toBeNull();
72
+ (0, vitest_1.expect)(rental_1.fetchRental).not.toHaveBeenCalled();
73
+ (0, vitest_1.expect)(snap.minimumBid).toBeDefined();
74
+ });
75
+ (0, vitest_1.it)('fetches active + queued when contract pointers are set', async () => {
76
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
77
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
78
+ data: makeContract({ activeRental: ACTIVE_ADDR, queuedRental: QUEUED_ADDR }),
79
+ address: CONTRACT_ADDR,
80
+ });
81
+ vitest_1.vi.mocked(rental_1.fetchRental).mockImplementation(async (addr) => ({
82
+ data: makeRental(),
83
+ address: addr,
84
+ }));
85
+ const snap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
86
+ (0, vitest_1.expect)(snap.activeRental?.address).toBe(ACTIVE_ADDR);
87
+ (0, vitest_1.expect)(snap.queuedRental?.address).toBe(QUEUED_ADDR);
88
+ (0, vitest_1.expect)(rental_1.fetchRental).toHaveBeenCalledTimes(2);
89
+ });
90
+ (0, vitest_1.it)('returns null when pointer is set but fetchRental throws (stale pointer)', async () => {
91
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
92
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
93
+ data: makeContract({ activeRental: ACTIVE_ADDR }),
94
+ address: CONTRACT_ADDR,
95
+ });
96
+ vitest_1.vi.mocked(rental_1.fetchRental).mockRejectedValue(new Error('not found'));
97
+ const snap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
98
+ (0, vitest_1.expect)(snap.activeRental).toBeNull();
99
+ (0, vitest_1.expect)(snap.queuedRental).toBeNull();
100
+ });
101
+ });
102
+ (0, vitest_1.describe)('computeMinimumBidFromSnapshot', () => {
103
+ const buildSnap = (parts) => ({
104
+ config: { data: makeConfig(), address: 'CFG' },
105
+ contract: {
106
+ data: makeContract({
107
+ rate: parts.rate ?? 100000000n,
108
+ activeRental: parts.activeStart !== undefined ? ACTIVE_ADDR : SYSTEM,
109
+ queuedRental: parts.queuedBidAtlas !== undefined || parts.queuedBidPoints !== undefined
110
+ ? QUEUED_ADDR
111
+ : SYSTEM,
112
+ }),
113
+ address: CONTRACT_ADDR,
114
+ },
115
+ activeRental: parts.activeStart !== undefined
116
+ ? {
117
+ data: makeRental({
118
+ startTime: parts.activeStart,
119
+ endTime: parts.activeEnd ?? parts.activeStart + 86400n,
120
+ }),
121
+ address: ACTIVE_ADDR,
122
+ }
123
+ : null,
124
+ queuedRental: parts.queuedBidAtlas !== undefined || parts.queuedBidPoints !== undefined
125
+ ? {
126
+ data: makeRental({
127
+ bidAtlas: parts.queuedBidAtlas ?? 0n,
128
+ bidPoints: parts.queuedBidPoints ?? 0n,
129
+ }),
130
+ address: QUEUED_ADDR,
131
+ }
132
+ : null,
133
+ });
134
+ (0, vitest_1.it)('no defender → floor = rate × captureRate cap', async () => {
135
+ const snap = buildSnap({ rate: 100000000n });
136
+ const bid = (0, contractSnapshot_1.computeMinimumBidFromSnapshot)(snap);
137
+ (0, vitest_1.expect)(bid.defenderBidStardust).toBe(0n);
138
+ // rate * captureRateBps / baseBps = 100M * 10500 / 10000 = 105M
139
+ (0, vitest_1.expect)(bid.minBidStardust).toBe(105000000n);
140
+ (0, vitest_1.expect)(bid.closenessFraction).toBe(0);
141
+ });
142
+ (0, vitest_1.it)('defender ATLAS bid raises floor above rate when bid > rate', async () => {
143
+ const snap = buildSnap({ rate: 100000000n, queuedBidAtlas: 200000000n });
144
+ const bid = (0, contractSnapshot_1.computeMinimumBidFromSnapshot)(snap);
145
+ (0, vitest_1.expect)(bid.defenderBidStardust).toBe(200000000n);
146
+ // base = max(rate, defender) = 200M, ramp at closeness=0 capped to 10500/10000 = 1.05x
147
+ (0, vitest_1.expect)(bid.minBidStardust).toBe(210000000n);
148
+ });
149
+ (0, vitest_1.it)('closeness ramps from 1× to maxMult as active rental nears end', async () => {
150
+ const now = 1_000_000;
151
+ const start = BigInt(now - 50);
152
+ const end = BigInt(now + 50);
153
+ const snap = buildSnap({
154
+ rate: 100000000n,
155
+ queuedBidAtlas: 100000000n,
156
+ activeStart: start,
157
+ activeEnd: end,
158
+ });
159
+ const bid = (0, contractSnapshot_1.computeMinimumBidFromSnapshot)(snap, { nowSeconds: now });
160
+ // closeness = 50/100 = 0.5
161
+ (0, vitest_1.expect)(bid.closenessFraction).toBeCloseTo(0.5, 5);
162
+ // ramp_bps = 10000 + (465 - 100) * 5000 / 100 = 10000 + 18250 = 28250 → 2.825×
163
+ // floor = 100M * 28250 / 10000 = 282_500_000
164
+ (0, vitest_1.expect)(bid.minBidStardust).toBe(282500000n);
165
+ });
166
+ (0, vitest_1.it)('delaySeconds projects closeness forward without RPC', async () => {
167
+ const start = 1000000n;
168
+ const end = 1000100n;
169
+ const snap = buildSnap({
170
+ rate: 100000000n,
171
+ queuedBidAtlas: 100000000n,
172
+ activeStart: start,
173
+ activeEnd: end,
174
+ });
175
+ const now = (0, contractSnapshot_1.computeMinimumBidFromSnapshot)(snap, { nowSeconds: 1_000_000 });
176
+ const later = (0, contractSnapshot_1.computeMinimumBidFromSnapshot)(snap, { nowSeconds: 1_000_050 });
177
+ (0, vitest_1.expect)(now.closenessFraction).toBe(0);
178
+ (0, vitest_1.expect)(later.closenessFraction).toBeCloseTo(0.5, 5);
179
+ (0, vitest_1.expect)(later.minBidStardust).toBeGreaterThan(now.minBidStardust);
180
+ });
181
+ });
182
+ (0, vitest_1.describe)('resolveContractSnapshot', () => {
183
+ (0, vitest_1.it)('fetches fresh when no snapshot provided', async () => {
184
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
185
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
186
+ data: makeContract(),
187
+ address: CONTRACT_ADDR,
188
+ });
189
+ await (0, contractSnapshot_1.resolveContractSnapshot)({ contractAddress: CONTRACT_ADDR });
190
+ (0, vitest_1.expect)(contract_1.fetchContract).toHaveBeenCalledTimes(1);
191
+ });
192
+ (0, vitest_1.it)('returns provided snapshot as-is when address matches and no staleness', async () => {
193
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
194
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
195
+ data: makeContract(),
196
+ address: CONTRACT_ADDR,
197
+ });
198
+ const snap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
199
+ vitest_1.vi.clearAllMocks();
200
+ const resolved = await (0, contractSnapshot_1.resolveContractSnapshot)({
201
+ contractAddress: CONTRACT_ADDR,
202
+ snapshot: snap,
203
+ });
204
+ (0, vitest_1.expect)(resolved).toBe(snap);
205
+ (0, vitest_1.expect)(contract_1.fetchContract).not.toHaveBeenCalled();
206
+ });
207
+ (0, vitest_1.it)('throws when snapshot contract address does not match', async () => {
208
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: VAULT_ADDR });
209
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({ data: makeContract(), address: OTHER_ADDR });
210
+ const snap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: OTHER_ADDR });
211
+ await (0, vitest_1.expect)((0, contractSnapshot_1.resolveContractSnapshot)({ contractAddress: CONTRACT_ADDR, snapshot: snap })).rejects.toThrow(/snapshot is for contract/);
212
+ });
213
+ (0, vitest_1.it)('lazy-refetches when snapshot is stale (pointer set, rental null)', async () => {
214
+ // First fetch: pointer set but rental fetch fails → snap.activeRental = null (stale)
215
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
216
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
217
+ data: makeContract({ activeRental: ACTIVE_ADDR }),
218
+ address: CONTRACT_ADDR,
219
+ });
220
+ vitest_1.vi.mocked(rental_1.fetchRental).mockRejectedValueOnce(new Error('not found'));
221
+ const staleSnap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
222
+ (0, vitest_1.expect)(staleSnap.activeRental).toBeNull();
223
+ // Refetch succeeds — rental now loads
224
+ vitest_1.vi.mocked(rental_1.fetchRental).mockResolvedValueOnce({
225
+ data: makeRental(),
226
+ address: ACTIVE_ADDR,
227
+ });
228
+ const resolved = await (0, contractSnapshot_1.resolveContractSnapshot)({
229
+ contractAddress: CONTRACT_ADDR,
230
+ snapshot: staleSnap,
231
+ });
232
+ (0, vitest_1.expect)(resolved.activeRental).not.toBeNull();
233
+ // resolve called fetchContract once more for refetch
234
+ (0, vitest_1.expect)(contract_1.fetchContract).toHaveBeenCalledTimes(2);
235
+ });
236
+ (0, vitest_1.it)('throws when still stale after lazy refetch', async () => {
237
+ vitest_1.vi.mocked(config_1.fetchConfig).mockResolvedValue({ data: makeConfig(), address: 'CFG' });
238
+ vitest_1.vi.mocked(contract_1.fetchContract).mockResolvedValue({
239
+ data: makeContract({ activeRental: ACTIVE_ADDR }),
240
+ address: CONTRACT_ADDR,
241
+ });
242
+ vitest_1.vi.mocked(rental_1.fetchRental).mockRejectedValue(new Error('not found'));
243
+ const staleSnap = await (0, contractSnapshot_1.getContractSnapshot)({ contractAddress: CONTRACT_ADDR });
244
+ await (0, vitest_1.expect)((0, contractSnapshot_1.resolveContractSnapshot)({ contractAddress: CONTRACT_ADDR, snapshot: staleSnap })).rejects.toThrow(/could not be loaded after lazy refetch/);
245
+ });
246
+ });
247
+ //# sourceMappingURL=contractSnapshot.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractSnapshot.test.js","sourceRoot":"","sources":["../../../src/utils/contractSnapshot.test.ts"],"names":[],"mappings":"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"}