Skip to content

Commit

Permalink
Fix access modifiers; allow user to specify custom host/port/protocol…
Browse files Browse the repository at this point in the history
… of Arweave host node
  • Loading branch information
lukereichold committed Nov 6, 2021
1 parent 128f2ef commit e4a902d
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 68 deletions.
105 changes: 56 additions & 49 deletions Sources/API/API.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import Foundation

struct API {
static var host: URL?
let route: Route
public struct API {
static let shared = API()
private init() {}
static var baseUrl = URL(string: "https://arweave.net")!

func request(for route: Route) -> Request {
return Request(route: route)
}
}

enum Route {
Expand All @@ -17,56 +22,58 @@ enum Route {
}

extension API {
var baseURL: URL {
API.host ?? URL(string: "https://arweave.net")!
}

var path: String {
switch route {
case .txAnchor:
return "/tx_anchor"
case let .transaction(id):
return "/tx/\(id)"
case let .transactionData(id):
return "/tx/\(id)/data"
case let .transactionStatus(id):
return "/tx/\(id)/status"
case let .lastTransactionId(walletAddress):
return "/wallet/\(walletAddress)/last_tx"
case let .walletBalance(walletAddress):
return "/wallet/\(walletAddress)/balance"
case let .reward(request):
var path = "/price/\(String(request.bytes))"
if let target = request.target {
path.append("/\(target.address)")
struct Request {

var route: Route

var path: String {
switch route {
case .txAnchor:
return "/tx_anchor"
case let .transaction(id):
return "/tx/\(id)"
case let .transactionData(id):
return "/tx/\(id)/data"
case let .transactionStatus(id):
return "/tx/\(id)/status"
case let .lastTransactionId(walletAddress):
return "/wallet/\(walletAddress)/last_tx"
case let .walletBalance(walletAddress):
return "/wallet/\(walletAddress)/balance"
case let .reward(request):
var path = "/price/\(String(request.bytes))"
if let target = request.target {
path.append("/\(target.address)")
}
return path
case .commit:
return "/tx"
}
return path
case .commit:
return "/tx"
}
}

var url: URL {
baseURL.appendingPathComponent(path)
}

var method: String {
if case Route.commit = route {
return "post"
} else {
return "get"

var url: URL {
baseUrl.appendingPathComponent(path)
}
}

var body: Data? {
if case let Route.commit(transaction) = route {
return try? JSONEncoder().encode(transaction)
} else {
return nil

var method: String {
if case Route.commit = route {
return "post"
} else {
return "get"
}
}

var body: Data? {
if case let Route.commit(transaction) = route {
return try? JSONEncoder().encode(transaction)
} else {
return nil
}
}

var headers: [String: String]? {
["Content-type": "application/json"]
}
}

var headers: [String: String]? {
["Content-type": "application/json"]
}
}
2 changes: 1 addition & 1 deletion Sources/API/HttpClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct HttpResponse {

struct HttpClient {

static func request(_ target: API) async throws -> HttpResponse {
static func request(_ target: API.Request) async throws -> HttpResponse {

var request = URLRequest(url: target.url)
request.httpMethod = target.method
Expand Down
11 changes: 8 additions & 3 deletions Sources/Amount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import Foundation

public struct Amount: Equatable {

@NonNegative var value: Double
var unit: Unit
@NonNegative public var value: Double
public var unit: Unit

func converted(to targetUnit: Unit) -> Amount {
public init(value: Double, unit: Amount.Unit) {
self.value = value
self.unit = unit
}

public func converted(to targetUnit: Unit) -> Amount {

guard unit != targetUnit else { return self }

Expand Down
6 changes: 3 additions & 3 deletions Sources/Helpers.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Foundation

@propertyWrapper
struct NonNegative<T: Numeric & Comparable>: Equatable {
public struct NonNegative<T: Numeric & Comparable>: Equatable {
var value: T

var wrappedValue: T {
public var wrappedValue: T {
get { value }
set { value = max(0, newValue) }
}

init(wrappedValue: T) {
public init(wrappedValue: T) {
self.value = max(0, wrappedValue)
}
}
24 changes: 15 additions & 9 deletions Sources/Transaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ public typealias Base64EncodedString = String
public extension Transaction {

struct PriceRequest {
var bytes: Int = 0
var target: Address?

public init(bytes: Int = 0, target: Address? = nil) {
self.bytes = bytes
self.target = target
}

public var bytes: Int = 0
public var target: Address?
}

struct Tag: Codable {
Expand Down Expand Up @@ -37,7 +43,7 @@ public struct Transaction: Codable {
case id, last_tx, owner, tags, target, quantity, data, reward, signature
}

var priceRequest: PriceRequest {
public var priceRequest: PriceRequest {
PriceRequest(bytes: rawData.count, target: Address(address: target))
}

Expand Down Expand Up @@ -76,7 +82,7 @@ public extension Transaction {
throw "Missing signature on transaction."
}

let commit = API(route: .commit(self))
let commit = API.shared.request(for: .commit(self))
_ = try await HttpClient.request(commit)
}

Expand All @@ -98,20 +104,20 @@ public extension Transaction {
public extension Transaction {

static func find(_ txId: TransactionId) async throws -> Transaction {
let findEndpoint = API(route: .transaction(id: txId))
let findEndpoint = API.shared.request(for: .transaction(id: txId))
let response = try await HttpClient.request(findEndpoint)
return try JSONDecoder().decode(Transaction.self, from: response.data)
}

static func data(for txId: TransactionId) async throws -> Base64EncodedString {
let target = API(route: .transactionData(id: txId))
let target = API.shared.request(for: .transactionData(id: txId))
let response = try await HttpClient.request(target)
return String(decoding: response.data, as: UTF8.self)
}

static func status(of txId: TransactionId) async throws -> Transaction.Status {

let target = API(route: .transactionStatus(id: txId))
let target = API.shared.request(for: .transactionStatus(id: txId))
let response = try await HttpClient.request(target)

var status: Transaction.Status
Expand All @@ -125,7 +131,7 @@ public extension Transaction {
}

static func price(for request: Transaction.PriceRequest) async throws -> Amount {
let target = API(route: .reward(request))
let target = API.shared.request(for: .reward(request))
let response = try await HttpClient.request(target)

let costString = String(decoding: response.data, as: UTF8.self)
Expand All @@ -136,7 +142,7 @@ public extension Transaction {
}

static func anchor() async throws -> String {
let target = API(route: .txAnchor)
let target = API.shared.request(for: .txAnchor)
let response = try await HttpClient.request(target)

let anchor = String(decoding: response.data, as: UTF8.self)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Wallet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public struct Wallet: Codable, Hashable, Comparable {
}

public func balance() async throws -> Amount {
let target = API(route: .walletBalance(walletAddress: address))
let target = API.shared.request(for: .walletBalance(walletAddress: address))
let response = try await HttpClient.request(target)

let respString = String(decoding: response.data, as: UTF8.self)
Expand All @@ -53,7 +53,7 @@ public struct Wallet: Codable, Hashable, Comparable {
}

public func lastTransactionId() async throws -> TransactionId {
let target = API(route: .lastTransactionId(walletAddress: address))
let target = API.shared.request(for: .lastTransactionId(walletAddress: address))
let response = try await HttpClient.request(target)

let lastTx = String(decoding: response.data, as: UTF8.self)
Expand Down Expand Up @@ -89,7 +89,7 @@ public struct Address: Hashable, Codable, Equatable, Comparable, CustomStringCon
}
}

extension Address {
public extension Address {
init(from modulus: String) {
guard let data = Data(base64URLEncoded: modulus) else {
preconditionFailure("Invalid base64 value for JWK public modulus (n) property.")
Expand Down
6 changes: 6 additions & 0 deletions Tests/WalletTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ final class WalletTests: XCTestCase {
let balance = try await WalletTests.wallet?.balance()
XCTAssertNotNil(balance?.value)
}

func testCheckWalletBalance_UsingCustomHost() async throws {
API.baseUrl = URL(string: "https://arweave.net:443")!
let balance = try await WalletTests.wallet?.balance()
XCTAssertNotNil(balance?.value)
}

func testFetchLastTransactionId() async throws {
let lastTxId = try await WalletTests.wallet?.lastTransactionId()
Expand Down

0 comments on commit e4a902d

Please sign in to comment.