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
38 changes: 38 additions & 0 deletions Sources/blocks/Domain/ClaimObjectContent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ClaimObjectContent.swift
// blocks
//
// Created by Codex on 2026/05/24.
//

import Foundation
import overlayNetwork

enum ClaimObjectContent {
static func commonFields(from content: String) -> (destination: OverlayNetworkAddressAsHexString, publicKeyForEncryption: PublicKeyForEncryption?, combinedSealedBox: String, description: String, attachedFileType: String)? {
guard let dictionary = content.jsonToAnyDictionary else {
return nil
}

let publicKeyForEncryptionString = stringValue(for: "PublicKeyForEncryption", in: dictionary)
let publicKeyForEncryption = publicKeyForEncryptionString.isEmpty ? nil : publicKeyForEncryptionString.base64DecodedData

return (
destination: stringValue(for: "Destination", in: dictionary),
publicKeyForEncryption: publicKeyForEncryption,
combinedSealedBox: stringValue(for: "CombinedSealedBox", in: dictionary),
description: stringValue(for: "Description", in: dictionary),
attachedFileType: stringValue(for: "AttachedFileType", in: dictionary, fallbackKey: "attachedFileType")
)
}

private static func stringValue(for key: String, in dictionary: [String: Any], fallbackKey: String? = nil) -> String {
if let value = dictionary[key] as? String {
return value
}
if let fallbackKey, let value = dictionary[fallbackKey] as? String {
return value
}
return ""
}
}
5 changes: 4 additions & 1 deletion Sources/blocks/Domain/Fact.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ public enum ClaimOnFact: String, Claim {
}

public func object(content: String) -> ClaimObject? {
return nil
guard let fields = ClaimObjectContent.commonFields(from: content) else {
return nil
}
return Object(destination: fields.destination, publicKeyForEncryption: fields.publicKeyForEncryption, combinedSealedBox: fields.combinedSealedBox, description: fields.description, attachedFileType: fields.attachedFileType)
}

public typealias ClaimType = ClaimOnFact
Expand Down
5 changes: 4 additions & 1 deletion Sources/blocks/Domain/Pay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ public enum ClaimOnPay: String, Claim {
}

public func object(content: String) -> ClaimObject? {
return nil
guard let fields = ClaimObjectContent.commonFields(from: content) else {
return nil
}
return Object(destination: fields.destination, publicKeyForEncryption: fields.publicKeyForEncryption, combinedSealedBox: fields.combinedSealedBox, description: fields.description, attachedFileType: fields.attachedFileType)
}

public init?(rawValue: String) {
Expand Down
75 changes: 75 additions & 0 deletions Tests/blocksTests/TransactionRestorationTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// TransactionRestorationTest.swift
// blocksTests
//
// Created by Codex on 2026/05/24.
//

import XCTest
@testable import blocks
import overlayNetwork

final class TransactionRestorationTest: XCTestCase {

func testRestoresReceivedPayTransaction() throws {
let signer = Signer(newPrivateKeyOn: "pay-maker" as OverlayNetworkAddressAsHexString)
guard let publicKey = signer.publicKeyAsData else {
XCTFail("Signer should have a public key.")
return
}
let transaction = try XCTUnwrap(TransactionType.pay.construct(
claim: ClaimOnPay.bookerFee,
claimObject: ClaimOnPay.Object(destination: "pay-destination", description: "pay description"),
makerDhtAddressAsHexString: signer.makerDhtAddressAsHexString,
publicKey: publicKey,
book: Book(signature: Data.DataNull),
signer: signer,
transactionId: "BK-pay-restore",
date: Date(timeIntervalSince1970: 1_700_000_000),
debitOnLeft: Decimal(10),
creditOnRight: Decimal(10),
withdrawalDhtAddressOnLeft: "pay-maker",
depositDhtAddressOnRight: "pay-destination"
))
let receivedSigner = Signer(publicKeyAsData: publicKey, makerDhtAddressAsHexString: signer.makerDhtAddressAsHexString)

let restored = Transactions.Maker(book: Book(signature: Data.DataNull), string: "[\(transaction.jsonString)]", signer: receivedSigner).stringToTransactions
let restoredPay = try XCTUnwrap(restored?.first as? Pay)
let restoredObject = try XCTUnwrap(restoredPay.claimObject as? ClaimOnPay.Object)

XCTAssertEqual(restoredPay.claim.rawValue, ClaimOnPay.bookerFee.rawValue)
XCTAssertEqual(restoredObject.destination.toString, "pay-destination")
XCTAssertEqual(restoredObject.description, "pay description")
}

func testRestoresReceivedFactTransaction() throws {
let signer = Signer(newPrivateKeyOn: "fact-maker" as OverlayNetworkAddressAsHexString)
guard let publicKey = signer.publicKeyAsData else {
XCTFail("Signer should have a public key.")
return
}
let transaction = try XCTUnwrap(TransactionType.fact.construct(
claim: ClaimOnFact.a,
claimObject: ClaimOnFact.Object(destination: "fact-destination", description: "fact description"),
makerDhtAddressAsHexString: signer.makerDhtAddressAsHexString,
publicKey: publicKey,
book: Book(signature: Data.DataNull),
signer: signer,
transactionId: "BK-fact-restore",
date: Date(timeIntervalSince1970: 1_700_000_000),
debitOnLeft: Decimal(1),
creditOnRight: Decimal(1),
withdrawalDhtAddressOnLeft: "fact-maker",
depositDhtAddressOnRight: "fact-destination"
))
let receivedSigner = Signer(publicKeyAsData: publicKey, makerDhtAddressAsHexString: signer.makerDhtAddressAsHexString)

let restored = Transactions.Maker(book: Book(signature: Data.DataNull), string: "[\(transaction.jsonString)]", signer: receivedSigner).stringToTransactions
let restoredFact = try XCTUnwrap(restored?.first as? Fact)
let restoredObject = try XCTUnwrap(restoredFact.claimObject as? ClaimOnFact.Object)

XCTAssertEqual(restoredFact.claim.rawValue, ClaimOnFact.a.rawValue)
XCTAssertEqual(restoredObject.destination.toString, "fact-destination")
XCTAssertEqual(restoredObject.description, "fact description")
}
}