@reflectmoney/stable.ts 1.0.7 → 1.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/classes/ApiClient.js +117 -0
- package/dist/classes/Reflect.d.ts +7 -0
- package/dist/classes/Reflect.js +27 -0
- package/dist/classes/ReflectKeeper.d.ts +6 -3
- package/dist/classes/ReflectKeeper.js +11 -4
- package/dist/classes/ReflectTokenisedBond.d.ts +2 -0
- package/dist/classes/ReflectTokenisedBond.js +2 -2
- package/dist/classes/Stablecoin.d.ts +24 -9
- package/dist/classes/Stablecoin.js +136 -20
- package/dist/classes/index.d.ts +1 -0
- package/dist/classes/index.js +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +3 -0
- package/dist/constants/lst.d.ts +3 -0
- package/dist/constants/lst.js +6 -0
- package/dist/generated/reflect_main/accounts/DriftJlpController.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/DriftLstController.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/DriftUsdcController.d.ts +28 -2
- package/dist/generated/reflect_main/accounts/DriftUsdcController.js +59 -9
- package/dist/generated/reflect_main/accounts/Main.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/PerpMarket.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/PrelaunchOracle.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/PythLazerOracle.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/RebalanceLst.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/SpotMarket.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/User.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/UserPermissions.d.ts +2 -0
- package/dist/generated/reflect_main/accounts/UserStats.d.ts +2 -0
- package/dist/generated/reflect_main/errors/index.d.ts +11 -0
- package/dist/generated/reflect_main/errors/index.js +84 -65
- package/dist/generated/reflect_main/instructions/captureSpreadDriftS1.d.ts +58 -0
- package/dist/generated/reflect_main/instructions/captureSpreadDriftS1.js +125 -0
- package/dist/generated/reflect_main/instructions/index.d.ts +1 -0
- package/dist/generated/reflect_main/instructions/index.js +1 -0
- package/dist/generated/reflect_main/instructions/initDriftControllerS1.js +0 -2
- package/dist/generated/reflect_main/instructions/mintDriftS1.d.ts +0 -12
- package/dist/generated/reflect_main/instructions/mintDriftS1.js +0 -30
- package/dist/generated/reflect_main/instructions/redeemDriftS1.d.ts +0 -12
- package/dist/generated/reflect_main/instructions/redeemDriftS1.js +0 -30
- package/dist/generated/reflect_main/types/Capture.d.ts +17 -0
- package/dist/generated/reflect_main/types/Capture.js +42 -0
- package/dist/generated/reflect_main/types/PermissionLevel.d.ts +8 -2
- package/dist/generated/reflect_main/types/index.d.ts +1 -0
- package/dist/generated/reflect_main/types/index.js +1 -0
- package/dist/generated/reflect_tokenised_bonds/accounts/Admin.d.ts +2 -0
- package/dist/generated/reflect_tokenised_bonds/accounts/Admin.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/accounts/Config.d.ts +2 -0
- package/dist/generated/reflect_tokenised_bonds/accounts/Config.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/accounts/Vault.d.ts +2 -0
- package/dist/generated/reflect_tokenised_bonds/accounts/Vault.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/index.d.ts +1 -1
- package/dist/generated/reflect_tokenised_bonds/index.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/instructions/createVault.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/instructions/deposit.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/instructions/initialize.js +1 -1
- package/dist/generated/reflect_tokenised_bonds/instructions/withdraw.js +1 -1
- package/dist/stablecoins/LstStablecoin.d.ts +3 -2
- package/dist/stablecoins/LstStablecoin.js +124 -22
- package/dist/stablecoins/UsdcPlusStablecoin.d.ts +2 -1
- package/dist/stablecoins/UsdcPlusStablecoin.js +109 -34
- package/package.json +12 -6
|
@@ -20,6 +20,7 @@ const constants_1 = require("../constants");
|
|
|
20
20
|
const reflect_main_1 = require("../generated/reflect_main");
|
|
21
21
|
const sdk_1 = require("@drift-labs/sdk");
|
|
22
22
|
const spl_token_1 = require("@solana/spl-token");
|
|
23
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
23
24
|
const nodewallet_1 = __importDefault(require("@coral-xyz/anchor/dist/cjs/nodewallet"));
|
|
24
25
|
/**
|
|
25
26
|
* LST (Liquid Staking Token) Delta-Neutral Stablecoin implementation.
|
|
@@ -43,30 +44,35 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
43
44
|
this.driftClient = new sdk_1.DriftClient({
|
|
44
45
|
connection,
|
|
45
46
|
env: "mainnet-beta",
|
|
46
|
-
wallet: new nodewallet_1.default(web3_js_1.Keypair.generate())
|
|
47
|
+
wallet: new nodewallet_1.default(web3_js_1.Keypair.generate()),
|
|
48
|
+
authority: this.controllerKey
|
|
47
49
|
});
|
|
48
50
|
// Otherwise has to be loaded first.
|
|
49
51
|
if (stablecoinMintOverride)
|
|
50
52
|
this.stablecoinMint = stablecoinMintOverride;
|
|
51
53
|
if (collateralMintsOverride)
|
|
52
|
-
this.collaterals = collateralMintsOverride
|
|
54
|
+
this.collaterals = collateralMintsOverride;
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Loads the LST controller data from the blockchain.
|
|
56
58
|
* Updates the stablecoin mint and LST mapping information.
|
|
57
59
|
*/
|
|
58
60
|
load() {
|
|
61
|
+
const _super = Object.create(null, {
|
|
62
|
+
load: { get: () => super.load }
|
|
63
|
+
});
|
|
59
64
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
|
|
61
|
-
this.
|
|
62
|
-
this.lstMap = lsts;
|
|
63
|
-
this.collaterals = lsts.map(({ marketIndex }) => {
|
|
64
|
-
var _a;
|
|
65
|
+
yield _super.load.call(this, reflect_main_1.DriftLstController);
|
|
66
|
+
this.collaterals = this.controller.lsts.map(({ marketIndex }) => {
|
|
65
67
|
const market = sdk_1.SpotMarkets["mainnet-beta"]
|
|
66
68
|
.find(({ marketIndex: index }) => index === marketIndex);
|
|
67
|
-
return {
|
|
69
|
+
return {
|
|
70
|
+
mint: market === null || market === void 0 ? void 0 : market.mint,
|
|
71
|
+
oracle: (market === null || market === void 0 ? void 0 : market.pythFeedId) || "",
|
|
72
|
+
// Assumes all LSTs have 9 decimals
|
|
73
|
+
decimals: 9
|
|
74
|
+
};
|
|
68
75
|
});
|
|
69
|
-
this.strategy = baseStrategy;
|
|
70
76
|
});
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
@@ -82,12 +88,21 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
82
88
|
*/
|
|
83
89
|
initialize(signer, cap, mint, recipientAddresses, recipientCuts) {
|
|
84
90
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const anchorRemainingAccounts = [
|
|
92
|
+
constants_1.REFERRAL_USER,
|
|
93
|
+
constants_1.REFERRAL_USER_STATS
|
|
94
|
+
].map(account => ({
|
|
95
|
+
isSigner: false,
|
|
96
|
+
isWritable: true,
|
|
97
|
+
pubkey: account
|
|
98
|
+
}));
|
|
85
99
|
const ix = (0, reflect_main_1.createInitDriftControllerS3Instruction)({
|
|
86
100
|
admin: signer,
|
|
87
101
|
adminPermissions: classes_1.PdaClient.derivePermissions(signer),
|
|
88
102
|
main: classes_1.PdaClient.deriveMain(),
|
|
89
103
|
systemProgram: web3_js_1.SystemProgram.programId,
|
|
90
|
-
driftLstController: this.
|
|
104
|
+
driftLstController: this.controllerKey,
|
|
105
|
+
anchorRemainingAccounts
|
|
91
106
|
}, {
|
|
92
107
|
mint,
|
|
93
108
|
cap,
|
|
@@ -104,17 +119,19 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
104
119
|
* @param lst - Public key of the LST being used as collateral
|
|
105
120
|
* @returns Promise resolving to the constructed accounts object of type T
|
|
106
121
|
*/
|
|
107
|
-
constructAccounts(
|
|
108
|
-
return __awaiter(this,
|
|
122
|
+
constructAccounts(signer_1) {
|
|
123
|
+
return __awaiter(this, arguments, void 0, function* (signer, lst = constants_1.JITO_SOL_MINT) {
|
|
109
124
|
const { marketIndex: lstMarketIndex } = sdk_1.SpotMarkets["mainnet-beta"]
|
|
110
125
|
.find(market => market.mint.equals(lst));
|
|
111
126
|
const spotMarketVault = yield (0, sdk_1.getSpotMarketVaultPublicKey)(constants_1.DRIFT_PROGRAM_ID, lstMarketIndex);
|
|
112
|
-
const { subAccountId } = this.
|
|
127
|
+
const { subAccountId } = this.controller.lsts.find(({ marketIndex }) => marketIndex == lstMarketIndex);
|
|
113
128
|
const userLstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(lst, signer);
|
|
114
|
-
const controllerLstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(this.
|
|
129
|
+
const controllerLstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(lst, this.controllerKey, true);
|
|
115
130
|
const userReflectAta = (0, spl_token_1.getAssociatedTokenAddressSync)(this.stablecoinMint, signer);
|
|
116
|
-
const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.
|
|
117
|
-
const
|
|
131
|
+
const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey, subAccountId);
|
|
132
|
+
const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey);
|
|
133
|
+
const { referrer } = yield (0, sdk_1.fetchUserStatsAccount)(this.connection, this.driftClient.program, this.controllerKey);
|
|
134
|
+
const referrerUser = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, referrer);
|
|
118
135
|
const referrerUserStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, referrer);
|
|
119
136
|
const accounts = {
|
|
120
137
|
adminPermissions: null,
|
|
@@ -122,14 +139,14 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
122
139
|
main: classes_1.PdaClient.deriveMain(),
|
|
123
140
|
clock: web3_js_1.SYSVAR_CLOCK_PUBKEY,
|
|
124
141
|
controllerLstAta,
|
|
125
|
-
lstController: this.
|
|
142
|
+
lstController: this.controllerKey,
|
|
126
143
|
driftVault: constants_1.DRIFT_VAULT,
|
|
127
144
|
stableMint: this.stablecoinMint,
|
|
128
145
|
user: signer,
|
|
129
|
-
userStats
|
|
130
|
-
referrerUser
|
|
131
|
-
state: yield (0, sdk_1.getDriftStateAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID),
|
|
146
|
+
userStats,
|
|
147
|
+
referrerUser,
|
|
132
148
|
referrerUserStats,
|
|
149
|
+
state: yield (0, sdk_1.getDriftStateAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID),
|
|
133
150
|
spotMarketVault,
|
|
134
151
|
systemProgram: web3_js_1.SystemProgram.programId,
|
|
135
152
|
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
@@ -158,7 +175,7 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
158
175
|
const solanaPerpMarket = yield (0, sdk_1.getPerpMarketPublicKey)(constants_1.DRIFT_PROGRAM_ID, solanaPerpMarketIndex);
|
|
159
176
|
const remainingOracles = [];
|
|
160
177
|
const remainingSpots = [];
|
|
161
|
-
this.
|
|
178
|
+
this.controller.lsts.map(({ marketIndex }) => {
|
|
162
179
|
const oracle = sdk_1.SpotMarkets["mainnet-beta"].find(({ marketIndex: m }) => m == marketIndex).oracle;
|
|
163
180
|
const spotMarket = (0, sdk_1.getSpotMarketPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, marketIndex);
|
|
164
181
|
remainingOracles.push(oracle);
|
|
@@ -174,11 +191,20 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
174
191
|
];
|
|
175
192
|
return remainingAccounts.map(pubkey => ({
|
|
176
193
|
pubkey,
|
|
177
|
-
isWritable:
|
|
194
|
+
isWritable: true,
|
|
178
195
|
isSigner: false
|
|
179
196
|
}));
|
|
180
197
|
});
|
|
181
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Creates a mint instruction for the LST stablecoin.
|
|
201
|
+
*
|
|
202
|
+
* @param signer - Public key of the signer
|
|
203
|
+
* @param amount - Amount of LST to deposit
|
|
204
|
+
* @param minimumReceived - Minimum amount of stablecoins to receive (slippage protection)
|
|
205
|
+
* @param lst - Public key of the LST being used as collateral
|
|
206
|
+
* @returns Promise resolving to an array containing a single TransactionInstruction
|
|
207
|
+
*/
|
|
182
208
|
mint(signer, amount, minimumReceived, lst) {
|
|
183
209
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
210
|
const accounts = yield this.constructAccounts(signer, lst);
|
|
@@ -189,6 +215,15 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
189
215
|
return [ix];
|
|
190
216
|
});
|
|
191
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Creates a redeem instruction for the LST-backed stablecoin.
|
|
220
|
+
*
|
|
221
|
+
* @param signer - Public key of the signer
|
|
222
|
+
* @param amount - Amount of stablecoin to redeem
|
|
223
|
+
* @param minimumReceived - Minimum amount of LST to receive (slippage protection)
|
|
224
|
+
* @param lst - Public key of the LST being used as collateral
|
|
225
|
+
* @returns Promise resolving to an array containing a single TransactionInstruction
|
|
226
|
+
*/
|
|
192
227
|
redeem(signer, amount, minimumReceived, lst) {
|
|
193
228
|
return __awaiter(this, void 0, void 0, function* () {
|
|
194
229
|
const accounts = yield this.constructAccounts(signer, lst);
|
|
@@ -200,6 +235,12 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
200
235
|
return [ix];
|
|
201
236
|
});
|
|
202
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Creates a rebalance instruction for the LST stablecoin.
|
|
240
|
+
* Currently returns an empty instruction, as the rebalance is unnecessary.
|
|
241
|
+
*
|
|
242
|
+
* @returns Promise resolving to an array containing a single, empty TransactionInstruction.
|
|
243
|
+
*/
|
|
203
244
|
rebalance() {
|
|
204
245
|
return __awaiter(this, void 0, void 0, function* () {
|
|
205
246
|
const ix = new web3_js_1.TransactionInstruction({
|
|
@@ -210,5 +251,66 @@ class LstStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
210
251
|
return [ix];
|
|
211
252
|
});
|
|
212
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Whitelists a new collateral for the LST stablecoin.
|
|
256
|
+
*
|
|
257
|
+
* @param signer - Public key of the admin
|
|
258
|
+
* @param mint - Public key of the collateral mint to whitelist
|
|
259
|
+
* @returns Promise resolving to an array containing a single TransactionInstruction
|
|
260
|
+
*/
|
|
261
|
+
whitelistCollateral(signer, mint) {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
const { marketIndex } = sdk_1.SpotMarkets["mainnet-beta"]
|
|
264
|
+
.find(({ mint: m }) => m.equals(mint));
|
|
265
|
+
const spotMarketLst = yield (0, sdk_1.getSpotMarketPublicKey)(constants_1.DRIFT_PROGRAM_ID, marketIndex);
|
|
266
|
+
const ix = (0, reflect_main_1.createAddLstDriftInstruction)({
|
|
267
|
+
admin: signer,
|
|
268
|
+
adminPermissions: classes_1.PdaClient.derivePermissions(signer),
|
|
269
|
+
main: classes_1.PdaClient.deriveMain(),
|
|
270
|
+
lstController: this.controllerKey,
|
|
271
|
+
lstMint: mint,
|
|
272
|
+
spotMarketLst,
|
|
273
|
+
systemProgram: web3_js_1.SystemProgram.programId
|
|
274
|
+
}, reflect_main_1.PROGRAM_ID);
|
|
275
|
+
return [ix];
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Gets the USD exchange rate for the LST-backed stablecoin.
|
|
280
|
+
*
|
|
281
|
+
* @returns Promise resolving to the USD exchange rate as a number
|
|
282
|
+
*/
|
|
283
|
+
getUsdExchangeRate() {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
285
|
+
const usdBalances = yield Promise.all(this
|
|
286
|
+
.collaterals
|
|
287
|
+
.map((_a) => __awaiter(this, [_a], void 0, function* ({ mint: collateralMint, decimals }) {
|
|
288
|
+
const { data: [{ price: { expo, price } }] } = yield this.getCollateralPrice(collateralMint);
|
|
289
|
+
const marketIndex = yield sdk_1.SpotMarkets["mainnet-beta"]
|
|
290
|
+
.find(({ mint: m }) => m.equals(collateralMint))
|
|
291
|
+
.marketIndex;
|
|
292
|
+
const spotPosition = this
|
|
293
|
+
.driftClient
|
|
294
|
+
.getSpotPosition(marketIndex);
|
|
295
|
+
const spotMarketAccount = this
|
|
296
|
+
.driftClient
|
|
297
|
+
.getSpotMarketAccount(marketIndex);
|
|
298
|
+
const tokenAmount = (0, sdk_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
299
|
+
const balanceValue = tokenAmount
|
|
300
|
+
.mul(new bn_js_1.default(price))
|
|
301
|
+
.mul(new bn_js_1.default(constants_1.EXCHANGE_RATE_PRECISION))
|
|
302
|
+
.div(new bn_js_1.default(10).pow(new bn_js_1.default(decimals)))
|
|
303
|
+
.div(new bn_js_1.default(10).pow(new bn_js_1.default(expo)));
|
|
304
|
+
return balanceValue;
|
|
305
|
+
})));
|
|
306
|
+
const { supply, decimals } = yield (0, spl_token_1.getMint)(this.connection, this.stablecoinMint, "confirmed");
|
|
307
|
+
const totalUsdValue = usdBalances
|
|
308
|
+
.reduce((acc, curr) => acc.add(curr), new bn_js_1.default(0))
|
|
309
|
+
.mul(new bn_js_1.default(decimals))
|
|
310
|
+
.div(new bn_js_1.default(supply.toString()))
|
|
311
|
+
.toNumber();
|
|
312
|
+
return totalUsdValue;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
213
315
|
}
|
|
214
316
|
exports.LstStablecoin = LstStablecoin;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Stablecoin } from "../classes/Stablecoin";
|
|
2
2
|
import { AccountMeta, Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
3
|
+
import { DriftUsdcController } from "../generated/reflect_main";
|
|
3
4
|
import BN from "bn.js";
|
|
4
5
|
/**
|
|
5
6
|
* USDC+ Stablecoin implementation for the Reflect protocol.
|
|
6
7
|
* Extends the base Stablecoin class to provide USDC-specific functionality
|
|
7
8
|
* including initialization, minting, redemption, and rebalancing operations.
|
|
8
9
|
*/
|
|
9
|
-
export declare class UsdcPlusStablecoin extends Stablecoin {
|
|
10
|
+
export declare class UsdcPlusStablecoin extends Stablecoin<DriftUsdcController> {
|
|
10
11
|
/**
|
|
11
12
|
* Creates a new USDC+ Stablecoin instance.
|
|
12
13
|
*
|
|
@@ -8,6 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.UsdcPlusStablecoin = void 0;
|
|
13
16
|
const Stablecoin_1 = require("../classes/Stablecoin");
|
|
@@ -16,11 +19,11 @@ const classes_1 = require("../classes");
|
|
|
16
19
|
const constants_1 = require("../constants");
|
|
17
20
|
const reflect_main_1 = require("../generated/reflect_main");
|
|
18
21
|
const sdk_1 = require("@drift-labs/sdk");
|
|
22
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
19
23
|
const constants_2 = require("../constants");
|
|
20
|
-
const ReflectTokenisedBond_1 = require("../classes/ReflectTokenisedBond");
|
|
21
24
|
const spl_token_1 = require("@solana/spl-token");
|
|
22
|
-
const
|
|
23
|
-
const
|
|
25
|
+
const sdk_2 = require("@drift-labs/sdk");
|
|
26
|
+
const nodewallet_1 = __importDefault(require("@coral-xyz/anchor/dist/cjs/nodewallet"));
|
|
24
27
|
/**
|
|
25
28
|
* USDC+ Stablecoin implementation for the Reflect protocol.
|
|
26
29
|
* Extends the base Stablecoin class to provide USDC-specific functionality
|
|
@@ -35,14 +38,28 @@ class UsdcPlusStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
35
38
|
*/
|
|
36
39
|
constructor(connection, stablecoinMintOverride) {
|
|
37
40
|
super(0, "USDC Money Market", connection, constants_2.USDC_PLUS_LOOKUP_TABLE);
|
|
38
|
-
this.collaterals = [{
|
|
41
|
+
this.collaterals = [{
|
|
42
|
+
mint: constants_1.USDC_MINT,
|
|
43
|
+
oracle: "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
|
|
44
|
+
decimals: 6
|
|
45
|
+
}];
|
|
46
|
+
this.driftClient = new sdk_2.DriftClient({
|
|
47
|
+
connection,
|
|
48
|
+
env: "mainnet-beta",
|
|
49
|
+
wallet: new nodewallet_1.default(web3_js_1.Keypair.generate()),
|
|
50
|
+
authority: this.controllerKey
|
|
51
|
+
});
|
|
39
52
|
// Otherwise has to be loaded first.
|
|
40
53
|
if (stablecoinMintOverride)
|
|
41
54
|
this.stablecoinMint = stablecoinMintOverride;
|
|
42
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Loads the USDC+ controller data from the blockchain.
|
|
58
|
+
* Updates the stablecoin mint and strategy information.
|
|
59
|
+
*/
|
|
43
60
|
load() {
|
|
44
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const { baseStrategy, } = yield reflect_main_1.DriftUsdcController.fromAccountAddress(this.connection, this.
|
|
62
|
+
const { baseStrategy, } = yield reflect_main_1.DriftUsdcController.fromAccountAddress(this.connection, this.controllerKey);
|
|
46
63
|
this.stablecoinMint = baseStrategy.mint;
|
|
47
64
|
this.strategy = baseStrategy;
|
|
48
65
|
});
|
|
@@ -60,25 +77,56 @@ class UsdcPlusStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
60
77
|
*/
|
|
61
78
|
initialize(signer, mint, cap, recipientAddresses, recipientCuts) {
|
|
62
79
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
-
const vault = classes_1.PdaClient.deriveLpVault(0);
|
|
64
|
-
const lp = new ReflectTokenisedBond_1.ReflectTokenisedBond(this.connection);
|
|
65
|
-
const { instructions: receiptIx, signers: [receiptKeypair] } = yield lp.createReceiptToken(this.connection, signer, vault);
|
|
66
|
-
const vaultIx = yield lp.initializeVault(signer, mint, receiptKeypair.publicKey);
|
|
67
80
|
const ix = (0, reflect_main_1.createInitDriftControllerS1Instruction)({
|
|
68
81
|
admin: signer,
|
|
69
82
|
adminPermissions: classes_1.PdaClient.derivePermissions(signer),
|
|
70
83
|
main: classes_1.PdaClient.deriveMain(),
|
|
71
|
-
driftUsdcController: this.
|
|
84
|
+
driftUsdcController: this.controllerKey,
|
|
72
85
|
systemProgram: web3_js_1.SystemProgram.programId,
|
|
86
|
+
anchorRemainingAccounts: [{
|
|
87
|
+
isSigner: false,
|
|
88
|
+
isWritable: false,
|
|
89
|
+
pubkey: constants_1.USDC_MINT
|
|
90
|
+
}]
|
|
73
91
|
}, {
|
|
74
92
|
mint,
|
|
75
93
|
cap,
|
|
76
94
|
recipientAddresses,
|
|
77
95
|
recipientCuts,
|
|
78
|
-
lpReciptMint: receiptKeypair.publicKey,
|
|
79
|
-
vault
|
|
80
96
|
}, reflect_main_1.PROGRAM_ID);
|
|
81
|
-
return [
|
|
97
|
+
return [ix];
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Initializes the stablecoin drift account for the USDC+ controller.
|
|
102
|
+
*
|
|
103
|
+
* @param signer - Public key of the signer/initializer
|
|
104
|
+
* @returns Promise resolving to a TransactionInstruction
|
|
105
|
+
*/
|
|
106
|
+
initializeStablecoinDriftAccount(signer) {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
const anchorRemainingAccounts = [
|
|
109
|
+
constants_1.REFERRAL_USER,
|
|
110
|
+
constants_1.REFERRAL_USER_STATS
|
|
111
|
+
].map(account => ({
|
|
112
|
+
isSigner: false,
|
|
113
|
+
isWritable: true,
|
|
114
|
+
pubkey: account
|
|
115
|
+
}));
|
|
116
|
+
const ix = (0, reflect_main_1.createInitDriftAccountsS1Instruction)({
|
|
117
|
+
admin: signer,
|
|
118
|
+
adminPermissions: classes_1.PdaClient.derivePermissions(signer),
|
|
119
|
+
main: classes_1.PdaClient.deriveMain(),
|
|
120
|
+
usdcController: this.controllerKey,
|
|
121
|
+
systemProgram: web3_js_1.SystemProgram.programId,
|
|
122
|
+
drift: constants_1.DRIFT_PROGRAM_ID,
|
|
123
|
+
state: yield (0, sdk_1.getDriftStateAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID),
|
|
124
|
+
userAccount: (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey),
|
|
125
|
+
userStats: (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey),
|
|
126
|
+
rent: web3_js_1.SYSVAR_RENT_PUBKEY,
|
|
127
|
+
anchorRemainingAccounts
|
|
128
|
+
}, reflect_main_1.PROGRAM_ID);
|
|
129
|
+
return ix;
|
|
82
130
|
});
|
|
83
131
|
}
|
|
84
132
|
/**
|
|
@@ -89,46 +137,34 @@ class UsdcPlusStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
89
137
|
*/
|
|
90
138
|
constructAccounts(signer) {
|
|
91
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.
|
|
93
|
-
const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.
|
|
140
|
+
const userAccount = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey);
|
|
141
|
+
const userStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, this.controllerKey);
|
|
94
142
|
const anchorRemainingAccounts = yield this.constructRemainingAccounts();
|
|
95
|
-
const { referrer } = yield (0, sdk_1.fetchUserStatsAccount)(this.connection, this.driftClient.program,
|
|
143
|
+
const { referrer } = yield (0, sdk_1.fetchUserStatsAccount)(this.connection, this.driftClient.program, this.controllerKey);
|
|
96
144
|
const referrerUser = (0, sdk_1.getUserAccountPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, referrer);
|
|
97
145
|
const referrerUserStats = (0, sdk_1.getUserStatsAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID, referrer);
|
|
98
|
-
const userUsdcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
.fromAccountAddress(this.connection, vault);
|
|
102
|
-
const userReceiptAta = (0, spl_token_1.getAssociatedTokenAddressSync)(receiptTokenMint, signer, true);
|
|
103
|
-
const controllerIntermediaryAta = (0, spl_token_1.getAssociatedTokenAddressSync)(intermediaryMint, this.controller, true);
|
|
104
|
-
const controllerReceiptAta = (0, spl_token_1.getAssociatedTokenAddressSync)(receiptTokenMint, this.controller, true);
|
|
105
|
-
const controllerUsdcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.USDC_MINT, this.controller, true);
|
|
146
|
+
const userUsdcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.USDC_MINT, signer, true);
|
|
147
|
+
const userReceiptAta = (0, spl_token_1.getAssociatedTokenAddressSync)(this.stablecoinMint, signer, true);
|
|
148
|
+
const controllerUsdcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.USDC_MINT, this.controllerKey, true);
|
|
106
149
|
const spotMarketVault = yield (0, sdk_1.getSpotMarketVaultPublicKey)(constants_1.DRIFT_PROGRAM_ID, 0);
|
|
107
150
|
const driftState = yield (0, sdk_1.getDriftStateAccountPublicKey)(constants_1.DRIFT_PROGRAM_ID);
|
|
108
|
-
const vaultPool = classes_1.PdaClient.deriveLpVaultPool(0);
|
|
109
151
|
const accounts = {
|
|
110
152
|
clock: web3_js_1.SYSVAR_CLOCK_PUBKEY,
|
|
111
|
-
controllerIntermediaryAta,
|
|
112
|
-
controllerReceiptAta,
|
|
113
153
|
controllerUsdcAta,
|
|
114
154
|
drift: constants_1.DRIFT_PROGRAM_ID,
|
|
115
155
|
driftVault: constants_1.DRIFT_VAULT,
|
|
116
|
-
intermediaryMint,
|
|
117
|
-
lpPoolIntermediaryAta: vaultPool,
|
|
118
|
-
lpProgram: __1.TOKENISED_BONDS_PROGRAM_ID,
|
|
119
156
|
main: classes_1.PdaClient.deriveMain(),
|
|
120
|
-
receiptMint:
|
|
157
|
+
receiptMint: this.stablecoinMint,
|
|
121
158
|
referrerUser,
|
|
122
159
|
referrerUserStats,
|
|
123
160
|
spotMarketVault,
|
|
124
161
|
state: driftState,
|
|
125
|
-
usdcController: this.
|
|
162
|
+
usdcController: this.controllerKey,
|
|
126
163
|
user: signer,
|
|
127
164
|
userAccount,
|
|
128
165
|
userReceiptAta,
|
|
129
166
|
userStats,
|
|
130
167
|
userUsdcAta,
|
|
131
|
-
vault,
|
|
132
168
|
adminPermissions: null,
|
|
133
169
|
anchorRemainingAccounts,
|
|
134
170
|
systemProgram: web3_js_1.SystemProgram.programId,
|
|
@@ -145,7 +181,20 @@ class UsdcPlusStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
145
181
|
*/
|
|
146
182
|
constructRemainingAccounts() {
|
|
147
183
|
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
-
|
|
184
|
+
const { oracle, marketIndex } = sdk_1.SpotMarkets["mainnet-beta"][0];
|
|
185
|
+
const spotMarket = (0, sdk_1.getSpotMarketPublicKeySync)(constants_1.DRIFT_PROGRAM_ID, marketIndex);
|
|
186
|
+
return [
|
|
187
|
+
{
|
|
188
|
+
pubkey: oracle,
|
|
189
|
+
isSigner: false,
|
|
190
|
+
isWritable: true
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
pubkey: spotMarket,
|
|
194
|
+
isSigner: false,
|
|
195
|
+
isWritable: true
|
|
196
|
+
},
|
|
197
|
+
];
|
|
149
198
|
});
|
|
150
199
|
}
|
|
151
200
|
;
|
|
@@ -200,5 +249,31 @@ class UsdcPlusStablecoin extends Stablecoin_1.Stablecoin {
|
|
|
200
249
|
return [ix];
|
|
201
250
|
});
|
|
202
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Gets the USD exchange rate for the USDC+ stablecoin.
|
|
254
|
+
*
|
|
255
|
+
* @returns Promise resolving to the USD exchange rate as a number
|
|
256
|
+
*/
|
|
257
|
+
getUsdExchangeRate() {
|
|
258
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
const { scaledBalance, balanceType } = this
|
|
260
|
+
.driftClient
|
|
261
|
+
.getSpotPosition(0);
|
|
262
|
+
const spotMarketAccount = this
|
|
263
|
+
.driftClient
|
|
264
|
+
.getSpotMarketAccount(0);
|
|
265
|
+
const usdcAmount = (0, sdk_2.getTokenAmount)(scaledBalance, spotMarketAccount, balanceType);
|
|
266
|
+
const { supply, decimals } = yield (0, spl_token_1.getMint)(this.connection, this.stablecoinMint, "confirmed");
|
|
267
|
+
const [{ mint: usdcMint }] = this.collaterals;
|
|
268
|
+
const { data: [{ price: { expo, price } }] } = yield this.getCollateralPrice(usdcMint);
|
|
269
|
+
const exchangeRate = usdcAmount
|
|
270
|
+
.mul(new bn_js_1.default(price))
|
|
271
|
+
.mul(new bn_js_1.default(constants_1.EXCHANGE_RATE_PRECISION)) // gives us exhcnage rate precision
|
|
272
|
+
.div(new bn_js_1.default(supply.toString())) // price per stablecoin
|
|
273
|
+
.div(new bn_js_1.default(10 ** decimals)) // cancels out the USDC decimals
|
|
274
|
+
.div(new bn_js_1.default(10 ** expo)); // cancels out the price decimals
|
|
275
|
+
return exchangeRate.toNumber();
|
|
276
|
+
});
|
|
277
|
+
}
|
|
203
278
|
}
|
|
204
279
|
exports.UsdcPlusStablecoin = UsdcPlusStablecoin;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reflectmoney/stable.ts",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"type": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "commonjs",
|
|
5
5
|
"author": "stablecoinjesus @ Palindrome Engineering",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@coral-xyz/anchor": "0.29.0",
|
|
12
|
-
"@drift-labs/sdk": "^2.
|
|
12
|
+
"@drift-labs/sdk": "^2.129.0-beta.2",
|
|
13
13
|
"@metaplex-foundation/beet": "=0.7.2",
|
|
14
14
|
"@metaplex-foundation/beet-solana": "=0.4.1",
|
|
15
15
|
"@metaplex-foundation/mpl-token-metadata": "2.13.0",
|
|
@@ -18,13 +18,19 @@
|
|
|
18
18
|
"@solana/spl-token": "^0.4.12",
|
|
19
19
|
"@solana/web3.js": "^1.98.0",
|
|
20
20
|
"bn.js": "5.2.1",
|
|
21
|
-
"decimal.js": "^10.5.0"
|
|
21
|
+
"decimal.js": "^10.5.0",
|
|
22
|
+
"rpc-websockets": "7.11.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"@types/bn.js": "5.1.6"
|
|
25
|
+
"@types/bn.js": "5.1.6",
|
|
26
|
+
"@types/mocha": "^10.0.6",
|
|
27
|
+
"@types/chai": "^4.3.11",
|
|
28
|
+
"mocha": "^10.2.0",
|
|
29
|
+
"chai": "^4.3.10",
|
|
30
|
+
"ts-node": "^10.9.2"
|
|
25
31
|
},
|
|
26
32
|
"license": "MIT",
|
|
27
|
-
"main": "./
|
|
33
|
+
"main": "./dist/index.js",
|
|
28
34
|
"module": "./dist/index.js",
|
|
29
35
|
"types": "./dist/index.d.ts",
|
|
30
36
|
"files": [
|