flash-sdk 1.0.16 → 1.0.18

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.
@@ -170,7 +170,7 @@ export class PerpetualsClient {
170
170
  };
171
171
 
172
172
  getPool = async (name: string) => {
173
- console.log("pool:", this.getPoolKey(name).toBase58())
173
+ // console.log("pool:", this.getPoolKey(name).toBase58())
174
174
  return this.program.account.pool.fetch(this.getPoolKey(name));
175
175
  };
176
176
 
@@ -214,7 +214,7 @@ export class PerpetualsClient {
214
214
  };
215
215
 
216
216
  getCustody = async (poolName: string, tokenMint: PublicKey) => {
217
- console.log("custody key :", this.getCustodyKey(poolName, tokenMint).toBase58());
217
+ // console.log("custody key :", this.getCustodyKey(poolName, tokenMint).toBase58());
218
218
  return this.program.account.custody.fetch(
219
219
  this.getCustodyKey(poolName, tokenMint)
220
220
  );
@@ -407,7 +407,7 @@ export class PerpetualsClient {
407
407
  } catch (err) {
408
408
  // @ts-ignore
409
409
  if (this.printErrors) {
410
- console.log(err);
410
+ console.error("setAdminSigners err:",err);
411
411
  }
412
412
  throw err;
413
413
  }
@@ -465,8 +465,8 @@ export class PerpetualsClient {
465
465
  borrowRate: BorrowRateParams,
466
466
  ratios: TokenRatios[]
467
467
  ) => {
468
- console.log("CustodyKey", this.getCustodyKey(poolName, tokenMint).toBase58())
469
- console.log("getCustodyTokenAccountKey", this.getCustodyTokenAccountKey(poolName, tokenMint).toBase58())
468
+ // console.log("CustodyKey", this.getCustodyKey(poolName, tokenMint).toBase58())
469
+ // console.log("getCustodyTokenAccountKey", this.getCustodyTokenAccountKey(poolName, tokenMint).toBase58())
470
470
  try {
471
471
  const trx_id = await this.program.methods
472
472
  // @ts-ignore
@@ -504,7 +504,7 @@ export class PerpetualsClient {
504
504
 
505
505
  console.log("trx_id:", `https://explorer.solana.com/tx/${trx_id}?cluster=devnet`)
506
506
  } catch (error) {
507
- console.log("cli error :", error);
507
+ console.error("cli error :", error);
508
508
  }
509
509
 
510
510
 
@@ -521,8 +521,8 @@ export class PerpetualsClient {
521
521
  borrowRate: BorrowRateParams,
522
522
  ratios: TokenRatios[]
523
523
  ) => {
524
- console.log("CustodyKey", this.getCustodyKey(poolName, tokenMint).toBase58())
525
- console.log("getCustodyTokenAccountKey", this.getCustodyTokenAccountKey(poolName, tokenMint).toBase58())
524
+ // console.log("editCustody CustodyKey", this.getCustodyKey(poolName, tokenMint).toBase58())
525
+ // console.log("editCustody getCustodyTokenAccountKey", this.getCustodyTokenAccountKey(poolName, tokenMint).toBase58())
526
526
 
527
527
  const trx_id = await this.program.methods
528
528
  //@ts-ignore
@@ -726,11 +726,10 @@ export class PerpetualsClient {
726
726
  size: BN,
727
727
  side: PositionSide
728
728
  ) => {
729
- console.log("perps: ", this.perpetuals.publicKey.toBase58())
730
-
731
- console.log("poolKey: ", this.getPoolKey(poolName).toBase58())
732
- console.log("custody key : ", this.getCustodyKey(poolName, tokenMint).toBase58());
733
- console.log("orcalve: ", (await this.getCustodyOracleAccountKey(poolName, tokenMint)).toBase58())
729
+ // console.log("perps: ", this.perpetuals.publicKey.toBase58())
730
+ // console.log("poolKey: ", this.getPoolKey(poolName).toBase58())
731
+ // console.log("custody key : ", this.getCustodyKey(poolName, tokenMint).toBase58());
732
+ // console.log("oracle: ", (await this.getCustodyOracleAccountKey(poolName, tokenMint)).toBase58())
734
733
 
735
734
  //@ts-ignore
736
735
  return await this.program.methods
@@ -901,7 +900,7 @@ export class PerpetualsClient {
901
900
  side: PositionSide
902
901
  ) => {
903
902
  const pos = this.getPositionKey(wallet, poolName, tokenMint, side);
904
- console.log("pos:", pos.toBase58())
903
+ // console.log("pos:", pos.toBase58())
905
904
  return await this.program.methods
906
905
  .getPnl({})
907
906
  .accounts({
@@ -929,7 +928,7 @@ export class PerpetualsClient {
929
928
  side: PositionSide
930
929
  ) => {
931
930
  const pos = this.getPositionKey(wallet, poolName, tokenMint, side);
932
- console.log("pos:", pos.toBase58())
931
+ // console.log("pos:", pos.toBase58())
933
932
  return await this.program.methods
934
933
  .getPnl({})
935
934
  .accounts({
@@ -1102,46 +1101,6 @@ export class PerpetualsClient {
1102
1101
  // Create WSOL Token account and not ATA and close it in end
1103
1102
  if (payTokenSymbol == 'SOL' && createUserWSOLATA) {
1104
1103
  console.log("payTokenSymbol === sol", payTokenSymbol);
1105
- // const wsolAssociatedTokenAccount = userCustodyTokenAccount;
1106
- // const wsolATAExist = await checkIfAccountExists(wsolAssociatedTokenAccount, this.provider.connection)
1107
- // if (!wsolATAExist) {
1108
- // console.log("wsol ata does not exist");
1109
- // instructions.push(
1110
- // createAssociatedTokenAccountInstruction(
1111
- // publicKey,
1112
- // wsolAssociatedTokenAccount,
1113
- // publicKey,
1114
- // NATIVE_MINT
1115
- // )
1116
- // );
1117
- // }
1118
- // // get balance of WSOL associated token account
1119
- // const wsolBalance = new BN(wsolATAExist ? (await this.provider.connection.getTokenAccountBalance(wsolAssociatedTokenAccount)).value.amount : 0);
1120
- // if (wsolBalance.lt(collateralWithfee)) {
1121
- // console.log("WSOL balance insufficient \n so Convert SOL to WSOL");
1122
- // let unWrappedSolBalance = new BN(await this.provider.connection.getBalance(publicKey));
1123
- // const totalSolBal = unWrappedSolBalance.add(wsolBalance);
1124
- // // const rentExemptSolNeedforATA = new BN(0.02 * LAMPORTS_PER_SOL);
1125
- // // console.log("rentExemptSolNeedforATA:",rentExemptSolNeedforATA.toString())
1126
- // //TODOD :: add(rentExemptSolNeedforATA)
1127
- // if (totalSolBal.lt(collateralWithfee)) {
1128
- // throw "Insufficient SOL Funds"
1129
- // } else {
1130
- // console.log("SOL balance sufficient so transfer from SOL to WSOL ATA")
1131
- // }
1132
-
1133
- // let conversionAmt = collateralWithfee.sub(wsolBalance);
1134
- // console.log("conversionAmt:",conversionAmt.toString())
1135
- // instructions.push(
1136
- // SystemProgram.transfer({
1137
- // fromPubkey: publicKey,
1138
- // toPubkey: wsolAssociatedTokenAccount,
1139
- // lamports: conversionAmt.toNumber(), // IS IT SAFE TO PUT AS NUMBER
1140
- // }),
1141
- // createSyncNativeInstruction(wsolAssociatedTokenAccount)
1142
- // );
1143
- // }
1144
-
1145
1104
  wrappedSolAccount = new Keypair();
1146
1105
  const accCreationLamports = (await getMinimumBalanceForRentExemptAccount(this.provider.connection)); // for account creation
1147
1106
  console.log("accCreationLamports:",accCreationLamports)
@@ -1328,7 +1287,7 @@ export class PerpetualsClient {
1328
1287
  this.programId
1329
1288
  )[0];
1330
1289
 
1331
- console.log("positionAccount:", positionAccount.toBase58())
1290
+ // console.log("positionAccount:", positionAccount.toBase58())
1332
1291
  const params: any = {
1333
1292
  price: priceAfterSlippage,
1334
1293
  };
@@ -1365,6 +1324,235 @@ export class PerpetualsClient {
1365
1324
  };
1366
1325
  }
1367
1326
 
1327
+
1328
+ // ==== OLD
1329
+ // TODO: handle SOL wrapping to WSOL and create a ATA - DONE
1330
+ // TODO: Balance checks - DONE
1331
+ // TODO: ATA check - else create - DONE
1332
+ // TODO: for close Accounts - NOT NEEDED
1333
+ openPositionOld = async (
1334
+ payTokenSymbol: string,
1335
+ priceAfterSlippage: BN,
1336
+ collateral: BN,
1337
+ fee : BN,
1338
+ size: BN,
1339
+ side: Side,
1340
+ poolConfig: PoolConfig,
1341
+ createUserWSOLATA = true // if false will also skip balance checks
1342
+ ): Promise<TransactionInstruction[]> => {
1343
+
1344
+ console.log("open position :::", payTokenSymbol, poolConfig.getTokenFromSymbol(payTokenSymbol).mintKey.toBase58());
1345
+
1346
+ // const slippageMultiplier = isVariant(side, 'long') ? -1 : 1;
1347
+ // const priceAfterSlippage = price.mul(new BN((100 - (slippagePercentage * slippageMultiplier)) * 100)).div(new BN(100 * 100))
1348
+
1349
+ let publicKey = this.provider.wallet.publicKey;
1350
+ const payTokenCustody = poolConfig.custodies.find(i => i.mintKey.equals(poolConfig.getTokenFromSymbol(payTokenSymbol).mintKey))!;
1351
+
1352
+ let userCustodyTokenAccount = await getAssociatedTokenAddress(
1353
+ poolConfig.getTokenFromSymbol(payTokenSymbol).mintKey,
1354
+ publicKey
1355
+ );
1356
+
1357
+ const instructions = [];
1358
+ try {
1359
+
1360
+ if (payTokenSymbol == 'SOL' && createUserWSOLATA) {
1361
+ console.log("payTokenSymbol === sol", payTokenSymbol);
1362
+ const wsolAssociatedTokenAccount = userCustodyTokenAccount;
1363
+ // await getAssociatedTokenAddress(
1364
+ // NATIVE_MINT,
1365
+ // publicKey
1366
+ // );
1367
+ const wsolATAExist = await checkIfAccountExists(wsolAssociatedTokenAccount, this.provider.connection)
1368
+ if (!wsolATAExist) {
1369
+ console.log("wsol ata does not exist");
1370
+ instructions.push(
1371
+ createAssociatedTokenAccountInstruction(
1372
+ publicKey,
1373
+ wsolAssociatedTokenAccount,
1374
+ publicKey,
1375
+ NATIVE_MINT
1376
+ )
1377
+ );
1378
+ }
1379
+
1380
+ const collateralWithfee = collateral.add(fee);
1381
+
1382
+ // get balance of WSOL associated token account
1383
+ const wsolBalance = new BN(wsolATAExist ? (await this.provider.connection.getTokenAccountBalance(wsolAssociatedTokenAccount)).value.amount : 0);
1384
+ if (wsolBalance.lt(collateralWithfee)) {
1385
+ console.log("WSOL balance insufficient \n so Convert SOL to WSOL");
1386
+ let unWrappedSolBalance = new BN(await this.provider.connection.getBalance(publicKey));
1387
+ const totalSolBal = unWrappedSolBalance.add(wsolBalance);
1388
+ // const rentExemptSolNeedforATA = new BN(0.02 * LAMPORTS_PER_SOL);
1389
+ // console.log("rentExemptSolNeedforATA:",rentExemptSolNeedforATA.toString())
1390
+ //TODOD :: add(rentExemptSolNeedforATA)
1391
+ if (totalSolBal.lt(collateralWithfee)) {
1392
+ throw "Insufficient SOL Funds"
1393
+ } else {
1394
+ console.log("SOL balance sufficient so transfer from SOL to WSOL ATA")
1395
+ }
1396
+
1397
+ let conversionAmt = collateralWithfee.sub(wsolBalance);
1398
+ console.log("conversionAmt:",conversionAmt.toString())
1399
+ instructions.push(
1400
+ SystemProgram.transfer({
1401
+ fromPubkey: publicKey,
1402
+ toPubkey: wsolAssociatedTokenAccount,
1403
+ lamports: conversionAmt.toNumber(), // IS IT SAFE TO PUT AS NUMBER
1404
+ }),
1405
+ createSyncNativeInstruction(wsolAssociatedTokenAccount)
1406
+ );
1407
+ }
1408
+ } else if(createUserWSOLATA == false){
1409
+ console.log("skip WSOL checks and creation ,since createUserWSOLATA == false")
1410
+ } else {
1411
+ // for other tokens check if ATA and balance
1412
+ if (!(await checkIfAccountExists(userCustodyTokenAccount, this.provider.connection))) {
1413
+ throw "Insufficient Funds , token Account doesn't exist"
1414
+ }
1415
+ const tokenAccountBalance = new BN((await this.provider.connection.getTokenAccountBalance(userCustodyTokenAccount)).value.amount);
1416
+ if (tokenAccountBalance.lt(collateral.add(fee))) {
1417
+ throw "Insufficient Funds"
1418
+ }
1419
+ }
1420
+
1421
+ // replace with getPositionKey()
1422
+ let positionAccount = PublicKey.findProgramAddressSync(
1423
+ [
1424
+ Buffer.from("position"),
1425
+ publicKey.toBuffer(),
1426
+ poolConfig.poolAddress.toBuffer(),
1427
+ payTokenCustody.custodyAccount.toBuffer(),
1428
+ isVariant(side, 'long') ? Buffer.from([1]) : Buffer.from([2]),
1429
+ ],
1430
+ this.programId
1431
+ )[0];
1432
+
1433
+ const params: any = {
1434
+ price: priceAfterSlippage,
1435
+ collateral,
1436
+ size,
1437
+ side,
1438
+ };
1439
+
1440
+ let instruction = await this.program.methods
1441
+ .openPosition(params)
1442
+ .accounts({
1443
+ owner: publicKey,
1444
+ fundingAccount: userCustodyTokenAccount,
1445
+ transferAuthority: poolConfig.transferAuthority,
1446
+ perpetuals: poolConfig.perpetuals,
1447
+ pool: poolConfig.poolAddress,
1448
+ position: positionAccount,
1449
+ custody: payTokenCustody.custodyAccount,
1450
+ custodyOracleAccount:
1451
+ payTokenCustody.oracleAddress,
1452
+ custodyTokenAccount:
1453
+ payTokenCustody.tokenAccount,
1454
+ systemProgram: SystemProgram.programId,
1455
+ tokenProgram: TOKEN_PROGRAM_ID,
1456
+ }).instruction()
1457
+ instructions.push(instruction);
1458
+
1459
+ } catch (error) {
1460
+ console.log("perpClient openPosition error:", error)
1461
+ }
1462
+ return instructions;
1463
+ }
1464
+
1465
+ // ==== OLD
1466
+ // TODO: handle SOL wrapping to WSOL and create a ATA - NOT NEEDED
1467
+ // TODO : Balance checks - NOT NEEDED
1468
+ // TODO: ATA check - else create - DONE
1469
+ // TODO: for close Accounts - DONE BY ANCHOR
1470
+ // TODO : if out token WSOL -> unwrap to SOL - DONE
1471
+ closePositionOld = async (
1472
+ receivingTokenSymbol: string,
1473
+ priceAfterSlippage: BN,
1474
+ side: Side,
1475
+ poolConfig: PoolConfig
1476
+ ): Promise<TransactionInstruction[]> => {
1477
+
1478
+ console.log("close position :::", receivingTokenSymbol, poolConfig.getTokenFromSymbol(receivingTokenSymbol).mintKey.toBase58());
1479
+
1480
+ // opp during close
1481
+ // const slippageMultiplier = isVariant(side, 'short') ? -1 : 1;
1482
+ // const priceAfterSlippage = price.mul(new BN((100 - (slippagePercentage * slippageMultiplier)) * 100)).div(new BN(100 * 100))
1483
+
1484
+ let publicKey = this.provider.wallet.publicKey;
1485
+
1486
+ let userReceivingTokenAccount = await getAssociatedTokenAddress(
1487
+ poolConfig.getTokenFromSymbol(receivingTokenSymbol).mintKey,
1488
+ publicKey
1489
+ );
1490
+ const instructions = [];
1491
+ try {
1492
+
1493
+ if (!(await checkIfAccountExists(userReceivingTokenAccount, this.provider.connection))) {
1494
+ instructions.push(
1495
+ createAssociatedTokenAccountInstruction(
1496
+ publicKey,
1497
+ userReceivingTokenAccount,
1498
+ publicKey,
1499
+ poolConfig.getTokenFromSymbol(receivingTokenSymbol).mintKey
1500
+ )
1501
+ );
1502
+ }
1503
+
1504
+ const receivingTokenCustody = poolConfig.custodies.find(i => i.mintKey.equals(poolConfig.getTokenFromSymbol(receivingTokenSymbol).mintKey))!;
1505
+
1506
+ // replace with getPositionKey
1507
+ let positionAccount = PublicKey.findProgramAddressSync(
1508
+ [
1509
+ Buffer.from("position"),
1510
+ publicKey.toBuffer(),
1511
+ poolConfig.poolAddress.toBuffer(),
1512
+ receivingTokenCustody.custodyAccount.toBuffer(),
1513
+ isVariant(side, 'long') ? Buffer.from([1]) : Buffer.from([2]),
1514
+ ],
1515
+ this.programId
1516
+ )[0];
1517
+
1518
+ console.log("positionAccount:", positionAccount.toBase58())
1519
+ const params: any = {
1520
+ price: priceAfterSlippage,
1521
+ };
1522
+
1523
+ let instruction = await this.program.methods
1524
+ .closePosition(params)
1525
+ .accounts({
1526
+ owner: publicKey,
1527
+ receivingAccount: userReceivingTokenAccount,
1528
+ transferAuthority: poolConfig.transferAuthority,
1529
+ perpetuals: poolConfig.perpetuals,
1530
+ pool: poolConfig.poolAddress,
1531
+ position: positionAccount,
1532
+ custody: receivingTokenCustody.custodyAccount,
1533
+ custodyOracleAccount:
1534
+ receivingTokenCustody.oracleAddress,
1535
+ custodyTokenAccount:
1536
+ receivingTokenCustody.tokenAccount,
1537
+ tokenProgram: TOKEN_PROGRAM_ID,
1538
+ }).instruction();
1539
+ instructions.push(instruction)
1540
+
1541
+ // SOL is only retrievable by closing the token account and choosing the desired address to send the token account's lamports.
1542
+ if (receivingTokenSymbol == 'SOL') {
1543
+ // await closeAccount()
1544
+ const closeWsolATAIns = createCloseAccountInstruction(userReceivingTokenAccount, publicKey, publicKey);
1545
+ instructions.push(closeWsolATAIns);
1546
+ }
1547
+ } catch (error) {
1548
+ console.error("perpclient closePosition error:", error);
1549
+ }
1550
+
1551
+ return instructions;
1552
+ }
1553
+
1554
+
1555
+
1368
1556
  // TODO: ATA check - else create - DONE
1369
1557
  // TODO: handle SOL wrapping to WSOL and create a ATA - DONE
1370
1558
  // TODO : Balance checks - NOT NEEDED
@@ -1504,7 +1692,7 @@ export class PerpetualsClient {
1504
1692
  }
1505
1693
 
1506
1694
  } catch (err) {
1507
- console.log("perpClient Swap error:: ", err);
1695
+ console.error("perpClient Swap error:: ", err);
1508
1696
  throw err;
1509
1697
  }
1510
1698
 
@@ -55,6 +55,7 @@
55
55
  ],
56
56
  "custodies": [
57
57
  {
58
+ "custodyId" : 0,
58
59
  "custodyAccount": "CkYddgaB8c5tvs9WP11B83HvMaU35ZFpTzLLGg4NviEj",
59
60
  "tokenAccount": "DHy9BXo36hwKkvBJnPd11zH77BefA77mTiL7yu2LNWPx",
60
61
  "symbol": "USDC",
@@ -64,6 +65,7 @@
64
65
  "oracleAddress": "5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7"
65
66
  },
66
67
  {
68
+ "custodyId" : 1,
67
69
  "custodyAccount": "4ueMZBmpTMPykYwTENJs7diYfgx6UBCPQnRwb2F5UFgw",
68
70
  "tokenAccount": "G9bJQdZkzXZsiwouZ8MsZw6p8Pg5vtM9hbVHjfqSrJZo",
69
71
  "symbol": "SOL",
@@ -73,6 +75,7 @@
73
75
  "oracleAddress": "J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix"
74
76
  },
75
77
  {
78
+ "custodyId" : 2,
76
79
  "custodyAccount": "F9qzX5pHGS5SFfP5M24a8dqXUHQdraexJ3P9TNGF2WFj",
77
80
  "tokenAccount": "y5vPUaQdM3fJkEyn3oA8uFMRzwJYcNJsjBZyW1yRUar",
78
81
  "symbol": "BTC",
@@ -82,6 +85,7 @@
82
85
  "oracleAddress": "HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J"
83
86
  },
84
87
  {
88
+ "custodyId" : 3,
85
89
  "custodyAccount": "BZggMsfpcpbB3tnhmtM2qJ1uMobKVBEmYZp2jmDrBHZD",
86
90
  "tokenAccount": "HP4CcezCpCZqcoo8BsrroFEaykz2F4bz6sWBCCUJEBPy",
87
91
  "symbol": "ETH",
package/src/PoolConfig.ts CHANGED
@@ -4,6 +4,7 @@ import poolConfigs from './PoolConfig.json';
4
4
 
5
5
 
6
6
  export interface CustodyConfig {
7
+ custodyId: number;
7
8
  custodyAccount: PublicKey;
8
9
  tokenAccount: PublicKey;
9
10
  symbol: string;
@@ -108,9 +109,10 @@ export class PoolConfig {
108
109
  mintKey : new PublicKey(i.mintKey)
109
110
  }
110
111
  })
111
- const custodies : CustodyConfig[] = poolConfig['custodies'].map(i => {
112
+ const custodies : CustodyConfig[] = poolConfig['custodies'].map((i, index) => {
112
113
  return {
113
114
  ...i,
115
+ custodyId : i?.custodyId ?? index,
114
116
  custodyAccount : new PublicKey(i.custodyAccount),
115
117
  tokenAccount : new PublicKey(i.tokenAccount),
116
118
  mintKey : new PublicKey(i.mintKey),