@reflectmoney/stable.ts 1.0.7 → 1.1.1

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/classes/ApiClient.js +117 -0
  2. package/dist/classes/Reflect.d.ts +7 -0
  3. package/dist/classes/Reflect.js +27 -0
  4. package/dist/classes/ReflectKeeper.d.ts +6 -3
  5. package/dist/classes/ReflectKeeper.js +11 -4
  6. package/dist/classes/ReflectTokenisedBond.d.ts +2 -0
  7. package/dist/classes/ReflectTokenisedBond.js +9 -2
  8. package/dist/classes/Stablecoin.d.ts +24 -9
  9. package/dist/classes/Stablecoin.js +136 -20
  10. package/dist/classes/index.d.ts +1 -0
  11. package/dist/classes/index.js +1 -0
  12. package/dist/constants/index.d.ts +1 -0
  13. package/dist/constants/index.js +3 -0
  14. package/dist/constants/lst.d.ts +3 -0
  15. package/dist/constants/lst.js +6 -0
  16. package/dist/generated/reflect_main/accounts/DriftJlpController.d.ts +2 -0
  17. package/dist/generated/reflect_main/accounts/DriftLstController.d.ts +2 -0
  18. package/dist/generated/reflect_main/accounts/DriftUsdcController.d.ts +28 -2
  19. package/dist/generated/reflect_main/accounts/DriftUsdcController.js +59 -9
  20. package/dist/generated/reflect_main/accounts/Main.d.ts +2 -0
  21. package/dist/generated/reflect_main/accounts/PerpMarket.d.ts +2 -0
  22. package/dist/generated/reflect_main/accounts/PrelaunchOracle.d.ts +2 -0
  23. package/dist/generated/reflect_main/accounts/PythLazerOracle.d.ts +2 -0
  24. package/dist/generated/reflect_main/accounts/RebalanceLst.d.ts +2 -0
  25. package/dist/generated/reflect_main/accounts/SpotMarket.d.ts +2 -0
  26. package/dist/generated/reflect_main/accounts/User.d.ts +2 -0
  27. package/dist/generated/reflect_main/accounts/UserPermissions.d.ts +2 -0
  28. package/dist/generated/reflect_main/accounts/UserStats.d.ts +2 -0
  29. package/dist/generated/reflect_main/errors/index.d.ts +11 -0
  30. package/dist/generated/reflect_main/errors/index.js +84 -65
  31. package/dist/generated/reflect_main/instructions/captureSpreadDriftS1.d.ts +58 -0
  32. package/dist/generated/reflect_main/instructions/captureSpreadDriftS1.js +125 -0
  33. package/dist/generated/reflect_main/instructions/index.d.ts +1 -0
  34. package/dist/generated/reflect_main/instructions/index.js +1 -0
  35. package/dist/generated/reflect_main/instructions/initDriftControllerS1.js +0 -2
  36. package/dist/generated/reflect_main/instructions/mintDriftS1.d.ts +0 -12
  37. package/dist/generated/reflect_main/instructions/mintDriftS1.js +0 -30
  38. package/dist/generated/reflect_main/instructions/redeemDriftS1.d.ts +0 -12
  39. package/dist/generated/reflect_main/instructions/redeemDriftS1.js +0 -30
  40. package/dist/generated/reflect_main/types/Capture.d.ts +17 -0
  41. package/dist/generated/reflect_main/types/Capture.js +42 -0
  42. package/dist/generated/reflect_main/types/PermissionLevel.d.ts +8 -2
  43. package/dist/generated/reflect_main/types/index.d.ts +1 -0
  44. package/dist/generated/reflect_main/types/index.js +1 -0
  45. package/dist/generated/reflect_tokenised_bonds/accounts/Admin.d.ts +2 -0
  46. package/dist/generated/reflect_tokenised_bonds/accounts/Admin.js +1 -1
  47. package/dist/generated/reflect_tokenised_bonds/accounts/Config.d.ts +2 -0
  48. package/dist/generated/reflect_tokenised_bonds/accounts/Config.js +1 -1
  49. package/dist/generated/reflect_tokenised_bonds/accounts/Vault.d.ts +2 -0
  50. package/dist/generated/reflect_tokenised_bonds/accounts/Vault.js +1 -1
  51. package/dist/generated/reflect_tokenised_bonds/index.d.ts +1 -1
  52. package/dist/generated/reflect_tokenised_bonds/index.js +1 -1
  53. package/dist/generated/reflect_tokenised_bonds/instructions/createVault.js +1 -1
  54. package/dist/generated/reflect_tokenised_bonds/instructions/deposit.js +1 -1
  55. package/dist/generated/reflect_tokenised_bonds/instructions/initialize.js +1 -1
  56. package/dist/generated/reflect_tokenised_bonds/instructions/withdraw.js +1 -1
  57. package/dist/stablecoins/LstStablecoin.d.ts +3 -2
  58. package/dist/stablecoins/LstStablecoin.js +137 -22
  59. package/dist/stablecoins/UsdcPlusStablecoin.d.ts +2 -1
  60. package/dist/stablecoins/UsdcPlusStablecoin.js +114 -34
  61. package/package.json +12 -6
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ApiClient = void 0;
16
+ const axios_1 = __importDefault(require("axios"));
17
+ var ApiEnvironment;
18
+ (function (ApiEnvironment) {
19
+ ApiEnvironment[ApiEnvironment["PROD"] = 0] = "PROD";
20
+ ApiEnvironment[ApiEnvironment["DEV"] = 1] = "DEV";
21
+ })(ApiEnvironment || (ApiEnvironment = {}));
22
+ class ApiClient {
23
+ constructor(environment) {
24
+ this.environment = environment;
25
+ this.url = this.getUrl();
26
+ this.supportedMarkets = [
27
+ "SOL-PERP",
28
+ "BTC-PERP",
29
+ "ETH-PERP"
30
+ ];
31
+ }
32
+ getUrl() {
33
+ switch (this.environment) {
34
+ case ApiEnvironment.PROD:
35
+ return "https://api.reflect.money/";
36
+ case ApiEnvironment.DEV:
37
+ return "http://localhost:8080";
38
+ }
39
+ }
40
+ getHealth() {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ const { data } = yield axios_1.default
43
+ .get(`${this.url}/health`);
44
+ return data;
45
+ });
46
+ }
47
+ getSupportedMarkets() {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const { data } = yield axios_1.default
50
+ .get(`${this.url}/funding/markets`);
51
+ this.supportedMarkets = data.markets;
52
+ return this.supportedMarkets;
53
+ });
54
+ }
55
+ // Unify funding rate data for all stablecoins
56
+ getFundingRates(market, period) {
57
+ return __awaiter(this, void 0, void 0, function* () {
58
+ if (!this.supportedMarkets.includes(market)) {
59
+ throw new Error(`Market ${market} is not supported`);
60
+ }
61
+ const { data } = yield axios_1.default
62
+ .get(`${this.url}/funding-rates`, {
63
+ params: {
64
+ market,
65
+ period
66
+ },
67
+ });
68
+ return data;
69
+ });
70
+ }
71
+ getApySummaryForAllStrategies(strategy, historical) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ const { data } = yield axios_1.default
74
+ .get(`${this.url}/apy`, {
75
+ params: {
76
+ strategy,
77
+ historical: historical ? "true" : "false"
78
+ },
79
+ });
80
+ });
81
+ }
82
+ // This needs to be unified to return same type for all stablecoins
83
+ getApyForStrategy(strategy, historical) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ const { data } = yield axios_1.default
86
+ .get(`${this.url}/apy/${strategy}`, {
87
+ params: {
88
+ historical: historical ? "true" : "false",
89
+ },
90
+ });
91
+ return data;
92
+ });
93
+ }
94
+ getSupplyCapInfo() {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const { data } = yield axios_1.default
97
+ .get(`${this.url}/stablecoin/limits`);
98
+ return data;
99
+ });
100
+ }
101
+ getStablecoinList() {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ const { data } = yield axios_1.default
104
+ .get(`${this.url}/stablecoin/types`);
105
+ return data;
106
+ });
107
+ }
108
+ getStablecoinHoldersForStrategy() {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ });
111
+ }
112
+ getExchangeRateForStablecoin() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ });
115
+ }
116
+ }
117
+ exports.ApiClient = ApiClient;
@@ -0,0 +1,7 @@
1
+ import { Connection } from "@solana/web3.js";
2
+ import { Main } from "../generated/reflect_main";
3
+ export declare class Reflect {
4
+ connection: Connection;
5
+ constructor(connection: Connection);
6
+ fetchMain(): Promise<Main>;
7
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Reflect = void 0;
13
+ const PdaClient_1 = require("./PdaClient");
14
+ const reflect_main_1 = require("../generated/reflect_main");
15
+ class Reflect {
16
+ constructor(connection) {
17
+ this.connection = connection;
18
+ }
19
+ fetchMain() {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const main = PdaClient_1.PdaClient.deriveMain();
22
+ const mainAccount = yield reflect_main_1.Main.fromAccountAddress(this.connection, main);
23
+ return mainAccount;
24
+ });
25
+ }
26
+ }
27
+ exports.Reflect = Reflect;
@@ -1,5 +1,7 @@
1
+ /// <reference types="@drift-labs/sdk/node_modules/@solana/web3.js" />
2
+ /// <reference types="jito-ts/node_modules/@solana/web3.js" />
1
3
  import { Connection, PublicKey } from "@solana/web3.js";
2
- import { Action, Role, Update } from "../generated/reflect_main";
4
+ import { Action, Role, Update, UserPermissions } from "../generated/reflect_main";
3
5
  /**
4
6
  * Administrative client for the Reflect protocol.
5
7
  * Provides functionality for protocol-level administration including:
@@ -11,7 +13,7 @@ import { Action, Role, Update } from "../generated/reflect_main";
11
13
  * This class is used by protocol administrators to manage global settings,
12
14
  * user permissions, and protocol-wide configurations.
13
15
  */
14
- export declare class ReflectAdmin {
16
+ export declare class ReflectKeeper {
15
17
  /** Public key of the admin user */
16
18
  private admin;
17
19
  /** Public key of the main program account */
@@ -19,7 +21,7 @@ export declare class ReflectAdmin {
19
21
  /** Solana connection instance for RPC communication */
20
22
  private connection;
21
23
  /**
22
- * Creates a new ReflectAdmin instance.
24
+ * Creates a new ReflectKeeper instance.
23
25
  *
24
26
  * @param admin - Public key of the admin user
25
27
  * @param connection - Solana connection instance
@@ -35,6 +37,7 @@ export declare class ReflectAdmin {
35
37
  * @returns TransactionInstruction for initializing the main account
36
38
  */
37
39
  static initializeMain(admin: PublicKey): import("@solana/web3.js").TransactionInstruction;
40
+ getPermissionAccount(): Promise<UserPermissions>;
38
41
  /**
39
42
  * Freezes or unfreezes a specific protocol action.
40
43
  *
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.ReflectAdmin = void 0;
12
+ exports.ReflectKeeper = void 0;
13
13
  const web3_js_1 = require("@solana/web3.js");
14
14
  const reflect_main_1 = require("../generated/reflect_main");
15
15
  const PdaClient_1 = require("./PdaClient");
@@ -24,9 +24,9 @@ const PdaClient_1 = require("./PdaClient");
24
24
  * This class is used by protocol administrators to manage global settings,
25
25
  * user permissions, and protocol-wide configurations.
26
26
  */
27
- class ReflectAdmin {
27
+ class ReflectKeeper {
28
28
  /**
29
- * Creates a new ReflectAdmin instance.
29
+ * Creates a new ReflectKeeper instance.
30
30
  *
31
31
  * @param admin - Public key of the admin user
32
32
  * @param connection - Solana connection instance
@@ -52,6 +52,13 @@ class ReflectAdmin {
52
52
  }, reflect_main_1.PROGRAM_ID);
53
53
  return ix;
54
54
  }
55
+ getPermissionAccount() {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const permissions = PdaClient_1.PdaClient.derivePermissions(this.admin);
58
+ const permissionsAccount = yield reflect_main_1.UserPermissions.fromAccountAddress(this.connection, permissions);
59
+ return permissionsAccount;
60
+ });
61
+ }
55
62
  /**
56
63
  * Freezes or unfreezes a specific protocol action.
57
64
  *
@@ -216,4 +223,4 @@ class ReflectAdmin {
216
223
  });
217
224
  }
218
225
  }
219
- exports.ReflectAdmin = ReflectAdmin;
226
+ exports.ReflectKeeper = ReflectKeeper;
@@ -1,3 +1,5 @@
1
+ /// <reference types="@drift-labs/sdk/node_modules/@solana/web3.js" />
2
+ /// <reference types="jito-ts/node_modules/@solana/web3.js" />
1
3
  import { Connection } from "@solana/web3.js";
2
4
  import { PublicKey } from "@solana/web3.js";
3
5
  import BN from "bn.js";
@@ -42,7 +42,7 @@ class ReflectTokenisedBond {
42
42
  * @param vault - Public key of the vault account
43
43
  * @returns Promise resolving to an object containing instructions and signers
44
44
  */
45
- createReceiptToken(connection, signer, vault) {
45
+ createReceiptToken(decimals, connection, signer, vault) {
46
46
  return __awaiter(this, void 0, void 0, function* () {
47
47
  const keypair = web3_js_2.Keypair.generate();
48
48
  const lamports = yield connection.getMinimumBalanceForRentExemption(spl_token_1.MINT_SIZE);
@@ -53,7 +53,7 @@ class ReflectTokenisedBond {
53
53
  programId: spl_token_1.TOKEN_PROGRAM_ID,
54
54
  space: spl_token_1.MINT_SIZE
55
55
  });
56
- const ix = (0, spl_token_1.createInitializeMintInstruction)(keypair.publicKey, 9, vault, vault);
56
+ const ix = (0, spl_token_1.createInitializeMintInstruction)(keypair.publicKey, decimals, vault, vault);
57
57
  return {
58
58
  instructions: [createAccountIx, ix],
59
59
  signers: [keypair]
@@ -177,5 +177,12 @@ class ReflectTokenisedBond {
177
177
  return ix;
178
178
  });
179
179
  }
180
+ getVault(vaultId) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ const vault = PdaClient_1.PdaClient.deriveLpVault(vaultId);
183
+ const data = yield reflect_tokenised_bonds_1.Vault.fromAccountAddress(this.connection, vault);
184
+ return data;
185
+ });
186
+ }
180
187
  }
181
188
  exports.ReflectTokenisedBond = ReflectTokenisedBond;
@@ -2,26 +2,28 @@ import { AccountMeta, Connection, Keypair, PublicKey, TransactionInstruction } f
2
2
  import BN from "bn.js";
3
3
  import { DriftClient } from "@drift-labs/sdk";
4
4
  import { Action, Strategy } from "../generated/reflect_main";
5
- import { StablecoinMetadata, Collateral } from "../types";
5
+ import { StablecoinMetadata, Collateral, Controller } from "../types";
6
6
  /**
7
7
  * Abstract base class for all stablecoin implementations in the Reflect protocol.
8
8
  * Provides common functionality for managing stablecoins including initialization,
9
9
  * minting, redemption, rebalancing, and administrative operations.
10
10
  *
11
- * This class serves as the foundation for different stablecoin strategies:
12
- * - USDC+ (Strategy 0): Simple USDC-backed stablecoin
13
- * - JLP Hedged (Strategy 1): Jupiter LP token with perpetual hedging
14
- * - LST Delta-Neutral (Strategy 2): Liquid staking tokens with delta-neutral strategies
11
+ * This class serves as the foundation for different stablecoins:
12
+ * - USDC+ (Index 0): Stablecoin backed by USDC deployed in money markets
13
+ * - JLP Hedged (Index 1): JLP token hedged with perpetual positions
14
+ * - LST Delta-Neutral (Index 2): Stablecoin backed by LSTs and delta-neutral strategies
15
15
  */
16
- export declare abstract class Stablecoin {
17
- /** Unique index identifier for the stablecoin strategy */
16
+ export declare abstract class Stablecoin<T extends Controller> {
17
+ /** Unique index identifier for the stablecoin */
18
18
  index: number;
19
19
  /** Human-readable name of the stablecoin */
20
20
  name: string;
21
- /** Solana connection instance for RPC communication */
21
+ /** Solana connection instance for communication */
22
22
  connection: Connection;
23
23
  /** Public key of the controller account for this stablecoin */
24
- controller: PublicKey;
24
+ controllerKey: PublicKey;
25
+ /** Public key of the controller account for this stablecoin */
26
+ controller: T;
25
27
  /** Public key of the controller account for this stablecoin */
26
28
  strategy: Strategy;
27
29
  /** Array of collateral assets backing this stablecoin */
@@ -32,6 +34,19 @@ export declare abstract class Stablecoin {
32
34
  driftClient?: DriftClient;
33
35
  /** Lookup table with stablecoin-specific accounts. */
34
36
  lookupTable: PublicKey;
37
+ /**
38
+ * Loads the controller account for this stablecoin.
39
+ *
40
+ * @returns Promise resolving to void, sets the controller and strategy fields
41
+ */
42
+ load(schema: {
43
+ fromAccountAddress: (connection: Connection, key: PublicKey) => Promise<T>;
44
+ }): Promise<void>;
45
+ buildLookupTables<T>(signer: PublicKey): Promise<{
46
+ instructions: TransactionInstruction[];
47
+ lookupTable: PublicKey;
48
+ }>;
49
+ setLookupTable(address: PublicKey): Promise<void>;
35
50
  /**
36
51
  * Creates a new Stablecoin instance.
37
52
  *
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.Stablecoin = void 0;
16
16
  const web3_js_1 = require("@solana/web3.js");
17
+ const bn_js_1 = __importDefault(require("bn.js"));
17
18
  const sdk_1 = require("@drift-labs/sdk");
18
19
  const reflect_main_1 = require("../generated/reflect_main");
19
20
  const PdaClient_1 = require("./PdaClient");
@@ -21,18 +22,76 @@ const spl_token_1 = require("@solana/spl-token");
21
22
  const constants_1 = require("../constants");
22
23
  const mpl_token_metadata_1 = require("@metaplex-foundation/mpl-token-metadata");
23
24
  const axios_1 = __importDefault(require("axios"));
24
- const PYTH_API_URL = "https://xc-mainnet.pyth.network/api/v1/price_feed/";
25
25
  /**
26
26
  * Abstract base class for all stablecoin implementations in the Reflect protocol.
27
27
  * Provides common functionality for managing stablecoins including initialization,
28
28
  * minting, redemption, rebalancing, and administrative operations.
29
29
  *
30
- * This class serves as the foundation for different stablecoin strategies:
31
- * - USDC+ (Strategy 0): Simple USDC-backed stablecoin
32
- * - JLP Hedged (Strategy 1): Jupiter LP token with perpetual hedging
33
- * - LST Delta-Neutral (Strategy 2): Liquid staking tokens with delta-neutral strategies
30
+ * This class serves as the foundation for different stablecoins:
31
+ * - USDC+ (Index 0): Stablecoin backed by USDC deployed in money markets
32
+ * - JLP Hedged (Index 1): JLP token hedged with perpetual positions
33
+ * - LST Delta-Neutral (Index 2): Stablecoin backed by LSTs and delta-neutral strategies
34
34
  */
35
35
  class Stablecoin {
36
+ /**
37
+ * Loads the controller account for this stablecoin.
38
+ *
39
+ * @returns Promise resolving to void, sets the controller and strategy fields
40
+ */
41
+ load(schema) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const controller = yield schema
44
+ .fromAccountAddress(this.connection, this.controllerKey);
45
+ this.controller = controller;
46
+ this.strategy = controller.baseStrategy;
47
+ this.stablecoinMint = this.strategy.mint;
48
+ if (this.driftClient) {
49
+ yield this.driftClient.subscribe();
50
+ }
51
+ });
52
+ }
53
+ buildLookupTables(signer) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const accounts = yield this.constructAccounts(signer);
56
+ const keysWithMetas = Object.values(accounts);
57
+ const keys = [];
58
+ keysWithMetas
59
+ .filter(key => !!key) // skip nulls, optional accounts
60
+ .forEach(key => {
61
+ if (key instanceof web3_js_1.PublicKey) {
62
+ keys.push(key);
63
+ }
64
+ else if (Array.isArray(key)) {
65
+ keys.push(...key.map(k => k.pubkey));
66
+ }
67
+ });
68
+ const currentSlot = yield this.connection.getSlot();
69
+ const slots = yield this.connection.getBlocks(currentSlot - 200);
70
+ if (slots.length < 10) {
71
+ throw new Error(`Could find only ${slots.length} ${slots} on the main fork. Failed to create lookup table.`);
72
+ }
73
+ const [initializeIx, lookupTablePubkey] = web3_js_1.AddressLookupTableProgram
74
+ .createLookupTable({
75
+ authority: signer,
76
+ payer: signer,
77
+ recentSlot: slots[0],
78
+ });
79
+ const updateIx = web3_js_1.AddressLookupTableProgram
80
+ .extendLookupTable({
81
+ authority: signer,
82
+ payer: signer,
83
+ addresses: keys,
84
+ lookupTable: lookupTablePubkey,
85
+ });
86
+ return {
87
+ instructions: [initializeIx, updateIx],
88
+ lookupTable: lookupTablePubkey,
89
+ };
90
+ });
91
+ }
92
+ setLookupTable(address) {
93
+ this.lookupTable = address;
94
+ }
36
95
  /**
37
96
  * Creates a new Stablecoin instance.
38
97
  *
@@ -44,7 +103,7 @@ class Stablecoin {
44
103
  this.index = index;
45
104
  this.name = name;
46
105
  this.connection = connection;
47
- this.controller = PdaClient_1.PdaClient.deriveController(this.index);
106
+ this.controllerKey = PdaClient_1.PdaClient.deriveController(this.index);
48
107
  this.lookupTable = lookupTable;
49
108
  }
50
109
  /**
@@ -90,7 +149,7 @@ class Stablecoin {
90
149
  main: PdaClient_1.PdaClient.deriveMain(),
91
150
  adminPermissions: PdaClient_1.PdaClient.derivePermissions(signer),
92
151
  systemProgram: web3_js_1.SystemProgram.programId,
93
- strategy: this.controller
152
+ strategy: this.controllerKey
94
153
  }, {
95
154
  newCap,
96
155
  }, reflect_main_1.PROGRAM_ID);
@@ -111,10 +170,10 @@ class Stablecoin {
111
170
  adminPermissions: PdaClient_1.PdaClient.derivePermissions(signer),
112
171
  systemProgram: web3_js_1.SystemProgram.programId,
113
172
  admin: signer,
114
- strategy: this.controller
173
+ strategy: this.controllerKey
115
174
  }, {
116
- recipientAddresses: [...recipients.keys()],
117
- recipientCuts: [...recipients.values()],
175
+ recipientAddresses: Array.from(recipients.keys()),
176
+ recipientCuts: Array.from(recipients.values()),
118
177
  }, reflect_main_1.PROGRAM_ID);
119
178
  return ix;
120
179
  });
@@ -128,8 +187,16 @@ class Stablecoin {
128
187
  */
129
188
  initializeStablecoinDriftAccount(signer_1) {
130
189
  return __awaiter(this, arguments, void 0, function* (signer, subAccountId = 0) {
131
- const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controller, subAccountId);
132
- const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controller);
190
+ const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey, subAccountId);
191
+ const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey);
192
+ const anchorRemainingAccounts = [
193
+ constants_1.REFERRAL_USER,
194
+ constants_1.REFERRAL_USER_STATS
195
+ ].map(account => ({
196
+ isSigner: false,
197
+ isWritable: true,
198
+ pubkey: account
199
+ }));
133
200
  const ix = (0, reflect_main_1.createAddSubAccountInstruction)({
134
201
  admin: signer,
135
202
  drift: constants_1.DRIFT_PROGRAM_ID,
@@ -140,7 +207,8 @@ class Stablecoin {
140
207
  main: PdaClient_1.PdaClient.deriveMain(),
141
208
  rent: web3_js_1.SYSVAR_RENT_PUBKEY,
142
209
  systemProgram: web3_js_1.SystemProgram.programId,
143
- lstController: this.controller
210
+ lstController: this.controllerKey,
211
+ anchorRemainingAccounts
144
212
  }, reflect_main_1.PROGRAM_ID);
145
213
  return ix;
146
214
  });
@@ -153,15 +221,15 @@ class Stablecoin {
153
221
  */
154
222
  initializeStablecoinDriftStatsAccount(signer) {
155
223
  return __awaiter(this, void 0, void 0, function* () {
156
- const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controller, 0);
157
- const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controller);
224
+ const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey, 0);
225
+ const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey);
158
226
  const ix = (0, reflect_main_1.createCreateUserStatsAccountInstruction)({
159
227
  admin: signer,
160
228
  main: PdaClient_1.PdaClient.deriveMain(),
161
229
  drift: constants_1.DRIFT_PROGRAM_ID,
162
230
  userStats,
163
231
  adminPermissions: PdaClient_1.PdaClient.derivePermissions(signer),
164
- controller: this.controller,
232
+ controller: this.controllerKey,
165
233
  rent: web3_js_1.SYSVAR_RENT_PUBKEY,
166
234
  state: yield (0, sdk_1.getDriftStateAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID),
167
235
  systemProgram: web3_js_1.SystemProgram.programId,
@@ -184,7 +252,7 @@ class Stablecoin {
184
252
  main: PdaClient_1.PdaClient.deriveMain(),
185
253
  adminPermissions: PdaClient_1.PdaClient.derivePermissions(signer),
186
254
  systemProgram: web3_js_1.SystemProgram.programId,
187
- strategy: this.controller,
255
+ strategy: this.controllerKey,
188
256
  }, {
189
257
  freeze,
190
258
  action,
@@ -230,7 +298,7 @@ class Stablecoin {
230
298
  });
231
299
  instructions.push(createMetadataInstruction);
232
300
  }
233
- const setAuthorityInstruction = (0, spl_token_1.createSetAuthorityInstruction)(tokenKeypair.publicKey, signer, spl_token_1.AuthorityType.MintTokens, this.controller);
301
+ const setAuthorityInstruction = (0, spl_token_1.createSetAuthorityInstruction)(tokenKeypair.publicKey, signer, spl_token_1.AuthorityType.MintTokens, this.controllerKey);
234
302
  instructions.push(setAuthorityInstruction);
235
303
  return instructions;
236
304
  });
@@ -249,7 +317,7 @@ class Stablecoin {
249
317
  main: PdaClient_1.PdaClient.deriveMain(),
250
318
  adminPermissions: PdaClient_1.PdaClient.derivePermissions(signer),
251
319
  systemProgram: web3_js_1.SystemProgram.programId,
252
- strategy: this.controller
320
+ strategy: this.controllerKey
253
321
  }, {
254
322
  slippage
255
323
  }, reflect_main_1.PROGRAM_ID);
@@ -269,7 +337,55 @@ class Stablecoin {
269
337
  if (!oracle) {
270
338
  throw new Error(`Oracle not found for collateral ${mint.toBase58()}`);
271
339
  }
272
- return axios_1.default.get(`${PYTH_API_URL}${oracle}`);
340
+ return axios_1.default.get(`${constants_1.PYTH_API_URL}${oracle}`);
341
+ });
342
+ }
343
+ /**
344
+ * Converts a stablecoin amount to the equivalent collateral amount, factoring in slippage (in bips).
345
+ * All math is done using BN for safety.
346
+ * @param amount Amount of stablecoin (BN)
347
+ * @param collateralMint Collateral mint PublicKey
348
+ * @param slippageBips Slippage in bips (1 bip = 0.01%, e.g. 50 = 0.5%)
349
+ * @returns Promise resolving to the collateral amount (BN)
350
+ */
351
+ stablecoinToCollateralWithSlippage(amount, collateralMint, slippageBips) {
352
+ return __awaiter(this, void 0, void 0, function* () {
353
+ const { data } = yield this.getCollateralPrice(collateralMint);
354
+ const priceObj = data[0].price;
355
+ const price = new bn_js_1.default(priceObj.price);
356
+ const expo = priceObj.expo;
357
+ const { decimals } = yield (0, spl_token_1.getMint)(this.connection, collateralMint);
358
+ const collateralAmount = new bn_js_1.default(amount)
359
+ .mul(new bn_js_1.default(10).pow(new bn_js_1.default(decimals)))
360
+ .div(new bn_js_1.default(10).pow(new bn_js_1.default(6))) // stablecoin decimals
361
+ .div(price)
362
+ .div(new bn_js_1.default(10).pow(new bn_js_1.default(expo)))
363
+ .mul(new bn_js_1.default(10000 - slippageBips))
364
+ .div(new bn_js_1.default(10000));
365
+ return collateralAmount;
366
+ });
367
+ }
368
+ /**
369
+ * Converts a collateral amount to the equivalent stablecoin amount, factoring in slippage (in bips).
370
+ * All math is done using BN for safety.
371
+ * @param amount Amount of collateral (BN)
372
+ * @param collateralMint Collateral mint PublicKey
373
+ * @param slippageBips Slippage in bips (1 bip = 0.01%, e.g. 50 = 0.5%)
374
+ * @returns Promise resolving to the stablecoin amount (BN)
375
+ */
376
+ collateralToStablecoinWithSlippage(amount, collateralMint, slippageBips) {
377
+ return __awaiter(this, void 0, void 0, function* () {
378
+ const { data } = yield this.getCollateralPrice(collateralMint);
379
+ const priceObj = data[0].price;
380
+ const price = new bn_js_1.default(priceObj.price);
381
+ const expo = priceObj.expo;
382
+ const { decimals } = yield (0, spl_token_1.getMint)(this.connection, collateralMint);
383
+ const stablecoinAmount = new bn_js_1.default(amount)
384
+ .mul(price)
385
+ .mul(new bn_js_1.default(10).pow(new bn_js_1.default(6))) // stablecoin decimals
386
+ .div(new bn_js_1.default(10).pow(new bn_js_1.default(expo)))
387
+ .div(new bn_js_1.default(10).pow(new bn_js_1.default(decimals)));
388
+ return stablecoinAmount;
273
389
  });
274
390
  }
275
391
  }
@@ -1,3 +1,4 @@
1
1
  export * from "./ReflectKeeper";
2
2
  export * from "./PdaClient";
3
3
  export * from "./Stablecoin";
4
+ export * from "./Reflect";
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./ReflectKeeper"), exports);
18
18
  __exportStar(require("./PdaClient"), exports);
19
19
  __exportStar(require("./Stablecoin"), exports);
20
+ __exportStar(require("./Reflect"), exports);
@@ -3,4 +3,5 @@ export * from "./drift";
3
3
  export * from "./wsol";
4
4
  export * from "./jupiter";
5
5
  export * from "./pyth";
6
+ export * from "./lst";
6
7
  export * from "./lookupTables";
@@ -14,9 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.EXCHANGE_RATE_PRECISION = void 0;
17
18
  __exportStar(require("./usdc"), exports);
18
19
  __exportStar(require("./drift"), exports);
19
20
  __exportStar(require("./wsol"), exports);
20
21
  __exportStar(require("./jupiter"), exports);
21
22
  __exportStar(require("./pyth"), exports);
23
+ __exportStar(require("./lst"), exports);
22
24
  __exportStar(require("./lookupTables"), exports);
25
+ exports.EXCHANGE_RATE_PRECISION = 10000;
@@ -0,0 +1,3 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ declare const JITO_SOL_MINT: PublicKey;
3
+ export { JITO_SOL_MINT };
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JITO_SOL_MINT = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const JITO_SOL_MINT = new web3_js_1.PublicKey("J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn");
6
+ exports.JITO_SOL_MINT = JITO_SOL_MINT;
@@ -4,6 +4,8 @@
4
4
  *
5
5
  * See: https://github.com/metaplex-foundation/solita
6
6
  */
7
+ /// <reference types="node" />
8
+ /// <reference types="node" />
7
9
  import * as web3 from '@solana/web3.js';
8
10
  import * as beet from '@metaplex-foundation/beet';
9
11
  import * as beetSolana from '@metaplex-foundation/beet-solana';
@@ -4,6 +4,8 @@
4
4
  *
5
5
  * See: https://github.com/metaplex-foundation/solita
6
6
  */
7
+ /// <reference types="node" />
8
+ /// <reference types="node" />
7
9
  import * as beet from '@metaplex-foundation/beet';
8
10
  import * as web3 from '@solana/web3.js';
9
11
  import * as beetSolana from '@metaplex-foundation/beet-solana';