Skip to content

Commit

Permalink
Added sources and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anquii committed Apr 17, 2023
1 parent 63e09ea commit ebffb7a
Show file tree
Hide file tree
Showing 32 changed files with 1,502 additions and 2 deletions.
23 changes: 23 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"pins" : [
{
"identity" : "bigint",
"kind" : "remoteSourceControl",
"location" : "https://github.com/attaswift/BigInt.git",
"state" : {
"revision" : "0ed110f7555c34ff468e72e1686e59721f2b0da6",
"version" : "5.3.0"
}
},
{
"identity" : "cryptoswiftwrapper",
"kind" : "remoteSourceControl",
"location" : "https://github.com/anquii/CryptoSwiftWrapper.git",
"state" : {
"revision" : "0d57e806de368b5d2364fabb7c789b48661ec90c",
"version" : "1.4.3"
}
}
],
"version" : 2
}
40 changes: 40 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// swift-tools-version:5.7

import PackageDescription

let package = Package(
name: "Navcoin",
platforms: [
.macOS(.v11),
.iOS(.v14)
],
products: [
.library(
name: "Navcoin",
targets: ["Navcoin"]
)
],
dependencies: [
.package(
url: "https://github.com/attaswift/BigInt.git",
.upToNextMajor(from: "5.3.0")
),
.package(
url: "https://github.com/anquii/CryptoSwiftWrapper.git",
.upToNextMajor(from: "1.4.3")
)
],
targets: [
.target(
name: "Navcoin",
dependencies: [
"BigInt",
"CryptoSwiftWrapper"
]
),
.testTarget(
name: "NavcoinTests",
dependencies: ["Navcoin"]
)
]
)
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Swift Package Manager compatible](https://img.shields.io/badge/SPM-compatible-orange)](#swift-package-manager)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/anquii/Navcoin/blob/main/LICENSE)

An implementation to interact with [Navcoin](https://github.com/navcoin/navcoin) in Swift.
An implementation to interact with [Navcoin](https://navcoin.org)'s upcoming [PePoS](https://medium.com/nav-coin/announcing-pepos-a-privacy-enhanced-proof-of-stake-protocol-95c3149e8bd6) protocol in Swift.

## Platforms
- macOS 11+
Expand All @@ -16,14 +16,20 @@ An implementation to interact with [Navcoin](https://github.com/navcoin/navcoin)

Add the following line to your `Package.swift` file:
```swift
.package(url: "https://github.com/anquii/Navcoin.git", from: "1.0.0")
.package(url: "https://github.com/anquii/Navcoin.git", from: "0.1.0")
```
...or integrate with Xcode via `File -> Swift Packages -> Add Package Dependency...` using the URL of the repository.

## Usage

```swift
import Navcoin

let transactionSerializer = TransactionSerializer()
let data = transactionSerializer.data(transaction: transaction)

let transactionDeserializer = TransactionDeserializer()
let transaction = transactionDeserializer.transaction(data: data)
```

## License
Expand Down
76 changes: 76 additions & 0 deletions Sources/Navcoin/CompactSizeUInt.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Foundation

struct CompactSizeUInt {
let value: UInt

init(_ value: UInt) {
self.value = value
}

init(_ value: Int) {
guard value >= 0 else {
preconditionFailure()
}
self.value = UInt(value)
}

init?(data: Data) {
guard !data.isEmpty, let firstByte = data.first else {
return nil
}
if firstByte <= 0xfc {
value = UInt(firstByte)
return
}
let startIndex = data.startIndex + 1
var endIndex = startIndex
switch firstByte {
case 0xfd:
endIndex += 2
case 0xfe:
endIndex += 4
case 0xff:
endIndex += 8
default:
preconditionFailure()
}
guard
data.indices.contains(startIndex),
data.indices.contains(endIndex - 1),
let unsignedInteger = UInt(data: data[startIndex..<endIndex])
else {
return nil
}
value = unsignedInteger
}

var bytes: [UInt8] {
switch value {
case 0...0xfc:
return UInt8(value).bytes
case 0xfd...0xffff:
return [UInt8(0xfd)] + UInt16(value).bytes
case 0x10000...0xffffffff:
return [UInt8(0xfe)] + UInt32(value).bytes
case 0x100000000...0xffffffffffffffff:
return [UInt8(0xff)] + UInt64(value).bytes
default:
preconditionFailure()
}
}

var totalByteCount: Int {
switch value {
case 0...0xfc:
return 1
case 0xfd...0xffff:
return 3
case 0x10000...0xffffffff:
return 5
case 0x100000000...0xffffffffffffffff:
return 9
default:
preconditionFailure()
}
}
}
3 changes: 3 additions & 0 deletions Sources/Navcoin/ErrorDescribing.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public protocol ErrorDescribing {
var description: String { get }
}
14 changes: 14 additions & 0 deletions Sources/Navcoin/Extensions/BigUInt+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import BigInt

extension BigUInt {
func serialized(requiredLength: Int) -> Data {
let data = self.serialize()
guard data.count < requiredLength else {
return data
}
let leadingZeroesCount = requiredLength - data.count
let leadingZeroes = Data(repeating: 0, count: leadingZeroesCount)
return leadingZeroes + data
}
}
16 changes: 16 additions & 0 deletions Sources/Navcoin/Extensions/Data+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Foundation
import CryptoSwift

extension Data {
init(hex: String) {
self.init(Array<UInt8>(hex: hex))
}

var bytes: Array<UInt8> {
Array(self)
}

func toHexString() -> String {
bytes.toHexString()
}
}
14 changes: 14 additions & 0 deletions Sources/Navcoin/Extensions/FixedWidthInteger+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation

extension FixedWidthInteger {
init?(data: Data) {
guard let value = Self(data.toHexString(), radix: 16) else {
return nil
}
self = value
}

var bytes: [UInt8] {
withUnsafeBytes(of: self, Array.init)
}
}
8 changes: 8 additions & 0 deletions Sources/Navcoin/Extensions/Int+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extension Int {
init?(unsignedInteger: UInt) {
guard unsignedInteger <= Int64.max else {
return nil
}
self = Int(unsignedInteger)
}
}
11 changes: 11 additions & 0 deletions Sources/Navcoin/Transaction/Outpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import BigInt

public struct Outpoint {
public let id: BigUInt
public let index: UInt32

public init(id: BigUInt, index: UInt32) {
self.id = id
self.index = index
}
}
44 changes: 44 additions & 0 deletions Sources/Navcoin/Transaction/RangeProof.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Foundation

public struct RangeProof {
public let Vs: [Data]
public let Ls: [Data]
public let Rs: [Data]
public let A: Data
public let S: Data
public let T1: Data
public let T2: Data
public let taux: Data
public let mu: Data
public let a: Data
public let b: Data
public let t: Data

public init(
Vs: [Data],
Ls: [Data],
Rs: [Data],
A: Data,
S: Data,
T1: Data,
T2: Data,
taux: Data,
mu: Data,
a: Data,
b: Data,
t: Data
) {
self.Vs = Vs
self.Ls = Ls
self.Rs = Rs
self.A = A
self.S = S
self.T1 = T1
self.T2 = T2
self.taux = taux
self.mu = mu
self.a = a
self.b = b
self.t = t
}
}
11 changes: 11 additions & 0 deletions Sources/Navcoin/Transaction/TokenIdentifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import BigInt

public struct TokenIdentifier {
public let id: BigUInt
public let nftId: UInt64

public init(id: BigUInt, nftId: UInt64) {
self.id = id
self.nftId = nftId
}
}
26 changes: 26 additions & 0 deletions Sources/Navcoin/Transaction/Transaction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

public struct Transaction {
public let version: Int32
public let inputs: [TransactionInput]?
public let outputs: [TransactionOutput]
public let witnesses: [TransactionWitness]?
public let signature: Data?
public let lockTime: UInt32

public init(
version: Int32,
inputs: [TransactionInput]? = nil,
outputs: [TransactionOutput],
witnesses: [TransactionWitness]? = nil,
signature: Data? = nil,
lockTime: UInt32
) {
self.version = version
self.inputs = inputs
self.outputs = outputs
self.witnesses = witnesses
self.signature = signature
self.lockTime = lockTime
}
}
13 changes: 13 additions & 0 deletions Sources/Navcoin/Transaction/TransactionInput.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation

public struct TransactionInput {
public let outpoint: Outpoint
public let scriptSignature: Data?
public let sequence: UInt32

public init(outpoint: Outpoint, scriptSignature: Data?, sequence: UInt32) {
self.outpoint = outpoint
self.scriptSignature = scriptSignature
self.sequence = sequence
}
}
32 changes: 32 additions & 0 deletions Sources/Navcoin/Transaction/TransactionOutput.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Foundation

public struct TransactionOutput {
public let value: Int64
public let publicScriptKey: Data?
public let rangeProof: RangeProof?
public let publicBLSSpendKey: Data?
public let publicBLSBlindKey: Data?
public let publicBLSEphemeralKey: Data?
public let viewTag: UInt16?
public let tokenIdentifier: TokenIdentifier?

public init(
value: Int64,
publicScriptKey: Data?,
rangeProof: RangeProof? = nil,
publicBLSSpendKey: Data? = nil,
publicBLSBlindKey: Data? = nil,
publicBLSEphemeralKey: Data? = nil,
viewTag: UInt16? = nil,
tokenIdentifier: TokenIdentifier? = nil
) {
self.value = value
self.publicScriptKey = publicScriptKey
self.rangeProof = rangeProof
self.publicBLSSpendKey = publicBLSSpendKey
self.publicBLSBlindKey = publicBLSBlindKey
self.publicBLSEphemeralKey = publicBLSEphemeralKey
self.viewTag = viewTag
self.tokenIdentifier = tokenIdentifier
}
}
9 changes: 9 additions & 0 deletions Sources/Navcoin/Transaction/TransactionWitness.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public struct TransactionWitness {
public let stack: [Data]

public init(stack: [Data]) {
self.stack = stack
}
}
Loading

0 comments on commit ebffb7a

Please sign in to comment.