@exponent-labs/exponent-sdk 0.9.1 → 0.9.2
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/build/client/vaults/types/kaminoObligationEntry.d.ts +21 -21
- package/build/client/vaults/types/obligationType.d.ts +1 -1
- package/build/client/vaults/types/proposalAction.d.ts +54 -54
- package/build/client/vaults/types/reserveFarmMapping.d.ts +3 -3
- package/build/client/vaults/types/strategyPosition.d.ts +1 -1
- package/build/exponentVaults/index.d.ts +1 -1
- package/build/exponentVaults/index.js +3 -2
- package/build/exponentVaults/index.js.map +1 -1
- package/build/exponentVaults/vault-instruction-types.d.ts +1 -1
- package/build/exponentVaults/vault-interaction.d.ts +58 -41
- package/build/exponentVaults/vault-interaction.js +294 -54
- package/build/exponentVaults/vault-interaction.js.map +1 -1
- package/build/exponentVaults/vault-interaction.kamino-vault.test.d.ts +1 -0
- package/build/exponentVaults/vault-interaction.kamino-vault.test.js +143 -0
- package/build/exponentVaults/vault-interaction.kamino-vault.test.js.map +1 -0
- package/build/exponentVaults/vaultTransactionBuilder.js +35 -30
- package/build/exponentVaults/vaultTransactionBuilder.js.map +1 -1
- package/build/exponentVaults/vaultTransactionBuilder.test.js +84 -1
- package/build/exponentVaults/vaultTransactionBuilder.test.js.map +1 -1
- package/package.json +34 -32
- package/src/exponentVaults/index.ts +1 -0
- package/src/exponentVaults/vault-instruction-types.ts +1 -1
- package/src/exponentVaults/vault-interaction.kamino-vault.test.ts +149 -0
- package/src/exponentVaults/vault-interaction.ts +514 -86
- package/src/exponentVaults/vaultTransactionBuilder.test.ts +93 -0
- package/src/exponentVaults/vaultTransactionBuilder.ts +47 -41
|
@@ -17,6 +17,7 @@ jest.mock("./loopscale", () => ({
|
|
|
17
17
|
|
|
18
18
|
jest.mock("./vault-interaction", () => ({
|
|
19
19
|
buildSetupStatePriceRefreshInstructions: jest.fn(),
|
|
20
|
+
createVaultSyncTransactions: jest.fn(),
|
|
20
21
|
createVaultSyncTransaction: jest.fn(),
|
|
21
22
|
createStrategySetupContext: jest.fn(),
|
|
22
23
|
}))
|
|
@@ -26,10 +27,12 @@ const { LoopscaleClient: mockLoopscaleClient } = jest.requireMock("./loopscale")
|
|
|
26
27
|
}
|
|
27
28
|
const {
|
|
28
29
|
buildSetupStatePriceRefreshInstructions: mockBuildSetupStatePriceRefreshInstructions,
|
|
30
|
+
createVaultSyncTransactions: mockCreateVaultSyncTransactions,
|
|
29
31
|
createVaultSyncTransaction: mockCreateVaultSyncTransaction,
|
|
30
32
|
createStrategySetupContext: mockCreateStrategySetupContext,
|
|
31
33
|
} = jest.requireMock("./vault-interaction") as {
|
|
32
34
|
buildSetupStatePriceRefreshInstructions: jest.Mock
|
|
35
|
+
createVaultSyncTransactions: jest.Mock
|
|
33
36
|
createVaultSyncTransaction: jest.Mock
|
|
34
37
|
createStrategySetupContext: jest.Mock
|
|
35
38
|
}
|
|
@@ -92,6 +95,7 @@ describe("VaultTransactionBuilder Loopscale integration", () => {
|
|
|
92
95
|
;(mockLoopscaleClient as any).mockPrepareVaultTransactions = mockPrepareVaultTransactions
|
|
93
96
|
;(mockLoopscaleClient as any).mockCoSign = mockCoSign
|
|
94
97
|
mockBuildSetupStatePriceRefreshInstructions.mockReset()
|
|
98
|
+
mockCreateVaultSyncTransactions.mockReset()
|
|
95
99
|
mockCreateVaultSyncTransaction.mockReset()
|
|
96
100
|
mockCreateStrategySetupContext.mockReset()
|
|
97
101
|
mockCreateStrategySetupContext.mockReturnValue({ kind: "shared-setup-context" })
|
|
@@ -254,3 +258,92 @@ describe("VaultTransactionBuilder Loopscale integration", () => {
|
|
|
254
258
|
expect(sendResult.ephemeralAlt).toBeNull()
|
|
255
259
|
})
|
|
256
260
|
})
|
|
261
|
+
|
|
262
|
+
describe("VaultTransactionBuilder smart Kamino Vault withdraw fan-out", () => {
|
|
263
|
+
beforeEach(() => {
|
|
264
|
+
mockBuildSetupStatePriceRefreshInstructions.mockReset()
|
|
265
|
+
mockCreateVaultSyncTransactions.mockReset()
|
|
266
|
+
mockCreateStrategySetupContext.mockReset()
|
|
267
|
+
mockCreateStrategySetupContext.mockReturnValue({ kind: "shared-setup-context" })
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
it("splits a single instruction step into multiple sequential transaction sets when the sync helper returns chunks", async () => {
|
|
271
|
+
const config = createVault()
|
|
272
|
+
const refreshIx = ix(config.vault.programId, 90)
|
|
273
|
+
const setupIx = ix(config.vault.programId, 91)
|
|
274
|
+
const firstPreIx = ix(pk(60), 92)
|
|
275
|
+
const firstSyncIx = ix(pk(61), 93)
|
|
276
|
+
const secondSyncIx = ix(pk(62), 94)
|
|
277
|
+
const secondPostIx = ix(pk(63), 95)
|
|
278
|
+
const firstAlt = pk(64)
|
|
279
|
+
const secondAlt = pk(65)
|
|
280
|
+
|
|
281
|
+
mockBuildSetupStatePriceRefreshInstructions.mockImplementation(async () => [refreshIx])
|
|
282
|
+
mockCreateVaultSyncTransactions.mockImplementation(async () => [
|
|
283
|
+
{
|
|
284
|
+
setupInstructions: [setupIx],
|
|
285
|
+
preInstructions: [firstPreIx],
|
|
286
|
+
instruction: firstSyncIx,
|
|
287
|
+
postInstructions: [],
|
|
288
|
+
signers: [],
|
|
289
|
+
addressLookupTableAddresses: [firstAlt],
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
setupInstructions: [],
|
|
293
|
+
preInstructions: [],
|
|
294
|
+
instruction: secondSyncIx,
|
|
295
|
+
postInstructions: [secondPostIx],
|
|
296
|
+
signers: [],
|
|
297
|
+
addressLookupTableAddresses: [secondAlt],
|
|
298
|
+
},
|
|
299
|
+
])
|
|
300
|
+
|
|
301
|
+
const result = await VaultTransactionBuilder
|
|
302
|
+
.create(config)
|
|
303
|
+
.addActions([{ action: "KAMINO_VAULT_WITHDRAW" } as any], { label: "withdraw" })
|
|
304
|
+
.build()
|
|
305
|
+
|
|
306
|
+
expect(mockCreateVaultSyncTransactions).toHaveBeenCalledTimes(1)
|
|
307
|
+
expect(result.labels).toEqual(["withdraw-1-setup", "withdraw-1", "withdraw-2"])
|
|
308
|
+
|
|
309
|
+
expect(result.transactionSets[0]).toEqual({
|
|
310
|
+
label: "withdraw-1-setup",
|
|
311
|
+
instructions: [
|
|
312
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 987_654 }),
|
|
313
|
+
refreshIx,
|
|
314
|
+
setupIx,
|
|
315
|
+
],
|
|
316
|
+
signers: [],
|
|
317
|
+
addressLookupTableAddresses: [firstAlt, config.vault.state.addressLookupTable],
|
|
318
|
+
coSignWithLoopscale: false,
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
expect(result.transactionSets[1]).toEqual({
|
|
322
|
+
label: "withdraw-1",
|
|
323
|
+
instructions: [
|
|
324
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 987_654 }),
|
|
325
|
+
ComputeBudgetProgram.requestHeapFrame({ bytes: 256 * 1024 }),
|
|
326
|
+
refreshIx,
|
|
327
|
+
firstPreIx,
|
|
328
|
+
firstSyncIx,
|
|
329
|
+
],
|
|
330
|
+
signers: [],
|
|
331
|
+
addressLookupTableAddresses: [firstAlt, config.vault.state.addressLookupTable],
|
|
332
|
+
coSignWithLoopscale: false,
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
expect(result.transactionSets[2]).toEqual({
|
|
336
|
+
label: "withdraw-2",
|
|
337
|
+
instructions: [
|
|
338
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 987_654 }),
|
|
339
|
+
ComputeBudgetProgram.requestHeapFrame({ bytes: 256 * 1024 }),
|
|
340
|
+
refreshIx,
|
|
341
|
+
secondSyncIx,
|
|
342
|
+
secondPostIx,
|
|
343
|
+
],
|
|
344
|
+
signers: [],
|
|
345
|
+
addressLookupTableAddresses: [secondAlt, config.vault.state.addressLookupTable],
|
|
346
|
+
coSignWithLoopscale: false,
|
|
347
|
+
})
|
|
348
|
+
})
|
|
349
|
+
})
|
|
@@ -15,7 +15,7 @@ import { LoopscaleClient } from "./loopscale"
|
|
|
15
15
|
import type { LoopscaleTransactionResponse } from "./loopscale"
|
|
16
16
|
import {
|
|
17
17
|
buildSetupStatePriceRefreshInstructions,
|
|
18
|
-
|
|
18
|
+
createVaultSyncTransactions,
|
|
19
19
|
createStrategySetupContext,
|
|
20
20
|
type VaultInstruction,
|
|
21
21
|
} from "./vault-interaction"
|
|
@@ -473,7 +473,7 @@ export class VaultTransactionBuilder {
|
|
|
473
473
|
|
|
474
474
|
const stepCU = step.options.computeUnitLimit ?? defaultCU
|
|
475
475
|
const stepHeap = step.options.heapFrameBytes ?? defaultHeap
|
|
476
|
-
const
|
|
476
|
+
const syncResults = await createVaultSyncTransactions({
|
|
477
477
|
instructions: step.instructions,
|
|
478
478
|
owner: vaultPda,
|
|
479
479
|
connection,
|
|
@@ -487,14 +487,47 @@ export class VaultTransactionBuilder {
|
|
|
487
487
|
|
|
488
488
|
const stepPriceRefreshIxs = await buildSetupStatePriceRefreshInstructions(sharedSetupContext)
|
|
489
489
|
|
|
490
|
-
|
|
491
|
-
const
|
|
492
|
-
|
|
490
|
+
for (const [syncIndex, syncResult] of syncResults.entries()) {
|
|
491
|
+
const txLabel = syncResults.length === 1
|
|
492
|
+
? step.label
|
|
493
|
+
: `${step.label}-${syncIndex + 1}`
|
|
494
|
+
|
|
495
|
+
if (syncResult.setupInstructions.length > 0) {
|
|
496
|
+
const setupSet: TransactionSet = {
|
|
497
|
+
label: `${txLabel}-setup`,
|
|
498
|
+
instructions: [
|
|
499
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: defaultCU }),
|
|
500
|
+
...syncResult.setupInstructions,
|
|
501
|
+
],
|
|
502
|
+
signers: [],
|
|
503
|
+
addressLookupTableAddresses: mergeAddressLookupTableAddresses(
|
|
504
|
+
syncResult.addressLookupTableAddresses,
|
|
505
|
+
extraLookupTableAddresses,
|
|
506
|
+
vault.state.addressLookupTable ? [vault.state.addressLookupTable] : [],
|
|
507
|
+
),
|
|
508
|
+
coSignWithLoopscale: false,
|
|
509
|
+
}
|
|
510
|
+
if (shouldInjectPriceRefresh(setupSet, vault.programId, squadsProgram)) {
|
|
511
|
+
setupSet.instructions = insertAfterLeadingComputeBudgetAndScopeInstructions(
|
|
512
|
+
setupSet.instructions,
|
|
513
|
+
stepPriceRefreshIxs,
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
transactionSets.push(setupSet)
|
|
517
|
+
for (const alt of setupSet.addressLookupTableAddresses) {
|
|
518
|
+
allAltAddresses.add(alt.toBase58())
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const syncSet: TransactionSet = {
|
|
523
|
+
label: txLabel,
|
|
493
524
|
instructions: [
|
|
494
|
-
|
|
495
|
-
...syncResult.
|
|
525
|
+
...buildComputeBudgetIxs(stepCU, stepHeap, step.options.priorityFee),
|
|
526
|
+
...syncResult.preInstructions,
|
|
527
|
+
syncResult.instruction,
|
|
528
|
+
...syncResult.postInstructions,
|
|
496
529
|
],
|
|
497
|
-
signers:
|
|
530
|
+
signers: syncResult.signers,
|
|
498
531
|
addressLookupTableAddresses: mergeAddressLookupTableAddresses(
|
|
499
532
|
syncResult.addressLookupTableAddresses,
|
|
500
533
|
extraLookupTableAddresses,
|
|
@@ -502,45 +535,18 @@ export class VaultTransactionBuilder {
|
|
|
502
535
|
),
|
|
503
536
|
coSignWithLoopscale: false,
|
|
504
537
|
}
|
|
505
|
-
if (shouldInjectPriceRefresh(
|
|
506
|
-
|
|
507
|
-
|
|
538
|
+
if (shouldInjectPriceRefresh(syncSet, vault.programId, squadsProgram)) {
|
|
539
|
+
syncSet.instructions = insertAfterLeadingComputeBudgetAndScopeInstructions(
|
|
540
|
+
syncSet.instructions,
|
|
508
541
|
stepPriceRefreshIxs,
|
|
509
542
|
)
|
|
510
543
|
}
|
|
511
|
-
transactionSets.push(
|
|
512
|
-
|
|
544
|
+
transactionSets.push(syncSet)
|
|
545
|
+
|
|
546
|
+
for (const alt of syncSet.addressLookupTableAddresses) {
|
|
513
547
|
allAltAddresses.add(alt.toBase58())
|
|
514
548
|
}
|
|
515
549
|
}
|
|
516
|
-
|
|
517
|
-
const syncSet: TransactionSet = {
|
|
518
|
-
label: step.label,
|
|
519
|
-
instructions: [
|
|
520
|
-
...buildComputeBudgetIxs(stepCU, stepHeap, step.options.priorityFee),
|
|
521
|
-
...syncResult.preInstructions,
|
|
522
|
-
syncResult.instruction,
|
|
523
|
-
...syncResult.postInstructions,
|
|
524
|
-
],
|
|
525
|
-
signers: syncResult.signers,
|
|
526
|
-
addressLookupTableAddresses: mergeAddressLookupTableAddresses(
|
|
527
|
-
syncResult.addressLookupTableAddresses,
|
|
528
|
-
extraLookupTableAddresses,
|
|
529
|
-
vault.state.addressLookupTable ? [vault.state.addressLookupTable] : [],
|
|
530
|
-
),
|
|
531
|
-
coSignWithLoopscale: false,
|
|
532
|
-
}
|
|
533
|
-
if (shouldInjectPriceRefresh(syncSet, vault.programId, squadsProgram)) {
|
|
534
|
-
syncSet.instructions = insertAfterLeadingComputeBudgetAndScopeInstructions(
|
|
535
|
-
syncSet.instructions,
|
|
536
|
-
stepPriceRefreshIxs,
|
|
537
|
-
)
|
|
538
|
-
}
|
|
539
|
-
transactionSets.push(syncSet)
|
|
540
|
-
|
|
541
|
-
for (const alt of syncSet.addressLookupTableAddresses) {
|
|
542
|
-
allAltAddresses.add(alt.toBase58())
|
|
543
|
-
}
|
|
544
550
|
}
|
|
545
551
|
|
|
546
552
|
const lookupTableAddresses = [...allAltAddresses].map((a) => new PublicKey(a))
|