@symmetry-hq/temp-v3-sdk 0.0.5 → 0.0.6
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/src/constants.js +1 -1
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.js +116 -0
- package/dist/src/instructions/user/deposit.d.ts +1 -1
- package/dist/src/instructions/user/deposit.js +34 -25
- package/dist/src/layouts/intents/rebalanceIntent.d.ts +1 -1
- package/dist/src/layouts/intents/rebalanceIntent.js +1 -1
- package/dist/src/states/oracles/oracle.js +4 -5
- package/dist/test.js +48 -0
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/index.ts +129 -3
- package/src/instructions/user/deposit.ts +43 -31
- package/src/layouts/intents/rebalanceIntent.ts +2 -2
- package/src/states/oracles/oracle.ts +4 -5
- package/test.ts +54 -0
package/dist/src/constants.js
CHANGED
|
@@ -15,7 +15,7 @@ exports.WSOL_MINT = new web3_js_1.PublicKey("So111111111111111111111111111111111
|
|
|
15
15
|
exports.USDC_MINT = new web3_js_1.PublicKey("USDCoctVLVnvTXBEuP9s8hntucdJokbo17RwHuNXemT");
|
|
16
16
|
exports.PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT = new web3_js_1.PublicKey("7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE");
|
|
17
17
|
exports.PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT = new web3_js_1.PublicKey("Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX");
|
|
18
|
-
exports.BOUNTY_MINT = new web3_js_1.PublicKey("
|
|
18
|
+
exports.BOUNTY_MINT = new web3_js_1.PublicKey("So11111111111111111111111111111111111111112");
|
|
19
19
|
exports.INTENT_TASK_DATA_SIZE = 600;
|
|
20
20
|
exports.MAX_MANAGERS_PER_BASKET = 10;
|
|
21
21
|
exports.X64 = new decimal_js_1.default(2).pow(new decimal_js_1.default(64));
|
package/dist/src/index.d.ts
CHANGED
|
@@ -48,6 +48,21 @@ export declare class SymmetryCore {
|
|
|
48
48
|
manager: PublicKey;
|
|
49
49
|
editType: TaskType;
|
|
50
50
|
}): Promise<VersionedTxs>;
|
|
51
|
+
depositTx(params: {
|
|
52
|
+
buyer: PublicKey;
|
|
53
|
+
basket: PublicKey;
|
|
54
|
+
contributions: {
|
|
55
|
+
mint: PublicKey;
|
|
56
|
+
amount: number;
|
|
57
|
+
}[];
|
|
58
|
+
rebalanceSlippageBps?: number;
|
|
59
|
+
executionStartTime?: number;
|
|
60
|
+
}): Promise<VersionedTxs>;
|
|
61
|
+
updateTokenPricesTx(params: {
|
|
62
|
+
keeper: PublicKey;
|
|
63
|
+
rebalanceIntent: RebalanceIntent;
|
|
64
|
+
basket: Basket;
|
|
65
|
+
}): Promise<VersionedTxs>;
|
|
51
66
|
signAndSendVersionedTxs(params: {
|
|
52
67
|
vtxs: VersionedTxs;
|
|
53
68
|
wallet: Wallet;
|
package/dist/src/index.js
CHANGED
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.SymmetryCore = exports.MAX_JUPITER_ACCOUNTS = exports.JUPITER_API_KEY = exports.PRIORITY_FEE = exports.COMPUTE_UNITS = void 0;
|
|
16
16
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
17
17
|
const web3_js_1 = require("@solana/web3.js");
|
|
18
|
+
const constants_1 = require("./constants");
|
|
18
19
|
const createBasket_1 = require("./instructions/management/createBasket");
|
|
19
20
|
const edit_1 = require("./instructions/management/edit");
|
|
20
21
|
const pda_1 = require("./instructions/pda");
|
|
@@ -25,6 +26,8 @@ const intent_2 = require("./states/intents/intent");
|
|
|
25
26
|
const rebalanceIntent_1 = require("./states/intents/rebalanceIntent");
|
|
26
27
|
const txUtils_1 = require("./txUtils");
|
|
27
28
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
29
|
+
const deposit_1 = require("./instructions/user/deposit");
|
|
30
|
+
const priceUpdate_1 = require("./instructions/automation/priceUpdate");
|
|
28
31
|
exports.COMPUTE_UNITS = 1000000;
|
|
29
32
|
exports.PRIORITY_FEE = 100000;
|
|
30
33
|
exports.JUPITER_API_KEY = "https://quote-api.jup.ag/v6/";
|
|
@@ -164,6 +167,119 @@ class SymmetryCore {
|
|
|
164
167
|
return vtxs;
|
|
165
168
|
});
|
|
166
169
|
}
|
|
170
|
+
depositTx(params) {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
+
let { buyer, basket, contributions, rebalanceSlippageBps, executionStartTime } = params;
|
|
173
|
+
if (!rebalanceSlippageBps)
|
|
174
|
+
rebalanceSlippageBps = 100;
|
|
175
|
+
if (!executionStartTime)
|
|
176
|
+
executionStartTime = 0;
|
|
177
|
+
let rebalanceIntent = (0, pda_1.getRebalanceIntentPda)(basket, buyer);
|
|
178
|
+
let batchIxs = [
|
|
179
|
+
[
|
|
180
|
+
(0, deposit_1.createUserRebalanceIntentIx)({
|
|
181
|
+
user: params.buyer,
|
|
182
|
+
basket: params.basket,
|
|
183
|
+
}),
|
|
184
|
+
(0, deposit_1.resizeRebalanceIntentIx)(rebalanceIntent),
|
|
185
|
+
(0, deposit_1.depositStateIx)({
|
|
186
|
+
buyer,
|
|
187
|
+
basket,
|
|
188
|
+
bountyMint: constants_1.BOUNTY_MINT,
|
|
189
|
+
rebalanceIntentRentPayer: buyer,
|
|
190
|
+
rebalanceSlippageBps: rebalanceSlippageBps,
|
|
191
|
+
executionStartTime: executionStartTime,
|
|
192
|
+
}),
|
|
193
|
+
]
|
|
194
|
+
];
|
|
195
|
+
let depositTokensIxs = (0, deposit_1.depositTokensIx)({
|
|
196
|
+
owner: buyer,
|
|
197
|
+
basket: basket,
|
|
198
|
+
contributions: contributions,
|
|
199
|
+
});
|
|
200
|
+
depositTokensIxs.forEach((ix) => {
|
|
201
|
+
batchIxs.push([ix]);
|
|
202
|
+
});
|
|
203
|
+
batchIxs.push([
|
|
204
|
+
(0, deposit_1.lockDepositsIx)({
|
|
205
|
+
owner: buyer,
|
|
206
|
+
basket: basket,
|
|
207
|
+
}),
|
|
208
|
+
]);
|
|
209
|
+
let signers = [];
|
|
210
|
+
let multipleLookupTableAddresses = [];
|
|
211
|
+
for (let i = 0; i < batchIxs.length; i++) {
|
|
212
|
+
signers.push([]);
|
|
213
|
+
multipleLookupTableAddresses.push([]);
|
|
214
|
+
}
|
|
215
|
+
let vtxs = yield (0, txUtils_1.prepareV0Transactions)({
|
|
216
|
+
connection: this.sdkParams.connection,
|
|
217
|
+
payer: buyer,
|
|
218
|
+
priorityFee: this.sdkParams.priorityFee,
|
|
219
|
+
multipleIxs: batchIxs,
|
|
220
|
+
multipleLookupTableAddresses: multipleLookupTableAddresses,
|
|
221
|
+
signers: signers,
|
|
222
|
+
batches: [1, depositTokensIxs.length, 1],
|
|
223
|
+
});
|
|
224
|
+
return vtxs;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
updateTokenPricesTx(params) {
|
|
228
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
+
let { keeper, rebalanceIntent, basket } = params;
|
|
230
|
+
let ixs = [];
|
|
231
|
+
let signers = [];
|
|
232
|
+
let multipleLookupTableAddresses = [];
|
|
233
|
+
let batches = [];
|
|
234
|
+
let batchSize = 5;
|
|
235
|
+
for (let batchStart = 0; batchStart < basket.numTokens; batchStart += batchSize) {
|
|
236
|
+
let allKeys = [];
|
|
237
|
+
let tokenIndices = [];
|
|
238
|
+
for (let i = batchStart; i < basket.numTokens && i < batchStart + batchSize; i++) {
|
|
239
|
+
tokenIndices.push(i);
|
|
240
|
+
let agg = basket.composition[i].oracleAggregator;
|
|
241
|
+
for (let i = 0; i < agg.numOracles; i++) {
|
|
242
|
+
const oracleData = agg.oracles[i];
|
|
243
|
+
for (let j = 0; j < oracleData.oracleSettings.numRequiredAccounts; j++) {
|
|
244
|
+
const lutId = oracleData.accountsToLoadLutIds[j];
|
|
245
|
+
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
246
|
+
if (lutId === 0 && lutIdx === 0)
|
|
247
|
+
continue;
|
|
248
|
+
if (!basket.lutPubkeys)
|
|
249
|
+
continue;
|
|
250
|
+
allKeys.push(basket.lutPubkeys[lutId].state.addresses[lutIdx]);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
while (tokenIndices.length < 20)
|
|
255
|
+
tokenIndices.push(0);
|
|
256
|
+
ixs.push([
|
|
257
|
+
(0, priceUpdate_1.updateTokenPricesIx)({
|
|
258
|
+
keeper: keeper,
|
|
259
|
+
basket: rebalanceIntent.basket, //@ts-ignore
|
|
260
|
+
rebalanceIntent: rebalanceIntent.ownAddress,
|
|
261
|
+
lookupTable0: basket.lookupTables.active[0],
|
|
262
|
+
lookupTable1: basket.lookupTables.active[1],
|
|
263
|
+
tokenIndices: tokenIndices,
|
|
264
|
+
additionalOracleAccounts: allKeys,
|
|
265
|
+
}),
|
|
266
|
+
]);
|
|
267
|
+
signers.push([]);
|
|
268
|
+
multipleLookupTableAddresses.push([]);
|
|
269
|
+
batches.push(1);
|
|
270
|
+
}
|
|
271
|
+
let vtxs = yield (0, txUtils_1.prepareV0Transactions)({
|
|
272
|
+
connection: this.sdkParams.connection,
|
|
273
|
+
payer: keeper,
|
|
274
|
+
priorityFee: this.sdkParams.priorityFee,
|
|
275
|
+
multipleIxs: ixs,
|
|
276
|
+
multipleLookupTableAddresses: multipleLookupTableAddresses,
|
|
277
|
+
signers: signers,
|
|
278
|
+
batches: batches,
|
|
279
|
+
});
|
|
280
|
+
return vtxs;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
167
283
|
signAndSendVersionedTxs(params) {
|
|
168
284
|
return __awaiter(this, void 0, void 0, function* () {
|
|
169
285
|
let { vtxs, wallet } = params;
|
|
@@ -98,31 +98,40 @@ function depositTokensIx(params) {
|
|
|
98
98
|
const { owner, basket, contributions } = params;
|
|
99
99
|
let rebalanceIntent = (0, pda_1.getRebalanceIntentPda)(basket, owner);
|
|
100
100
|
const discriminator = DEPOSIT_TOKENS_DISCRIMINATOR;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
101
|
+
let ixs = [];
|
|
102
|
+
let batch_size = 5;
|
|
103
|
+
for (let i = 0; i < contributions.length; i += batch_size) {
|
|
104
|
+
let batch_contributions = contributions.slice(i, i + batch_size);
|
|
105
|
+
let amounts = batch_contributions.map((contribution) => contribution.amount);
|
|
106
|
+
while (amounts.length < 10)
|
|
107
|
+
amounts.push(0);
|
|
108
|
+
const amountsBuffer = Buffer.concat(amounts.map((amount) => Buffer.from(new anchor_1.BN(amount).toArray("le", 8))));
|
|
109
|
+
const data = Buffer.concat([discriminator, amountsBuffer]);
|
|
110
|
+
const keys = [
|
|
111
|
+
{ pubkey: owner, isSigner: true, isWritable: true },
|
|
112
|
+
{ pubkey: basket, isSigner: false, isWritable: true },
|
|
113
|
+
{ pubkey: rebalanceIntent, isSigner: false, isWritable: true },
|
|
114
|
+
{ pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
115
|
+
{ pubkey: spl_token_1.TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
116
|
+
{ pubkey: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
117
|
+
{ pubkey: web3_js_3.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
118
|
+
];
|
|
119
|
+
// remaining accounts
|
|
120
|
+
batch_contributions.forEach((contribution) => {
|
|
121
|
+
let mint = contribution.mint;
|
|
122
|
+
let ownerAta = (0, pda_1.getAta)(owner, mint);
|
|
123
|
+
let basketAta = (0, pda_1.getAta)(basket, mint);
|
|
124
|
+
keys.push({ pubkey: mint, isSigner: false, isWritable: false });
|
|
125
|
+
keys.push({ pubkey: ownerAta, isSigner: false, isWritable: true });
|
|
126
|
+
keys.push({ pubkey: basketAta, isSigner: false, isWritable: true });
|
|
127
|
+
});
|
|
128
|
+
ixs.push(new web3_js_2.TransactionInstruction({
|
|
129
|
+
keys,
|
|
130
|
+
programId: constants_1.BASKETS_V3_PROGRAM_ID,
|
|
131
|
+
data,
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
return ixs;
|
|
126
135
|
}
|
|
127
136
|
function lockDepositsIx(params) {
|
|
128
137
|
const { owner, basket } = params;
|
|
@@ -30,9 +30,9 @@ export interface TokenAuction {
|
|
|
30
30
|
}
|
|
31
31
|
export declare const TokenAuctionLayout: any;
|
|
32
32
|
export interface TaskCompletion {
|
|
33
|
+
completedBy: PublicKey;
|
|
33
34
|
completedBounty: BN;
|
|
34
35
|
completedTime: BN;
|
|
35
|
-
completedBy: PublicKey;
|
|
36
36
|
}
|
|
37
37
|
export declare const TaskCompletionLayout: any;
|
|
38
38
|
export interface RebalanceIntent {
|
|
@@ -36,9 +36,9 @@ exports.TokenAuctionLayout = (0, borsh_1.struct)([
|
|
|
36
36
|
]);
|
|
37
37
|
;
|
|
38
38
|
exports.TaskCompletionLayout = (0, borsh_1.struct)([
|
|
39
|
+
(0, borsh_1.publicKey)('completedBy'),
|
|
39
40
|
(0, borsh_1.u64)('completedBounty'),
|
|
40
41
|
(0, borsh_1.u64)('completedTime'),
|
|
41
|
-
(0, borsh_1.publicKey)('completedBy'),
|
|
42
42
|
]);
|
|
43
43
|
;
|
|
44
44
|
exports.RebalanceIntentLayout = (0, borsh_1.struct)([
|
|
@@ -66,8 +66,6 @@ class PriceAggregator {
|
|
|
66
66
|
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
67
67
|
if (lutId === 0 && lutIdx === 0)
|
|
68
68
|
continue;
|
|
69
|
-
console.log(lutId, lutIdx);
|
|
70
|
-
console.log(lutAccounts[lutId]);
|
|
71
69
|
let pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
72
70
|
let account = accountInfoMap.get(pubkey.toBase58());
|
|
73
71
|
//@ts-ignore
|
|
@@ -98,9 +96,10 @@ class PriceAggregator {
|
|
|
98
96
|
let prices = [];
|
|
99
97
|
for (let i = 0; i < oracleResults.length; i++) {
|
|
100
98
|
const pr = oracleResults[i];
|
|
101
|
-
|
|
102
|
-
prices.push({ price: pr.
|
|
103
|
-
prices.push({ price: pr.
|
|
99
|
+
const weight = new decimal_js_1.default(agg.oracles[i].oracleSettings.weight);
|
|
100
|
+
prices.push({ price: pr.getMid(), weight: weight });
|
|
101
|
+
prices.push({ price: pr.getLow(), weight: weight });
|
|
102
|
+
prices.push({ price: pr.getHigh(), weight: weight });
|
|
104
103
|
}
|
|
105
104
|
const medianPrice = weightedPercentile(prices, 50);
|
|
106
105
|
const p25Price = weightedPercentile(prices, 25);
|
package/dist/test.js
CHANGED
|
@@ -37,6 +37,54 @@ function testStates() {
|
|
|
37
37
|
let kp = Array.from(web3_js_1.Keypair.generate().secretKey);
|
|
38
38
|
let wallet = new anchor_1.Wallet(web3_js_1.Keypair.fromSecretKey(new Uint8Array(kp)));
|
|
39
39
|
console.log(wallet.publicKey);
|
|
40
|
+
// let pubkey = await createAssociatedTokenAccountIdempotent(
|
|
41
|
+
// connection,
|
|
42
|
+
// wallet.payer,
|
|
43
|
+
// WSOL_MINT,
|
|
44
|
+
// wallet.publicKey,
|
|
45
|
+
// {commitment: "confirmed"},
|
|
46
|
+
// TOKEN_PROGRAM_ID,
|
|
47
|
+
// ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
48
|
+
// true,
|
|
49
|
+
// );
|
|
50
|
+
// let xxx = await createWrappedNativeAccount(
|
|
51
|
+
// connection,
|
|
52
|
+
// wallet.payer,
|
|
53
|
+
// wallet.publicKey,
|
|
54
|
+
// 1100000000,
|
|
55
|
+
// );
|
|
56
|
+
// console.log(xxx);
|
|
57
|
+
// return;
|
|
58
|
+
// let intentPda = getRebalanceIntentPda(basket.ownAddress, wallet.publicKey);
|
|
59
|
+
// let tx = await sdk.depositTx({
|
|
60
|
+
// buyer: wallet.publicKey,
|
|
61
|
+
// basket: basket.ownAddress,
|
|
62
|
+
// contributions: [{mint: USDC_MINT, amount: 10000000}],
|
|
63
|
+
// });
|
|
64
|
+
// let resTx = await sdk.signAndSendVersionedTxs({
|
|
65
|
+
// vtxs: tx,
|
|
66
|
+
// wallet,
|
|
67
|
+
// });
|
|
68
|
+
// console.log(resTx);
|
|
69
|
+
// return;
|
|
70
|
+
let myIntents = yield sdk.fetchAllRebalanceIntents([
|
|
71
|
+
{ filterType: "owner", filterValue: wallet.publicKey },
|
|
72
|
+
{ filterType: "basket", filterValue: basket.ownAddress }
|
|
73
|
+
]);
|
|
74
|
+
let myIntent = myIntents[0];
|
|
75
|
+
console.log(myIntent.priceUpdateTasks[0]);
|
|
76
|
+
console.log(myIntent.priceUpdateTasks[1]);
|
|
77
|
+
return;
|
|
78
|
+
let tx = yield sdk.updateTokenPricesTx({
|
|
79
|
+
keeper: wallet.publicKey,
|
|
80
|
+
rebalanceIntent: myIntent,
|
|
81
|
+
basket,
|
|
82
|
+
});
|
|
83
|
+
let resTx = yield sdk.signAndSendVersionedTxs({
|
|
84
|
+
vtxs: tx,
|
|
85
|
+
wallet,
|
|
86
|
+
});
|
|
87
|
+
console.log(resTx);
|
|
40
88
|
return;
|
|
41
89
|
let editWeightsTx = yield sdk.createEditBasketIntentTx({
|
|
42
90
|
manager: wallet.publicKey,
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -15,7 +15,7 @@ export const USDC_MINT = new PublicKey("USDCoctVLVnvTXBEuP9s8hntucdJokbo17RwHuNX
|
|
|
15
15
|
export const PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT = new PublicKey("7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE");
|
|
16
16
|
export const PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT = new PublicKey("Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX");
|
|
17
17
|
|
|
18
|
-
export const BOUNTY_MINT = new PublicKey("
|
|
18
|
+
export const BOUNTY_MINT = new PublicKey("So11111111111111111111111111111111111111112");
|
|
19
19
|
|
|
20
20
|
export const INTENT_TASK_DATA_SIZE = 600;
|
|
21
21
|
export const MAX_MANAGERS_PER_BASKET = 10;
|
package/src/index.ts
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import { BN } from '@coral-xyz/anchor';
|
|
2
2
|
import { Connection, Keypair, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
3
3
|
|
|
4
|
-
import { BOUNTY_MINT } from './constants';
|
|
4
|
+
import { BOUNTY_MINT, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT } from './constants';
|
|
5
5
|
import {
|
|
6
6
|
createBasketIx, createBasketStateAccountIx, resizeBasketStateIx
|
|
7
7
|
} from './instructions/management/createBasket';
|
|
8
8
|
import { createEditBasketIntentIx, editBasketIx } from './instructions/management/edit';
|
|
9
9
|
import {
|
|
10
10
|
getBasketState, getBasketTokenMintPda, getIntentPda, getLookupTableAccount, getMetadataAccount,
|
|
11
|
-
getRandomSeed
|
|
11
|
+
getRandomSeed,
|
|
12
|
+
getRebalanceIntentPda,
|
|
13
|
+
getRentPayerPda
|
|
12
14
|
} from './instructions/pda';
|
|
13
15
|
import { Basket } from './layouts/basket';
|
|
14
16
|
import { decimalToFraction, Fraction } from './layouts/fraction';
|
|
15
17
|
import { EditData, HostFees, Intent, MetadataParams, TaskType } from './layouts/intents/intent';
|
|
16
18
|
import { RebalanceIntent } from './layouts/intents/rebalanceIntent';
|
|
17
|
-
import { BasketFilter, fetchBasket, fetchBaskets, loadBasketPrice } from './states/basket';
|
|
19
|
+
import { BasketFilter, fetchBasket, fetchBaskets, getBasketOracleAccountInfos, loadBasketPrice } from './states/basket';
|
|
18
20
|
import { fetchIntents, IntentFilter } from './states/intents/intent';
|
|
19
21
|
import { fetchRebalanceIntents, RebalanceIntentFilter } from './states/intents/rebalanceIntent';
|
|
20
22
|
import { prepareV0Transactions, sendV0Transactions, signedVersionedTxs, VersionedTxs, Wallet } from './txUtils';
|
|
21
23
|
import Decimal from 'decimal.js';
|
|
24
|
+
import { createUserRebalanceIntentIx, depositStateIx, depositTokensIx, lockDepositsIx, resizeRebalanceIntentIx } from './instructions/user/deposit';
|
|
25
|
+
import { updateTokenPricesIx } from './instructions/automation/priceUpdate';
|
|
22
26
|
|
|
23
27
|
export const COMPUTE_UNITS = 1_000_000;
|
|
24
28
|
export const PRIORITY_FEE = 100_000;
|
|
@@ -220,6 +224,128 @@ export class SymmetryCore {
|
|
|
220
224
|
return vtxs;
|
|
221
225
|
}
|
|
222
226
|
|
|
227
|
+
async depositTx(params: {
|
|
228
|
+
buyer: PublicKey,
|
|
229
|
+
basket: PublicKey,
|
|
230
|
+
contributions: {mint: PublicKey, amount: number}[];
|
|
231
|
+
rebalanceSlippageBps?: number;
|
|
232
|
+
executionStartTime?: number;
|
|
233
|
+
}): Promise<VersionedTxs> {
|
|
234
|
+
let { buyer, basket, contributions, rebalanceSlippageBps, executionStartTime } = params;
|
|
235
|
+
if (!rebalanceSlippageBps)
|
|
236
|
+
rebalanceSlippageBps = 100;
|
|
237
|
+
if (!executionStartTime)
|
|
238
|
+
executionStartTime = 0;
|
|
239
|
+
let rebalanceIntent = getRebalanceIntentPda(basket, buyer);
|
|
240
|
+
let batchIxs = [
|
|
241
|
+
[
|
|
242
|
+
createUserRebalanceIntentIx({
|
|
243
|
+
user: params.buyer,
|
|
244
|
+
basket: params.basket,
|
|
245
|
+
}),
|
|
246
|
+
resizeRebalanceIntentIx(rebalanceIntent),
|
|
247
|
+
depositStateIx({
|
|
248
|
+
buyer,
|
|
249
|
+
basket,
|
|
250
|
+
bountyMint: BOUNTY_MINT,
|
|
251
|
+
rebalanceIntentRentPayer: buyer,
|
|
252
|
+
rebalanceSlippageBps: rebalanceSlippageBps,
|
|
253
|
+
executionStartTime: executionStartTime,
|
|
254
|
+
}),
|
|
255
|
+
]
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
let depositTokensIxs = depositTokensIx({
|
|
259
|
+
owner: buyer,
|
|
260
|
+
basket: basket,
|
|
261
|
+
contributions: contributions,
|
|
262
|
+
});
|
|
263
|
+
depositTokensIxs.forEach((ix) => {
|
|
264
|
+
batchIxs.push([ix]);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
batchIxs.push([
|
|
268
|
+
lockDepositsIx({
|
|
269
|
+
owner: buyer,
|
|
270
|
+
basket: basket,
|
|
271
|
+
}),
|
|
272
|
+
]);
|
|
273
|
+
|
|
274
|
+
let signers = [];
|
|
275
|
+
let multipleLookupTableAddresses = [];
|
|
276
|
+
for (let i = 0; i < batchIxs.length; i++) {
|
|
277
|
+
signers.push([]);
|
|
278
|
+
multipleLookupTableAddresses.push([]);
|
|
279
|
+
}
|
|
280
|
+
let vtxs = await prepareV0Transactions({
|
|
281
|
+
connection: this.sdkParams.connection,
|
|
282
|
+
payer: buyer,
|
|
283
|
+
priorityFee: this.sdkParams.priorityFee,
|
|
284
|
+
multipleIxs: batchIxs,
|
|
285
|
+
multipleLookupTableAddresses: multipleLookupTableAddresses,
|
|
286
|
+
signers: signers,
|
|
287
|
+
batches: [1, depositTokensIxs.length, 1],
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
return vtxs;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async updateTokenPricesTx(params: {
|
|
294
|
+
keeper: PublicKey,
|
|
295
|
+
rebalanceIntent: RebalanceIntent,
|
|
296
|
+
basket: Basket,
|
|
297
|
+
}): Promise<VersionedTxs> {
|
|
298
|
+
let { keeper, rebalanceIntent, basket } = params;
|
|
299
|
+
let ixs: TransactionInstruction[][] = [];
|
|
300
|
+
let signers: Keypair[][] = [];
|
|
301
|
+
let multipleLookupTableAddresses: PublicKey[][] = [];
|
|
302
|
+
let batches: number[] = [];
|
|
303
|
+
let batchSize = 5;
|
|
304
|
+
for (let batchStart = 0; batchStart < basket.numTokens; batchStart += batchSize) {
|
|
305
|
+
let allKeys: PublicKey[] = [];
|
|
306
|
+
let tokenIndices: number[] = [];
|
|
307
|
+
for (let i = batchStart; i < basket.numTokens && i < batchStart + batchSize; i++) {
|
|
308
|
+
tokenIndices.push(i);
|
|
309
|
+
let agg = basket.composition[i].oracleAggregator;
|
|
310
|
+
for (let i = 0; i < agg.numOracles; i++) {
|
|
311
|
+
const oracleData = agg.oracles[i];
|
|
312
|
+
for (let j = 0; j < oracleData.oracleSettings.numRequiredAccounts; j++) {
|
|
313
|
+
const lutId = oracleData.accountsToLoadLutIds[j];
|
|
314
|
+
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
315
|
+
if (lutId === 0 && lutIdx === 0) continue;
|
|
316
|
+
if (!basket.lutPubkeys) continue;
|
|
317
|
+
allKeys.push(basket.lutPubkeys[lutId].state.addresses[lutIdx]);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
while (tokenIndices.length < 20) tokenIndices.push(0);
|
|
322
|
+
ixs.push([
|
|
323
|
+
updateTokenPricesIx({
|
|
324
|
+
keeper: keeper,
|
|
325
|
+
basket: rebalanceIntent.basket, //@ts-ignore
|
|
326
|
+
rebalanceIntent: rebalanceIntent.ownAddress,
|
|
327
|
+
lookupTable0: basket.lookupTables.active[0],
|
|
328
|
+
lookupTable1: basket.lookupTables.active[1],
|
|
329
|
+
tokenIndices: tokenIndices,
|
|
330
|
+
additionalOracleAccounts: allKeys,
|
|
331
|
+
}),
|
|
332
|
+
]);
|
|
333
|
+
signers.push([]);
|
|
334
|
+
multipleLookupTableAddresses.push([]);
|
|
335
|
+
batches.push(1);
|
|
336
|
+
}
|
|
337
|
+
let vtxs = await prepareV0Transactions({
|
|
338
|
+
connection: this.sdkParams.connection,
|
|
339
|
+
payer: keeper,
|
|
340
|
+
priorityFee: this.sdkParams.priorityFee,
|
|
341
|
+
multipleIxs: ixs,
|
|
342
|
+
multipleLookupTableAddresses: multipleLookupTableAddresses,
|
|
343
|
+
signers: signers,
|
|
344
|
+
batches: batches,
|
|
345
|
+
});
|
|
346
|
+
return vtxs;
|
|
347
|
+
}
|
|
348
|
+
|
|
223
349
|
async signAndSendVersionedTxs(params: {
|
|
224
350
|
vtxs: VersionedTxs,
|
|
225
351
|
wallet: Wallet,
|
|
@@ -130,48 +130,60 @@ export function depositTokensIx(params: {
|
|
|
130
130
|
owner: PublicKey;
|
|
131
131
|
basket: PublicKey;
|
|
132
132
|
contributions: {mint: PublicKey, amount: number}[]; // length 10
|
|
133
|
-
}): TransactionInstruction{
|
|
133
|
+
}): TransactionInstruction[] {
|
|
134
134
|
|
|
135
135
|
const { owner, basket, contributions } = params;
|
|
136
136
|
|
|
137
137
|
let rebalanceIntent = getRebalanceIntentPda(basket, owner);
|
|
138
138
|
|
|
139
139
|
const discriminator = DEPOSIT_TOKENS_DISCRIMINATOR;
|
|
140
|
-
const amountsBuffer = Buffer.concat(
|
|
141
|
-
contributions.map((contribution) => Buffer.from(new BN(contribution.amount).toArray("le", 8)))
|
|
142
|
-
);
|
|
143
|
-
const data = Buffer.concat([discriminator, amountsBuffer]);
|
|
144
|
-
|
|
145
|
-
const keys = [
|
|
146
|
-
{ pubkey: owner, isSigner: true, isWritable: true },
|
|
147
|
-
{ pubkey: basket, isSigner: false, isWritable: true },
|
|
148
|
-
{ pubkey: rebalanceIntent, isSigner: false, isWritable: true },
|
|
149
|
-
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
150
|
-
{ pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
151
|
-
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
152
|
-
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
153
|
-
];
|
|
154
|
-
|
|
155
|
-
// remaining accounts
|
|
156
|
-
contributions.forEach((contribution) => {
|
|
157
|
-
let mint = contribution.mint;
|
|
158
|
-
let ownerAta = getAta(owner, mint);
|
|
159
|
-
let basketAta = getAta(basket, mint);
|
|
160
|
-
keys.push({ pubkey: mint, isSigner: false, isWritable: false });
|
|
161
|
-
keys.push({ pubkey: ownerAta, isSigner: false, isWritable: true });
|
|
162
|
-
keys.push({ pubkey: basketAta, isSigner: false, isWritable: true });
|
|
163
|
-
});
|
|
164
140
|
|
|
141
|
+
let ixs: TransactionInstruction[] = [];
|
|
142
|
+
|
|
143
|
+
let batch_size = 5;
|
|
144
|
+
for (let i = 0; i < contributions.length; i += batch_size) {
|
|
145
|
+
let batch_contributions = contributions.slice(i, i + batch_size);
|
|
146
|
+
let amounts = batch_contributions.map((contribution) => contribution.amount);
|
|
147
|
+
while (amounts.length < 10) amounts.push(0);
|
|
148
|
+
const amountsBuffer = Buffer.concat(
|
|
149
|
+
amounts.map((amount) => Buffer.from(new BN(amount).toArray("le", 8)))
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const data = Buffer.concat([discriminator, amountsBuffer]);
|
|
153
|
+
|
|
154
|
+
const keys = [
|
|
155
|
+
{ pubkey: owner, isSigner: true, isWritable: true },
|
|
156
|
+
{ pubkey: basket, isSigner: false, isWritable: true },
|
|
157
|
+
{ pubkey: rebalanceIntent, isSigner: false, isWritable: true },
|
|
158
|
+
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
159
|
+
{ pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
160
|
+
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
161
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
// remaining accounts
|
|
165
|
+
batch_contributions.forEach((contribution) => {
|
|
166
|
+
let mint = contribution.mint;
|
|
167
|
+
let ownerAta = getAta(owner, mint);
|
|
168
|
+
let basketAta = getAta(basket, mint);
|
|
169
|
+
keys.push({ pubkey: mint, isSigner: false, isWritable: false });
|
|
170
|
+
keys.push({ pubkey: ownerAta, isSigner: false, isWritable: true });
|
|
171
|
+
keys.push({ pubkey: basketAta, isSigner: false, isWritable: true });
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
ixs.push(
|
|
175
|
+
new TransactionInstruction({
|
|
176
|
+
keys,
|
|
177
|
+
programId: BASKETS_V3_PROGRAM_ID,
|
|
178
|
+
data,
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
}
|
|
165
182
|
|
|
166
|
-
return
|
|
167
|
-
keys,
|
|
168
|
-
programId: BASKETS_V3_PROGRAM_ID,
|
|
169
|
-
data,
|
|
170
|
-
});
|
|
183
|
+
return ixs;
|
|
171
184
|
}
|
|
172
185
|
|
|
173
186
|
|
|
174
|
-
|
|
175
187
|
export function lockDepositsIx(params: {
|
|
176
188
|
owner: PublicKey;
|
|
177
189
|
basket: PublicKey;
|
|
@@ -48,15 +48,15 @@ export const TokenAuctionLayout = struct<TokenAuction>([
|
|
|
48
48
|
]);
|
|
49
49
|
|
|
50
50
|
export interface TaskCompletion {
|
|
51
|
+
completedBy: PublicKey; //Pubkey
|
|
51
52
|
completedBounty: BN; //u64
|
|
52
53
|
completedTime: BN; //u64
|
|
53
|
-
completedBy: PublicKey; //Pubkey
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
export const TaskCompletionLayout = struct<TaskCompletion>([
|
|
57
|
+
publicKey('completedBy'),
|
|
57
58
|
u64('completedBounty'),
|
|
58
59
|
u64('completedTime'),
|
|
59
|
-
publicKey('completedBy'),
|
|
60
60
|
]);
|
|
61
61
|
|
|
62
62
|
export interface RebalanceIntent {
|
|
@@ -89,8 +89,6 @@ export class PriceAggregator{
|
|
|
89
89
|
const lutId = oracleData.accountsToLoadLutIds[j];
|
|
90
90
|
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
91
91
|
if (lutId === 0 && lutIdx === 0) continue;
|
|
92
|
-
console.log(lutId, lutIdx);
|
|
93
|
-
console.log(lutAccounts[lutId]);
|
|
94
92
|
let pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
95
93
|
let account = accountInfoMap.get(pubkey.toBase58());
|
|
96
94
|
//@ts-ignore
|
|
@@ -127,9 +125,10 @@ export class PriceAggregator{
|
|
|
127
125
|
|
|
128
126
|
for (let i = 0; i < oracleResults.length; i++) {
|
|
129
127
|
const pr = oracleResults[i];
|
|
130
|
-
|
|
131
|
-
prices.push({ price: pr.
|
|
132
|
-
prices.push({ price: pr.
|
|
128
|
+
const weight = new Decimal(agg.oracles[i].oracleSettings.weight);
|
|
129
|
+
prices.push({ price: pr.getMid(), weight: weight });
|
|
130
|
+
prices.push({ price: pr.getLow(), weight: weight });
|
|
131
|
+
prices.push({ price: pr.getHigh(), weight: weight });
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
const medianPrice = weightedPercentile(prices, 50);
|
package/test.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { decimalToFraction, fractionToDecimal } from "./src/layouts/fraction";
|
|
|
6
6
|
import { OracleType, Quote, Side } from "./src/layouts/oracle";
|
|
7
7
|
import { PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, USDC_MINT, WSOL_MINT } from "./src/constants";
|
|
8
8
|
import { TaskType } from "./src/layouts/intents/intent";
|
|
9
|
+
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
let connection = new Connection("https://api.devnet.solana.com");
|
|
@@ -27,6 +28,59 @@ async function testStates() {
|
|
|
27
28
|
let kp = Array.from(Keypair.generate().secretKey);
|
|
28
29
|
let wallet = new Wallet(Keypair.fromSecretKey(new Uint8Array(kp)));
|
|
29
30
|
console.log(wallet.publicKey);
|
|
31
|
+
|
|
32
|
+
// let pubkey = await createAssociatedTokenAccountIdempotent(
|
|
33
|
+
// connection,
|
|
34
|
+
// wallet.payer,
|
|
35
|
+
// WSOL_MINT,
|
|
36
|
+
// wallet.publicKey,
|
|
37
|
+
// {commitment: "confirmed"},
|
|
38
|
+
// TOKEN_PROGRAM_ID,
|
|
39
|
+
// ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
40
|
+
// true,
|
|
41
|
+
// );
|
|
42
|
+
// let xxx = await createWrappedNativeAccount(
|
|
43
|
+
// connection,
|
|
44
|
+
// wallet.payer,
|
|
45
|
+
// wallet.publicKey,
|
|
46
|
+
// 1100000000,
|
|
47
|
+
// );
|
|
48
|
+
// console.log(xxx);
|
|
49
|
+
// return;
|
|
50
|
+
// let intentPda = getRebalanceIntentPda(basket.ownAddress, wallet.publicKey);
|
|
51
|
+
|
|
52
|
+
// let tx = await sdk.depositTx({
|
|
53
|
+
// buyer: wallet.publicKey,
|
|
54
|
+
// basket: basket.ownAddress,
|
|
55
|
+
// contributions: [{mint: USDC_MINT, amount: 10000000}],
|
|
56
|
+
// });
|
|
57
|
+
// let resTx = await sdk.signAndSendVersionedTxs({
|
|
58
|
+
// vtxs: tx,
|
|
59
|
+
// wallet,
|
|
60
|
+
// });
|
|
61
|
+
// console.log(resTx);
|
|
62
|
+
// return;
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
let myIntents = await sdk.fetchAllRebalanceIntents([
|
|
66
|
+
{filterType: "owner", filterValue: wallet.publicKey},
|
|
67
|
+
{filterType: "basket", filterValue: basket.ownAddress}
|
|
68
|
+
]);
|
|
69
|
+
let myIntent = myIntents[0];
|
|
70
|
+
console.log(myIntent.priceUpdateTasks[0]);
|
|
71
|
+
console.log(myIntent.priceUpdateTasks[1]);
|
|
72
|
+
return;
|
|
73
|
+
|
|
74
|
+
let tx = await sdk.updateTokenPricesTx({
|
|
75
|
+
keeper: wallet.publicKey,
|
|
76
|
+
rebalanceIntent: myIntent,
|
|
77
|
+
basket,
|
|
78
|
+
});
|
|
79
|
+
let resTx = await sdk.signAndSendVersionedTxs({
|
|
80
|
+
vtxs: tx,
|
|
81
|
+
wallet,
|
|
82
|
+
});
|
|
83
|
+
console.log(resTx);
|
|
30
84
|
return;
|
|
31
85
|
let editWeightsTx = await sdk.createEditBasketIntentTx({
|
|
32
86
|
manager: wallet.publicKey,
|