├── react ├── .eslintrc ├── src │ ├── components │ │ ├── Tags │ │ │ ├── index.tsx │ │ │ └── Tag.tsx │ │ ├── Select │ │ │ └── index.tsx │ │ ├── Charts │ │ │ ├── index.ts │ │ │ └── ActiveDot.tsx │ │ ├── Utils │ │ │ └── index.tsx │ │ ├── Text │ │ │ └── index.ts │ │ ├── Loaders │ │ │ ├── index.ts │ │ │ ├── inlineLoading.css │ │ │ ├── InlineLoadingBar.tsx │ │ │ └── ProgressBarThreeColor.tsx │ │ ├── index.ts │ │ └── Tables │ │ │ ├── BodyRowWrapper.tsx │ │ │ ├── index.tsx │ │ │ ├── HeaderCell.tsx │ │ │ ├── SummaryRow.tsx │ │ │ ├── HeaderCellWrapper.tsx │ │ │ ├── BodyCell.tsx │ │ │ ├── HeaderRow.tsx │ │ │ ├── BodyRow.tsx │ │ │ ├── TableCellCardValue.tsx │ │ │ └── BodyCellWrapper.tsx │ ├── hooks │ │ ├── oraclePrice │ │ │ └── index.ts │ │ ├── priorityFees │ │ │ ├── index.ts │ │ │ ├── usePriorityFeesPollingRate.ts │ │ │ └── usePriorityFeeUserSettings.ts │ │ ├── useDisableScroll.tsx │ │ ├── useDriftClientIsReady.tsx │ │ ├── useCommonDriftActions.tsx │ │ ├── useIsMainnet.tsx │ │ ├── useWalletContext.tsx │ │ ├── useDevSwitchIsOn.tsx │ │ ├── index.ts │ │ ├── useLastAcknowledgedTerms.tsx │ │ ├── useCurrentRpc.tsx │ │ ├── useImmediateInterval.ts │ │ └── useHandleBadRpc.ts │ ├── utils │ │ ├── index.ts │ │ └── ui.ts │ ├── providers │ │ └── index.ts │ ├── constants │ │ ├── index.ts │ │ ├── charts.ts │ │ ├── wallets.ts │ │ └── priorityFees.ts │ ├── stores │ │ ├── priorityFee │ │ │ ├── index.ts │ │ │ └── usePriorityFeeStore.ts │ │ ├── index.ts │ │ └── useOraclePriceStore.tsx │ └── index.ts └── tsconfig.json ├── common-ts ├── .yarnrc.yml ├── .gitignore ├── src │ ├── drift │ │ ├── Drift │ │ │ ├── data │ │ │ │ └── index.ts │ │ │ ├── constants │ │ │ │ ├── index.ts │ │ │ │ ├── orderbook.ts │ │ │ │ └── errors.ts │ │ │ ├── index.ts │ │ │ ├── stores │ │ │ │ └── index.ts │ │ │ └── clients │ │ │ │ ├── index.ts │ │ │ │ └── CentralServerDrift │ │ │ │ ├── markets.ts │ │ │ │ └── types.ts │ │ ├── base │ │ │ ├── actions │ │ │ │ ├── user │ │ │ │ │ └── index.ts │ │ │ │ ├── spot │ │ │ │ │ └── index.ts │ │ │ │ ├── perp │ │ │ │ │ └── index.ts │ │ │ │ ├── builder │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── trade │ │ │ │ │ ├── index.ts │ │ │ │ │ └── openPerpOrder │ │ │ │ │ └── index.ts │ │ │ ├── constants │ │ │ │ ├── auction.ts │ │ │ │ ├── index.ts │ │ │ │ └── accountNames.ts │ │ │ ├── details │ │ │ │ ├── index.ts │ │ │ │ ├── market │ │ │ │ │ ├── index.ts │ │ │ │ │ └── openInterest.ts │ │ │ │ └── user │ │ │ │ │ ├── index.ts │ │ │ │ │ └── orders.ts │ │ │ └── types.ts │ │ ├── utils │ │ │ ├── index.ts │ │ │ └── funding.ts │ │ ├── .env.example │ │ ├── index.ts │ │ └── constants │ │ │ └── apiUrls.ts │ ├── utils │ │ ├── featureFlags.ts │ │ ├── CircularBuffers │ │ │ └── index.ts │ │ ├── priority-fees │ │ │ └── index.ts │ │ ├── orderbook │ │ │ └── constants.ts │ │ ├── assert.ts │ │ ├── candles │ │ │ └── types.ts │ │ ├── signedMsgs.ts │ │ ├── fetch.ts │ │ ├── geoblock │ │ │ └── index.ts │ │ ├── SlotBasedResultValidator.ts │ │ ├── pollingSequenceGuard.ts │ │ ├── Stopwatch.ts │ │ └── rxjs.ts │ ├── types │ │ ├── candles.ts │ │ ├── Superstake.ts │ │ ├── utility.ts │ │ ├── index.ts │ │ ├── trade.ts │ │ └── user.ts │ ├── clients │ │ └── index.ts │ ├── actions │ │ └── actionHelpers │ │ │ └── actionHelpers.ts │ ├── constants │ │ ├── pools.ts │ │ ├── trade.ts │ │ ├── markets.ts │ │ ├── index.ts │ │ ├── predictionMarket.ts │ │ ├── dev.ts │ │ ├── misc.ts │ │ └── geoblockList.ts │ ├── common-ui-utils │ │ └── index.ts │ ├── chartConstants.ts │ ├── scripts │ │ └── update-drift-error-codes.js │ └── Config.ts ├── .madgerc ├── bun.lockb ├── esbuild-shims.js ├── tsconfig.json ├── tests │ └── utils │ │ ├── txAssertions.ts │ │ └── stringUtils.test.ts └── build-node.js ├── .prettierignore ├── bun.lockb ├── icons ├── bun.lockb ├── thumbnail.png ├── src │ ├── index.ts │ ├── types.ts │ ├── icons │ │ ├── IconWrapper.tsx │ │ └── components │ │ │ ├── Status.tsx │ │ │ ├── Loading15.tsx │ │ │ ├── Loading95.tsx │ │ │ ├── Add.tsx │ │ │ ├── ChevronUp.tsx │ │ │ ├── ChevronDown.tsx │ │ │ ├── Subtract.tsx │ │ │ ├── ChevronLeft.tsx │ │ │ ├── Loading.tsx │ │ │ ├── Phoenix.tsx │ │ │ ├── ArrowLeft.tsx │ │ │ ├── ArrowRight.tsx │ │ │ ├── ChevronRight.tsx │ │ │ ├── Up.tsx │ │ │ ├── Close.tsx │ │ │ ├── Down.tsx │ │ │ ├── WarningFilled.tsx │ │ │ ├── CheckEmpty.tsx │ │ │ ├── Warning.tsx │ │ │ ├── CaretUp.tsx │ │ │ ├── List.tsx │ │ │ ├── CaretDown.tsx │ │ │ ├── Checkmark.tsx │ │ │ ├── Fastlane.tsx │ │ │ ├── SuccessFilled.tsx │ │ │ ├── Resize.tsx │ │ │ ├── OrderbookVertical.tsx │ │ │ ├── Twitter.tsx │ │ │ ├── RecentTrades.tsx │ │ │ ├── HamburgerNew.tsx │ │ │ ├── Bolt.tsx │ │ │ ├── Hamburger.tsx │ │ │ ├── Mouse.tsx │ │ │ ├── Signal.tsx │ │ │ ├── ErrorFilled.tsx │ │ │ ├── Futarchy.tsx │ │ │ ├── Menu.tsx │ │ │ ├── Metadao.tsx │ │ │ ├── ResizeFull.tsx │ │ │ ├── Swap.tsx │ │ │ ├── TradingUp.tsx │ │ │ ├── Hide.tsx │ │ │ ├── Accordion.tsx │ │ │ ├── Switch.tsx │ │ │ ├── Star.tsx │ │ │ ├── GridMenu.tsx │ │ │ ├── Megaphone.tsx │ │ │ ├── Layout.tsx │ │ │ ├── YES.tsx │ │ │ ├── Control.tsx │ │ │ ├── Filter.tsx │ │ │ ├── Medium.tsx │ │ │ ├── Deposit.tsx │ │ │ ├── LiqHalf.tsx │ │ │ ├── Info.tsx │ │ │ ├── Trade.tsx │ │ │ ├── Transfer.tsx │ │ │ ├── Withdraw.tsx │ │ │ ├── ChevronsUp.tsx │ │ │ ├── ChevronsDown.tsx │ │ │ ├── ChevronsRight.tsx │ │ │ ├── ChevronsLeft.tsx │ │ │ ├── Share.tsx │ │ │ ├── Collapse.tsx │ │ │ ├── Stake.tsx │ │ │ ├── Expand.tsx │ │ │ ├── Edit.tsx │ │ │ ├── No.tsx │ │ │ ├── SettingsTrade.tsx │ │ │ ├── Wallet.tsx │ │ │ ├── Apple.tsx │ │ │ ├── Replies.tsx │ │ │ ├── Play.tsx │ │ │ ├── MegaphoneNew.tsx │ │ │ ├── OrderBook.tsx │ │ │ ├── Stats.tsx │ │ │ ├── Telegram.tsx │ │ │ ├── Vote.tsx │ │ │ ├── Email.tsx │ │ │ ├── Search.tsx │ │ │ ├── Lightning.tsx │ │ │ ├── Diamond.tsx │ │ │ ├── SortUp.tsx │ │ │ ├── SortDown.tsx │ │ │ ├── CheckFilled.tsx │ │ │ ├── PieChart.tsx │ │ │ ├── GraphSquare.tsx │ │ │ ├── Calculator.tsx │ │ │ ├── Calendar.tsx │ │ │ ├── GraphCircle.tsx │ │ │ ├── Disclaimers.tsx │ │ │ ├── ExitPosition.tsx │ │ │ ├── Google.tsx │ │ │ ├── Account.tsx │ │ │ ├── CreditCard.tsx │ │ │ ├── Lock.tsx │ │ │ ├── Help.tsx │ │ │ ├── SettingsOther.tsx │ │ │ ├── Autoconfirm.tsx │ │ │ ├── Balance.tsx │ │ │ ├── Terms.tsx │ │ │ ├── Discourse.tsx │ │ │ ├── Others.tsx │ │ │ ├── Claimstart.tsx │ │ │ ├── NewMarket.tsx │ │ │ ├── Notification.tsx │ │ │ ├── Positions.tsx │ │ │ ├── Form.tsx │ │ │ ├── LP.tsx │ │ │ ├── Copy.tsx │ │ │ ├── Realms.tsx │ │ │ ├── Simple.tsx │ │ │ ├── Data.tsx │ │ │ ├── MouseClick.tsx │ │ │ ├── Bank.tsx │ │ │ ├── History.tsx │ │ │ ├── Shield.tsx │ │ │ ├── Discord.tsx │ │ │ ├── Exponent.tsx │ │ │ ├── Fuel.tsx │ │ │ └── NotificationNew.tsx │ └── templates │ │ └── componentTemplate.js ├── .env.example ├── svgr.config.js ├── README.md └── rollup.config.js ├── .gitmodules ├── .husky └── pre-commit ├── .gitignore ├── .prettierrc.js ├── README.md ├── package.json └── .github └── workflows └── common_unit_tests.yml /react/.eslintrc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /common-ts/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /common-ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | dist 4 | *.tgz -------------------------------------------------------------------------------- /react/src/components/Tags/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Tag'; 2 | -------------------------------------------------------------------------------- /react/src/components/Select/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './Default'; 2 | -------------------------------------------------------------------------------- /react/src/components/Charts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ActiveDot'; 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** 2 | **/lib/** 3 | **/dist/** 4 | protocol -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drift-labs/drift-common/HEAD/bun.lockb -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/data/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PollingDlob'; 2 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/user/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create'; 2 | -------------------------------------------------------------------------------- /react/src/components/Utils/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './CentreFillScroller'; 2 | -------------------------------------------------------------------------------- /react/src/hooks/oraclePrice/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useSyncOraclePriceStore'; 2 | -------------------------------------------------------------------------------- /react/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './graph'; 2 | export * from './ui'; 3 | -------------------------------------------------------------------------------- /icons/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drift-labs/drift-common/HEAD/icons/bun.lockb -------------------------------------------------------------------------------- /common-ts/.madgerc: -------------------------------------------------------------------------------- 1 | { 2 | "excludeRegExp": [ 3 | "\\.\\./\\.\\./protocol/.*" 4 | ] 5 | } -------------------------------------------------------------------------------- /common-ts/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drift-labs/drift-common/HEAD/common-ts/bun.lockb -------------------------------------------------------------------------------- /icons/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drift-labs/drift-common/HEAD/icons/thumbnail.png -------------------------------------------------------------------------------- /react/src/components/Text/index.ts: -------------------------------------------------------------------------------- 1 | export * from './GradientText'; 2 | export * from './Typo'; 3 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/constants/auction.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_LIMIT_AUCTION_DURATION = 60; 2 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/details/index.ts: -------------------------------------------------------------------------------- 1 | export * from './user'; 2 | export * from './market'; 3 | -------------------------------------------------------------------------------- /common-ts/src/utils/featureFlags.ts: -------------------------------------------------------------------------------- 1 | export const FEATURE_FLAGS = { 2 | UI_ORACLE_CANDLES: true, 3 | }; 4 | -------------------------------------------------------------------------------- /react/src/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DriftProvider'; 2 | export * from './DriftWalletProvider'; 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "protocol"] 2 | path = protocol 3 | url = https://github.com/drift-labs/protocol-v2 4 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/spot/index.ts: -------------------------------------------------------------------------------- 1 | export * from './deposit'; 2 | export * from './withdraw'; 3 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './accountNames'; 2 | export * from './auction'; 3 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/perp/index.ts: -------------------------------------------------------------------------------- 1 | export * from './settleFunding'; 2 | export * from './settlePnl'; 3 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/details/market/index.ts: -------------------------------------------------------------------------------- 1 | export * from './funding'; 2 | export * from './openInterest'; 3 | -------------------------------------------------------------------------------- /react/src/components/Loaders/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ProgressBarThreeColor'; 2 | export * from './InlineLoadingBar'; 3 | -------------------------------------------------------------------------------- /common-ts/src/utils/CircularBuffers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CircularBuffer'; 2 | export * from './UniqueCircularBuffer'; 3 | -------------------------------------------------------------------------------- /icons/src/index.ts: -------------------------------------------------------------------------------- 1 | // All icon components 2 | export * from './icons/index'; 3 | 4 | // Types 5 | export * from './types'; 6 | -------------------------------------------------------------------------------- /react/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './priorityFees'; 2 | export * from './wallets'; 3 | export * from './charts'; 4 | -------------------------------------------------------------------------------- /react/src/stores/priorityFee/index.ts: -------------------------------------------------------------------------------- 1 | export * from './usePriorityFeeStore'; 2 | export * from './useSyncPriorityFeeStore'; 3 | -------------------------------------------------------------------------------- /common-ts/src/types/candles.ts: -------------------------------------------------------------------------------- 1 | export enum CandleType { 2 | FILL_PRICE = 'FILL_PRICE', 3 | ORACLE_PRICE = 'ORACLE_PRICE', 4 | } 5 | -------------------------------------------------------------------------------- /common-ts/src/utils/priority-fees/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PriorityFeeCalculator'; 2 | export * from './PriorityFeeStrategies'; 3 | -------------------------------------------------------------------------------- /icons/.env.example: -------------------------------------------------------------------------------- 1 | FIGMA_API_TOKEN="YOUR FIGMA API TOKEN" 2 | FIGMA_FILE_ID=7ontXyBmE6iK8xhRMLfkCV 3 | FIGMA_CANVAS='24x24 Product icon' -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './blockchain'; 2 | export * from './errors'; 3 | export * from './orderbook'; 4 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/types.ts: -------------------------------------------------------------------------------- 1 | import { TxParams } from '@drift-labs/sdk'; 2 | 3 | export type WithTxnParams = T & { txParams?: TxParams }; 4 | -------------------------------------------------------------------------------- /common-ts/src/drift/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './auctionParamsResponseMapper'; 2 | export * from './orderParams'; 3 | export * from './funding'; 4 | -------------------------------------------------------------------------------- /common-ts/src/utils/orderbook/constants.ts: -------------------------------------------------------------------------------- 1 | import { EmptyRow } from './types'; 2 | 3 | export const EMPTY_ORDERBOOK_ROW = 'EMPTY_ROW' as EmptyRow; 4 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/index.ts: -------------------------------------------------------------------------------- 1 | export * from './clients'; 2 | export * from './constants'; 3 | export * from './data'; 4 | export * from './stores'; 5 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/stores/index.ts: -------------------------------------------------------------------------------- 1 | export * from './OraclePriceCache'; 2 | export * from './MarkPriceCache'; 3 | export * from './UserAccountCache'; 4 | -------------------------------------------------------------------------------- /react/src/components/Loaders/inlineLoading.css: -------------------------------------------------------------------------------- 1 | @keyframes progress-loading { 2 | 0% { 3 | width: 0%; 4 | } 5 | 100% { 6 | width: 100%; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | bun lint 5 | bun prettify 6 | bun typecheck 7 | cd common-ts && bun run test 8 | bun run build -------------------------------------------------------------------------------- /common-ts/src/drift/base/details/user/index.ts: -------------------------------------------------------------------------------- 1 | export * from './positions'; 2 | export * from './balances'; 3 | export * from './orders'; 4 | export * from './marginInfo'; 5 | -------------------------------------------------------------------------------- /common-ts/src/drift/.env.example: -------------------------------------------------------------------------------- 1 | ANCHOR_WALLET=/path/to/your/wallet.json 2 | # devnet or mainnet-beta 3 | DRIFT_ENV=devnet 4 | ENDPOINT=https://api.devnet.solana.com 5 | 6 | 7 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/clients/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AuthorityDrift'; 2 | export * from './AuthorityDrift/DriftOperations/types'; 3 | export * from './CentralServerDrift'; 4 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/builder/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createRevenueShareAccount'; 2 | export * from './createRevenueShareEscrow'; 3 | export * from './manageBuilder'; 4 | -------------------------------------------------------------------------------- /common-ts/src/clients/index.ts: -------------------------------------------------------------------------------- 1 | export * from './redisClient'; 2 | // do not add other clients here, since this is meant to be imported by nodejs servers (has browser incompatible code) 3 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './user'; 2 | export * from './trade'; 3 | export * from './perp'; 4 | export * from './spot'; 5 | export * from './builder'; 6 | -------------------------------------------------------------------------------- /react/src/hooks/priorityFees/index.ts: -------------------------------------------------------------------------------- 1 | export * from './usePriorityFeesPollingRate'; 2 | export * from './usePriorityFeeUserSettings'; 3 | export * from './usePriorityFeeSubscriber'; 4 | -------------------------------------------------------------------------------- /react/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useCommonDriftStore'; 2 | export * from './useOraclePriceStore'; 3 | export * from './useScreenSizeStore'; 4 | export * from './priorityFee'; 5 | -------------------------------------------------------------------------------- /common-ts/src/drift/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base/actions'; 2 | export * from './base/details'; 3 | export * from './base/constants'; 4 | export * from './Drift'; 5 | export * from './utils'; 6 | -------------------------------------------------------------------------------- /common-ts/src/utils/assert.ts: -------------------------------------------------------------------------------- 1 | export function assert(condition: boolean, error?: string): void { 2 | if (!condition) { 3 | throw new Error(error || 'Unspecified AssertionError'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.env.mainnet 3 | *.env.devnet 4 | .DS_Store 5 | node_modules 6 | **/.env.local 7 | scratchpad.ts 8 | .env 9 | **/*.tsbuildinfo 10 | lib 11 | **/*.log 12 | icons/dist 13 | .yarn -------------------------------------------------------------------------------- /common-ts/src/actions/actionHelpers/actionHelpers.ts: -------------------------------------------------------------------------------- 1 | import { ACCOUNT_DELETION_HELPERS } from './accountDeletionHelpers'; 2 | 3 | export const ACTION_HELPERS = { 4 | ACCOUNT_DELETION_HELPERS, 5 | }; 6 | -------------------------------------------------------------------------------- /common-ts/src/types/Superstake.ts: -------------------------------------------------------------------------------- 1 | export type LstMetrics = { 2 | loaded: boolean; 3 | priceInSol: number; 4 | lstPriceApy30d: number; 5 | emissionsApy?: number; 6 | driftEmissions?: number; 7 | }; 8 | -------------------------------------------------------------------------------- /react/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Charts'; 2 | export * from './Loaders'; 3 | export * from './Select'; 4 | export * from './Text'; 5 | export * from './Tables'; 6 | export * from './Tags'; 7 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'es5', 4 | singleQuote: true, 5 | printWidth: 80, 6 | tabWidth: 2, 7 | useTabs: true, 8 | bracketSameLine: false, 9 | }; 10 | -------------------------------------------------------------------------------- /common-ts/src/constants/pools.ts: -------------------------------------------------------------------------------- 1 | export const MAIN_POOL_ID = 0; 2 | export const JLP_POOL_ID = 1; 3 | export const LST_POOL_ID = 2; 4 | export const EXPONENT_POOL_ID = 3; 5 | export const SACRED_POOL_ID = 4; 6 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/trade/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openPerpOrder'; 2 | export * from './cancelOrder'; 3 | export * from './editOrder'; 4 | export * from './swap'; 5 | export * from './margin'; 6 | -------------------------------------------------------------------------------- /common-ts/src/common-ui-utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './commonUiUtils'; 2 | export * from './market'; 3 | export * from './order'; 4 | export * from './trading'; 5 | export * from './user'; 6 | export * from './settings/settings'; 7 | -------------------------------------------------------------------------------- /common-ts/src/constants/trade.ts: -------------------------------------------------------------------------------- 1 | import { AuctionParams } from 'src/types'; 2 | 3 | export const EMPTY_AUCTION_PARAMS: AuctionParams = { 4 | auctionStartPrice: null, 5 | auctionEndPrice: null, 6 | auctionDuration: null, 7 | }; 8 | -------------------------------------------------------------------------------- /common-ts/src/chartConstants.ts: -------------------------------------------------------------------------------- 1 | import { CandleResolution } from '@drift-labs/sdk'; 2 | 3 | export const CandleResolutions: CandleResolution[] = [ 4 | '1', 5 | '5', 6 | '15', 7 | '60', 8 | '240', 9 | 'D', 10 | 'W', 11 | 'M', 12 | ]; 13 | -------------------------------------------------------------------------------- /common-ts/src/utils/candles/types.ts: -------------------------------------------------------------------------------- 1 | // This Type is copied from tradingview charting_library 2 | export type Bar = { 3 | time: number; 4 | open: number; 5 | high: number; 6 | low: number; 7 | close: number; 8 | volume?: number; 9 | }; 10 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/actions/trade/openPerpOrder/index.ts: -------------------------------------------------------------------------------- 1 | export * from './openPerpMarketOrder'; 2 | export * from './openPerpNonMarketOrder'; 3 | export * from './openSwiftOrder'; 4 | export * from './dlobServer'; 5 | export * from './types'; 6 | export * from './positionMaxLeverage'; 7 | -------------------------------------------------------------------------------- /react/src/utils/ui.ts: -------------------------------------------------------------------------------- 1 | export const getStyleValue = (value: string) => { 2 | if (!isWindowDefined()) throw 'trying to getStyleValue when unmounted'; 3 | 4 | return window.getComputedStyle(document.body).getPropertyValue(value); 5 | }; 6 | 7 | const isWindowDefined = () => typeof window !== 'undefined'; 8 | -------------------------------------------------------------------------------- /common-ts/src/constants/markets.ts: -------------------------------------------------------------------------------- 1 | export const USDC_SPOT_MARKET_INDEX = 0; 2 | export const SOL_SPOT_MARKET_INDEX = 1; 3 | export const WBTC_SPOT_MARKET_INDEX = 3; 4 | export const WETH_SPOT_MARKET_INDEX = 4; 5 | export const CBBTC_SPOT_MARKET_INDEX = 27; 6 | 7 | export const DEFAULT_MAX_MARKET_LEVERAGE = 10; 8 | -------------------------------------------------------------------------------- /common-ts/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dev'; 2 | export * from './orders'; 3 | export * from './geoblockList'; 4 | export * from './misc'; 5 | export * from './superstake'; 6 | export * from './pools'; 7 | export * from './trade'; 8 | export * from './markets'; 9 | export * from './predictionMarket'; 10 | -------------------------------------------------------------------------------- /react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './constants'; 3 | export * from './hooks'; 4 | export * from './providers'; 5 | export * from './stores'; 6 | export * from './utils'; 7 | 8 | export * from '@solana/wallet-adapter-base'; 9 | export { Wallet } from '@solana/wallet-adapter-react'; 10 | -------------------------------------------------------------------------------- /common-ts/esbuild-shims.js: -------------------------------------------------------------------------------- 1 | import { Buffer } from 'buffer'; 2 | import process from 'process'; 3 | 4 | if (typeof globalThis.Buffer === 'undefined') { 5 | globalThis.Buffer = Buffer; 6 | } 7 | 8 | if (typeof globalThis.process === 'undefined') { 9 | globalThis.process = process; 10 | } 11 | 12 | export { Buffer, process }; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # drift-common 2 | 3 | ## quick start 4 | 5 | ```bash 6 | 7 | git submodule init 8 | git submodule update 9 | 10 | yarn 11 | 12 | cd protocol 13 | yarn 14 | yarn build 15 | cd sdk 16 | yarn 17 | yarn build 18 | npm link 19 | cd ../.. 20 | 21 | # do this for the packages that requires sdk 22 | npm link @drift-labs/sdk 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /common-ts/src/utils/signedMsgs.ts: -------------------------------------------------------------------------------- 1 | import { SLOT_TIME_ESTIMATE_MS } from '@drift-labs/sdk'; 2 | 3 | export function getSwiftConfirmationTimeoutMs( 4 | slotsTillAuctionEnd: number, 5 | multiplier?: number 6 | ): number { 7 | const baseMs = ((slotsTillAuctionEnd ?? 0) + 15) * SLOT_TIME_ESTIMATE_MS; 8 | return baseMs * (multiplier ?? 1); 9 | } 10 | -------------------------------------------------------------------------------- /common-ts/src/utils/fetch.ts: -------------------------------------------------------------------------------- 1 | export const encodeQueryParams = ( 2 | params: Record 3 | ): string => { 4 | return Object.entries(params) 5 | .filter(([_, value]) => value !== undefined) 6 | .map( 7 | ([key, value]) => 8 | `${encodeURIComponent(key)}=${encodeURIComponent(value!)}` 9 | ) 10 | .join('&'); 11 | }; 12 | -------------------------------------------------------------------------------- /react/src/hooks/useDisableScroll.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | 3 | /** 4 | * Disables overflow on the document body while an element is being rendered 5 | */ 6 | export const useDisableScroll = () => { 7 | useEffect(() => { 8 | document.body.style.overflow = 'hidden'; 9 | 10 | return () => { 11 | document.body.style.overflow = 'auto'; 12 | }; 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /react/src/hooks/useDriftClientIsReady.tsx: -------------------------------------------------------------------------------- 1 | import { useCommonDriftStore } from '../stores'; 2 | 3 | /** 4 | * Checks if the drift client is subscribed and ready to use. 5 | */ 6 | export const useDriftClientIsReady = () => { 7 | const driftClientIsReady = useCommonDriftStore((s) => { 8 | return s.checkIsDriftClientReady(); 9 | }); 10 | 11 | return driftClientIsReady; 12 | }; 13 | -------------------------------------------------------------------------------- /common-ts/src/types/utility.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a utility type that is used to create opaque types. 3 | * 4 | * E.g. 5 | * ```ts 6 | * type MyOpaqueType = Opaque<"MyOpaqueType", string>; 7 | * ``` 8 | * 9 | * This will create a type that is a string, but will not allow you to assign any other type to it. 10 | * 11 | * ```ts 12 | */ 13 | export type Opaque = T & { __TYPE__: K }; 14 | -------------------------------------------------------------------------------- /react/src/components/Tables/BodyRowWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren, type JSX } from 'react'; 2 | 3 | export const BodyRowWrapper = ({ 4 | children, 5 | noBg, 6 | }: PropsWithChildren<{ noBg?: boolean }>): JSX.Element => { 7 | return ( 8 |
11 | {children} 12 |
13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /react/src/hooks/useCommonDriftActions.tsx: -------------------------------------------------------------------------------- 1 | import createDriftActions from '../actions/driftActions'; 2 | import { useCommonDriftStore } from '../stores'; 3 | 4 | /** 5 | * Returns the common Drift actions object. 6 | */ 7 | export function useCommonDriftActions(): ReturnType { 8 | const actions = useCommonDriftStore((s) => s.actions); 9 | 10 | return actions; 11 | } 12 | -------------------------------------------------------------------------------- /common-ts/src/constants/predictionMarket.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MAX_PREDICTION_PRICE, 3 | BigNum, 4 | PRICE_PRECISION, 5 | PRICE_PRECISION_EXP, 6 | } from '@drift-labs/sdk'; 7 | 8 | export const MAX_PREDICTION_PRICE_NUM = 9 | MAX_PREDICTION_PRICE.div(PRICE_PRECISION).toNumber(); 10 | 11 | export const MAX_PREDICTION_PRICE_BIG_NUM = BigNum.from( 12 | MAX_PREDICTION_PRICE, 13 | PRICE_PRECISION_EXP 14 | ); 15 | -------------------------------------------------------------------------------- /react/src/hooks/useIsMainnet.tsx: -------------------------------------------------------------------------------- 1 | import { useCommonDriftStore } from '../stores'; 2 | 3 | /** 4 | * Checks if the app is running on mainnet based on its environment variables. 5 | */ 6 | const useIsMainnet = () => { 7 | const env = useCommonDriftStore((s) => s.env); 8 | 9 | const isMainnet = env.driftEnv === 'mainnet-beta'; 10 | 11 | return isMainnet; 12 | }; 13 | 14 | export default useIsMainnet; 15 | -------------------------------------------------------------------------------- /common-ts/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MarketId'; 2 | export * from './UIMarket'; 3 | export * from './Superstake'; 4 | export * from './remote-configs'; 5 | export * from './UIEnv'; 6 | export * from './candles'; 7 | export * from './dataServer'; 8 | export * from './historyServer'; 9 | export * from './trade'; 10 | export * from './user'; 11 | export * from './leaderboard'; 12 | export * from './utility'; 13 | -------------------------------------------------------------------------------- /react/src/constants/charts.ts: -------------------------------------------------------------------------------- 1 | import { BigNum } from '@drift-labs/sdk'; 2 | 3 | export type HistoricalPrice = { 4 | ms: number; 5 | price: number; 6 | swapInfo?: { 7 | inMarketSymbol: string; 8 | outMarketSymbol: string; 9 | amountIn: BigNum; 10 | amountOut: BigNum; 11 | }; 12 | }; 13 | 14 | export enum HistoricalTokenPriceDuration { 15 | ONE_DAY = '1', 16 | ONE_WEEK = '7', 17 | ONE_MONTH = '30', 18 | } 19 | -------------------------------------------------------------------------------- /react/src/components/Tables/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './BodyCell'; 2 | export * from './BodyCellWrapper'; 3 | export * from './BodyRow'; 4 | export * from './BodyRowWrapper'; 5 | export * from './HeaderCellWrapper'; 6 | export * from './HeaderCell'; 7 | export * from './HeaderRow'; 8 | export * from './SummaryRow'; 9 | export * from './TableCellCardValue'; 10 | export * from './TableRowWrapper'; 11 | export * from './TableSkeleton'; 12 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/details/user/orders.ts: -------------------------------------------------------------------------------- 1 | import { Order } from '@drift-labs/sdk'; 2 | import { Serializer, UISerializableOrder } from '../../../../serializableTypes'; 3 | 4 | export const getOrderDetails = (order: Order): UISerializableOrder => { 5 | const serializedOrder = Serializer.Serialize.Order(order); 6 | const deserializedOrder = Serializer.Deserialize.UIOrder(serializedOrder); 7 | 8 | return deserializedOrder; 9 | }; 10 | -------------------------------------------------------------------------------- /common-ts/src/drift/utils/funding.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BigNum, 3 | BN, 4 | PRICE_PRECISION, 5 | PRICE_PRECISION_EXP, 6 | FUNDING_RATE_BUFFER_PRECISION, 7 | } from '@drift-labs/sdk'; 8 | 9 | export const getFundingRate = (rate: BN, oracleTwap: BN): number => { 10 | return ( 11 | BigNum.from( 12 | rate.mul(PRICE_PRECISION.mul(new BN(100))).div(oracleTwap), 13 | PRICE_PRECISION_EXP 14 | ).toNum() / FUNDING_RATE_BUFFER_PRECISION.toNumber() 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /react/src/components/Tables/HeaderCell.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren } from 'react'; 2 | import { HeaderCellWrapper } from './HeaderCellWrapper'; 3 | 4 | export const HeaderCell = ({ 5 | children, 6 | className, 7 | alignRight, 8 | }: PropsWithChildren<{ 9 | className?: string; 10 | alignRight?: boolean; 11 | }>) => { 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/constants/orderbook.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DlobServerChannel, 3 | OrderbookGrouping, 4 | } from '../../../utils/dlob-server/DlobServerWebsocketUtils'; 5 | 6 | export const DEFAULT_ORDERBOOK_GROUPING: OrderbookGrouping = 100; 7 | export const DEFAULT_ORDERBOOK_CHANNEL: DlobServerChannel = 8 | 'orderbook_indicative'; 9 | 10 | export const DEFAULT_ORDERBOOK_SUBSCRIPTION_CONFIG = { 11 | channel: DEFAULT_ORDERBOOK_CHANNEL, 12 | grouping: DEFAULT_ORDERBOOK_GROUPING, 13 | }; 14 | -------------------------------------------------------------------------------- /react/src/hooks/useWalletContext.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { useCommonDriftStore } from '../stores'; 3 | import { DriftWalletContext } from '../providers'; 4 | 5 | export const useWalletContext = () => { 6 | const walletContextState = useCommonDriftStore( 7 | (s) => s.currentlyConnectedWalletContext 8 | ); 9 | 10 | return walletContextState; 11 | }; 12 | 13 | export const useWallet = () => { 14 | const driftWalletContext = useContext(DriftWalletContext); 15 | 16 | return driftWalletContext; 17 | }; 18 | -------------------------------------------------------------------------------- /common-ts/src/utils/geoblock/index.ts: -------------------------------------------------------------------------------- 1 | import { GEOBLOCK_LIST } from '../../constants'; 2 | 3 | /** 4 | * Returns true if the user is geo-blocked. 5 | */ 6 | export const checkGeoBlock = async () => { 7 | const result = await fetch(`https://geolocation.drift-labs.workers.dev/`, { 8 | cache: 'no-cache', 9 | }); 10 | 11 | if (!result.ok) { 12 | return; 13 | } 14 | 15 | const country_code = await result.text(); 16 | 17 | const countryIsBlocked = !!GEOBLOCK_LIST.find( 18 | (country) => country.code === country_code 19 | ); 20 | 21 | return countryIsBlocked; 22 | }; 23 | -------------------------------------------------------------------------------- /common-ts/src/constants/dev.ts: -------------------------------------------------------------------------------- 1 | export const PERFORMANCE_TESTING_LABELS = { 2 | totalRenders: 'Total Renders', 3 | totalActualDuration: 'Total Render Duration', 4 | min: 'Min Duration', 5 | median: 'Median Duration', 6 | max: 'Max Duration', 7 | p90: '90th Percentile Duration', 8 | mean: 'Mean Duration', 9 | totalDurationMs: 'Total Profiling Duration', 10 | totalDurationSec: 'Total Profiling Duration', 11 | avgRendersPerSec: 'Average Renders Per Second', 12 | avgDurationPerSec: 'Average Render Duration Per Second', 13 | avgFPS: 'Avg FPS', 14 | avgEventLoopLag: 'Avg Event Loop Lag', 15 | }; 16 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/constants/accountNames.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_USER_NAME } from '@drift-labs/sdk'; 2 | import { 3 | JLP_POOL_ID, 4 | MAIN_POOL_ID, 5 | SACRED_POOL_ID, 6 | LST_POOL_ID, 7 | EXPONENT_POOL_ID, 8 | } from '../../../constants/pools'; 9 | 10 | export const DEFAULT_ACCOUNT_NAMES_BY_POOL_ID: Record = { 11 | [MAIN_POOL_ID]: DEFAULT_USER_NAME, 12 | [JLP_POOL_ID]: 'JLP Market - Isolated Pool', 13 | [EXPONENT_POOL_ID]: 'Exponent Market - Isolated Pool', 14 | [SACRED_POOL_ID]: 'ACRED Market - Isolated Pool', 15 | [LST_POOL_ID]: 'LST Market - Isolated Pool', 16 | }; 17 | -------------------------------------------------------------------------------- /icons/src/types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export type IconProps = { 4 | /** Set icon fill color from design system */ 5 | color?: string; 6 | /** Set width and height of icon in pixels */ 7 | size?: number; 8 | /** Whether to scale icon according to font-size. Sets width and height to 1em. */ 9 | autoSize?: boolean; 10 | /** Props to pass directly to svg element */ 11 | svgProps?: React.SVGProps; 12 | } & Omit, 'color' | 'size'>; 13 | 14 | export type GradientIconProps = Omit & { 15 | gradientColors: string[]; 16 | }; 17 | -------------------------------------------------------------------------------- /react/src/components/Loaders/InlineLoadingBar.tsx: -------------------------------------------------------------------------------- 1 | import './inlineLoading.css'; 2 | 3 | export const InlineLoadingBar = () => { 4 | return ( 5 |
6 |
16 |
17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /icons/svgr.config.js: -------------------------------------------------------------------------------- 1 | const componentTemplate = require('./src/templates/componentTemplate'); 2 | 3 | module.exports = { 4 | typescript: true, 5 | icon: true, 6 | svgProps: { 7 | // width: '', 8 | // height: '', 9 | }, 10 | replaceAttrValues: { 11 | '#6683A7': '{allProps.color ? allProps.color : "currentColor"}', 12 | }, 13 | plugins: [ 14 | // Clean SVG files using SVGO 15 | '@svgr/plugin-svgo', 16 | // Generate JSX 17 | '@svgr/plugin-jsx', 18 | // Format the result using Prettier 19 | '@svgr/plugin-prettier', 20 | ], 21 | dimensions: false, 22 | template: componentTemplate, 23 | }; 24 | -------------------------------------------------------------------------------- /react/src/components/Tables/SummaryRow.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren, type JSX } from 'react'; 2 | import { TableRowWrapper } from './TableRowWrapper'; 3 | import { twMerge } from 'tailwind-merge'; 4 | 5 | export const SummaryRow = ({ 6 | children, 7 | className, 8 | ...props 9 | }: PropsWithChildren<{ 10 | grid: string; 11 | className?: string; 12 | header?: boolean; 13 | }>): JSX.Element => { 14 | return ( 15 | 22 | {children} 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /react/src/components/Loaders/ProgressBarThreeColor.tsx: -------------------------------------------------------------------------------- 1 | type ProgressBarThreeColorProps = { 2 | firstProgress: number; 3 | secondProgress: number; 4 | }; 5 | 6 | export const ProgressBarThreeColor = ({ 7 | firstProgress, 8 | secondProgress, 9 | }: ProgressBarThreeColorProps) => { 10 | return ( 11 |
12 |
16 |
20 |
21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/clients/CentralServerDrift/markets.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DriftClient, 3 | PerpMarketAccount, 4 | SpotMarketAccount, 5 | } from '@drift-labs/sdk'; 6 | 7 | export class CentralServerDriftMarkets { 8 | constructor(private readonly driftClient: DriftClient) {} 9 | 10 | async getPerpMarketAccount( 11 | marketIndex: number 12 | ): Promise { 13 | return this.driftClient.getPerpMarketAccount(marketIndex); 14 | } 15 | 16 | async getSpotMarketAccount( 17 | marketIndex: number 18 | ): Promise { 19 | return this.driftClient.getSpotMarketAccount(marketIndex); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /react/src/components/Tables/HeaderCellWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | import { Typo } from '../Text/Typo'; 4 | 5 | export const HeaderCellWrapper = ({ 6 | children, 7 | className, 8 | alignRight, 9 | }: PropsWithChildren<{ 10 | className?: string; 11 | alignRight?: boolean; 12 | }>) => { 13 | return ( 14 |
21 | {children} 22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /icons/README.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | # ICONS GENERATOR 10 | 11 | ## Steps to run 12 | 13 | 1. Configure .env 14 | 2. `yarn` 15 | 16 | 3. `yarn build-icons-script` 17 | 18 | 4. `yarn icons` 19 | 20 | 5. `yarn build` 21 | -------------------------------------------------------------------------------- /icons/src/icons/IconWrapper.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../types'; 3 | 4 | export const IconWrapper: React.FC<{ icon: React.ReactNode } & IconProps> = ({ 5 | icon, 6 | color: colorProp, 7 | size: sizeProp, 8 | autoSize, 9 | ...restProps 10 | }) => { 11 | const color = colorProp ? colorProp : 'currentColor'; 12 | const size = sizeProp ? `${sizeProp}px` : autoSize ? '1em' : '16px'; 13 | return ( 14 | 24 | {icon} 25 | 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | "jsx": "react-jsx", 6 | "module": "ES2022", 7 | "target": "ES2022", 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "outDir": "lib", 11 | "esModuleInterop": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "strict": true, 14 | "skipLibCheck": true, 15 | "declaration": true, 16 | "paths": { 17 | "@drift-labs/sdk": ["../protocol/sdk"], 18 | "@drift/common": ["../common-ts"], 19 | "@drift-labs/icons": ["../icons/dist"] 20 | } 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "tests"] 24 | } 25 | -------------------------------------------------------------------------------- /common-ts/src/drift/base/details/market/openInterest.ts: -------------------------------------------------------------------------------- 1 | import { BASE_PRECISION_EXP, BigNum, DriftClient } from '@drift-labs/sdk'; 2 | 3 | export const getMarketOpenInterest = ( 4 | driftClient: DriftClient, 5 | marketIndex: number 6 | ): { longOpenInterest: BigNum; shortOpenInterest: BigNum } => { 7 | const perpMarketAccount = driftClient.getPerpMarketAccount(marketIndex); 8 | const longOpenInterest = BigNum.from( 9 | perpMarketAccount.amm.baseAssetAmountLong, 10 | BASE_PRECISION_EXP 11 | ); 12 | const shortOpenInterest = BigNum.from( 13 | perpMarketAccount.amm.baseAssetAmountShort, 14 | BASE_PRECISION_EXP 15 | ); 16 | return { longOpenInterest, shortOpenInterest }; 17 | }; 18 | -------------------------------------------------------------------------------- /icons/src/icons/components/Status.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Status = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Status; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Loading15.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Loading15 = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Loading15; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Loading95.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Loading95 = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Loading95; 27 | -------------------------------------------------------------------------------- /common-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "declaration": true, 5 | "module": "commonjs", 6 | "esModuleInterop": true, 7 | "preserveConstEnums": true, 8 | "sourceMap": true, 9 | "inlineSources": true, // <— embed source in the .map (sourcesContent) 10 | "sourceRoot": "", // <— keep sources relative (don’t point to http) 11 | "resolveJsonModule": true, 12 | "skipLibCheck": true, 13 | "experimentalDecorators": true, 14 | "emitDecoratorMetadata": true, 15 | "baseUrl": ".", 16 | "moduleResolution": "node", 17 | "paths": { 18 | "@drift-labs/sdk": ["../protocol/sdk"] 19 | }, 20 | "outDir": "./lib" 21 | }, 22 | "include": ["src/**/*"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "@drift-labs", 3 | "license": "MIT", 4 | "devDependencies": { 5 | "@typescript-eslint/eslint-plugin": "6.9.1", 6 | "@typescript-eslint/parser": "6.9.1", 7 | "husky": "8.0.3", 8 | "typescript": "5.1.6" 9 | }, 10 | "scripts": { 11 | "lint": "eslint './**/*.{ts,tsx}'", 12 | "lint:fix": "yarn lint --fix", 13 | "prepare": "husky install", 14 | "prettify": "prettier --check './**/*.{ts,tsx}'", 15 | "prettify:write": "prettier --write './**/*.{ts,tsx}'", 16 | "typecheck": "tsc --project common-ts --noEmit" 17 | }, 18 | "dependencies": { 19 | "@types/big.js": "6.2.2", 20 | "eslint": "8.44.0", 21 | "posthog-js": "1.72.1", 22 | "prettier": "2.8.8" 23 | }, 24 | "version": "0.0.1" 25 | } 26 | -------------------------------------------------------------------------------- /react/src/hooks/useDevSwitchIsOn.tsx: -------------------------------------------------------------------------------- 1 | import { singletonHook } from 'react-singleton-hook'; 2 | import { useLocalStorage } from 'react-use'; 3 | 4 | /** 5 | * Returns the dev switch state and a function to toggle it. 6 | */ 7 | export const useDevSwitchIsOn = singletonHook( 8 | { devSwitchIsOn: false, toggleDevSwitch: () => {} }, 9 | () => { 10 | const [devSwitchIsOn, setDevSwitchIsOn] = useLocalStorage( 11 | 'devswitch', 12 | false, 13 | { 14 | raw: false, 15 | serializer: JSON.stringify, 16 | deserializer: JSON.parse, 17 | } 18 | ); 19 | 20 | const toggleDevSwitch = () => { 21 | setDevSwitchIsOn(devSwitchIsOn); 22 | }; 23 | 24 | return { devSwitchIsOn: !!devSwitchIsOn, toggleDevSwitch }; 25 | } 26 | ); 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Add.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Add = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Add; 27 | -------------------------------------------------------------------------------- /react/src/constants/wallets.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CloverWalletAdapter, 3 | Coin98WalletAdapter, 4 | CoinbaseWalletAdapter, 5 | MathWalletAdapter, 6 | PhantomWalletAdapter, 7 | SolflareWalletAdapter, 8 | } from '@solana/wallet-adapter-wallets'; 9 | 10 | /** 11 | * A list of wallets to display in the wallet connection list. 12 | * 13 | * On SAGA the mobile wallet adapter will be added to the list automatically. 14 | * 15 | * The Wallet Provider should also be smart enough to add any other detected wallets to the list too. 16 | */ 17 | export const DRIFT_WALLET_PROVIDERS = [ 18 | new PhantomWalletAdapter(), 19 | new SolflareWalletAdapter(), 20 | new CoinbaseWalletAdapter(), 21 | new MathWalletAdapter(), 22 | new Coin98WalletAdapter(), 23 | new CloverWalletAdapter(), 24 | ]; 25 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronUp = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ChevronUp; 27 | -------------------------------------------------------------------------------- /common-ts/tests/utils/txAssertions.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { 3 | ComputeBudgetProgram, 4 | VersionedTransaction, 5 | PublicKey, 6 | } from '@solana/web3.js'; 7 | 8 | export function assertComputeBudgetThenProgram( 9 | transaction: VersionedTransaction, 10 | programId: PublicKey, 11 | computeBudgetInstructionCount: number = 2 12 | ): void { 13 | transaction.message.compiledInstructions.forEach((ix, index) => { 14 | const ixProgramId = 15 | transaction.message.staticAccountKeys[ix.programIdIndex]; 16 | if (index < computeBudgetInstructionCount) { 17 | expect(ixProgramId.toString()).to.equal( 18 | ComputeBudgetProgram.programId.toString() 19 | ); 20 | } else { 21 | expect(ixProgramId.toString()).to.equal(programId.toString()); 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronDown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronDown = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ChevronDown; 27 | -------------------------------------------------------------------------------- /common-ts/src/utils/SlotBasedResultValidator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility class which makes sure that all results with a slot are only accepted if the slot is higher than the previous result 3 | */ 4 | export class SlotBasedResultValidator { 5 | private resultIncrements = new Map(); 6 | private allowUndefined: boolean; 7 | 8 | constructor(allowUndefined = true) { 9 | this.allowUndefined = allowUndefined; 10 | } 11 | 12 | handleResult(key: string, slot: number | undefined) { 13 | if (slot === undefined) { 14 | return this.allowUndefined; 15 | } 16 | 17 | const previous = this.resultIncrements.get(key); 18 | 19 | if (!previous || slot >= previous) { 20 | this.resultIncrements.set(key, slot); 21 | return true; 22 | } else { 23 | return false; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Subtract.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Subtract = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Subtract; 29 | -------------------------------------------------------------------------------- /react/src/constants/priorityFees.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from '@solana/web3.js'; 2 | 3 | export const FEE_SUBSCRIPTION_SLOT_LOOKBACK = 10; 4 | 5 | export const PRIORITY_FEE_SUBSCRIPTION_ADDRESSES = [ 6 | new PublicKey('8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'), // sol openbook market 7 | new PublicKey('8UJgxaiQx5nTrdDgph5FiahMmzduuLTLf5WmsPegYA6W'), // sol perp 8 | new PublicKey('6gMq3mRCKf8aP3ttTyYhuijVZ2LGi14oDsBbkgubfLB3'), // usdc 9 | ]; 10 | 11 | export const PRIORITY_FEE_SUBSCRIPTION_ADDRESS_STRINGS = 12 | PRIORITY_FEE_SUBSCRIPTION_ADDRESSES.map((pubkey) => pubkey.toString()); // Pre-Computed string versions of the addresses, to save on computation 13 | 14 | export const BOOSTED_MULITPLIER = 5; 15 | export const TURBO_MULTIPLIER = 10; 16 | 17 | export const DEFAULT_PRIORITY_FEE_MAX_CAP = 0.01; 18 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronLeft.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronLeft = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ChevronLeft; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Loading.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Loading = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Loading; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Phoenix.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Phoenix = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Phoenix; 27 | -------------------------------------------------------------------------------- /react/src/hooks/priorityFees/usePriorityFeesPollingRate.ts: -------------------------------------------------------------------------------- 1 | import { useCommonDriftStore, usePriorityFeeStore } from '../../stores'; 2 | 3 | export const usePriorityFeesPollingRate = () => { 4 | const pollingMultiplier = useCommonDriftStore((s) => s.pollingMultiplier); 5 | const basePollingRateMs = useCommonDriftStore((s) => s.env.basePollingRateMs); 6 | const priorityFeePollingMultiplier = useCommonDriftStore( 7 | (s) => s.env.priorityFeePollingMultiplier 8 | ); 9 | const isPriorityFeeStoreReady = usePriorityFeeStore((s) => s.ready); 10 | 11 | const pollingFrequencyMs = isPriorityFeeStoreReady 12 | ? basePollingRateMs * 13 | Math.max(pollingMultiplier, priorityFeePollingMultiplier) 14 | : 1000; // poll more frequently until priority fee store is ready 15 | 16 | return pollingFrequencyMs; 17 | }; 18 | -------------------------------------------------------------------------------- /icons/src/icons/components/ArrowLeft.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ArrowLeft = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ArrowLeft; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/ArrowRight.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ArrowRight = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ArrowRight; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronRight.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronRight = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ChevronRight; 27 | -------------------------------------------------------------------------------- /react/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useCommonDriftActions'; 2 | export * from './useCurrentRpc'; 3 | export * from './useWalletContext'; 4 | export * from './useSyncWalletToStore'; 5 | export * from './useSolBalance'; 6 | export * from './useEmulation'; 7 | export * from './useDisableScroll'; 8 | export * from './useDriftClientIsReady'; 9 | export * from './useRpcLatencies'; 10 | export * from './useDevSwitchIsOn'; 11 | export * from './useLastAcknowledgedTerms'; 12 | export * from './useAccountCreationCost'; 13 | export * from './oraclePrice'; 14 | export * from './priorityFees'; 15 | export * from './useImmediateInterval'; 16 | export * from './useSyncLocalStorage'; 17 | export * from './useHandleBadRpc'; 18 | export * from './charts/useGroupHistoricalPricesByAverage'; 19 | export * from './useTargetedPopover'; 20 | -------------------------------------------------------------------------------- /icons/src/icons/components/Up.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Up = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Up; 29 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/constants/errors.ts: -------------------------------------------------------------------------------- 1 | import { OptionalOrderParams } from '@drift-labs/sdk'; 2 | 3 | /** 4 | * Error thrown when a method is called while the user is geo-blocked. 5 | */ 6 | export class GeoBlockError extends Error { 7 | constructor(methodName: string) { 8 | super( 9 | `Method '${methodName}' is not available due to geographical restrictions.` 10 | ); 11 | this.name = 'GeoBlockError'; 12 | } 13 | } 14 | 15 | /** 16 | * Error thrown when no top makers are found. The order params provided can still be used as a fallback. 17 | */ 18 | export class NoTopMakersError extends Error { 19 | orderParams: OptionalOrderParams; 20 | constructor(message: string, orderParams: OptionalOrderParams) { 21 | super(message); 22 | this.name = 'NoTopMakersError'; 23 | this.orderParams = orderParams; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /icons/src/icons/components/Close.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Close = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Close; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Down.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Down = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Down; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/WarningFilled.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const WarningFilled = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default WarningFilled; 27 | -------------------------------------------------------------------------------- /icons/rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from '@rollup/plugin-node-resolve'; 2 | import commonjs from '@rollup/plugin-commonjs'; 3 | import typescript from '@rollup/plugin-typescript'; 4 | import dts from 'rollup-plugin-dts'; 5 | 6 | const packageJson = require('./package.json'); 7 | 8 | export default [ 9 | { 10 | input: 'src/index.ts', 11 | output: [ 12 | // { 13 | // file: packageJson.main, 14 | // format: 'cjs', 15 | // sourcemap: true, 16 | // }, 17 | { 18 | file: packageJson.module, 19 | format: 'esm', 20 | sourcemap: true, 21 | }, 22 | ], 23 | plugins: [ 24 | resolve(), 25 | commonjs(), 26 | typescript({ tsconfig: './tsconfig.json' }), 27 | ], 28 | }, 29 | { 30 | input: 'dist/esm/index.d.ts', 31 | output: [{ file: 'dist/index.d.ts', format: 'esm' }], 32 | plugins: [dts()], 33 | }, 34 | ]; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/CheckEmpty.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const CheckEmpty = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default CheckEmpty; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Warning.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Warning = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Warning; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/CaretUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const CaretUp = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default CaretUp; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/List.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const List = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default List; 27 | -------------------------------------------------------------------------------- /react/src/components/Tables/BodyCell.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren } from 'react'; 2 | import { BodyCellWrapper } from './BodyCellWrapper'; 3 | 4 | export const BodyCell = ({ 5 | children, 6 | className, 7 | onClick, 8 | dataPuppetTag, 9 | flexCol, 10 | alignCenter, 11 | alignRight, 12 | innerClassName, 13 | }: PropsWithChildren<{ 14 | className?: string; 15 | innerClassName?: string; 16 | onClick?: () => void; 17 | dataPuppetTag?: string; 18 | flexCol?: boolean; 19 | alignCenter?: boolean; 20 | alignRight?: boolean; 21 | }>) => { 22 | return ( 23 | 32 | {children} 33 | 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /icons/src/icons/components/CaretDown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const CaretDown = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default CaretDown; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Checkmark.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Checkmark = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Checkmark; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Fastlane.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Fastlane = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Fastlane; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/SuccessFilled.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const SuccessFilled = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default SuccessFilled; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Resize.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Resize = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Resize; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/OrderbookVertical.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const OrderbookVertical = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 17 | 18 | 19 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default OrderbookVertical; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Twitter.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Twitter = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Twitter; 29 | -------------------------------------------------------------------------------- /react/src/components/Tables/HeaderRow.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren, type JSX } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | import { TableRowWrapper } from './TableRowWrapper'; 4 | 5 | export const HeaderRow = ({ 6 | children, 7 | className, 8 | ...props 9 | }: PropsWithChildren<{ 10 | grid: string; 11 | className?: string; 12 | forceBottomBorder?: boolean; 13 | header?: boolean; 14 | lastColumnJustify?: string; 15 | id?: string; 16 | /** 17 | * Adds padding to the right of the table to account for scrollbar in the table. 18 | */ 19 | addScrollPadding?: boolean; 20 | }>): JSX.Element => { 21 | return ( 22 | 31 | {children} 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/RecentTrades.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const RecentTrades = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default RecentTrades; 29 | -------------------------------------------------------------------------------- /react/src/hooks/useLastAcknowledgedTerms.tsx: -------------------------------------------------------------------------------- 1 | import { singletonHook } from 'react-singleton-hook'; 2 | import { useLocalStorage } from 'react-use'; 3 | 4 | /** 5 | * Returns the last timestamp that the user acknowledged the terms, and a function to update the timestamp. 6 | * 7 | * Timestamp is stored in local storage. 8 | */ 9 | export const useLastAcknowledgedTerms = singletonHook( 10 | { lastAcknowledgedTerms: 0, updateLastAcknowledgedTerms: () => {} }, 11 | () => { 12 | const [lastAcknowledgedTerms, setLastAcknowledgedTerms] = 13 | useLocalStorage('lastAcknowledgedTerms', 0, { 14 | raw: false, 15 | serializer: JSON.stringify, 16 | deserializer: JSON.parse, 17 | }); 18 | 19 | const updateLastAcknowledgedTerms = () => { 20 | setLastAcknowledgedTerms(Date.now()); 21 | }; 22 | 23 | return { lastAcknowledgedTerms, updateLastAcknowledgedTerms }; 24 | } 25 | ); 26 | -------------------------------------------------------------------------------- /icons/src/icons/components/HamburgerNew.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const HamburgerNew = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 17 | 21 | 22 | } 23 | {...restProps} 24 | /> 25 | ); 26 | }; 27 | export default HamburgerNew; 28 | -------------------------------------------------------------------------------- /common-ts/src/utils/pollingSequenceGuard.ts: -------------------------------------------------------------------------------- 1 | export const LATE_POLLING_RESPONSE = Symbol('Late polling response'); 2 | 3 | /** 4 | * Utility class which makes sure that asyncronous responses get rejected when we expect them to return in the same sequence that we request them but they don't 5 | */ 6 | export class PollingSequenceGuard { 7 | static pollingCounts = new Map(); 8 | static LATE_POLLING_RESPONSE = LATE_POLLING_RESPONSE; 9 | static async fetch( 10 | key: string | symbol, 11 | cb: () => Promise 12 | ): Promise { 13 | const newCount = (this.pollingCounts.get(key) ?? 0) + 1; 14 | 15 | const promise = await cb(); 16 | 17 | const latestCount = this.pollingCounts.get(key) ?? 0; 18 | 19 | if (latestCount > newCount) { 20 | return Promise.reject(LATE_POLLING_RESPONSE); 21 | } 22 | 23 | this.pollingCounts.set(key, newCount); 24 | 25 | return promise; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /icons/src/icons/components/Bolt.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Bolt = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Bolt; 27 | -------------------------------------------------------------------------------- /common-ts/src/types/trade.ts: -------------------------------------------------------------------------------- 1 | import { BN, OrderType } from '@drift-labs/sdk'; 2 | 3 | export type TradeOffsetPrice = 4 | | 'worst' 5 | | 'best' 6 | | 'oracle' 7 | | 'mark' 8 | | 'entry' 9 | | 'bestOffer'; 10 | 11 | export type UIOrderType = 12 | | 'market' 13 | | 'limit' 14 | | 'stopMarket' 15 | | 'stopLimit' 16 | | 'takeProfitMarket' 17 | | 'takeProfitLimit' 18 | | 'oracle' 19 | | 'oracleLimit' 20 | | 'scaledOrders'; 21 | 22 | export type UIOrderTypeValue = { 23 | label: string; 24 | value: UIOrderType; 25 | orderType: OrderType; 26 | description?: string; 27 | }; 28 | 29 | export type UIOrderTypeLookup = { 30 | [key in UIOrderType]: UIOrderTypeValue; 31 | }; 32 | 33 | export type AuctionParams = { 34 | auctionStartPrice: BN; 35 | auctionEndPrice: BN; 36 | auctionDuration: number; 37 | constrainedBySlippage?: boolean; // flag to tell the UI that end price is constrained by max slippage tolerance 38 | }; 39 | -------------------------------------------------------------------------------- /icons/src/icons/components/Hamburger.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Hamburger = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Hamburger; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Mouse.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Mouse = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 17 | 23 | 24 | } 25 | {...restProps} 26 | /> 27 | ); 28 | }; 29 | export default Mouse; 30 | -------------------------------------------------------------------------------- /icons/src/icons/components/Signal.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Signal = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Signal; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/ErrorFilled.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ErrorFilled = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default ErrorFilled; 27 | -------------------------------------------------------------------------------- /common-ts/src/drift/constants/apiUrls.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * API URL constants for Drift protocol services 3 | * 4 | * These constants define the URLs used within the drift directory for various Drift services. 5 | */ 6 | 7 | export const API_URLS = { 8 | /** 9 | * Data API - Used for historical data, funding rates, candles, etc. 10 | */ 11 | DATA_API: 'https://data.api.drift.trade', 12 | 13 | /** 14 | * DLOB (Decentralized Limit Order Book) Server - Used for auction parameters, priority fees, etc. 15 | */ 16 | DLOB: 'https://dlob.drift.trade', 17 | 18 | /** 19 | * Swift Server - Used for signed message (gasless) orders 20 | */ 21 | SWIFT: 'https://swift.drift.trade', 22 | } as const; 23 | 24 | /** 25 | * API endpoints for specific functionality 26 | */ 27 | export const API_ENDPOINTS = { 28 | FUNDING_RATES: '/fundingRates', 29 | BATCH_PRIORITY_FEES: '/batchPriorityFees', 30 | AUCTION_PARAMS: '/auctionParams', 31 | } as const; 32 | -------------------------------------------------------------------------------- /icons/src/icons/components/Futarchy.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Futarchy = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Futarchy; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Menu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Menu = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Menu; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Metadao.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Metadao = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Metadao; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/ResizeFull.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ResizeFull = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default ResizeFull; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Swap.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Swap = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Swap; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/TradingUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const TradingUp = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default TradingUp; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Hide.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Hide = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Hide; 29 | -------------------------------------------------------------------------------- /common-ts/src/constants/misc.ts: -------------------------------------------------------------------------------- 1 | import { BigNum, LAMPORTS_EXP } from '@drift-labs/sdk'; 2 | 3 | /** 4 | * Equal to 0.0001 5 | */ 6 | export const NEW_ACCOUNT_DONATION = BigNum.fromPrint('0.0001', LAMPORTS_EXP); 7 | 8 | /** 9 | * Equal to 0.035 10 | */ 11 | export const NEW_ACCOUNT_BASE_RENT = new BigNum('31347840', LAMPORTS_EXP); 12 | 13 | export const SWIFT_ACCOUNT_BASE_RENT = new BigNum('2756160', LAMPORTS_EXP); 14 | 15 | /** 16 | * Equal to NEW_ACCOUNT_DONATION + NEW_ACCOUNT_BASE_RENT 17 | */ 18 | export const NEW_ACCOUNT_BASE_COST = NEW_ACCOUNT_BASE_RENT.add( 19 | NEW_ACCOUNT_DONATION 20 | ).add(SWIFT_ACCOUNT_BASE_RENT); 21 | 22 | /** 23 | * Equal to 0.002 24 | */ 25 | export const IF_STAKE_ACCOUNT_BASE_RENT = BigNum.fromPrint( 26 | '0.002', 27 | LAMPORTS_EXP 28 | ); 29 | 30 | /** 31 | * Equal to 0.015 SOL 32 | */ 33 | export const MIN_LEFTOVER_SOL = BigNum.fromPrint('0.015', LAMPORTS_EXP); 34 | 35 | export const ONE_DAY_MS = 1000 * 60 * 60 * 24; 36 | -------------------------------------------------------------------------------- /icons/src/icons/components/Accordion.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Accordion = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Accordion; 27 | -------------------------------------------------------------------------------- /common-ts/src/utils/Stopwatch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A Dev Tool to help with performance analysis. 3 | * 4 | * The stopwatch class should function as a "timer" for a variety of unique keys. Any time a caller calls the "tick" method, with a key, the stopwatch will log the time since the last tick for that key. 5 | */ 6 | export class Stopwatch { 7 | private _lastTick: { [key: string]: number } = {}; 8 | constructor() {} 9 | 10 | /** 11 | * Logs the time since the last tick for the given key. 12 | * @param key The key to log the time for. 13 | */ 14 | public tick(key: string, message?: string) { 15 | const now = Date.now(); 16 | const lastTick = this._lastTick[key]; 17 | if (lastTick) { 18 | console.log( 19 | `⏱️ :: ${message ? ` ${message} ` : ''} \n${key} => ${now - lastTick}ms` 20 | ); 21 | } 22 | this._lastTick[key] = now; 23 | } 24 | 25 | blankTick(key: string) { 26 | const now = Date.now(); 27 | this._lastTick[key] = now; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /icons/src/icons/components/Switch.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Switch = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Switch; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Star.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Star = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Star; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/GridMenu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const GridMenu = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default GridMenu; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Megaphone.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Megaphone = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Megaphone; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Layout = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Layout; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/YES.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const YES = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default YES; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Control.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Control = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Control; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Filter.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Filter = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Filter; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Medium.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Medium = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Medium; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Deposit.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Deposit = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 26 | 27 | } 28 | {...restProps} 29 | /> 30 | ); 31 | }; 32 | export default Deposit; 33 | -------------------------------------------------------------------------------- /icons/src/icons/components/LiqHalf.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const LiqHalf = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default LiqHalf; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Info.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Info = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Info; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Trade.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Trade = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Trade; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Transfer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Transfer = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Transfer; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Withdraw.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Withdraw = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 26 | 27 | } 28 | {...restProps} 29 | /> 30 | ); 31 | }; 32 | export default Withdraw; 33 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronsUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronsUp = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default ChevronsUp; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronsDown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronsDown = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default ChevronsDown; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronsRight.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronsRight = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default ChevronsRight; 29 | -------------------------------------------------------------------------------- /react/src/components/Tables/BodyRow.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren, type JSX } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | import { TableRowWrapper } from './TableRowWrapper'; 4 | 5 | export const BodyRow = ({ 6 | children, 7 | className, 8 | isDataRow, 9 | ...props 10 | }: PropsWithChildren<{ 11 | grid: string; 12 | className?: string; 13 | forceBottomBorder?: boolean; 14 | header?: boolean; 15 | lastColumnJustify?: string; 16 | isDataRow?: boolean; 17 | noBorder?: boolean; 18 | onClick?: (_event: MouseEvent) => void; 19 | lastChildNoBorder?: boolean; 20 | strongBottomBorder?: boolean; 21 | }>): JSX.Element => { 22 | return ( 23 | 33 | {children} 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /icons/src/icons/components/ChevronsLeft.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ChevronsLeft = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default ChevronsLeft; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Share.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Share = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Share; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Collapse.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Collapse = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Collapse; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Stake.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Stake = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Stake; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Expand.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Expand = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Expand; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Edit.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Edit = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Edit; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/No.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const No = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default No; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/SettingsTrade.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const SettingsTrade = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default SettingsTrade; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Wallet.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Wallet = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Wallet; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Apple.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Apple = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Apple; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Replies.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Replies = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Replies; 29 | -------------------------------------------------------------------------------- /react/src/hooks/priorityFees/usePriorityFeeUserSettings.ts: -------------------------------------------------------------------------------- 1 | import { FeeType } from '../../stores'; 2 | import { singletonHook } from 'react-singleton-hook'; 3 | import { useSyncLocalStorage } from '../useSyncLocalStorage'; 4 | 5 | type UserPriorityFeeSettings = { 6 | userPriorityFeeType: FeeType; 7 | userCustomMaxPriorityFeeCap: number; 8 | userCustomPriorityFee: number | null; 9 | }; 10 | 11 | const DEFAULT_SETTING: UserPriorityFeeSettings = { 12 | userPriorityFeeType: 'dynamic', 13 | userCustomMaxPriorityFeeCap: 0.01, 14 | userCustomPriorityFee: null, 15 | }; 16 | 17 | export const usePriorityFeeUserSettings = singletonHook( 18 | { priorityFeeSettings: DEFAULT_SETTING, setPriorityFeeSettings: () => {} }, 19 | () => { 20 | const [priorityFeeSettings, setPriorityFeeSettings] = 21 | useSyncLocalStorage( 22 | 'priorityFeeSettings', 23 | DEFAULT_SETTING 24 | ); 25 | 26 | return { 27 | priorityFeeSettings: priorityFeeSettings ?? DEFAULT_SETTING, 28 | setPriorityFeeSettings, 29 | }; 30 | } 31 | ); 32 | -------------------------------------------------------------------------------- /icons/src/icons/components/Play.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Play = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 26 | 27 | } 28 | {...restProps} 29 | /> 30 | ); 31 | }; 32 | export default Play; 33 | -------------------------------------------------------------------------------- /icons/src/icons/components/MegaphoneNew.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const MegaphoneNew = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | 22 | } 23 | {...restProps} 24 | /> 25 | ); 26 | }; 27 | export default MegaphoneNew; 28 | -------------------------------------------------------------------------------- /icons/src/icons/components/OrderBook.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const OrderBook = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default OrderBook; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Stats.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Stats = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Stats; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Telegram.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Telegram = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Telegram; 27 | -------------------------------------------------------------------------------- /react/src/stores/useOraclePriceStore.tsx: -------------------------------------------------------------------------------- 1 | import { produce } from 'immer'; 2 | import { create } from 'zustand'; 3 | import { MarketId, UIMarket } from '@drift/common'; 4 | import { OraclePriceData } from '@drift-labs/sdk'; 5 | 6 | export type FormattedOraclePriceData = { 7 | price: number; 8 | slot: number; 9 | confidence: number; 10 | twap?: number; 11 | twapConfidence?: number; 12 | maxPrice?: number; 13 | }; 14 | 15 | export type OraclePriceInfo = { 16 | market: UIMarket; 17 | priceData: FormattedOraclePriceData; 18 | rawPriceData: OraclePriceData; 19 | }; 20 | 21 | export interface OraclePriceStore { 22 | set: (x: (s: OraclePriceStore) => void) => void; 23 | get: (x: any) => OraclePriceStore; 24 | getMarketPriceData: (market: MarketId) => OraclePriceInfo; 25 | symbolMap: { 26 | [index: string]: OraclePriceInfo; 27 | }; 28 | } 29 | 30 | export const useOraclePriceStore = create((set, get) => ({ 31 | set: (fn) => set(produce(fn)), 32 | get: () => get(), 33 | getMarketPriceData: (market: MarketId) => get().symbolMap[market.key], 34 | symbolMap: {}, 35 | })); 36 | -------------------------------------------------------------------------------- /icons/src/icons/components/Vote.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Vote = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Vote; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Email.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Email = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Email; 29 | -------------------------------------------------------------------------------- /common-ts/src/constants/geoblockList.ts: -------------------------------------------------------------------------------- 1 | export const GEOBLOCK_LIST = [ 2 | { code: 'AG', name: 'Antigua and Barbuda' }, 3 | { code: 'DZ', name: 'Algeria' }, 4 | { code: 'BD', name: 'Bangladesh' }, 5 | { code: 'BO', name: 'Bolivia' }, 6 | { code: 'BY', name: 'Belarus' }, 7 | { code: 'BI', name: 'Burundi' }, 8 | { code: 'MM', name: 'Burma (Myanmar)' }, 9 | { code: 'CI', name: "Cote D'Ivoire (Ivory Coast)" }, 10 | { code: 'CU', name: 'Cuba' }, 11 | { code: 'CD', name: 'Democratic Republic of Congo' }, 12 | { code: 'EC', name: 'Ecuador' }, 13 | { code: 'IR', name: 'Iran' }, 14 | { code: 'IQ', name: 'Iraq' }, 15 | { code: 'LR', name: 'Liberia' }, 16 | { code: 'LY', name: 'Libya' }, 17 | { code: 'ML', name: 'Mali' }, 18 | { code: 'MA', name: 'Morocco' }, 19 | { code: 'NP', name: 'Nepal' }, 20 | { code: 'KP', name: 'North Korea' }, 21 | { code: 'SO', name: 'Somalia' }, 22 | { code: 'SD', name: 'Sudan' }, 23 | { code: 'SY', name: 'Syria' }, 24 | { code: 'VE', name: 'Venezuela' }, 25 | { code: 'YE', name: 'Yemen' }, 26 | { code: 'ZW', name: 'Zimbabwe' }, 27 | { code: 'US', name: 'United States' }, 28 | ]; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Search.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Search = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default Search; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Lightning.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Lightning = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Lightning; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Diamond.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Diamond = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Diamond; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/SortUp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const SortUp = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 24 | 25 | } 26 | {...restProps} 27 | /> 28 | ); 29 | }; 30 | export default SortUp; 31 | -------------------------------------------------------------------------------- /icons/src/icons/components/SortDown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const SortDown = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 24 | 25 | } 26 | {...restProps} 27 | /> 28 | ); 29 | }; 30 | export default SortDown; 31 | -------------------------------------------------------------------------------- /icons/src/icons/components/CheckFilled.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const CheckFilled = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default CheckFilled; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/PieChart.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const PieChart = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default PieChart; 29 | -------------------------------------------------------------------------------- /react/src/components/Tables/TableCellCardValue.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo, ReactNode, type JSX } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export const TableCellCardValue = ({ 5 | value, 6 | label, 7 | icon, 8 | size, 9 | highlight, 10 | isMobileTopRow, 11 | className, 12 | onClick, 13 | }: { 14 | value: ReactNode; 15 | label: string; 16 | icon?: JSX.Element; 17 | size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; 18 | highlight?: boolean; 19 | isMobileTopRow?: boolean; 20 | className?: string; 21 | onClick?: () => void; 22 | }) => { 23 | const memoedClassName = useMemo( 24 | () => 25 | twMerge( 26 | `flex flex-col items-start`, 27 | isMobileTopRow ? 'pt-0' : 'pt-2', 28 | highlight && 'text-lg', 29 | className 30 | ), 31 | [isMobileTopRow, highlight, className] 32 | ); 33 | 34 | return ( 35 |
{ 38 | onClick?.(); 39 | }} 40 | > 41 |
42 | {label} 43 | {icon && icon} 44 |
45 |
{value}
46 |
47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /react/src/components/Charts/ActiveDot.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useEffect, useRef } from 'react'; 4 | 5 | export const ActiveDot = ({ 6 | x, 7 | y, 8 | stroke, 9 | size = 32, 10 | strokeWidth = 8, 11 | fill, 12 | className, 13 | }: { 14 | x: number; 15 | y: number; 16 | stroke: string; 17 | size?: number; 18 | strokeWidth?: number; 19 | fill?: string; 20 | className?: string; 21 | }) => { 22 | const radius = size / 2; 23 | const circleRef = useRef(null); 24 | 25 | useEffect(() => { 26 | if (circleRef.current) { 27 | circleRef.current.style.transform = 'scale(1)'; 28 | } 29 | }, []); 30 | 31 | return ( 32 | 42 | 52 | 53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /icons/src/icons/components/GraphSquare.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const GraphSquare = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 24 | 25 | } 26 | {...restProps} 27 | /> 28 | ); 29 | }; 30 | export default GraphSquare; 31 | -------------------------------------------------------------------------------- /icons/src/templates/componentTemplate.js: -------------------------------------------------------------------------------- 1 | function componentTemplate( 2 | { template }, 3 | opts, 4 | { imports, componentName, props, jsx, exports } 5 | ) { 6 | const code = ` 7 | %%NEWLINE%% 8 | %%NEWLINE%% 9 | 10 | import * as React from 'react'; 11 | import { IconProps } from '../../types'; 12 | import { IconWrapper } from '../IconWrapper'; 13 | 14 | %%NEWLINE%% 15 | 16 | const %%COMPONENT_NAME%% = (allProps: IconProps) => { 17 | const { svgProps: props, ...restProps } = allProps; 18 | return 19 | }; 20 | 21 | %%EXPORTS%% 22 | `; 23 | 24 | const mapping = { 25 | COMPONENT_NAME: componentName, 26 | JSX: jsx, 27 | EXPORTS: exports, 28 | NEWLINE: "\n" 29 | }; 30 | 31 | /** 32 | * API Docs: https://babeljs.io/docs/en/babel-template#api 33 | */ 34 | const typeScriptTpl = template(code, { 35 | plugins: ["jsx", "typescript"], 36 | preserveComments: true, 37 | syntacticPlaceholders: true 38 | }); 39 | 40 | return typeScriptTpl(mapping); 41 | } 42 | 43 | module.exports = componentTemplate; 44 | -------------------------------------------------------------------------------- /icons/src/icons/components/Calculator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Calculator = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default Calculator; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Calendar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Calendar = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Calendar; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/GraphCircle.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const GraphCircle = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default GraphCircle; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Disclaimers.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Disclaimers = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Disclaimers; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/ExitPosition.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const ExitPosition = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default ExitPosition; 35 | -------------------------------------------------------------------------------- /common-ts/src/types/user.ts: -------------------------------------------------------------------------------- 1 | import { BN, PublicKey, SpotPosition } from '@drift-labs/sdk'; 2 | 3 | export type OpenPosition = { 4 | marketIndex: number; 5 | marketSymbol: string; 6 | direction: 'short' | 'long'; 7 | notional: BN; 8 | baseSize: BN; 9 | entryPrice: BN; 10 | exitPrice: BN; 11 | liqPrice: BN; 12 | pnlVsOracle: BN; 13 | pnlVsMark: BN; 14 | quoteAssetNotionalAmount: BN; 15 | quoteEntryAmount: BN; 16 | quoteBreakEvenAmount: BN; 17 | unrealizedFundingPnl: BN; 18 | feesAndFundingPnl: BN; 19 | lastCumulativeFundingRate: BN; 20 | openOrders: number; 21 | /** 22 | * This is the unsettled pnl that is claimable. Naming is a bit confusing here. 23 | */ 24 | unsettledPnl: BN; 25 | unsettledFundingPnl: BN; 26 | /** 27 | * This is the total of unsettled pnl and unsettled funding. 28 | */ 29 | totalUnrealizedPnl: BN; 30 | costBasis: BN; 31 | realizedPnl: BN; 32 | lpShares: BN; 33 | pnlIsClaimable: boolean; 34 | remainderBaseAmount?: number; // LP only 35 | lpDeriskPrice?: BN; //LP only 36 | maxMarginRatio: number; 37 | }; 38 | 39 | export type BankBalanceUI = SpotPosition & { 40 | accountId: number; 41 | accountName: string; 42 | accountAuthority: PublicKey; 43 | }; 44 | -------------------------------------------------------------------------------- /icons/src/icons/components/Google.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Google = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Google; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Account.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Account = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Account; 29 | -------------------------------------------------------------------------------- /common-ts/tests/utils/stringUtils.test.ts: -------------------------------------------------------------------------------- 1 | import { COMMON_UI_UTILS } from '../../src/common-ui-utils/commonUiUtils'; 2 | import { expect } from 'chai'; 3 | describe('trimTrailingZeros', () => { 4 | it('trims trailing zeros after decimal', () => { 5 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.0000')).to.equal('1.0'); // default is leave 1 zero 6 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.0000', 0)).to.equal('1'); 7 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.1000', 0)).to.equal('1.1'); 8 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.1200', 0)).to.equal('1.12'); 9 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.0010', 0)).to.equal('1.001'); 10 | }); 11 | 12 | it('handles numbers without trailing zeros', () => { 13 | expect(COMMON_UI_UTILS.trimTrailingZeros('1', 0)).to.equal('1'); 14 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.1', 0)).to.equal('1.1'); 15 | expect(COMMON_UI_UTILS.trimTrailingZeros('1.123', 0)).to.equal('1.123'); 16 | }); 17 | 18 | it('handles zero', () => { 19 | expect(COMMON_UI_UTILS.trimTrailingZeros('0', 0)).to.equal('0'); 20 | expect(COMMON_UI_UTILS.trimTrailingZeros('0.0', 0)).to.equal('0'); 21 | expect(COMMON_UI_UTILS.trimTrailingZeros('0.000', 0)).to.equal('0'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /common-ts/src/drift/Drift/clients/CentralServerDrift/types.ts: -------------------------------------------------------------------------------- 1 | import { SwiftOrderOptions } from '../../../base/actions/trade/openPerpOrder/openSwiftOrder'; 2 | import { WithTxnParams } from '../../../base/types'; 3 | import { OpenPerpMarketOrderParams } from '../../../base/actions/trade/openPerpOrder/openPerpMarketOrder'; 4 | import { OpenPerpNonMarketOrderParams } from '../../../base/actions/trade/openPerpOrder/openPerpNonMarketOrder'; 5 | import { PublicKey } from '@solana/web3.js'; 6 | 7 | export type CentralServerSwiftOrderOptions = Omit< 8 | SwiftOrderOptions, 9 | 'swiftServerUrl' 10 | >; 11 | 12 | export type CentralServerGetOpenPerpMarketOrderTxnParams< 13 | T extends boolean = boolean 14 | > = WithTxnParams< 15 | Omit< 16 | OpenPerpMarketOrderParams, 17 | 'driftClient' | 'user' | 'dlobServerHttpUrl' 18 | > 19 | > & { 20 | userAccountPublicKey: PublicKey; 21 | }; 22 | 23 | export type CentralServerGetOpenPerpNonMarketOrderTxnParams< 24 | T extends boolean = boolean 25 | > = WithTxnParams< 26 | Omit< 27 | OpenPerpNonMarketOrderParams, 28 | 'driftClient' | 'user' | 'dlobServerHttpUrl' 29 | > 30 | > & { 31 | userAccountPublicKey: PublicKey; 32 | }; 33 | -------------------------------------------------------------------------------- /.github/workflows/common_unit_tests.yml: -------------------------------------------------------------------------------- 1 | name: common_unit_tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - develop 8 | - 'release/**' 9 | pull_request: 10 | paths: 11 | - 'common-ts/**' 12 | - 'protocol/sdk/**' 13 | - '.github/workflows/common_unit_tests.yml' 14 | 15 | jobs: 16 | tests: 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 10 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | with: 23 | submodules: recursive 24 | 25 | - name: Setup Node 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: '22.14.x' 29 | cache: 'yarn' 30 | 31 | - name: Setup bun 32 | uses: oven-sh/setup-bun@v1 33 | with: 34 | bun-version: 1.2.15 35 | 36 | - name: Build SDK 37 | run: | 38 | yarn 39 | yarn build 40 | working-directory: protocol/sdk 41 | 42 | - name: Build Common 43 | run: | 44 | yarn 45 | yarn build 46 | working-directory: common-ts 47 | 48 | - name: Run Common Tests 49 | run: | 50 | yarn test:ci 51 | working-directory: common-ts 52 | -------------------------------------------------------------------------------- /common-ts/src/utils/rxjs.ts: -------------------------------------------------------------------------------- 1 | import { Subject, Observable } from 'rxjs'; 2 | import { filter, share } from 'rxjs/operators'; 3 | import { UniqueCircularBuffer } from './CircularBuffers/UniqueCircularBuffer'; 4 | 5 | /** 6 | * Deduplicated subject, using UniqueCircularBuffer to dedupe the input subject. 7 | * 8 | * The windowSize defines the amount of unique elements to keep in memory for the sake of deduplicating. Any incoming duplicate objects will NOT be added to the buffer so won't take up space. 9 | * @param inputSubject 10 | * @param windowSize maximum size of recent unique objects which will be stored to use for deduplication 11 | * @param uniquenessKeyGenerator function that generates a unique key for an object 12 | * @returns 13 | */ 14 | export function dedupeSubject( 15 | inputSubject: Subject, 16 | windowSize: number, 17 | uniquenessKeyGenerator: (a: T) => string 18 | ): Observable { 19 | const buffer = new UniqueCircularBuffer( 20 | windowSize, 21 | uniquenessKeyGenerator 22 | ); 23 | 24 | const dedupedObservable = inputSubject.pipe( 25 | filter((value) => { 26 | const added = buffer.add(value); 27 | 28 | return added; 29 | }), 30 | share() 31 | ); 32 | 33 | return dedupedObservable; 34 | } 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/CreditCard.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const CreditCard = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default CreditCard; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Lock.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Lock = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Lock; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Help.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Help = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Help; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/SettingsOther.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const SettingsOther = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default SettingsOther; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Autoconfirm.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Autoconfirm = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 24 | 25 | } 26 | {...restProps} 27 | /> 28 | ); 29 | }; 30 | export default Autoconfirm; 31 | -------------------------------------------------------------------------------- /react/src/hooks/useCurrentRpc.tsx: -------------------------------------------------------------------------------- 1 | import { EnvironmentConstants, RpcEndpoint } from '@drift/common'; 2 | import { singletonHook } from 'react-singleton-hook'; 3 | import { useCommonDriftStore } from '../stores'; 4 | import { useSyncLocalStorage } from './useSyncLocalStorage'; 5 | 6 | export const MAINNET_RPCS = EnvironmentConstants.rpcs.mainnet; 7 | export const DEVNET_RPCS = EnvironmentConstants.rpcs.dev; 8 | 9 | const DEFAULT_MAINNET_RPC = 10 | MAINNET_RPCS[Math.floor(Math.random() * MAINNET_RPCS.length)]; 11 | 12 | const _useCurrentRpc = () => { 13 | const Env = useCommonDriftStore((s) => s.env); 14 | 15 | const rpcToUse = 16 | Env.driftEnv === 'mainnet-beta' ? DEFAULT_MAINNET_RPC : DEVNET_RPCS[0]; 17 | 18 | const [savedRpc, setSavedRpc] = useSyncLocalStorage( 19 | 'currentRpc', 20 | rpcToUse 21 | ); 22 | 23 | const dedupedRpc = 24 | savedRpc.value === DEFAULT_MAINNET_RPC.value 25 | ? DEFAULT_MAINNET_RPC 26 | : savedRpc; 27 | 28 | return [dedupedRpc, setSavedRpc] as [ 29 | RpcEndpoint, 30 | (savedRpc: RpcEndpoint) => void 31 | ]; 32 | }; 33 | 34 | export const useCurrentRpc = singletonHook( 35 | [DEFAULT_MAINNET_RPC, () => {}] as [ 36 | RpcEndpoint, 37 | (savedRpc: RpcEndpoint) => void 38 | ], 39 | _useCurrentRpc 40 | ); 41 | -------------------------------------------------------------------------------- /react/src/stores/priorityFee/usePriorityFeeStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | import { produce } from 'immer'; 3 | 4 | export type FeeType = 'custom' | 'dynamic' | 'boosted' | 'turbo'; 5 | 6 | export type PriorityFeeStore = { 7 | set: (x: (s: PriorityFeeStore) => void) => void; 8 | get: () => PriorityFeeStore; 9 | ready: boolean; 10 | getPriorityFeeToUse: ( 11 | computeUnitsLimit?: number, 12 | feeTypeOverride?: FeeType 13 | ) => { 14 | priorityFeeInSol: number; 15 | computeUnitsPrice: number; 16 | }; 17 | }; 18 | 19 | /** 20 | * To use this store, you need to first import and call `useSyncPriorityFeeStore` at the top of your components. 21 | * You may use the hook `usePriorityFeeUserSettings` to fetch and update the user's priority fee settings in local storage. 22 | * The compute units price to use can be obtained through this store's `getPriorityFeeToUse` function, and should be used 23 | * to supplement the transaction params when building and sending a transaction. 24 | */ 25 | export const usePriorityFeeStore = create((set, get) => ({ 26 | set: (fn) => set(produce(fn)), 27 | get: () => get(), 28 | ready: false, 29 | getPriorityFeeToUse: () => ({ 30 | priorityFeeInSol: 0, 31 | computeUnitsPrice: 0, 32 | }), 33 | })); 34 | -------------------------------------------------------------------------------- /icons/src/icons/components/Balance.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Balance = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Balance; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Terms.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Terms = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Terms; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Discourse.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Discourse = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Discourse; 27 | -------------------------------------------------------------------------------- /react/src/hooks/useImmediateInterval.ts: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect } from 'react'; 2 | 3 | /** 4 | * Immediately invoking the callback function upon mounting, and executes the callback at a specified interval afterwards. 5 | * 6 | * @param callback - The function to be executed at the specified interval. 7 | * @param delayMs - The delay in milliseconds between each execution of the callback function. 8 | * @param runOnCallbackChange - Determines whether the callback should be executed immediately when it changes. 9 | */ 10 | export function useImmediateInterval( 11 | callback: () => void, 12 | delayMs: number, 13 | runOnCallbackChange = false 14 | ) { 15 | const savedCallback: React.MutableRefObject<(() => void) | null> = 16 | useRef<() => void>(null); 17 | 18 | // Remember the latest callback. 19 | useEffect(() => { 20 | savedCallback.current = callback; 21 | runOnCallbackChange && savedCallback.current?.(); 22 | }, [callback, runOnCallbackChange]); 23 | 24 | // Set up the interval. 25 | useEffect(() => { 26 | function tick() { 27 | savedCallback.current && savedCallback.current(); 28 | } 29 | 30 | tick(); 31 | 32 | if (delayMs) { 33 | const id = setInterval(tick, delayMs); 34 | return () => { 35 | clearInterval(id); 36 | }; 37 | } 38 | }, [delayMs]); 39 | } 40 | -------------------------------------------------------------------------------- /icons/src/icons/components/Others.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Others = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 34 | 40 | 41 | } 42 | {...restProps} 43 | /> 44 | ); 45 | }; 46 | export default Others; 47 | -------------------------------------------------------------------------------- /icons/src/icons/components/Claimstart.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Claimstart = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Claimstart; 29 | -------------------------------------------------------------------------------- /common-ts/src/scripts/update-drift-error-codes.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const clearingHouseData = require('../../../protocol/sdk/src/idl/drift.json'); 4 | 5 | let uiErrors = { 6 | errorsList: {}, 7 | }; 8 | 9 | const DRIFT_ERRORS_PATH = path.resolve( 10 | __dirname, 11 | '../constants/autogenerated/driftErrors.json' 12 | ); 13 | 14 | try { 15 | uiErrors = require(DRIFT_ERRORS_PATH); 16 | } catch (e) { 17 | console.log("ui errors file doesn't exist yet"); 18 | } 19 | 20 | // errorCodesMap should get reset every time, because the numbers could potentially change in the protocol's output 21 | // UI will use this to map the error code (number) to the name, so we can keep our manually added messages identified by the name but independent of the number 22 | uiErrors.errorCodesMap = {}; 23 | 24 | clearingHouseData.errors.forEach((err) => { 25 | uiErrors.errorCodesMap[err.code] = err.name; 26 | if (!uiErrors.errorsList[err.name]) { 27 | uiErrors.errorsList[err.name] = err; 28 | } else { 29 | // Only update error code in errorsList 30 | uiErrors.errorsList[err.name].code = err.code; 31 | } 32 | }); 33 | 34 | const copyErrorCodes = () => { 35 | fs.writeFileSync( 36 | DRIFT_ERRORS_PATH, 37 | `${JSON.stringify(uiErrors, null, ' ')}\n` 38 | ); 39 | }; 40 | 41 | copyErrorCodes(); 42 | -------------------------------------------------------------------------------- /common-ts/src/Config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SpotMarketConfig, 3 | DriftEnv, 4 | initialize, 5 | PerpMarketConfig, 6 | } from '@drift-labs/sdk'; 7 | 8 | export const Config: { 9 | initialized: boolean; 10 | spotMarketsLookup: SpotMarketConfig[]; 11 | perpMarketsLookup: PerpMarketConfig[]; 12 | sdkConfig: ReturnType; 13 | } = { 14 | initialized: false, 15 | spotMarketsLookup: [], 16 | perpMarketsLookup: [], 17 | sdkConfig: undefined, 18 | }; 19 | 20 | export const Initialize = (env: DriftEnv) => { 21 | const SDKConfig = initialize({ env }); 22 | 23 | const maxSpotMarketIndex = Math.max( 24 | ...SDKConfig.SPOT_MARKETS.map((market) => market.marketIndex) 25 | ); 26 | 27 | const maxPerpMarketIndex = Math.max( 28 | ...SDKConfig.PERP_MARKETS.map((market) => market.marketIndex) 29 | ); 30 | 31 | const spotMarkets = new Array(maxSpotMarketIndex); 32 | const markets = new Array(maxPerpMarketIndex); 33 | 34 | SDKConfig.SPOT_MARKETS.forEach((spotMarket) => { 35 | spotMarkets[spotMarket.marketIndex] = spotMarket; 36 | }); 37 | 38 | SDKConfig.PERP_MARKETS.forEach((perpMarket) => { 39 | markets[perpMarket.marketIndex] = perpMarket; 40 | }); 41 | 42 | Config.spotMarketsLookup = spotMarkets; 43 | Config.perpMarketsLookup = markets; 44 | 45 | Config.initialized = true; 46 | 47 | return SDKConfig; 48 | }; 49 | -------------------------------------------------------------------------------- /icons/src/icons/components/NewMarket.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const NewMarket = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | } 36 | {...restProps} 37 | /> 38 | ); 39 | }; 40 | export default NewMarket; 41 | -------------------------------------------------------------------------------- /icons/src/icons/components/Notification.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Notification = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Notification; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Positions.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Positions = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Positions; 29 | -------------------------------------------------------------------------------- /react/src/components/Tables/BodyCellWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { PropsWithChildren } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | import { Typo } from '../Text'; 4 | 5 | export const BodyCellWrapper = ({ 6 | children, 7 | className, 8 | label, 9 | onClick, 10 | dataPuppetTag, 11 | flexCol, 12 | alignCenter, 13 | alignRight, 14 | innerClassName, 15 | }: PropsWithChildren<{ 16 | className?: string; 17 | innerClassName?: string; 18 | label?: string; 19 | onClick?: () => void; 20 | dataPuppetTag?: string; 21 | flexCol?: boolean; 22 | alignCenter?: boolean; 23 | alignRight?: boolean; 24 | }>) => { 25 | return ( 26 |
36 | {label &&
{label}
} 37 | 49 | {children} 50 | 51 |
52 | ); 53 | }; 54 | -------------------------------------------------------------------------------- /icons/src/icons/components/Form.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Form = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Form; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/LP.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const LP = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default LP; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Copy.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Copy = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | } 31 | {...restProps} 32 | /> 33 | ); 34 | }; 35 | export default Copy; 36 | -------------------------------------------------------------------------------- /react/src/components/Tags/Tag.tsx: -------------------------------------------------------------------------------- 1 | import { Typo } from '../Text/Typo'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export type TagColor = 5 | | 'green' 6 | | 'purple' 7 | | 'yellow' 8 | | 'warning' 9 | | 'default' 10 | | 'red'; 11 | 12 | export type TagProps = { 13 | children: React.ReactNode; 14 | color: TagColor; 15 | className?: string; 16 | }; 17 | 18 | const TAG_COLORS: Record = { 19 | green: { 20 | text: 'text-text-positive-green-button', 21 | bg: 'bg-positive-green-secondary-bg', 22 | }, 23 | purple: { 24 | text: 'text-interactive-link', 25 | bg: 'bg-interactive-secondary-bg', 26 | }, 27 | yellow: { text: 'text-yellow-50', bg: 'bg-yellow-50/20' }, 28 | warning: { text: 'text-warn-yellow', bg: 'bg-brand-yellow-secondary-bg' }, 29 | default: { text: 'text-default', bg: 'bg-button-secondary-bg' }, 30 | red: { 31 | text: 'text-text-negative-red-button', 32 | bg: 'bg-negative-red-secondary-bg', 33 | }, 34 | }; 35 | 36 | export const Tag: React.FC = ({ children, color, className }) => { 37 | return ( 38 | 46 | {children} 47 | 48 | ); 49 | }; 50 | 51 | export default Tag; 52 | -------------------------------------------------------------------------------- /icons/src/icons/components/Realms.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Realms = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default Realms; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/Simple.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Simple = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Simple; 29 | -------------------------------------------------------------------------------- /react/src/hooks/useHandleBadRpc.ts: -------------------------------------------------------------------------------- 1 | import { useCurrentRpc } from './useCurrentRpc'; 2 | import { EnvironmentConstants, getResponseTime } from '@drift/common'; 3 | import { useEffect } from 'react'; 4 | import useIsMainnet from './useIsMainnet'; 5 | 6 | const invalidRpcsRef: { current: string[] } = { current: [] }; 7 | 8 | export const useHandleBadRpc = (changeRpcCallback?: () => void) => { 9 | const [currentRpc, setCurrentRpc] = useCurrentRpc(); 10 | 11 | const isMainnet = useIsMainnet(); 12 | 13 | const rpcEndpoints = isMainnet 14 | ? EnvironmentConstants.rpcs.mainnet 15 | : EnvironmentConstants.rpcs.dev; 16 | 17 | useEffect(() => { 18 | const timeout = setTimeout(() => { 19 | if (!currentRpc) return; 20 | 21 | getResponseTime(currentRpc.value).then((responseTime) => { 22 | if (responseTime < 1) { 23 | invalidRpcsRef.current.push(currentRpc.value); 24 | 25 | const otherRpcs = rpcEndpoints.filter( 26 | (rpc) => !invalidRpcsRef.current.includes(rpc.value) 27 | ); 28 | 29 | if (otherRpcs[0]) { 30 | setCurrentRpc(otherRpcs[0]); 31 | changeRpcCallback?.(); 32 | } 33 | 34 | return; 35 | } 36 | }); 37 | }, 3000); // we set a timeout because the saved RPC from the local storage may not be set in state yet 38 | 39 | return () => clearTimeout(timeout); 40 | }, [currentRpc, setCurrentRpc]); 41 | }; 42 | -------------------------------------------------------------------------------- /icons/src/icons/components/Data.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Data = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default Data; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/MouseClick.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const MouseClick = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 26 | 27 | } 28 | {...restProps} 29 | /> 30 | ); 31 | }; 32 | export default MouseClick; 33 | -------------------------------------------------------------------------------- /icons/src/icons/components/Bank.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Bank = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 26 | 27 | } 28 | {...restProps} 29 | /> 30 | ); 31 | }; 32 | export default Bank; 33 | -------------------------------------------------------------------------------- /icons/src/icons/components/History.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const History = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 23 | } 24 | {...restProps} 25 | /> 26 | ); 27 | }; 28 | export default History; 29 | -------------------------------------------------------------------------------- /icons/src/icons/components/Shield.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Shield = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | } 36 | {...restProps} 37 | /> 38 | ); 39 | }; 40 | export default Shield; 41 | -------------------------------------------------------------------------------- /icons/src/icons/components/Discord.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Discord = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Discord; 27 | -------------------------------------------------------------------------------- /icons/src/icons/components/Exponent.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Exponent = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 20 | 21 | } 22 | {...restProps} 23 | /> 24 | ); 25 | }; 26 | export default Exponent; 27 | -------------------------------------------------------------------------------- /common-ts/build-node.js: -------------------------------------------------------------------------------- 1 | const esbuild = require('esbuild'); 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | 5 | function getPackageExternalModules() { 6 | const packageJsonPath = path.resolve(__dirname, 'package.json'); 7 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); 8 | 9 | const dependencyNames = Object.keys(packageJson.dependencies ?? {}); 10 | const peerDependencyNames = Object.keys(packageJson.peerDependencies ?? {}); 11 | 12 | return Array.from(new Set([...dependencyNames, ...peerDependencyNames])); 13 | } 14 | 15 | async function build() { 16 | try { 17 | fs.mkdirSync(path.resolve(__dirname, 'dist'), { recursive: true }); 18 | 19 | await esbuild.build({ 20 | entryPoints: ['./lib/index.js'], 21 | bundle: true, 22 | minify: true, 23 | format: 'cjs', 24 | platform: 'node', 25 | target: ['node22'], 26 | outfile: './dist/node.min.js', 27 | external: getPackageExternalModules(), 28 | define: { 29 | 'process.env.NODE_ENV': '"production"', 30 | }, 31 | loader: { 32 | '.json': 'json', 33 | }, 34 | treeShaking: true, 35 | sourcemap: false, 36 | }); 37 | 38 | console.log('✅ common-ts node minify complete'); 39 | } catch (error) { 40 | console.error('❌ Node minify failed:', error); 41 | process.exit(1); 42 | } 43 | } 44 | 45 | build(); 46 | -------------------------------------------------------------------------------- /icons/src/icons/components/Fuel.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const Fuel = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 22 | 28 | 29 | } 30 | {...restProps} 31 | /> 32 | ); 33 | }; 34 | export default Fuel; 35 | -------------------------------------------------------------------------------- /icons/src/icons/components/NotificationNew.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { IconProps } from '../../types'; 3 | import { IconWrapper } from '../IconWrapper'; 4 | 5 | const NotificationNew = (allProps: IconProps) => { 6 | const { svgProps: props, ...restProps } = allProps; 7 | return ( 8 | 16 | 17 | 21 | 22 | } 23 | {...restProps} 24 | /> 25 | ); 26 | }; 27 | export default NotificationNew; 28 | --------------------------------------------------------------------------------