@drift-labs/sdk 0.2.0-master.8 → 0.2.0-temp.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.
- package/lib/admin.d.ts +3 -3
- package/lib/admin.js +6 -6
- package/lib/clearingHouse.d.ts +15 -4
- package/lib/clearingHouse.js +200 -37
- package/lib/clearingHouseUser.d.ts +2 -2
- package/lib/clearingHouseUser.js +8 -17
- package/lib/config.js +1 -1
- package/lib/constants/banks.js +2 -3
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/idl/clearing_house.json +484 -103
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/orders.js +1 -1
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +7 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +41 -40
- package/lib/types.d.ts +62 -13
- package/lib/types.js +12 -1
- package/lib/util/computeUnits.js +1 -1
- package/package.json +1 -1
- package/src/admin.js +517 -0
- package/src/admin.ts +7 -7
- package/src/clearingHouse.ts +335 -47
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +12 -23
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.js +67 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +2 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/factory/bigNum.js +37 -11
- package/src/idl/clearing_house.json +484 -103
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.js +1 -1
- package/src/index.ts +1 -1
- package/src/mockUSDCFaucet.js +276 -167
- package/src/orders.ts +2 -1
- package/src/tokenFaucet.js +189 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +48 -59
- package/src/types.js +12 -1
- package/src/types.ts +63 -13
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.js +9 -0
- package/src/addresses/pda.js +0 -104
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
package/src/clearingHouse.ts
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
AccountMeta,
|
|
30
30
|
} from '@solana/web3.js';
|
|
31
31
|
|
|
32
|
-
import {
|
|
32
|
+
import { TokenFaucet } from './tokenFaucet';
|
|
33
33
|
import { EventEmitter } from 'events';
|
|
34
34
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
35
35
|
import {
|
|
@@ -644,11 +644,12 @@ export class ClearingHouse {
|
|
|
644
644
|
public async initializeUserAccountForDevnet(
|
|
645
645
|
userId = 0,
|
|
646
646
|
name = DEFAULT_USER_NAME,
|
|
647
|
-
|
|
647
|
+
bankIndex: BN,
|
|
648
|
+
tokenFaucet: TokenFaucet,
|
|
648
649
|
amount: BN
|
|
649
650
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
650
651
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] =
|
|
651
|
-
await
|
|
652
|
+
await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(
|
|
652
653
|
this.wallet.publicKey,
|
|
653
654
|
amount
|
|
654
655
|
);
|
|
@@ -658,7 +659,7 @@ export class ClearingHouse {
|
|
|
658
659
|
|
|
659
660
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
660
661
|
amount,
|
|
661
|
-
|
|
662
|
+
bankIndex,
|
|
662
663
|
associateTokenPublicKey,
|
|
663
664
|
userId,
|
|
664
665
|
false,
|
|
@@ -1390,72 +1391,359 @@ export class ClearingHouse {
|
|
|
1390
1391
|
});
|
|
1391
1392
|
}
|
|
1392
1393
|
|
|
1393
|
-
public async
|
|
1394
|
-
|
|
1394
|
+
public async liquidatePerp(
|
|
1395
|
+
userAccountPublicKey: PublicKey,
|
|
1396
|
+
userAccount: UserAccount,
|
|
1397
|
+
marketIndex: BN,
|
|
1398
|
+
maxBaseAssetAmount: BN
|
|
1395
1399
|
): Promise<TransactionSignature> {
|
|
1396
1400
|
const { txSig } = await this.txSender.send(
|
|
1397
|
-
wrapInTx(
|
|
1401
|
+
wrapInTx(
|
|
1402
|
+
await this.getLiquidatePerpIx(
|
|
1403
|
+
userAccountPublicKey,
|
|
1404
|
+
userAccount,
|
|
1405
|
+
marketIndex,
|
|
1406
|
+
maxBaseAssetAmount
|
|
1407
|
+
)
|
|
1408
|
+
),
|
|
1398
1409
|
[],
|
|
1399
1410
|
this.opts
|
|
1400
1411
|
);
|
|
1401
1412
|
return txSig;
|
|
1402
1413
|
}
|
|
1403
1414
|
|
|
1404
|
-
public async
|
|
1405
|
-
|
|
1415
|
+
public async getLiquidatePerpIx(
|
|
1416
|
+
userAccountPublicKey: PublicKey,
|
|
1417
|
+
userAccount: UserAccount,
|
|
1418
|
+
marketIndex: BN,
|
|
1419
|
+
maxBaseAssetAmount: BN
|
|
1406
1420
|
): Promise<TransactionInstruction> {
|
|
1407
|
-
const
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1421
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1422
|
+
|
|
1423
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1424
|
+
writableMarketIndex: marketIndex,
|
|
1425
|
+
userAccount,
|
|
1426
|
+
});
|
|
1411
1427
|
|
|
1412
|
-
|
|
1428
|
+
return await this.program.instruction.liquidatePerp(
|
|
1429
|
+
marketIndex,
|
|
1430
|
+
maxBaseAssetAmount,
|
|
1413
1431
|
{
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1432
|
+
accounts: {
|
|
1433
|
+
state: await this.getStatePublicKey(),
|
|
1434
|
+
authority: this.wallet.publicKey,
|
|
1435
|
+
user: userAccountPublicKey,
|
|
1436
|
+
liquidator: liquidatorPublicKey,
|
|
1437
|
+
},
|
|
1438
|
+
remainingAccounts: remainingAccounts,
|
|
1439
|
+
}
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
public async liquidateBorrow(
|
|
1444
|
+
userAccountPublicKey: PublicKey,
|
|
1445
|
+
userAccount: UserAccount,
|
|
1446
|
+
assetBankIndex: BN,
|
|
1447
|
+
liabilityBankIndex: BN,
|
|
1448
|
+
maxLiabilityTransfer: BN
|
|
1449
|
+
): Promise<TransactionSignature> {
|
|
1450
|
+
const { txSig } = await this.txSender.send(
|
|
1451
|
+
wrapInTx(
|
|
1452
|
+
await this.getLiquidateBorrowIx(
|
|
1453
|
+
userAccountPublicKey,
|
|
1454
|
+
userAccount,
|
|
1455
|
+
assetBankIndex,
|
|
1456
|
+
liabilityBankIndex,
|
|
1457
|
+
maxLiabilityTransfer
|
|
1458
|
+
)
|
|
1459
|
+
),
|
|
1460
|
+
[],
|
|
1461
|
+
this.opts
|
|
1462
|
+
);
|
|
1463
|
+
return txSig;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
public async getLiquidateBorrowIx(
|
|
1467
|
+
userAccountPublicKey: PublicKey,
|
|
1468
|
+
userAccount: UserAccount,
|
|
1469
|
+
assetBankIndex: BN,
|
|
1470
|
+
liabilityBankIndex: BN,
|
|
1471
|
+
maxLiabilityTransfer: BN
|
|
1472
|
+
): Promise<TransactionInstruction> {
|
|
1473
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1474
|
+
|
|
1475
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1476
|
+
userAccount,
|
|
1477
|
+
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
return await this.program.instruction.liquidateBorrow(
|
|
1481
|
+
assetBankIndex,
|
|
1482
|
+
liabilityBankIndex,
|
|
1483
|
+
maxLiabilityTransfer,
|
|
1484
|
+
{
|
|
1485
|
+
accounts: {
|
|
1486
|
+
state: await this.getStatePublicKey(),
|
|
1487
|
+
authority: this.wallet.publicKey,
|
|
1488
|
+
user: userAccountPublicKey,
|
|
1489
|
+
liquidator: liquidatorPublicKey,
|
|
1490
|
+
},
|
|
1491
|
+
remainingAccounts: remainingAccounts,
|
|
1492
|
+
}
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
public async liquidateBorrowForPerpPnl(
|
|
1497
|
+
userAccountPublicKey: PublicKey,
|
|
1498
|
+
userAccount: UserAccount,
|
|
1499
|
+
perpMarketIndex: BN,
|
|
1500
|
+
liabilityBankIndex: BN,
|
|
1501
|
+
maxLiabilityTransfer: BN
|
|
1502
|
+
): Promise<TransactionSignature> {
|
|
1503
|
+
const { txSig } = await this.txSender.send(
|
|
1504
|
+
wrapInTx(
|
|
1505
|
+
await this.getLiquidateBorrowForPerpPnlIx(
|
|
1506
|
+
userAccountPublicKey,
|
|
1507
|
+
userAccount,
|
|
1508
|
+
perpMarketIndex,
|
|
1509
|
+
liabilityBankIndex,
|
|
1510
|
+
maxLiabilityTransfer
|
|
1511
|
+
)
|
|
1512
|
+
),
|
|
1513
|
+
[],
|
|
1514
|
+
this.opts
|
|
1515
|
+
);
|
|
1516
|
+
return txSig;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
public async getLiquidateBorrowForPerpPnlIx(
|
|
1520
|
+
userAccountPublicKey: PublicKey,
|
|
1521
|
+
userAccount: UserAccount,
|
|
1522
|
+
perpMarketIndex: BN,
|
|
1523
|
+
liabilityBankIndex: BN,
|
|
1524
|
+
maxLiabilityTransfer: BN
|
|
1525
|
+
): Promise<TransactionInstruction> {
|
|
1526
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1527
|
+
|
|
1528
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1529
|
+
userAccount,
|
|
1530
|
+
writableMarketIndex: perpMarketIndex,
|
|
1531
|
+
writableBankIndexes: [liabilityBankIndex],
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
return await this.program.instruction.liquidateBorrowForPerpPnl(
|
|
1535
|
+
perpMarketIndex,
|
|
1536
|
+
liabilityBankIndex,
|
|
1537
|
+
maxLiabilityTransfer,
|
|
1538
|
+
{
|
|
1539
|
+
accounts: {
|
|
1540
|
+
state: await this.getStatePublicKey(),
|
|
1541
|
+
authority: this.wallet.publicKey,
|
|
1542
|
+
user: userAccountPublicKey,
|
|
1543
|
+
liquidator: liquidatorPublicKey,
|
|
1544
|
+
},
|
|
1545
|
+
remainingAccounts: remainingAccounts,
|
|
1546
|
+
}
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
public async liquidatePerpPnlForDeposit(
|
|
1551
|
+
userAccountPublicKey: PublicKey,
|
|
1552
|
+
userAccount: UserAccount,
|
|
1553
|
+
perpMarketIndex: BN,
|
|
1554
|
+
assetBankIndex: BN,
|
|
1555
|
+
maxPnlTransfer: BN
|
|
1556
|
+
): Promise<TransactionSignature> {
|
|
1557
|
+
const { txSig } = await this.txSender.send(
|
|
1558
|
+
wrapInTx(
|
|
1559
|
+
await this.getLiquidatePerpPnlForDepositIx(
|
|
1560
|
+
userAccountPublicKey,
|
|
1561
|
+
userAccount,
|
|
1562
|
+
perpMarketIndex,
|
|
1563
|
+
assetBankIndex,
|
|
1564
|
+
maxPnlTransfer
|
|
1565
|
+
)
|
|
1566
|
+
),
|
|
1567
|
+
[],
|
|
1568
|
+
this.opts
|
|
1569
|
+
);
|
|
1570
|
+
return txSig;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
public async getLiquidatePerpPnlForDepositIx(
|
|
1574
|
+
userAccountPublicKey: PublicKey,
|
|
1575
|
+
userAccount: UserAccount,
|
|
1576
|
+
perpMarketIndex: BN,
|
|
1577
|
+
assetBankIndex: BN,
|
|
1578
|
+
maxPnlTransfer: BN
|
|
1579
|
+
): Promise<TransactionInstruction> {
|
|
1580
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1581
|
+
|
|
1582
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1583
|
+
userAccount,
|
|
1584
|
+
writableMarketIndex: perpMarketIndex,
|
|
1585
|
+
writableBankIndexes: [assetBankIndex],
|
|
1586
|
+
});
|
|
1587
|
+
|
|
1588
|
+
return await this.program.instruction.liquidatePerpPnlForDeposit(
|
|
1589
|
+
perpMarketIndex,
|
|
1590
|
+
assetBankIndex,
|
|
1591
|
+
maxPnlTransfer,
|
|
1592
|
+
{
|
|
1593
|
+
accounts: {
|
|
1594
|
+
state: await this.getStatePublicKey(),
|
|
1595
|
+
authority: this.wallet.publicKey,
|
|
1596
|
+
user: userAccountPublicKey,
|
|
1597
|
+
liquidator: liquidatorPublicKey,
|
|
1598
|
+
},
|
|
1599
|
+
remainingAccounts: remainingAccounts,
|
|
1600
|
+
}
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
getRemainingAccountsForLiquidation(params: {
|
|
1605
|
+
userAccount: UserAccount;
|
|
1606
|
+
writableMarketIndex?: BN;
|
|
1607
|
+
writableBankIndexes?: BN[];
|
|
1608
|
+
}): AccountMeta[] {
|
|
1609
|
+
const liquidateeUserAccount = params.userAccount;
|
|
1610
|
+
|
|
1611
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1612
|
+
const bankAccountMap = new Map<number, AccountMeta>();
|
|
1613
|
+
const marketAccountMap = new Map<number, AccountMeta>();
|
|
1614
|
+
for (const bankBalance of liquidateeUserAccount.bankBalances) {
|
|
1615
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
1616
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1617
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1618
|
+
pubkey: bankAccount.pubkey,
|
|
1619
|
+
isSigner: false,
|
|
1620
|
+
isWritable: false,
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1624
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1625
|
+
pubkey: bankAccount.oracle,
|
|
1626
|
+
isSigner: false,
|
|
1627
|
+
isWritable: false,
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1421
1632
|
for (const position of liquidateeUserAccount.positions) {
|
|
1422
1633
|
if (!positionIsAvailable(position)) {
|
|
1423
1634
|
const market = this.getMarketAccount(position.marketIndex);
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
);
|
|
1428
|
-
marketAccountInfos.push({
|
|
1429
|
-
pubkey: marketPublicKey,
|
|
1430
|
-
isWritable: true,
|
|
1635
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1636
|
+
pubkey: market.pubkey,
|
|
1637
|
+
isWritable: false,
|
|
1431
1638
|
isSigner: false,
|
|
1432
1639
|
});
|
|
1433
|
-
|
|
1640
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1434
1641
|
pubkey: market.amm.oracle,
|
|
1435
1642
|
isWritable: false,
|
|
1436
1643
|
isSigner: false,
|
|
1437
1644
|
});
|
|
1438
1645
|
}
|
|
1439
1646
|
}
|
|
1440
|
-
const remainingAccounts = oracleAccountInfos.concat(
|
|
1441
|
-
bankAccountInfos.concat(marketAccountInfos)
|
|
1442
|
-
);
|
|
1443
1647
|
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1648
|
+
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
1649
|
+
if (!userAccountAndSlot) {
|
|
1650
|
+
throw Error(
|
|
1651
|
+
'No user account found. Most likely user account does not exist or failed to fetch account'
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
const { data: userAccount, slot: lastUserPositionsSlot } =
|
|
1655
|
+
userAccountAndSlot;
|
|
1656
|
+
|
|
1657
|
+
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
1658
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1659
|
+
// otherwise remove from slot
|
|
1660
|
+
if (slot > lastUserPositionsSlot) {
|
|
1661
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
1662
|
+
marketAccountMap.set(marketIndexNum, {
|
|
1663
|
+
pubkey: marketAccount.pubkey,
|
|
1664
|
+
isSigner: false,
|
|
1665
|
+
isWritable: false,
|
|
1666
|
+
});
|
|
1667
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1668
|
+
pubkey: marketAccount.amm.oracle,
|
|
1669
|
+
isSigner: false,
|
|
1670
|
+
isWritable: false,
|
|
1671
|
+
});
|
|
1672
|
+
} else {
|
|
1673
|
+
this.marketLastSlotCache.delete(marketIndexNum);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
1677
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
1678
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1679
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1680
|
+
pubkey: bankAccount.pubkey,
|
|
1681
|
+
isSigner: false,
|
|
1682
|
+
isWritable: false,
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1686
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1687
|
+
pubkey: bankAccount.oracle,
|
|
1688
|
+
isSigner: false,
|
|
1689
|
+
isWritable: false,
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
for (const position of userAccount.positions) {
|
|
1695
|
+
if (!positionIsAvailable(position)) {
|
|
1696
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
1697
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1698
|
+
pubkey: market.pubkey,
|
|
1699
|
+
isWritable: false,
|
|
1700
|
+
isSigner: false,
|
|
1701
|
+
});
|
|
1702
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1703
|
+
pubkey: market.amm.oracle,
|
|
1704
|
+
isWritable: false,
|
|
1705
|
+
isSigner: false,
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
if (params.writableMarketIndex) {
|
|
1711
|
+
const market = this.getMarketAccount(params.writableMarketIndex);
|
|
1712
|
+
marketAccountMap.set(market.marketIndex.toNumber(), {
|
|
1713
|
+
pubkey: market.pubkey,
|
|
1714
|
+
isSigner: false,
|
|
1715
|
+
isWritable: true,
|
|
1716
|
+
});
|
|
1717
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1718
|
+
pubkey: market.amm.oracle,
|
|
1719
|
+
isSigner: false,
|
|
1720
|
+
isWritable: false,
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
if (params.writableBankIndexes) {
|
|
1725
|
+
for (const writableBankIndex of params.writableBankIndexes) {
|
|
1726
|
+
const bank = this.getBankAccount(writableBankIndex);
|
|
1727
|
+
bankAccountMap.set(bank.bankIndex.toNumber(), {
|
|
1728
|
+
pubkey: bank.pubkey,
|
|
1729
|
+
isSigner: false,
|
|
1730
|
+
isWritable: true,
|
|
1731
|
+
});
|
|
1732
|
+
if (!bank.oracle.equals(PublicKey.default)) {
|
|
1733
|
+
oracleAccountMap.set(bank.oracle.toString(), {
|
|
1734
|
+
pubkey: bank.oracle,
|
|
1735
|
+
isSigner: false,
|
|
1736
|
+
isWritable: false,
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
return [
|
|
1743
|
+
...oracleAccountMap.values(),
|
|
1744
|
+
...bankAccountMap.values(),
|
|
1745
|
+
...marketAccountMap.values(),
|
|
1746
|
+
];
|
|
1459
1747
|
}
|
|
1460
1748
|
|
|
1461
1749
|
public async updateFundingRate(
|
package/src/clearingHouseUser.ts
CHANGED
|
@@ -205,7 +205,7 @@ export class ClearingHouseUser {
|
|
|
205
205
|
/**
|
|
206
206
|
* @returns The partial margin requirement in USDC. : QUOTE_PRECISION
|
|
207
207
|
*/
|
|
208
|
-
public
|
|
208
|
+
public getMaintenanceMarginRequirement(): BN {
|
|
209
209
|
return this.getUserAccount()
|
|
210
210
|
.positions.reduce((marginRequirement, marketPosition) => {
|
|
211
211
|
const market = this.clearingHouse.getMarketAccount(
|
|
@@ -217,7 +217,7 @@ export class ClearingHouseUser {
|
|
|
217
217
|
marketPosition,
|
|
218
218
|
this.getOracleDataForMarket(market.marketIndex)
|
|
219
219
|
)
|
|
220
|
-
.mul(new BN(market.
|
|
220
|
+
.mul(new BN(market.marginRatioMaintenance))
|
|
221
221
|
.div(MARGIN_PRECISION)
|
|
222
222
|
);
|
|
223
223
|
}, ZERO)
|
|
@@ -514,9 +514,6 @@ export class ClearingHouseUser {
|
|
|
514
514
|
case 'Maintenance':
|
|
515
515
|
marginRatioCategory = market.marginRatioMaintenance;
|
|
516
516
|
break;
|
|
517
|
-
case 'Partial':
|
|
518
|
-
marginRatioCategory = market.marginRatioPartial;
|
|
519
|
-
break;
|
|
520
517
|
default:
|
|
521
518
|
marginRatioCategory = market.marginRatioInitial;
|
|
522
519
|
break;
|
|
@@ -543,7 +540,8 @@ export class ClearingHouseUser {
|
|
|
543
540
|
|
|
544
541
|
public canBeLiquidated(): [boolean, BN] {
|
|
545
542
|
const totalCollateral = this.getTotalCollateral();
|
|
546
|
-
const partialMaintenanceRequirement =
|
|
543
|
+
const partialMaintenanceRequirement =
|
|
544
|
+
this.getMaintenanceMarginRequirement();
|
|
547
545
|
const marginRatio = this.getMarginRatio();
|
|
548
546
|
const canLiquidate = totalCollateral.lt(partialMaintenanceRequirement);
|
|
549
547
|
return [canLiquidate, marginRatio];
|
|
@@ -587,8 +585,7 @@ export class ClearingHouseUser {
|
|
|
587
585
|
*/
|
|
588
586
|
public liquidationPrice(
|
|
589
587
|
marketPosition: Pick<UserPosition, 'marketIndex'>,
|
|
590
|
-
positionBaseSizeChange: BN = ZERO
|
|
591
|
-
partial = false
|
|
588
|
+
positionBaseSizeChange: BN = ZERO
|
|
592
589
|
): BN {
|
|
593
590
|
// solves formula for example canBeLiquidated below
|
|
594
591
|
|
|
@@ -661,11 +658,7 @@ export class ClearingHouseUser {
|
|
|
661
658
|
this.getOracleDataForMarket(market.marketIndex)
|
|
662
659
|
);
|
|
663
660
|
const marketMarginRequirement = positionValue
|
|
664
|
-
.mul(
|
|
665
|
-
partial
|
|
666
|
-
? new BN(market.marginRatioPartial)
|
|
667
|
-
: new BN(market.marginRatioMaintenance)
|
|
668
|
-
)
|
|
661
|
+
.mul(new BN(market.marginRatioMaintenance))
|
|
669
662
|
.div(MARGIN_PRECISION);
|
|
670
663
|
totalMarginRequirement = totalMarginRequirement.add(
|
|
671
664
|
marketMarginRequirement
|
|
@@ -691,20 +684,17 @@ export class ClearingHouseUser {
|
|
|
691
684
|
const marginRequirementAfterTrade =
|
|
692
685
|
marginRequirementExcludingTargetMarket.add(
|
|
693
686
|
proposedMarketPositionValue
|
|
694
|
-
.mul(
|
|
695
|
-
partial
|
|
696
|
-
? new BN(market.marginRatioPartial)
|
|
697
|
-
: new BN(market.marginRatioMaintenance)
|
|
698
|
-
)
|
|
687
|
+
.mul(new BN(market.marginRatioMaintenance))
|
|
699
688
|
.div(MARGIN_PRECISION)
|
|
700
689
|
);
|
|
701
690
|
const freeCollateralAfterTrade = totalCollateral.sub(
|
|
702
691
|
marginRequirementAfterTrade
|
|
703
692
|
);
|
|
704
693
|
|
|
705
|
-
const marketMaxLeverage =
|
|
706
|
-
|
|
707
|
-
|
|
694
|
+
const marketMaxLeverage = this.getMaxLeverage(
|
|
695
|
+
proposedMarketPosition.marketIndex,
|
|
696
|
+
'Maintenance'
|
|
697
|
+
);
|
|
708
698
|
|
|
709
699
|
let priceDelta;
|
|
710
700
|
if (proposedBaseAssetAmount.lt(ZERO)) {
|
|
@@ -777,8 +767,7 @@ export class ClearingHouseUser {
|
|
|
777
767
|
{
|
|
778
768
|
marketIndex: positionMarketIndex,
|
|
779
769
|
},
|
|
780
|
-
closeBaseAmount
|
|
781
|
-
true
|
|
770
|
+
closeBaseAmount
|
|
782
771
|
);
|
|
783
772
|
}
|
|
784
773
|
|
package/src/config.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMarketsBanksAndOraclesForSubscription = exports.initialize = exports.getConfig = exports.configs = void 0;
|
|
4
|
+
const markets_1 = require("./constants/markets");
|
|
5
|
+
const banks_1 = require("./constants/banks");
|
|
6
|
+
exports.configs = {
|
|
7
|
+
devnet: {
|
|
8
|
+
ENV: 'devnet',
|
|
9
|
+
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
10
|
+
CLEARING_HOUSE_PROGRAM_ID: '4oyTJnAQ9FqJj1y9mPytbWsLeeHmBzGYfuFqypwyQvuh',
|
|
11
|
+
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
12
|
+
MARKETS: markets_1.DevnetMarkets,
|
|
13
|
+
BANKS: banks_1.DevnetBanks,
|
|
14
|
+
},
|
|
15
|
+
'mainnet-beta': {
|
|
16
|
+
ENV: 'mainnet-beta',
|
|
17
|
+
PYTH_ORACLE_MAPPING_ADDRESS: 'AHtgzX45WTKfkPG53L6WYhGEXwQkN1BVknET3sVsLL8J',
|
|
18
|
+
CLEARING_HOUSE_PROGRAM_ID: 'dammHkt7jmytvbS3nHTxQNEcP59aE57nxwV21YdqEDN',
|
|
19
|
+
USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
20
|
+
MARKETS: markets_1.MainnetMarkets,
|
|
21
|
+
BANKS: banks_1.MainnetBanks,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
let currentConfig = exports.configs.devnet;
|
|
25
|
+
const getConfig = () => currentConfig;
|
|
26
|
+
exports.getConfig = getConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Allows customization of the SDK's environment and endpoints. You can pass individual settings to override the settings with your own presets.
|
|
29
|
+
*
|
|
30
|
+
* Defaults to master environment if you don't use this function.
|
|
31
|
+
* @param props
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
const initialize = (props) => {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
//@ts-ignore
|
|
37
|
+
if (props.env === 'master')
|
|
38
|
+
return Object.assign(Object.assign({}, exports.configs['devnet']), ((_a = props.overrideEnv) !== null && _a !== void 0 ? _a : {}));
|
|
39
|
+
currentConfig = Object.assign(Object.assign({}, exports.configs[props.env]), ((_b = props.overrideEnv) !== null && _b !== void 0 ? _b : {}));
|
|
40
|
+
return currentConfig;
|
|
41
|
+
};
|
|
42
|
+
exports.initialize = initialize;
|
|
43
|
+
function getMarketsBanksAndOraclesForSubscription(env) {
|
|
44
|
+
const marketIndexes = [];
|
|
45
|
+
const bankIndexes = [];
|
|
46
|
+
const oracleInfos = new Map();
|
|
47
|
+
for (const market of markets_1.Markets[env]) {
|
|
48
|
+
marketIndexes.push(market.marketIndex);
|
|
49
|
+
oracleInfos.set(market.oracle.toString(), {
|
|
50
|
+
publicKey: market.oracle,
|
|
51
|
+
source: market.oracleSource,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
for (const bank of banks_1.Banks[env]) {
|
|
55
|
+
bankIndexes.push(bank.bankIndex);
|
|
56
|
+
oracleInfos.set(bank.oracle.toString(), {
|
|
57
|
+
publicKey: bank.oracle,
|
|
58
|
+
source: bank.oracleSource,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
marketIndexes,
|
|
63
|
+
bankIndexes,
|
|
64
|
+
oracleInfos: Array.from(oracleInfos.values()),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
exports.getMarketsBanksAndOraclesForSubscription = getMarketsBanksAndOraclesForSubscription;
|
package/src/config.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
|
|
|
28
28
|
devnet: {
|
|
29
29
|
ENV: 'devnet',
|
|
30
30
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
31
|
-
CLEARING_HOUSE_PROGRAM_ID: '
|
|
31
|
+
CLEARING_HOUSE_PROGRAM_ID: '4oyTJnAQ9FqJj1y9mPytbWsLeeHmBzGYfuFqypwyQvuh',
|
|
32
32
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
33
33
|
MARKETS: DevnetMarkets,
|
|
34
34
|
BANKS: DevnetBanks,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Banks = exports.MainnetBanks = exports.DevnetBanks = exports.WRAPPED_SOL_MINT = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const __1 = require("../");
|
|
6
|
+
exports.WRAPPED_SOL_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
|
|
7
|
+
exports.DevnetBanks = [
|
|
8
|
+
{
|
|
9
|
+
symbol: 'USDC',
|
|
10
|
+
bankIndex: new __1.BN(0),
|
|
11
|
+
oracle: web3_js_1.PublicKey.default,
|
|
12
|
+
oracleSource: __1.OracleSource.QUOTE_ASSET,
|
|
13
|
+
mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
symbol: 'SOL',
|
|
17
|
+
bankIndex: new __1.BN(1),
|
|
18
|
+
oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
19
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
20
|
+
mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
symbol: 'BTC',
|
|
24
|
+
bankIndex: new __1.BN(2),
|
|
25
|
+
oracle: new web3_js_1.PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
|
|
26
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
27
|
+
mint: new web3_js_1.PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
exports.MainnetBanks = [
|
|
31
|
+
{
|
|
32
|
+
symbol: 'USDC',
|
|
33
|
+
bankIndex: new __1.BN(0),
|
|
34
|
+
oracle: web3_js_1.PublicKey.default,
|
|
35
|
+
oracleSource: __1.OracleSource.QUOTE_ASSET,
|
|
36
|
+
mint: new web3_js_1.PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
exports.Banks = {
|
|
40
|
+
devnet: exports.DevnetBanks,
|
|
41
|
+
'mainnet-beta': exports.MainnetBanks,
|
|
42
|
+
};
|
package/src/constants/banks.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BN, OracleSource } from '../';
|
|
2
2
|
import { DriftEnv } from '../';
|
|
3
3
|
import { PublicKey } from '@solana/web3.js';
|
|
4
|
-
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions';
|
|
5
4
|
|
|
6
5
|
export type BankConfig = {
|
|
7
6
|
symbol: string;
|
|
@@ -24,14 +23,14 @@ export const DevnetBanks: BankConfig[] = [
|
|
|
24
23
|
bankIndex: new BN(1),
|
|
25
24
|
oracle: new PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
26
25
|
oracleSource: OracleSource.PYTH,
|
|
27
|
-
mint:
|
|
26
|
+
mint: new PublicKey('So11111111111111111111111111111111111111112'),
|
|
28
27
|
},
|
|
29
28
|
{
|
|
30
29
|
symbol: 'BTC',
|
|
31
30
|
bankIndex: new BN(2),
|
|
32
31
|
oracle: new PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
|
|
33
32
|
oracleSource: OracleSource.PYTH,
|
|
34
|
-
mint: new PublicKey('
|
|
33
|
+
mint: new PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
|
|
35
34
|
},
|
|
36
35
|
];
|
|
37
36
|
|