Giter Site home page Giter Site logo

uphold-sdk-ios's Introduction

Uphold SDK for iOS Build Status Carthage compatible CocoaPods

Uphold is a next generation platform that allows anyone to transfer and exchange value for free, instantly and securely.

The Uphold SDK for iOS provides an easy way for developers to integrate iOS applications with the Uphold API.

Requirements

* Xcode 8
* Swift 3
* Carthage or CocoaPods

Installation

Using CocoaPods

  1. Add to your Podfile.

    platform :ios, '10.0'
    use_frameworks!
    
    # To use Uphold's production environment.
    pod 'UpholdSdk/Production'
    
    # To use Uphold's sandbox environment:
    # pod 'UpholdSdk/Sandbox'
    
  2. Run pod install.

Using Carthage

  1. Add to your Cartfile.

    github "uphold/uphold-sdk-ios" ~> 0.17.0
    
  2. Run carthage update --platform iOS specifying the build configuration to use Uphold's different environments.

    # To use Uphold's production environment.
    carthage update --platform iOS --configuration ProductionRelease
    
    # To use Uphold's sandbox environment:
    # carthage update --platform iOS --configuration SandboxRelease
    

Basic usage

In order to learn more about the Uphold API, please visit the developer website.

To use the SDK you must first register an Application and obtain a unique CLIENT_ID and CLIENT_SECRET combination. We recommend your first app be registered in the Sandbox environment, so you can safely play around during development.

From the application page in your account you can get the client id, client secret , configure the redirect URI and the desired scopes.

Authenticate User

In order to allow users to be re-directed back to the application after the authorization process, you’ll need to associate your custom scheme with your app by adding the following keys into the Info.plist file:

  • CFBundleURLTypes - The list of URLs types to be handled by the application.
    • CFBundleURLSchemes - The custom application schemes.

For instance, our demo application has the following configuration:

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>uphold-demo</string>
            </array>
        </dict>
    </array>

We start the authentication process by instantiating the UpholdClient and then calling the beginAuthorization method:

/// LoginViewController.swift

let upholdClient = UpholdClient()
let authorizationViewController = upholdClient.beginAuthorization(self, clientId: CLIENT_ID, scopes: scopes, state: state)

In the AppDelegate class you'll need to implement the method application(application: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool that is called when the user completes the authorization process.

/// AppDelegate.swift

func application(application: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
    loginViewController.completeAuthorization(url)

    return true
}

To complete the authorization process you'll need to call the completeAuthorization method from the upholdClient and get the user bearer token from the authentication response.

/// LoginViewController.swift

upholdClient.completeAuthorization(authorizationViewController, clientId: CLIENT_ID, clientSecret: CLIENT_SECRET, grantType: "authorization_code", state: state, uri: url).then { (response: AuthenticationResponse) -> () in
    // Get the user bearer token from the authenticationResponse.
}

To get the current user information, just instantiate the Uphold client with the user bearer token and then call the getUser() function:

let upholdClient = UpholdClient(bearertoken: bearerToken)

upholdClient.getUser().then { (user: User) -> () in
    /// The user information is available at the user object.
}

Note: Don't forget to add keychain sharing capabilities in your application's target inside the Capabilities tab.

Get user cards with chaining

let upholdClient = UpholdClient(bearerToken: bearerToken)

upholdClient.getUser().then { (user: User) -> Promise<[Card]> in
    return user.getCards()
.then { (cards: [Card]) -> () in
    /// Do something with the list of cards.         
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.
}

Get user cards

user.getCards().then { (cards: [Card]) -> () in
    /// Do something with the list of cards.        
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.            
}

Create a new card for the user

let cardRequest: CardRequest = CardRequest(currency: "foo", label: "BTC", settings: CardSettings(position: 1, starred: true))

// Or just create a card without specifying the card settings.
// let cardRequest: CardRequest = CardRequest(currency: "foo", label: "BTC")

user.createCard(cardRequest).then { (card: Card) -> () in
    /// Do something with the card.        
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.            
}

Create a new address for a card

let addressRequest: AddressRequest = AddressRequest(network: "bitcoin")

card.createAddress(addressRequest).then { (address: Address) -> () in
    /// Do something with the address of the card.        
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.            
}

Get ticker

/// Instantiate the client. In this case, we don't need an
/// AUTHORIZATION_TOKEN because the Ticker endpoint is public.
let upholdClient = UpholdClient()

/// Get tickers.
upholdClient.getTickers().then { (rateList: [Rate]) -> () in
    /// Do something with the rates list.
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.
}

Or you could get a ticker for a specific currency:

/// Get tickers for BTC.
upholdClient.getTickersByCurrency("BTC").then { (rateList: [Rate]) -> () in
    /// Do something with the rates list.
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.
}

Create and commit a new transaction

let transactionDenominationRequest = TransactionDenominationRequest(amount: "1.0", currency: "BTC")

/// A transaction to a destination (card id, crypto address, email, phone number or username).
let transactionTransferRequest = TransactionTransferRequest(denomination: transactionDenominationRequest, destination: "[email protected]")

card.createTransaction(transactionTransferRequest).then { (transaction: Transaction) -> () in
    /// Commit the transaction.
    transaction.commit(TransactionCommitRequest("Commit message"))
}.error({ (error: ErrorType) -> Void in
    /// Do something with the error.            
})

/// A transaction to a destination (card id, crypto address, email, phone number or username) with reference.
let transactionTransferRequest = TransactionTransferRequest(denomination: transactionDenominationRequest, destination: "[email protected]", reference: "123456")

card.createTransaction(transactionTransferRequest).then { (transaction: Transaction) -> () in
    /// Commit the transaction.
    transaction.commit(TransactionCommitRequest("Commit message"))
}.error({ (error: ErrorType) -> Void in
    /// Do something with the error.            
})

/// A deposit from an ACH or SEPA account.
let transactionDepositRequest = TransactionDepositRequest(denomination: transactionDenominationRequest, origin: "accountId")

card.createTransaction(transactionDepositRequest).then { (transaction: Transaction) -> () in
    /// Commit the transaction.
    transaction.commit(TransactionCommitRequest("Commit message"))
}.error({ (error: ErrorType) -> Void in
    /// Do something with the error.
})

/// A deposit from a credit card.
let transactionCardDepositRequest = TransactionCardDepositRequest(denomination: transactionDenominationRequest, origin: "creditCardId", securityCode: "1234")

card.createTransaction(transactionCardDepositRequest).then { (transaction: Transaction) -> () in
    /// Commit the transaction.
    transaction.commit(TransactionCommitRequest("Commit message"))
}.error({ (error: ErrorType) -> Void in
    /// Do something with the error.
})

If you want to commit the transaction on the creation process, call the createTransaction method with the first parameter set to true.

card.createTransaction(true, transactionRequest: transactionRequest)

Get all public transactions

/// Instantiate the client. In this case, we don't need an
/// AUTHORIZATION_TOKEN because the Ticker endpoint is public.
let upholdClient = UpholdClient()
let paginator: Paginator<Transaction> = client.getReserve().getTransactions()

/// Get the list of transactions.
paginator.elements.then { (transactions: [Transaction]) -> () in
    /// Do something with the list of transactions.            
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.         
}

/// Get the next page of transactions.
paginator.getNext().then { (transactions: [Transaction]) -> () in
    /// Do something with the list of transactions.         
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.         
}

Or you could get a specific public transaction:

/// Get one public transaction.
upholdClient.getReserve().getTransactionById("a97bb994-6e24-4a89-b653-e0a6d0bcf634").then { (transaction: Transaction) -> () in
    /// Do something with the list of transactions.     
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.      
}

Get reserve status

/// Instantiate the client. In this case, we don't need an
/// AUTHORIZATION_TOKEN because the Ticker endpoint is public.
let upholdClient = UpholdClient()

/// Get the reserve summary of all the obligations and assets within it.
client.getReserve().getStatistics().then { (reserveStatistics: [ReserveStatistics]) -> () in
    /// Do something with the reserve statistics.    
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.     
}

Pagination

Some endpoints will return a paginator. Here are some examples on how to handle it:

/// Get public transactions paginator.
let paginator: Paginator<Transaction> = client.getReserve().getTransactions()

/// Get the first page of transactions.
paginator.elements.then { (transactions: [Transaction]) -> () in
    /// Do something with the list of transactions.            
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.         
}

/// Check if the paginator has a valid next page.
paginator.hasNext().then { (hasNext: Bool) -> () in
    /// Do something with the hasNext.     
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.         
}

/// Get the number of paginator elements.
paginator.count().then { (count: Int) -> () in
    /// Do something with the count.    
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.     
}

/// Get the next page.
paginator.getNext().then { (transactions: [Transaction]) -> () in
    /// Do something with the list of transactions.         
}.error { (error: ErrorType) -> Void in
    /// Do something with the error.         
}

Uphold SDK sample

Check the sample application to explore an application using the Uphold iOS SDK.

Building

To build the sample application you need the Xcode. Steps to build:

  1. Clone the repository.
  2. Get the project dependencies:
carthage bootstrap --platform iOS
  1. Open the sample project SampleApplication.xcodeproj.
  2. Add keychain sharing capabilities.
  3. Build and run the app from inside Xcode.

The sample application is configured to use the sandbox environment, make sure you use a sandbox account to perform the login.

Contributing & Development

Contributing

Have you found a bug or want to suggest something? Please search the issues first and, if it is new, go ahead and submit it.

Develop

It will be awesome if you can help us evolve uphold-sdk-ios. Want to help?

  1. Fork it.
  2. Hack away.
  3. Run the tests.
  4. Create a Pull Request.

uphold-sdk-ios's People

Contributors

d-moreira avatar digobaptista avatar diogoguimaraes avatar fixe avatar nunofgs avatar ruipenso avatar sandromachado 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

Watchers

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

uphold-sdk-ios's Issues

"Invalidate Session" is not working properly

After making a call to the UpholdClient.invalidateSession() method a user stays logged in the Safari Controller and when he tries to log in again he will be automatically logged in without any interaction or confirmation, and there is no chance to authenticate a different account.

To solve this issue I should be able to open a logout page in the Safari Controller (because there is no way to clean cookies programmatically in SFSafariViewController as it runs in a separate process and shares cookies with Safari.app). But I can't find any endpoint or public API to force a user to log out (something like https://uphold.com/logout).

In Uphold SDK for JavaScript, there is "POST oauth2/revoke" endpoint (https://github.com/uphold/uphold-sdk-javascript/blob/master/docs/oauthclient.md#buildrevoketokenrequest) but it's not possible to make a POST-requests via SFSafariViewController.

Authentication stuck at "Confirm your account"

When authenticating for the very first time (or registering a new user) auth process hangs at confirming email page. If the user confirms his email by opening the link in the Safari.app and manually returns to the app nothing happens. The only way to log in is to press the "Done" button in Safari Controller (after confirming email) and open login page again.
img_1562

Update documentation

Update the documentation to have the following format:

/**
  Description.

  - Parameters:
      - foo: The foo.
      - bar: The bar.

  - Returns: The foobar.
*/

Add XinFin-XDC Network support

Hello Team,

It will be great if Would you consider to Add ETH compatible DPOS chain XinFin(XDC) Network support.

XinFin Digital Contract or XDC — the XinFin network’s native crypto — is a one-stop solution that combines speed, scalability, and sustainability into an immaculate package. XDC is built on XinFin’s exclusive consensus mechanism — the XinFin Delegated Proof-of-Stake or XDPoS protocol that was specially developed to overcome the shortcomings of the technology that came before it.

XinFin Network: https://xdc.network/home
Github:- https://github.com/XinFinOrg/XDPoSChain
CMC :- https://coinmarketcap.com/currencies/xinfin-network/
Circulating Supply:- https://explorerapi.xinfin.network/publicAPI?module=balance&action=getcirculatingsupply
Total Supply:- https://explorerapi.xinfin.network/publicAPI?module=balance&action=totalXDC
Docker FullNode:- https://github.com/xinfinorg/XinFin-Node
Integration Code example: https://xinfin.org/exchange-listing-resource

Technical Community Support available at:

Telegram Community: https://t.me/XinFinDevelopers
Slack Community: https://xinfin-public.slack.com/messages/CELR2M831/
Slack Invitation Link: https://launchpass.com/xinfin-public
Technical help Resource: http://howto.xinfin.org/

It is a pleasure to talk about commercials and ready to support with large XinFin community to increase the adoption rate of your team.

Hope you will revert soon.

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.