diff --git a/Features/Perpetuals/Sources/ViewModels/PerpetualPositionViewModel.swift b/Features/Perpetuals/Sources/ViewModels/PerpetualPositionViewModel.swift index a9ccd5b8b..7c943bd2b 100644 --- a/Features/Perpetuals/Sources/ViewModels/PerpetualPositionViewModel.swift +++ b/Features/Perpetuals/Sources/ViewModels/PerpetualPositionViewModel.swift @@ -30,7 +30,7 @@ public struct PerpetualPositionViewModel { } public var nameText: String { - data.asset.name + data.perpetual.name } public var symbolText: String { diff --git a/Features/Perpetuals/Sources/ViewModels/PerpetualSceneViewModel.swift b/Features/Perpetuals/Sources/ViewModels/PerpetualSceneViewModel.swift index a95a00154..99894d3fe 100644 --- a/Features/Perpetuals/Sources/ViewModels/PerpetualSceneViewModel.swift +++ b/Features/Perpetuals/Sources/ViewModels/PerpetualSceneViewModel.swift @@ -122,7 +122,7 @@ public final class PerpetualSceneViewModel { } } - private var currentChartSubscription: ChartSubscription { ChartSubscription(coin: perpetual.name, period: currentPeriod) } + private var currentChartSubscription: ChartSubscription { ChartSubscription(coin: perpetual.coin, period: currentPeriod) } } // MARK: - Actions @@ -130,7 +130,7 @@ public final class PerpetualSceneViewModel { public extension PerpetualSceneViewModel { func fetch() { Task { await observerService.update(for: wallet) } - Task { try await perpetualService.updateMarket(symbol: perpetual.name) } + Task { try await perpetualService.updateMarket(symbol: perpetual.coin) } Task { await fetchTransactions() } Task { await updateCandlesticks() } } @@ -152,7 +152,7 @@ public extension PerpetualSceneViewModel { func onScenePhaseChange(_ oldPhase: ScenePhase, _ newPhase: ScenePhase) { switch newPhase { case .active: - Task { try? await perpetualService.updateMarket(symbol: perpetual.name) } + Task { try? await perpetualService.updateMarket(symbol: perpetual.coin) } Task { await fetchTransactions() } Task { await updateCandlesticks() } case .inactive, .background: break @@ -162,9 +162,9 @@ public extension PerpetualSceneViewModel { func onPeriodChange(_ oldPeriod: ChartPeriod, _ newPeriod: ChartPeriod) { Task { - await unsubscribeCandles(ChartSubscription(coin: perpetual.name, period: oldPeriod)) + await unsubscribeCandles(ChartSubscription(coin: perpetual.coin, period: oldPeriod)) await updateCandlesticks() - await subscribeCandles(ChartSubscription(coin: perpetual.name, period: newPeriod)) + await subscribeCandles(ChartSubscription(coin: perpetual.coin, period: newPeriod)) } } @@ -223,7 +223,8 @@ public extension PerpetualSceneViewModel { func onOpenLongPosition() { guard let transferData = createTransferData( direction: .long, - leverage: perpetual.maxLeverage + leverage: perpetual.maxLeverage, + marginType: perpetual.marginType ) else { return } @@ -233,7 +234,8 @@ public extension PerpetualSceneViewModel { func onOpenShortPosition() { guard let transferData = createTransferData( direction: .short, - leverage: perpetual.maxLeverage + leverage: perpetual.maxLeverage, + marginType: perpetual.marginType ) else { return } @@ -244,7 +246,7 @@ public extension PerpetualSceneViewModel { isPresentingModifyAlert = false guard let position = positions.first?.position, - let transferData = createTransferData(direction: position.direction, leverage: position.leverage) + let transferData = createTransferData(direction: position.direction, leverage: position.leverage, marginType: position.marginType) else { return } onPositionAction(.increase(transferData)) @@ -264,7 +266,7 @@ public extension PerpetualSceneViewModel { } }() - guard let transferData = createTransferData(direction: direction, leverage: position.leverage) else { + guard let transferData = createTransferData(direction: direction, leverage: position.leverage, marginType: position.marginType) else { return } @@ -289,7 +291,7 @@ private extension PerpetualSceneViewModel { state = .loading do { let candlesticks = try await perpetualService.candlesticks( - symbol: perpetual.name, + symbol: perpetual.coin, period: currentPeriod ) state = .data(candlesticks) @@ -341,7 +343,7 @@ private extension PerpetualSceneViewModel { state = .data(candlesticks) } - func createTransferData(direction: PerpetualDirection, leverage: UInt8) -> PerpetualTransferData? { + func createTransferData(direction: PerpetualDirection, leverage: UInt8, marginType: PerpetualMarginType) -> PerpetualTransferData? { guard let assetIndex = Int(perpetual.identifier) else { return nil } @@ -353,7 +355,8 @@ private extension PerpetualSceneViewModel { baseAsset: .hypercoreUSDC(), assetIndex: assetIndex, price: perpetual.price, - leverage: leverage + leverage: leverage, + marginType: marginType ) } diff --git a/Features/Perpetuals/TestKit/Perpetual+TestKit.swift b/Features/Perpetuals/TestKit/Perpetual+TestKit.swift index 5326e687f..a45f75964 100644 --- a/Features/Perpetuals/TestKit/Perpetual+TestKit.swift +++ b/Features/Perpetuals/TestKit/Perpetual+TestKit.swift @@ -28,7 +28,8 @@ public extension Perpetual { openInterest: openInterest, volume24h: volume24h, funding: funding, - maxLeverage: maxLeverage + maxLeverage: maxLeverage, + onlyIsolated: false ) } } diff --git a/Packages/FeatureServices/PerpetualService/PerpetualOrderFactory.swift b/Packages/FeatureServices/PerpetualService/PerpetualOrderFactory.swift index 8922d3bd2..075e3d037 100644 --- a/Packages/FeatureServices/PerpetualService/PerpetualOrderFactory.swift +++ b/Packages/FeatureServices/PerpetualService/PerpetualOrderFactory.swift @@ -40,6 +40,7 @@ public struct PerpetualOrderFactory { let data = makePerpetualConfirmData( direction: perpetual.direction, + marginType: perpetual.marginType, baseAsset: perpetual.baseAsset, fiatValue: fiatValue, assetIndex: Int32(perpetual.assetIndex), @@ -81,6 +82,7 @@ public struct PerpetualOrderFactory { return makePerpetualConfirmData( direction: position.direction, + marginType: position.marginType, baseAsset: baseAsset, fiatValue: abs(position.size) * positionPrice, assetIndex: assetIndex, @@ -115,6 +117,7 @@ public struct PerpetualOrderFactory { private func makePerpetualConfirmData( direction: PerpetualDirection, + marginType: PerpetualMarginType, baseAsset: Asset, fiatValue: Double, assetIndex: Int32, @@ -143,6 +146,7 @@ public struct PerpetualOrderFactory { return PerpetualConfirmData( direction: direction, + marginType: marginType, baseAsset: baseAsset, assetIndex: assetIndex, price: price, diff --git a/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetual+GemstonePrimitives.swift b/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetual+GemstonePrimitives.swift index 2f51b5a8f..2389234bd 100644 --- a/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetual+GemstonePrimitives.swift +++ b/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetual+GemstonePrimitives.swift @@ -17,7 +17,8 @@ extension GemPerpetual { openInterest: openInterest, volume24h: volume24h, funding: funding, - maxLeverage: maxLeverage + maxLeverage: maxLeverage, + onlyIsolated: onlyIsolated ) } } diff --git a/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetualConfirmData+GemstonePrimitives.swift b/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetualConfirmData+GemstonePrimitives.swift index f7a2cf593..586f4fe55 100644 --- a/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetualConfirmData+GemstonePrimitives.swift +++ b/Packages/GemstonePrimitives/Sources/Extensions/GemPerpetualConfirmData+GemstonePrimitives.swift @@ -8,6 +8,7 @@ extension Gemstone.PerpetualConfirmData { public func map() throws -> Primitives.PerpetualConfirmData { Primitives.PerpetualConfirmData( direction: direction.map(), + marginType: marginType.map(), baseAsset: try baseAsset.map(), assetIndex: assetIndex, price: price, @@ -29,6 +30,7 @@ extension Primitives.PerpetualConfirmData { public func map() -> Gemstone.PerpetualConfirmData { Gemstone.PerpetualConfirmData( direction: direction.map(), + marginType: marginType.map(), baseAsset: baseAsset.map(), assetIndex: assetIndex, price: price, diff --git a/Packages/Primitives/Sources/Extensions/Perpetual+Primitives.swift b/Packages/Primitives/Sources/Extensions/Perpetual+Primitives.swift index de30ac408..eaac9285c 100644 --- a/Packages/Primitives/Sources/Extensions/Perpetual+Primitives.swift +++ b/Packages/Primitives/Sources/Extensions/Perpetual+Primitives.swift @@ -22,6 +22,14 @@ extension PerpetualDirection { } } +extension Perpetual { + public var coin: String { + assetId.tokenId?.components(separatedBy: AssetId.subTokenSeparator).last ?? name + } + + public var marginType: PerpetualMarginType { onlyIsolated ? .isolated : .cross } +} + extension PerpetualSearchData { public var assetBasic: AssetBasic { AssetBasic( diff --git a/Packages/Primitives/Sources/Perpetual.swift b/Packages/Primitives/Sources/Perpetual.swift index 65fee99f7..340c069ee 100644 --- a/Packages/Primitives/Sources/Perpetual.swift +++ b/Packages/Primitives/Sources/Perpetual.swift @@ -55,8 +55,9 @@ public struct Perpetual: Codable, Equatable, Hashable, Sendable { public let volume24h: Double public let funding: Double public let maxLeverage: UInt8 + public let onlyIsolated: Bool - public init(id: String, name: String, provider: PerpetualProvider, assetId: AssetId, identifier: String, price: Double, pricePercentChange24h: Double, openInterest: Double, volume24h: Double, funding: Double, maxLeverage: UInt8) { + public init(id: String, name: String, provider: PerpetualProvider, assetId: AssetId, identifier: String, price: Double, pricePercentChange24h: Double, openInterest: Double, volume24h: Double, funding: Double, maxLeverage: UInt8, onlyIsolated: Bool) { self.id = id self.name = name self.provider = provider @@ -68,6 +69,7 @@ public struct Perpetual: Codable, Equatable, Hashable, Sendable { self.volume24h = volume24h self.funding = funding self.maxLeverage = maxLeverage + self.onlyIsolated = onlyIsolated } } @@ -97,6 +99,7 @@ public struct PerpetualBasic: Codable, Equatable, Hashable, Sendable { public struct PerpetualConfirmData: Codable, Equatable, Hashable, Sendable { public let direction: PerpetualDirection + public let marginType: PerpetualMarginType public let baseAsset: Asset public let assetIndex: Int32 public let price: String @@ -111,8 +114,9 @@ public struct PerpetualConfirmData: Codable, Equatable, Hashable, Sendable { public let takeProfit: String? public let stopLoss: String? - public init(direction: PerpetualDirection, baseAsset: Asset, assetIndex: Int32, price: String, fiatValue: Double, size: String, slippage: Double, leverage: UInt8, pnl: Double?, entryPrice: Double?, marketPrice: Double, marginAmount: Double, takeProfit: String?, stopLoss: String?) { + public init(direction: PerpetualDirection, marginType: PerpetualMarginType, baseAsset: Asset, assetIndex: Int32, price: String, fiatValue: Double, size: String, slippage: Double, leverage: UInt8, pnl: Double?, entryPrice: Double?, marketPrice: Double, marginAmount: Double, takeProfit: String?, stopLoss: String?) { self.direction = direction + self.marginType = marginType self.baseAsset = baseAsset self.assetIndex = assetIndex self.price = price diff --git a/Packages/Primitives/Sources/PerpetualTransferData.swift b/Packages/Primitives/Sources/PerpetualTransferData.swift index 3d5b96b5a..285bbd51d 100644 --- a/Packages/Primitives/Sources/PerpetualTransferData.swift +++ b/Packages/Primitives/Sources/PerpetualTransferData.swift @@ -39,6 +39,7 @@ public struct PerpetualTransferData: Codable, Equatable, Hashable, Sendable { public let assetIndex: Int public let price: Double public let leverage: UInt8 + public let marginType: PerpetualMarginType public init( provider: PerpetualProvider, @@ -47,7 +48,8 @@ public struct PerpetualTransferData: Codable, Equatable, Hashable, Sendable { baseAsset: Asset, assetIndex: Int, price: Double, - leverage: UInt8 + leverage: UInt8, + marginType: PerpetualMarginType ) { self.provider = provider self.direction = direction @@ -56,6 +58,7 @@ public struct PerpetualTransferData: Codable, Equatable, Hashable, Sendable { self.assetIndex = assetIndex self.price = price self.leverage = leverage + self.marginType = marginType } } diff --git a/Packages/Primitives/TestKit/Perpetual+PrimitivesTestKit.swift b/Packages/Primitives/TestKit/Perpetual+PrimitivesTestKit.swift index 42ff75490..0cda77741 100644 --- a/Packages/Primitives/TestKit/Perpetual+PrimitivesTestKit.swift +++ b/Packages/Primitives/TestKit/Perpetual+PrimitivesTestKit.swift @@ -27,7 +27,8 @@ public extension Perpetual { openInterest: openInterest, volume24h: volume24h, funding: funding, - maxLeverage: maxLeverage + maxLeverage: maxLeverage, + onlyIsolated: false ) } } diff --git a/Packages/Primitives/TestKit/PerpetualConfirmData+PrimitivesTestKit.swift b/Packages/Primitives/TestKit/PerpetualConfirmData+PrimitivesTestKit.swift index 79f1a5316..a5752913b 100644 --- a/Packages/Primitives/TestKit/PerpetualConfirmData+PrimitivesTestKit.swift +++ b/Packages/Primitives/TestKit/PerpetualConfirmData+PrimitivesTestKit.swift @@ -6,6 +6,7 @@ import Primitives public extension PerpetualConfirmData { static func mock( direction: PerpetualDirection = .long, + marginType: PerpetualMarginType = .cross, baseAsset: Asset = .mock(), assetIndex: Int32 = 0, price: String = "100", @@ -22,6 +23,7 @@ public extension PerpetualConfirmData { ) -> PerpetualConfirmData { PerpetualConfirmData( direction: direction, + marginType: marginType, baseAsset: baseAsset, assetIndex: assetIndex, price: price, diff --git a/Packages/Primitives/TestKit/PerpetualTransferData+PrimitivesTestKit.swift b/Packages/Primitives/TestKit/PerpetualTransferData+PrimitivesTestKit.swift index 01d3e95d3..fac2887bb 100644 --- a/Packages/Primitives/TestKit/PerpetualTransferData+PrimitivesTestKit.swift +++ b/Packages/Primitives/TestKit/PerpetualTransferData+PrimitivesTestKit.swift @@ -11,7 +11,8 @@ public extension PerpetualTransferData { baseAsset: Asset = .mock(), assetIndex: Int = 0, price: Double = 100.0, - leverage: UInt8 = 3 + leverage: UInt8 = 3, + marginType: PerpetualMarginType = .cross ) -> PerpetualTransferData { PerpetualTransferData( provider: provider, @@ -20,7 +21,8 @@ public extension PerpetualTransferData { baseAsset: baseAsset, assetIndex: assetIndex, price: price, - leverage: leverage + leverage: leverage, + marginType: marginType ) } } diff --git a/Packages/Store/Sources/Migrations.swift b/Packages/Store/Sources/Migrations.swift index d01f84fad..75a55ab83 100644 --- a/Packages/Store/Sources/Migrations.swift +++ b/Packages/Store/Sources/Migrations.swift @@ -451,6 +451,14 @@ struct Migrations { } } + migrator.registerMigration("Add onlyIsolated to \(PerpetualRecord.databaseTableName)") { db in + try? db.alter(table: PerpetualRecord.databaseTableName) { + $0.add(column: PerpetualRecord.Columns.onlyIsolated.name, .boolean) + .notNull() + .defaults(to: false) + } + } + try migrator.migrate(dbQueue) } } diff --git a/Packages/Store/Sources/Models/PerpetualRecord.swift b/Packages/Store/Sources/Models/PerpetualRecord.swift index 27b96f175..78bba95be 100644 --- a/Packages/Store/Sources/Models/PerpetualRecord.swift +++ b/Packages/Store/Sources/Models/PerpetualRecord.swift @@ -19,6 +19,7 @@ struct PerpetualRecord: Codable, TableRecord, FetchableRecord, PersistableRecord static let volume24h = Column("volume24h") static let funding = Column("funding") static let maxLeverage = Column("maxLeverage") + static let onlyIsolated = Column("onlyIsolated") static let isPinned = Column("isPinned") } @@ -33,6 +34,7 @@ struct PerpetualRecord: Codable, TableRecord, FetchableRecord, PersistableRecord var volume24h: Double var funding: Double var maxLeverage: UInt8 + var onlyIsolated: Bool var isPinned: Bool init( @@ -47,6 +49,7 @@ struct PerpetualRecord: Codable, TableRecord, FetchableRecord, PersistableRecord volume24h: Double, funding: Double, maxLeverage: UInt8, + onlyIsolated: Bool = false, isPinned: Bool = false ) { self.id = id @@ -60,6 +63,7 @@ struct PerpetualRecord: Codable, TableRecord, FetchableRecord, PersistableRecord self.volume24h = volume24h self.funding = funding self.maxLeverage = maxLeverage + self.onlyIsolated = onlyIsolated self.isPinned = isPinned } @@ -83,6 +87,7 @@ extension PerpetualRecord: CreateTable { $0.column(Columns.volume24h.name, .double).notNull() $0.column(Columns.funding.name, .double).notNull() $0.column(Columns.maxLeverage.name, .integer).notNull() + $0.column(Columns.onlyIsolated.name, .boolean).notNull().defaults(to: false) $0.column(Columns.isPinned.name, .boolean).notNull().defaults(to: false) } } @@ -101,7 +106,8 @@ extension PerpetualRecord { openInterest: openInterest, volume24h: volume24h, funding: funding, - maxLeverage: maxLeverage + maxLeverage: maxLeverage, + onlyIsolated: onlyIsolated ) } } @@ -119,7 +125,8 @@ extension Perpetual { openInterest: openInterest, volume24h: volume24h, funding: funding, - maxLeverage: maxLeverage + maxLeverage: maxLeverage, + onlyIsolated: onlyIsolated ) } } diff --git a/Packages/Store/Sources/Requests/Perpetuals/PerpetualRequest.swift b/Packages/Store/Sources/Requests/Perpetuals/PerpetualRequest.swift index 26eee95a9..b0e0d4a40 100644 --- a/Packages/Store/Sources/Requests/Perpetuals/PerpetualRequest.swift +++ b/Packages/Store/Sources/Requests/Perpetuals/PerpetualRequest.swift @@ -42,7 +42,8 @@ extension PerpetualData { openInterest: .zero, volume24h: .zero, funding: .zero, - maxLeverage: 1 + maxLeverage: 1, + onlyIsolated: false ), asset: Asset(id: .init(chain: .bitcoin, tokenId: .none), name: "", symbol: "", decimals: 0, type: .native), metadata: PerpetualMetadata(isPinned: false) diff --git a/core b/core index 2c164baa7..a24d0467b 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 2c164baa7fd80fe1d8737c0b74feac2dde16801c +Subproject commit a24d0467b741815338a7ca15c47a2eecffa756c3