@sly-rentals/core 6.0.0 → 6.1.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/dist/api.json +3556 -3373
- package/dist/cjs/doctor/contract.js +106 -66
- package/dist/cjs/doctor/contract.js.map +1 -1
- package/dist/cjs/doctor/contract.test.js +73 -2
- package/dist/cjs/doctor/contract.test.js.map +1 -1
- package/dist/cjs/generated/codama/instructions/closeRental.js +12 -0
- package/dist/cjs/generated/codama/instructions/closeRental.js.map +1 -1
- package/dist/cjs/idl/srsly.json +53 -2
- package/dist/cjs/instructions/closeContract.js +23 -38
- package/dist/cjs/instructions/closeContract.js.map +1 -1
- package/dist/cjs/instructions/closeContract.test.js +88 -0
- package/dist/cjs/instructions/closeContract.test.js.map +1 -1
- package/dist/cjs/instructions/closeRental.js +12 -1
- package/dist/cjs/instructions/closeRental.js.map +1 -1
- package/dist/cjs/legacy/closeContract.test.js +107 -0
- package/dist/cjs/legacy/closeContract.test.js.map +1 -0
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/utils/rpc.js +43 -0
- package/dist/cjs/utils/rpc.js.map +1 -1
- package/dist/cjs/utils/rpc.test.js +60 -0
- package/dist/cjs/utils/rpc.test.js.map +1 -0
- package/dist/cjs/version.js +1 -1
- package/dist/esm/doctor/contract.js +107 -67
- package/dist/esm/doctor/contract.js.map +1 -1
- package/dist/esm/doctor/contract.test.js +73 -2
- package/dist/esm/doctor/contract.test.js.map +1 -1
- package/dist/esm/generated/codama/instructions/closeRental.js +12 -0
- package/dist/esm/generated/codama/instructions/closeRental.js.map +1 -1
- package/dist/esm/idl/srsly.json +53 -2
- package/dist/esm/instructions/closeContract.js +23 -38
- package/dist/esm/instructions/closeContract.js.map +1 -1
- package/dist/esm/instructions/closeContract.test.js +88 -0
- package/dist/esm/instructions/closeContract.test.js.map +1 -1
- package/dist/esm/instructions/closeRental.js +13 -2
- package/dist/esm/instructions/closeRental.js.map +1 -1
- package/dist/esm/legacy/closeContract.test.js +105 -0
- package/dist/esm/legacy/closeContract.test.js.map +1 -0
- package/dist/esm/package.json +1 -1
- package/dist/esm/utils/rpc.js +41 -0
- package/dist/esm/utils/rpc.js.map +1 -1
- package/dist/esm/utils/rpc.test.js +58 -0
- package/dist/esm/utils/rpc.test.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/dist/idl/srsly.json +53 -2
- package/dist/types/doctor/contract.d.ts +23 -1
- package/dist/types/doctor/contract.d.ts.map +1 -1
- package/dist/types/generated/codama/instructions/closeRental.d.ts +46 -1
- package/dist/types/generated/codama/instructions/closeRental.d.ts.map +1 -1
- package/dist/types/instructions/closeContract.d.ts +6 -3
- package/dist/types/instructions/closeContract.d.ts.map +1 -1
- package/dist/types/instructions/closeRental.d.ts.map +1 -1
- package/dist/types/legacy/closeContract.test.d.ts +2 -0
- package/dist/types/legacy/closeContract.test.d.ts.map +1 -0
- package/dist/types/utils/rpc.d.ts +18 -0
- package/dist/types/utils/rpc.d.ts.map +1 -1
- package/dist/types/utils/rpc.test.d.ts +2 -0
- package/dist/types/utils/rpc.test.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -17,12 +17,15 @@ import { deriveContractThread } from '../pda/thread';
|
|
|
17
17
|
import { prepareInstructions } from '../utils/instructions';
|
|
18
18
|
import { closeRental } from './closeRental';
|
|
19
19
|
/**
|
|
20
|
-
* Close a rental contract and refund rent to the owner.
|
|
21
|
-
*
|
|
20
|
+
* Close a rental contract and refund rent to the owner. Whenever the close
|
|
21
|
+
* finishes in this transaction, the contract's automation thread is torn down
|
|
22
|
+
* in the same one — the on-chain immediate-close branch refuses to run while
|
|
23
|
+
* `contract.thread` still names a live thread.
|
|
22
24
|
*
|
|
23
25
|
* A live rental cannot be closed out from under its borrower, so the close is
|
|
24
26
|
* latched as `to_close` and completed later by the automation thread, once the
|
|
25
|
-
* rental ends.
|
|
27
|
+
* rental ends. On that path the thread is deliberately left running: it is the
|
|
28
|
+
* only thing that can act on the flag. Antegen execution is permissionless and executors are paid from
|
|
26
29
|
* the thread's own lamport balance, so a drained thread can be revived by
|
|
27
30
|
* anyone with a plain SOL transfer — the owner does not need to come back.
|
|
28
31
|
*
|
|
@@ -178,47 +181,29 @@ export async function closeContract(params, config) {
|
|
|
178
181
|
: {}),
|
|
179
182
|
}, { programAddress });
|
|
180
183
|
};
|
|
181
|
-
//
|
|
184
|
+
// Mirrors `has_live_active_rental` (contract_close.rs:292-302): a live rental
|
|
185
|
+
// defers via `to_close`, anything else closes immediately. Keying the thread
|
|
186
|
+
// decision off "is there a rental" instead conflates an empty slot with a
|
|
187
|
+
// live one and gets the live case backwards.
|
|
188
|
+
const willDefer = hasActiveSlot && !activeExpired;
|
|
182
189
|
const ixs = [];
|
|
183
|
-
if (activeExpired
|
|
184
|
-
//
|
|
190
|
+
if (activeExpired) {
|
|
191
|
+
// Settle first: the fee flush, CTF points, SAGE invalidate and discount
|
|
192
|
+
// refund only exist in `rental_close`. Without it `contract_close` sweeps
|
|
193
|
+
// the contract ATA to the owner (contract_close.rs:336-350).
|
|
185
194
|
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// would just re-latch `to_close`. Suppress the activation so the rental
|
|
189
|
-
// ends and the slot stays empty (Path A), drop the thread so the
|
|
190
|
-
// immediate-close branch isn't blocked by `ThreadStillExists`, then let a
|
|
191
|
-
// single `closeContract` force-refund the challenger and close for real.
|
|
192
|
-
// 1. Settle the expired active without promoting the queued challenger.
|
|
195
|
+
// `activateQueued` must stay false — Path B would install a new live
|
|
196
|
+
// rental and every close after it could only re-latch `to_close`.
|
|
193
197
|
const closeRentalResult = await closeRental({ payer: params.owner, contract: contractAddress, activateQueued: false }, config);
|
|
194
198
|
ixs.push(...closeRentalResult.instructions);
|
|
195
|
-
// 2. closeContractThread (if thread exists)
|
|
196
|
-
if (hasThread) {
|
|
197
|
-
ixs.push(await buildThreadCloseIx());
|
|
198
|
-
}
|
|
199
|
-
// 3. closeContract — force-refunds the queued challenger, then closes.
|
|
200
|
-
ixs.push(await buildCloseContractIx(true));
|
|
201
|
-
}
|
|
202
|
-
else if (activeExpired && !hasQueuedSlot) {
|
|
203
|
-
// Expired active only, no queued — settle then close
|
|
204
|
-
const closeRentalResult = await closeRental({ payer: params.owner, contract: contractAddress }, config);
|
|
205
|
-
ixs.push(...closeRentalResult.instructions);
|
|
206
|
-
if (hasThread) {
|
|
207
|
-
ixs.push(await buildThreadCloseIx());
|
|
208
|
-
}
|
|
209
|
-
ixs.push(await buildCloseContractIx(false));
|
|
210
|
-
}
|
|
211
|
-
else if (!activeExpired && hasQueuedSlot) {
|
|
212
|
-
// Non-expired active + queued — deferred close with queued borrower accounts
|
|
213
|
-
ixs.push(await buildCloseContractIx(true));
|
|
214
199
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
ixs.push(await buildCloseContractIx(false));
|
|
200
|
+
// Closing now means the thread must go first (ThreadStillExists); deferring
|
|
201
|
+
// means keeping it, since `contract_process` (:260 → Signal::Close) is the
|
|
202
|
+
// only automated route from `to_close` to a closed contract.
|
|
203
|
+
if (hasThread && !willDefer) {
|
|
204
|
+
ixs.push(await buildThreadCloseIx());
|
|
221
205
|
}
|
|
206
|
+
ixs.push(await buildCloseContractIx(hasQueuedSlot));
|
|
222
207
|
return prepareInstructions(ixs, {
|
|
223
208
|
computeUnits: params.computeUnits,
|
|
224
209
|
PublicKey: finalConfig.PublicKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"closeContract.js","sourceRoot":"","sources":["../../../src/instructions/closeContract.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,OAAO,EAAkC,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,gCAAgC,EAChC,sCAAsC,GACvC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAyB,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAqD5C
|
|
1
|
+
{"version":3,"file":"closeContract.js","sourceRoot":"","sources":["../../../src/instructions/closeContract.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,42 @@ function mockExpiredActiveWithQueued(thread) {
|
|
|
70
70
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* A contract in an arbitrary slot state, with a thread. `activeEndTime` is
|
|
75
|
+
* only read when `active` is set: `1n` is long expired, a far-future value is
|
|
76
|
+
* still live.
|
|
77
|
+
*/
|
|
78
|
+
function mockContractState(opts) {
|
|
79
|
+
const thread = opts.thread ?? THREAD_ADDR;
|
|
80
|
+
vi.mocked(resolveContractSnapshot).mockResolvedValue({
|
|
81
|
+
config: { data: makeConfig(), address: 'CFG' },
|
|
82
|
+
contract: {
|
|
83
|
+
data: makeContract({
|
|
84
|
+
activeRental: opts.active ? ACTIVE_ADDR : SYSTEM,
|
|
85
|
+
queuedRental: opts.queued ? QUEUED_ADDR : SYSTEM,
|
|
86
|
+
thread,
|
|
87
|
+
}),
|
|
88
|
+
address: CONTRACT_ADDR,
|
|
89
|
+
},
|
|
90
|
+
activeRental: opts.active
|
|
91
|
+
? { data: makeRental({ endTime: opts.activeEndTime ?? 1n }), address: ACTIVE_ADDR }
|
|
92
|
+
: null,
|
|
93
|
+
queuedRental: opts.queued ? { data: makeRental(), address: QUEUED_ADDR } : null,
|
|
94
|
+
nowSeconds: 1_700_000_000,
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
+
});
|
|
97
|
+
vi.mocked(closeRental).mockResolvedValue({
|
|
98
|
+
instructions: [{ programAddress: CONTRACT_ADDR, accounts: [], data: new Uint8Array() }],
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
});
|
|
101
|
+
vi.mocked(fetchThreadByAddress).mockResolvedValue({
|
|
102
|
+
data: { fiberIds: [0, 1] },
|
|
103
|
+
address: thread,
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** Far enough out that the rental is unambiguously still running. */
|
|
108
|
+
const STILL_LIVE = 9999999999n;
|
|
73
109
|
beforeEach(() => {
|
|
74
110
|
vi.clearAllMocks();
|
|
75
111
|
});
|
|
@@ -112,4 +148,56 @@ describe('closeContract — expired active + queued reservation', () => {
|
|
|
112
148
|
expect(fetchThreadByAddress).not.toHaveBeenCalled();
|
|
113
149
|
});
|
|
114
150
|
});
|
|
151
|
+
describe('closeContract — the thread survives a deferred close', () => {
|
|
152
|
+
// A live rental latches `to_close` and leaves the contract standing.
|
|
153
|
+
// `contract_process` is the only automated path from that flag to a closed
|
|
154
|
+
// contract, so closing the thread here strands it.
|
|
155
|
+
it('keeps the thread when a live active rental defers the close', async () => {
|
|
156
|
+
mockContractState({ active: true, queued: false, activeEndTime: STILL_LIVE });
|
|
157
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
158
|
+
expect(fetchThreadByAddress).not.toHaveBeenCalled();
|
|
159
|
+
});
|
|
160
|
+
it('keeps the thread when a live active rental defers alongside a queued one', async () => {
|
|
161
|
+
mockContractState({ active: true, queued: true, activeEndTime: STILL_LIVE });
|
|
162
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
163
|
+
expect(fetchThreadByAddress).not.toHaveBeenCalled();
|
|
164
|
+
});
|
|
165
|
+
it('does not settle a rental that is still running', async () => {
|
|
166
|
+
// Only an expired rental gets a `closeRental`. Settling a live one would
|
|
167
|
+
// close it out from under its borrower.
|
|
168
|
+
mockContractState({ active: true, queued: false, activeEndTime: STILL_LIVE });
|
|
169
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
170
|
+
expect(closeRental).not.toHaveBeenCalled();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('closeContract — the thread goes when the close finishes now', () => {
|
|
174
|
+
// The mirror: the immediate branch requires the thread gone or it fails with
|
|
175
|
+
// ThreadStillExists.
|
|
176
|
+
it('closes the thread when the slot is empty', async () => {
|
|
177
|
+
mockContractState({ active: false, queued: false });
|
|
178
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
179
|
+
expect(fetchThreadByAddress).toHaveBeenCalledTimes(1);
|
|
180
|
+
expect(closeRental).not.toHaveBeenCalled();
|
|
181
|
+
});
|
|
182
|
+
it('closes the thread when the slot is empty but a reservation is queued', async () => {
|
|
183
|
+
// Previously missed: a queued reservation with no active rental still
|
|
184
|
+
// closes immediately, so it needs the thread gone just as much.
|
|
185
|
+
mockContractState({ active: false, queued: true });
|
|
186
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
187
|
+
expect(fetchThreadByAddress).toHaveBeenCalledTimes(1);
|
|
188
|
+
});
|
|
189
|
+
it('closes the thread when the active rental has expired', async () => {
|
|
190
|
+
mockContractState({ active: true, queued: false, activeEndTime: 1n });
|
|
191
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
192
|
+
expect(fetchThreadByAddress).toHaveBeenCalledTimes(1);
|
|
193
|
+
});
|
|
194
|
+
it('settles an expired rental before closing, exactly once', async () => {
|
|
195
|
+
// The settlement carries the fee flush, CTF points, SAGE invalidate and
|
|
196
|
+
// discount refund. `contract_close` has no equivalent — its immediate
|
|
197
|
+
// branch would sweep the escrow to the owner instead.
|
|
198
|
+
mockContractState({ active: true, queued: false, activeEndTime: 1n });
|
|
199
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
200
|
+
expect(closeRental).toHaveBeenCalledTimes(1);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
115
203
|
//# sourceMappingURL=closeContract.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"closeContract.test.js","sourceRoot":"","sources":["../../../src/instructions/closeContract.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"closeContract.test.js","sourceRoot":"","sources":["../../../src/instructions/closeContract.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Thin convenience wrapper around Codama-generated closeRental instruction.
|
|
5
5
|
* Closes a completed rental and returns the fleet to the owner.
|
|
6
6
|
*/
|
|
7
|
-
import { address } from '@solana/kit';
|
|
7
|
+
import { address, downgradeRoleToReadonly, isWritableRole } from '@solana/kit';
|
|
8
8
|
import { isOption, unwrapOption } from '@solana/kit';
|
|
9
9
|
import { getCloseRentalInstructionAsync } from '../generated/codama/instructions';
|
|
10
10
|
import { mergeConfig, getAddresses } from '../utils/config';
|
|
@@ -139,7 +139,18 @@ export async function closeRental(params, config) {
|
|
|
139
139
|
closeRentalFiber: closeRentalFiberAddress,
|
|
140
140
|
sageProgram,
|
|
141
141
|
}, { programAddress });
|
|
142
|
-
|
|
142
|
+
// The program address in an account slot is Anchor's `None` sentinel, but
|
|
143
|
+
// codama stamps it with the role the real account would carry — so
|
|
144
|
+
// `queuedRental` comes back WRITABLE, asking for a write lock on the program
|
|
145
|
+
// being invoked. The runtime demotes it silently; @solana/kit refuses to
|
|
146
|
+
// compile the message at all. Nothing is written through a sentinel.
|
|
147
|
+
const instruction = {
|
|
148
|
+
...kitInstruction,
|
|
149
|
+
accounts: kitInstruction.accounts.map(account => account.address === programAddress && isWritableRole(account.role)
|
|
150
|
+
? { ...account, role: downgradeRoleToReadonly(account.role) }
|
|
151
|
+
: account),
|
|
152
|
+
};
|
|
153
|
+
return prepareInstructions(instruction, {
|
|
143
154
|
computeUnits: params.computeUnits,
|
|
144
155
|
PublicKey: finalConfig.PublicKey,
|
|
145
156
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"closeRental.js","sourceRoot":"","sources":["../../../src/instructions/closeRental.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAgB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"closeRental.js","sourceRoot":"","sources":["../../../src/instructions/closeRental.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The legacy subpath only converts: one instruction in, one out, in order. A
|
|
3
|
+
* duplicate here would be invisible at the call site and land two identical
|
|
4
|
+
* `rental_close` instructions in one transaction.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
|
7
|
+
vi.mock('../utils/contractSnapshot', () => ({
|
|
8
|
+
resolveContractSnapshot: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
vi.mock('../instructions/closeRental', () => ({
|
|
11
|
+
closeRental: vi.fn(),
|
|
12
|
+
}));
|
|
13
|
+
import { resolveContractSnapshot } from '../utils/contractSnapshot';
|
|
14
|
+
import { closeRental } from '../instructions/closeRental';
|
|
15
|
+
import { closeContract, setSdkConfig } from './index';
|
|
16
|
+
import { CLOSE_CONTRACT_DISCRIMINATOR } from '../generated/codama/instructions/closeContract';
|
|
17
|
+
const SYSTEM = '11111111111111111111111111111111';
|
|
18
|
+
const CONTRACT_ADDR = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
19
|
+
const ACTIVE_ADDR = 'So11111111111111111111111111111111111111112';
|
|
20
|
+
const OWNER_ADDR = 'BPFLoader2111111111111111111111111111111111';
|
|
21
|
+
const MINT_ADDR = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
|
|
22
|
+
/** Minimal stand-in for web3.js PublicKey — `toLegacy` only stringifies. */
|
|
23
|
+
class StubPublicKey {
|
|
24
|
+
value;
|
|
25
|
+
constructor(value) {
|
|
26
|
+
this.value = String(value);
|
|
27
|
+
}
|
|
28
|
+
toString() {
|
|
29
|
+
return this.value;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const OWNER_SIGNER = {
|
|
33
|
+
address: OWNER_ADDR,
|
|
34
|
+
signTransactionMessage: vi.fn(),
|
|
35
|
+
};
|
|
36
|
+
/** Marker for the instruction `closeContract` folds in from `closeRental`. */
|
|
37
|
+
const RENTAL_MARKER = new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd]);
|
|
38
|
+
/** Expired active rental, no queued reservation, thread already gone. */
|
|
39
|
+
function mockExpiredActiveNoThread() {
|
|
40
|
+
vi.mocked(resolveContractSnapshot).mockResolvedValue({
|
|
41
|
+
config: {
|
|
42
|
+
data: { atlasMint: MINT_ADDR, slyvault: MINT_ADDR },
|
|
43
|
+
address: 'CFG',
|
|
44
|
+
},
|
|
45
|
+
contract: {
|
|
46
|
+
data: {
|
|
47
|
+
owner: OWNER_ADDR,
|
|
48
|
+
fleet: MINT_ADDR,
|
|
49
|
+
gameId: MINT_ADDR,
|
|
50
|
+
activeRental: ACTIVE_ADDR,
|
|
51
|
+
queuedRental: SYSTEM,
|
|
52
|
+
thread: SYSTEM,
|
|
53
|
+
managedTokenAccount: MINT_ADDR,
|
|
54
|
+
},
|
|
55
|
+
address: CONTRACT_ADDR,
|
|
56
|
+
},
|
|
57
|
+
activeRental: {
|
|
58
|
+
data: {
|
|
59
|
+
borrower: OWNER_ADDR,
|
|
60
|
+
borrowerProfile: MINT_ADDR,
|
|
61
|
+
endTime: 1n,
|
|
62
|
+
},
|
|
63
|
+
address: ACTIVE_ADDR,
|
|
64
|
+
},
|
|
65
|
+
queuedRental: null,
|
|
66
|
+
nowSeconds: 1_700_000_000,
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
});
|
|
69
|
+
vi.mocked(closeRental).mockResolvedValue({
|
|
70
|
+
instructions: [{ programAddress: CONTRACT_ADDR, accounts: [], data: RENTAL_MARKER }],
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
beforeEach(() => {
|
|
75
|
+
vi.clearAllMocks();
|
|
76
|
+
setSdkConfig({ PublicKey: StubPublicKey });
|
|
77
|
+
});
|
|
78
|
+
describe('legacy closeContract — conversion does not duplicate', () => {
|
|
79
|
+
it('builds the underlying rental close exactly once', async () => {
|
|
80
|
+
mockExpiredActiveNoThread();
|
|
81
|
+
await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
82
|
+
expect(closeRental).toHaveBeenCalledTimes(1);
|
|
83
|
+
});
|
|
84
|
+
it('returns one legacy instruction per kit instruction, in order', async () => {
|
|
85
|
+
mockExpiredActiveNoThread();
|
|
86
|
+
const ixs = await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
87
|
+
const startsWith = (data, prefix) => prefix.every((b, i) => data[i] === b);
|
|
88
|
+
expect(ixs).toHaveLength(2);
|
|
89
|
+
expect(startsWith(ixs[0].data, RENTAL_MARKER)).toBe(true);
|
|
90
|
+
expect(startsWith(ixs[1].data, CLOSE_CONTRACT_DISCRIMINATOR)).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
it('converts to web3.js shape without cloning entries', async () => {
|
|
93
|
+
mockExpiredActiveNoThread();
|
|
94
|
+
const ixs = await closeContract({ owner: OWNER_SIGNER, contract: CONTRACT_ADDR });
|
|
95
|
+
// Every entry carries a PublicKey-shaped programId and a keys array —
|
|
96
|
+
// the legacy contract — and there are no repeats of the same data buffer.
|
|
97
|
+
const seen = ixs.map(ix => String(ix.programId) + ':' + Array.from(ix.data).join());
|
|
98
|
+
expect(new Set(seen).size).toBe(ixs.length);
|
|
99
|
+
for (const ix of ixs) {
|
|
100
|
+
expect(ix.programId).toBeInstanceOf(StubPublicKey);
|
|
101
|
+
expect(Array.isArray(ix.keys)).toBe(true);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
//# sourceMappingURL=closeContract.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"closeContract.test.js","sourceRoot":"","sources":["../../../src/legacy/closeContract.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/package.json
CHANGED
package/dist/esm/utils/rpc.js
CHANGED
|
@@ -49,4 +49,45 @@ export function createRpc(rpcUrl) {
|
|
|
49
49
|
}
|
|
50
50
|
return createSolanaRpc(rpcUrl);
|
|
51
51
|
}
|
|
52
|
+
/** Largest account list `getMultipleAccounts` accepts in one request. */
|
|
53
|
+
export const MAX_MULTIPLE_ACCOUNTS = 100;
|
|
54
|
+
/** Providers signal "slow down" as 429, and the wording varies by host. */
|
|
55
|
+
function isRateLimited(error) {
|
|
56
|
+
const e = error;
|
|
57
|
+
if (e?.statusCode === 429 || e?.status === 429)
|
|
58
|
+
return true;
|
|
59
|
+
const message = String(e?.message ?? error);
|
|
60
|
+
return message.includes('429') || /too many requests/i.test(message);
|
|
61
|
+
}
|
|
62
|
+
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
63
|
+
/**
|
|
64
|
+
* Run an RPC call, backing off and retrying when the provider rate-limits it.
|
|
65
|
+
*
|
|
66
|
+
* A 429 is not a result — it means the question was never asked, so a caller
|
|
67
|
+
* that treats it as one reports on state it never read. Backoff is exponential
|
|
68
|
+
* with jitter so workers that trip the limit together do not retry together.
|
|
69
|
+
*
|
|
70
|
+
* @param send - Performs the call. Invoked again on each retry.
|
|
71
|
+
* @param options.retries - Extra attempts after the first. Defaults to 5.
|
|
72
|
+
* @param options.baseDelayMs - Delay before the first retry. Defaults to 250.
|
|
73
|
+
* @throws The last error, once retries are exhausted or it is not a 429.
|
|
74
|
+
*/
|
|
75
|
+
export async function sendWithRetry(send, options = {}) {
|
|
76
|
+
const retries = options.retries ?? 5;
|
|
77
|
+
const baseDelayMs = options.baseDelayMs ?? 250;
|
|
78
|
+
let lastError;
|
|
79
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
80
|
+
try {
|
|
81
|
+
return await send();
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
lastError = error;
|
|
85
|
+
if (!isRateLimited(error) || attempt === retries)
|
|
86
|
+
throw error;
|
|
87
|
+
const backoff = baseDelayMs * 2 ** attempt;
|
|
88
|
+
await delay(backoff + Math.floor(Math.random() * backoff));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
throw lastError;
|
|
92
|
+
}
|
|
52
93
|
//# sourceMappingURL=rpc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../../src/utils/rpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAA+B,MAAM,aAAa,CAAC;AAE3E,0DAA0D;AAC1D,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE;YACpD,GAAG,EAAE,MAAM;YACX,WAAW,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;YAC/D,SAAS,EAAE,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;SAC1E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../../src/utils/rpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAA+B,MAAM,aAAa,CAAC;AAE3E,0DAA0D;AAC1D,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE;YACpD,GAAG,EAAE,MAAM;YACX,WAAW,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;YAC/D,SAAS,EAAE,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;SAC1E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC,2EAA2E;AAC3E,SAAS,aAAa,CAAC,KAAc;IACnC,MAAM,CAAC,GAAG,KAAoE,CAAC;IAC/E,IAAI,CAAC,EAAE,UAAU,KAAK,GAAG,IAAI,CAAC,EAAE,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAsB,EACtB,UAAsD,EAAE;IAExD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC;IAE/C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,OAAO;gBAAE,MAAM,KAAK,CAAC;YAC9D,MAAM,OAAO,GAAG,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC;YAC3C,MAAM,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** A 429 means the question never reached the provider, not that it answered. */
|
|
2
|
+
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
+
import { sendWithRetry, MAX_MULTIPLE_ACCOUNTS } from './rpc';
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
vi.useFakeTimers();
|
|
6
|
+
});
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
vi.useRealTimers();
|
|
9
|
+
});
|
|
10
|
+
/** Drives the fake clock until `promise` settles, so backoff sleeps resolve. */
|
|
11
|
+
async function runToCompletion(promise) {
|
|
12
|
+
const settled = promise.then(value => ({ ok: true, value }), error => ({ ok: false, error }));
|
|
13
|
+
await vi.runAllTimersAsync();
|
|
14
|
+
const outcome = await settled;
|
|
15
|
+
if (!outcome.ok)
|
|
16
|
+
throw outcome.error;
|
|
17
|
+
return outcome.value;
|
|
18
|
+
}
|
|
19
|
+
describe('sendWithRetry', () => {
|
|
20
|
+
it('returns the first result when nothing is rate limited', async () => {
|
|
21
|
+
const send = vi.fn().mockResolvedValue('ok');
|
|
22
|
+
await expect(runToCompletion(sendWithRetry(send))).resolves.toBe('ok');
|
|
23
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
24
|
+
});
|
|
25
|
+
it('retries a 429 and returns the eventual success', async () => {
|
|
26
|
+
const send = vi
|
|
27
|
+
.fn()
|
|
28
|
+
.mockRejectedValueOnce(new Error('HTTP error (429): Too Many Requests'))
|
|
29
|
+
.mockRejectedValueOnce(new Error('HTTP error (429): Too Many Requests'))
|
|
30
|
+
.mockResolvedValue('ok');
|
|
31
|
+
await expect(runToCompletion(sendWithRetry(send))).resolves.toBe('ok');
|
|
32
|
+
expect(send).toHaveBeenCalledTimes(3);
|
|
33
|
+
});
|
|
34
|
+
it('recognises a rate limit from a status code alone', async () => {
|
|
35
|
+
const err = Object.assign(new Error('rejected'), { statusCode: 429 });
|
|
36
|
+
const send = vi.fn().mockRejectedValueOnce(err).mockResolvedValue('ok');
|
|
37
|
+
await expect(runToCompletion(sendWithRetry(send))).resolves.toBe('ok');
|
|
38
|
+
expect(send).toHaveBeenCalledTimes(2);
|
|
39
|
+
});
|
|
40
|
+
it('does not retry an error that is not a rate limit', async () => {
|
|
41
|
+
// Retrying a decode failure or a bad request just multiplies the damage.
|
|
42
|
+
const send = vi.fn().mockRejectedValue(new Error('Invalid param: bad address'));
|
|
43
|
+
await expect(runToCompletion(sendWithRetry(send))).rejects.toThrow('Invalid param');
|
|
44
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
45
|
+
});
|
|
46
|
+
it('gives up after the retry budget and surfaces the rate limit', async () => {
|
|
47
|
+
// The caller has to be able to tell "still limited" from "answered", so the
|
|
48
|
+
// final failure propagates rather than resolving to something empty.
|
|
49
|
+
const send = vi.fn().mockRejectedValue(new Error('HTTP error (429): Too Many Requests'));
|
|
50
|
+
await expect(runToCompletion(sendWithRetry(send, { retries: 2 }))).rejects.toThrow('429');
|
|
51
|
+
expect(send).toHaveBeenCalledTimes(3);
|
|
52
|
+
});
|
|
53
|
+
it('batches at the getMultipleAccounts ceiling', () => {
|
|
54
|
+
// Asking for more than this in one call is rejected outright by the RPC.
|
|
55
|
+
expect(MAX_MULTIPLE_ACCOUNTS).toBe(100);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=rpc.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.test.js","sourceRoot":"","sources":["../../../src/utils/rpc.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/version.js
CHANGED
package/dist/idl/srsly.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"address": "SRSLYxcFnjd5jG2DpJw4as6UEyjwJQK1U4J1TD1hvZH",
|
|
3
3
|
"metadata": {
|
|
4
4
|
"name": "srsly",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.1",
|
|
6
6
|
"spec": "0.1.0",
|
|
7
7
|
"description": "Space Rental from SLY",
|
|
8
8
|
"repository": "https://github.com/wuwei-labs/srsly"
|
|
@@ -1779,10 +1779,61 @@
|
|
|
1779
1779
|
},
|
|
1780
1780
|
{
|
|
1781
1781
|
"name": "rental_state",
|
|
1782
|
-
"
|
|
1782
|
+
"docs": [
|
|
1783
|
+
"Seeds, not `address = contract.active_rental`: `address` is checked",
|
|
1784
|
+
"before the handler runs, so a close arriving after the slot was cleared",
|
|
1785
|
+
"aborted the whole transaction with 2012 rather than no-opping. The",
|
|
1786
|
+
"pointer only ever holds this PDA or the system program, so the seeds",
|
|
1787
|
+
"prove the same ownership without that failure. Paths C and D already",
|
|
1788
|
+
"handle an empty slot."
|
|
1789
|
+
],
|
|
1790
|
+
"writable": true,
|
|
1791
|
+
"pda": {
|
|
1792
|
+
"seeds": [
|
|
1793
|
+
{
|
|
1794
|
+
"kind": "const",
|
|
1795
|
+
"value": [
|
|
1796
|
+
114,
|
|
1797
|
+
101,
|
|
1798
|
+
110,
|
|
1799
|
+
116,
|
|
1800
|
+
97,
|
|
1801
|
+
108,
|
|
1802
|
+
95,
|
|
1803
|
+
115,
|
|
1804
|
+
116,
|
|
1805
|
+
97,
|
|
1806
|
+
116,
|
|
1807
|
+
101
|
|
1808
|
+
]
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
"kind": "account",
|
|
1812
|
+
"path": "contract"
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
"kind": "const",
|
|
1816
|
+
"value": [
|
|
1817
|
+
97,
|
|
1818
|
+
99,
|
|
1819
|
+
116,
|
|
1820
|
+
105,
|
|
1821
|
+
118,
|
|
1822
|
+
101
|
|
1823
|
+
]
|
|
1824
|
+
}
|
|
1825
|
+
]
|
|
1826
|
+
}
|
|
1783
1827
|
},
|
|
1784
1828
|
{
|
|
1785
1829
|
"name": "borrower_state",
|
|
1830
|
+
"docs": [
|
|
1831
|
+
"Bound to the rental being closed, but only while there is one. `reset()`",
|
|
1832
|
+
"clears `borrower_state` along with the rest of the slot, so an `address`",
|
|
1833
|
+
"constraint here would reject the empty case the same way the pointer on",
|
|
1834
|
+
"`rental_state` did. Only `process_rental_close` reads this account, and",
|
|
1835
|
+
"that runs solely when the slot is occupied."
|
|
1836
|
+
],
|
|
1786
1837
|
"writable": true
|
|
1787
1838
|
},
|
|
1788
1839
|
{
|