Skip to main content

Swift

The Polywrap Client

To use Wraps in your app, all you need is the Polywrap Client.

Swift Project setup

We'll use a basic iOS App project as our template/boilerplate.

Within ContentView.swift, add a button that will invoke a run function within its action and print any errors that may occur when executed:

ContentView.swift
import SwiftUI

func run() throws -> Void {
print("Running...")

// Your code will go here

print("Done running!")
}

struct ContentView: View {
var body: some View {
VStack {
Button("Run example", action: {
do {
try run()
}
catch {
print("\(error)")
}
})
}
.padding()
}
}

Install the Polywrap Client

The Polywrap Client package is available via Swift Package Manager and Cocoapods.

For detailed instructions on how to install the Polywrap Swift Client see the client's readme.

We will install the Polywrap Client directly through XCode.

Navigate to File -> Add Package Dependency and enter https://github.com/polywrap/swift-client into the URL field.

Invoking your first Wrap

In order to invoke a Wrap, we first need to instantiate the Polywrap Client:

Inside ContentView.swift, import the PolywrapClient package at the top of your file:

ContentView.swift
import SwiftUI
import PolywrapClient

After this, inside the run function, initialize the Polywrap client:

ContentView.swift
    let client = BuilderConfig()
.addSystemDefault()
.addWeb3Default()
.build()

At this point, you can already invoke Wraps! In the simple example below, we will invoke the SHA3 Wrap within our run function:

ContentView.swift
    let client = BuilderConfig()
.addSystemDefault()
.addWeb3Default()
.build()

By clicking on the "Run example" button in the preview pane, you should now see the following appear in your console:

ba5a5d5fb7674f5975f0ecd0cd9a2f4bcadc9c04f5ac2ab3a887d8f10355fc38

This is the return value of our invocation.

What's going on here?

Using the Polywrap Client, we are invoking the sha3_256 method of a Wrap found under the WRAP URI wrapscan.io/polywrap/sha3@1.0 called the SHA3 Wrap.

Under the hood, through a process we call URI Resolution, the Polywrap Client knows how to fetch and execute the Wrap from decentralized storage.

The PolywrapClient comes pre-configured with everything you need for most Web2 and Web3 use-cases by default.

Invocation return value

Invoking a wrap can result in one of two scenarios:

  • A successful Wrap invocation returns the return value of the Wrap invocation. This can be anything - a boolean value, a string, an object, etc.
  • A failed Wrap invocation throws an error describing the reason for invocation failure.

Universal SDKs

Now that we know how a Wrap is invoked, let's see Polywrap's true power: universal SDKs!

One of the greatest benefits of Polywrap for the end-user (you!) lies in the fact that you can use the Polywrap Client to invoke the same Wrap from a variety of platforms and languages. If there's a Polywrap Client for your language, you can invoke any Wrap. This means that you can use the same SDK across multiple languages!

Another important benefit of using Polywrap is that, since Wraps are downloaded from various sources, you can automatically receive patches and updates to your SDKs without having to update your codebase.

Now we'll invoke the Uniswap V3 Wrap which is a port of the Uniswap SDK, but written as a Wrap.

We can use the Uniswap Wrap to fetch Uniswap's basic data related to the WETH and USDC tokes, find the address of the pool for those two tokens. We are also checking each result for errors.

    // First we need to define our argument and return types for the fetchToken call
struct FetchToken_Args : Codable {
var address: String
var chainId: String
}

struct Currency: Codable {
var decimals: Int
var symbol: String
var name: String
}

struct Token: Codable {
var address: String
var chainId: Int
var currency: Currency
}

// Fetch information about WETH
let weth: Token = try client.invoke(
uri: try Uri("wrapscan.io/polywrap/uniswap-v3@1.0"),
method: "fetchToken",
args: FetchToken_Args(
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
chainId: "MAINNET"
)
)

print("WETH: \(weth)")

let usdc: Token = try client.invoke(
uri: try Uri("wrapscan.io/polywrap/uniswap-v3@1.0"),
method: "fetchToken",
args: FetchToken_Args(
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
chainId: "MAINNET"
)
)

print("USDC: \(usdc)")

// Define our argument types for getPoolAddress
struct GetPoolAddress_Args: Codable {
var tokenA: Token
var tokenB: Token
var fee: String
}

let poolAddress: String = try client.invoke(
uri: try Uri("wrapscan.io/polywrap/uniswap-v3@1.0"),
method: "getPoolAddress",
args: GetPoolAddress_Args(
tokenA: weth,
tokenB: usdc,
fee: "MEDIUM"
)
)

print("Pool address: \(poolAddress)")

You can see more examples on how to use the Uniswap V3 Wrap in its docs page.

Compose everything

So far, we've only invoked a single Wrap, essentially using Polywrap to access a single SDK.

Using the Polywrap Client, we can invoke any number of SDKs, allowing us to build infinitely composable applications. If there's a Wrap for it, we can invoke it and use its functionality.

Visit Wrapscan and the awesome-polywrap repository to find a curated list of Wraps we and our community have developed.