├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── Example ├── .swiftlint.yml ├── Podfile ├── Podfile.lock ├── Tests │ ├── CommandTests.swift │ ├── Extensions │ │ └── DictionaryTests.swift │ ├── Info.plist │ ├── RequestRegistryTests.swift │ ├── WalletRequestTests.swift │ └── WalletResponseTests.swift ├── TrustSDK.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── TrustSDK-Example.xcscheme ├── TrustSDK.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDETemplateMacros.plist │ │ └── IDEWorkspaceChecks.plist ├── TrustSDK │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── Main.storyboard │ └── ViewController.swift └── fastlane │ ├── Appfile │ ├── Fastfile │ └── README.md ├── LICENSE ├── README.md ├── TrustSDK.podspec ├── TrustSDK ├── Classes │ ├── Client │ │ ├── Extensions │ │ │ ├── BigInt.swift │ │ │ ├── Collection.swift │ │ │ ├── Data.swift │ │ │ ├── Dictionary.swift │ │ │ ├── String.swift │ │ │ ├── URLComponents.swift │ │ │ └── URLQueryItem.swift │ │ ├── Request │ │ │ ├── GetAccountsRequest.swift │ │ │ ├── Request.swift │ │ │ ├── RequestRegistry.swift │ │ │ ├── SignMessageRequest.swift │ │ │ ├── SignRequest.swift │ │ │ ├── SignThenSendRequest.swift │ │ │ └── TransactionRequest.swift │ │ ├── Signer │ │ │ ├── Signer.swift │ │ │ ├── Signers.swift │ │ │ └── SigningInputEncoder.swift │ │ ├── Types │ │ │ ├── ConfirmType.swift │ │ │ ├── Transaction.swift │ │ │ ├── TrustCommand.swift │ │ │ ├── TrustConfiguration.swift │ │ │ ├── TrustError.swift │ │ │ ├── TrustSDK.swift │ │ │ └── WalletApp.swift │ │ └── UI │ │ │ ├── Colors.swift │ │ │ ├── Icons.swift │ │ │ ├── TrustButton.swift │ │ │ ├── TrustButtonTheme.swift │ │ │ └── UIColor+Hex.swift │ └── Wallet │ │ ├── WalletRequest.swift │ │ ├── WalletResponse.swift │ │ └── WalletSDK.swift └── Resources │ ├── .gitkeep │ ├── Images.xcassets │ ├── Contents.json │ ├── trust.imageset │ │ ├── Contents.json │ │ └── trust_icon.pdf │ ├── trust.shield.fill.imageset │ │ ├── Contents.json │ │ └── trust_filled.pdf │ └── trust.shield.imageset │ │ ├── Contents.json │ │ └── trust_line.pdf │ └── en.lproj │ └── Localizable.strings ├── _Pods.xcodeproj ├── docs ├── demo.gif └── scheme.png └── tools └── pod-release /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: TrustSDK CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | test: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Cache 15 | id: pod_cache 16 | uses: actions/cache@v1.1.2 17 | with: 18 | path: Example/Pods 19 | key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} 20 | - name : Pod install 21 | run: pod install --repo-update 22 | if: steps.pod_cache.outputs.cache-hit != 'true' 23 | working-directory: ./Example 24 | - name: Run Tests 25 | run: fastlane ios tests 26 | working-directory: ./Example 27 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: TrustSDK release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | pull_request: 8 | tags: 9 | - '*' 10 | 11 | jobs: 12 | podspec: 13 | runs-on: macos-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: pod trunk push 17 | run: tools/pod-release 18 | env: 19 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # CocoaPods 26 | Pods/ 27 | 28 | # Fastlane 29 | fastlane/report.xml 30 | fastlane/Preview.html 31 | fastlane/screenshots/**/*.png 32 | fastlane/screenshots/screenshots.html 33 | fastlane/test_output 34 | 35 | .vscode/ 36 | *~ 37 | -------------------------------------------------------------------------------- /Example/.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - cyclomatic_complexity 3 | - force_cast 4 | - force_try 5 | - identifier_name 6 | - nesting 7 | - redundant_discardable_let 8 | - todo 9 | - type_name 10 | - unused_optional_binding 11 | - xctfail_message 12 | - fallthrough 13 | opt_in_rules: 14 | - closure_end_indentation 15 | - closure_spacing 16 | - empty_count 17 | - file_header 18 | - multiline_parameters 19 | - vertical_parameter_alignment_on_call 20 | included: 21 | - ../TrustSDK 22 | excluded: 23 | - Pods 24 | function_parameter_count: 25 | warning: 20 26 | error: 25 27 | line_length: 28 | warning: 250 29 | error: 450 30 | large_tuple: 31 | warning: 4 32 | type_body_length: 33 | warning: 450 34 | error: 650 35 | function_body_length: 200 36 | file_length: 37 | warning: 600 38 | error: 1200 39 | trailing_comma: 40 | mandatory_comma: true 41 | file_header: 42 | required_pattern: "// Copyright Trust Wallet. All rights reserved.\n" 43 | superfluous_disable_command: warning 44 | reporter: "xcode" 45 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '12.0' 2 | use_frameworks! 3 | 4 | target 'TrustSDK_Example' do 5 | project 'TrustSDK' 6 | pod 'TrustSDK/Wallet', :path => '../' 7 | pod 'SwiftLint' 8 | pod 'CryptoSwift' 9 | target 'TrustSDK_Tests' do 10 | inherit! :search_paths 11 | end 12 | end 13 | 14 | post_install do |installer| 15 | installer.pods_project.targets.each do |target| 16 | target.build_configurations.each do |config| 17 | # remove deployment_target from target level 18 | config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET' 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BigInt (5.2.0) 3 | - CryptoSwift (1.4.0) 4 | - SwiftLint (0.43.1) 5 | - SwiftProtobuf (1.17.0) 6 | - TrustSDK/Client (1.4.7): 7 | - BigInt 8 | - TrustWalletCore/Types 9 | - TrustSDK/Wallet (1.4.7): 10 | - TrustSDK/Client 11 | - TrustWalletCore/Types (2.6.8): 12 | - SwiftProtobuf 13 | 14 | DEPENDENCIES: 15 | - CryptoSwift 16 | - SwiftLint 17 | - TrustSDK/Wallet (from `../`) 18 | 19 | SPEC REPOS: 20 | trunk: 21 | - BigInt 22 | - CryptoSwift 23 | - SwiftLint 24 | - SwiftProtobuf 25 | - TrustWalletCore 26 | 27 | EXTERNAL SOURCES: 28 | TrustSDK: 29 | :path: "../" 30 | 31 | SPEC CHECKSUMS: 32 | BigInt: f668a80089607f521586bbe29513d708491ef2f7 33 | CryptoSwift: 7cc902df1784de3b389a387756c7d710f197730c 34 | SwiftLint: 99f82d07b837b942dd563c668de129a03fc3fb52 35 | SwiftProtobuf: 9c85136c6ba74b0a1b84279dbf0f6db8efb714e0 36 | TrustSDK: e1b5f33d3df28044a6b2ed07407f640b227e7f0c 37 | TrustWalletCore: 182a5dc39512187878d5968b8a9a25406b181d96 38 | 39 | PODFILE CHECKSUM: c172da0a8f94e804c320befae5bffabca7cc177f 40 | 41 | COCOAPODS: 1.10.1 42 | -------------------------------------------------------------------------------- /Example/Tests/CommandTests.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import XCTest 8 | import BigInt 9 | import WalletCore 10 | @testable import TrustSDK 11 | 12 | class CommandTests: XCTestCase { 13 | func testSignCommandAttributes() { 14 | let signCommand = TrustSDK.Command.sign(coin: .ethereum, input: Data(), send: true, metadata: .dApp(name: "Test", url: URL(string: "https://dapptest.com"))) 15 | let signParams = signCommand.params 16 | 17 | let getAccountsCommand = TrustSDK.Command.getAccounts(coins: [.ethereum, .bitcoin]) 18 | let getAccountsParams = getAccountsCommand.params 19 | 20 | XCTAssertEqual("sdk_get_accounts", getAccountsCommand.name.rawValue) 21 | XCTAssertEqual([60, 0], getAccountsParams["coins"] as? [UInt32]) 22 | XCTAssertEqual([ 23 | URLQueryItem(name: "coins.0", value: "60"), 24 | URLQueryItem(name: "coins.1", value: "0"), 25 | ], getAccountsParams.queryItems()) 26 | 27 | XCTAssertEqual("sdk_sign", signCommand.name.rawValue) 28 | XCTAssertEqual("60", signParams["coin"] as? String) 29 | XCTAssertEqual("", signParams["data"] as? String) 30 | XCTAssertTrue(signParams["send"] as! Bool) 31 | 32 | let metaParams = signParams["meta"] as! [String: Any] 33 | XCTAssertEqual("dapp", metaParams["__name"] as? String) 34 | XCTAssertEqual("Test", metaParams["name"] as? String) 35 | XCTAssertEqual("https://dapptest.com", metaParams["url"] as? String) 36 | 37 | XCTAssertEqual([ 38 | URLQueryItem(name: "coin", value: "60"), 39 | URLQueryItem(name: "data", value: ""), 40 | URLQueryItem(name: "meta.__name", value: "dapp"), 41 | URLQueryItem(name: "meta.name", value: "Test"), 42 | URLQueryItem(name: "meta.url", value: "https://dapptest.com"), 43 | URLQueryItem(name: "send", value: "true"), 44 | ], signParams.queryItems()) 45 | } 46 | 47 | func testSignCommandInit() { 48 | let command = TrustSDK.Command( 49 | name: "sdk_sign", 50 | params: [ 51 | "coin": "60", 52 | "data": "", 53 | "send": "true", 54 | "meta": [ 55 | "__name": "dapp", 56 | "name": "Test", 57 | "url": "https://dapptest.com" 58 | ] 59 | ] 60 | ) 61 | 62 | switch command { 63 | case let .sign(coin, data, send, meta): 64 | XCTAssertEqual(CoinType.ethereum, coin) 65 | XCTAssertEqual(Data(), data) 66 | XCTAssertTrue(send) 67 | XCTAssertEqual(TrustSDK.SignMetadata.dApp(name: "Test", url: URL(string: "https://dapptest.com")), meta) 68 | default: 69 | XCTFail() 70 | } 71 | } 72 | 73 | func testSignCommandInitFromURLComponents() { 74 | let components = URLComponents(string: "example://sdk_sign?coin=60&data=&send=true&meta.__name=dapp&meta.name=Test&meta.url=https%3A%2F%2Fdapptest.com")! 75 | let command = TrustSDK.Command(components: components) 76 | 77 | switch command { 78 | case let .sign(coin, data, send, meta): 79 | XCTAssertEqual(CoinType.ethereum, coin) 80 | XCTAssertEqual(Data(), data) 81 | XCTAssertTrue(send) 82 | XCTAssertEqual(TrustSDK.SignMetadata.dApp(name: "Test", url: URL(string: "https://dapptest.com")), meta) 83 | default: 84 | XCTFail() 85 | } 86 | } 87 | 88 | func testGetAccountsCommandInit() { 89 | let command = TrustSDK.Command(name: "sdk_get_accounts", params: ["coins": ["0": "60", "1": "0"]]) 90 | switch command { 91 | case let .getAccounts(coins): 92 | XCTAssertEqual([CoinType.ethereum, CoinType.bitcoin], coins) 93 | default: 94 | XCTFail() 95 | } 96 | } 97 | 98 | func testGetAccountsCommandInitFromURLComponents() { 99 | let components = URLComponents(string: "example://sdk_get_accounts?coins.0=60&coins.1=0")! 100 | let command = TrustSDK.Command(components: components) 101 | 102 | switch command { 103 | case let .getAccounts(coins): 104 | XCTAssertEqual([CoinType.ethereum, CoinType.bitcoin], coins) 105 | default: 106 | XCTFail() 107 | } 108 | } 109 | 110 | func testTransactionToURL() { 111 | let app = "trust" 112 | let wallet = WalletApp(scheme: app, installURL: URL(string: "https://trustwallet.com")!) 113 | let tx = TrustSDK.Transaction( 114 | asset: UniversalAssetID(coin: .ethereum, token: ""), 115 | to: "0x728B02377230b5df73Aa4E3192E89b6090DD7312", 116 | amount: "0.01", 117 | action: .transfer, 118 | confirm: .sign, 119 | from: nil, 120 | nonce: 447, 121 | feePrice: BigInt(2112000000), 122 | feeLimit: BigInt(21000), 123 | meta: "0xasdf" 124 | ) 125 | 126 | let command = TrustSDK.Command(name: CommandName.signSimple.rawValue, params: tx.params())! 127 | 128 | let url = wallet.build( 129 | command: command.name.rawValue, 130 | params: tx.params().queryItems(), 131 | app: app, 132 | callback: "callback_me", 133 | id: "123" 134 | )! 135 | 136 | XCTAssertEqual(url.absoluteString, "trust://sdk_transaction?action=transfer&amount=0.01&asset=c60&confirm_type=sign&fee_limit=21000&fee_price=2112000000&meta=0xasdf&nonce=447&to=0x728B02377230b5df73Aa4E3192E89b6090DD7312&app=trust&callback=callback_me&id=123") 137 | } 138 | 139 | func testTransactionFromURLComponents() { 140 | let url = "trust://sdk_transaction?action=transfer&asset=c60_t0x514910771af9ca656af840dff83e8264ecf986ca&to=0x514910771af9ca656af840dff83e8264ecf986ca&amount=0.01&app=sample_app&callback=sdk_sign_result&confirm_type=send&nonce=2&from=0xF36f148D6FdEaCD6c765F8f59D4074109E311f0c&meta=memo&fee_limit=21000&fee_price=123456&id=1" 141 | let command = TrustSDK.Command(components: URLComponents(string: url)!) 142 | 143 | guard case .signSimple(let tx) = command else { 144 | XCTFail() 145 | return 146 | } 147 | 148 | XCTAssertEqual(tx.asset.coin, .ethereum) 149 | XCTAssertEqual(tx.action, .transfer) 150 | XCTAssertEqual(tx.confirm, .send) 151 | XCTAssertEqual(tx.to, "0x514910771af9ca656af840dff83e8264ecf986ca") 152 | XCTAssertEqual(tx.amount, "0.01") 153 | XCTAssertEqual(tx.nonce, 2) 154 | XCTAssertEqual(tx.from, "0xF36f148D6FdEaCD6c765F8f59D4074109E311f0c") 155 | XCTAssertEqual(tx.meta, "memo") 156 | XCTAssertEqual(tx.feeLimit, "21000") 157 | XCTAssertEqual(tx.feePrice, "123456") 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Example/Tests/Extensions/DictionaryTests.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | 8 | import XCTest 9 | @testable import TrustSDK 10 | 11 | class DictionaryTests: XCTestCase { 12 | func testToQueryItems() { 13 | let dict: [String: Any] = [ 14 | "key1": 0, 15 | "key2": [ 16 | "key1": false, 17 | "key2": [ 18 | "value3", 19 | "value4", 20 | ], 21 | ], 22 | ] 23 | 24 | XCTAssertEqual([ 25 | URLQueryItem(name: "key1", value: "0"), 26 | URLQueryItem(name: "key2.key1", value: "false"), 27 | URLQueryItem(name: "key2.key2.0", value: "value3"), 28 | URLQueryItem(name: "key2.key2.1", value: "value4"), 29 | ], dict.queryItems()) 30 | } 31 | 32 | func testInitFromQueryItems() { 33 | let items = [ 34 | URLQueryItem(name: "key1", value: "value1"), 35 | URLQueryItem(name: "key2.key1", value: "value2"), 36 | URLQueryItem(name: "key2.key2.0", value: "value3"), 37 | URLQueryItem(name: "key2.key2.1", value: "value4"), 38 | ] 39 | 40 | let dict: [String: Any] = Dictionary(queryItems: items) 41 | let subdict = dict["key2"] as! [String: Any] 42 | let subsubdict = subdict["key2"] as! [String: Any] 43 | 44 | XCTAssertEqual("value1", dict["key1"] as! String) 45 | XCTAssertEqual("value2", subdict["key1"] as! String) 46 | XCTAssertEqual("value3", subsubdict["0"] as! String) 47 | XCTAssertEqual("value4", subsubdict["1"] as! String) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/RequestRegistryTests.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import XCTest 8 | @testable import TrustSDK 9 | 10 | struct MockRequest: CallbackRequest { 11 | typealias Response = String 12 | 13 | let command: TrustSDK.Command 14 | var callback: ((Result) -> Void) 15 | 16 | func resolve(with components: URLComponents) { 17 | callback(Result.success("test")) 18 | } 19 | } 20 | 21 | class RequestRegistryTests: XCTestCase { 22 | var registry: RequestRegistry! 23 | 24 | override func setUp() { 25 | super.setUp() 26 | registry = RequestRegistry() 27 | } 28 | 29 | func testResolve() { 30 | let expect = expectation(description: "Command resolved") 31 | 32 | let key = registry.register(request: MockRequest(command: .getAccounts(coins: []), callback: { _ in 33 | expect.fulfill() 34 | })) 35 | 36 | registry.resolve(request: key, with: URLComponents(string: "http://trustwallet.com")!) 37 | 38 | wait(for: [expect], timeout: 1) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Example/Tests/WalletRequestTests.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import XCTest 8 | import WalletCore 9 | @testable import TrustSDK 10 | 11 | class WalletRequestTests: XCTestCase { 12 | func testResponseUrl() { 13 | let request = WalletSDK.Request(command: "sdk_get_accounts", params: ["coins": ["0": "60"], "app": "trust", "callback": "callback", "id": "1"])! 14 | let response = WalletSDK.Response.accounts(["test"]) 15 | 16 | XCTAssertEqual(URL(string: "trust://callback?accounts=test&id=1")!, request.callbackUrl(response: response)!) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/Tests/WalletResponseTests.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import XCTest 8 | import WalletCore 9 | @testable import TrustSDK 10 | 11 | class WalletResponseTests: XCTestCase { 12 | func testResponseAttributes() { 13 | let sign = WalletSDK.Response.sign(output: Data(hexEncoded: "0x123456")!) 14 | let accounts = WalletSDK.Response.accounts(["test1", "test2"]) 15 | let failure = WalletSDK.Response.failure(error: TrustSDKError.unknown) 16 | 17 | XCTAssertEqual(["data": "EjRW"], sign.params) 18 | XCTAssertEqual(["accounts": "test1,test2"], accounts.params) 19 | XCTAssertEqual(["error": "unknown"], failure.params) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2FD67F7E4A7463DFF28E3DB7 /* Pods_TrustSDK_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D6535858A45225CBB70BA8 /* Pods_TrustSDK_Example.framework */; }; 11 | 33758FFB3D21DDEAA9C93AA9 /* Pods_TrustSDK_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5D9043738C8AAF9420A137C /* Pods_TrustSDK_Tests.framework */; }; 12 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 13 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 607FACEC1AFB9204008FA782 /* RequestRegistryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* RequestRegistryTests.swift */; }; 17 | 7507FFDF240D73BD00DE2741 /* CommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7507FFDD240D738100DE2741 /* CommandTests.swift */; }; 18 | 7507FFE1240D75AE00DE2741 /* WalletResponseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7507FFE0240D75AE00DE2741 /* WalletResponseTests.swift */; }; 19 | 7507FFE3240D774300DE2741 /* WalletRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7507FFE2240D774300DE2741 /* WalletRequestTests.swift */; }; 20 | 7598AD192414175000421EFA /* DictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7598AD182414175000421EFA /* DictionaryTests.swift */; }; 21 | 75CD0D8324A41DC300242DA3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75CD0D8224A41DC300242DA3 /* Main.storyboard */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 30 | remoteInfo = TrustSDK; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 050ED1A351EBC5A95A79BEF0 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 36 | 27A447C41E9C2F17EC207F57 /* Pods-TrustSDK_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustSDK_Example.release.xcconfig"; path = "Target Support Files/Pods-TrustSDK_Example/Pods-TrustSDK_Example.release.xcconfig"; sourceTree = ""; }; 37 | 42D6535858A45225CBB70BA8 /* Pods_TrustSDK_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustSDK_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 607FACD01AFB9204008FA782 /* TrustSDK_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrustSDK_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 41 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 42 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 44 | 607FACE51AFB9204008FA782 /* TrustSDK_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrustSDK_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 607FACEB1AFB9204008FA782 /* RequestRegistryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestRegistryTests.swift; sourceTree = ""; }; 47 | 7507FFDD240D738100DE2741 /* CommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandTests.swift; sourceTree = ""; }; 48 | 7507FFE0240D75AE00DE2741 /* WalletResponseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletResponseTests.swift; sourceTree = ""; }; 49 | 7507FFE2240D774300DE2741 /* WalletRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletRequestTests.swift; sourceTree = ""; }; 50 | 7598AD182414175000421EFA /* DictionaryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryTests.swift; sourceTree = ""; }; 51 | 75CD0D8224A41DC300242DA3 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 52 | 8E3A0941E4AF3948909E87BE /* Pods-TrustSDK_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustSDK_Tests.release.xcconfig"; path = "Target Support Files/Pods-TrustSDK_Tests/Pods-TrustSDK_Tests.release.xcconfig"; sourceTree = ""; }; 53 | 973C7B142BAB8746D0C53AF2 /* TrustSDK.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = TrustSDK.podspec; path = ../TrustSDK.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 54 | 9CE43E415D1BA0F22441C393 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 55 | A5726054D0480EABD61CA7E8 /* Pods-TrustSDK_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustSDK_Tests.debug.xcconfig"; path = "Target Support Files/Pods-TrustSDK_Tests/Pods-TrustSDK_Tests.debug.xcconfig"; sourceTree = ""; }; 56 | C5D9043738C8AAF9420A137C /* Pods_TrustSDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustSDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | C9B18CC4B138BEA7D295FC63 /* Pods-TrustSDK_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustSDK_Example.debug.xcconfig"; path = "Target Support Files/Pods-TrustSDK_Example/Pods-TrustSDK_Example.debug.xcconfig"; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | 2FD67F7E4A7463DFF28E3DB7 /* Pods_TrustSDK_Example.framework in Frameworks */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 33758FFB3D21DDEAA9C93AA9 /* Pods_TrustSDK_Tests.framework in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXFrameworksBuildPhase section */ 78 | 79 | /* Begin PBXGroup section */ 80 | 3FDECD3AF8AAE4C02D48FD4E /* Pods */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | C9B18CC4B138BEA7D295FC63 /* Pods-TrustSDK_Example.debug.xcconfig */, 84 | 27A447C41E9C2F17EC207F57 /* Pods-TrustSDK_Example.release.xcconfig */, 85 | A5726054D0480EABD61CA7E8 /* Pods-TrustSDK_Tests.debug.xcconfig */, 86 | 8E3A0941E4AF3948909E87BE /* Pods-TrustSDK_Tests.release.xcconfig */, 87 | ); 88 | path = Pods; 89 | sourceTree = ""; 90 | }; 91 | 607FACC71AFB9204008FA782 = { 92 | isa = PBXGroup; 93 | children = ( 94 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 95 | 607FACD21AFB9204008FA782 /* Example for TrustSDK */, 96 | 607FACE81AFB9204008FA782 /* Tests */, 97 | 607FACD11AFB9204008FA782 /* Products */, 98 | 3FDECD3AF8AAE4C02D48FD4E /* Pods */, 99 | FFAAFD7E26EBF7785801851C /* Frameworks */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | 607FACD11AFB9204008FA782 /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 607FACD01AFB9204008FA782 /* TrustSDK_Example.app */, 107 | 607FACE51AFB9204008FA782 /* TrustSDK_Tests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 607FACD21AFB9204008FA782 /* Example for TrustSDK */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 116 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 117 | 75CD0D8224A41DC300242DA3 /* Main.storyboard */, 118 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 119 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 120 | 607FACD31AFB9204008FA782 /* Supporting Files */, 121 | ); 122 | name = "Example for TrustSDK"; 123 | path = TrustSDK; 124 | sourceTree = ""; 125 | }; 126 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 607FACD41AFB9204008FA782 /* Info.plist */, 130 | ); 131 | name = "Supporting Files"; 132 | sourceTree = ""; 133 | }; 134 | 607FACE81AFB9204008FA782 /* Tests */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 7598AD172414171700421EFA /* Extensions */, 138 | 7507FFE2240D774300DE2741 /* WalletRequestTests.swift */, 139 | 7507FFE0240D75AE00DE2741 /* WalletResponseTests.swift */, 140 | 7507FFDD240D738100DE2741 /* CommandTests.swift */, 141 | 607FACEB1AFB9204008FA782 /* RequestRegistryTests.swift */, 142 | 607FACE91AFB9204008FA782 /* Supporting Files */, 143 | ); 144 | path = Tests; 145 | sourceTree = ""; 146 | }; 147 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 607FACEA1AFB9204008FA782 /* Info.plist */, 151 | ); 152 | name = "Supporting Files"; 153 | sourceTree = ""; 154 | }; 155 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 973C7B142BAB8746D0C53AF2 /* TrustSDK.podspec */, 159 | 050ED1A351EBC5A95A79BEF0 /* README.md */, 160 | 9CE43E415D1BA0F22441C393 /* LICENSE */, 161 | ); 162 | name = "Podspec Metadata"; 163 | sourceTree = ""; 164 | }; 165 | 7598AD172414171700421EFA /* Extensions */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 7598AD182414175000421EFA /* DictionaryTests.swift */, 169 | ); 170 | path = Extensions; 171 | sourceTree = ""; 172 | }; 173 | FFAAFD7E26EBF7785801851C /* Frameworks */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 42D6535858A45225CBB70BA8 /* Pods_TrustSDK_Example.framework */, 177 | C5D9043738C8AAF9420A137C /* Pods_TrustSDK_Tests.framework */, 178 | ); 179 | name = Frameworks; 180 | sourceTree = ""; 181 | }; 182 | /* End PBXGroup section */ 183 | 184 | /* Begin PBXNativeTarget section */ 185 | 607FACCF1AFB9204008FA782 /* TrustSDK_Example */ = { 186 | isa = PBXNativeTarget; 187 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustSDK_Example" */; 188 | buildPhases = ( 189 | A3F0CE45328AC71D3D508F2E /* [CP] Check Pods Manifest.lock */, 190 | 607FACCC1AFB9204008FA782 /* Sources */, 191 | 607FACCD1AFB9204008FA782 /* Frameworks */, 192 | 607FACCE1AFB9204008FA782 /* Resources */, 193 | 7507FFE5240D845A00DE2741 /* ShellScript */, 194 | 1CB479F60EAC6F66FDE02F9C /* [CP] Embed Pods Frameworks */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = TrustSDK_Example; 201 | productName = TrustSDK; 202 | productReference = 607FACD01AFB9204008FA782 /* TrustSDK_Example.app */; 203 | productType = "com.apple.product-type.application"; 204 | }; 205 | 607FACE41AFB9204008FA782 /* TrustSDK_Tests */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustSDK_Tests" */; 208 | buildPhases = ( 209 | CA5757373FF5AEA1703E6B40 /* [CP] Check Pods Manifest.lock */, 210 | 607FACE11AFB9204008FA782 /* Sources */, 211 | 607FACE21AFB9204008FA782 /* Frameworks */, 212 | 607FACE31AFB9204008FA782 /* Resources */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 218 | ); 219 | name = TrustSDK_Tests; 220 | productName = Tests; 221 | productReference = 607FACE51AFB9204008FA782 /* TrustSDK_Tests.xctest */; 222 | productType = "com.apple.product-type.bundle.unit-test"; 223 | }; 224 | /* End PBXNativeTarget section */ 225 | 226 | /* Begin PBXProject section */ 227 | 607FACC81AFB9204008FA782 /* Project object */ = { 228 | isa = PBXProject; 229 | attributes = { 230 | LastSwiftUpdateCheck = 0830; 231 | LastUpgradeCheck = 1200; 232 | ORGANIZATIONNAME = CocoaPods; 233 | TargetAttributes = { 234 | 607FACCF1AFB9204008FA782 = { 235 | CreatedOnToolsVersion = 6.3.1; 236 | LastSwiftMigration = 1130; 237 | }; 238 | 607FACE41AFB9204008FA782 = { 239 | CreatedOnToolsVersion = 6.3.1; 240 | LastSwiftMigration = 1150; 241 | TestTargetID = 607FACCF1AFB9204008FA782; 242 | }; 243 | }; 244 | }; 245 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "TrustSDK" */; 246 | compatibilityVersion = "Xcode 3.2"; 247 | developmentRegion = en; 248 | hasScannedForEncodings = 0; 249 | knownRegions = ( 250 | en, 251 | Base, 252 | ); 253 | mainGroup = 607FACC71AFB9204008FA782; 254 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 255 | projectDirPath = ""; 256 | projectRoot = ""; 257 | targets = ( 258 | 607FACCF1AFB9204008FA782 /* TrustSDK_Example */, 259 | 607FACE41AFB9204008FA782 /* TrustSDK_Tests */, 260 | ); 261 | }; 262 | /* End PBXProject section */ 263 | 264 | /* Begin PBXResourcesBuildPhase section */ 265 | 607FACCE1AFB9204008FA782 /* Resources */ = { 266 | isa = PBXResourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | 75CD0D8324A41DC300242DA3 /* Main.storyboard in Resources */, 270 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 271 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | 607FACE31AFB9204008FA782 /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | /* End PBXResourcesBuildPhase section */ 283 | 284 | /* Begin PBXShellScriptBuildPhase section */ 285 | 1CB479F60EAC6F66FDE02F9C /* [CP] Embed Pods Frameworks */ = { 286 | isa = PBXShellScriptBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | inputPaths = ( 291 | "${PODS_ROOT}/Target Support Files/Pods-TrustSDK_Example/Pods-TrustSDK_Example-frameworks.sh", 292 | "${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework", 293 | "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", 294 | "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework", 295 | "${BUILT_PRODUCTS_DIR}/TrustSDK/TrustSDK.framework", 296 | "${BUILT_PRODUCTS_DIR}/TrustWalletCore/WalletCore.framework", 297 | ); 298 | name = "[CP] Embed Pods Frameworks"; 299 | outputPaths = ( 300 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework", 301 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", 302 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework", 303 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TrustSDK.framework", 304 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WalletCore.framework", 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | shellPath = /bin/sh; 308 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TrustSDK_Example/Pods-TrustSDK_Example-frameworks.sh\"\n"; 309 | showEnvVarsInLog = 0; 310 | }; 311 | 7507FFE5240D845A00DE2741 /* ShellScript */ = { 312 | isa = PBXShellScriptBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | inputFileListPaths = ( 317 | ); 318 | inputPaths = ( 319 | ); 320 | outputFileListPaths = ( 321 | ); 322 | outputPaths = ( 323 | ); 324 | runOnlyForDeploymentPostprocessing = 0; 325 | shellPath = /bin/sh; 326 | shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; 327 | }; 328 | A3F0CE45328AC71D3D508F2E /* [CP] Check Pods Manifest.lock */ = { 329 | isa = PBXShellScriptBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | inputFileListPaths = ( 334 | ); 335 | inputPaths = ( 336 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 337 | "${PODS_ROOT}/Manifest.lock", 338 | ); 339 | name = "[CP] Check Pods Manifest.lock"; 340 | outputFileListPaths = ( 341 | ); 342 | outputPaths = ( 343 | "$(DERIVED_FILE_DIR)/Pods-TrustSDK_Example-checkManifestLockResult.txt", 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | shellPath = /bin/sh; 347 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 348 | showEnvVarsInLog = 0; 349 | }; 350 | CA5757373FF5AEA1703E6B40 /* [CP] Check Pods Manifest.lock */ = { 351 | isa = PBXShellScriptBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | inputFileListPaths = ( 356 | ); 357 | inputPaths = ( 358 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 359 | "${PODS_ROOT}/Manifest.lock", 360 | ); 361 | name = "[CP] Check Pods Manifest.lock"; 362 | outputFileListPaths = ( 363 | ); 364 | outputPaths = ( 365 | "$(DERIVED_FILE_DIR)/Pods-TrustSDK_Tests-checkManifestLockResult.txt", 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | shellPath = /bin/sh; 369 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 370 | showEnvVarsInLog = 0; 371 | }; 372 | /* End PBXShellScriptBuildPhase section */ 373 | 374 | /* Begin PBXSourcesBuildPhase section */ 375 | 607FACCC1AFB9204008FA782 /* Sources */ = { 376 | isa = PBXSourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 380 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | 607FACE11AFB9204008FA782 /* Sources */ = { 385 | isa = PBXSourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | 7507FFE3240D774300DE2741 /* WalletRequestTests.swift in Sources */, 389 | 7598AD192414175000421EFA /* DictionaryTests.swift in Sources */, 390 | 7507FFE1240D75AE00DE2741 /* WalletResponseTests.swift in Sources */, 391 | 7507FFDF240D73BD00DE2741 /* CommandTests.swift in Sources */, 392 | 607FACEC1AFB9204008FA782 /* RequestRegistryTests.swift in Sources */, 393 | ); 394 | runOnlyForDeploymentPostprocessing = 0; 395 | }; 396 | /* End PBXSourcesBuildPhase section */ 397 | 398 | /* Begin PBXTargetDependency section */ 399 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 400 | isa = PBXTargetDependency; 401 | target = 607FACCF1AFB9204008FA782 /* TrustSDK_Example */; 402 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 403 | }; 404 | /* End PBXTargetDependency section */ 405 | 406 | /* Begin PBXVariantGroup section */ 407 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 408 | isa = PBXVariantGroup; 409 | children = ( 410 | 607FACDF1AFB9204008FA782 /* Base */, 411 | ); 412 | name = LaunchScreen.xib; 413 | sourceTree = ""; 414 | }; 415 | /* End PBXVariantGroup section */ 416 | 417 | /* Begin XCBuildConfiguration section */ 418 | 607FACED1AFB9204008FA782 /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 423 | CLANG_CXX_LIBRARY = "libc++"; 424 | CLANG_ENABLE_MODULES = YES; 425 | CLANG_ENABLE_OBJC_ARC = YES; 426 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_COMMA = YES; 429 | CLANG_WARN_CONSTANT_CONVERSION = YES; 430 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 431 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 432 | CLANG_WARN_EMPTY_BODY = YES; 433 | CLANG_WARN_ENUM_CONVERSION = YES; 434 | CLANG_WARN_INFINITE_RECURSION = YES; 435 | CLANG_WARN_INT_CONVERSION = YES; 436 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 437 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 438 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 439 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 440 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 441 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 442 | CLANG_WARN_STRICT_PROTOTYPES = YES; 443 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 444 | CLANG_WARN_UNREACHABLE_CODE = YES; 445 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 447 | COPY_PHASE_STRIP = NO; 448 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 449 | ENABLE_STRICT_OBJC_MSGSEND = YES; 450 | ENABLE_TESTABILITY = YES; 451 | GCC_C_LANGUAGE_STANDARD = gnu99; 452 | GCC_DYNAMIC_NO_PIC = NO; 453 | GCC_NO_COMMON_BLOCKS = YES; 454 | GCC_OPTIMIZATION_LEVEL = 0; 455 | GCC_PREPROCESSOR_DEFINITIONS = ( 456 | "DEBUG=1", 457 | "$(inherited)", 458 | ); 459 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 467 | MTL_ENABLE_DEBUG_INFO = YES; 468 | ONLY_ACTIVE_ARCH = YES; 469 | SDKROOT = iphoneos; 470 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 471 | }; 472 | name = Debug; 473 | }; 474 | 607FACEE1AFB9204008FA782 /* Release */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ALWAYS_SEARCH_USER_PATHS = NO; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INFINITE_RECURSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 493 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 494 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 495 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 496 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 497 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 498 | CLANG_WARN_STRICT_PROTOTYPES = YES; 499 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 500 | CLANG_WARN_UNREACHABLE_CODE = YES; 501 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 502 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 503 | COPY_PHASE_STRIP = NO; 504 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 505 | ENABLE_NS_ASSERTIONS = NO; 506 | ENABLE_STRICT_OBJC_MSGSEND = YES; 507 | GCC_C_LANGUAGE_STANDARD = gnu99; 508 | GCC_NO_COMMON_BLOCKS = YES; 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 516 | MTL_ENABLE_DEBUG_INFO = NO; 517 | SDKROOT = iphoneos; 518 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 519 | VALIDATE_PRODUCT = YES; 520 | }; 521 | name = Release; 522 | }; 523 | 607FACF01AFB9204008FA782 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | baseConfigurationReference = C9B18CC4B138BEA7D295FC63 /* Pods-TrustSDK_Example.debug.xcconfig */; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | INFOPLIST_FILE = TrustSDK/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | MODULE_NAME = ExampleApp; 532 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 535 | SWIFT_VERSION = 5.0; 536 | }; 537 | name = Debug; 538 | }; 539 | 607FACF11AFB9204008FA782 /* Release */ = { 540 | isa = XCBuildConfiguration; 541 | baseConfigurationReference = 27A447C41E9C2F17EC207F57 /* Pods-TrustSDK_Example.release.xcconfig */; 542 | buildSettings = { 543 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 544 | INFOPLIST_FILE = TrustSDK/Info.plist; 545 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 546 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 547 | MODULE_NAME = ExampleApp; 548 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 549 | PRODUCT_NAME = "$(TARGET_NAME)"; 550 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 551 | SWIFT_VERSION = 5.0; 552 | }; 553 | name = Release; 554 | }; 555 | 607FACF31AFB9204008FA782 /* Debug */ = { 556 | isa = XCBuildConfiguration; 557 | baseConfigurationReference = A5726054D0480EABD61CA7E8 /* Pods-TrustSDK_Tests.debug.xcconfig */; 558 | buildSettings = { 559 | FRAMEWORK_SEARCH_PATHS = ( 560 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 561 | "$(inherited)", 562 | ); 563 | GCC_PREPROCESSOR_DEFINITIONS = ( 564 | "DEBUG=1", 565 | "$(inherited)", 566 | ); 567 | INFOPLIST_FILE = Tests/Info.plist; 568 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 569 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 570 | PRODUCT_NAME = "$(TARGET_NAME)"; 571 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 572 | SWIFT_VERSION = 5.0; 573 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TrustSDK_Example.app/TrustSDK_Example"; 574 | }; 575 | name = Debug; 576 | }; 577 | 607FACF41AFB9204008FA782 /* Release */ = { 578 | isa = XCBuildConfiguration; 579 | baseConfigurationReference = 8E3A0941E4AF3948909E87BE /* Pods-TrustSDK_Tests.release.xcconfig */; 580 | buildSettings = { 581 | FRAMEWORK_SEARCH_PATHS = ( 582 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 583 | "$(inherited)", 584 | ); 585 | INFOPLIST_FILE = Tests/Info.plist; 586 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 587 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 588 | PRODUCT_NAME = "$(TARGET_NAME)"; 589 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 590 | SWIFT_VERSION = 5.0; 591 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TrustSDK_Example.app/TrustSDK_Example"; 592 | }; 593 | name = Release; 594 | }; 595 | /* End XCBuildConfiguration section */ 596 | 597 | /* Begin XCConfigurationList section */ 598 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "TrustSDK" */ = { 599 | isa = XCConfigurationList; 600 | buildConfigurations = ( 601 | 607FACED1AFB9204008FA782 /* Debug */, 602 | 607FACEE1AFB9204008FA782 /* Release */, 603 | ); 604 | defaultConfigurationIsVisible = 0; 605 | defaultConfigurationName = Release; 606 | }; 607 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustSDK_Example" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | 607FACF01AFB9204008FA782 /* Debug */, 611 | 607FACF11AFB9204008FA782 /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustSDK_Tests" */ = { 617 | isa = XCConfigurationList; 618 | buildConfigurations = ( 619 | 607FACF31AFB9204008FA782 /* Debug */, 620 | 607FACF41AFB9204008FA782 /* Release */, 621 | ); 622 | defaultConfigurationIsVisible = 0; 623 | defaultConfigurationName = Release; 624 | }; 625 | /* End XCConfigurationList section */ 626 | }; 627 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 628 | } 629 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcodeproj/xcshareddata/xcschemes/TrustSDK-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 64 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcworkspace/xcshareddata/IDETemplateMacros.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FILEHEADER 6 | Copyright Trust Wallet. All rights reserved. 7 | // 8 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 9 | // terms governing use, modification, and redistribution, is contained in the 10 | // file LICENSE at the root of the source code distribution tree. 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/TrustSDK.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/TrustSDK/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import UIKit 8 | import TrustSDK 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | TrustSDK.initialize(with: TrustSDK.Configuration(scheme: "trustsdk")) 17 | return true 18 | } 19 | 20 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { 21 | return TrustSDK.application(app, open: url, options: options) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/TrustSDK/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/TrustSDK/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/TrustSDK/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLName 27 | 28 | CFBundleURLSchemes 29 | 30 | trustsdk 31 | 32 | 33 | 34 | CFBundleVersion 35 | 1 36 | LSApplicationQueriesSchemes 37 | 38 | trust 39 | 40 | LSRequiresIPhoneOS 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Example/TrustSDK/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 | 37 | 44 | 51 | 52 | 53 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Example/TrustSDK/ViewController.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import UIKit 8 | import BigInt 9 | import TrustSDK 10 | import CryptoSwift 11 | import WalletCore 12 | 13 | class ViewController: UIViewController { 14 | @IBOutlet weak var signMesageButton: TrustButton! 15 | @IBOutlet weak var signTransactionButton: TrustButton! 16 | @IBOutlet weak var payWithTrustButton: TrustButton! 17 | @IBOutlet weak var getAccountsButton: TrustButton! 18 | @IBOutlet weak var signSimpleTxButton: UIButton! 19 | 20 | let meta = TrustSDK.SignMetadata.dApp(name: "Test", url: URL(string: "https://dapptest.com")) 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | setupSignTransactionButton() 25 | setupSignMessageButton() 26 | setupGetAccountsButton() 27 | setupPayWithTrustButton() 28 | } 29 | 30 | override func didReceiveMemoryWarning() { 31 | super.didReceiveMemoryWarning() 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | func setupSignMessageButton() { 36 | let data = Data("Some message".utf8) 37 | let message = Data("\u{19}Ethereum Signed Message:\n\(data.count)".utf8) + data 38 | let hash = message.sha3(.keccak256) 39 | 40 | signMesageButton.apply(theme: TrustButtonTheme 41 | .blue 42 | .with(styles: .title(.plain("Sign Message")), .icon(.trust), .roundFull) 43 | ) 44 | 45 | signMesageButton.action = .signMessage(hash) { result in 46 | switch result { 47 | case .success(let signature): 48 | let alert = UIAlertController( 49 | title: "Signature", 50 | message: signature, 51 | preferredStyle: .alert 52 | ) 53 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 54 | self.present(alert, animated: true) 55 | case .failure(let error): 56 | print("Failed to sign: \(error)") 57 | } 58 | } 59 | } 60 | 61 | func setupSignTransactionButton() { 62 | let input = EthereumSigningInput.with { 63 | $0.toAddress = "0x728B02377230b5df73Aa4E3192E89b6090DD7312" 64 | $0.chainID = BigInt("1").serialize()! 65 | $0.nonce = BigInt("477").serialize()! 66 | $0.gasPrice = BigInt("2112000000").serialize()! 67 | $0.gasLimit = BigInt("21000").serialize()! 68 | $0.transaction = EthereumTransaction.with { 69 | $0.transfer = EthereumTransaction.Transfer.with { 70 | $0.amount = BigInt("100000000000000").serialize()! 71 | } 72 | } 73 | } 74 | 75 | signTransactionButton.apply(theme: TrustButtonTheme 76 | .white 77 | .with(styles: .title(.plain("Sign Transaction")), .icon(.trust)) 78 | ) 79 | 80 | signTransactionButton.action = .sign(signer: TrustSDK.signers.ethereum, input: input, metadata: meta) { result in 81 | switch result { 82 | case .success(let output): 83 | let alert = UIAlertController( 84 | title: "Transaction", 85 | message: output.map({ String(format: "%02x", $0) }).joined(), 86 | preferredStyle: .alert 87 | ) 88 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 89 | self.present(alert, animated: true) 90 | case .failure(let error): 91 | print("Failed to sign: \(error)") 92 | } 93 | } 94 | } 95 | 96 | @IBAction func signSimpleEthTx(sender: UIButton) { 97 | let tx = TrustSDK.Transaction( 98 | asset: UniversalAssetID(coin: .ethereum, token: ""), 99 | to: "0x728B02377230b5df73Aa4E3192E89b6090DD7312", 100 | amount: "0.01", 101 | action: .transfer, 102 | confirm: .sign, 103 | from: nil, 104 | nonce: 447, 105 | feePrice: "2112000000", 106 | feeLimit: "21000" 107 | ) 108 | TrustSDK.Signer(coin: .ethereum).sign(tx) { result in 109 | print(result) 110 | } 111 | } 112 | 113 | func setupPayWithTrustButton() { 114 | let input = EthereumSigningInput.with { 115 | $0.toAddress = "0x728B02377230b5df73Aa4E3192E89b6090DD7312" 116 | $0.chainID = BigInt("1").serialize()! 117 | $0.transaction = EthereumTransaction.with { 118 | $0.transfer = EthereumTransaction.Transfer.with { 119 | $0.amount = BigInt("100000000000000").serialize()! 120 | } 121 | } 122 | } 123 | 124 | payWithTrustButton.apply(theme: TrustButtonTheme 125 | .black 126 | .with(styles: .title(.payWithTrust(icon: .shieldLined))) 127 | ) 128 | 129 | payWithTrustButton.action = .signThenSend(signer: TrustSDK.signers.ethereum, input: input, metadata: meta) { (result) in 130 | switch result { 131 | case .success(let output): 132 | let alert = UIAlertController( 133 | title: "Transaction Hash", 134 | message: output, 135 | preferredStyle: .alert 136 | ) 137 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 138 | self.present(alert, animated: true) 139 | case .failure(let error): 140 | print("Failed to sign: \(error)") 141 | } 142 | } 143 | } 144 | 145 | func setupGetAccountsButton() { 146 | getAccountsButton.apply(theme: TrustButtonTheme 147 | .white 148 | .with(styles: .title(.plain("Get Accounts")), .icon(.trust), .roundFull) 149 | ) 150 | 151 | getAccountsButton.action = .getAccounts(coins: [.ethereum, .binance]) { result in 152 | switch result { 153 | case .success(let addresses): 154 | let alert = UIAlertController( 155 | title: "Address", 156 | message: addresses.joined(separator: ", "), 157 | preferredStyle: .alert 158 | ) 159 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 160 | self.present(alert, animated: true) 161 | case .failure(let error): 162 | print("Failed to get addresses: \(error)") 163 | } 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /Example/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | # app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app 2 | # apple_id("[[APPLE_ID]]") # Your Apple email address 3 | 4 | 5 | # For more information about the Appfile, see: 6 | # https://docs.fastlane.tools/advanced/#appfile 7 | -------------------------------------------------------------------------------- /Example/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:ios) 17 | 18 | platform :ios do 19 | desc "Description of what the lane does" 20 | lane :tests do 21 | scan( 22 | workspace: "TrustSDK.xcworkspace", 23 | devices: ["iPhone 8"], 24 | scheme: "TrustSDK-Example", 25 | clean: true 26 | ) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /Example/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew install fastlane` 16 | 17 | # Available Actions 18 | ## iOS 19 | ### ios tests 20 | ``` 21 | fastlane ios tests 22 | ``` 23 | Description of what the lane does 24 | 25 | ---- 26 | 27 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 28 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 29 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Trust Wallet. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TrustSDK 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/TrustSDK.svg?style=flat)](https://cocoapods.org/pods/TrustSDK) 4 | [![License](https://img.shields.io/cocoapods/l/TrustSDK.svg?style=flat)](https://cocoapods.org/pods/TrustSDK) 5 | [![Platform](https://img.shields.io/cocoapods/p/TrustSDK.svg?style=flat)](https://cocoapods.org/pods/TrustSDK) 6 | ![TrustSDK CI](https://github.com/trustwallet/TrustSDK-iOS/workflows/TrustSDK%20CI/badge.svg) 7 | 8 | ## Getting Started 9 | 10 | The TrustSDK lets you sign Ethereum transactions and messages so that you can bulid a native DApp without having to worry about keys or wallets. Follw these instructions to integrate TrustSDK in your native DApp. 11 | 12 | ## Demo 13 | 14 | ![Sign Message and Transaction](docs/demo.gif) 15 | 16 | 17 | ## Installation 18 | 19 | TrustSDK is available through [CocoaPods](https://cocoapods.org). To install it, simply add the following line to your Podfile: 20 | 21 | ```ruby 22 | pod 'TrustSDK' 23 | ``` 24 | 25 | Run `pod install`. 26 | 27 | ## Configuration 28 | 29 | Follow the next steps to configure `TrustSDK` in your app. 30 | 31 | ### Schema Configuration 32 | 33 | Open Xcode an click on your project. Go to the 'Info' tab and expand the 'URL Types' group. Click on the **+** button to add a new scheme. Enter a custom scheme name in **'URL Scemes'**. 34 | 35 | ![Adding a scheme](docs/scheme.png) 36 | 37 | ### Initialization 38 | 39 | Open `AppDelegate.swift` file and initialize TrustSDK in`application(_:didFinishLaunchingWithOptions:)` method: 40 | 41 | ```swift 42 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 43 | TrustSDK.initialize(with: TrustSDK.Configuration(scheme: "trustexample")) 44 | return true 45 | } 46 | ``` 47 | 48 | ### Handling Callbacks 49 | 50 | Let `TrustSDK` capture deeplink responses by calling TrustSDK in `application(_:open:options:)` method: 51 | 52 | ```swift 53 | func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { 54 | return TrustSDK.application(app, open: url, options: options) 55 | } 56 | ``` 57 | 58 | ## API 59 | 60 | To use TrustSDK you have to import `TrustSDK` and `TrustWalletCore` modules. 61 | 62 | ### Sign Transaction 63 | 64 | TrustSDK comes with an easy to use generic API to sign transactions. Each blockchain accept a `SigningInput` object and respond with a `SigningOutput` that can be broadcasted directly to the node. Each input and output object is a Swift implementation of wallet-core's [ protobuf messages](https://github.com/trustwallet/wallet-core/tree/master/src/proto). To sign an Ethereum transaction you have the following `SigningInput`: 65 | 66 | ```swift 67 | let input = EthereumSigningInput.with { 68 | $0.toAddress = "0x3D60643Bf82b928602bce34EE426a7d392157b69" 69 | $0.chainID = BigInt("1").serialize()! 70 | $0.nonce = BigInt("464").serialize()! 71 | $0.gasPrice = BigInt("11500000000").serialize()! 72 | $0.gasLimit = BigInt("21000").serialize()! 73 | $0.amount = BigInt("1000000000000000").serialize()! 74 | } 75 | ``` 76 | 77 | > TrustSDK comes with some handy extensions to handle `Data` and `BigInt` serialization with ease. 78 | 79 | Once you have the input defined, you just have to call the blockchain signer to sign the transaction: 80 | 81 | ```swift 82 | TrustSDK.signers.ethereum.sign(input: input) { result in 83 | switch result { 84 | case .success(let output): 85 | // Handle the signing output 86 | case .failure(let error): 87 | // Handle failres like user rejections 88 | } 89 | } 90 | ``` 91 | 92 | ### Sign Messages 93 | 94 | To request signing message, you have to encode or hash your message in hex-encoded format first, and then call `sign(message:)` from `TrustSDK.signers`, below is an Ethereum example message: 95 | 96 | ```swift 97 | let data = Data("Some message".utf8) 98 | let message = Data("\u{19}Ethereum Signed Message:\n\(data.count)".utf8) + data 99 | let hash = message.sha3(.keccak256) 100 | TrustSDK.signers.ethereum.sign(message: hash) { result in 101 | switch result { 102 | case .success(let signature): 103 | // Handle the signature 104 | case .failure(let error): 105 | // Handle failure 106 | } 107 | } 108 | ``` 109 | 110 | ### Get Addresses 111 | 112 | To get users addresses, you just need to call `getAccounts(for:)` directly from `TrustSDK` and pass an array of `CoinType`: 113 | 114 | ```swift 115 | TrustSDK.getAccounts(for: [.ethereum, .bitcoin]) { result in 116 | switch result { 117 | case .success(let addresses): 118 | // Handle the address array 119 | case .failure(let error): 120 | // Handle failure 121 | } 122 | } 123 | ``` 124 | 125 | ## Wallet Developers 126 | If your wallet already uses `TrustWalletCore` and want to integrate with `TrustSDK` you just need to follow the steps below: 127 | 128 | 129 | ### Install WalletSDK 130 | 131 | Add the following line to your Podfile: 132 | 133 | 134 | ```ruby 135 | pod 'TrustSDK/Wallet' 136 | ``` 137 | 138 | Run `pod install`. 139 | 140 | ### Handling TrustSDK Commands 141 | 142 | Import `TrustSDK` and implement `WalletSDKRequestHandler.handle(request:callback:)`. Commands must handled asyncronously, once 143 | finished, your implementation have to call the `callback` parameter with the command's response. 144 | 145 | 146 | ```swift 147 | class WalletSDKRequestHandlerImplementation: WalletSDKRequestHandler { 148 | func handle(request: WalletSDK.Request, callback: @escaping ((WalletSDK.Response) -> Void)) { 149 | switch request.command { 150 | case .getAccounts(let coins): 151 | // Handle get accoutns command 152 | let accounts = ... 153 | callback(.accounts(accounts)) 154 | case .sign(let coin, let input): 155 | // Handle sign command 156 | let output = ... 157 | callback(.sign(coin: coin, output: output)) 158 | } 159 | // You can respond with a failure response in case of exception 160 | callback(.failure(.unknown)) 161 | } 162 | } 163 | ``` 164 | 165 | On your app initialization method, set the handler implemention `WalletSDK.handler` then let `WalletSDK` handle deeplinks by calling it in `application(_:open:options:)` method: 166 | 167 | ```swift 168 | func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { 169 | return WalletSDK.application(app, open: url, options: options) 170 | } 171 | ``` 172 | 173 | If you have your app already handles deeplinks, or you have to parse `WalletSDK.Request` struct by yourself and dispatch is 174 | using `WalletSDK.dispatch(request:)` method. 175 | 176 | ### Supporting Your Wallet 177 | 178 | Once you have `WalletSDK` configured for your wallet, tell dApp developers to set the`walletApp` attribute in `TrustSDK.Configureation` with your wallet's `scheme` and `installURL`: 179 | 180 | ```swift 181 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 182 | let wallet = WalletApp( 183 | scheme: "walletscheme", 184 | installURL: URL(string: "https://apps.apple.com/app/walletapp")! 185 | ) 186 | TrustSDK.initialize(with: TrustSDK.Configuration(scheme: "trustexample", walletApp: wallet)) 187 | return true 188 | } 189 | ``` 190 | 191 | ## Example 192 | 193 | Trust SDK includes an example project with the above code. To run the example project clone the repo and run pod install from the `Example` directory. Open `TrustSDK.xcworkspace` and run. Make sure that you have Trust Wallet installed on the device or simulator to test the full callback flow. 194 | 195 | ## Author 196 | 197 | * Leone Parise 198 | * Viktor Radchenko 199 | 200 | ## License 201 | 202 | TrustSDK is available under the MIT license. See the LICENSE file for more info. 203 | -------------------------------------------------------------------------------- /TrustSDK.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'TrustSDK' 3 | s.version = '1.4.7' 4 | s.summary = 'Trust Wallet SDK' 5 | s.homepage = 'https://github.com/TrustWallet/TrustSDK-iOS' 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.authors = { 'Leone Parise' => 'leoneparise', 'Viktor Radchenko' => 'vikmeup' } 8 | s.source = { :git => 'https://github.com/TrustWallet/TrustSDK-iOS.git', :tag => s.version.to_s } 9 | s.ios.deployment_target = '11.0' 10 | s.swift_version = '5.1' 11 | s.default_subspec = 'Client' 12 | 13 | s.subspec 'Client' do |cs| 14 | cs.resource_bundles = { 15 | 'TrustSDK' => ['TrustSDK/Resources/**/*.xcassets', 'TrustSDK/Resources/**/*.strings'] 16 | } 17 | cs.source_files = 'TrustSDK/Classes/Client/**/*' 18 | cs.dependency 'TrustWalletCore/Types' 19 | cs.dependency 'BigInt' 20 | end 21 | 22 | s.subspec 'Wallet' do |cs| 23 | cs.source_files = 'TrustSDK/Classes/Wallet/**/*' 24 | cs.dependency 'TrustSDK/Client' 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/BigInt.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import BigInt 9 | 10 | public extension BigInt { 11 | /// Serializes the `BigInt` with the specified bit width. 12 | /// 13 | /// - Returns: the serialized data or `nil` if the number doesn't fit in the specified bit width. 14 | func serialize(bitWidth: Int = 160) -> Data? { 15 | precondition(bitWidth % 8 == 0) 16 | let byteCount = bitWidth / 8 17 | 18 | let valueData = twosComplement() 19 | if valueData.count > byteCount { 20 | return nil 21 | } 22 | 23 | var data = Data() 24 | if sign == .plus { 25 | data.append(Data(repeating: 0, count: byteCount - valueData.count)) 26 | } else { 27 | data.append(Data(repeating: 255, count: byteCount - valueData.count)) 28 | } 29 | data.append(valueData) 30 | 31 | return data 32 | } 33 | 34 | // Computes the two's complement for a `BigInt` with 256 bits 35 | private func twosComplement() -> Data { 36 | if sign == .plus { 37 | return magnitude.serialize() 38 | } 39 | 40 | let serializedLength = magnitude.serialize().count 41 | let max = BigUInt(1) << (serializedLength * 8) 42 | return (max - magnitude).serialize() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/Collection.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | extension Collection { 10 | func toDictionary(transform: (_ element: Element) -> [Key: Value]) -> [Key: Value] { 11 | return Dictionary(self, transform: transform) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/Data.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | extension Data { 10 | /// Returns the hexadecimal representation of this data 11 | var hex: String { 12 | return map({ String(format: "%02x", $0) }).joined() 13 | } 14 | 15 | /// Initializes `Data` with a hex string representation. 16 | public init?(hexEncoded hexString: String) { 17 | let string: String 18 | if hexString.hasPrefix("0x") { 19 | string = String(hexString.dropFirst(2)) 20 | } else { 21 | string = hexString 22 | } 23 | 24 | // Convert the string to bytes for better performance 25 | guard let stringData = string.data(using: .ascii, allowLossyConversion: true) else { 26 | return nil 27 | } 28 | 29 | self.init(capacity: string.count / 2) 30 | let stringBytes = Array(stringData) 31 | for i in stride(from: 0, to: stringBytes.count, by: 2) { 32 | guard let high = Data.value(of: stringBytes[i]) else { 33 | return nil 34 | } 35 | if i < stringBytes.count - 1, let low = Data.value(of: stringBytes[i + 1]) { 36 | append((high << 4) | low) 37 | } else { 38 | append(high) 39 | } 40 | } 41 | } 42 | 43 | /// Converts an ASCII byte to a hex value. 44 | static func value(of nibble: UInt8) -> UInt8? { 45 | guard let letter = String(bytes: [nibble], encoding: .ascii) else { return nil } 46 | return UInt8(letter, radix: 16) 47 | } 48 | 49 | public func base64UrlEncodedString() -> String { 50 | return self.base64EncodedString() 51 | .replacingOccurrences(of: "+", with: "-") 52 | .replacingOccurrences(of: "/", with: "_") 53 | .replacingOccurrences(of: "=", with: "") 54 | } 55 | 56 | public init?(base64UrlEncoded: String) { 57 | var base64Encoded = base64UrlEncoded 58 | .replacingOccurrences(of: "-", with: "+") 59 | .replacingOccurrences(of: "_", with: "/") 60 | if base64Encoded.count % 4 != 0 { 61 | base64Encoded.append(String(repeating: "=", count: 4 - base64Encoded.count % 4)) 62 | } 63 | 64 | self.init(base64Encoded: base64Encoded) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/Dictionary.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | extension Dictionary { 10 | init(_ collection: C, transform: (_ element: C.Iterator.Element) -> [Key: Value]) { 11 | self.init() 12 | collection.forEach { (element) in 13 | for (k, v) in transform(element) { 14 | self[k] = v 15 | } 16 | } 17 | } 18 | } 19 | 20 | extension Dictionary where Key == String, Value: Any { 21 | public func queryItems() -> [URLQueryItem] { 22 | return queryItems(parentKey: nil) 23 | } 24 | 25 | private func queryItems(parentKey: String?) -> [URLQueryItem] { 26 | var items: [URLQueryItem] = [] 27 | 28 | for (_key, _value) in self { 29 | let key = { () -> String in 30 | if let parent = parentKey { 31 | return "\(parent).\(_key)" 32 | } else { 33 | return _key 34 | } 35 | }() 36 | 37 | if let value = _value as? [String: Any] { 38 | items.append(contentsOf: value.queryItems(parentKey: key)) 39 | } else if let value = _value as? [CustomStringConvertible] { 40 | items.append( 41 | contentsOf: value 42 | .enumerated() 43 | .map { URLQueryItem(name: "\(key).\($0.offset)", value: $0.element.description) } 44 | ) 45 | } else if let value = _value as? CustomStringConvertible { 46 | items.append(URLQueryItem(name: key, value: value.description)) 47 | } 48 | } 49 | 50 | return items.sorted { $0.name < $1.name } 51 | } 52 | } 53 | 54 | extension Dictionary where Key == String, Value: Any { 55 | public init(queryItems items: [URLQueryItem]) { 56 | var dict: [String: Any] = [:] 57 | for item in items { 58 | Dictionary.fill(&dict, key: item.name, value: item.value ?? "") 59 | } 60 | 61 | self = (dict as? [String: Value]) ?? [:] 62 | } 63 | 64 | private static func fill(_ dict: inout [String: Any], key: String, value: Any) { 65 | if key.contains(".") { 66 | let comps = key.components(separatedBy: ".") 67 | let head = comps.first! 68 | var subdict = (dict[head] as? [String: Any]) ?? [:] 69 | fill(&subdict, key: comps.dropFirst().joined(separator: "."), value: value) 70 | dict[head] = subdict 71 | } else { 72 | dict[key] = value 73 | } 74 | } 75 | } 76 | 77 | extension Dictionary { 78 | // swiftlint:disable syntactic_sugar 79 | func mapKeys(transform: (_ key: Key) -> T?) -> [T: Value] { 80 | let entries = self.compactMap { entry -> (key: T, value: Value)? in 81 | guard let key = transform(entry.key) else { 82 | return nil 83 | } 84 | 85 | return (key, entry.value) 86 | } 87 | return Dictionary(uniqueKeysWithValues: entries) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/String.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | extension String { 11 | init(coins: [CoinType], separator: String = ",") { 12 | self = coins.map { "\($0.rawValue)" }.joined(separator: separator) 13 | } 14 | 15 | func toCoinArray(separator: String = ",") -> [CoinType] { 16 | return self.components(separatedBy: separator) 17 | .map { $0.toCoin() } 18 | .compactMap { $0 } 19 | } 20 | 21 | func toCoin() -> CoinType? { 22 | if let rawValue = UInt32(self), let coin = CoinType(rawValue: rawValue) { 23 | return coin 24 | } 25 | return nil 26 | } 27 | 28 | func toBase64Data() -> Data? { 29 | return Data(base64UrlEncoded: self) 30 | } 31 | 32 | func toBool() -> Bool { 33 | return Bool(self) ?? false 34 | } 35 | } 36 | 37 | extension String { 38 | func localized(comment: String = "") -> String { 39 | return NSLocalizedString(self, bundle: TrustSDK.resourceBundle, comment: comment) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/URLComponents.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | extension URLComponents { 10 | func queryItem(for key: String) -> URLQueryItem? { 11 | return queryItems?.first(where: { $0.name == key }) 12 | } 13 | 14 | func containsQueryItem(for key: String) -> Bool { 15 | guard let items = queryItems else { return false } 16 | return items.contains(where: { $0.name == key }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Extensions/URLQueryItem.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | extension URLQueryItem { 11 | var intValue: Int? { 12 | if let value = self.value { 13 | return Int(value) 14 | } 15 | 16 | return nil 17 | } 18 | 19 | var coinValue: CoinType? { 20 | if let value = self.value, let intValue = UInt32(value) { 21 | return CoinType(rawValue: intValue) 22 | } 23 | 24 | return nil 25 | } 26 | 27 | var dataValue: Data? { 28 | if let value = self.value { 29 | return Data(base64UrlEncoded: value) 30 | } 31 | 32 | return nil 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/GetAccountsRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | struct GetAccountsRequest: CallbackRequest { 10 | enum QueryItems: String { 11 | case error, message, accounts 12 | } 13 | 14 | typealias Response = [String] 15 | 16 | let command: TrustSDK.Command 17 | let callback: Callback 18 | 19 | init(command: TrustSDK.Command, callback: @escaping Callback) { 20 | self.command = command 21 | self.callback = callback 22 | } 23 | 24 | func resolve(with components: URLComponents) { 25 | if let error = components.queryItem(for: QueryItems.error.rawValue)?.value { 26 | let message = components.queryItem(for: QueryItems.message.rawValue)?.value 27 | callback(.failure(TrustSDKError(from: error, value: message) ?? TrustSDKError.unknown)) 28 | return 29 | } 30 | 31 | guard let accounts = components.queryItem(for: QueryItems.accounts.rawValue)?.value else { 32 | callback(.failure(TrustSDKError.invalidResponse)) 33 | return 34 | } 35 | 36 | callback(.success(accounts.components(separatedBy: ","))) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/Request.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | protocol Request { 10 | var command: TrustSDK.Command { get } 11 | func resolve(with components: URLComponents) 12 | } 13 | 14 | protocol CallbackRequest: Request { 15 | associatedtype Response 16 | 17 | typealias Callback = ((Result) -> Void) 18 | var callback: Callback { get } 19 | } 20 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/RequestRegistry.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | class RequestRegistry { 10 | private static var index: UInt64 = 0 11 | private var requests: [String: Request] = [:] 12 | 13 | func register(request: Request) -> String { 14 | let id = Self.nextId() 15 | requests[id] = request 16 | return id 17 | } 18 | 19 | func resolve(request id: String, with components: URLComponents) { 20 | guard let request = requests[id] else { return } 21 | request.resolve(with: components) 22 | requests.removeValue(forKey: id) 23 | } 24 | 25 | private static func nextId() -> String { 26 | index += 1 27 | return "\(index)" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/SignMessageRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | struct SignMessageRequest: CallbackRequest { 11 | enum QueryItems: String { 12 | case error, message, signature 13 | } 14 | 15 | typealias Response = String 16 | 17 | let command: TrustSDK.Command 18 | let callback: Callback 19 | 20 | init(command: TrustSDK.Command, callback: @escaping Callback) { 21 | self.command = command 22 | self.callback = callback 23 | } 24 | 25 | func resolve(with components: URLComponents) { 26 | if let error = components.queryItem(for: QueryItems.error.rawValue)?.value { 27 | let message = components.queryItem(for: QueryItems.message.rawValue)?.value 28 | callback(.failure(TrustSDKError(from: error, value: message) ?? TrustSDKError.unknown)) 29 | return 30 | } 31 | 32 | guard let signature = components.queryItem(for: QueryItems.signature.rawValue)?.value else { 33 | callback(.failure(TrustSDKError.invalidResponse)) 34 | return 35 | } 36 | 37 | callback(.success(signature)) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/SignRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | struct SignRequest: CallbackRequest { 11 | enum QueryItems: String { 12 | case error, message, data 13 | } 14 | 15 | typealias Response = Data 16 | 17 | let command: TrustSDK.Command 18 | let callback: Callback 19 | 20 | init(command: TrustSDK.Command, callback: @escaping Callback) { 21 | self.command = command 22 | self.callback = callback 23 | } 24 | 25 | func resolve(with components: URLComponents) { 26 | if let error = components.queryItem(for: QueryItems.error.rawValue)?.value { 27 | let message = components.queryItem(for: QueryItems.message.rawValue)?.value 28 | callback(.failure(TrustSDKError(from: error, value: message) ?? TrustSDKError.unknown)) 29 | return 30 | } 31 | 32 | guard let data = components.queryItem(for: QueryItems.data.rawValue)?.dataValue else { 33 | callback(.failure(TrustSDKError.invalidResponse)) 34 | return 35 | } 36 | 37 | callback(.success(data)) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/SignThenSendRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | struct SignThenSendRequest: CallbackRequest { 10 | enum QueryItems: String { 11 | case error, message, txHash = "tx_hash" 12 | } 13 | 14 | typealias Response = String 15 | 16 | let command: TrustSDK.Command 17 | let callback: Callback 18 | 19 | init(command: TrustSDK.Command, callback: @escaping Callback) { 20 | self.command = command 21 | self.callback = callback 22 | } 23 | 24 | func resolve(with components: URLComponents) { 25 | if let error = components.queryItem(for: QueryItems.error.rawValue)?.value { 26 | let message = components.queryItem(for: QueryItems.message.rawValue)?.value 27 | callback(.failure(TrustSDKError(from: error, value: message) ?? TrustSDKError.unknown)) 28 | return 29 | } 30 | 31 | guard let txHash = components.queryItem(for: QueryItems.txHash.rawValue)?.value else { 32 | callback(.failure(TrustSDKError.invalidResponse)) 33 | return 34 | } 35 | 36 | callback(.success(txHash)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Request/TransactionRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | struct TransactionRequest: CallbackRequest { 11 | enum QueryItems: String { 12 | case error, message, data, hash = "tx_hash" 13 | } 14 | 15 | typealias Response = String 16 | 17 | let command: TrustSDK.Command 18 | let callback: Callback 19 | 20 | init(command: TrustSDK.Command, callback: @escaping Callback) { 21 | self.command = command 22 | self.callback = callback 23 | } 24 | 25 | func resolve(with components: URLComponents) { 26 | if let error = components.queryItem(for: QueryItems.error.rawValue)?.value { 27 | let message = components.queryItem(for: QueryItems.message.rawValue)?.value 28 | callback(.failure(TrustSDKError(from: error, value: message) ?? TrustSDKError.unknown)) 29 | return 30 | } 31 | 32 | if let data = components.queryItem(for: QueryItems.data.rawValue)?.value { 33 | callback(.success(data)) 34 | } else { 35 | callback(.failure(TrustSDKError.invalidResponse)) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Signer/Signer.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | import SwiftProtobuf 10 | 11 | public typealias SigningInput = SwiftProtobuf.Message 12 | 13 | public extension TrustSDK { 14 | struct Signer { 15 | let coin: CoinType 16 | 17 | public init(coin: CoinType) { 18 | self.coin = coin 19 | } 20 | 21 | public func sign(_ tx: Transaction, callback: @escaping ((Result) -> Void)) { 22 | guard self.coin == .ethereum else { 23 | callback(.failure(TrustSDKError.coinNotSupported)) 24 | return 25 | } 26 | do { 27 | let command = Command.signSimple(tx: tx) 28 | try TrustSDK.send(request: TransactionRequest(command: command, callback: callback)) 29 | } catch { 30 | callback(.failure(error)) 31 | } 32 | } 33 | 34 | public func sign(message: Data, metadata: SignMetadata? = nil, callback: @escaping ((Result) -> Void)) { 35 | if !TrustSDK.isSupported(coin: coin) { 36 | callback(.failure(TrustSDKError.coinNotSupported)) 37 | return 38 | } 39 | do { 40 | let command = Command.signMessage(coin: coin, message: message, metadata: metadata) 41 | try TrustSDK.send(request: SignMessageRequest(command: command, callback: callback)) 42 | } catch { 43 | callback(.failure(error)) 44 | } 45 | } 46 | 47 | public func sign(input: SigningInput, metadata: SignMetadata? = nil, callback: @escaping ((Result) -> Void)) { 48 | if !TrustSDK.isSupported(coin: coin) { 49 | callback(.failure(TrustSDKError.coinNotSupported)) 50 | return 51 | } 52 | 53 | do { 54 | let command = Command.sign(coin: coin, input: try input.serializedData(), send: false, metadata: metadata) 55 | try TrustSDK.send(request: SignRequest(command: command, callback: callback)) 56 | } catch { 57 | callback(.failure(error)) 58 | } 59 | } 60 | 61 | public func signThenSend(input: SigningInput, metadata: SignMetadata? = nil, callback: @escaping ((Result) -> Void)) { 62 | if !TrustSDK.isSupported(coin: coin) { 63 | callback(.failure(TrustSDKError.coinNotSupported)) 64 | return 65 | } 66 | 67 | do { 68 | let command: TrustSDK.Command = .sign(coin: coin, input: try input.serializedData(), send: true, metadata: metadata) 69 | try TrustSDK.send(request: SignThenSendRequest(command: command, callback: callback)) 70 | } catch { 71 | callback(.failure(error)) 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Signer/Signers.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | extension TrustSDK { 11 | public struct Signers { } 12 | } 13 | 14 | public extension TrustSDK.Signers { 15 | var aeternity: TrustSDK.Signer { 16 | return TrustSDK.Signer(coin: .aeternity) 17 | } 18 | 19 | var aion: TrustSDK.Signer { 20 | return TrustSDK.Signer(coin: .aion) 21 | } 22 | 23 | var algorand: TrustSDK.Signer { 24 | return TrustSDK.Signer(coin: .algorand) 25 | } 26 | 27 | var binance: TrustSDK.Signer { 28 | return TrustSDK.Signer(coin: .binance) 29 | } 30 | 31 | var eos: TrustSDK.Signer { 32 | return TrustSDK.Signer(coin: .eos) 33 | } 34 | 35 | var filecoin: TrustSDK.Signer { 36 | return TrustSDK.Signer(coin: .filecoin) 37 | } 38 | 39 | var fio: TrustSDK.Signer { 40 | return TrustSDK.Signer(coin: .fio) 41 | } 42 | 43 | var harmony: TrustSDK.Signer { 44 | return TrustSDK.Signer(coin: .harmony) 45 | } 46 | 47 | var icon: TrustSDK.Signer { 48 | return TrustSDK.Signer(coin: .icon) 49 | } 50 | 51 | var ioTeX: TrustSDK.Signer { 52 | return TrustSDK.Signer(coin: .ioTeX) 53 | } 54 | 55 | var near: TrustSDK.Signer { 56 | return TrustSDK.Signer(coin: .near) 57 | } 58 | 59 | var neo: TrustSDK.Signer { 60 | return TrustSDK.Signer(coin: .neo) 61 | } 62 | 63 | var nuls: TrustSDK.Signer { 64 | return TrustSDK.Signer(coin: .nuls) 65 | } 66 | 67 | var ontology: TrustSDK.Signer { 68 | return TrustSDK.Signer(coin: .ontology) 69 | } 70 | 71 | var nano: TrustSDK.Signer { 72 | return TrustSDK.Signer(coin: .nano) 73 | } 74 | 75 | var nebulas: TrustSDK.Signer { 76 | return TrustSDK.Signer(coin: .nebulas) 77 | } 78 | 79 | var nimiq: TrustSDK.Signer { 80 | return TrustSDK.Signer(coin: .nimiq) 81 | } 82 | 83 | var xrp: TrustSDK.Signer { 84 | return TrustSDK.Signer(coin: .xrp) 85 | } 86 | 87 | var solana: TrustSDK.Signer { 88 | return TrustSDK.Signer(coin: .solana) 89 | } 90 | 91 | var theta: TrustSDK.Signer { 92 | return TrustSDK.Signer(coin: .theta) 93 | } 94 | 95 | var tezos: TrustSDK.Signer { 96 | return TrustSDK.Signer(coin: .tezos) 97 | } 98 | 99 | var tron: TrustSDK.Signer { 100 | return TrustSDK.Signer(coin: .tron) 101 | } 102 | 103 | var veChain: TrustSDK.Signer { 104 | return TrustSDK.Signer(coin: .veChain) 105 | } 106 | 107 | var waves: TrustSDK.Signer { 108 | return TrustSDK.Signer(coin: .waves) 109 | } 110 | 111 | var zilliqa: TrustSDK.Signer { 112 | return TrustSDK.Signer(coin: .zilliqa) 113 | } 114 | } 115 | 116 | // Ethereum based chains 117 | public extension TrustSDK.Signers { 118 | var ethereum: TrustSDK.Signer { 119 | return TrustSDK.Signer(coin: .ethereum) 120 | } 121 | 122 | var ethereumClassic: TrustSDK.Signer { 123 | return TrustSDK.Signer(coin: .ethereumClassic) 124 | } 125 | 126 | var callisto: TrustSDK.Signer { 127 | return TrustSDK.Signer(coin: .callisto) 128 | } 129 | 130 | var goChain: TrustSDK.Signer { 131 | return TrustSDK.Signer(coin: .goChain) 132 | } 133 | 134 | var poanetwork: TrustSDK.Signer { 135 | return TrustSDK.Signer(coin: .poanetwork) 136 | } 137 | 138 | var tomoChain: TrustSDK.Signer { 139 | return TrustSDK.Signer(coin: .tomoChain) 140 | } 141 | 142 | var thunderToken: TrustSDK.Signer { 143 | return TrustSDK.Signer(coin: .thunderToken) 144 | } 145 | 146 | var wanchain: TrustSDK.Signer { 147 | return TrustSDK.Signer(coin: .wanchain) 148 | } 149 | 150 | var smartChain: TrustSDK.Signer { 151 | return TrustSDK.Signer(coin: .smartChain) 152 | } 153 | } 154 | 155 | // Cosmos based chains 156 | public extension TrustSDK.Signers { 157 | var cosmos: TrustSDK.Signer { 158 | return TrustSDK.Signer(coin: .cosmos) 159 | } 160 | 161 | var kava: TrustSDK.Signer { 162 | return TrustSDK.Signer(coin: .kava) 163 | } 164 | 165 | var terra: TrustSDK.Signer { 166 | return TrustSDK.Signer(coin: .terra) 167 | } 168 | 169 | var band: TrustSDK.Signer { 170 | return TrustSDK.Signer(coin: .bandChain) 171 | } 172 | } 173 | 174 | // Polkador based chains 175 | public extension TrustSDK.Signers { 176 | var polkadot: TrustSDK.Signer { 177 | return TrustSDK.Signer(coin: .polkadot) 178 | } 179 | 180 | var kusama: TrustSDK.Signer { 181 | return TrustSDK.Signer(coin: .kusama) 182 | } 183 | } 184 | 185 | // Stellar based chains 186 | public extension TrustSDK.Signers { 187 | var stellar: TrustSDK.Signer { 188 | return TrustSDK.Signer(coin: .stellar) 189 | } 190 | 191 | var kin: TrustSDK.Signer { 192 | return TrustSDK.Signer(coin: .kin) 193 | } 194 | } 195 | 196 | public extension TrustSDK.Signers { 197 | var elrond: TrustSDK.Signer { 198 | return TrustSDK.Signer(coin: .elrond) 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Signer/SigningInputEncoder.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | public struct SigningInputEncoder { 11 | private init() { } 12 | 13 | public static func encode(data: Data, privateKey: Data, for coin: CoinType) throws -> SigningInput { 14 | switch coin { 15 | case .aeternity: 16 | var input = try AeternitySigningInput(serializedData: data) 17 | input.privateKey = privateKey 18 | return input 19 | case .aion: 20 | var input = try AionSigningInput(serializedData: data) 21 | input.privateKey = privateKey 22 | return input 23 | case .algorand: 24 | var input = try AlgorandSigningInput(serializedData: data) 25 | input.privateKey = privateKey 26 | return input 27 | case .binance: 28 | var input = try BinanceSigningInput(serializedData: data) 29 | input.privateKey = privateKey 30 | return input 31 | case .cosmos, 32 | .kava, 33 | .terra, 34 | .bandChain: 35 | var input = try CosmosSigningInput(serializedData: data) 36 | input.privateKey = privateKey 37 | return input 38 | case .ethereum, 39 | .ethereumClassic, 40 | .callisto, 41 | .goChain, 42 | .poanetwork, 43 | .tomoChain, 44 | .thunderToken, 45 | .wanchain, 46 | .smartChain: 47 | var input = try EthereumSigningInput(serializedData: data) 48 | input.privateKey = privateKey 49 | return input 50 | case .eos: 51 | var input = try EOSSigningInput(serializedData: data) 52 | input.privateKey = privateKey 53 | return input 54 | case .filecoin: 55 | var input = try FilecoinSigningInput(serializedData: data) 56 | input.privateKey = privateKey 57 | return input 58 | case .fio: 59 | var input = try FIOSigningInput(serializedData: data) 60 | input.privateKey = privateKey 61 | return input 62 | case .harmony: 63 | var input = try HarmonySigningInput(serializedData: data) 64 | input.privateKey = privateKey 65 | return input 66 | case .icon: 67 | var input = try IconSigningInput(serializedData: data) 68 | input.privateKey = privateKey 69 | return input 70 | case .ioTeX: 71 | var input = try IoTeXSigningInput(serializedData: data) 72 | input.privateKey = privateKey 73 | return input 74 | case .near: 75 | var input = try NEARSigningInput(serializedData: data) 76 | input.privateKey = privateKey 77 | return input 78 | case .neo: 79 | var input = try NEOSigningInput(serializedData: data) 80 | input.privateKey = privateKey 81 | return input 82 | case .nuls: 83 | var input = try NULSSigningInput(serializedData: data) 84 | input.privateKey = privateKey 85 | return input 86 | case .nano: 87 | var input = try NanoSigningInput(serializedData: data) 88 | input.privateKey = privateKey 89 | return input 90 | case .nebulas: 91 | var input = try NebulasSigningInput(serializedData: data) 92 | input.privateKey = privateKey 93 | return input 94 | case .nimiq: 95 | var input = try NimiqSigningInput(serializedData: data) 96 | input.privateKey = privateKey 97 | return input 98 | case .polkadot, 99 | .kusama: 100 | var input = try PolkadotSigningInput(serializedData: data) 101 | input.privateKey = privateKey 102 | return input 103 | case .xrp: 104 | var input = try RippleSigningInput(serializedData: data) 105 | input.privateKey = privateKey 106 | return input 107 | case .solana: 108 | var input = try SolanaSigningInput(serializedData: data) 109 | input.privateKey = privateKey 110 | return input 111 | case .stellar, 112 | .kin: 113 | var input = try StellarSigningInput(serializedData: data) 114 | input.privateKey = privateKey 115 | return input 116 | case .theta: 117 | var input = try ThetaSigningInput(serializedData: data) 118 | input.privateKey = privateKey 119 | return input 120 | case .tezos: 121 | var input = try TezosSigningInput(serializedData: data) 122 | input.privateKey = privateKey 123 | return input 124 | case .tron: 125 | var input = try TronSigningInput(serializedData: data) 126 | input.privateKey = privateKey 127 | return input 128 | case .veChain: 129 | var input = try VeChainSigningInput(serializedData: data) 130 | input.privateKey = privateKey 131 | return input 132 | case .waves: 133 | var input = try WavesSigningInput(serializedData: data) 134 | input.privateKey = privateKey 135 | return input 136 | case .zilliqa: 137 | var input = try ZilliqaSigningInput(serializedData: data) 138 | input.privateKey = privateKey 139 | return input 140 | case .ontology: 141 | var input = try OntologySigningInput(serializedData: data) 142 | input.payerPrivateKey = privateKey 143 | input.ownerPrivateKey = privateKey 144 | return input 145 | case .elrond: 146 | var input = try ElrondSigningInput(serializedData: data) 147 | input.privateKey = privateKey 148 | return input 149 | default: 150 | throw TrustSDKError.coinNotSupported 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/ConfirmType.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | public extension TrustSDK { 10 | enum ConfirmType: String, Equatable { 11 | case send 12 | case sign 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/Transaction.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import BigInt 9 | import WalletCore 10 | 11 | public extension TrustSDK { 12 | struct Transaction: Equatable { 13 | public enum Action: String, Equatable { 14 | case transfer 15 | } 16 | 17 | public let to: String 18 | public let asset: UniversalAssetID 19 | public let amount: String 20 | public let action: Action 21 | public let confirm: ConfirmType 22 | public let from: String? 23 | public let nonce: UInt64? 24 | public let feeLimit: BigInt? 25 | public let feePrice: BigInt? 26 | public let meta: String? 27 | 28 | public init( 29 | asset: UniversalAssetID, 30 | to: String, 31 | amount: String, 32 | action: Action, 33 | confirm: ConfirmType, 34 | from: String? = nil, 35 | nonce: UInt64? = nil, 36 | feePrice: BigInt? = nil, 37 | feeLimit: BigInt? = nil, 38 | meta: String? = nil 39 | ) { 40 | self.asset = asset 41 | self.to = to 42 | self.amount = amount 43 | self.action = action 44 | self.confirm = confirm 45 | self.from = from 46 | self.nonce = nonce 47 | self.feePrice = feePrice 48 | self.feeLimit = feeLimit 49 | self.meta = meta 50 | } 51 | 52 | public init?(params: [String: Any]) { 53 | guard 54 | let asset = UniversalAssetID(string: (params["asset"] as? String) ?? ""), 55 | let action = Action(rawValue: (params["action"] as? String) ?? ""), 56 | let confirm = ConfirmType(rawValue: (params["confirm_type"] as? String) ?? ""), 57 | let to = params["to"] as? String, !to.isEmpty, 58 | let amount = params["amount"] as? String, !amount.isEmpty 59 | else { 60 | return nil 61 | } 62 | self.asset = asset 63 | self.to = to 64 | self.amount = amount 65 | self.action = action 66 | self.confirm = confirm 67 | self.from = params["from"] as? String 68 | self.meta = params["meta"] as? String 69 | 70 | if let limit = params["fee_limit"] as? String { 71 | self.feeLimit = BigInt(limit) 72 | } else { 73 | self.feeLimit = nil 74 | } 75 | 76 | if let price = params["fee_price"] as? String { 77 | self.feePrice = BigInt(price) 78 | } else { 79 | self.feePrice = nil 80 | } 81 | 82 | if let nonceStr = params["nonce"] as? String { 83 | self.nonce = UInt64(nonceStr) 84 | } else { 85 | self.nonce = nil 86 | } 87 | } 88 | 89 | public func params() -> [String: Any] { 90 | var params: [String: Any] = [ 91 | "asset": asset.description, 92 | "to": to, 93 | "amount": amount, 94 | "action": action.rawValue, 95 | "confirm_type": confirm.rawValue, 96 | ] 97 | if let from = from { 98 | params["from"] = from 99 | } 100 | if let nonce = nonce { 101 | params["nonce"] = nonce 102 | } 103 | if let feePrice = feePrice { 104 | params["fee_price"] = feePrice.description 105 | } 106 | if let feeLimit = feeLimit { 107 | params["fee_limit"] = feeLimit.description 108 | } 109 | if let meta = meta { 110 | params["meta"] = meta 111 | } 112 | return params 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/TrustCommand.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | public enum CommandName: String { 11 | case getAccounts = "sdk_get_accounts" 12 | case sign = "sdk_sign" 13 | case signMessage = "sdk_sign_message" 14 | case signSimple = "sdk_transaction" 15 | } 16 | 17 | enum SignMetadataName: String { 18 | case dApp = "dapp" 19 | } 20 | 21 | public extension TrustSDK { 22 | enum SignMetadata: CustomStringConvertible { 23 | case dApp(name: String, url: URL?) 24 | 25 | init?(params: [String: Any]) { 26 | guard 27 | let nameParam = params["__name"] as? String, 28 | let name = SignMetadataName(rawValue: nameParam) 29 | else { return nil } 30 | 31 | switch name { 32 | case .dApp: 33 | let name = params["name"] as? String 34 | let url = params["url"] as? String 35 | self = .dApp(name: name ?? "", url: URL(string: url ?? "")) 36 | } 37 | } 38 | 39 | var name: String { 40 | let name = { () -> SignMetadataName in 41 | switch self { 42 | case .dApp: 43 | return .dApp 44 | } 45 | }() 46 | 47 | return name.rawValue 48 | } 49 | 50 | var params: [String: Any] { 51 | var params = { () -> [String: Any] in 52 | switch self { 53 | case .dApp(let name, let url): 54 | return [ 55 | "name": name, 56 | "url": url?.absoluteString ?? "", 57 | ] 58 | } 59 | }() 60 | 61 | params["__name"] = self.name 62 | return params 63 | } 64 | 65 | public var description: String { 66 | return "\(params)" 67 | } 68 | } 69 | 70 | enum Command { 71 | case sign(coin: CoinType, input: Data, send: Bool, metadata: SignMetadata?) 72 | case signMessage(coin: CoinType, message: Data, metadata: SignMetadata?) 73 | case getAccounts(coins: [CoinType]) 74 | case signSimple(tx: Transaction) 75 | 76 | public var name: CommandName { 77 | switch self { 78 | case .getAccounts: return .getAccounts 79 | case .sign: return .sign 80 | case .signMessage: return .signMessage 81 | case .signSimple: return.signSimple 82 | } 83 | } 84 | 85 | public var params: [String: Any] { 86 | switch self { 87 | case .getAccounts(let coins): 88 | return [ 89 | "coins": coins.map { $0.rawValue }, 90 | ] 91 | case .sign(let coin, let input, let send, let meta): 92 | return [ 93 | "coin": "\(coin.rawValue)", 94 | "data": input.base64UrlEncodedString(), 95 | "send": send, 96 | "meta": meta?.params ?? [:], 97 | ] 98 | case .signMessage(let coin, let data, let meta): 99 | return [ 100 | "coin": "\(coin.rawValue)", 101 | "data": data.hex, 102 | "meta": meta?.params ?? [:], 103 | ] 104 | case .signSimple(let tx): 105 | return tx.params() 106 | } 107 | } 108 | 109 | public init?(name: String, params: [String: Any]) { 110 | switch CommandName(rawValue: name) { 111 | case .getAccounts: 112 | guard let coinsParam = params["coins"] as? [String: String] else { 113 | return nil 114 | } 115 | 116 | self = .getAccounts( 117 | coins: coinsParam 118 | .mapKeys { UInt32($0) } 119 | .sorted { $0.key < $1.key } 120 | .compactMap { $0.value.toCoin() } 121 | ) 122 | case .sign: 123 | guard 124 | let coinParam = params["coin"] as? String, 125 | let dataParam = params["data"] as? String, 126 | let coin = coinParam.toCoin(), 127 | let data = dataParam.toBase64Data() 128 | else { 129 | return nil 130 | } 131 | let metaParam = params["meta"] as? [String: Any] 132 | let sendParam = params["send"] as? String 133 | self = .sign( 134 | coin: coin, 135 | input: data, 136 | send: sendParam?.toBool() ?? false, 137 | metadata: SignMetadata(params: metaParam ?? [:]) 138 | ) 139 | case .signMessage: 140 | guard let coin = (params["coin"] as? String)?.toCoin(), 141 | let dataParam = params["data"] as? String, 142 | let data = Data(hexEncoded: dataParam) else { 143 | return nil 144 | } 145 | let meta = params["meta"] as? [String: Any] ?? [:] 146 | self = .signMessage(coin: coin, message: data, metadata: SignMetadata(params: meta)) 147 | case .signSimple: 148 | guard let tx = Transaction(params: params) else { 149 | return nil 150 | } 151 | self = .signSimple(tx: tx) 152 | default: 153 | return nil 154 | } 155 | } 156 | 157 | public init?(components: URLComponents) { 158 | guard let name = components.host else { return nil } 159 | self.init(name: name, params: Dictionary(queryItems: components.queryItems ?? [])) 160 | } 161 | } 162 | } 163 | 164 | extension TrustSDK.SignMetadata: Equatable {} 165 | extension TrustSDK.Command: Equatable {} 166 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/TrustConfiguration.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | public extension TrustSDK { 10 | struct Configuration { 11 | public static let trustWalletApp = WalletApp( 12 | scheme: "trust", 13 | installURL: URL(string: "https://apps.apple.com/app/trust-crypto-bitcoin-wallet/id1288339409")! 14 | ) 15 | 16 | let scheme: String 17 | let callback: String 18 | let walletApp: WalletApp 19 | 20 | public init( 21 | scheme: String, 22 | callback: String = "sdk_sign_result", 23 | walletApp: WalletApp = Self.trustWalletApp 24 | ) { 25 | self.scheme = scheme 26 | self.callback = callback 27 | self.walletApp = walletApp 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/TrustError.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | enum TrustSDKErrorName: String { 10 | case notInitialized = "not_initialized" 11 | case coinNotSupported = "coin_not_supported" 12 | case invalidResponse = "invalid_response" 13 | case rejectedByUser = "rejected_by_user" 14 | case signError = "sign_error" 15 | case accountError = "account_error" 16 | case unknown 17 | } 18 | 19 | public enum TrustSDKError: Error { 20 | case notInitialized 21 | case coinNotSupported 22 | case invalidResponse 23 | case rejectedByUser 24 | case signError(message: String) 25 | case accountError 26 | case unknown 27 | 28 | init?(from name: String, value: String? = nil) { 29 | switch TrustSDKErrorName(rawValue: name) { 30 | case .notInitialized: 31 | self = .notInitialized 32 | case .coinNotSupported: 33 | self = .coinNotSupported 34 | case .invalidResponse: 35 | self = .invalidResponse 36 | case .rejectedByUser: 37 | self = .rejectedByUser 38 | case .signError: 39 | self = .signError(message: value ?? "") 40 | case .accountError: 41 | self = .accountError 42 | case .unknown: 43 | self = .unknown 44 | default: 45 | return nil 46 | } 47 | } 48 | 49 | init?(components: URLComponents) { 50 | guard let name = components.queryItem(for: "error")?.value else { return nil } 51 | self.init(from: name, value: components.queryItem(for: "message")?.value) 52 | } 53 | 54 | public var name: String { 55 | let name = { () -> TrustSDKErrorName in 56 | switch self { 57 | case .notInitialized: 58 | return .notInitialized 59 | case .coinNotSupported: 60 | return .coinNotSupported 61 | case .invalidResponse: 62 | return .invalidResponse 63 | case .rejectedByUser: 64 | return .rejectedByUser 65 | case .signError: 66 | return .signError 67 | case .accountError: 68 | return .accountError 69 | case .unknown: 70 | return .unknown 71 | } 72 | }() 73 | 74 | return name.rawValue 75 | } 76 | 77 | public var params: [String: String] { 78 | var params = [ 79 | "error": self.name, 80 | ] 81 | 82 | switch self { 83 | case .signError(let message): 84 | params["message"] = message 85 | default: 86 | break 87 | } 88 | 89 | return params 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/TrustSDK.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | public class TrustSDK { 11 | enum QueryItems: String { 12 | case id 13 | } 14 | 15 | public static let signers = Signers() 16 | internal static var configuration: TrustSDK.Configuration? 17 | internal static let requestRegistry = RequestRegistry() 18 | 19 | public static func initialize(with configuration: TrustSDK.Configuration) { 20 | self.configuration = configuration 21 | } 22 | 23 | public static func application( 24 | _ app: UIApplication, 25 | open url: URL, 26 | options: [UIApplication.OpenURLOptionsKey: Any] = [:] 27 | ) -> Bool { 28 | guard 29 | let config = configuration, 30 | let components = URLComponents(url: url, resolvingAgainstBaseURL: false), 31 | let scheme = components.scheme, 32 | let host = components.host, 33 | scheme == config.scheme && host == config.callback 34 | else { 35 | return false 36 | } 37 | 38 | guard let id = components.queryItem(for: QueryItems.id.rawValue)?.value else { 39 | return false 40 | } 41 | 42 | requestRegistry.resolve(request: id, with: components) 43 | return true 44 | } 45 | } 46 | 47 | extension TrustSDK { 48 | static func send(request: Request) throws { 49 | guard let config = configuration else { 50 | throw TrustSDKError.notInitialized 51 | } 52 | 53 | let id = requestRegistry.register(request: request) 54 | let command = request.command 55 | config.walletApp.open( 56 | command: command.name.rawValue, 57 | params: command.params.queryItems(), 58 | app: config.scheme, 59 | callback: config.callback, 60 | id: id 61 | ) 62 | } 63 | } 64 | 65 | public extension TrustSDK { 66 | static func getAccounts(for coins: [CoinType], callback: @escaping ((Result<[String], Error>) -> Void)) { 67 | do { 68 | for coin in coins { 69 | if !isSupported(coin: coin) { 70 | callback(.failure(TrustSDKError.coinNotSupported)) 71 | return 72 | } 73 | } 74 | 75 | let command: TrustSDK.Command = .getAccounts(coins: coins) 76 | try send(request: GetAccountsRequest(command: command, callback: callback)) 77 | } catch { 78 | callback(.failure(error)) 79 | } 80 | } 81 | } 82 | 83 | public extension TrustSDK { 84 | static func isSupported(coin: CoinType) -> Bool { 85 | switch coin { 86 | case .aeternity, 87 | .aion, 88 | .algorand, 89 | .binance, 90 | .cosmos, 91 | .bandChain, 92 | .kava, 93 | .terra, 94 | .ethereum, 95 | .ethereumClassic, 96 | .callisto, 97 | .goChain, 98 | .poanetwork, 99 | .smartChain, 100 | .tomoChain, 101 | .thunderToken, 102 | .wanchain, 103 | .eos, 104 | .elrond, 105 | .filecoin, 106 | .fio, 107 | .harmony, 108 | .icon, 109 | .ioTeX, 110 | .ontology, 111 | .near, 112 | .neo, 113 | .nuls, 114 | .nano, 115 | .nebulas, 116 | .nimiq, 117 | .polkadot, 118 | .kusama, 119 | .xrp, 120 | .solana, 121 | .stellar, 122 | .kin, 123 | .theta, 124 | .tezos, 125 | .tron, 126 | .veChain, 127 | .waves, 128 | .zilliqa: 129 | return true 130 | default: 131 | return false 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/Types/WalletApp.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | /// Describes a wallet app supporting the trust deeplink spec 10 | public struct WalletApp { 11 | /// Wallet scheme 12 | public let scheme: String 13 | /// Wallet install URL 14 | let installURL: URL 15 | 16 | public init(scheme: String, installURL: URL) { 17 | self.scheme = scheme 18 | self.installURL = installURL 19 | } 20 | } 21 | 22 | extension WalletApp { 23 | enum ParamKeys: String { 24 | case app, callback, id 25 | } 26 | 27 | func build(command: String, params: [URLQueryItem], app: String, callback: String, id: String) -> URL? { 28 | guard let url = URL(string: "\(scheme)://\(command)"), 29 | var components = URLComponents(url: url, resolvingAgainstBaseURL: true) else { 30 | return nil 31 | } 32 | 33 | components.queryItems = params 34 | components.queryItems?.append(contentsOf: [ 35 | URLQueryItem(name: ParamKeys.app.rawValue, value: app), 36 | URLQueryItem(name: ParamKeys.callback.rawValue, value: callback), 37 | URLQueryItem(name: ParamKeys.id.rawValue, value: id), 38 | ]) 39 | 40 | return components.url 41 | } 42 | 43 | func open(command: String, params: [URLQueryItem], app: String, callback: String, id: String) { 44 | if let url = build(command: command, params: params, app: app, callback: callback, id: id), UIApplication.shared.canOpenURL(url) { 45 | UIApplication.shared.open(url) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/UI/Colors.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import UIKit 8 | 9 | extension TrustSDK { 10 | public struct Colors { 11 | static let white = color(light: .white, dark: .white) 12 | static let light = color(light: .white, dark: .black) 13 | static let black = color(light: .black, dark: .black) 14 | static let blue = color(light: UIColor(hex: 0x2e91db), dark: UIColor(hex: 0x4390E2)) 15 | 16 | internal static func color(light: UIColor, dark: UIColor) -> UIColor { 17 | if #available(iOS 13.0, *) { 18 | return UIColor { (traits) -> UIColor in 19 | return traits.userInterfaceStyle == .dark ? dark : light 20 | } 21 | } else { 22 | return light 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/UI/Icons.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import UIKit 8 | 9 | extension TrustSDK { 10 | public static let resourceBundle: Bundle = { 11 | let bundle = Bundle(for: TrustSDK.self) 12 | guard let resourceBundleUrl = bundle.url(forResource: "TrustSDK", withExtension: "bundle") else { 13 | fatalError("TrustSDK.bundle not found!") 14 | } 15 | guard let resourceBundle = Bundle(url: resourceBundleUrl) else { 16 | fatalError("Could not access TrustSDK.bundle") 17 | } 18 | return resourceBundle 19 | }() 20 | 21 | public enum Icon { 22 | case trust, shieldFilled, shieldLined 23 | 24 | public var image: UIImage? { 25 | switch self { 26 | case .trust: 27 | return UIImage(named: "trust", in: TrustSDK.resourceBundle, compatibleWith: nil) 28 | case .shieldFilled: 29 | return UIImage(named: "trust.shield.fill", in: TrustSDK.resourceBundle, compatibleWith: nil) 30 | case .shieldLined: 31 | return UIImage(named: "trust.shield", in: TrustSDK.resourceBundle, compatibleWith: nil) 32 | } 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/UI/TrustButton.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import UIKit 8 | import WalletCore 9 | 10 | public final class TrustButton: UIButton { 11 | public enum Action { 12 | case getAccounts( 13 | coins: [CoinType], 14 | callback: ((Result<[String], Error>) -> Void) 15 | ) 16 | 17 | case signMessage(Data, 18 | metadata: TrustSDK.SignMetadata? = nil, 19 | callback: ((Result) -> Void) 20 | ) 21 | 22 | case sign( 23 | signer: TrustSDK.Signer, 24 | input: SigningInput, 25 | metadata: TrustSDK.SignMetadata? = nil, 26 | callback: ((Result) -> Void) 27 | ) 28 | 29 | case signThenSend( 30 | signer: TrustSDK.Signer, 31 | input: SigningInput, 32 | metadata: TrustSDK.SignMetadata? = nil, 33 | callback: ((Result) -> Void) 34 | ) 35 | } 36 | 37 | private var isFullRounded: Bool = false 38 | public var action: Action? 39 | 40 | public override init(frame: CGRect) { 41 | super.init(frame: frame) 42 | initialize() 43 | } 44 | 45 | public required init?(coder: NSCoder) { 46 | super.init(coder: coder) 47 | initialize() 48 | } 49 | 50 | private func initialize() { 51 | self.apply(theme: .blue) 52 | self.addTarget(self, action: #selector(didPress), for: .touchUpInside) 53 | } 54 | 55 | public func apply(theme: TrustButtonTheme) { 56 | for style in theme.styles { 57 | apply(style: style) 58 | } 59 | } 60 | 61 | @objc func didPress() { 62 | switch action { 63 | case let .getAccounts(coins, callback): 64 | TrustSDK.getAccounts(for: coins, callback: callback) 65 | case let .sign(signer, input, metadata, callback): 66 | signer.sign(input: input, metadata: metadata, callback: callback) 67 | case let .signThenSend(signer, input, metadata, callback): 68 | signer.signThenSend(input: input, metadata: metadata, callback: callback) 69 | case let .signMessage(message, metadata, callback): 70 | TrustSDK.signers.ethereum.sign(message: message, metadata: metadata, callback: callback) 71 | case .none: 72 | break 73 | } 74 | } 75 | 76 | func apply(style: TrustButtonStyle) { 77 | switch style { 78 | case let .font(font): 79 | self.titleLabel?.font = font 80 | case let .title(style): 81 | guard let font = self.titleLabel?.font else { 82 | return 83 | } 84 | self.setAttributedTitle(style.title(font: font), for: .normal) 85 | case let .icon(icon, insets): 86 | self.setImage(icon.image, for: .normal) 87 | self.imageView?.contentMode = .scaleAspectFit 88 | self.imageEdgeInsets = insets 89 | case let .tintColor(color): 90 | self.tintColor = color 91 | case let .backgroundColor(color): 92 | self.backgroundColor = color 93 | case let .border(width, color): 94 | self.layer.borderColor = color.cgColor 95 | self.layer.borderWidth = width 96 | case let .round(radius): 97 | self.layer.cornerRadius = radius 98 | self.isFullRounded = false 99 | case .roundFull: 100 | self.layer.cornerRadius = 0 101 | self.isFullRounded = true 102 | } 103 | } 104 | 105 | public override func layoutSubviews() { 106 | super.layoutSubviews() 107 | if isFullRounded { 108 | self.layer.cornerRadius = self.bounds.height / 2.0 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/UI/TrustButtonTheme.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | public struct TrustButtonTheme { 10 | let styles: [TrustButtonStyle] 11 | 12 | public init(_ styles: TrustButtonStyle...) { 13 | self.styles = styles 14 | } 15 | 16 | init(styles: [TrustButtonStyle]) { 17 | self.styles = styles 18 | } 19 | 20 | public func with(styles: TrustButtonStyle...) -> TrustButtonTheme { 21 | let current = self.styles.filter { !styles.contains($0) } 22 | return TrustButtonTheme(styles: current + styles) 23 | } 24 | 25 | public static let white = TrustButtonTheme( 26 | .font(.systemFont(ofSize: 18, weight: .regular)), 27 | .tintColor(TrustSDK.Colors.blue), 28 | .backgroundColor(TrustSDK.Colors.light), 29 | .border(width: 1, color: TrustSDK.Colors.blue), 30 | .round(radius: 8.0) 31 | ) 32 | 33 | public static let blue = TrustButtonTheme( 34 | .font(.systemFont(ofSize: 18, weight: .regular)), 35 | .tintColor(TrustSDK.Colors.white), 36 | .backgroundColor(TrustSDK.Colors.blue), 37 | .round(radius: 8.0) 38 | ) 39 | 40 | public static let black = TrustButtonTheme( 41 | .font(.systemFont(ofSize: 18, weight: .regular)), 42 | .tintColor(TrustSDK.Colors.white), 43 | .backgroundColor(TrustSDK.Colors.black), 44 | .border(width: 1, color: TrustSDK.Colors.white), 45 | .round(radius: 8.0) 46 | ) 47 | } 48 | 49 | enum TrustButtonStyleName: String { 50 | case icon 51 | case font 52 | case title 53 | case backgroundColor 54 | case tintColor 55 | case border 56 | case round 57 | case roundFull 58 | } 59 | 60 | public enum TrustButtonTitleStyle { 61 | case plain(String) 62 | case payWithTrust(icon: TrustSDK.Icon, size: CGSize = CGSize(width: 20, height: 20)) 63 | 64 | func title(font: UIFont) -> NSAttributedString { 65 | switch self { 66 | case .plain(let title): 67 | return NSAttributedString(string: title) 68 | case let .payWithTrust(icon, iconSize): 69 | let titleString = NSMutableAttributedString(string: "Pay with".localized()) 70 | titleString.append(NSAttributedString(string: " ")) 71 | 72 | let iconAttachment = NSTextAttachment() 73 | iconAttachment.image = icon.image 74 | iconAttachment.bounds = CGRect(origin: CGPoint(x: 0, y: (font.capHeight - iconSize.height) / 2), size: iconSize) 75 | 76 | titleString.append(NSAttributedString(attachment: iconAttachment)) 77 | titleString.append(NSAttributedString(string: "Wallet".localized())) 78 | 79 | return titleString 80 | } 81 | 82 | } 83 | } 84 | 85 | public enum TrustButtonStyle { 86 | case backgroundColor(UIColor) 87 | case tintColor(UIColor) 88 | case font(UIFont) 89 | case icon(TrustSDK.Icon, insets: UIEdgeInsets = UIEdgeInsets(top: 5.0, left: 0, bottom: 5.0, right: 8.0)) 90 | case title(TrustButtonTitleStyle) 91 | case border(width: CGFloat, color: UIColor) 92 | case round(radius: CGFloat) 93 | case roundFull 94 | 95 | var name: TrustButtonStyleName { 96 | switch self { 97 | case .icon: return .icon 98 | case .font: return .font 99 | case .title: return .title 100 | case .backgroundColor: return .backgroundColor 101 | case .tintColor: return .tintColor 102 | case .border: return .border 103 | case .round: return .round 104 | case .roundFull: return .roundFull 105 | } 106 | } 107 | } 108 | 109 | extension TrustButtonStyle: Hashable { 110 | public static func == (lhs: TrustButtonStyle, rhs: TrustButtonStyle) -> Bool { 111 | return lhs.name == rhs.name 112 | } 113 | 114 | public func hash(into hasher: inout Hasher) { 115 | self.name.hash(into: &hasher) 116 | } 117 | } 118 | 119 | extension Array where Element == TrustButtonStyle { 120 | func unique() -> [Element] { 121 | return Array(Set(self)) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Client/UI/UIColor+Hex.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | extension UIColor { 10 | convenience init(hex: UInt64) { 11 | let red = (hex & 0xff0000) >> 16 12 | let green = (hex & 0xff00) >> 8 13 | let blue = hex & 0xff 14 | 15 | self.init( 16 | red: CGFloat(red) / 0xff, 17 | green: CGFloat(green) / 0xff, 18 | blue: CGFloat(blue) / 0xff, alpha: 1 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Wallet/WalletRequest.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | public extension WalletSDK { 10 | struct Request: Equatable { 11 | enum Keys: String { 12 | case app, callback, id 13 | } 14 | 15 | public let command: TrustSDK.Command 16 | public let app: String 17 | public let callback: String 18 | public let id: String 19 | 20 | public init?(command name: String, params: [String: Any]) { 21 | guard 22 | let command = TrustSDK.Command(name: name, params: params), 23 | let app = params[Keys.app.rawValue] as? String, 24 | let callback = params[Keys.callback.rawValue] as? String, 25 | let id = params[Keys.id.rawValue] as? String else { 26 | return nil 27 | } 28 | 29 | self.command = command 30 | self.app = app 31 | self.callback = callback 32 | self.id = id 33 | } 34 | 35 | public init?(components: URLComponents) { 36 | guard let name = components.host else { return nil } 37 | self.init(command: name, params: Dictionary(queryItems: components.queryItems ?? [])) 38 | } 39 | 40 | func callbackUrl(response: Response) -> URL? { 41 | guard 42 | let baseUrl = URL(string: "\(app)://\(callback)"), 43 | var components = URLComponents(url: baseUrl, resolvingAgainstBaseURL: false) 44 | else { return nil } 45 | 46 | var params = response.params 47 | params[Keys.id.rawValue] = id 48 | 49 | components.queryItems = params.sorted { $0.key < $1.key }.map { URLQueryItem(name: $0, value: $1) } 50 | 51 | return components.url 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Wallet/WalletResponse.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | import WalletCore 9 | 10 | public extension WalletSDK { 11 | enum Response { 12 | case sign(output: Data) 13 | case signThenSend(txHash: String) 14 | case signMessage(signature: Data) 15 | case accounts([String]) 16 | case failure(error: TrustSDKError) 17 | case signSimple(data: Data) 18 | case sentSimple(hash: String) 19 | 20 | var params: [String: String] { 21 | switch self { 22 | case .sign(let output): 23 | return [ 24 | "data": output.base64UrlEncodedString(), 25 | ] 26 | case .accounts(let accounts): 27 | return [ 28 | "accounts": accounts.joined(separator: ","), 29 | ] 30 | case .signThenSend(let txHash): 31 | return [ 32 | "tx_hash": txHash, 33 | ] 34 | case .signMessage(let signature): 35 | return [ 36 | "signature": signature.hex, 37 | ] 38 | case .failure(let error): 39 | return error.params 40 | case .signSimple(let data): 41 | return [ 42 | "data": "0x" + data.hex, 43 | ] 44 | case .sentSimple(let data): 45 | return [ 46 | "data": data, 47 | ] 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /TrustSDK/Classes/Wallet/WalletSDK.swift: -------------------------------------------------------------------------------- 1 | // Copyright Trust Wallet. All rights reserved. 2 | // 3 | // This file is part of TrustSDK. The full TrustSDK copyright notice, including 4 | // terms governing use, modification, and redistribution, is contained in the 5 | // file LICENSE at the root of the source code distribution tree. 6 | 7 | import Foundation 8 | 9 | public struct WalletSDK { 10 | public static var delegate: WalletSDKDelegate? 11 | 12 | public static func application( 13 | _ app: UIApplication, 14 | open url: URL, 15 | options: [UIApplication.OpenURLOptionsKey: Any] = [:] 16 | ) -> Bool { 17 | guard 18 | let components = URLComponents(url: url, resolvingAgainstBaseURL: false), 19 | let request = WalletSDK.Request(components: components) else { 20 | return false 21 | } 22 | 23 | dispatch(request: request) 24 | 25 | return true 26 | } 27 | 28 | public static func dispatch(request: Request) { 29 | delegate?.didReceive(request: request, callback: { response in 30 | guard let url = request.callbackUrl(response: response) else { return } 31 | UIApplication.shared.open(url) 32 | }) 33 | } 34 | } 35 | 36 | public protocol WalletSDKDelegate: AnyObject { 37 | func didReceive(request: WalletSDK.Request, callback: @escaping ((WalletSDK.Response) -> Void)) 38 | } 39 | -------------------------------------------------------------------------------- /TrustSDK/Resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/TrustSDK/Resources/.gitkeep -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "trust_icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.imageset/trust_icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/TrustSDK/Resources/Images.xcassets/trust.imageset/trust_icon.pdf -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.shield.fill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "trust_filled.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.shield.fill.imageset/trust_filled.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/TrustSDK/Resources/Images.xcassets/trust.shield.fill.imageset/trust_filled.pdf -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.shield.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "trust_line.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TrustSDK/Resources/Images.xcassets/trust.shield.imageset/trust_line.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/TrustSDK/Resources/Images.xcassets/trust.shield.imageset/trust_line.pdf -------------------------------------------------------------------------------- /TrustSDK/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | "Pay with"="Pay with"; 2 | "Trust Wallet"="Trust Wallet"; 3 | "Wallet"="Wallet"; 4 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /docs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/docs/demo.gif -------------------------------------------------------------------------------- /docs/scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustwallet/TrustSDK-iOS/9b0c2f2a3eab1cd580de60168fa85dbbb9c5e5d1/docs/scheme.png -------------------------------------------------------------------------------- /tools/pod-release: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | VERSION=$1 6 | if [ -z "$VERSION" ]; then 7 | VERSION=`git describe --long --tags | cut -f 1 -d "-"` 8 | fi 9 | 10 | PODSPEC_FILE="/tmp/TrustSDK.podspec" 11 | echo Pushing "$VERSION" "$PODSPEC_FILE" 12 | 13 | cat << EOF > "$PODSPEC_FILE" 14 | Pod::Spec.new do |s| 15 | s.name = 'TrustSDK' 16 | s.version = '$VERSION' 17 | s.summary = 'Trust Wallet SDK' 18 | s.homepage = 'https://github.com/trustwallet/TrustSDK-iOS' 19 | s.license = { :type => 'MIT', :file => 'LICENSE' } 20 | s.authors = { 'Leone Parise' => 'leoneparise', 'Viktor Radchenko' => 'vikmeup' } 21 | s.source = { :git => 'https://github.com/trustwallet/TrustSDK-iOS.git', :tag => s.version.to_s } 22 | s.ios.deployment_target = '11.0' 23 | s.swift_version = '5.1' 24 | s.default_subspec = 'Client' 25 | 26 | s.subspec 'Client' do |cs| 27 | cs.source_files = 'TrustSDK/Classes/Client/**/*' 28 | cs.dependency 'TrustWalletCore/Types', '~> 2.3.2' 29 | cs.dependency 'BigInt' 30 | end 31 | 32 | s.subspec 'Wallet' do |cs| 33 | cs.source_files = 'TrustSDK/Classes/Wallet/**/*' 34 | cs.dependency 'TrustSDK/Client' 35 | end 36 | end 37 | EOF 38 | 39 | # Upload to Cocoapod 40 | echo "Done. running 'pod trunk push $PODSPEC_FILE'" 41 | pod trunk push --allow-warnings "$PODSPEC_FILE" 42 | --------------------------------------------------------------------------------