Awesome
SwiftyEOS
SwiftyEOS is an open-source framework for interacting with EOS, written in Swift.
Features
- EOS key pairs generation
- Private key import
- Signature hash
- Basic RPC API(chain/history) query client
- Transaction(EOS token transfer)
- Helper class for handling offline wallet on iOS
- Encrypt/decrypt importing private key on iOS
How to use it
- Copy the
Libraries
andSources
folders into your project, withoutmain.swift
. - Delete
Sources/Utils/iOS
if not targeted to iOS platform. - Add
Libraries/include
into Header Search Path. - Set
Libraries/include/Bridging-Header.h
as Objective-C Bridging Header. If you've got your own bridging header , copy all theimport
content in that file and paste into your own one. - Compile and pray.
Key Pairs Generation
SwiftyEOS now support secp256k1 key pairs.
There are bugs around secp256r1 key pairs generation but I cannot figure out why. Unit tests created from
cleos create key --r1
wouldn't pass. You may not consider secp256r1 as an option since thecleos wallet
command cannot import those keys, either.
Generate a random key pair:
let (pk, pub) = generateRandomKeyPair(enclave: .Secp256k1)
Easy, right?
print("private key: \(pk!.wif())")
print("public key : \(pub!.wif())")
// private key: PVT_K1_5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL
// public key : PUB_K1_4yDYdmcVcXxAxeNsUWRG7x9FKQE4HbJZdzgZFv1AYxk6oSVcLd
The PVT_K1_
and the PUB_K1_
prefixes are the parts of standard key presentations. But old styles are also supported in EOS system and SwiftyEOS:
print("private key: \(pk!.rawPrivateKey())")
print("public key : \(pub!.rawPublicKey())")
// private key: 5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL
// public key : EOS4yDYdmcVcXxAxeNsUWRG7x9FKQE4HbJZdzgZFv1AYxk6oSVcLd
Import existing key:
let importedPk = try PrivateKey(keyString: "5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL")
let importedPub = PublicKey(privateKey: importedPk!)
With delimiter and prefix:
let importedPk = try PrivateKey(keyString: "PVT_K1_5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL")
let importedPub = PublicKey(privateKey: importedPk!)
RPC API
EOSRPC.sharedInstance.chainInfo { (chainInfo, error) in
if error == nil {
print("Success: \(chainInfo!)")
} else {
print("Error: \(error!.localizedDescription)")
}
}
Currently we have some basic rpc endpoints, you can find it at Sources/SwiftyEOS/Network
iOS Key Store
We have helpers for iOS offline wallet management at SEWallet.swift
.
With SEWallet.swift
you can easily store AES encrypted key info into file system. The default location is app's sandbox Library.
Multiple wallets management is not supported yet.
Create new wallet on iOS
In Objective-C:
[SEKeystoreService.sharedInstance newAccountWithPasscode:passcode succeed:^(SELocalAccount *account) {
} failed:^(NSError *error) {
}];
Retrieve saved wallet
[SELocalAccount currentAccount];
It will return nil if there's no saved wallet.
Transactions
Transaction behaviors are not fully supported yet, but you still can have a try with sample code at main.swift
.
The related documents will be provided once the whole function is done.
- Currency transfer (2018.08.15)
- Push general transactions (2018.08.16)
- On-device(offline) wallet lock & unlock on iOS (2018.08.17)
- Stake/unstake cpu/net (2018.08.28)
- Buy/sell ram (2018.08.28)
- Create account (2018.10)
- Push transaction with params list (2018.11.05)
- Create/import key pairs with mnemonic
Transfer Currency
var transfer = Transfer()
transfer.from = "agoodaccount"
transfer.to = "gq3dinztgage"
transfer.quantity = "1.0000 EOS"
transfer.memo = "eureka"
Currency.transferCurrency(transfer: transfer, code: "eosio.token", privateKey: importedPk!, completion: { (result, error) in
if error != nil {
if error is RPCErrorResponse {
print("\((error as! RPCErrorResponse).errorDescription())")
} else {
print("other error: \(String(describing: error?.localizedDescription))")
}
} else {
print("done.")
}
})
Push General Transactions
In Swift:
let account = "raoji"
let asset = "1.0000 EPRA"
let data = "{\"hey\": {\"account\":\"" + account + "\", \"quantity\":\"" + asset + "\"}}"
let abi = try! AbiJson(code: "prabox1", action: "withdraw", json: data)
TransactionUtil.pushTransaction(abi: abi, account: account, privateKey: importedPk!, completion: { (result, error) in
if error != nil {
if (error! as NSError).code == RPCErrorResponse.ErrorCode {
print("\(((error! as NSError).userInfo[RPCErrorResponse.ErrorKey] as! RPCErrorResponse).errorDescription())")
} else {
print("other error: \(String(describing: error?.localizedDescription))")
}
} else {
print("Ok. Txid: \(result!.transactionId)")
}
})
And also in Objective-C:
AbiJson *your_abi;
[TransactionUtil pushTransactionWithAbi:your_abi
account:@"your_account"
pkString:@"your_private_key"
completion:^(TransactionResult *result, NSError *error) {
}];
On-device(offline) Wallet Lock & Unlock on iOS
We added lock
and timedUnlock
functions to SELocalAccount
.
Cpu/net/ram operations
There's a ResourceUtil.swift
file with ResourceUtil
class including, within which are several methods:
stakeResource
unstakeResource
buyRam
sellRam
Stake resource:
ResourceUtil.stakeResource(account: "raoji", net: 1.0, cpu: 1.0, pkString: "5HsaHvRCPrjU3yhapB5rLRyuKHuFTsziidA13Uw6WnQTeJAG3t4", completion: { (result, error) in
})
Mnemonic
Create a new key pair:
let (pk, pub, mn) = generateRandomKeyPair(enclave: .Secp256k1)
Import existing mnemonic:
let (pk, mn) = PrivateKey(enclave: .Secp256k1, mnemonicString: "your words here")
And we do have iOS helper API with mnemonic for key manangement in SEWallet.swift
. Creating and importing mnemonic is possible now, with SEKeystoreService
class(or SEKeystore
deep level API if you're store it on yourself):
SEKeystoreService.sharedInstance.newAccountAndMnemonic(passcode: "your pass here", succeed: { (account, mnemonic) in
}) { (error) in
}
We're using NSObject
inhereiting class for all top level API, so calling in Objective-C is the same way without providing additional bridging files.
And in SEWallet.swift
file there are helper methods for iOS, too.
Thanks
Inspired by:
- https://github.com/EOSIO/eos
- https://github.com/EOSIO/fc
- https://github.com/bitcoin/bitcoin
- https://github.com/bitcoin/libbase58
- https://github.com/OracleChain/chainkit
- https://github.com/OracleChain/PocketEOS-IOS
Built with:
Contributers: