Skip to content

Commit

Permalink
Merge pull request #41 from XYOracleNetwork/feature/wallets
Browse files Browse the repository at this point in the history
Accounts
  • Loading branch information
JoelBCarter authored Nov 12, 2024
2 parents 5a3852c + de5fb0c commit e9dbad0
Show file tree
Hide file tree
Showing 19 changed files with 160 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"cSpell.words": ["Alamofire", "keccak", "secp", "unkeyed"]
"cSpell.words": ["Alamofire", "keccak", "Protobuf", "secp", "unkeyed"]
}
43 changes: 21 additions & 22 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
{
"object": {
"pins": [
{
"package": "Alamofire",
"repositoryURL": "https://github.com/Alamofire/Alamofire.git",
"state": {
"branch": null,
"revision": "e16d3481f5ed35f0472cb93350085853d754913f",
"version": "5.10.1"
}
},
{
"package": "swift-secp256k1",
"repositoryURL": "https://github.com/21-DOT-DEV/swift-secp256k1",
"state": {
"branch": null,
"revision": "57ce9af6db14e0114af631ace25231a9d0ccccbd",
"version": "0.18.0"
}
"originHash" : "f3249e1a536ee6e8dbb38e511a584a952ad70dd2ca47f9b2313e3410784259cc",
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire.git",
"state" : {
"revision" : "e16d3481f5ed35f0472cb93350085853d754913f",
"version" : "5.10.1"
}
]
},
"version": 1
},
{
"identity" : "swift-secp256k1",
"kind" : "remoteSourceControl",
"location" : "https://github.com/21-DOT-DEV/swift-secp256k1",
"state" : {
"revision" : "57ce9af6db14e0114af631ace25231a9d0ccccbd",
"version" : "0.18.0"
}
}
],
"version" : 3
}
6 changes: 1 addition & 5 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

Expand All @@ -12,18 +11,15 @@ let package = Package(
.watchOS(.v5),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "XyoClient",
targets: ["XyoClient"])
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.2.0")),
.package(url: "https://github.com/21-DOT-DEV/swift-secp256k1", .upToNextMinor(from: "0.18.0")),
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.2.0")),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(name: "keccak"),
.target(
name: "XyoClient",
Expand Down
52 changes: 52 additions & 0 deletions Sources/XyoClient/Address/Account.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Foundation

public class Account: AccountInstance, AccountStatic {
let _account: XyoAddress
var _previousHash: String? = nil

public static func fromPrivateKey(key: Data?) -> AccountInstance {
guard let key else {
return Account()
}
let address = XyoAddress(key)
return Account(address: address)
}

public static func random() -> AccountInstance {
return Account()
}

init() {
self._account = XyoAddress()
}

init(address: XyoAddress) {
self._account = address
}

public var address: Address {
guard let value = self._account.address else {
fatalError("Invalid address")
}
return value as Address
}

public var addressBytes: Data {
guard let value = self._account.addressBytes else {
fatalError("Invalid addressBytes")
}
return value
}

public var previousHash: Hash? {
return self._previousHash
}

public func sign(hash: Hash) throws -> String {
guard let value = try self._account.sign(hash: hash) else {
fatalError("Error signing hash")
}
_previousHash = value
return value
}
}
14 changes: 10 additions & 4 deletions Sources/XyoClient/Address/AccountInstance.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import Foundation

public protocol AccountInstance {
var address: String? { get }
var addressBytes: Data? { get }
var previousHash: String? { get }
func sign(hash: String) throws -> String?
var address: Address { get }
var addressBytes: Data { get }
var previousHash: Hash? { get }
// var previousHashBytes: Data? { get set }
// var `private`: Data? { get }
// var `public`: Data? { get }

func sign(hash: Hash) throws -> String
// func sign(hash: Data, previousHash: Data?) async throws -> Data
// func verify(msg: Data, signature: Data) async throws -> Bool
}
10 changes: 10 additions & 0 deletions Sources/XyoClient/Address/AccountStatic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Foundation

public protocol AccountStatic {
// associatedtype T: AccountInstance
// associatedtype C: XyoPayload

// static func create(options: C?) async throws -> T
static func fromPrivateKey(key: Data?) -> AccountInstance
static func random() -> AccountInstance
}
1 change: 1 addition & 0 deletions Sources/XyoClient/Address/Address.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public typealias Address = String
11 changes: 2 additions & 9 deletions Sources/XyoClient/Address/XyoAddress.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import Foundation
import secp256k1

public class XyoAddress: AccountInstance {
public class XyoAddress {

private var _previousHash: String? = nil
private var _privateKey: secp256k1.Signing.PrivateKey?

public init(_ privateKey: Data? = generateRandomBytes()) {
Expand All @@ -15,10 +14,6 @@ public class XyoAddress: AccountInstance {
self.init(privateKey.hexToData())
}

public var previousHash: String? {
return _previousHash
}

public var privateKey: secp256k1.Signing.PrivateKey? {
return _privateKey
}
Expand Down Expand Up @@ -71,9 +66,7 @@ public class XyoAddress: AccountInstance {
let message = hash.hexToData()
guard message != nil else { return nil }
let sig = self.signature(message!)
let ret = sig?.dataRepresentation.toHex()
_previousHash = hash
return ret
return sig?.dataRepresentation.toHex()
}

public func signature(_ hash: Data) -> secp256k1.Signing.ECDSASignature? {
Expand Down
4 changes: 2 additions & 2 deletions Sources/XyoClient/ArchivistApi/ArchivistApiClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class XyoArchivistApiClient {

private init(_ config: XyoArchivistApiConfig, _ account: AccountInstance?) {
self.config = config
self.queryAccount = account ?? XyoAddress()
self.queryAccount = account ?? Account()
}

public func insert(payloads: [XyoPayload]) async throws -> [XyoPayload] {
Expand Down Expand Up @@ -109,7 +109,7 @@ public class XyoArchivistApiClient {
}

public static func get(_ config: XyoArchivistApiConfig) -> XyoArchivistApiClient {
return XyoArchivistApiClient(config, XyoAddress())
return XyoArchivistApiClient(config, Account())
}
}

Expand Down
1 change: 1 addition & 0 deletions Sources/XyoClient/Hash/Hash.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public typealias Hash = String
12 changes: 6 additions & 6 deletions Sources/XyoClient/Module/AbstractModule.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
open class AbstractModule: Module {

private let _account: XyoAddress
private let _account: AccountInstance

public var account: AccountInstance {
_account
}

public var address: String? {
_account.addressHex
public var address: Address {
_account.address
}

public var previousHash: String? {
public var previousHash: Hash? {
_account.previousHash
}

public init(account: XyoAddress? = nil) {
self._account = account ?? XyoAddress()
public init(account: AccountInstance? = nil) {
self._account = account ?? Account()
}
}
4 changes: 2 additions & 2 deletions Sources/XyoClient/Module/Module.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
public protocol Module {
var address: String? { get }
var address: Address { get }
var account: AccountInstance { get }
var previousHash: String? { get }
var previousHash: Hash? { get }
}
12 changes: 12 additions & 0 deletions Sources/XyoClient/Wallet/Wallet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Foundation

public class Wallet {

// public class Wallet: WalletInstance, WalletStatic {
// private let _wallet: HDWallet

init() {

}

}
17 changes: 17 additions & 0 deletions Sources/XyoClient/Wallet/WalletInstance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation

public protocol WalletInstance: AccountInstance {
var chainCode: String { get }
var depth: Int { get }
var extendedKey: String { get }
var fingerprint: String { get }
var index: Int { get }
var mnemonic: String? { get }
var parentFingerprint: String { get }
var path: String? { get }
var privateKey: String { get }
var publicKey: String { get }

func derivePath(path: String) throws -> WalletInstance
func neuter() -> WalletInstance
}
11 changes: 11 additions & 0 deletions Sources/XyoClient/Wallet/WalletStatic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

public protocol WalletStatic {

// func create(config: XyoPayload) throws -> WalletInstance
// func fromExtendedKey(key: String) throws -> WalletInstance
// func fromMnemonic(mnemonic: String) throws -> WalletInstance
// func fromPhrase(mnemonic: String, path: String?) throws -> WalletInstance
// func fromSeed(seed: Data) throws -> WalletInstance
func random() -> WalletInstance
}
4 changes: 2 additions & 2 deletions Sources/XyoClient/XyoWitness/Basic/BasicWitness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ open class XyoBasicWitness: AbstractWitness {
super.init()
}

public init(address: XyoAddress, observer: @escaping ObserverClosure) {
public init(account: AccountInstance, observer: @escaping ObserverClosure) {
_observer = observer
super.init(account: address)
super.init(account: account)
}

public typealias ObserverClosure = (() -> XyoPayload?)
Expand Down
4 changes: 2 additions & 2 deletions Sources/XyoClient/XyoWitness/Event/EventWitness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ open class XyoEventWitness: AbstractWitness {
super.init()
}

public init(_ address: XyoAddress, _ observer: @escaping ObserverClosure) {
public init(_ account: AccountInstance, _ observer: @escaping ObserverClosure) {
_observer = observer
super.init(account: address)
super.init(account: account)
}

public typealias ObserverClosure = (() -> XyoEventPayload?)
Expand Down
8 changes: 4 additions & 4 deletions Tests/XyoClientTests/BoundWitness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ final class BoundWitnessTests: XCTestCase {
func testPayload1() throws {
let hash = try BoundWitnessBuilder.hash(TestPayload1("network.xyo.test"))
XCTAssertEqual(hash, "c915c56dd93b5e0db509d1a63ca540cfb211e11f03039b05e19712267bb8b6db")
let address = XyoAddress(testVectorPrivateKey.hexToData())
let address = Account.fromPrivateKey(key: testVectorPrivateKey.hexToData())
let bw = try BoundWitnessBuilder().signer(address).payload(
"network.xyo.test", TestPayload1("network.xyo.test"))
let (bwJson, _) = try bw.build()
XCTAssertEqual(bwJson._hash, knownHash)
}

func testPayload1WithSend() throws {
let address = XyoAddress(testVectorPrivateKey.hexToData())
let address = Account.fromPrivateKey(key: testVectorPrivateKey.hexToData())
let config = XyoArchivistApiConfig("Archivist", "https://beta.api.archivist.xyo.network")
let api = XyoArchivistApiClient.get(config)
let bw = try BoundWitnessBuilder().signer(address).payload(
Expand All @@ -107,15 +107,15 @@ final class BoundWitnessTests: XCTestCase {
}

func testPayload2() throws {
let address = XyoAddress(testVectorPrivateKey.hexToData())
let address = Account.fromPrivateKey(key: testVectorPrivateKey.hexToData())
let testPayload2 = TestPayload2("network.xyo.test")
let bw = try BoundWitnessBuilder().signer(address).payload("network.xyo.test", testPayload2)
let (bwJson, _) = try bw.build()
XCTAssertEqual(bwJson._hash, knownHash)
}

func testPayload2WithSend() throws {
let address = XyoAddress(testVectorPrivateKey.hexToData())
let address = Account.fromPrivateKey(key: testVectorPrivateKey.hexToData())
let config = XyoArchivistApiConfig("Archivist", "https://beta.api.archivist.xyo.network")
let api = XyoArchivistApiClient.get(config)
let bw = try BoundWitnessBuilder().signer(address).payload(
Expand Down
6 changes: 3 additions & 3 deletions Tests/XyoClientTests/Panel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ final class PanelTests: XCTestCase {
func testCreatePanel() throws {
let apiDomain = XyoPanel.Defaults.apiDomain
let archive = XyoPanel.Defaults.apiModule
let address = XyoAddress()
let witness = AbstractWitness(account: address)
let account = Account()
let witness = AbstractWitness(account: account)
let panel = XyoPanel(archive: archive, apiDomain: apiDomain, witnesses: [witness])
XCTAssertNotNil(address)
XCTAssertNotNil(account)
XCTAssertNotNil(panel)
}

Expand Down

0 comments on commit e9dbad0

Please sign in to comment.