Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
fix offering and add protocol field (#58)
Browse files Browse the repository at this point in the history
* fix offering and add protocol field

* add tests back

* remove tests.xml and add to gitignore
  • Loading branch information
kirahsapong authored Mar 19, 2024
1 parent 4f74398 commit 5f8e8ae
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 109 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ Package.resolved
*.pyc
.docc-build
.vscode
Utilities/InstalledSwiftPMConfiguration/config.json
Utilities/InstalledSwiftPMConfiguration/config.json
tests.xml
49 changes: 5 additions & 44 deletions Sources/tbDEX/Protocol/Models/Resource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,12 @@ public struct Resource<D: ResourceData>: Codable, Equatable {
public let data: D

/// Signature that verifies the authenticity and integrity of the Resource
public private(set) var signature: String?

/// Default Initializer
init(
from: String,
data: D
) {
let now = Date()
self.metadata = ResourceMetadata(
id: TypeID(prefix: data.kind().rawValue)!,
kind: data.kind(),
from: from,
createdAt: now,
updatedAt: now
)
self.data = data
self.signature = nil
}
public let signature: String?

private func digest() throws -> Data {
try CryptoUtils.digest(data: data, metadata: metadata)
}

public mutating func sign(did: BearerDID, keyAlias: String? = nil) throws {
self.signature = try JWS.sign(
did: did,
payload: try digest(),
options: .init(
detached: true,
verificationMethodID: keyAlias
)
)
}

public func verify() async throws -> Bool {
return try await JWS.verify(
compactJWS: signature,
Expand Down Expand Up @@ -91,19 +63,8 @@ public struct ResourceMetadata: Codable, Equatable {

/// The time at which the resource was last updated
public let updatedAt: Date?

/// Default Initializer
init(
id: TypeID,
kind: ResourceKind,
from: String,
createdAt: Date,
updatedAt: Date? = nil
) {
self.id = id
self.kind = kind
self.from = from
self.createdAt = createdAt
self.updatedAt = updatedAt
}

/// Version of the protocol in use (x.x format). Must be consistent with all other messages in a given exchange
public let `protocol`: String

}
25 changes: 0 additions & 25 deletions Sources/tbDEX/Protocol/Models/Resources/Offering.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,6 @@ public struct CurrencyDetails: Codable, Equatable {
/// Maximum amount of currency that the offer is valid for
public let maxAmount: String?

/// Default initializer
init(
currencyCode: String,
minAmount: String? = nil,
maxAmount: String? = nil
) {
self.currencyCode = currencyCode
self.minAmount = minAmount
self.maxAmount = maxAmount
}

}

/// Details about payment methods within an Offering
Expand All @@ -77,18 +66,4 @@ public struct PaymentMethod: Codable, Equatable {
/// A JSON Schema containing the fields that need to be collected in order to use this payment method
public let requiredPaymentDetails: AnyCodable?

/// The fee expressed in the currency's sub units to make use of this payment method
public let fee: String?

/// Default initializer
init(
kind: String,
requiredPaymentDetails: AnyCodable? = nil,
fee: String? = nil
) {
self.kind = kind
self.requiredPaymentDetails = requiredPaymentDetails
self.fee = fee
}

}
62 changes: 24 additions & 38 deletions Tests/tbDEXTests/Protocol/Models/Resources/OfferingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,35 @@ import XCTest
@testable import tbDEX

final class OfferingTests: XCTestCase {

func test_parseOffering() throws {
if let offering = try parsedOffering() {
XCTAssertEqual(offering.metadata.kind, ResourceKind.offering)
} else {
XCTFail("Offering is not a parsed offering")
}

func test_init() {
let offering = createOffering(from: "pfi")

XCTAssertEqual(offering.metadata.id.prefix, "offering")
XCTAssertEqual(offering.metadata.from, "pfi")
XCTAssertEqual(offering.data.description, "test offering")
XCTAssertEqual(offering.data.payoutUnitsPerPayinUnit, "1")
XCTAssertEqual(offering.data.payinCurrency.currencyCode, "AUD")
XCTAssertEqual(offering.data.payoutCurrency.currencyCode, "BTC")
}

func test_signAndVerifySuccess() async throws {
let did = try DIDJWK.create(keyManager: InMemoryKeyManager())
var offering = createOffering(from: did.uri)

XCTAssertNil(offering.signature)
try offering.sign(did: did)
XCTAssertNotNil(offering.signature)
let isValid = try await offering.verify()
XCTAssertTrue(isValid)
}

func test_verifyWithoutSigningFailure() async throws {
let did = try DIDJWK.create(keyManager: InMemoryKeyManager())
let offering = createOffering(from: did.uri)

await XCTAssertThrowsErrorAsync(try await offering.verify())
func test_verifyOfferingIsValid() async throws {
if let offering = try parsedOffering() {
XCTAssertNotNil(offering.signature)
XCTAssertNotNil(offering.data)
XCTAssertNotNil(offering.metadata)
let isValid = try await offering.verify()
XCTAssertTrue(isValid)
} else {
XCTFail("Offering is not a parsed offering")
}
}

private func createOffering(from: String) -> Offering {
Offering(
from: from,
data: .init(
description: "test offering",
payoutUnitsPerPayinUnit: "1",
payinCurrency: .init(currencyCode: "AUD"),
payoutCurrency: .init(currencyCode: "BTC"),
payinMethods: [],
payoutMethods: [],
requiredClaims: [:]
)
)
private func parsedOffering() throws -> Offering? {
let offeringJson = "{\"metadata\":{\"from\":\"did:dht:77em1f968c1gzwrrb15cgkzjxg8rft67ebxj6gjkocnz5p8sdniy\",\"protocol\":\"1.0\",\"kind\":\"offering\",\"id\":\"offering_01hrqn6ph3f00asxqvx46capbw\",\"createdAt\":\"2024-03-11T21:02:55.523Z\"},\"data\":{\"description\":\"Selling BTC for USD\",\"payinCurrency\":{\"currencyCode\":\"USD\",\"minAmount\":\"0.0\",\"maxAmount\":\"999999.99\"},\"payoutCurrency\":{\"currencyCode\":\"BTC\",\"maxAmount\":\"999526.11\"},\"payoutUnitsPerPayinUnit\":\"0.00003826\",\"payinMethods\":[{\"kind\":\"DEBIT_CARD\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"type\":\"object\",\"properties\":{\"cardNumber\":{\"type\":\"string\",\"description\":\"The 16-digit debit card number\",\"minLength\":16,\"maxLength\":16},\"expiryDate\":{\"type\":\"string\",\"description\":\"The expiry date of the card in MM/YY format\",\"pattern\":\"^(0[1-9]|1[0-2])\\\\/([0-9]{2})$\"},\"cardHolderName\":{\"type\":\"string\",\"description\":\"Name of the cardholder as it appears on the card\"},\"cvv\":{\"type\":\"string\",\"description\":\"The 3-digit CVV code\",\"minLength\":3,\"maxLength\":3}},\"required\":[\"cardNumber\",\"expiryDate\",\"cardHolderName\",\"cvv\"],\"additionalProperties\":false}}],\"payoutMethods\":[{\"kind\":\"BTC_ADDRESS\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"type\":\"object\",\"properties\":{\"btcAddress\":{\"type\":\"string\",\"description\":\"your Bitcoin wallet address\"}},\"required\":[\"btcAddress\"],\"additionalProperties\":false}}],\"requiredClaims\":{\"id\":\"7ce4004c-3c38-4853-968b-e411bafcd945\",\"input_descriptors\":[{\"id\":\"bbdb9b7c-5754-4f46-b63b-590bada959e0\",\"constraints\":{\"fields\":[{\"path\":[\"$.type\"],\"filter\":{\"type\":\"string\",\"const\":\"YoloCredential\"}}]}}]}},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6NzdlbTFmOTY4YzFnendycmIxNWNna3pqeGc4cmZ0NjdlYnhqNmdqa29jbno1cDhzZG5peSMwIn0..puQwdTvi4KTfKedA6CXdHHldztoQ8udUrQrGmw1wvWfYW3ilMB8myoD3ATw7NGlt1NuizJ80i4ufZArgGrTiAA\"}"
let parsedResource = try AnyResource.parse(offeringJson)
guard case let .offering(parsedOffering) = parsedResource else {
return nil
}
return parsedOffering
}

}

0 comments on commit 5f8e8ae

Please sign in to comment.