@drift-labs/vaults-sdk 0.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/.env.example +2 -0
- package/README.md +58 -0
- package/cli/cli.ts +105 -0
- package/cli/commands/applyProfitShare.ts +48 -0
- package/cli/commands/deposit.ts +35 -0
- package/cli/commands/index.ts +13 -0
- package/cli/commands/initVault.ts +61 -0
- package/cli/commands/initVaultDepositor.ts +43 -0
- package/cli/commands/listDepositorsForVault.ts +33 -0
- package/cli/commands/managerCancelWithdraw.ts +25 -0
- package/cli/commands/managerDeposit.ts +34 -0
- package/cli/commands/managerRequestWithdraw.ts +27 -0
- package/cli/commands/managerUpdateVault.ts +36 -0
- package/cli/commands/managerWithdraw.ts +25 -0
- package/cli/commands/requestWithdraw.ts +29 -0
- package/cli/commands/vaultDeposit.ts +43 -0
- package/cli/commands/vaultWithdraw.ts +43 -0
- package/cli/commands/viewVault.ts +30 -0
- package/cli/commands/viewVaultDepositor.ts +37 -0
- package/cli/commands/withdraw.ts +25 -0
- package/cli/utils.ts +119 -0
- package/lib/accountSubscribers/index.d.ts +2 -0
- package/lib/accountSubscribers/index.js +14 -0
- package/lib/accountSubscribers/pollingVaultDepositorSubscriber.d.ts +7 -0
- package/lib/accountSubscribers/pollingVaultDepositorSubscriber.js +44 -0
- package/lib/accountSubscribers/pollingVaultSubscriber.d.ts +7 -0
- package/lib/accountSubscribers/pollingVaultSubscriber.js +44 -0
- package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.d.ts +28 -0
- package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.js +68 -0
- package/lib/accounts/index.d.ts +2 -0
- package/lib/accounts/index.js +14 -0
- package/lib/accounts/vaultAccount.d.ts +15 -0
- package/lib/accounts/vaultAccount.js +53 -0
- package/lib/accounts/vaultDepositorAccount.d.ts +18 -0
- package/lib/accounts/vaultDepositorAccount.js +45 -0
- package/lib/accounts/vaultsProgramAccount.d.ts +13 -0
- package/lib/accounts/vaultsProgramAccount.js +25 -0
- package/lib/addresses.d.ts +4 -0
- package/lib/addresses.js +46 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.js +5 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +21 -0
- package/lib/name.d.ts +3 -0
- package/lib/name.js +19 -0
- package/lib/parsers/index.d.ts +1 -0
- package/lib/parsers/index.js +13 -0
- package/lib/parsers/logParser.d.ts +14 -0
- package/lib/parsers/logParser.js +21 -0
- package/lib/types/drift_vaults.d.ts +1475 -0
- package/lib/types/drift_vaults.js +1477 -0
- package/lib/types/types.d.ts +137 -0
- package/lib/types/types.js +20 -0
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +43 -0
- package/lib/vaultClient.d.ts +100 -0
- package/lib/vaultClient.js +596 -0
- package/package.json +29 -0
- package/src/accountSubscribers/index.ts +2 -0
- package/src/accountSubscribers/pollingVaultDepositorSubscriber.ts +68 -0
- package/src/accountSubscribers/pollingVaultSubscriber.ts +62 -0
- package/src/accountSubscribers/pollingVaultsProgramAccountSubscriber.ts +111 -0
- package/src/accounts/index.ts +2 -0
- package/src/accounts/vaultAccount.ts +86 -0
- package/src/accounts/vaultDepositorAccount.ts +67 -0
- package/src/accounts/vaultsProgramAccount.ts +37 -0
- package/src/addresses.ts +43 -0
- package/src/constants/index.ts +3 -0
- package/src/idl/drift_vaults.json +1547 -0
- package/src/index.ts +9 -0
- package/src/name.ts +18 -0
- package/src/parsers/index.ts +1 -0
- package/src/parsers/logParser.ts +28 -0
- package/src/types/drift_vaults.ts +2949 -0
- package/src/types/types.ts +158 -0
- package/src/utils.ts +33 -0
- package/src/vaultClient.ts +904 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { getCommandContext, printVault } from "../utils";
|
|
7
|
+
import { QUOTE_PRECISION, convertToNumber } from "@drift-labs/sdk";
|
|
8
|
+
|
|
9
|
+
export const viewVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
10
|
+
|
|
11
|
+
let address: PublicKey;
|
|
12
|
+
try {
|
|
13
|
+
address = new PublicKey(cmdOpts.vaultAddress as string);
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error("Invalid vault address");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
driftVault
|
|
21
|
+
} = await getCommandContext(program, true);
|
|
22
|
+
|
|
23
|
+
const vault = await driftVault.getVault(address);
|
|
24
|
+
printVault(vault);
|
|
25
|
+
const vaultEquity = await driftVault.calculateVaultEquity({
|
|
26
|
+
vault,
|
|
27
|
+
});
|
|
28
|
+
console.log(`vaultEquity: ${convertToNumber(vaultEquity, QUOTE_PRECISION)}`);
|
|
29
|
+
console.log("Done!");
|
|
30
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { getCommandContext, printVaultDepositor } from "../utils";
|
|
7
|
+
import { getVaultDepositorAddressSync } from "../../src";
|
|
8
|
+
|
|
9
|
+
export const viewVaultDepositor = async (program: Command, cmdOpts: OptionValues) => {
|
|
10
|
+
|
|
11
|
+
let vaultDepositorAddress: PublicKey;
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
driftVault
|
|
15
|
+
} = await getCommandContext(program, false);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
if (cmdOpts.vaultDepositorAddress !== undefined) {
|
|
19
|
+
vaultDepositorAddress = new PublicKey(cmdOpts.vaultDepositorAddress as string);
|
|
20
|
+
} else if (cmdOpts.authority !== undefined && cmdOpts.vaultAddress !== undefined) {
|
|
21
|
+
vaultDepositorAddress = getVaultDepositorAddressSync(
|
|
22
|
+
driftVault.program.programId,
|
|
23
|
+
new PublicKey(cmdOpts.vaultAddress as string),
|
|
24
|
+
new PublicKey(cmdOpts.authority as string));
|
|
25
|
+
} else {
|
|
26
|
+
console.error("Must supply --vault-depositor-address or --authority and --vault-address");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("Failed to load VaultDepositor address");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const vaultDepositor = await driftVault.getVaultDepositor(vaultDepositorAddress);
|
|
35
|
+
printVaultDepositor(vaultDepositor);
|
|
36
|
+
console.log("Done!");
|
|
37
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { getCommandContext } from "../utils";
|
|
7
|
+
|
|
8
|
+
export const withdraw = async (program: Command, cmdOpts: OptionValues) => {
|
|
9
|
+
|
|
10
|
+
let vaultDepositorAddress: PublicKey;
|
|
11
|
+
try {
|
|
12
|
+
vaultDepositorAddress = new PublicKey(cmdOpts.vaultDepositorAddress as string);
|
|
13
|
+
} catch (err) {
|
|
14
|
+
console.error("Invalid vault depositor address");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
driftVault
|
|
20
|
+
} = await getCommandContext(program, true);
|
|
21
|
+
|
|
22
|
+
const tx = await driftVault.withdraw(vaultDepositorAddress);
|
|
23
|
+
console.log(`Withdrew from vault: ${tx}`);
|
|
24
|
+
console.log("Done!");
|
|
25
|
+
};
|
package/cli/utils.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { DriftClient, PublicKey, Wallet, loadKeypair } from "@drift-labs/sdk";
|
|
2
|
+
import { Vault, VaultClient, decodeName } from "../src";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { Connection, Keypair } from "@solana/web3.js";
|
|
5
|
+
import { AnchorProvider } from "@coral-xyz/anchor";
|
|
6
|
+
import * as anchor from '@coral-xyz/anchor';
|
|
7
|
+
import { IDL } from "../src/types/drift_vaults";
|
|
8
|
+
|
|
9
|
+
export function printVault(vault: Vault) {
|
|
10
|
+
console.log(`vault: ${decodeName(vault.name)}`);
|
|
11
|
+
console.log(`pubkey: ${vault.pubkey.toBase58()}`);
|
|
12
|
+
console.log(`manager: ${vault.manager.toBase58()}`);
|
|
13
|
+
console.log(`tokenAccount: ${vault.tokenAccount.toBase58()}`);
|
|
14
|
+
console.log(`driftUserStats: ${vault.userStats.toBase58()}`);
|
|
15
|
+
console.log(`driftUser: ${vault.user.toBase58()}`);
|
|
16
|
+
console.log(`delegate: ${vault.delegate.toBase58()}`);
|
|
17
|
+
console.log(`liqDelegate: ${vault.liquidationDelegate.toBase58()}`);
|
|
18
|
+
console.log(`userShares: ${vault.userShares.toString()}`);
|
|
19
|
+
console.log(`totalShares: ${vault.totalShares.toString()}`);
|
|
20
|
+
const managerShares = vault.totalShares.sub(vault.userShares);
|
|
21
|
+
console.log(` [managerShares]: ${managerShares.toString()} (${(managerShares.toNumber() / vault.totalShares.toNumber() * 100.0).toFixed(4)}%)`);
|
|
22
|
+
console.log(`totalShares: ${vault.totalShares.toString()}`);
|
|
23
|
+
console.log(`lastFeeUpdateTs: ${vault.lastFeeUpdateTs.toString()}`);
|
|
24
|
+
console.log(`liquidationStartTs: ${vault.liquidationStartTs.toString()}`);
|
|
25
|
+
console.log(`redeemPeriod: ${vault.redeemPeriod.toString()}`);
|
|
26
|
+
console.log(`totalWithdrawRequested: ${vault.totalWithdrawRequested.toString()}`);
|
|
27
|
+
console.log(`maxTokens: ${vault.maxTokens.toString()}`);
|
|
28
|
+
console.log(`sharesBase: ${vault.sharesBase}`);
|
|
29
|
+
console.log(`managementFee: ${vault.managementFee.toString()}`);
|
|
30
|
+
console.log(`initTs: ${vault.initTs.toString()}`);
|
|
31
|
+
console.log(`netDeposits: ${vault.netDeposits.toString()}`);
|
|
32
|
+
console.log(`managerNetDeposits: ${vault.managerNetDeposits.toString()}`);
|
|
33
|
+
console.log(`totalDeposits: ${vault.totalDeposits.toString()}`);
|
|
34
|
+
console.log(`totalWithdraws: ${vault.totalWithdraws.toString()}`);
|
|
35
|
+
console.log(`managerTotalDeposits: ${vault.managerTotalDeposits.toString()}`);
|
|
36
|
+
console.log(`managerTotalWithdraws: ${vault.managerTotalWithdraws.toString()}`);
|
|
37
|
+
console.log(`managerTotalFee: ${vault.managerTotalFee.toString()}`);
|
|
38
|
+
console.log(`managerTotalProfitShare: ${vault.managerTotalProfitShare.toString()}`);
|
|
39
|
+
console.log(`lastManagerWithdrawRequest:`);
|
|
40
|
+
console.log(` shares: ${vault.lastManagerWithdrawRequest.shares.toString()}`);
|
|
41
|
+
console.log(` values: ${vault.lastManagerWithdrawRequest.value.toString()}`);
|
|
42
|
+
console.log(` ts: ${vault.lastManagerWithdrawRequest.ts.toString()}`);
|
|
43
|
+
|
|
44
|
+
console.log(`minDepositAmount: ${vault.minDepositAmount.toString()}`);
|
|
45
|
+
console.log(`profitShare: ${vault.profitShare}`);
|
|
46
|
+
console.log(`hurdleRate: ${vault.hurdleRate}`);
|
|
47
|
+
console.log(`spotMarketIndex: ${vault.spotMarketIndex}`);
|
|
48
|
+
console.log(`permissioned: ${vault.permissioned}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function printVaultDepositor(vaultDepositor) {
|
|
52
|
+
console.log(`vault: ${vaultDepositor.vault.toBase58()}`);
|
|
53
|
+
console.log(`pubkey: ${vaultDepositor.pubkey.toBase58()}`);
|
|
54
|
+
console.log(`authority: ${vaultDepositor.authority.toBase58()}`);
|
|
55
|
+
console.log(`vaultShares: ${vaultDepositor.vaultShares.toString()}`);
|
|
56
|
+
console.log(`lastWithdrawRequestShares: ${vaultDepositor.lastWithdrawRequestShares.toString()}`);
|
|
57
|
+
console.log(`lastWithdrawRequestValue: ${vaultDepositor.lastWithdrawRequestValue.toString()}`);
|
|
58
|
+
console.log(`lastWithdrawRequestTs: ${vaultDepositor.lastWithdrawRequestTs.toString()}`);
|
|
59
|
+
console.log(`lastValidTs: ${vaultDepositor.lastValidTs.toString()}`);
|
|
60
|
+
console.log(`netDeposits: ${vaultDepositor.netDeposits.toString()}`);
|
|
61
|
+
console.log(`totalDeposits: ${vaultDepositor.totalDeposits.toString()}`);
|
|
62
|
+
console.log(`totalWithdraws: ${vaultDepositor.totalWithdraws.toString()}`);
|
|
63
|
+
console.log(`cumulativeProfitShareAmount: ${vaultDepositor.cumulativeProfitShareAmount.toString()}`);
|
|
64
|
+
console.log(`vaultSharesBase: ${vaultDepositor.vaultSharesBase.toString()}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function getCommandContext(program: Command, needToSign: boolean): Promise<{
|
|
68
|
+
driftClient: DriftClient,
|
|
69
|
+
driftVault: VaultClient,
|
|
70
|
+
}> {
|
|
71
|
+
|
|
72
|
+
const opts = program.opts();
|
|
73
|
+
|
|
74
|
+
let keypair: Keypair;
|
|
75
|
+
if (needToSign) {
|
|
76
|
+
try {
|
|
77
|
+
keypair = loadKeypair(opts.keypair as string);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
console.error(`Need to provide a valid keypair: ${e}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
keypair = Keypair.generate();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const wallet = new Wallet(keypair);
|
|
87
|
+
console.log(`Signing wallet address (need to sign: ${needToSign}): `, wallet.publicKey.toBase58());
|
|
88
|
+
|
|
89
|
+
const connection = new Connection(opts.rpc, {
|
|
90
|
+
commitment: opts.commitment,
|
|
91
|
+
});
|
|
92
|
+
const driftClient = new DriftClient({
|
|
93
|
+
connection,
|
|
94
|
+
wallet,
|
|
95
|
+
env: "mainnet-beta",
|
|
96
|
+
opts: {
|
|
97
|
+
commitment: opts.commitment,
|
|
98
|
+
skipPreflight: false,
|
|
99
|
+
preflightCommitment: opts.commitment,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
await driftClient.subscribe();
|
|
103
|
+
|
|
104
|
+
const provider = new AnchorProvider(connection, wallet, {});
|
|
105
|
+
anchor.setProvider(provider);
|
|
106
|
+
const vaultProgramId = new PublicKey("vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR");
|
|
107
|
+
const vaultProgram = new anchor.Program(IDL, vaultProgramId, provider);
|
|
108
|
+
|
|
109
|
+
const driftVault = new VaultClient({
|
|
110
|
+
driftClient,
|
|
111
|
+
program: vaultProgram,
|
|
112
|
+
cliMode: true
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
driftClient,
|
|
117
|
+
driftVault,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./pollingVaultDepositorSubscriber"), exports);
|
|
14
|
+
__exportStar(require("./pollingVaultSubscriber"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { VaultDepositor, VaultDepositorAccountEvents, VaultDepositorAccountSubscriber } from '../types/types';
|
|
2
|
+
import { PollingVaultsProgramAccountSubscriber } from './pollingVaultsProgramAccountSubscriber';
|
|
3
|
+
export declare class PollingVaultDepositorSubscriber extends PollingVaultsProgramAccountSubscriber<VaultDepositor, VaultDepositorAccountEvents> implements VaultDepositorAccountSubscriber {
|
|
4
|
+
addToAccountLoader(): Promise<void>;
|
|
5
|
+
fetch(): Promise<void>;
|
|
6
|
+
updateData(vaultDepositorAcc: VaultDepositor, slot: number): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PollingVaultDepositorSubscriber = void 0;
|
|
4
|
+
const pollingVaultsProgramAccountSubscriber_1 = require("./pollingVaultsProgramAccountSubscriber");
|
|
5
|
+
class PollingVaultDepositorSubscriber extends pollingVaultsProgramAccountSubscriber_1.PollingVaultsProgramAccountSubscriber {
|
|
6
|
+
async addToAccountLoader() {
|
|
7
|
+
if (this.callbackId) {
|
|
8
|
+
console.log('Account for vault depositor already added to account loader');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
this.callbackId = await this.accountLoader.addAccount(this.pubkey, (buffer, slot) => {
|
|
12
|
+
if (!buffer)
|
|
13
|
+
return;
|
|
14
|
+
if (this.account && this.account.slot > slot) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const account = this.program.account.vaultDepositor.coder.accounts.decode('vaultDepositor', buffer);
|
|
18
|
+
this.account = { data: account, slot };
|
|
19
|
+
this._eventEmitter.emit('vaultDepositorUpdate', account);
|
|
20
|
+
this._eventEmitter.emit('update');
|
|
21
|
+
});
|
|
22
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
23
|
+
this._eventEmitter.emit('error', error);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async fetch() {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
await this.accountLoader.load();
|
|
29
|
+
const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.pubkey);
|
|
30
|
+
const currentSlot = (_b = (_a = this.account) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0;
|
|
31
|
+
if (buffer && slot > currentSlot) {
|
|
32
|
+
const account = this.program.account.vaultDepositor.coder.accounts.decode('vaultDepositor', buffer);
|
|
33
|
+
this.account = { data: account, slot };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
updateData(vaultDepositorAcc, slot) {
|
|
37
|
+
if (!this.account || this.account.slot < slot) {
|
|
38
|
+
this.account = { data: vaultDepositorAcc, slot };
|
|
39
|
+
this._eventEmitter.emit('vaultDepositorUpdate', vaultDepositorAcc);
|
|
40
|
+
this._eventEmitter.emit('update');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.PollingVaultDepositorSubscriber = PollingVaultDepositorSubscriber;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Vault, VaultAccountEvents, VaultAccountSubscriber } from '../types/types';
|
|
2
|
+
import { PollingVaultsProgramAccountSubscriber } from './pollingVaultsProgramAccountSubscriber';
|
|
3
|
+
export declare class PollingVaultSubscriber extends PollingVaultsProgramAccountSubscriber<Vault, VaultAccountEvents> implements VaultAccountSubscriber {
|
|
4
|
+
addToAccountLoader(): Promise<void>;
|
|
5
|
+
fetch(): Promise<void>;
|
|
6
|
+
updateData(vaultAcc: Vault, slot: number): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PollingVaultSubscriber = void 0;
|
|
4
|
+
const pollingVaultsProgramAccountSubscriber_1 = require("./pollingVaultsProgramAccountSubscriber");
|
|
5
|
+
class PollingVaultSubscriber extends pollingVaultsProgramAccountSubscriber_1.PollingVaultsProgramAccountSubscriber {
|
|
6
|
+
async addToAccountLoader() {
|
|
7
|
+
if (this.callbackId) {
|
|
8
|
+
console.log('Account for vault already added to account loader');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
this.callbackId = await this.accountLoader.addAccount(this.pubkey, (buffer, slot) => {
|
|
12
|
+
if (!buffer)
|
|
13
|
+
return;
|
|
14
|
+
if (this.account && this.account.slot > slot) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const account = this.program.account.vault.coder.accounts.decode('vault', buffer);
|
|
18
|
+
this.account = { data: account, slot };
|
|
19
|
+
this._eventEmitter.emit('vaultUpdate', account);
|
|
20
|
+
this._eventEmitter.emit('update');
|
|
21
|
+
});
|
|
22
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
23
|
+
this._eventEmitter.emit('error', error);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async fetch() {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
await this.accountLoader.load();
|
|
29
|
+
const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.pubkey);
|
|
30
|
+
const currentSlot = (_b = (_a = this.account) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0;
|
|
31
|
+
if (buffer && slot > currentSlot) {
|
|
32
|
+
const account = this.program.account.vault.coder.accounts.decode('vault', buffer);
|
|
33
|
+
this.account = { data: account, slot };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
updateData(vaultAcc, slot) {
|
|
37
|
+
if (!this.account || this.account.slot < slot) {
|
|
38
|
+
this.account = { data: vaultAcc, slot };
|
|
39
|
+
this._eventEmitter.emit('vaultUpdate', vaultAcc);
|
|
40
|
+
this._eventEmitter.emit('update');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.PollingVaultSubscriber = PollingVaultSubscriber;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BulkAccountLoader, DataAndSlot, PublicKey } from '@drift-labs/sdk';
|
|
3
|
+
import { Program } from '@coral-xyz/anchor';
|
|
4
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { DriftVaults } from '../types/drift_vaults';
|
|
7
|
+
import { VaultsProgramAccountBaseEvents, VaultsProgramAccountSubscriber } from '../types/types';
|
|
8
|
+
export declare abstract class PollingVaultsProgramAccountSubscriber<Account, AccountEvents extends VaultsProgramAccountBaseEvents> implements VaultsProgramAccountSubscriber<Account, AccountEvents> {
|
|
9
|
+
protected program: Program<DriftVaults>;
|
|
10
|
+
protected _isSubscribed: boolean;
|
|
11
|
+
protected pubkey: PublicKey;
|
|
12
|
+
protected account?: DataAndSlot<Account>;
|
|
13
|
+
protected _eventEmitter: StrictEventEmitter<EventEmitter, AccountEvents>;
|
|
14
|
+
protected accountLoader: BulkAccountLoader;
|
|
15
|
+
protected callbackId: string | null;
|
|
16
|
+
protected errorCallbackId: string | null;
|
|
17
|
+
constructor(program: Program<DriftVaults>, accountPubkey: PublicKey, accountLoader: BulkAccountLoader);
|
|
18
|
+
get isSubscribed(): boolean;
|
|
19
|
+
get eventEmitter(): StrictEventEmitter<EventEmitter, AccountEvents>;
|
|
20
|
+
subscribe(): Promise<boolean>;
|
|
21
|
+
unsubscribe(): Promise<void>;
|
|
22
|
+
fetchIfUnloaded(): Promise<void>;
|
|
23
|
+
assertIsSubscribed(): void;
|
|
24
|
+
getAccountAndSlot(): DataAndSlot<Account>;
|
|
25
|
+
abstract addToAccountLoader(): Promise<void>;
|
|
26
|
+
abstract fetch(): Promise<void>;
|
|
27
|
+
abstract updateData(account: Account, slot: number): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PollingVaultsProgramAccountSubscriber = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
class PollingVaultsProgramAccountSubscriber {
|
|
7
|
+
constructor(program, accountPubkey, accountLoader) {
|
|
8
|
+
this.callbackId = null;
|
|
9
|
+
this.errorCallbackId = null;
|
|
10
|
+
this.accountLoader = accountLoader;
|
|
11
|
+
this._isSubscribed = false;
|
|
12
|
+
this.pubkey = accountPubkey;
|
|
13
|
+
this.program = program;
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
this._eventEmitter = new events_1.EventEmitter();
|
|
16
|
+
}
|
|
17
|
+
get isSubscribed() {
|
|
18
|
+
return this._isSubscribed;
|
|
19
|
+
}
|
|
20
|
+
get eventEmitter() {
|
|
21
|
+
return this._eventEmitter;
|
|
22
|
+
}
|
|
23
|
+
async subscribe() {
|
|
24
|
+
if (this._isSubscribed) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
await this.addToAccountLoader();
|
|
29
|
+
await this.fetchIfUnloaded();
|
|
30
|
+
if (this.account) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
this._eventEmitter.emit('update');
|
|
33
|
+
}
|
|
34
|
+
this._isSubscribed = true;
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
this._isSubscribed = false;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async unsubscribe() {
|
|
44
|
+
if (!this._isSubscribed) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.accountLoader.removeAccount(this.pubkey, this.callbackId);
|
|
48
|
+
this.callbackId = undefined;
|
|
49
|
+
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
50
|
+
this.errorCallbackId = undefined;
|
|
51
|
+
this._isSubscribed = false;
|
|
52
|
+
}
|
|
53
|
+
async fetchIfUnloaded() {
|
|
54
|
+
if (this.account === undefined) {
|
|
55
|
+
await this.fetch();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
assertIsSubscribed() {
|
|
59
|
+
if (!this._isSubscribed) {
|
|
60
|
+
throw new sdk_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
getAccountAndSlot() {
|
|
64
|
+
this.assertIsSubscribed();
|
|
65
|
+
return this.account;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.PollingVaultsProgramAccountSubscriber = PollingVaultsProgramAccountSubscriber;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./vaultDepositorAccount"), exports);
|
|
14
|
+
__exportStar(require("./vaultAccount"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN, Program } from '@coral-xyz/anchor';
|
|
3
|
+
import { BulkAccountLoader } from '@drift-labs/sdk';
|
|
4
|
+
import { PublicKey } from '@solana/web3.js';
|
|
5
|
+
import { DriftVaults } from '../types/drift_vaults';
|
|
6
|
+
import { Vault, VaultAccountEvents } from '../types/types';
|
|
7
|
+
import { VaultsProgramAccount } from './vaultsProgramAccount';
|
|
8
|
+
export declare class VaultAccount extends VaultsProgramAccount<Vault, VaultAccountEvents> {
|
|
9
|
+
constructor(program: Program<DriftVaults>, vaultPubkey: PublicKey, accountLoader: BulkAccountLoader, accountSubscriptionType?: 'polling' | 'websocket');
|
|
10
|
+
static getAddressSync(programId: PublicKey, vaultName: string): PublicKey;
|
|
11
|
+
calcSharesAfterManagementFee(vaultEquity: BN): {
|
|
12
|
+
totalShares: BN;
|
|
13
|
+
managementFeeShares: BN;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VaultAccount = void 0;
|
|
4
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
6
|
+
const accountSubscribers_1 = require("../accountSubscribers");
|
|
7
|
+
const vaultsProgramAccount_1 = require("./vaultsProgramAccount");
|
|
8
|
+
const addresses_1 = require("../addresses");
|
|
9
|
+
const name_1 = require("../name");
|
|
10
|
+
class VaultAccount extends vaultsProgramAccount_1.VaultsProgramAccount {
|
|
11
|
+
constructor(program, vaultPubkey, accountLoader, accountSubscriptionType = 'polling') {
|
|
12
|
+
super();
|
|
13
|
+
if (accountSubscriptionType === 'polling') {
|
|
14
|
+
this.accountSubscriber = new accountSubscribers_1.PollingVaultSubscriber(program, vaultPubkey, accountLoader);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
throw new Error('Websocket subscription not yet implemented');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
static getAddressSync(programId, vaultName) {
|
|
21
|
+
return addresses_1.getVaultAddressSync(programId, name_1.encodeName(vaultName));
|
|
22
|
+
}
|
|
23
|
+
calcSharesAfterManagementFee(vaultEquity) {
|
|
24
|
+
const accountData = this.accountSubscriber.getAccountAndSlot().data;
|
|
25
|
+
const depositorsEquity = accountData.userShares
|
|
26
|
+
.mul(vaultEquity)
|
|
27
|
+
.div(accountData.totalShares);
|
|
28
|
+
if (accountData.managementFee.eq(sdk_1.ZERO) || depositorsEquity.lte(sdk_1.ZERO)) {
|
|
29
|
+
return {
|
|
30
|
+
totalShares: accountData.totalShares,
|
|
31
|
+
managementFeeShares: sdk_1.ZERO,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const now = new anchor_1.BN(Date.now() / 1000);
|
|
35
|
+
const sinceLast = now.sub(accountData.lastFeeUpdateTs);
|
|
36
|
+
let managementFeeAmount = depositorsEquity
|
|
37
|
+
.mul(accountData.managementFee)
|
|
38
|
+
.div(sdk_1.PERCENTAGE_PRECISION)
|
|
39
|
+
.mul(sinceLast)
|
|
40
|
+
.div(sdk_1.ONE_YEAR);
|
|
41
|
+
managementFeeAmount = anchor_1.BN.min(managementFeeAmount, depositorsEquity.sub(sdk_1.ONE));
|
|
42
|
+
const newTotalSharesFactor = depositorsEquity
|
|
43
|
+
.mul(sdk_1.PERCENTAGE_PRECISION)
|
|
44
|
+
.div(depositorsEquity.sub(managementFeeAmount));
|
|
45
|
+
let newTotalShares = accountData.totalShares
|
|
46
|
+
.mul(newTotalSharesFactor)
|
|
47
|
+
.div(sdk_1.PERCENTAGE_PRECISION);
|
|
48
|
+
newTotalShares = anchor_1.BN.max(newTotalShares, accountData.userShares);
|
|
49
|
+
const managementFeeShares = newTotalShares.sub(accountData.totalShares);
|
|
50
|
+
return { totalShares: newTotalShares, managementFeeShares };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.VaultAccount = VaultAccount;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN, Program } from '@coral-xyz/anchor';
|
|
3
|
+
import { BulkAccountLoader } from '@drift-labs/sdk';
|
|
4
|
+
import { PublicKey } from '@solana/web3.js';
|
|
5
|
+
import { DriftVaults } from '../types/drift_vaults';
|
|
6
|
+
import { VaultDepositor, VaultDepositorAccountEvents } from '../types/types';
|
|
7
|
+
import { VaultsProgramAccount } from './vaultsProgramAccount';
|
|
8
|
+
export declare class VaultDepositorAccount extends VaultsProgramAccount<VaultDepositor, VaultDepositorAccountEvents> {
|
|
9
|
+
constructor(program: Program<DriftVaults>, vaultDepositorPubkey: PublicKey, accountLoader: BulkAccountLoader, accountSubscriptionType?: 'polling' | 'websocket');
|
|
10
|
+
static getAddressSync(programId: PublicKey, vault: PublicKey, authority: PublicKey): PublicKey;
|
|
11
|
+
/**
|
|
12
|
+
* Calculates the percentage of a depositor's equity that will be paid as profit share fees.
|
|
13
|
+
*
|
|
14
|
+
* @param vaultProfitShare Vault's profit share fee
|
|
15
|
+
* @param depositorEquity Vault depositor's equity amount
|
|
16
|
+
*/
|
|
17
|
+
calcProfitShareFeesPct(vaultProfitShare: BN, depositorEquity: BN): BN;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VaultDepositorAccount = void 0;
|
|
4
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
6
|
+
const accountSubscribers_1 = require("../accountSubscribers");
|
|
7
|
+
const vaultsProgramAccount_1 = require("./vaultsProgramAccount");
|
|
8
|
+
const addresses_1 = require("../addresses");
|
|
9
|
+
class VaultDepositorAccount extends vaultsProgramAccount_1.VaultsProgramAccount {
|
|
10
|
+
constructor(program, vaultDepositorPubkey, accountLoader, accountSubscriptionType = 'polling') {
|
|
11
|
+
super();
|
|
12
|
+
if (accountSubscriptionType === 'polling') {
|
|
13
|
+
this.accountSubscriber = new accountSubscribers_1.PollingVaultDepositorSubscriber(program, vaultDepositorPubkey, accountLoader);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
throw new Error('Websocket subscription not yet implemented');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
static getAddressSync(programId, vault, authority) {
|
|
20
|
+
return addresses_1.getVaultDepositorAddressSync(programId, vault, authority);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Calculates the percentage of a depositor's equity that will be paid as profit share fees.
|
|
24
|
+
*
|
|
25
|
+
* @param vaultProfitShare Vault's profit share fee
|
|
26
|
+
* @param depositorEquity Vault depositor's equity amount
|
|
27
|
+
*/
|
|
28
|
+
calcProfitShareFeesPct(vaultProfitShare, depositorEquity) {
|
|
29
|
+
const accountData = this.accountSubscriber.getAccountAndSlot().data;
|
|
30
|
+
const profit = depositorEquity
|
|
31
|
+
.sub(accountData.netDeposits)
|
|
32
|
+
.sub(accountData.cumulativeProfitShareAmount);
|
|
33
|
+
if (profit.lte(new anchor_1.BN(0))) {
|
|
34
|
+
return sdk_1.ZERO;
|
|
35
|
+
}
|
|
36
|
+
const profitShareAmount = profit
|
|
37
|
+
.mul(vaultProfitShare)
|
|
38
|
+
.div(sdk_1.PERCENTAGE_PRECISION);
|
|
39
|
+
const profitShareProportion = profitShareAmount
|
|
40
|
+
.mul(sdk_1.PERCENTAGE_PRECISION)
|
|
41
|
+
.div(depositorEquity);
|
|
42
|
+
return profitShareProportion;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.VaultDepositorAccount = VaultDepositorAccount;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
4
|
+
import { VaultsProgramAccountBaseEvents, VaultsProgramAccountSubscriber } from '../types/types';
|
|
5
|
+
export declare abstract class VaultsProgramAccount<Account, AccountEvents extends VaultsProgramAccountBaseEvents> {
|
|
6
|
+
accountSubscriber: VaultsProgramAccountSubscriber<Account, AccountEvents>;
|
|
7
|
+
get isSubscribed(): boolean;
|
|
8
|
+
get eventEmitter(): StrictEventEmitter<EventEmitter, AccountEvents>;
|
|
9
|
+
subscribe(): Promise<boolean>;
|
|
10
|
+
unsubscribe(): Promise<void>;
|
|
11
|
+
getData(): Account;
|
|
12
|
+
updateData(newData: Account, slot: number): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VaultsProgramAccount = void 0;
|
|
4
|
+
class VaultsProgramAccount {
|
|
5
|
+
get isSubscribed() {
|
|
6
|
+
return this.accountSubscriber.isSubscribed;
|
|
7
|
+
}
|
|
8
|
+
get eventEmitter() {
|
|
9
|
+
return this.accountSubscriber.eventEmitter;
|
|
10
|
+
}
|
|
11
|
+
async subscribe() {
|
|
12
|
+
return await this.accountSubscriber.subscribe();
|
|
13
|
+
}
|
|
14
|
+
async unsubscribe() {
|
|
15
|
+
return await this.accountSubscriber.unsubscribe();
|
|
16
|
+
}
|
|
17
|
+
getData() {
|
|
18
|
+
var _a;
|
|
19
|
+
return (_a = this.accountSubscriber.getAccountAndSlot()) === null || _a === void 0 ? void 0 : _a.data;
|
|
20
|
+
}
|
|
21
|
+
async updateData(newData, slot) {
|
|
22
|
+
return await this.accountSubscriber.updateData(newData, slot);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.VaultsProgramAccount = VaultsProgramAccount;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
export declare function getVaultAddressSync(programId: PublicKey, encodedName: number[]): PublicKey;
|
|
3
|
+
export declare function getVaultDepositorAddressSync(programId: PublicKey, vault: PublicKey, authority: PublicKey): PublicKey;
|
|
4
|
+
export declare function getTokenVaultAddressSync(programId: PublicKey, vault: PublicKey): PublicKey;
|