Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,34 @@ called out explicitly even when nothing else did.
release notes, so a version with no entry here does not release. Write the entry in the same PR that
syncs the contract, while the diff is still in front of you.

## 0.6.0

Synced to [`ocp-protobuf-api@e3d25a85`](https://github.com/code-payments/ocp-protobuf-api/commit/e3d25a85b1e1ce088e956714e1a71248322e215f),
picking up [#67](https://github.com/code-payments/ocp-protobuf-api/pull/67) (docs only) and
[#68](https://github.com/code-payments/ocp-protobuf-api/pull/68). Only `balance.v1` moved.

`GetBalances` can now report fiat values alongside core-mint values. The change is opt-in per
request, so the upgrade is free: a caller that sends no currency codes gets exactly what it got
before.

### Added

- `GetBalancesRequest.currency_codes` (field 3), a `repeated string` of lowercase ISO 4217 codes
such as `"usd"`. At most 256, no duplicates, each matching `^[a-z]{3,4}$`. Empty means core-mint
values only.
- `OwnerBalance.fiat_values_by_currency` (field 4), a `map<string, double>` holding the owner's
total across all balances, keyed by currency code.
- `MintBalance.fiat_values_by_currency` (field 3), the same map for a single mint's balance.

Both maps are populated only for the codes the request asked for. A code the caller did not request
is absent, not zero.

### Unchanged

Nothing was renumbered, and nothing existing changed type or meaning. The new fields take the next
free number in each message. No service, RPC, message or enum case was removed. Everything else in
the diff is comments.

## 0.5.0

No contract change. Still synced to
Expand Down
2 changes: 1 addition & 1 deletion Sources/OCPClientProtocol/ContractInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public enum OCPContractInfo {
public static let version = "0.5.0-dev"
public static let protoCommit = "82202912574e122bba90025fe8b292d5a3f04c05"
public static let protoCommit = "e3d25a85b1e1ce088e956714e1a71248322e215f"

public static var isLocal: Bool { protoCommit == localSentinel }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ extension Ocp_Balance_V1_Balance {
/// > Source IDL Documentation:
/// >
/// > GetBalances returns balance data for a set of owner accounts, optionally
/// > filtered by a set of mints
/// > filtered by a set of mints. Balances are always denominated in the core
/// > mint, and can additionally be denominated in a set of fiat currencies.
///
/// - Parameters:
/// - request: A request containing a single `Ocp_Balance_V1_GetBalancesRequest` message.
Expand Down Expand Up @@ -100,7 +101,8 @@ extension Ocp_Balance_V1_Balance {
/// > Source IDL Documentation:
/// >
/// > GetBalances returns balance data for a set of owner accounts, optionally
/// > filtered by a set of mints
/// > filtered by a set of mints. Balances are always denominated in the core
/// > mint, and can additionally be denominated in a set of fiat currencies.
///
/// - Parameters:
/// - request: A request containing a single `Ocp_Balance_V1_GetBalancesRequest` message.
Expand Down Expand Up @@ -140,7 +142,8 @@ extension Ocp_Balance_V1_Balance.ClientProtocol {
/// > Source IDL Documentation:
/// >
/// > GetBalances returns balance data for a set of owner accounts, optionally
/// > filtered by a set of mints
/// > filtered by a set of mints. Balances are always denominated in the core
/// > mint, and can additionally be denominated in a set of fiat currencies.
///
/// - Parameters:
/// - request: A request containing a single `Ocp_Balance_V1_GetBalancesRequest` message.
Expand Down Expand Up @@ -174,7 +177,8 @@ extension Ocp_Balance_V1_Balance.ClientProtocol {
/// > Source IDL Documentation:
/// >
/// > GetBalances returns balance data for a set of owner accounts, optionally
/// > filtered by a set of mints
/// > filtered by a set of mints. Balances are always denominated in the core
/// > mint, and can additionally be denominated in a set of fiat currencies.
///
/// - Parameters:
/// - message: request message to send.
Expand Down
36 changes: 33 additions & 3 deletions Sources/OCPClientProtocol/balance_v1_ocp_balance_service.pb.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public struct Ocp_Balance_V1_GetBalancesRequest: Sendable {
/// When empty, balances for all mints held by each owner are returned.
public var mints: [Ocp_Common_V1_SolanaAccountId] = []

/// Optional set of ISO 4217 alpha-3 currency codes (e.g., "usd") to also
/// denominate balance values in, in addition to the core mint value. When
/// empty, only core mint values are returned.
public var currencyCodes: [String] = []

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand Down Expand Up @@ -107,6 +112,11 @@ public struct Ocp_Balance_V1_OwnerBalance: Sendable {
/// Individual balances keyed by mint address
public var balancesByMint: Dictionary<String,Ocp_Balance_V1_MintBalance> = [:]

/// The total fiat value across all balances for the owner, keyed by currency
/// code. Only populated for the currency codes requested in
/// GetBalancesRequest.currency_codes.
public var fiatValuesByCurrency: Dictionary<String,Double> = [:]

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand All @@ -132,6 +142,11 @@ public struct Ocp_Balance_V1_MintBalance: Sendable {
/// The balance value, in quarks, denominated in the core mint
public var coreMintValue: UInt64 = 0

/// The balance value denominated in fiat, keyed by currency code. Only
/// populated for the currency codes requested in
/// GetBalancesRequest.currency_codes.
public var fiatValuesByCurrency: Dictionary<String,Double> = [:]

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand All @@ -145,7 +160,7 @@ fileprivate let _protobuf_package = "ocp.balance.v1"

extension Ocp_Balance_V1_GetBalancesRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".GetBalancesRequest"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}owners\0\u{1}mints\0")
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}owners\0\u{1}mints\0\u{3}currency_codes\0")

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
Expand All @@ -155,6 +170,7 @@ extension Ocp_Balance_V1_GetBalancesRequest: SwiftProtobuf.Message, SwiftProtobu
switch fieldNumber {
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.owners) }()
case 2: try { try decoder.decodeRepeatedMessageField(value: &self.mints) }()
case 3: try { try decoder.decodeRepeatedStringField(value: &self.currencyCodes) }()
default: break
}
}
Expand All @@ -167,12 +183,16 @@ extension Ocp_Balance_V1_GetBalancesRequest: SwiftProtobuf.Message, SwiftProtobu
if !self.mints.isEmpty {
try visitor.visitRepeatedMessageField(value: self.mints, fieldNumber: 2)
}
if !self.currencyCodes.isEmpty {
try visitor.visitRepeatedStringField(value: self.currencyCodes, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Ocp_Balance_V1_GetBalancesRequest, rhs: Ocp_Balance_V1_GetBalancesRequest) -> Bool {
if lhs.owners != rhs.owners {return false}
if lhs.mints != rhs.mints {return false}
if lhs.currencyCodes != rhs.currencyCodes {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
Expand Down Expand Up @@ -219,7 +239,7 @@ extension Ocp_Balance_V1_GetBalancesResponse.Result: SwiftProtobuf._ProtoNamePro

extension Ocp_Balance_V1_OwnerBalance: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".OwnerBalance"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}owner\0\u{3}core_mint_value\0\u{3}balances_by_mint\0")
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}owner\0\u{3}core_mint_value\0\u{3}balances_by_mint\0\u{3}fiat_values_by_currency\0")

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
Expand All @@ -230,6 +250,7 @@ extension Ocp_Balance_V1_OwnerBalance: SwiftProtobuf.Message, SwiftProtobuf._Mes
case 1: try { try decoder.decodeSingularMessageField(value: &self._owner) }()
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.coreMintValue) }()
case 3: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMessageMap<SwiftProtobuf.ProtobufString,Ocp_Balance_V1_MintBalance>.self, value: &self.balancesByMint) }()
case 4: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap<SwiftProtobuf.ProtobufString,SwiftProtobuf.ProtobufDouble>.self, value: &self.fiatValuesByCurrency) }()
default: break
}
}
Expand All @@ -249,21 +270,25 @@ extension Ocp_Balance_V1_OwnerBalance: SwiftProtobuf.Message, SwiftProtobuf._Mes
if !self.balancesByMint.isEmpty {
try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMessageMap<SwiftProtobuf.ProtobufString,Ocp_Balance_V1_MintBalance>.self, value: self.balancesByMint, fieldNumber: 3)
}
if !self.fiatValuesByCurrency.isEmpty {
try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap<SwiftProtobuf.ProtobufString,SwiftProtobuf.ProtobufDouble>.self, value: self.fiatValuesByCurrency, fieldNumber: 4)
}
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Ocp_Balance_V1_OwnerBalance, rhs: Ocp_Balance_V1_OwnerBalance) -> Bool {
if lhs._owner != rhs._owner {return false}
if lhs.coreMintValue != rhs.coreMintValue {return false}
if lhs.balancesByMint != rhs.balancesByMint {return false}
if lhs.fiatValuesByCurrency != rhs.fiatValuesByCurrency {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

extension Ocp_Balance_V1_MintBalance: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".MintBalance"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}mint\0\u{3}core_mint_value\0")
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}mint\0\u{3}core_mint_value\0\u{3}fiat_values_by_currency\0")

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
Expand All @@ -273,6 +298,7 @@ extension Ocp_Balance_V1_MintBalance: SwiftProtobuf.Message, SwiftProtobuf._Mess
switch fieldNumber {
case 1: try { try decoder.decodeSingularMessageField(value: &self._mint) }()
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.coreMintValue) }()
case 3: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap<SwiftProtobuf.ProtobufString,SwiftProtobuf.ProtobufDouble>.self, value: &self.fiatValuesByCurrency) }()
default: break
}
}
Expand All @@ -289,12 +315,16 @@ extension Ocp_Balance_V1_MintBalance: SwiftProtobuf.Message, SwiftProtobuf._Mess
if self.coreMintValue != 0 {
try visitor.visitSingularUInt64Field(value: self.coreMintValue, fieldNumber: 2)
}
if !self.fiatValuesByCurrency.isEmpty {
try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap<SwiftProtobuf.ProtobufString,SwiftProtobuf.ProtobufDouble>.self, value: self.fiatValuesByCurrency, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Ocp_Balance_V1_MintBalance, rhs: Ocp_Balance_V1_MintBalance) -> Bool {
if lhs._mint != rhs._mint {return false}
if lhs.coreMintValue != rhs.coreMintValue {return false}
if lhs.fiatValuesByCurrency != rhs.fiatValuesByCurrency {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
Expand Down
4 changes: 2 additions & 2 deletions ocp.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Pinned upstream contract. Regenerate with scripts/sync-protos.sh <sha>.
upstream: code-payments/ocp-protobuf-api
commit: 82202912574e122bba90025fe8b292d5a3f04c05
subject: Remove GetBalance RPC in favour of GetBalances (#66)
commit: e3d25a85b1e1ce088e956714e1a71248322e215f
subject: GetBalance now supports balance values across many fiat currencies (#68)
26 changes: 25 additions & 1 deletion proto/balance/v1/ocp_balance_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import "validate/validate.proto";

service Balance {
// GetBalances returns balance data for a set of owner accounts, optionally
// filtered by a set of mints
// filtered by a set of mints. Balances are always denominated in the core
// mint, and can additionally be denominated in a set of fiat currencies.
rpc GetBalances(GetBalancesRequest) returns (GetBalancesResponse);
}

Expand All @@ -27,6 +28,19 @@ message GetBalancesRequest {
repeated common.v1.SolanaAccountId mints = 2 [(validate.rules).repeated = {
max_items: 1024 // Arbitrary
}];

// Optional set of ISO 4217 alpha-3 currency codes (e.g., "usd") to also
// denominate balance values in, in addition to the core mint value. When
// empty, only core mint values are returned.
repeated string currency_codes = 3 [(validate.rules).repeated = {
max_items: 256
unique: true
items: {
string: {
pattern: "^[a-z]{3,4}$"
}
}
}];
}

message GetBalancesResponse {
Expand All @@ -49,6 +63,11 @@ message OwnerBalance {

// Individual balances keyed by mint address
map<string, MintBalance> balances_by_mint = 3;

// The total fiat value across all balances for the owner, keyed by currency
// code. Only populated for the currency codes requested in
// GetBalancesRequest.currency_codes.
map<string, double> fiat_values_by_currency = 4;
}

message MintBalance {
Expand All @@ -57,4 +76,9 @@ message MintBalance {

// The balance value, in quarks, denominated in the core mint
uint64 core_mint_value = 2;

// The balance value denominated in fiat, keyed by currency code. Only
// populated for the currency codes requested in
// GetBalancesRequest.currency_codes.
map<string, double> fiat_values_by_currency = 3;
}
Loading