Replace the JavaScript mobile app with a native Swift iOS wallet
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import Foundation
|
||||
|
||||
/// Base58 with the XRP Ledger alphabet and Base58Check helpers.
|
||||
enum XRPBase58 {
|
||||
static let alphabet: [Character] = Array("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz")
|
||||
|
||||
private static let valueOf: [Character: Int] = {
|
||||
var map: [Character: Int] = [:]
|
||||
for (index, character) in alphabet.enumerated() { map[character] = index }
|
||||
return map
|
||||
}()
|
||||
|
||||
static func encode(_ bytes: [UInt8]) -> String {
|
||||
var zeros = 0
|
||||
for byte in bytes {
|
||||
if byte == 0 { zeros += 1 } else { break }
|
||||
}
|
||||
|
||||
var digits: [Int] = []
|
||||
for byte in bytes[zeros...] {
|
||||
var carry = Int(byte)
|
||||
for index in digits.indices {
|
||||
carry += digits[index] << 8
|
||||
digits[index] = carry % 58
|
||||
carry /= 58
|
||||
}
|
||||
while carry > 0 {
|
||||
digits.append(carry % 58)
|
||||
carry /= 58
|
||||
}
|
||||
}
|
||||
|
||||
var output = String(repeating: String(alphabet[0]), count: zeros)
|
||||
for digit in digits.reversed() { output.append(alphabet[digit]) }
|
||||
return output
|
||||
}
|
||||
|
||||
static func decode(_ string: String) throws -> [UInt8] {
|
||||
let characters = Array(string)
|
||||
var zeros = 0
|
||||
for character in characters {
|
||||
if character == alphabet[0] { zeros += 1 } else { break }
|
||||
}
|
||||
|
||||
var bytes: [Int] = []
|
||||
for character in characters[zeros...] {
|
||||
guard let value = valueOf[character] else { throw XRPError.invalidBase58 }
|
||||
var carry = value
|
||||
for index in bytes.indices {
|
||||
carry += bytes[index] * 58
|
||||
bytes[index] = carry & 0xff
|
||||
carry >>= 8
|
||||
}
|
||||
while carry > 0 {
|
||||
bytes.append(carry & 0xff)
|
||||
carry >>= 8
|
||||
}
|
||||
}
|
||||
|
||||
return [UInt8](repeating: 0, count: zeros) + bytes.reversed().map { UInt8($0) }
|
||||
}
|
||||
|
||||
static func checkEncode(version: [UInt8], payload: [UInt8]) -> String {
|
||||
let body = version + payload
|
||||
return encode(body + XRPHash.checksum(body))
|
||||
}
|
||||
|
||||
static func checkDecode(_ string: String, versionLength: Int) throws -> [UInt8] {
|
||||
let decoded = try decode(string)
|
||||
guard decoded.count > versionLength + 4 else { throw XRPError.invalidAddress }
|
||||
let body = Array(decoded[0..<(decoded.count - 4)])
|
||||
let checksum = Array(decoded[(decoded.count - 4)...])
|
||||
guard XRPHash.checksum(body) == checksum else { throw XRPError.invalidAddress }
|
||||
return Array(body[versionLength...])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user