Git Product home page Git Product logo

stellar-ios-mac-sdk's 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.6.2'
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.6.2

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: "[email protected]:Soneso/stellar-ios-mac-sdk.git", from: "2.6.2"),

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)
     }
}

See also: detailed code example

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. See Stellar's lumen buying guide. 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 = try CreateAccountOperation(sourceAccountId: nil,
                                           destinationAccountId: destinationAccountId,
                                           startBalance: 2.0)

// build the transaction
let transaction = try Transaction(sourceAccount: accountResponse,
                                     operations: [createAccount],
                                     memo: Memo.none)
                                     
// 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):
       // ...
    }
}

See also: detailed code example

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.key)")
        }

        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)
    }
}

See also: detailed code example

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)
    }
}

See also: detailed code example

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.

For example get payments for account:

sdk.payments.getPayments(forAccount:keyPair.accountId, order:Order.descending, limit:10)

See also: detailed code example

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

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

var streamItem:OperationsStreamItem? = nil

then create, assign and use it:

streamItem = sdk.payments.stream(for: .paymentsForAccount(account: destinationAccountId, 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()

See also: detailed code example

3.3 Check others

Just like payments, you can 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(sourceAccountId: sourceAccountId,
                                        destinationAccountId: destinationAccountId,
                                        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)

// 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(_):
          // ...
      default:
          // ...
    }
}

See also: detailed code example

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")
}

See also: detailed code example

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

See SDK's SEP-006 docs

7. URI Scheme to facilitate delegated signing

The Stellar Ecosystem Proposal SEP-007 introduces a URI Scheme that can be used to generate a URI that will serve as a request to sign a transaction. The URI (request) will typically be signed by the user’s trusted wallet where she stores her secret key(s).

7.1 Generate a URI for sign transaction.

Generate a URI that will serve as a request to sign a transaction. The URI (request) will typically be signed by the user’s trusted wallet where he stores his secret key(s).

// create the payment operation
let paymentOperation = try! PaymentOperation(sourceAccountId: sourceAccountId,
                                        destinationAccountId: destinationAccountId,
                                        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)
// create the URIScheme object
let uriSchemeBuilder = URIScheme()

// get the URI with your transactionXDR
// more params can be added to the url, check method definition
let uriScheme = uriSchemeBuilder.getSignTransactionURI(transactionXDR: transaction.transactionXDR, callBack: "your_callback_api.com")
print (uriScheme);

See also: detailed code example

7.2 Generate a URI for pay operation

Generate a URI that will serve as a request to pay a specific address with a specific asset, regardless of the source asset used by the payer.

let uriSchemeBuilder = URIScheme()
// more params can be added to the url, check method definition
let uriScheme = uriSchemeBuilder.getPayOperationURI(destination: "GAK7I2E6PVBFF27NU5MRY6UXGDWAJT4PF2AH46NUWLFJFFVLOZIEIO4Q", amount: 100, assetCode: "BTC", assetIssuer:"GC2PIUYXSD23UVLR5LZJPUMDREQ3VTM23XVMERNCHBRTRVFKWJUSRON5", callBack: "your_callback_api.com")
print (uriScheme);

See also: detailed code example

7.3 Sign a transaction from a given URI and send it to the network

Signs a transaction from a URI and sends it to the callback url if present or to the stellar network otherwise.

uriBuilder.signTransaction(forURL: uri, signerKeyPair: keyPair, transactionConfirmation: { (transaction) -> (Bool) in
    // here the transaction from the uri can be checked and confirmed if the signing should continue
    return true
}) { (response) -> (Void) in
    switch response {
    case .success:
    // the transaction was successfully signed
    case .failure(error: let error):
        // the transaction wasn't valid or it didn't pass the confirmation
}

8. Stellar Web Authentication

This SEP defines the standard way for clients such as wallets or exchanges to create authenticated web sessions on behalf of a user who holds a Stellar account. A wallet may want to authenticate with any web service which requires a Stellar account ownership verification, for example, to upload KYC information to an anchor in an authenticated way as described in SEP-6. Stellar Web Authentication is described in SEP-0010.

8.1 Get a JWT token.

Authenticate with a server and get a JWT token.

let authEndpoint = "https://testanchor.stellar.org/auth"
let serverSigningKey = "GCUZ6YLL5RQBTYLTTQLPCM73C5XAIUGK2TIMWQH7HPSGWVS2KJ2F3CHS"
let serverHomeDomain = "testanchor.stellar.org"
let userAccountId = "GB4L7JUU5DENUXYH3ANTLVYQL66KQLDDJTN5SF7MWEDGWSGUA375V44V"
let userSeed = "SBAYNYLQFXVLVAHW4BXDQYNJLMDQMZ5NQDDOHVJD3PTBAUIJRNRK5LGX"

// Hold a strong reference to this to avoid being deallocated
let webAuth = WebAuthenticator(authEndpoint: authEndpoint, network: .testnet,
                                serverSigningKey: serverSigningKey, serverHomeDomain: serverHomeDomain)

let signers = [try! KeyPair(secretSeed: self.userSeed)]
webAuth.jwtToken(forUserAccount: userAccountId, signers: signers) { (response) -> (Void) in
    switch response {
    case .success(let jwtToken):
        print("JWT received: \(jwtToken)")
    case .failure(let error):
        print("Error: \(error)")
    }
}

8.2 Create WebAuthenticator from stellar.toml

Creates the WebAuthenticator by loading the web auth endpoint and the server signing key from the stellar.toml file of the given domain.

let webAuth = WebAuthenticator.from(domain:"yourserverhomedomain.com", network: .testnet)

The Web Authenticator can now be used to get the JWT token (see: 8.1)

9. Txrep: human-readable low-level representation of Stellar transactions

Txrep: human-readable low-level representation of Stellar transactions is described in SEP-0011.

For more details have a look to our Txrep examples

10. Hosted Deposit and Withdrawal

Helps clients to interact with anchors in a standard way defined by SEP-0024: Hosted Deposit and Withdrawal.

See SEP-0024 SDK documentation

11. Account recovery

Enables an individual (e.g., a user or wallet) to regain access to a Stellar account as defined by SEP-0030: Account Recovery.

See SEP-0030: Account Recovery

12. Quotes

see SEP-38 - Anchor RFQ API

13. Regulated Assets

see SEP-08 - Regulated Assets

Documentation and Examples

You can find more documentation and examples in the docs folder.

Sample

Our SDK is used by the open source LOBSTR Vault. You can find the LOBSTR Vault source code here.

Our SDK is also used by the LOBSTR Wallet.

Stellar Ecosystem Proposals (SEPs) supported

Soroban support

This SDK provides support for Soroban.

How to contribute

Please read our Contribution Guide.

Then please sign the Contributor License Agreement.

License

stellar-ios-mac-sdk is licensed under an Apache-2.0 license. See the LICENSE file for details.

Donations

Send lumens to: GANSYJ64BTHYFM6BAJEWXYLVSZVSHYZFPW4DIQDWJL5BOT6O6GUE7JM5

stellar-ios-mac-sdk's People

Contributors

chelemen-razvan avatar christian-rogobete avatar cstephens-phunware avatar istvanelekes avatar kutan74 avatar light-cloud avatar lolpuddle avatar ndizazzo avatar ngybnc avatar oliveratkinson-bc avatar steadyaction avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stellar-ios-mac-sdk's Issues

Could not build Objective-C module 'CSwiftyCommonCrypto'

Hi,
I am trying to build the SDK, but having issues with the module CSwiftyCommonCrypto.

Following errors occur during build:

  • Header '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonHMAC.h' not found

  • Could not build Objective-C module 'CSwiftyCommonCrypto'

Is it necessary to manually handle CommonCrypto in the project ?

Unable to Build and Submit Accounts

Account ID: GAWE7LGEFNRN3QZL5ILVLYKKKGGVYCXXDCIBUJ3RVOC2ZWW6WLGK76TJ
Account Sequence: 513197052264508
Account balance: 9954.4994000 XLM
Sample: Horizon request error of type request failed with message: {
"type": "https://stellar.org/horizon-errors/not_found",
"title": "Resource Missing",
"status": 404,
"detail": "The resource at the url requested was not found. This is usually occurs for one of two reasons: The url requested is not valid, or no data in our database could be found with the parameters provided."
}
Sample: Horizon Error response type: https://stellar.org/horizon-errors/not_found
Sample: Horizon Error response tite: Resource Missing
Sample: Horizon Error response httpStatusCode: 404
Sample: Horizon Error response detail: The resource at the url requested was not found. This is usually occurs for one of two reasons: The url requested is not valid, or no data in our database could be found with the parameters provided.
Sample: Horizon Error response instance: unspecified

Support stellar-core protocol 12

The upcoming stellar-core protocol 12 release will add support for CAP 24 ("Make PathPayment Symmetrical").

To support this change, the following steps are necessary:

  • Existing PathPayment operation should be deprecated (it will be renamed to PathPaymentStrictReceive in protocol 12, with behavior unchanged). Consider adding the new operation name immediately as an alias during the transition period.
  • Once v12 is voted on and is adopted by the network, a new operation, PathPaymentStrictSend will be available and should be provided. This is expected to happen around the end of October, 2019.
  • Horizon will continue to provide the old path_payment operation name in responses until Horizon 0.24. Both types of path_payment operation will be returned with the existing name. In Horizon release 0.24 (targeted for ~10 weeks from now), Horizon will change, and begin to return path_payment_strict_receive and path_payment_strict_send in the type field of responses that refer to operations or payments. You should update client code if necessary (e.g. for validation) and note this for users.

For further information, see the following issues in the SDF Go monorepo:

Path Payment Path Assets not optional

Creating a path payment operation seems to require the path of assets a transaction goes through. I would like to have it optional and let the Stellar network decide what path to take.

Is that possible? I tried building a path payment transaction without the path: [Asset] option but it will not let me as it is not optional.

Added stellar-ios-mac-sdk in my framework.

Hi, I have a problem. I make my library based on yours but there are problems in the absence of modules.

My flow:
1- Create Cocoa touch framework
2- Pod init
3- past this in pod file :

      _platform :ios, '9.0'
      target 'ProstoLibrary' do
      use_modular_headers!
       pod 'stellar-ios-mac-sdk', '~> 1.5.6'

end_

4- pod install
5- open *.xcworkspace
6- cmd+b
7- error (no such module)
Screen Shot 2019-04-17 at 2 55 32 PM

Who faced, tell me how to solve this problem please. Or maybe some other flow.

IOS 9 crashing while creating SHA512 hash

Crash in one of third party libs
// |||||||||||||||| SMP Core.swift ||||||||||||||||
// Created by Marcel Kröker on 30.09.16.
// Copyright (c) 2016 Blubyte. All rights reserved.

For Big Int, while trying to make 2048 iterations SHA512 hash from 24 words.

Identify client SDK + version in request headers

As described in stellar/go#725, it would be really helpful if this SDK sent two simple headers with each request, identifying the SDK and version:

two headers are sent: client name (X-Client-Name) and version (X-Client-Version)

This will help maintainers of public Horizon instances understand where their traffic is coming from, and allow them to assess the impact of upgrading their Horizon version (for example they might delay upgrading to a version with breaking changes not handled by a client SDK with significant traffic to the server).

TransactionResponse fails parsing when number of characters is == 28

Description

When attempting to parse a transaction list for an account, a max-length Memo text string causes the SDK to fail parsing during the TransactionResponse init(from decoder: Decoder) method.

Problem

The transaction in question is: 47fa1432223fe0a1fcd84f4cabeedf6d77f1a27cfa20f4c3e47f15238150adae

Note the memo is exactly 28 characters long, causing the following check to fail because of the null terminated C-string:

if text.utf8CString.count > 28 { ... }

Console Debug Output

decoding 47fa1432223fe0a1fcd84f4cabeedf6d77f1a27cfa20f4c3e47f15238150adae
(lldb) po memo
▿ Optional<String>
  - some : "https://gift-stellarterm.org"

(lldb) po memoType
"text"

(lldb) po Memo(text: memo)
▿ StellarSDKError
  ▿ invalidArgument : 1 element
    - message : "text must be <= 28 bytes. length=28"

  Fix-it applied, fixed expression was: 
    Memo(text: memo as! String)

(lldb) po memo.self
▿ Optional<String>
  - some : "https://gift-stellarterm.org"

(lldb) po Memo(text: "https://gift-stellarterm.or")
▿ Optional<Memo>
  ▿ some : Memo
    - text : "https://gift-stellarterm.or"

(lldb) po Memo(text: "https://gift-stellarterm.org")
▿ StellarSDKError
  ▿ invalidArgument : 1 element
    - message : "text must be <= 28 bytes. length=28"

(lldb) po text.utf8CString
▿ 29 elements
  - 0 : 104
  - 1 : 116
  - 2 : 116
  - 3 : 112
  - 4 : 115
  - 5 : 58
  - 6 : 47
  - 7 : 47
  - 8 : 103
  - 9 : 105
  - 10 : 102
  - 11 : 116
  - 12 : 45
  - 13 : 115
  - 14 : 116
  - 15 : 101
  - 16 : 108
  - 17 : 108
  - 18 : 97
  - 19 : 114
  - 20 : 116
  - 21 : 101
  - 22 : 114
  - 23 : 109
  - 24 : 46
  - 25 : 111
  - 26 : 114
  - 27 : 103
  - 28 : 0

(lldb) po text.utf8CString.count
29

(lldb) po text.count
28

Proposed Fix

Replace text.utf8CString.count with text.count

SDK needs to be updated to handle Horizon 0.17.0 breaking changes

In Horizon release 0.17.0 (released 26 Feb 2019), several breaking changes were made (changelog), changing or removing fields that had previously been marked as deprecated.

Breaking changes

Fields removed in this version:
    Root > protocol_version, use current_protocol_version and core_supported_protocol_version.
    Ledger > transaction_count, use successful_transaction_count and failed_transaction_count.
    Signer > public_key, use key.
This Horizon version no longer supports Core <10.0.0. Horizon can still ingest version <10 ledgers.
Error event name during streaming changed to error to follow W3C specification.

Here is the relevant Horizon commit, showing the fields that were changed: stellar/go@575707e

This is an urgent issue! Any code using this SDK to access a Horizon 0.17.0 server (which includes the SDF public horizon instance at https://horizon.stellar.org/) will be broken until the SDK is updated to match the new response fields.

Reason: image not found

I added your SDK to my project and it build successfully but when add the code

@IBAction func AA(_ sender: Any) {
    
    let keyPair = try! KeyPair.generateRandomKeyPair()
    publicKeyText.text = keyPair.accountId
    privateKeyText.text = keyPair.secretSeed
}

It show the error that
dyld: Library not loaded: @rpath/libswiftSwiftOnoneSupport.dylib
Referenced from: /Users/onnz/Library/Developer/Xcode/DerivedData/AAApple-dpiwihmukivykxecjcqukwbxnjxo/Build/Products/Debug-iphonesimulator/stellarsdk.framework/stellarsdk
Reason: image not found
(lldb)

Some amounts overflow in XDR

Some amounts overflow when they are encoded in XDR.

Sample amount:

▿ 0.18050270000000002048
  ▿ _mantissa : 8 elements
    - .0 : 59392
    - .1 : 14819
    - .2 : 28910
    - .3 : 64127
    - .4 : 0
    - .5 : 0
    - .6 : 0
    - .7 : 0

Encoded Amount: -0.0039647 (raw: -39647)

Sample Response:

{\n  \"type\": \"https://stellar.org/horizon-errors/transaction_failed\",\n  \"title\": \"Transaction Failed\",\n  \"status\": 400,\n  \"detail\": \"The transaction failed when submitted to the stellar network. The `extras.result_codes` field on this response contains further details.  Descriptions of each code can be found at: https://www.stellar.org/developers/learn/concepts/list-of-operations.html\",\n  \"extras\": {\n    \"envelope_xdr\": \"AAAAAJoY8kcE4G/6PqnzgNutcZ6Ffu22hOTbo1OS0RRhSLEZAAAAZACfbX4AAABgAAAAAAAAAAAAAAABAAAAAQAAAACaGPJHBOBv+j6p84DbrXGehX7ttoTk26NTktEUYUixGQAAAAEAAAAAdxM91EE5PqEiQmQg9oR2q2gxA50UA47qDj8GlYjrenQAAAABT0cAAAAAAAB8CTr1M3808ueF/pik9o3XLuo85lEv/PQVDVgGdMxkxP///////2UhAAAAAAAAAAFhSLEZAAAAQFSjH9sG6N0VgHu7KcPc+ICOCpy9eWwgpBhZMyhVwKVdQYSJVYuEL2H+uGJVf76rJa1losFNYYlFW6QJl5ImLQ0=\",\n    \"result_codes\": {\n      \"transaction\": \"tx_failed\",\n      \"operations\": [\n        \"op_malformed\"\n      ]\n    },\n    \"result_xdr\": \"AAAAAAAAAGT/////AAAAAQAAAAAAAAAB/////wAAAAA=\"\n  }\n}

issue on getAccountDetails and getPayments.

Hey,
When I try to get account details and payments it is giving this error.
"The operation couldn’t be completed. (stellarsdk.HorizonRequestError error 4.)
error!"

version: "1.6.0"

TransactionMetaXDR decode error after submitting Transaction

after submitting Transaction, I got an error Error 6 when decoding transaction xdr

  • SubmitTransactionResponse.swift
  public required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        transactionHash = try values.decode(String.self, forKey: .transactionHash)
        ledger = try values.decode(Int.self, forKey: .ledger)
        
        let encodedEnvelope = try values.decode(String.self, forKey: .envelopeXDR)
        let data = Data(base64Encoded: encodedEnvelope)!
        transactionEnvelope = try XDRDecoder.decode(TransactionEnvelopeXDR.self, data:data)
        
        let encodedResult = try values.decode(String.self, forKey: .transactionResult)
        let resultData = Data(base64Encoded: encodedResult)!
        transactionResult = try XDRDecoder.decode(TransactionResultXDR.self, data:resultData)
        
        let encodedMeta = try values.decode(String.self, forKey: .transactionMeta)
        let metaData = Data(base64Encoded: encodedMeta)!
        transactionMeta = try XDRDecoder.decode(TransactionMetaXDR.self, data:metaData)
    }

error occured try decode TransactionMetaXDR

the encodedMeta is

AAAAAQAAAAIAAAADATEGnQAAAAAAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAAAAktbYgEYwUoAAAD/AAAAAwAAAAEAAAAANlpgrn2zruLzED+4q1QzmnE7X3HhGRq7qInv0I8hSDEAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABATEGnQAAAAAAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAAAAktbYgEYwUoAAAEAAAAAAwAAAAEAAAAANlpgrn2zruLzED+4q1QzmnE7X3HhGRq7qInv0I8hSDEAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAABwAAAAABMQadAAAAAgAAAABNHexE1sx+XZc4AYKtyh77tQDjdt+CraLsyZgH6/LJIQAAAAAB2FITAAAAAVhGRgAAAAAAMkvqkqBYyxY5LL/6jTi9CrujmTFfa/phbkUpkhZqy5YAAAABWENOAAAAAACbjrr4ljhVHc+epPdDIHEQa4erDi2z1pt1pTgicvdZ2AAAAAAAmJaAAADqWgABhqAAAAAAAAAAAAAAAAAAAAADATEGnQAAAAAAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAAAAktbYgEYwUoAAAEAAAAAAwAAAAEAAAAANlpgrn2zruLzED+4q1QzmnE7X3HhGRq7qInv0I8hSDEAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABATEGnQAAAAAAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAAAAktbYgEYwUoAAAEAAAAABAAAAAEAAAAANlpgrn2zruLzED+4q1QzmnE7X3HhGRq7qInv0I8hSDEAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAADATEF4wAAAAEAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAABWENOAAAAAACbjrr4ljhVHc+epPdDIHEQa4erDi2z1pt1pTgicvdZ2AAAAAAChjWwYitIJrNCAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBMQadAAAAAQAAAABNHexE1sx+XZc4AYKtyh77tQDjdt+CraLsyZgH6/LJIQAAAAFYQ04AAAAAAJuOuviWOFUdz56k90MgcRBrh6sOLbPWm3WlOCJy91nYAAAAAAKGNbBiK0gms0IAAAAAAAEAAAABAAAAAABbiygAAAAAAAAAAAAAAAAAAAAAAAAAAwExBeMAAAABAAAAAE0d7ETWzH5dlzgBgq3KHvu1AON234KtouzJmAfr8skhAAAAAVhGRgAAAAAAMkvqkqBYyxY5LL/6jTi9CrujmTFfa/phbkUpkhZqy5YAAAAAqNn0NmIrSCazQgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABATEGnQAAAAEAAAAATR3sRNbMfl2XOAGCrcoe+7UA43bfgq2i7MmYB+vyySEAAAABWEZGAAAAAAAyS+qSoFjLFjksv/qNOL0Ku6OZMV9r+mFuRSmSFmrLlgAAAACo2fQ2YitIJrNCAAAAAAABAAAAAQAAAAAAAAAAAAAAAACYloAAAAAAAAAAAA==

Memory leak at Base32Decode.swift

Memory leak at function
func Base32Decode(data: String, alphabet: Array<Int>, characters: Array<String>) -> Data?

Memory leak supposedly here
Data(bytesNoCopy: buffer, count: totalNumberOfBytes, deallocator: .free)

KeyPair secreteseed falsely accepts public key

After fighting with a 404 "Resource Missing" response, I realized that I have mistakenly provided a public key instead of a secret key into the following function:
let sourceAccountKeyPair = try! KeyPair(secretSeed: "G...")

I think a good solution to this would be to check the first character that it's in fact a secret key since they all start with an "S" and all public keys start with a "G". -> print or throw an error

Update challenge transaction helpers for SEP-10 v1.3.0

Summary

A change has been released in SEP-10 Web Authentication v1.3.0 that adds support for:

  1. Accounts not using the master key as a signer.
  2. Accounts multiple signers.

SEP-10 v1.3.0 Change: stellar/stellar-protocol@ea0d7ed

The new functionality requires changes to any SDK implementing challenge verification.

Details and Reference Implementations

The Stellar Go SDK is the first SDK we've implemented this new functionality and it can be used as a reference. It has implemented the following changes and similar changes may be required in this SDK:

  • Deprecated the existing verification function (VerifyChallengeTx).
  • Added new functions to:
    • Read the client account ID out of a challenge transaction without verifying client signatures, so that servers can lookup the signers of the account before verifying. (ReadChallengeTx)
    • Verify signatures on a challenge transaction meet a threshold. (VerifyChallengeTxThreshold)
    • Verify signatures on a challenge transaction match signers. (VerifyChallengeTxSigners)
  • Increased the timeout on the challenge transaction from 5 minutes to 15 minutes.

Go SDK Change: stellar/go@8ff0848

An example of a SEP-10 server using the v1.3.0 verification process is implemented here:
https://github.com/stellar/go/tree/master/exp/services/webauth

If anyone has any questions feel free to join us in #dev-discussion in stellar.public Keybase.

Payment stream in in background

Hi guys, thank you for library!

Could you, please provide with some example how to make working payment stream when application is in background? Thank you in advance!

I've edited my code as explained here: #56 (comment)

When app is in foreground all work like expected, when in background nothing and after entering foreground the following error:
HTTP load failed (error code: 53 [1:53])
finished with error - code: 53
load failed with error Error
load failed with error Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <694DD23A-7B6A-417C-A281-C693AF311BF3>.<1>, _kCFStreamErrorDomainKey=1, NSErrorPeerAddressKey=<CFData 0x2814b3110 [0x24010d430]>{length = 16, capacity = 16, bytes = 0x100201bb22edc33f0000000000000000}, _kCFStreamErrorCodeKey=53, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <694DD23A-7B6A-417C-A281-C693AF311BF3>.<1>"

than value is printed to console output.

Data Couldn't Be Read Because it is Missing

I'm trying to fetch the details of an account, but I'm receiving the following error:

failure(error: stellarsdk.HorizonRequestError.parsingResponseFailed(message: "The data couldn’t be read because it is missing."))

My best guess is that I'm somehow making the request on the wrong network, but I really don't have a clue. Here is my code:

Stellar.sdk.accounts.getAccountDetails(accountId: accountId) { (response) -> (Void) in

The Stellar struct looks like this:

public struct Stellar {
    static let sdk = StellarSDK(withHorizonUrl: HorizonServer.url)
    static let network = Network.testnet
}

public struct HorizonServer {
    static let production = "https://horizon.stellar.org"
    static let test = "https://horizon-testnet.stellar.org/"
    static let url = HorizonServer.test
}

Horizon Release v0.18.0 Compatibility

Hey @christain-rogobete, we actually pushed back the renames mentioned in #58 to 0.19.0, but wanted to send this your way regarding the other deprecations present — feel free to close if you're already good to go.

Horizon 0.18.0 Release

Horizon 0.18.0 has been released, which continues additional work for a better integration with Stellar Protocol 11. This release contains breaking changes from 0.17.*, including a requirement to use Postgres 9.5+, along with various changes, including deprecations, that further support the protocol changes presented in CAP-0005 and CAP-0006.

You can find the official release on Github; below are the release notes.

This issue has been filed as a reminder for compatibility — if your SDK is already compatible, feel free to just respond on the thread and close it out. Thank you, and let me know if you have any questions!

Breaking changes

  • Horizon requires Postgres 9.5+.
  • Removed paging_token field from /accounts/{id} endpoint.
  • Removed /operation_fee_stats endpoint. Please use /fee_stats.

Deprecations

  • fee_paid field on Transaction resource has been deprecated and will be removed in 0.19.0. Two new fields have been added: max_fee that defines the maximum fee the source account is willing to pay and fee_charged that defines the fee that was actually paid for a transaction. See CAP-0005 for more information.
  • The following operation type names have been deprecated: manage_offer and create_passive_offer. The names will be changed to: manage_sell_offer and create_passive_sell_offer in 0.19.0.

Changes

  • The following new config parameters were added. When old max-db-connections config parameter is set, it has a priority over the the new params. Run horizon help for more information.
    • horizon-db-max-open-connections
    • horizon-db-max-idle-connections
    • core-db-max-open-connections
    • core-db-max-idle-connections
  • Fixed fee_paid value in Transaction resource ( #1358 ).
  • Fix int64: value out of range errors in trade aggregations ( #1319 ).
  • Improved horizon db reingest range command.

Error on parsing payment operation's response

Payment operation's response is not getting parsed. This used to work, so there might something changed on Horizon APIs. Tested with 1.1.5.

Error description:

HorizonRequestError: parsingResponseFailed : "The operation couldn’t be completed. (stellarsdk.XDRDecoder.Error error 6.)"

User code:

var memo: Memo

if let memoID = memoID {
    memo = Memo.id(memoID)
} else {
    memo = Memo.none
}

let paymentOperation = PaymentOperation(sourceAccount: keyPair, destination: try KeyPair(accountId: destinationAccountID), asset: asset, amount: amount)
let transaction = try Transaction(sourceAccount: accountResponse, operations: [paymentOperation], memo: memo, timeBounds: nil)
try transaction.sign(keyPair: keyPair, network: MPConfig.STELLAR_NETORK)
try StellarSDK(withHorizonUrl: MPConfig.URL_HORIZON).transactions.submitTransaction(transaction: transaction) { (transactionPostResponse) -> (Void) in
    
    switch transactionPostResponse {
//                    case .success(let submitTransactionResponse):
    case .success(_):
        fulfill(())
    case .failure(let horizonRequestError):
        reject(horizonRequestError)
    }
    
}

Response:
{
"_links": {
"transaction": {
"href": "https://horizon-testnet.stellar.org/transactions/89e43763c72331af432fb3db241b723e82370e0802d4a17c5c32d6284a9124d2"
}
},
"hash": "89e43763c72331af432fb3db241b723e82370e0802d4a17c5c32d6284a9124d2",
"ledger": 10642164,
"envelope_xdr": "AAAAAN1u4nbfMpcFr71wNt1ViTlk/hS59jD0pMcyXzm3pfBFAAAAZACdq+gAAAARAAAAAAAAAAAAAAABAAAAAQAAAADdbuJ23zKXBa+9cDbdVYk5ZP4UufYw9KTHMl85t6XwRQAAAAEAAAAAv3PZYYqz1lB5qjK5R7Kn7MyHfHTIYxjTLqqSYEtjQ7QAAAABT0cAAAAAAAB8CTr1M3808ueF/pik9o3XLuo85lEv/PQVDVgGdMxkxAAAAAABCGO3AAAAAAAAAAG3pfBFAAAAQOTIsPSPYGnyrvEwGfsLChKiddgrA3YOf8ayHZr4tCavUXLRHh3UgxG3ncoiqDIY7sFTME+5pt9gAoKwLb7WnQo=",
"result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=",
"result_meta_xdr": "AAAAAQAAAAIAAAADAKJi9AAAAAAAAAAA3W7idt8ylwWvvXA23VWJOWT+FLn2MPSkxzJfObel8EUAAAAA2F1ihgCdq+gAAAAQAAAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAKJi9AAAAAAAAAAA3W7idt8ylwWvvXA23VWJOWT+FLn2MPSkxzJfObel8EUAAAAA2F1ihgCdq+gAAAARAAAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAMAomLmAAAAAQAAAAC/c9lhirPWUHmqMrlHsqfszId8dMhjGNMuqpJgS2NDtAAAAAFPRwAAAAAAAHwJOvUzfzTy54X+mKT2jdcu6jzmUS/89BUNWAZ0zGTEAAAAGuuJGGAG8FtZ07IAAAAAAAEAAAAAAAAAAAAAAAEAomL0AAAAAQAAAAC/c9lhirPWUHmqMrlHsqfszId8dMhjGNMuqpJgS2NDtAAAAAFPRwAAAAAAAHwJOvUzfzTy54X+mKT2jdcu6jzmUS/89BUNWAZ0zGTEAAAAGuyRfBcG8FtZ07IAAAAAAAEAAAAAAAAAAAAAAAMAomLmAAAAAQAAAADdbuJ23zKXBa+9cDbdVYk5ZP4UufYw9KTHMl85t6XwRQAAAAFPRwAAAAAAAHwJOvUzfzTy54X+mKT2jdcu6jzmUS/89BUNWAZ0zGTEAAAAEqAibDYCf30L25IAAAAAAAEAAAAAAAAAAAAAAAEAomL0AAAAAQAAAADdbuJ23zKXBa+9cDbdVYk5ZP4UufYw9KTHMl85t6XwRQAAAAFPRwAAAAAAAHwJOvUzfzTy54X+mKT2jdcu6jzmUS/89BUNWAZ0zGTEAAAAEp8aCH8Cf30L25IAAAAAAAEAAAAAAAAAAA=="
}

I can't check balance from this day....(ios).

Hi!
I used code such as:
sdk.accounts.getAccountDetails(accountId: keyPair.accountId) { (response) -> (Void) in
switch response { from https://github.com/Soneso/stellar-ios-mac-sdk

in my implementation:

StellarSDK().accounts.getAccountDetails(accountId: Account.getAccountID()) { (response) -> Void in
switch response {
case .success(let accountDetails):

            for balance in accountDetails.balances {

                switch balance.assetType {
                case AssetTypeAsString.CREDIT_ALPHANUM4:

                    DispatchQueue.main.async {
                        completion((balance.balance.currencyFormatting(), balance.assetCode!, balance.balance))
                    }
                default: break
                }
            }
        case .failure(let error):
            print(error.localizedDescription)
        }
    }

accountId - correct
I see response error The operation couldn’t be completed. (stellarsdk.HorizonRequestError error 11.).
Yesterday everything worked correctly and I did not make any changes to the code.

I need Your help!

Stellar Protocol 11 Compatibility

Protocol V11 of Stellar adds a new manage_buy_offer operation. Also names of manage_offer and create_passive_offer have been changed to manage_sell_offer and create_passive_sell_offer.

References:

Let me know if you have any questions!

Adding data in MEMO_HASH (iOS). Need help!

Hi!
I want to add some information (such as dictionary) in MEMO_HASH in my transaction (get data from QR) and than, in other side - read this info and using it.
Can you give advice - how create this most effective?

Great thanks!

Сhecksum issue in Mnemonic.create

Function Mnemonic.create uses 8-bit checksum (for 24 words seed) during mnemonic words seed generation.
But neither Wallet.createKeyPair nor Mnemonic.createSeed are checking checksum.

submitTransaction error

Hi! There is a problem.
I created a new account on the public network and I can verify this using https://stellar.expert/explorer/public/.
Everything is correct - the account is open. To get account details, I use StellarSDK (withHorizonUrl: "https://horizon.stellar.org") .accounts.getAccountDetails - and get a valid response.
Next, I need to change the trustline for which I call try StellarSDK (withHorizonUrl: "myHorizonUrl") .transactions.submitTransaction (transaction: transaction).
In this call, I use a unique horizonUrl.
I get error 401 // Unauthorized. What am I doing wrong?
This is an account https://stellar.expert/explorer/public/search?term=GADKWDVTMPW6A6VG7I2SXWYPDJC6SSUNOZKH7JB4C46KVZJZFP75YTIZ
Thanks!

getAccountDetails not working !

Hi, I need Your help !

I'm created account in test net and checking it - he exists.
When I using getAccountDetails with "https://horizon-testnet.stellar.org" - I have error "The data couldn’t be read because it is missing."
When "https://horizon.stellar.org" as in the example above -

notFound(message: "{\n "type": "https://stellar.org/horizon-errors/not_found\",\n "title": "Resource Missing",\n "status": 404,\n "detail": "The resource at the url requested was not found. This is usually occurs for one of two reasons: The url requested is not valid, or no data in our database could be found with the parameters provided."\n}", horizonErrorResponse: Optional(<stellarsdk.NotFoundErrorResponse: 0x281e3fe30>))

my account "GB33EPYLVRLD6GTCRLSBCXET35TZKJJCQDRQZHLR5UNNNWWTHMD4IL4B".

And I using

let sdk = StellarSDK.init(withHorizonUrl: "https://horizon.stellar.org")
let account = "GB33EPYLVRLD6GTCRLSBCXET35TZKJJCQDRQZHLR5UNNNWWTHMD4IL4B"

sdk.accounts.getAccountDetails(accountId: account) { response -> Void in
switch response {
case .success(let details):
print(details.balances)
print(details.accountId)
case .failure(let error):
print(error)
}
}

But it's not works for me.
Thank You !

Support for Swift Package Manager

As a developer, I would like to be able to use the native Swift Package Manager (SPM) to install and consume the SDK. Documentation for achieving this can be found on the Swift.org website.

This is motivated by the desire to use pure Swift projects, such as server-side Swift frameworks like Vapor, without the need to use external tooling like CocoaPods and Carthage.

More generally, it may be worth asking, should this be thought of as a "stellar-swift" client, or as a client specific to macOS and iOS as the name/description suggests?

Using the iOS SDK on an application extension

I am trying to use the iOS SDK in a network extension and getting these ld warnings:

ld: warning: linking against a dylib which is not safe for use in application extensions: /Users/umit/Library/Developer/Xcode/DerivedData/Meshkat-gwogyokwgikwifetcprpfclgujwh/Build/Products/Release-iphoneos/stellarsdk.framework/stellarsdk

According to documentation, submitting my app to iTunes Connect without clearing these warnings will cause a rejection.

https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html

Again from documentation:

"To configure an app extension target to use an embedded framework, set the target’s “Require Only App-Extension-Safe API” build setting to Yes. If you don’t, Xcode reminds you to do so by displaying the warning “linking against dylib not safe for use in application extensions”."

Thanks a lot!

Horizon v0.18.0 Compatibility

With Horizon v0.18.0, the following breaking changes will occur:

  • The manage_offer endpoint will be renamed to manage_sell_offer
  • The create_passive_offer endpoint will be renamed to create_passive_sell_offer.

We suggest for all Stellar SDK maintainers to offer compatibility between v.0.17.X type names as well as the new names in v.0.18.0 in order to make the transition process from v0.17.X to v0.18.0 to go smoother.

Let me know if you have any questions!

Carthage Update Error

"carthage update" command gives this error:

"*** Skipped building stellar-ios-mac-sdk due to the error:
Dependency "stellar-ios-mac-sdk" has no shared framework schemes"

To reproduce, add "github "soneso/stellar-ios-mac-sdk" ~> 1.1.4" to Cartfile and then run "carthage update"

Error: Cyclic dependency in module 'CSwiftyCommonCrypto'

After upgrading to Xcode10/Swift 4.2 I'm getting an error in Data+Hash.swift:

Could not build Objective-C module 'CSwiftyCommonCrypto'

In CommonCrypto.h:
Cyclic dependency in module 'CSwiftyCommonCrypto': CSwiftyCommonCrypto -> CommonCrypto -> CSwiftyCommonCrypto.

In CommonHMAC.h:
Could not build module 'CommonCrypto'.

Any idea why?

Add transaction fee to a Transaction object from parsed XDR string

Hi guys, at this moment you are only adding maxOperationFee to transactions created with your sdk. However, maxOperationFee is not included when parsing a XDR string. To be more specific, the following is the scenario I think the sdk should cover:

  1. There is a tx with a fee, of let us say of 1000 stroops, that is sent to the ios client to be signed
  2. the client parses XDR string and takes the fee in addition to the other fields needed
  3. The client creates a tx and signs it

Currently, if you send a tx to be signed by the sdk, the sdk overwrites whatever fee was sent with the default 100 stroops. I see that this is because you are taking the fee coming in the XDR in your convenience init methods in lines 71 and 95

Question about streaming

Hi Guys,

I am giving it a try to your sdk and have a question related to streaming. Will the sdk try to reconnect in case the connection is dropped due to errors? In here the guys from stellar recommend to use their sdk because for some errors the event source object will not reconnect.

Thanks in advance!

Horizon v1.0.0 Compatibility

The upcoming Horizon release is coming, and there are multiple breaking changes plus new features 🎉🎉🎉!

The following are the list of changes required to support this new release:

  • ➕Update /fee_stats response.

    • ✂ Remove the following fields:

      min_accepted_fee
      mode_accepted_fee
      p10_accepted_fee
      p20_accepted_fee
      p30_accepted_fee
      p40_accepted_fee
      p50_accepted_fee
      p60_accepted_fee
      p70_accepted_fee
      p80_accepted_fee
      p90_accepted_fee
      p95_accepted_fee
      p99_accepted_fee
    • ➕Add support for max_fee and fee_charged fields. Each field contains a JSON object that looks like this:

      {
        "last_ledger": "22606298",
        "last_ledger_base_fee": "100",
        "ledger_capacity_usage": "0.97",
        "fee_charged": {
          "max": "100",
          "min": "100",
          "mode": "100",
          "p10": "100",
          "p20": "100",
          "p30": "100",
          "p40": "100",
          "p50": "100",
          "p60": "100",
          "p70": "100",
          "p80": "100",
          "p90": "100",
          "p95": "100",
          "p99": "100"
        },
        "max_fee": {
          "max": "100000",
          "min": "100",
          "mode": "100",
          "p10": "100",
          "p20": "100",
          "p30": "100",
          "p40": "100",
          "p50": "100",
          "p60": "100",
          "p70": "100",
          "p80": "100",
          "p90": "15000",
          "p95": "100000",
          "p99": "100000"
        }
       }

    See stellar/go#2140 for more info.

  • ✂ Remove deprecated fee_paid field from Transaction response (replace it with the fee_charged and max_fee fields, see #1372).

  • 🚨Multiple fields changed from int64 to string. If your SDK has types, they need to be updated. If possible, we recommend implementing backward compatibility support, as we did here.

    See stellar/go#1609, stellar/go#1909, and stellar/go#1912 for more info

  • 🚨 Update operation types to canonical names (if needed) (see stellar/go#2134).

  • ➕Add support for /accounts end-point with ?signer and ?asset filters. We recommend a method like .accounts(queryParams) (see documentation for accounts).

  • ➕Add support for /offers end-point with query parameters. We recommend a method like .offers(queryParams) (see documentation for offers).

  • ➕Add support for /paths/strict-send end-point. See documentation.
    We recommend a method like

    strictSendPaths(sourceAsset, sourceAmount, [destinationAsset])
    
  • ➕ Add support for /paths/strict-receive end-point. See documentation.
    We recommend a method like:

    strictReceivePaths(sourceAssets,destinationAsset, destinationAmount)
    
  • ♻ Regenerate the XDR definitions to include MetaV2 support (also see #1902).

That's it! If you have any questions feel free to ping us on #dev-discussion in Keybase.

swift payments.stream HELP WANTED

Hello!
I'm using code for detect any payments to the my wallet:

StellarSDK().payments.stream(for: .paymentsForAccount(account: Account.accountID, cursor: "now")).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.CREDIT_ALPHANUM4:
print("Payment of (paymentResponse.amount) 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")
}
}

Account.accountID - it's my wallet account id.
I got money transaction (+ on my wallet), but I have't see any result via this stream!
Can you help me? What I'm doing wrong?

EventSource missing return in didCompleteWithError?

@chelemen-razvan (tagging since you worked on this originally)

I noticed quite a bit of error output being logged when using any streaming endpoint for an account.

Digging in, I saw that Apple's documentation states that urlSession(... didCompleteWithError) is only called when error on the client side is encountered, but not when a server side error is encountered.

To test this out, I added an implementation of urlSession(... didBecomeInvalidWithError) delegate method to see if there actually is a server side error, but this delegate method is not called.

So if there aren't really any errors, wouldn't the SDK need a return in the block where the nil check for error is (right after line 184)?

if error == nil || (error! as NSError).code != -999 {

As implemented right now when there's no error, self.connect() will be called in this block, and then the error callback will immediately be invoked if there is one.

It seems to me like this should return in that block after re-establishing the stream connection instead of continuing on, but I'm not really sure about the intentions of the implementation.

Price.fromString appears to be inaccurate

I'm trying to construct a price for a ManageOfferOperation by passing a string to Price.fromString(price), but the return value is negative.

In the case where I pass "7.76" the return values are {-2147483648, -2147483648} when they should be {194,25}.

I see code comments that state the function gives "unexpected results", and suggests initializing a price by passing a numerator & denominator instead. If you want to bid 7.76 for an asset, how would you know to pass {194, 25} if the fromString method gives inaccurate results?

Get bytes array from memo.toXDR (where memo is hash) ! (iOS)

Hi!
In my transactions I'm using hash memo.
I need get array of bytes for getting data from him.

What I must doing with this memo.toXDR?
In Java we have input bytes array.

I can't find any help in web. Please, can you advise me what I must doing with xdr for getting bytes array from him?

Great thanks for any help!

Decoding problem

Hi, would like to clarify one point. I have an issue with the recovery of unsigned tranasction for signature. Such transaction is formed on backend NodeJS. Then it coordinates to toEnvelop, ten to xdr and finally to base64. How can I properly restore signTX on my swift 4.2 and send it?

This from backend.
2018-11-15 16 40 46

Response:
screen shot 2018-11-15 at 4 23 21 pm

Decode and sign transactions

I would like to decode an unsigned transaction envelope that is created and encoded (Base64 XDR) on my backend (Java). Then I want to sign it, and send it back to the server encoded.
Is it possible using this library?
Thanks,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.