• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Soneso/stellar-ios-mac-sdk: Stellar SDK for iOS & macOS - Swift, Stellar, Ho ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称(OpenSource Name):

Soneso/stellar-ios-mac-sdk

开源软件地址(OpenSource Url):

https://github.com/Soneso/stellar-ios-mac-sdk

开源编程语言(OpenSource Language):

Swift 92.2%

开源软件介绍(OpenSource Introduction):

stellar-ios-mac-sdk

The Soneso open source stellar SDK for iOS & Mac provides APIs to build transactions and connect to Horizon.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate stellar SDK into your Xcode project using CocoaPods, specify it in your Podfile:

use_frameworks!

target '<Your Target Name>' do
    pod 'stellar-ios-mac-sdk', '~> 2.2.3'
end

Then, run the following command:

$ pod repo update
$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate stellar-ios-mac-sdk into your Xcode project using Carthage, specify it in your Cartfile:

github "soneso/stellar-ios-mac-sdk" ~> 2.2.3

Run carthage update to build the framework and drag the build stellar-ios-mac-sdk.framework into your Xcode project.

Swift Package Manager

.package(name: "stellarsdk", url: "git@github.com:Soneso/stellar-ios-mac-sdk.git", from: "2.2.3"),

Manual

Add the SDK project as a subproject, and having the SDK as a target dependencies. Here is a step by step that we recommend:

  1. Clone this repo (as a submodule or in a different directory, it's up to you);
  2. Drag stellarsdk.xcodeproj as a subproject;
  3. In your main .xcodeproj file, select the desired target(s);
  4. Go to Build Phases, expand Target Dependencies, and add stellarsdk for iOS and stellarsdk-macOS for OSX;
  5. In Swift, import stellarsdk and you are good to go!

Quick Start

1. Create a Stellar key pair

1.1 Random generation

// create a completely new and unique pair of keys.
let keyPair = try! KeyPair.generateRandomKeyPair()

print("Account Id: " + keyPair.accountId)
// GCFXHS4GXL6BVUCXBWXGTITROWLVYXQKQLF4YH5O5JT3YZXCYPAFBJZB

print("Secret Seed: " + keyPair.secretSeed)
// SAV76USXIJOBMEQXPANUOQM6F5LIOTLPDIDVRJBFFE2MDJXG24TAPUU7
 

1.2 Deterministic generation

The Stellar Ecosystem Proposal SEP-005 Key Derivation Methods for Stellar Accounts describes methods for key derivation for Stellar. This improves key storage and moving keys between wallets and apps.

Generate mnemonic

let mnemonic = Wallet.generate24WordMnemonic()
print("generated 24 words mnemonic: \(mnemonic)")
// bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better

Generate key pairs

let keyPair0 = try! Wallet.createKeyPair(mnemonic: mnemonic, passphrase: nil, index: 0)
let keyPair1 = try! Wallet.createKeyPair(mnemonic: mnemonic, passphrase: nil, index: 1)

print("key pair 0 accountId: \(keyPair0.accountId)")
// key pair 0 accountId: GC3MMSXBWHL6CPOAVERSJITX7BH76YU252WGLUOM5CJX3E7UCYZBTPJQ

print("key pair 0 secretSeed: \(keyPair0.secretSeed!)")
// key pair 0 secretSeed: SAEWIVK3VLNEJ3WEJRZXQGDAS5NVG2BYSYDFRSH4GKVTS5RXNVED5AX7

Generate key pairs with passphrase

let keyPair0 = try! Wallet.createKeyPair(mnemonic: mnemonic, passphrase: "p4ssphr4se", index: 0)
let keyPair1 = try! Wallet.createKeyPair(mnemonic: mnemonic, passphrase: "p4ssphr4se", index: 0)

BIP and master key generation

let bip39Seed = Mnemonic.createSeed(mnemonic: mnemonic)

let masterPrivateKey = Ed25519Derivation(seed: bip39Seed)
let purpose = masterPrivateKey.derived(at: 44)
let coinType = purpose.derived(at: 148)

let account0 = coinType.derived(at: 0)
let keyPair0 = try! KeyPair.init(seed: Seed(bytes: account0.raw.bytes))

let account1 = coinType.derived(at: 1)
let keyPair1 = try! KeyPair.init(seed: Seed(bytes: account1.raw.bytes))

2. Create an account

After the key pair generation, you have already got the address, but it is not activated until someone transfers at least 1 lumen into it.

2.1 Testnet

If you want to play in the Stellar test network, the sdk can ask Friendbot to create an account for you as shown below:

// To create a test account, sdk.accounts.createTestAccount will send Friendbot the public key you created
sdk.accounts.createTestAccount(accountId: keyPair.accountId) { (response) -> (Void) in
    switch response {
        case .success(let details):
                print(details)
        case .failure(let error):
                print(error.localizedDescription)
     }
}

2.2 Public net

On the other hand, if you would like to create an account in the public net, you should buy some Stellar Lumens from an exchange. When you withdraw the Lumens into your new account, the exchange will automatically create the account for you. However, if you want to create an account from another account of your own, you may run the following code:

// build the operation
let createAccount = CreateAccountOperation(sourceAccount: nil, 
                                           destination: destinationKeyPair, 
                                           startBalance: 2.0)

// build the transaction
let transaction = try Transaction(sourceAccount: accountResponse,
                                     operations: [createAccount],
                                     memo: Memo.none,
                                     timeBounds:nil)
                                     
// sign the transaction
try transaction.sign(keyPair: sourceAccountKeyPair, network: Network.testnet)
                        
// submit the transaction
try sdk.transactions.submitTransaction(transaction: transaction) { (response) -> (Void) in
    switch response {
    case .success(_):
        //...
    case .failure(let error):
       // ...
    }
}

3. Check account

3.1 Basic info

After creating the account, we may check the basic information of the account.

sdk.accounts.getAccountDetails(accountId: keyPair.accountId) { (response) -> (Void) in
    switch response {
    case .success(let accountDetails):
        
        // You can check the `balance`, `sequence`, `flags`, `signers`, `data` etc.
        
        for balance in accountDetails.balances {
            switch balance.assetType {
            case AssetTypeAsString.NATIVE:
                print("balance: \(balance.balance) XLM")
            default:
                print("balance: \(balance.balance) \(balance.assetCode!) issuer: \(balance.assetIssuer!)")
            }
        }

        print("sequence number: \(accountDetails.sequenceNumber)")

        for signer in accountDetails.signers {
            print("signer public key: \(signer.publicKey)")
        }

        print("auth required: \(accountDetails.flags.authRequired)")
        print("auth revocable: \(accountDetails.flags.authRevocable)")

        for (key, value) in accountDetails.data {
            print("data key: \(key) value: \(value.base64Decoded() ?? "")")
        }
    case .failure(let error):
        print(error.localizedDescription)
    }
}

3.2 Check payments

You can check the most recent payments by:

sdk.payments.getPayments(order:Order.descending, limit:10) { response in
    switch response {
    case .success(let paymentsResponse):
        for payment in paymentsResponse.records {
            if let nextPayment = payment as? PaymentOperationResponse {
                if (nextPayment.assetType == AssetTypeAsString.NATIVE) {
                    print("received: \(nextPayment.amount) lumen" )
                } else {
                    print("received: \(nextPayment.amount) \(nextPayment.assetCode!)" )
                }
                print("from: \(nextPayment.from)" )
            }
            else if let nextPayment = payment as? AccountCreatedOperationResponse {
                //...
            }
        }
    case .failure(let error):
        print(error.localizedDescription)
    }
}

You can use the parameters:limit, order, and cursor to customize the query. You can also get most recent payments for accounts, ledgers and transactions.

Horizon has SSE support for push data. You can use it like this:

first define your stream item somwhere to be able to hold the reference:

var streamItem:OperationsStreamItem? = nil

then create, assign and use it:

streamItem = sdk.payments.stream(for: .paymentsForAccount(account: destinationAccountKeyPair.accountId, cursor: nil))

streamItem?.onReceive { (response) -> (Void) in
    switch response {
    case .open:
        break
    case .response(let id, let operationResponse):
        if let paymentResponse = operationResponse as? PaymentOperationResponse {
            switch paymentResponse.assetType {
            case AssetTypeAsString.NATIVE:
                print("Payment of \(paymentResponse.amount) XLM from \(paymentResponse.sourceAccount) received -  id \(id)" )
            default:
                print("Payment of \(paymentResponse.amount) \(paymentResponse.assetCode!) from \(paymentResponse.sourceAccount) received -  id \(id)" )
            }
        }
    case .error(let err):
        print(err?.localizedDescription ?? "Error")
    }
}

later you can close the stream item:

streamItem.close()

3.3 Check others

Just like payments, you you check assets, transactions, effects, offers, operations, ledgers etc. by:

sdk.assets.getAssets()
sdk.transactions.getTransactions()
sdk.effects.getEffects()
sdk.offers.getOffers()
sdk.operations.getOperations()
// add so on ...

4. Building and submitting transactions

Example "send payment":

// create the payment operation
let paymentOperation = PaymentOperation(sourceAccount: sourceAccountKeyPair,
                                        destination: destinationAccountKeyPair,
                                        asset: Asset(type: AssetType.ASSET_TYPE_NATIVE)!,
                                        amount: 1.5)
                                        
// create the transaction containing the payment operation                                        
let transaction = try Transaction(sourceAccount: accountResponse,
                                  operations: [paymentOperation],
                                  memo: Memo.none,
                                  timeBounds:nil)

// sign the transaction
try transaction.sign(keyPair: sourceAccountKeyPair, network: Network.testnet)

// submit the transaction
try sdk.transactions.submitTransaction(transaction: transaction) { (response) -> (Void) in
    switch response {
      case .success(_):
          // ...
      case .failure(_):
          // ...
    }
}

Get a transaction envelope from an XDR string:

let xdrString = "AAAAAJ/Ax+axve53/7sXfQY0fI6jzBeHEcPl0Vsg1C2tqyRbAAAAZAAAAAAAAAAAAAAAAQAAAABb2L/OAAAAAFvYwPoAAAAAAAAAAQAAAAEAAAAAo7FW8r8Nj+SMwPPeAoL4aUkLob7QU68+9Y8CAia5k78AAAAKAAAAN0NJcDhiSHdnU2hUR042ZDE3bjg1ZlFGRVBKdmNtNFhnSWhVVFBuUUF4cUtORVd4V3JYIGF1dGgAAAAAAQAAAEDh/7kQjZbcXypISjto5NtGLuaDGrfL/F08apZQYp38JNMNQ9p/e1Fy0z23WOg/Ic+e91+hgbdTude6+1+i0V41AAAAAAAAAAGtqyRbAAAAQNeY1rEwPynWnVXaaE/XWeuRnOHS/479J+Eu7s5OplSlF41xB7E8u9WzEItaOs167xuOVcLZUKBCBF1fnfzMEQg="
do {
    let envelope = try TransactionEnvelopeXDR(xdr:xdrString)
    let envelopeString = envelope.xdrEncoded
} catch {
    print("Invalid xdr string")
}

Get a transaction object from an XDR string:

let xdrString = "AAAAAJ/Ax+axve53/7sXfQY0fI6jzBeHEcPl0Vsg1C2tqyRbAAAAZAAAAAAAAAAAAAAAAQAAAABb2L/OAAAAAFvYwPoAAAAAAAAAAQAAAAEAAAAAo7FW8r8Nj+SMwPPeAoL4aUkLob7QU68+9Y8CAia5k78AAAAKAAAAN0NJcDhiSHdnU2hUR042ZDE3bjg1ZlFGRVBKdmNtNFhnSWhVVFBuUUF4cUtORVd4V3JYIGF1dGgAAAAAAQAAAEDh/7kQjZbcXypISjto5NtGLuaDGrfL/F08apZQYp38JNMNQ9p/e1Fy0z23WOg/Ic+e91+hgbdTude6+1+i0V41AAAAAA=="
do {
    // Get the transaction object
    let transaction = try Transaction(xdr:xdrString)
    // Convert your transaction back to xdr
    let transactionString = transaction.xdrEncoded
} catch {
    print("Invalid xdr string")
}

5. Using a federation server

The Stellar federation protocol defined in SEP-002 maps Stellar addresses to more information about a given user. It’s a way for Stellar client software to resolve email-like addresses such as:

name*yourdomain.com

into account IDs like:

GCCVPYFOHY7ZB7557JKENAX62LUAPLMGIWNZJAFV2MITK6T32V37KEJU

Stellar addresses provide an easy way for users to share payment details by using a syntax that interoperates across different domains and providers.

5.1 Get federation server address for a domain

Get the federation of your domain:

Federation.forDomain(domain: "https://YOUR_DOMAIN") { (response) -> (Void) in
    switch response {
    case .success(let federation):
        //use the federation object to map your infos
    case .failure(_):
        //something went wrong
    }
}

5.2 Resolve a federation address to an account id

Resolve your addresses:

let federation = Federation(federationAddress: "https://YOUR_FEDERATION_SERVER")
federation.resolve(address: "bob*YOUR_DOMAIN") { (response) -> (Void) in
    switch response {
    case .success(let federationResponse):
        if let accountId = federationResponse.accountId {
            // use the account id
        } else {
            // there is no account id corresponding to the given address
        }
    case .failure(_):
        // something went wrong
    }
}

6. Anchor-Client interoperability

The Stellar Ecosystem Proposal SEP-006 defines the standard way for anchors and wallets to interact on behalf of users. This improves user experience by allowing wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor's site.

This protocol requires anchors to implement endpoints on their TRANSFER_SERVER. An anchor must define the location of their transfer server in their stellar.toml. This is how a wallet knows where to find the anchor's server.

Example: TRANSFER_SERVER="https://api.example.com"

6.1 Get the TransferServerService for a domain

Get the TransferServerService for your domain:

TransferServerService.forDomain(domain: "https://YOUR_DOMAIN") { (response) -> (Void) in
    switch response {
        case .success(let transferServerService):
	        // use the transferServerService object to call other operations
        case .failure(_):
	        // something went wrong
    }
}

6.2 Deposit external assets with an anchor

A deposit is when a user sends an external token (BTC via Bitcoin, USD via bank transfer, etc...) to an address held by an anchor. In turn, the anchor sends an equal amount of tokens on the Stellar network (minus fe


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap