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
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,36 @@ 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.9.0

Synced to [`ocp-protobuf-api@98cf14de`](https://github.com/code-payments/ocp-protobuf-api/commit/98cf14de185d5abadf6f03b6802ff298f61610d0),
picking up [#71](https://github.com/code-payments/ocp-protobuf-api/pull/71). Only `transaction.v1` moved.

Stablecoin swaps can now use CoinbaseStableSwapper's `swap_v2` instruction, which is `swap` without
the deprecated whitelist account. The field is additive, so upgrading changes nothing until a client
sets it.

### Added

- `swap_version` (`uint32`, at most 2) on the CoinbaseStableSwapper initiate parameters of
`StatefulSwapRequest` (field 9) and `StatelessSwapRequest` (field 4). Only `2` selects `swap_v2`.
Unset, `0` and `1` keep the legacy `swap` instruction.
- The server builds the swap instruction from this field, and the client rebuilds and signs the
same transaction locally. A client that sends `2` has to build `swap_v2` itself: discriminator
`[43, 4, 237, 11, 26, 201, 30, 98]`, the same `amount_in` and `min_amount_out` args, and `swap`'s
accounts with the whitelist (index 12) removed. If the field and the local instruction disagree,
the swap fails.

### Changed

- Comments only: the CoinbaseStableSwapper server parameters on `StatefulSwapResponse` and
`StatelessSwapResponse` now list the swap step as `Swap` or `SwapV2`, per `swap_version`.

### Unchanged

Nothing was renumbered, and nothing existing changed type or meaning. No service, RPC, message or
enum case was removed.

## 0.8.0

Synced to [`ocp-protobuf-api@6f70c0d8`](https://github.com/code-payments/ocp-protobuf-api/commit/6f70c0d8e832531fd006bbb02fcb2c5d07e0c247),
Expand Down
4 changes: 2 additions & 2 deletions Sources/OCPClientProtocol/ContractInfo.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Generated by scripts/generate-swift.sh. Do not edit.

public enum OCPContractInfo {
public static let version = "0.8.0-dev"
public static let protoCommit = "6f70c0d8e832531fd006bbb02fcb2c5d07e0c247"
public static let version = "0.9.0-dev"
public static let protoCommit = "98cf14de185d5abadf6f03b6802ff298f61610d0"

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,11 @@ public struct Ocp_Transaction_V1_StatefulSwapRequest: Sendable {
/// CanWithdrawToAccountResponse.fee_amount
public var feeAmount: UInt64 = 0

/// The CoinbaseStableSwapper swap instruction version the client will
/// use when constructing the transaction. 2 uses SwapV2. Any other value,
/// including unset, uses the legacy Swap instruction.
public var swapVersion: UInt32 = 0

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand Down Expand Up @@ -1462,7 +1467,7 @@ public struct Ocp_Transaction_V1_StatefulSwapResponse: Sendable {
/// 5. AssociatedTokenAccount::CreateIdempotent (open swap authority's from_mint ATA)
/// 6. AssociatedTokenAccount::CreateIdempotent (open destination owner's to_mint ATA)
/// 7. VM::TransferForSwapWithFee (from_mint VM swap ATA -> swap authority's from_mint ATA (swap amount) and fee destination (fee amount))
/// 8. CoinbaseStableSwapper::Swap (from_mint swap authority ATA -> to_mint destination owner ATA)
/// 8. CoinbaseStableSwapper::Swap or CoinbaseStableSwapper::SwapV2, per client swap_version (from_mint swap authority ATA -> to_mint destination owner ATA)
/// 9. Token::CloseAccount (closes swap authority's from_mint ATA)
public struct CoinbaseStableSwapperServerParameter: Sendable {
// SwiftProtobuf.Message conformance is added in an extension below. See the
Expand Down Expand Up @@ -1766,6 +1771,11 @@ public struct Ocp_Transaction_V1_StatelessSwapRequest: Sendable {
/// The amount to swap from the source mint in quarks.
public var swapAmount: UInt64 = 0

/// The CoinbaseStableSwapper swap instruction version the client will
/// use when constructing the transaction. 2 uses SwapV2. Any other value,
/// including unset, uses the legacy Swap instruction.
public var swapVersion: UInt32 = 0

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand Down Expand Up @@ -1868,7 +1878,7 @@ public struct Ocp_Transaction_V1_StatelessSwapResponse: Sendable {
/// 2. [Optional] ComputeBudget::SetComputeUnitPrice
/// 3. [Optional] Memo::Memo
/// 4. AssociatedTokenAccount::CreateIdempotent (open owner's to_mint VM Deposit ATA)
/// 5. CoinbaseStableSwapper::Swap (owner's from_mint ATA -> owner's to_mint VM Deposit ATA)
/// 5. CoinbaseStableSwapper::Swap or CoinbaseStableSwapper::SwapV2, per client swap_version (owner's from_mint ATA -> owner's to_mint VM Deposit ATA)
public struct CoinbaseStableSwapperServerParameter: Sendable {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
Expand Down Expand Up @@ -4756,7 +4766,7 @@ extension Ocp_Transaction_V1_StatefulSwapRequest.Initiate.ReserveSwapClientParam

extension Ocp_Transaction_V1_StatefulSwapRequest.Initiate.CoinbaseStableSwapperClientParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = Ocp_Transaction_V1_StatefulSwapRequest.Initiate.protoMessageName + ".CoinbaseStableSwapperClientParameters"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{3}from_mint\0\u{3}to_mint\0\u{3}swap_amount\0\u{3}funding_source\0\u{3}funding_id\0\u{3}destination_owner\0\u{3}fee_amount\0")
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{3}from_mint\0\u{3}to_mint\0\u{3}swap_amount\0\u{3}funding_source\0\u{3}funding_id\0\u{3}destination_owner\0\u{3}fee_amount\0\u{3}swap_version\0")

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
Expand All @@ -4772,6 +4782,7 @@ extension Ocp_Transaction_V1_StatefulSwapRequest.Initiate.CoinbaseStableSwapperC
case 6: try { try decoder.decodeSingularStringField(value: &self.fundingID) }()
case 7: try { try decoder.decodeSingularMessageField(value: &self._destinationOwner) }()
case 8: try { try decoder.decodeSingularUInt64Field(value: &self.feeAmount) }()
case 9: try { try decoder.decodeSingularUInt32Field(value: &self.swapVersion) }()
default: break
}
}
Expand Down Expand Up @@ -4806,6 +4817,9 @@ extension Ocp_Transaction_V1_StatefulSwapRequest.Initiate.CoinbaseStableSwapperC
if self.feeAmount != 0 {
try visitor.visitSingularUInt64Field(value: self.feeAmount, fieldNumber: 8)
}
if self.swapVersion != 0 {
try visitor.visitSingularUInt32Field(value: self.swapVersion, fieldNumber: 9)
}
try unknownFields.traverse(visitor: &visitor)
}

Expand All @@ -4818,6 +4832,7 @@ extension Ocp_Transaction_V1_StatefulSwapRequest.Initiate.CoinbaseStableSwapperC
if lhs.fundingID != rhs.fundingID {return false}
if lhs._destinationOwner != rhs._destinationOwner {return false}
if lhs.feeAmount != rhs.feeAmount {return false}
if lhs.swapVersion != rhs.swapVersion {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
Expand Down Expand Up @@ -5486,7 +5501,7 @@ extension Ocp_Transaction_V1_StatelessSwapRequest.Initiate: SwiftProtobuf.Messag

extension Ocp_Transaction_V1_StatelessSwapRequest.Initiate.CoinbaseStableSwapperClientParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = Ocp_Transaction_V1_StatelessSwapRequest.Initiate.protoMessageName + ".CoinbaseStableSwapperClientParameters"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}from_mint\0\u{3}to_mint\0\u{3}swap_amount\0")
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}from_mint\0\u{3}to_mint\0\u{3}swap_amount\0\u{3}swap_version\0")

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
Expand All @@ -5497,6 +5512,7 @@ extension Ocp_Transaction_V1_StatelessSwapRequest.Initiate.CoinbaseStableSwapper
case 1: try { try decoder.decodeSingularMessageField(value: &self._fromMint) }()
case 2: try { try decoder.decodeSingularMessageField(value: &self._toMint) }()
case 3: try { try decoder.decodeSingularUInt64Field(value: &self.swapAmount) }()
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.swapVersion) }()
default: break
}
}
Expand All @@ -5516,13 +5532,17 @@ extension Ocp_Transaction_V1_StatelessSwapRequest.Initiate.CoinbaseStableSwapper
if self.swapAmount != 0 {
try visitor.visitSingularUInt64Field(value: self.swapAmount, fieldNumber: 3)
}
if self.swapVersion != 0 {
try visitor.visitSingularUInt32Field(value: self.swapVersion, fieldNumber: 4)
}
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Ocp_Transaction_V1_StatelessSwapRequest.Initiate.CoinbaseStableSwapperClientParameters, rhs: Ocp_Transaction_V1_StatelessSwapRequest.Initiate.CoinbaseStableSwapperClientParameters) -> Bool {
if lhs._fromMint != rhs._fromMint {return false}
if lhs._toMint != rhs._toMint {return false}
if lhs.swapAmount != rhs.swapAmount {return false}
if lhs.swapVersion != rhs.swapVersion {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: 6f70c0d8e832531fd006bbb02fcb2c5d07e0c247
subject: Add SendPublicMultiPaymentMetadata intent type (#70)
commit: 98cf14de185d5abadf6f03b6802ff298f61610d0
subject: Enable clients to migrate to Coinbase Stableswapper's v2 swap instruction (#71)
14 changes: 12 additions & 2 deletions proto/transaction/v1/ocp_transaction_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ message StatefulSwapRequest {
// The fee amount to pay for this swap, which should be exactly
// CanWithdrawToAccountResponse.fee_amount
uint64 fee_amount = 8;

// The CoinbaseStableSwapper swap instruction version the client will
// use when constructing the transaction. 2 uses SwapV2. Any other value,
// including unset, uses the legacy Swap instruction.
uint32 swap_version = 9 [(validate.rules).uint32.lte = 2];
}

// The owner account starting the swap
Expand Down Expand Up @@ -655,7 +660,7 @@ message StatefulSwapResponse {
// 5. AssociatedTokenAccount::CreateIdempotent (open swap authority's from_mint ATA)
// 6. AssociatedTokenAccount::CreateIdempotent (open destination owner's to_mint ATA)
// 7. VM::TransferForSwapWithFee (from_mint VM swap ATA -> swap authority's from_mint ATA (swap amount) and fee destination (fee amount))
// 8. CoinbaseStableSwapper::Swap (from_mint swap authority ATA -> to_mint destination owner ATA)
// 8. CoinbaseStableSwapper::Swap or CoinbaseStableSwapper::SwapV2, per client swap_version (from_mint swap authority ATA -> to_mint destination owner ATA)
// 9. Token::CloseAccount (closes swap authority's from_mint ATA)
message CoinbaseStableSwapperServerParameter {
// Subisdizer account that will be paying for the swap
Expand Down Expand Up @@ -741,6 +746,11 @@ message StatelessSwapRequest {

// The amount to swap from the source mint in quarks.
uint64 swap_amount = 3 [(validate.rules).uint64.gt = 0];

// The CoinbaseStableSwapper swap instruction version the client will
// use when constructing the transaction. 2 uses SwapV2. Any other value,
// including unset, uses the legacy Swap instruction.
uint32 swap_version = 4 [(validate.rules).uint32.lte = 2];
}

// The owner account that owns the source ATA and the destination VM
Expand Down Expand Up @@ -794,7 +804,7 @@ message StatelessSwapResponse {
// 2. [Optional] ComputeBudget::SetComputeUnitPrice
// 3. [Optional] Memo::Memo
// 4. AssociatedTokenAccount::CreateIdempotent (open owner's to_mint VM Deposit ATA)
// 5. CoinbaseStableSwapper::Swap (owner's from_mint ATA -> owner's to_mint VM Deposit ATA)
// 5. CoinbaseStableSwapper::Swap or CoinbaseStableSwapper::SwapV2, per client swap_version (owner's from_mint ATA -> owner's to_mint VM Deposit ATA)
message CoinbaseStableSwapperServerParameter {
// Subsidizer account that will pay the transaction fee.
common.v1.SolanaAccountId payer = 1 [(validate.rules).message.required = true];
Expand Down
Loading