├── .circleci └── config.yml ├── .gitignore ├── Cadence.podspec ├── FlowSDK.podspec ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── Protobuf └── flow │ ├── access │ └── access.proto │ ├── entities │ ├── account.proto │ ├── block.proto │ ├── block_header.proto │ ├── block_seal.proto │ ├── collection.proto │ ├── event.proto │ ├── execution_result.proto │ └── transaction.proto │ └── execution │ └── execution.proto ├── README.md ├── Sources ├── Cadence │ ├── Address.swift │ ├── Argument.swift │ ├── CType │ │ ├── CompositeType.swift │ │ ├── EnumType.swift │ │ ├── FieldType.swift │ │ ├── FunctionType.swift │ │ ├── InitializerType.swift │ │ ├── IntersectionType.swift │ │ ├── ParameterType.swift │ │ ├── ReferenceType.swift │ │ └── RestrictionType.swift │ ├── Capability.swift │ ├── Composite.swift │ ├── Dictionary.swift │ ├── Extensions │ │ ├── CodingUserInfoKeyExtension.swift │ │ ├── KeyedDecodingContainerProtocolExtension.swift │ │ ├── SingleValueDecodingContainerExtension.swift │ │ └── StringExtension.swift │ ├── FType.swift │ ├── FTypeDecodingResults.swift │ ├── FTypeKind.swift │ ├── Format.swift │ ├── Path.swift │ ├── StaticTypeValue.swift │ ├── Value.swift │ └── ValueType.swift └── FlowSDK │ ├── Client.swift │ ├── Crypto │ ├── HashAlgorithm.swift │ ├── InMemorySigner.swift │ ├── PrivateKey.swift │ ├── PublicKey.swift │ ├── SHA256Digest.swift │ ├── SignatureAlgorithm.swift │ └── Signer.swift │ ├── Extensions │ ├── HashAlgorithm+Cadence.swift │ ├── PublickKey+Cadence.swift │ └── SignatureAlgorithm+Cadence.swift │ ├── Models │ ├── Account.swift │ ├── Block.swift │ ├── BlockEvents.swift │ ├── Collection.swift │ ├── DomainTag.swift │ ├── Event.swift │ ├── ExecutionResult.swift │ ├── Identifier.swift │ ├── Transaction.swift │ ├── TransactionProposalKey.swift │ ├── TransactionResult.swift │ └── TransactionSignature.swift │ ├── Network.swift │ ├── Protobuf │ └── Generated │ │ └── flow │ │ ├── access │ │ ├── access.grpc.swift │ │ └── access.pb.swift │ │ ├── entities │ │ ├── account.pb.swift │ │ ├── block.pb.swift │ │ ├── block_header.pb.swift │ │ ├── block_seal.pb.swift │ │ ├── collection.pb.swift │ │ ├── event.pb.swift │ │ ├── execution_result.pb.swift │ │ └── transaction.pb.swift │ │ └── execution │ │ ├── execution.grpc.swift │ │ └── execution.pb.swift │ └── RLP │ ├── RLPDecodable.swift │ ├── RLPDecoder.swift │ ├── RLPDecodingError.swift │ ├── RLPEncodable.swift │ ├── RLPEncodableList.swift │ └── RLPItem.swift ├── Tests ├── CadenceTests │ ├── AddressTests.swift │ ├── ArgumentTests.swift │ ├── StaticTypeTests.swift │ └── ValueTests.swift └── FlowSDKTests │ ├── ClientTests.swift │ ├── Crypto │ ├── PrivateKeyTests.swift │ └── PublicKeyTests.swift │ ├── Generated │ └── flow │ │ ├── access │ │ └── access.grpc.swift │ │ └── execution │ │ └── execution.grpc.swift │ ├── Integration │ ├── SendScriptTests.swift │ └── SendTransactionTests.swift │ ├── Mock │ └── FlowAccessAPIProvider.swift │ ├── Models │ └── TransactionTests.swift │ ├── RLP │ ├── RLPDecoderTests.swift │ └── RLPEncodableTests.swift │ ├── TestData │ ├── FlowToken.cdc │ ├── createAccount.cdc │ ├── getFlowBalance.cdc │ ├── getFlowFees.cdc │ ├── greetingScript.cdc │ ├── protocolState.hex │ └── transferFlow.cdc │ └── Utils.swift ├── examples └── cocoapods │ ├── Example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── Example.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── Example │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── ContentView.swift │ ├── ExampleApp.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── ViewModel.swift │ ├── Gemfile │ ├── Gemfile.lock │ ├── Podfile │ └── Podfile.lock └── images └── logo.jpg /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | jobs: 4 | build-and-test: 5 | macos: 6 | xcode: 13.4.1 7 | steps: 8 | - checkout 9 | - run: 10 | name: Run tests 11 | command: swift test -v 12 | 13 | workflows: 14 | build_and_test: 15 | jobs: 16 | - build-and-test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Environment Variable 2 | .env 3 | .bundle 4 | vendor 5 | 6 | .DS_Store 7 | 8 | ## Build generated 9 | # build/ 10 | DerivedData/ 11 | ..xcarchive 12 | *.xcarchive 13 | 14 | ## Various settings 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata/ 24 | 25 | ## Other 26 | *.moved-aside 27 | *.xccheckout 28 | *.xcscmblueprint 29 | 30 | ## Obj-C/Swift specific 31 | *.hmap 32 | *.ipa 33 | *.dSYM.zip 34 | *.dSYM 35 | 36 | # Swift Package Manager 37 | .build/ 38 | .swiftpm 39 | 40 | # CocoaPods 41 | Pods/ 42 | 43 | # VIM 44 | *.swp 45 | *.swo 46 | *~ 47 | -------------------------------------------------------------------------------- /Cadence.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Cadence' 3 | s.version = '0.7.1' 4 | s.summary = 'JSON-Cadence Data Interchange Format Wrapper' 5 | 6 | s.homepage = 'https://github.com/portto/flow-swift-sdk' 7 | s.license = { :type => 'Apache 2.0', :file => 'LICENSE' } 8 | s.author = { 'Scott' => 'scott@portto.com' } 9 | s.source = { :git => 'https://github.com/portto/flow-swift-sdk.git', :tag => s.version.to_s } 10 | s.social_media_url = 'https://twitter.com/BloctoApp' 11 | 12 | s.swift_version = '5.0' 13 | s.ios.deployment_target = '13.0' 14 | 15 | s.source_files = "Sources/Cadence/**/*" 16 | s.dependency "BigInt", "~> 5.2.0" 17 | s.dependency "CryptoSwift", "~> 1.5.1" 18 | 19 | end 20 | -------------------------------------------------------------------------------- /FlowSDK.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'FlowSDK' 3 | s.version = '0.7.1' 4 | s.summary = 'Flow blockchain swift SDK' 5 | 6 | s.homepage = 'https://github.com/portto/flow-swift-sdk' 7 | s.license = { :type => 'Apache 2.0', :file => 'LICENSE' } 8 | s.author = { 'Scott' => 'scott@portto.com' } 9 | s.source = { :git => 'https://github.com/portto/flow-swift-sdk.git', :tag => s.version.to_s } 10 | s.social_media_url = 'https://twitter.com/BloctoApp' 11 | 12 | s.swift_version = '5.0' 13 | s.ios.deployment_target = '13.0' 14 | 15 | s.default_subspec = 'FlowSDK' 16 | 17 | s.subspec "FlowSDK" do |ss| 18 | ss.source_files = "Sources/FlowSDK/**/*" 19 | ss.dependency "BigInt", "~> 5.2.0" 20 | ss.dependency "CryptoSwift", "~> 1.5.1" 21 | ss.dependency "Cadence", "~> 0.7.1" 22 | ss.dependency "gRPC-Swiftp", "1.8.2" 23 | ss.dependency "SwiftProtobuf", '1.9.0' 24 | ss.dependency "secp256k1Swift", "~> 0.7.4" 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ALL_PROTOBUF_FILES=./Protobuf/flow/**/*.proto 2 | GENERATED_SOURCES_PATH=./Sources/FlowSDK/Protobuf/Generated 3 | GENERATED_TESTS_PATH=./Tests/FlowSDKTests/Generated 4 | 5 | install: 6 | brew list swift-protobuf || brew install swift-protobuf 7 | brew list grpc-swift || brew install grpc-swift 8 | 9 | generate-protobuf: clean 10 | mkdir -p ${GENERATED_SOURCES_PATH} 11 | protoc ${ALL_PROTOBUF_FILES} \ 12 | -I=./Protobuf \ 13 | --swift_opt=Visibility=Public \ 14 | --swift_out=${GENERATED_SOURCES_PATH} 15 | protoc ${ALL_PROTOBUF_FILES} \ 16 | -I=./Protobuf \ 17 | --grpc-swift_opt=Client=true,Server=false,Visibility=Public \ 18 | --grpc-swift_out=${GENERATED_SOURCES_PATH} 19 | 20 | mkdir -p ${GENERATED_TESTS_PATH} 21 | protoc ${ALL_PROTOBUF_FILES} \ 22 | -I=./Protobuf \ 23 | --grpc-swift_opt=Client=false,Server=true,ExtraModuleImports=FlowSDK \ 24 | --grpc-swift_out=${GENERATED_TESTS_PATH} 25 | 26 | clean: 27 | if [ -d "${GENERATED_SOURCES_PATH}" ]; then rm -r ${GENERATED_SOURCES_PATH}; fi 28 | if [ -d "${GENERATED_TESTS_PATH}" ]; then rm -r ${GENERATED_TESTS_PATH}; fi 29 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "bigint", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/attaswift/BigInt.git", 7 | "state" : { 8 | "revision" : "889a1ecacd73ccc189c5cb29288048f186c44ed9", 9 | "version" : "5.2.1" 10 | } 11 | }, 12 | { 13 | "identity" : "cryptoswift", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", 16 | "state" : { 17 | "revision" : "039f56c5d7960f277087a0be51f5eb04ed0ec073", 18 | "version" : "1.5.1" 19 | } 20 | }, 21 | { 22 | "identity" : "grpc-swift", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/grpc/grpc-swift.git", 25 | "state" : { 26 | "revision" : "4c63368b7462305903507e8acebd77264c0fb695", 27 | "version" : "1.8.2" 28 | } 29 | }, 30 | { 31 | "identity" : "secp256k1", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/portto/secp256k1.git", 34 | "state" : { 35 | "revision" : "6864a2560066cedede330c4b344689432a7300f7", 36 | "version" : "0.0.5" 37 | } 38 | }, 39 | { 40 | "identity" : "secp256k1.swift", 41 | "kind" : "remoteSourceControl", 42 | "location" : "https://github.com/portto/secp256k1.swift", 43 | "state" : { 44 | "revision" : "23aa6bab1f60e513297d0d58a863418f68534e56", 45 | "version" : "0.7.4" 46 | } 47 | }, 48 | { 49 | "identity" : "swift-log", 50 | "kind" : "remoteSourceControl", 51 | "location" : "https://github.com/apple/swift-log.git", 52 | "state" : { 53 | "revision" : "5d66f7ba25daf4f94100e7022febf3c75e37a6c7", 54 | "version" : "1.4.2" 55 | } 56 | }, 57 | { 58 | "identity" : "swift-nio", 59 | "kind" : "remoteSourceControl", 60 | "location" : "https://github.com/apple/swift-nio.git", 61 | "state" : { 62 | "revision" : "124119f0bb12384cef35aa041d7c3a686108722d", 63 | "version" : "2.40.0" 64 | } 65 | }, 66 | { 67 | "identity" : "swift-nio-extras", 68 | "kind" : "remoteSourceControl", 69 | "location" : "https://github.com/apple/swift-nio-extras.git", 70 | "state" : { 71 | "revision" : "8eea84ec6144167354387ef9244b0939f5852dc8", 72 | "version" : "1.11.0" 73 | } 74 | }, 75 | { 76 | "identity" : "swift-nio-http2", 77 | "kind" : "remoteSourceControl", 78 | "location" : "https://github.com/apple/swift-nio-http2.git", 79 | "state" : { 80 | "revision" : "108ac15087ea9b79abb6f6742699cf31de0e8772", 81 | "version" : "1.22.0" 82 | } 83 | }, 84 | { 85 | "identity" : "swift-nio-ssl", 86 | "kind" : "remoteSourceControl", 87 | "location" : "https://github.com/apple/swift-nio-ssl.git", 88 | "state" : { 89 | "revision" : "1750873bce84b4129b5303655cce2c3d35b9ed3a", 90 | "version" : "2.19.0" 91 | } 92 | }, 93 | { 94 | "identity" : "swift-nio-transport-services", 95 | "kind" : "remoteSourceControl", 96 | "location" : "https://github.com/apple/swift-nio-transport-services.git", 97 | "state" : { 98 | "revision" : "1a4692acb88156e3da1b0c6732a8a38b2a744166", 99 | "version" : "1.12.0" 100 | } 101 | }, 102 | { 103 | "identity" : "swift-protobuf", 104 | "kind" : "remoteSourceControl", 105 | "location" : "https://github.com/apple/swift-protobuf.git", 106 | "state" : { 107 | "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", 108 | "version" : "1.28.2" 109 | } 110 | } 111 | ], 112 | "version" : 2 113 | } 114 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.6 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "FlowSDK", 7 | platforms: [ 8 | .iOS(.v13), 9 | .macOS(.v10_15), 10 | .tvOS(.v13), 11 | .watchOS(.v6) 12 | ], 13 | products: [ 14 | .library( 15 | name: "FlowSDK", 16 | targets: ["FlowSDK"]) 17 | ], 18 | dependencies: [ 19 | .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.8.2"), 20 | .package(url: "https://github.com/attaswift/BigInt.git", .upToNextMinor(from: "5.2.0")), 21 | .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .upToNextMajor(from: "1.5.1")), 22 | .package(url: "https://github.com/portto/secp256k1.swift", from: "0.7.4") 23 | ], 24 | targets: [ 25 | .target( 26 | name: "Cadence", 27 | dependencies: [ 28 | "BigInt", 29 | "CryptoSwift" 30 | ] 31 | ), 32 | .target( 33 | name: "FlowSDK", 34 | dependencies: [ 35 | "BigInt", 36 | "CryptoSwift", 37 | "Cadence", 38 | .product(name: "GRPC", package: "grpc-swift"), 39 | .product(name: "secp256k1Swift", package: "secp256k1.swift") 40 | ] 41 | ), 42 | .testTarget( 43 | name: "CadenceTests", 44 | dependencies: ["Cadence"] 45 | ), 46 | .testTarget( 47 | name: "FlowSDKTests", 48 | dependencies: ["FlowSDK"], 49 | resources: [ 50 | .copy("TestData") 51 | ] 52 | ), 53 | ], 54 | swiftLanguageVersions: [.v5] 55 | ) 56 | -------------------------------------------------------------------------------- /Protobuf/flow/access/access.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.access; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/access"; 6 | option java_package = "org.onflow.protobuf.access"; 7 | 8 | import "flow/entities/account.proto"; 9 | import "flow/entities/block_header.proto"; 10 | import "flow/entities/block.proto"; 11 | import "flow/entities/collection.proto"; 12 | import "flow/entities/event.proto"; 13 | import "flow/entities/execution_result.proto"; 14 | import "flow/entities/transaction.proto"; 15 | import "google/protobuf/timestamp.proto"; 16 | 17 | // AccessAPI is the public-facing API provided by access nodes. 18 | service AccessAPI { 19 | // Ping is used to check if the access node is alive and healthy. 20 | rpc Ping(PingRequest) returns (PingResponse); 21 | 22 | // Block Headers 23 | 24 | // GetLatestBlockHeader gets the latest sealed or unsealed block header. 25 | rpc GetLatestBlockHeader(GetLatestBlockHeaderRequest) 26 | returns (BlockHeaderResponse); 27 | // GetBlockHeaderByID gets a block header by ID. 28 | rpc GetBlockHeaderByID(GetBlockHeaderByIDRequest) 29 | returns (BlockHeaderResponse); 30 | // GetBlockHeaderByHeight gets a block header by height. 31 | rpc GetBlockHeaderByHeight(GetBlockHeaderByHeightRequest) 32 | returns (BlockHeaderResponse); 33 | 34 | // Blocks 35 | 36 | // GetLatestBlock gets the full payload of the latest sealed or unsealed 37 | // block. 38 | rpc GetLatestBlock(GetLatestBlockRequest) returns (BlockResponse); 39 | // GetBlockByID gets a full block by ID. 40 | rpc GetBlockByID(GetBlockByIDRequest) returns (BlockResponse); 41 | // GetBlockByHeight gets a full block by height. 42 | rpc GetBlockByHeight(GetBlockByHeightRequest) returns (BlockResponse); 43 | 44 | // Collections 45 | 46 | // GetCollectionByID gets a collection by ID. 47 | rpc GetCollectionByID(GetCollectionByIDRequest) returns (CollectionResponse); 48 | 49 | // Transactions 50 | 51 | // SendTransaction submits a transaction to the network. 52 | rpc SendTransaction(SendTransactionRequest) returns (SendTransactionResponse); 53 | // GetTransaction gets a transaction by ID. 54 | rpc GetTransaction(GetTransactionRequest) returns (TransactionResponse); 55 | // GetTransactionResult gets the result of a transaction. 56 | rpc GetTransactionResult(GetTransactionRequest) 57 | returns (TransactionResultResponse); 58 | // GetTransactionResultByIndex gets the result of a transaction at a specified 59 | // block and index 60 | rpc GetTransactionResultByIndex(GetTransactionByIndexRequest) 61 | returns (TransactionResultResponse); 62 | // GetTransactionResultsByBlockID gets all the transaction results for a 63 | // specified block 64 | rpc GetTransactionResultsByBlockID(GetTransactionsByBlockIDRequest) 65 | returns (TransactionResultsResponse); 66 | // GetTransactionsByBlockID gets all the transactions for a specified block 67 | rpc GetTransactionsByBlockID(GetTransactionsByBlockIDRequest) 68 | returns (TransactionsResponse); 69 | 70 | // Accounts 71 | 72 | // GetAccount is an alias for GetAccountAtLatestBlock. 73 | // 74 | // Warning: this function is deprecated. It behaves identically to 75 | // GetAccountAtLatestBlock and will be removed in a future version. 76 | rpc GetAccount(GetAccountRequest) returns (GetAccountResponse); 77 | // GetAccountAtLatestBlock gets an account by address from the latest sealed 78 | // execution state. 79 | rpc GetAccountAtLatestBlock(GetAccountAtLatestBlockRequest) 80 | returns (AccountResponse); 81 | // GetAccountAtBlockHeight gets an account by address at the given block 82 | // height 83 | rpc GetAccountAtBlockHeight(GetAccountAtBlockHeightRequest) 84 | returns (AccountResponse); 85 | 86 | // Scripts 87 | 88 | // ExecuteScriptAtLatestBlock executes a read-only Cadence script against the 89 | // latest sealed execution state. 90 | rpc ExecuteScriptAtLatestBlock(ExecuteScriptAtLatestBlockRequest) 91 | returns (ExecuteScriptResponse); 92 | // ExecuteScriptAtBlockID executes a ready-only Cadence script against the 93 | // execution state at the block with the given ID. 94 | rpc ExecuteScriptAtBlockID(ExecuteScriptAtBlockIDRequest) 95 | returns (ExecuteScriptResponse); 96 | // ExecuteScriptAtBlockHeight executes a ready-only Cadence script against the 97 | // execution state at the given block height. 98 | rpc ExecuteScriptAtBlockHeight(ExecuteScriptAtBlockHeightRequest) 99 | returns (ExecuteScriptResponse); 100 | 101 | // Events 102 | 103 | // GetEventsForHeightRange retrieves events emitted within the specified block 104 | // range. 105 | rpc GetEventsForHeightRange(GetEventsForHeightRangeRequest) 106 | returns (EventsResponse); 107 | 108 | // GetEventsForBlockIDs retrieves events for the specified block IDs and event 109 | // type. 110 | rpc GetEventsForBlockIDs(GetEventsForBlockIDsRequest) 111 | returns (EventsResponse); 112 | 113 | // NetworkParameters 114 | 115 | // GetNetworkParameters retrieves the Flow network details 116 | rpc GetNetworkParameters(GetNetworkParametersRequest) 117 | returns (GetNetworkParametersResponse); 118 | 119 | // ProtocolState 120 | 121 | // GetLatestProtocolStateSnapshot retrieves the latest sealed protocol state 122 | // snapshot. Used by Flow nodes joining the network to bootstrap a 123 | // space-efficient local state. 124 | rpc GetLatestProtocolStateSnapshot(GetLatestProtocolStateSnapshotRequest) 125 | returns (ProtocolStateSnapshotResponse); 126 | 127 | // GetExecutionResultForBlockID returns Execution Result for a given block. 128 | // At present, Access Node might not have execution results for every block 129 | // and as usual, until sealed, this data can change 130 | rpc GetExecutionResultForBlockID(GetExecutionResultForBlockIDRequest) 131 | returns (ExecutionResultForBlockIDResponse); 132 | } 133 | 134 | message PingRequest {} 135 | 136 | message PingResponse {} 137 | 138 | // Block Headers 139 | 140 | message GetLatestBlockHeaderRequest { 141 | bool is_sealed = 1; 142 | } 143 | 144 | message GetBlockHeaderByIDRequest { 145 | bytes id = 1; 146 | } 147 | 148 | message GetBlockHeaderByHeightRequest { 149 | uint64 height = 1; 150 | } 151 | 152 | message BlockHeaderResponse { 153 | entities.BlockHeader block = 1; 154 | } 155 | 156 | // Blocks 157 | 158 | message GetLatestBlockRequest { 159 | bool is_sealed = 1; 160 | bool full_block_response = 2; 161 | } 162 | 163 | message GetBlockByIDRequest { 164 | bytes id = 1; 165 | bool full_block_response = 2; 166 | } 167 | 168 | message GetBlockByHeightRequest { 169 | uint64 height = 1; 170 | bool full_block_response = 2; 171 | } 172 | 173 | message BlockResponse { 174 | entities.Block block = 1; 175 | } 176 | 177 | // Collections 178 | 179 | message GetCollectionByIDRequest { 180 | bytes id = 1; 181 | } 182 | 183 | message CollectionResponse { 184 | entities.Collection collection = 1; 185 | } 186 | 187 | // Transactions 188 | 189 | message SendTransactionRequest { 190 | entities.Transaction transaction = 1; 191 | } 192 | 193 | message SendTransactionResponse { 194 | bytes id = 1; 195 | } 196 | 197 | message GetTransactionRequest { 198 | bytes id = 1; 199 | } 200 | 201 | message GetTransactionByIndexRequest { 202 | bytes block_id = 1; 203 | uint32 index = 2; 204 | } 205 | 206 | message GetTransactionsByBlockIDRequest { 207 | bytes block_id = 1; 208 | } 209 | 210 | message TransactionResultsResponse { 211 | repeated TransactionResultResponse transaction_results = 1; 212 | } 213 | 214 | message TransactionsResponse { 215 | repeated entities.Transaction transactions = 1; 216 | } 217 | 218 | message TransactionResponse { 219 | entities.Transaction transaction = 1; 220 | } 221 | 222 | message TransactionResultResponse { 223 | entities.TransactionStatus status = 1; 224 | uint32 status_code = 2; 225 | string error_message = 3; 226 | repeated entities.Event events = 4; 227 | bytes block_id = 5; 228 | bytes transaction_id = 6; 229 | bytes collection_id = 7; 230 | } 231 | 232 | // Accounts 233 | 234 | message GetAccountRequest { 235 | bytes address = 1; 236 | } 237 | 238 | message GetAccountResponse { 239 | entities.Account account = 1; 240 | } 241 | 242 | message GetAccountAtLatestBlockRequest { 243 | bytes address = 1; 244 | } 245 | 246 | message AccountResponse { 247 | entities.Account account = 1; 248 | } 249 | 250 | message GetAccountAtBlockHeightRequest { 251 | bytes address = 1; 252 | uint64 block_height = 2; 253 | } 254 | 255 | // Scripts 256 | 257 | message ExecuteScriptAtLatestBlockRequest { 258 | bytes script = 1; 259 | repeated bytes arguments = 2; 260 | } 261 | 262 | message ExecuteScriptAtBlockIDRequest { 263 | bytes block_id = 1; 264 | bytes script = 2; 265 | repeated bytes arguments = 3; 266 | } 267 | 268 | message ExecuteScriptAtBlockHeightRequest { 269 | uint64 block_height = 1; 270 | bytes script = 2; 271 | repeated bytes arguments = 3; 272 | } 273 | 274 | message ExecuteScriptResponse { 275 | bytes value = 1; 276 | } 277 | 278 | // Events 279 | 280 | message GetEventsForHeightRangeRequest { 281 | string type = 1; 282 | uint64 start_height = 2; 283 | uint64 end_height = 3; 284 | } 285 | 286 | message GetEventsForBlockIDsRequest { 287 | string type = 1; 288 | repeated bytes block_ids = 2; 289 | } 290 | 291 | message EventsResponse { 292 | message Result { 293 | bytes block_id = 1; 294 | uint64 block_height = 2; 295 | repeated entities.Event events = 3; 296 | google.protobuf.Timestamp block_timestamp = 4; 297 | } 298 | repeated Result results = 1; 299 | } 300 | 301 | // Network Parameters 302 | 303 | message GetNetworkParametersRequest {} 304 | 305 | message GetNetworkParametersResponse { 306 | string chain_id = 1; 307 | } 308 | 309 | // Protocol State 310 | 311 | message GetLatestProtocolStateSnapshotRequest {} 312 | 313 | message ProtocolStateSnapshotResponse { 314 | bytes serializedSnapshot = 1; 315 | } 316 | 317 | // Execution Results 318 | 319 | message GetExecutionResultForBlockIDRequest { 320 | bytes block_id = 1; 321 | } 322 | 323 | message ExecutionResultForBlockIDResponse { 324 | entities.ExecutionResult execution_result = 1; 325 | } 326 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/account.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | message Account { 9 | bytes address = 1; 10 | uint64 balance = 2; 11 | bytes code = 3; 12 | repeated AccountKey keys = 4; 13 | map contracts = 5; 14 | } 15 | 16 | message AccountKey { 17 | uint32 index = 1; 18 | bytes public_key = 2; 19 | uint32 sign_algo = 3; 20 | uint32 hash_algo = 4; 21 | uint32 weight = 5; 22 | uint32 sequence_number = 6; 23 | bool revoked = 7; 24 | } 25 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/block.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | import "google/protobuf/timestamp.proto"; 9 | 10 | import "flow/entities/collection.proto"; 11 | import "flow/entities/block_seal.proto"; 12 | import "flow/entities/execution_result.proto"; 13 | import "flow/entities/block_header.proto"; 14 | 15 | message Block { 16 | bytes id = 1; 17 | bytes parent_id = 2; 18 | uint64 height = 3; 19 | google.protobuf.Timestamp timestamp = 4; 20 | repeated CollectionGuarantee collection_guarantees = 5; 21 | repeated BlockSeal block_seals = 6; 22 | repeated bytes signatures = 7; 23 | repeated ExecutionReceiptMeta execution_receipt_metaList = 8; 24 | repeated ExecutionResult execution_result_list = 9; 25 | BlockHeader block_header = 10; 26 | } 27 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/block_header.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | import "google/protobuf/timestamp.proto"; 9 | 10 | message BlockHeader { 11 | bytes id = 1; 12 | bytes parent_id = 2; 13 | uint64 height = 3; 14 | google.protobuf.Timestamp timestamp = 4; 15 | bytes payload_hash = 5; 16 | uint64 view = 6; 17 | repeated bytes parent_voter_ids = 7; // deprecated!! value will be empty. replaced by parent_vote_indices 18 | bytes parent_voter_sig_data = 8; 19 | bytes proposer_id = 9; 20 | bytes proposer_sig_data = 10; 21 | string chain_id = 11; 22 | bytes parent_voter_indices = 12; 23 | } 24 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/block_seal.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | message BlockSeal { 9 | bytes block_id = 1; 10 | bytes execution_receipt_id = 2; 11 | repeated bytes execution_receipt_signatures = 3; 12 | repeated bytes result_approval_signatures = 4; 13 | bytes final_state = 5; 14 | bytes result_id = 6; 15 | repeated AggregatedSignature aggregated_approval_sigs = 7; 16 | } 17 | 18 | message AggregatedSignature { 19 | repeated bytes verifier_signatures = 1; 20 | repeated bytes signer_ids = 2; 21 | } -------------------------------------------------------------------------------- /Protobuf/flow/entities/collection.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | message Collection { 9 | bytes id = 1; 10 | repeated bytes transaction_ids = 2; 11 | } 12 | 13 | message CollectionGuarantee { 14 | bytes collection_id = 1; 15 | repeated bytes signatures = 2; 16 | bytes reference_block_id = 3; 17 | bytes signature = 4; 18 | repeated bytes signer_ids = 5; // deprecated!! value will be empty. replaced by signer_indices 19 | bytes signer_indices = 6; 20 | } 21 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/event.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | message Event { 9 | string type = 1; 10 | bytes transaction_id = 2; 11 | uint32 transaction_index = 3; 12 | uint32 event_index = 4; 13 | bytes payload = 5; 14 | } 15 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/execution_result.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | message ExecutionResult { 9 | bytes previous_result_id = 1; 10 | bytes block_id = 2; 11 | repeated Chunk chunks = 3; 12 | repeated ServiceEvent service_events = 4; 13 | bytes execution_data_id = 5 [deprecated = true]; 14 | } 15 | 16 | message Chunk { 17 | uint32 CollectionIndex = 1; 18 | bytes start_state = 2; // state when starting executing this chunk 19 | bytes event_collection = 3; // Events generated by executing results 20 | bytes block_id = 4; // Block id of the execution result this chunk belongs to 21 | uint64 total_computation_used = 22 | 5; // total amount of computation used by running all txs in this chunk 23 | uint32 number_of_transactions = 24 | 6; // number of transactions inside the collection 25 | uint64 index = 7; // chunk index inside the ER (starts from zero) 26 | bytes end_state = 8; // EndState inferred from next chunk or from the ER 27 | bytes execution_data_id = 9; 28 | } 29 | 30 | message ServiceEvent { 31 | string type = 1; 32 | bytes payload = 2; 33 | } 34 | 35 | message ExecutionReceiptMeta { 36 | bytes executor_id = 1; 37 | bytes result_id = 2; 38 | repeated bytes spocks = 3; 39 | bytes executor_signature = 4; 40 | } 41 | -------------------------------------------------------------------------------- /Protobuf/flow/entities/transaction.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.entities; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/entities"; 6 | option java_package = "org.onflow.protobuf.entities"; 7 | 8 | import "flow/entities/event.proto"; 9 | 10 | enum TransactionStatus { 11 | UNKNOWN = 0; 12 | PENDING = 1; 13 | FINALIZED = 2; 14 | EXECUTED = 3; 15 | SEALED = 4; 16 | EXPIRED = 5; 17 | } 18 | 19 | message Transaction { 20 | message ProposalKey { 21 | bytes address = 1; 22 | uint32 key_id = 2; 23 | uint64 sequence_number = 3; 24 | } 25 | 26 | message Signature { 27 | bytes address = 1; 28 | uint32 key_id = 2; 29 | bytes signature = 3; 30 | } 31 | 32 | bytes script = 1; 33 | repeated bytes arguments = 2; 34 | bytes reference_block_id = 3; 35 | uint64 gas_limit = 4; 36 | ProposalKey proposal_key = 5; 37 | bytes payer = 6; 38 | repeated bytes authorizers = 7; 39 | repeated Signature payload_signatures = 8; 40 | repeated Signature envelope_signatures = 9; 41 | } 42 | -------------------------------------------------------------------------------- /Protobuf/flow/execution/execution.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package flow.execution; 4 | 5 | option go_package = "github.com/onflow/flow/protobuf/go/flow/execution"; 6 | option java_package = "org.onflow.protobuf.execution"; 7 | 8 | import "flow/entities/account.proto"; 9 | import "flow/entities/block_header.proto"; 10 | import "flow/entities/event.proto"; 11 | import "flow/entities/transaction.proto"; 12 | 13 | // ExecutionAPI is the API provided by the execution nodes. 14 | service ExecutionAPI { 15 | // Ping is used to check if the access node is alive and healthy. 16 | rpc Ping(PingRequest) returns (PingResponse); 17 | 18 | // Accounts 19 | 20 | // GetAccountAtBlockID gets an account by address at the given block ID 21 | rpc GetAccountAtBlockID(GetAccountAtBlockIDRequest) 22 | returns (GetAccountAtBlockIDResponse); 23 | 24 | // Scripts 25 | 26 | // ExecuteScriptAtBlockID executes a ready-only Cadence script against the 27 | // execution state at the block with the given ID. 28 | rpc ExecuteScriptAtBlockID(ExecuteScriptAtBlockIDRequest) 29 | returns (ExecuteScriptAtBlockIDResponse); 30 | 31 | // Events 32 | 33 | // GetEventsForBlockIDs retrieves events for all the specified block IDs that 34 | // have the given type 35 | rpc GetEventsForBlockIDs(GetEventsForBlockIDsRequest) 36 | returns (GetEventsForBlockIDsResponse); 37 | 38 | // Transaction 39 | 40 | // GetTransactionResult gets the result of a transaction. 41 | rpc GetTransactionResult(GetTransactionResultRequest) 42 | returns (GetTransactionResultResponse); 43 | 44 | // GetTransactionResultByIndex gets the result of a transaction at the index . 45 | rpc GetTransactionResultByIndex(GetTransactionByIndexRequest) 46 | returns (GetTransactionResultResponse); 47 | 48 | // GetTransactionResultByIndex gets the results of all transactions in the 49 | // block ordered by transaction index 50 | rpc GetTransactionResultsByBlockID(GetTransactionsByBlockIDRequest) 51 | returns (GetTransactionResultsResponse); 52 | 53 | // Registers 54 | 55 | // GetRegisterAtBlockID collects a register at the block with the given ID (if 56 | // available). 57 | rpc GetRegisterAtBlockID(GetRegisterAtBlockIDRequest) 58 | returns (GetRegisterAtBlockIDResponse); 59 | 60 | // Block headers 61 | 62 | // GetLatestBlockHeader gets the latest sealed or unsealed block header. 63 | rpc GetLatestBlockHeader(GetLatestBlockHeaderRequest) 64 | returns (BlockHeaderResponse); 65 | // GetBlockHeaderByID gets a block header by ID. 66 | rpc GetBlockHeaderByID(GetBlockHeaderByIDRequest) 67 | returns (BlockHeaderResponse); 68 | } 69 | 70 | // Ping 71 | 72 | message PingRequest {} 73 | 74 | message PingResponse {} 75 | 76 | // Accounts 77 | 78 | message GetAccountAtBlockIDRequest { 79 | bytes block_id = 1; 80 | bytes address = 2; 81 | } 82 | 83 | message GetAccountAtBlockIDResponse { 84 | entities.Account account = 1; 85 | } 86 | 87 | // Scripts 88 | 89 | message ExecuteScriptAtBlockIDRequest { 90 | bytes block_id = 1; 91 | bytes script = 2; 92 | repeated bytes arguments = 3; 93 | } 94 | 95 | message ExecuteScriptAtBlockIDResponse { 96 | bytes value = 1; 97 | } 98 | 99 | // Events 100 | 101 | message GetEventsForBlockIDsResponse { 102 | message Result { 103 | bytes block_id = 1; 104 | uint64 block_height = 2; 105 | repeated entities.Event events = 3; 106 | } 107 | repeated Result results = 1; 108 | } 109 | 110 | message GetEventsForBlockIDsRequest { 111 | string type = 1; 112 | repeated bytes block_ids = 2; 113 | } 114 | 115 | // Transactions 116 | 117 | message GetTransactionResultRequest { 118 | bytes block_id = 1; 119 | bytes transaction_id = 2; 120 | } 121 | 122 | message GetTransactionByIndexRequest { 123 | bytes block_id = 1; 124 | uint32 index = 2; 125 | } 126 | 127 | message GetTransactionResultResponse { 128 | uint32 status_code = 1; 129 | string error_message = 2; 130 | repeated entities.Event events = 3; 131 | } 132 | 133 | message GetTransactionsByBlockIDRequest { 134 | bytes block_id = 1; 135 | } 136 | 137 | message GetTransactionResultsResponse { 138 | repeated GetTransactionResultResponse transaction_results = 1; 139 | } 140 | 141 | // Registers 142 | 143 | message GetRegisterAtBlockIDRequest { 144 | bytes block_id = 1; 145 | bytes register_owner = 2; 146 | bytes register_controller = 3; 147 | bytes register_key = 4; 148 | } 149 | 150 | message GetRegisterAtBlockIDResponse { 151 | bytes value = 1; 152 | } 153 | 154 | // Block Headers 155 | 156 | message GetLatestBlockHeaderRequest { 157 | bool is_sealed = 1; 158 | } 159 | 160 | message GetBlockHeaderByIDRequest { 161 | bytes id = 1; 162 | } 163 | 164 | message BlockHeaderResponse { 165 | entities.BlockHeader block = 1; 166 | } 167 | -------------------------------------------------------------------------------- /Sources/Cadence/Address.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Address.swift 3 | // 4 | // Created by Scott on 2022/5/18. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// [n,k,d]-Linear code parameters 11 | /// The linear code used in the account addressing is a [64,45,7] 12 | /// It generates a [64,45]-code, which is the space of Flow account addresses. 13 | /// 14 | /// n is the size of the code words in bits, 15 | /// which is also the size of the account addresses in bits. 16 | private let linearCodeN = 64 17 | 18 | public struct Address: Equatable, Hashable { 19 | 20 | /// the size of an account address in bytes. 21 | public static let length = (linearCodeN + 7) >> 3 22 | 23 | public static let emptyAddress = Address(data: Data()) 24 | 25 | public let data: Data 26 | 27 | public var bytes: [UInt8] { 28 | data.bytes 29 | } 30 | 31 | public var hexString: String { 32 | data.toHexString() 33 | } 34 | 35 | public var hexStringWithPrefix: String { 36 | var result = "0x" 37 | if data.count < Self.length { 38 | let zeroPadding = Data(repeating: 0, count: Self.length - data.count) 39 | result += zeroPadding.toHexString() 40 | } 41 | result += data.toHexString() 42 | return result 43 | } 44 | 45 | /// If b is larger than 8, b will be cropped from the left. 46 | /// If b is smaller than 8, b will be appended by zeroes at the front. 47 | public init(data: Data) { 48 | self.data = data.normalized 49 | } 50 | 51 | public init(hexString: String) { 52 | self.init(data: Data(hex: hexString.fixedHexString)) 53 | } 54 | } 55 | 56 | // MARK: - Codable 57 | extension Address: Codable { 58 | 59 | public func encode(to encoder: Encoder) throws { 60 | var container = encoder.singleValueContainer() 61 | try container.encode(description) 62 | } 63 | 64 | public init(from decoder: Decoder) throws { 65 | let container = try decoder.singleValueContainer() 66 | data = try container.decodeHexString().normalized 67 | } 68 | } 69 | 70 | // MARK: - CustomStringConvertible 71 | 72 | extension Address: CustomStringConvertible { 73 | 74 | public var description: String { 75 | "0x" + hexString 76 | } 77 | } 78 | 79 | // MARK: - Data 80 | 81 | private extension Data { 82 | 83 | var normalized: Data { 84 | switch count { 85 | case 0.. Bool { 57 | lhs.type == rhs.type && 58 | lhs.typeId == rhs.typeId 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/EnumType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnumType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public class EnumType: Codable { 11 | 12 | public var type: FType 13 | public let typeId: String 14 | public var initializers: [InitializerType] 15 | public var fields: [FieldType] 16 | 17 | public init( 18 | type: FType, 19 | typeId: String, 20 | initializers: [InitializerType] = [], 21 | fields: [FieldType] 22 | ) { 23 | self.type = type 24 | self.typeId = typeId 25 | self.initializers = initializers 26 | self.fields = fields 27 | } 28 | 29 | // MARK: Codable 30 | 31 | enum CodingKeys: String, CodingKey { 32 | case type 33 | case typeId = "typeID" 34 | case initializers 35 | case fields 36 | } 37 | 38 | required public init(from decoder: Decoder) throws { 39 | let container = try decoder.container(keyedBy: CodingKeys.self) 40 | self.type = .bool // must call decodePossibleRepeatedProperties later 41 | self.typeId = try container.decode(String.self, forKey: .typeId) 42 | self.initializers = [] // must call decodePossibleRepeatedProperties later 43 | self.fields = [] // must call decodePossibleRepeatedProperties later 44 | } 45 | 46 | public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { 47 | let container = try decoder.container(keyedBy: CodingKeys.self) 48 | type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) 49 | initializers = try container.decode([InitializerType].self, forKey: .initializers) 50 | fields = try container.decode([FieldType].self, forKey: .fields) 51 | } 52 | } 53 | 54 | // MARK: - Equatable 55 | 56 | extension EnumType: Equatable { 57 | 58 | public static func == (lhs: EnumType, rhs: EnumType) -> Bool { 59 | lhs.type == rhs.type && 60 | lhs.typeId == rhs.typeId 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/FieldType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FieldType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct FieldType: Equatable, Codable { 11 | public let id: String 12 | public let type: FType 13 | 14 | public init(id: String, type: FType) { 15 | self.id = id 16 | self.type = type 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/FunctionType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FunctionType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public class FunctionType: Codable { 11 | public let typeId: String 12 | public var parameters: [ParameterType] 13 | public var `return`: FType 14 | 15 | public init( 16 | typeId: String, 17 | parameters: [ParameterType] = [], 18 | return: FType = .void 19 | ) { 20 | self.typeId = typeId 21 | self.parameters = parameters 22 | self.return = `return` 23 | } 24 | 25 | // MARK: Codable 26 | 27 | enum CodingKeys: String, CodingKey { 28 | case typeId = "typeID" 29 | case parameters 30 | case `return` 31 | } 32 | 33 | required public init(from decoder: Decoder) throws { 34 | let container = try decoder.container(keyedBy: CodingKeys.self) 35 | self.typeId = try container.decode(String.self, forKey: .typeId) 36 | self.parameters = [] // must call decodePossibleRepeatedProperties later 37 | self.return = .bool // must call decodePossibleRepeatedProperties later 38 | } 39 | 40 | public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { 41 | let container = try decoder.container(keyedBy: CodingKeys.self) 42 | parameters = try container.decode([ParameterType].self, forKey: .parameters) 43 | `return` = try container.decodeFType(userInfo: decoder.userInfo, forKey: .return) 44 | } 45 | } 46 | 47 | // MARK: - Equatable 48 | 49 | extension FunctionType: Equatable { 50 | 51 | public static func == (lhs: FunctionType, rhs: FunctionType) -> Bool { 52 | lhs.typeId == rhs.typeId && 53 | lhs.parameters == rhs.parameters && 54 | lhs.return == rhs.return 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/InitializerType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InitializerType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public typealias InitializerType = [ParameterType] 11 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/IntersectionType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Shane Chi on 2024/9/30. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct IntersectionType: Equatable, Codable { 11 | public let typeId: String 12 | public let types: [FType] 13 | 14 | public init(typeId: String, types: [FType]) { 15 | self.typeId = typeId 16 | self.types = types 17 | } 18 | 19 | // MARK: Codable 20 | enum CodingKeys: String, CodingKey { 21 | case typeId = "typeID" 22 | case types 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/ParameterType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ParameterType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct ParameterType: Equatable, Codable { 11 | public let label: String 12 | public let id: String 13 | public let type: FType 14 | 15 | public init( 16 | label: String, 17 | id: String, 18 | type: FType 19 | ) { 20 | self.label = label 21 | self.id = id 22 | self.type = type 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/ReferenceType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReferenceType.swift 3 | // 4 | // Created by Scott on 2022/6/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct ReferenceType: Equatable, Codable { 11 | public let authorization: Authorization 12 | public let type: FType 13 | 14 | public init(authorization: Authorization, type: FType) { 15 | self.authorization = authorization 16 | self.type = type 17 | } 18 | } 19 | 20 | public extension ReferenceType { 21 | struct Authorization: Codable, Equatable { 22 | public let kind: AuthorizationKind 23 | 24 | public init(kind: AuthorizationKind) { 25 | self.kind = kind 26 | } 27 | } 28 | 29 | enum AuthorizationKind: String, Codable { 30 | case unauthorized = "Unauthorized" 31 | case entitlementMapAuthorization = "EntitlementMapAuthorization" 32 | case entitlementConjunctionSet = "EntitlementConjunctionSet" 33 | case entitlementDisjunctionSet = "EntitlementDisjunctionSet" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/Cadence/CType/RestrictionType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RestrictionType.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public class RestrictionType: Codable { 11 | public let typeId: String 12 | public var type: FType 13 | public var restrictions: [FType] 14 | 15 | public init( 16 | typeId: String, 17 | type: FType, 18 | restrictions: [FType] 19 | ) { 20 | self.typeId = typeId 21 | self.type = type 22 | self.restrictions = restrictions 23 | } 24 | 25 | // MARK: Codable 26 | 27 | enum CodingKeys: String, CodingKey { 28 | case typeId = "typeID" 29 | case type 30 | case restrictions 31 | } 32 | 33 | required public init(from decoder: Decoder) throws { 34 | let container = try decoder.container(keyedBy: CodingKeys.self) 35 | self.typeId = try container.decode(String.self, forKey: .typeId) 36 | self.type = .bool // must call decodePossibleRepeatedProperties later 37 | self.restrictions = [] // must call decodePossibleRepeatedProperties later 38 | } 39 | 40 | public func decodePossibleRepeatedProperties(from decoder: Decoder) throws { 41 | let container = try decoder.container(keyedBy: CodingKeys.self) 42 | type = try container.decodeFType(userInfo: decoder.userInfo, forKey: .type) 43 | restrictions = try container.decode([FType].self, forKey: .restrictions) 44 | } 45 | } 46 | 47 | // MARK: - Equatable 48 | 49 | extension RestrictionType: Equatable { 50 | 51 | public static func == (lhs: RestrictionType, rhs: RestrictionType) -> Bool { 52 | lhs.typeId == rhs.typeId && 53 | lhs.type == rhs.type 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/Cadence/Capability.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Capability.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://docs.onflow.org/cadence/json-cadence-spec/#capability 11 | public struct Capability: Codable, Equatable { 12 | 13 | public let id: String 14 | public let address: Address 15 | public let borrowType: FType 16 | 17 | public init( 18 | id: String, 19 | address: Address, 20 | borrowType: FType 21 | ) { 22 | self.id = id 23 | self.address = address 24 | self.borrowType = borrowType 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Cadence/Composite.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Composite.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://docs.onflow.org/cadence/json-cadence-spec/#composites-struct-resource-event-contract-enum 11 | public struct Composite: Codable, Equatable { 12 | 13 | public let id: String 14 | public let fields: [Field] 15 | 16 | public init(id: String, fields: [Field]) { 17 | self.id = id 18 | self.fields = fields 19 | } 20 | } 21 | 22 | public typealias CompositeStruct = Composite 23 | public typealias CompositeResource = Composite 24 | public typealias CompositeEvent = Composite 25 | public typealias CompositeContract = Composite 26 | public typealias CompositeEnum = Composite 27 | 28 | // MARK: - Field 29 | extension Composite { 30 | 31 | public struct Field: Codable, Equatable { 32 | public let name: String 33 | public let value: Argument 34 | 35 | public init(name: String, value: Argument) { 36 | self.name = name 37 | self.value = value 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/Cadence/Dictionary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dictionary.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://docs.onflow.org/cadence/json-cadence-spec/#dictionary 11 | public struct Dictionary: Codable, Equatable { 12 | 13 | public let key: Argument 14 | public let value: Argument 15 | 16 | public init(key: Argument, value: Argument) { 17 | self.key = key 18 | self.value = value 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/Cadence/Extensions/CodingUserInfoKeyExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // Created by Scott on 2022/6/28. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | extension CodingUserInfoKey { 11 | static let decodingResults = CodingUserInfoKey(rawValue: "decodingResults")! 12 | } 13 | -------------------------------------------------------------------------------- /Sources/Cadence/Extensions/KeyedDecodingContainerProtocolExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyedDecodingContainerProtocolExtension.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BigInt 10 | 11 | // MARK: - BigInt, BigUInt 12 | 13 | extension KeyedDecodingContainerProtocol { 14 | 15 | func decodeBigIntFromString(forKey key: Self.Key) throws -> BigInt { 16 | let string = try decode(String.self, forKey: key) 17 | guard let bigInt = BigInt(string) else { 18 | throw DecodingError.dataCorruptedError( 19 | forKey: key, 20 | in: self, 21 | debugDescription: "Expected BigInt string") 22 | } 23 | return bigInt 24 | } 25 | 26 | func decodeBigUIntFromString(forKey key: Self.Key) throws -> BigUInt { 27 | let string = try decode(String.self, forKey: key) 28 | guard let bigUInt = BigUInt(string) else { 29 | throw DecodingError.dataCorruptedError( 30 | forKey: key, 31 | in: self, 32 | debugDescription: "Expected BigUInt string") 33 | } 34 | return bigUInt 35 | } 36 | 37 | } 38 | 39 | // MARK: - Decimal 40 | 41 | extension KeyedDecodingContainerProtocol { 42 | 43 | func decodeDecimalFromString(forKey key: Self.Key) throws -> Decimal { 44 | let string = try decode(String.self, forKey: key) 45 | guard let decimal = Decimal(string: string) else { 46 | throw DecodingError.dataCorruptedError( 47 | forKey: key, 48 | in: self, 49 | debugDescription: "Expected Decimal string") 50 | } 51 | return decimal 52 | } 53 | } 54 | 55 | // MARK: - String Integer 56 | 57 | extension KeyedDecodingContainerProtocol { 58 | 59 | func decodeStringInteger( 60 | _ type: IntegerType.Type, 61 | forKey key: Self.Key 62 | ) throws -> IntegerType { 63 | let text = try decode(String.self, forKey: key) 64 | guard let value = IntegerType(text) else { 65 | throw DecodingError.dataCorruptedError( 66 | forKey: key, 67 | in: self, 68 | debugDescription: "Expected \(IntegerType.self) string") 69 | } 70 | return value 71 | } 72 | } 73 | 74 | // MARK: FType 75 | 76 | extension KeyedDecodingContainerProtocol { 77 | 78 | func decodeFType( 79 | userInfo: [CodingUserInfoKey: Any], 80 | forKey key: Self.Key 81 | ) throws -> FType { 82 | if let typeId = try? decode(String.self, forKey: key) { 83 | if let results = userInfo[.decodingResults] as? FTypeDecodingResults, 84 | let type = results.value[typeId] { 85 | return type 86 | } else { 87 | throw DecodingError.dataCorruptedError( 88 | forKey: key, 89 | in: self, 90 | debugDescription: "TypeID(\(typeId)) Not found") 91 | } 92 | } else { 93 | let type = try decode(FType.self, forKey: key) 94 | return type 95 | } 96 | } 97 | 98 | } 99 | 100 | -------------------------------------------------------------------------------- /Sources/Cadence/Extensions/SingleValueDecodingContainerExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingleValueDecodingContainerExtension.swift 3 | // 4 | // Created by Scott on 2022/5/19. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import CryptoSwift 10 | 11 | extension SingleValueDecodingContainer { 12 | 13 | func decodeHexString() throws -> Data { 14 | let hexString = try decode(String.self) 15 | let data = Data(hex: hexString.fixedHexString) 16 | return data 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Sources/Cadence/Extensions/StringExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringExtension.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | extension String { 11 | 12 | var fixedHexString: String { 13 | if count % 2 == 1 { 14 | return "0" + self 15 | } else { 16 | return self 17 | } 18 | } 19 | 20 | var quoteString: String { 21 | var result = "" 22 | result += "\"" 23 | 24 | unicodeScalars.forEach { char in 25 | switch char { 26 | case "\0": 27 | result += #"\0"# 28 | case "\n": 29 | result += #"\n"# 30 | case "\r": 31 | result += #"\r"# 32 | case "\t": 33 | result += #"\t"# 34 | case "\\": 35 | result += #"\\"# 36 | case "\"": 37 | result += #"\""# 38 | default: 39 | if 0x20 <= char.value && char.value <= 0x7E { 40 | // ASCII printable from space through DEL-1. 41 | result += String(char) 42 | } else { 43 | let finalChar: Unicode.Scalar 44 | if char.value > 1114111 { 45 | finalChar = Unicode.Scalar(65533 as UInt32) ?? char 46 | } else { 47 | finalChar = char 48 | } 49 | result += finalChar.description 50 | } 51 | } 52 | } 53 | result += "\"" 54 | return result 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Sources/Cadence/FTypeDecodingResults.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FTypeDecodingResults.swift 3 | // 4 | // Created by Scott on 2022/6/28. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | class FTypeDecodingResults { 11 | public var value: [String: FType] = [:] 12 | } 13 | -------------------------------------------------------------------------------- /Sources/Cadence/FTypeKind.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FTypeKind.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum FTypeKind: String, Equatable, Codable { 11 | case `any` = "Any" 12 | case anyStruct = "AnyStruct" 13 | case anyResource = "AnyResource" 14 | case type = "Type" 15 | case void = "Void" 16 | case never = "Never" 17 | case bool = "Bool" 18 | case string = "String" 19 | case character = "Character" 20 | case bytes = "Bytes" 21 | case address = "Address" 22 | case number = "Number" 23 | case signedNumber = "SignedNumber" 24 | case integer = "Integer" 25 | case signedInteger = "SignedInteger" 26 | case fixedPoint = "FixedPoint" 27 | case signedFixedPoint = "SignedFixedPoint" 28 | case int = "Int" 29 | case int8 = "Int8" 30 | case int16 = "Int16" 31 | case int32 = "Int32" 32 | case int64 = "Int64" 33 | case int128 = "Int128" 34 | case int256 = "Int256" 35 | case uint = "UInt" 36 | case uint8 = "UInt8" 37 | case uint16 = "UInt16" 38 | case uint32 = "UInt32" 39 | case uint64 = "UInt64" 40 | case uint128 = "UInt128" 41 | case uint256 = "UInt256" 42 | case word8 = "Word8" 43 | case word16 = "Word16" 44 | case word32 = "Word32" 45 | case word64 = "Word64" 46 | case fix64 = "Fix64" 47 | case ufix64 = "UFix64" 48 | case path = "Path" 49 | case capabilityPath = "CapabilityPath" 50 | case storagePath = "StoragePath" 51 | case publicPath = "PublicPath" 52 | case privatePath = "PrivatePath" 53 | case authAccount = "AuthAccount" 54 | case publicAccount = "PublicAccount" 55 | case authAccountKeys = "AuthAccount.Keys" 56 | case publicAccountKeys = "PublicAccount.Keys" 57 | case authAccountContracts = "AuthAccount.Contracts" 58 | case publicAccountContracts = "PublicAccount.Contracts" 59 | case deployedContract = "DeployedContract" 60 | case accountKey = "AccountKey" 61 | case block = "Block" 62 | case `optional` = "Optional" 63 | case variableSizedArray = "VariableSizedArray" 64 | case constantSizedArray = "ConstantSizedArray" 65 | case dictionary = "Dictionary" 66 | case `struct` = "Struct" 67 | case resource = "Resource" 68 | case event = "Event" 69 | case contract = "Contract" 70 | case structInterface = "StructInterface" 71 | case resourceInterface = "ResourceInterface" 72 | case contractInterface = "ContractInterface" 73 | case function = "Function" 74 | case reference = "Reference" 75 | case restriction = "Restriction" 76 | case capability = "Capability" 77 | case `enum` = "Enum" 78 | case intersection = "Intersection" 79 | } 80 | -------------------------------------------------------------------------------- /Sources/Cadence/Format.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Format.swift 3 | // 4 | // Created by Scott on 2022/6/29. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BigInt 10 | 11 | enum Format { 12 | case void 13 | case `nil` 14 | case string(String) 15 | case address(Address) 16 | case bool(Bool) 17 | case bigInt(BigInt) 18 | case bigUInt(BigUInt) 19 | case int8(Int8) 20 | case uint8(UInt8) 21 | case int16(Int16) 22 | case uint16(UInt16) 23 | case int32(Int32) 24 | case uint32(UInt32) 25 | case int64(Int64) 26 | case uint64(UInt64) 27 | case int(Int) 28 | case uint(UInt) 29 | case decimal(Decimal) 30 | case array([String]) 31 | case dictionary([(key: String, value: String)]) 32 | case composite( 33 | typeId: String, 34 | fields: [(name: String, value: String)]) 35 | case path( 36 | domain: String, 37 | identifier: String) 38 | case type(FType) 39 | case capability( 40 | borrowType: FType, 41 | address: Address, 42 | id: String) 43 | } 44 | 45 | // MARK: - CustomStringConvertible 46 | 47 | extension Format: CustomStringConvertible { 48 | 49 | var description: String { 50 | switch self { 51 | case .void: 52 | return "()" 53 | case .nil: 54 | return "nil" 55 | case let .string(string): 56 | return string.quoteString 57 | case let .address(address): 58 | return address.description 59 | case let .bool(bool): 60 | return bool ? "true" : "false" 61 | case let .bigInt(bigInt): 62 | return bigInt.description 63 | case let .bigUInt(bigUInt): 64 | return bigUInt.description 65 | case let .int8(int8): 66 | return String(int8) 67 | case let .uint8(uint8): 68 | return String(uint8) 69 | case let .int16(int16): 70 | return String(int16) 71 | case let .uint16(uint16): 72 | return String(uint16) 73 | case let .int32(int32): 74 | return String(int32) 75 | case let .uint32(uint32): 76 | return String(uint32) 77 | case let .int64(int64): 78 | return String(int64) 79 | case let .uint64(uint64): 80 | return String(uint64) 81 | case let .int(int): 82 | return String(int) 83 | case let .uint(uint): 84 | return String(uint) 85 | case let .decimal(decimal): 86 | let elements = decimal.description.split(separator: ".") 87 | switch elements.count { 88 | case 1: 89 | return "\(elements[0]).00000000" 90 | case 2: 91 | let paddingZero = String(repeating: "0", count: 8 - elements[1].count) 92 | return "\(elements[0]).\(elements[1])\(paddingZero)" 93 | default: 94 | return decimal.description 95 | } 96 | case let .array(array): 97 | var result = "[" 98 | for (index, string) in array.enumerated() { 99 | if index > 0 { 100 | result += ", " 101 | } 102 | result += string 103 | } 104 | result += "]" 105 | return result 106 | case let .dictionary(pairs): 107 | var result = "{" 108 | for (index, pair) in pairs.enumerated() { 109 | if index > 0 { 110 | result += ", " 111 | } 112 | result += "\(pair.key): \(pair.value)" 113 | } 114 | result += "}" 115 | return result 116 | case let .composite(typeId, fields): 117 | var result = "\(typeId)(" 118 | for (index, pair) in fields.enumerated() { 119 | if index > 0 { 120 | result += ", " 121 | } 122 | result += "\(pair.name): \(pair.value)" 123 | } 124 | result += ")" 125 | return result 126 | case let .path(domain, identifier): 127 | return "/\(domain)/\(identifier)" 128 | case let .type(type): 129 | if type.id == "" { 130 | return "Type()" 131 | } else { 132 | return "Type<\(type.id)>()" 133 | } 134 | case let .capability(borrowType, address, id): 135 | let typeArgument = borrowType.id.isEmpty ? "" : "<\(borrowType.id)>" 136 | return "Capability\(typeArgument)(address: \(address.hexStringWithPrefix), id: \(id))" 137 | } 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /Sources/Cadence/Path.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Path.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://docs.onflow.org/cadence/json-cadence-spec/#path 11 | public struct Path: Codable, Equatable { 12 | 13 | public let domain: Domain 14 | public let identifier: String 15 | 16 | public init(domain: Domain, identifier: String) { 17 | self.domain = domain 18 | self.identifier = identifier 19 | } 20 | } 21 | 22 | // MARK: - Domain 23 | 24 | extension Path { 25 | 26 | public enum Domain: String, Codable { 27 | case storage 28 | case `private` 29 | case `public` 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/Cadence/StaticTypeValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaticTypeValue.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// https://docs.onflow.org/cadence/json-cadence-spec/#type-value 11 | public struct StaticTypeValue: Codable, Equatable { 12 | public let staticType: FType 13 | 14 | public init(staticType: FType) { 15 | self.staticType = staticType 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sources/Cadence/ValueType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ValueType.swift 3 | // 4 | // Created by Scott on 2022/5/18. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum ValueType: String, Equatable, Codable { 11 | case void = "Void" 12 | case optional = "Optional" 13 | case bool = "Bool" 14 | case string = "String" 15 | case address = "Address" 16 | case int = "Int" 17 | case uint = "UInt" 18 | case int8 = "Int8" 19 | case uint8 = "UInt8" 20 | case int16 = "Int16" 21 | case uint16 = "UInt16" 22 | case int32 = "Int32" 23 | case uint32 = "UInt32" 24 | case int64 = "Int64" 25 | case uint64 = "UInt64" 26 | case int128 = "Int128" 27 | case uint128 = "UInt128" 28 | case int256 = "Int256" 29 | case uint256 = "UInt256" 30 | case word8 = "Word8" 31 | case word16 = "Word16" 32 | case word32 = "Word32" 33 | case word64 = "Word64" 34 | case fix64 = "Fix64" 35 | case ufix64 = "UFix64" 36 | case array = "Array" 37 | case dictionary = "Dictionary" 38 | case `struct` = "Struct" 39 | case resource = "Resource" 40 | case event = "Event" 41 | case contract = "Contract" 42 | case `enum` = "Enum" 43 | case path = "Path" 44 | case type = "Type" 45 | case capability = "Capability" 46 | } 47 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/HashAlgorithm.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashAlgorithm.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum HashAlgorithm: UInt32, RawRepresentable { 11 | /// SHA2_256 is SHA-2 with a 256-bit digest (also referred to as SHA256). 12 | case sha2_256 = 1 13 | 14 | /// SHA3_256 is SHA-3 with a 256-bit digest. 15 | case sha3_256 = 3 16 | } 17 | 18 | extension HashAlgorithm { 19 | 20 | func getDigest(message: Data) -> SHA256Digest { 21 | let digest: SHA256Digest 22 | switch self { 23 | case .sha2_256: 24 | digest = SHA256Digest(data: message.sha256())! 25 | case .sha3_256: 26 | digest = SHA256Digest(data: message.sha3(.sha256))! 27 | } 28 | return digest 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/InMemorySigner.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InMemorySigner.swift 3 | // 4 | // Created by Scott on 2022/6/6. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct InMemorySigner: Signer { 11 | 12 | public let privateKey: PrivateKey 13 | 14 | public let hashAlgorithm: HashAlgorithm 15 | 16 | public init(privateKey: PrivateKey, hashAlgorithm: HashAlgorithm) { 17 | self.privateKey = privateKey 18 | self.hashAlgorithm = hashAlgorithm 19 | } 20 | 21 | public var publicKey: PublicKey { 22 | privateKey.publicKey 23 | } 24 | 25 | public func sign(message: Data) throws -> Data { 26 | try privateKey.sign(message: message, hashAlgorithm: hashAlgorithm) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/PrivateKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrivateKey.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import CryptoKit 10 | import CryptoSwift 11 | import secp256k1Swift 12 | 13 | public struct PrivateKey { 14 | 15 | public let data: Data 16 | 17 | public let algorithm: SignatureAlgorithm 18 | 19 | public let publicKey: PublicKey 20 | 21 | private let implementation: Implementation 22 | 23 | public var size: Int { 24 | data.count 25 | } 26 | 27 | public var hexString: String { 28 | data.toHexString() 29 | } 30 | 31 | public init(signatureAlgorithm: SignatureAlgorithm) throws { 32 | self.algorithm = signatureAlgorithm 33 | 34 | switch signatureAlgorithm { 35 | case .ecdsaP256: 36 | let key = P256.Signing.PrivateKey(compactRepresentable: false) 37 | self.data = key.rawRepresentation 38 | self.publicKey = try PublicKey(data: key.publicKey.rawRepresentation, signatureAlgorithm: .ecdsaP256) 39 | self.implementation = .ecdsaP256(key) 40 | case .ecdsaSecp256k1: 41 | let key = try secp256k1.Signing.PrivateKey(format: .uncompressed) 42 | self.data = key.rawRepresentation 43 | let rawPublicKey = key.publicKey.rawRepresentation 44 | self.publicKey = try PublicKey(data: rawPublicKey.dropFirst(), signatureAlgorithm: .ecdsaSecp256k1) 45 | self.implementation = .ecdsaSecp256k1(key) 46 | } 47 | } 48 | 49 | public init(data: Data, signatureAlgorithm: SignatureAlgorithm) throws { 50 | self.data = data 51 | self.algorithm = signatureAlgorithm 52 | 53 | switch signatureAlgorithm { 54 | case .ecdsaP256: 55 | let key = try P256.Signing.PrivateKey(rawRepresentation: data) 56 | self.publicKey = try PublicKey(data: key.publicKey.rawRepresentation, signatureAlgorithm: .ecdsaP256) 57 | self.implementation = .ecdsaP256(key) 58 | case .ecdsaSecp256k1: 59 | let key = try secp256k1.Signing.PrivateKey(rawRepresentation: data, format: .uncompressed) 60 | let rawPublicKey = key.publicKey.rawRepresentation 61 | self.publicKey = try PublicKey(data: rawPublicKey.dropFirst(), signatureAlgorithm: .ecdsaSecp256k1) 62 | self.implementation = .ecdsaSecp256k1(key) 63 | } 64 | } 65 | 66 | /// Generates a signature. 67 | /// - Parameter data: The data to sign. 68 | /// - Parameter hashAlgorithm: The hash algorithm. 69 | /// - Returns: The ECDSA Signature. 70 | /// - Throws: If there is a failure producing the signature. 71 | public func sign(message: Data, hashAlgorithm: HashAlgorithm) throws -> Data { 72 | switch implementation { 73 | case let .ecdsaP256(key): 74 | let digest = hashAlgorithm.getDigest(message: message) 75 | return try key.signature(for: digest).rawRepresentation 76 | case let .ecdsaSecp256k1(key): 77 | let digest = hashAlgorithm.getDigest(message: message) 78 | return try key.ecdsa.signature(for: digest).compactRepresentation 79 | } 80 | } 81 | } 82 | 83 | // MARK: - Equatable, Hashable 84 | 85 | extension PrivateKey: Equatable, Hashable { 86 | 87 | public static func == (lhs: PrivateKey, rhs: PrivateKey) -> Bool { 88 | lhs.hashValue == rhs.hashValue 89 | } 90 | 91 | public func hash(into hasher: inout Hasher) { 92 | hasher.combine(data) 93 | hasher.combine(algorithm) 94 | } 95 | 96 | } 97 | 98 | // MARK: - Error 99 | 100 | extension PrivateKey { 101 | 102 | public enum Error: Swift.Error { 103 | case insufficientSeedLength 104 | } 105 | } 106 | 107 | // MARK: - CustomStringConvertible 108 | 109 | extension PrivateKey: CustomStringConvertible { 110 | 111 | public var description: String { 112 | hexString 113 | } 114 | } 115 | 116 | // MARK: - Implementation 117 | 118 | extension PrivateKey { 119 | 120 | private enum Implementation { 121 | case ecdsaP256(P256.Signing.PrivateKey) 122 | case ecdsaSecp256k1(secp256k1.Signing.PrivateKey) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/PublicKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicKey.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import CryptoKit 10 | import CryptoSwift 11 | import secp256k1Swift 12 | 13 | public struct PublicKey { 14 | 15 | public let data: Data 16 | 17 | public let algorithm: SignatureAlgorithm 18 | 19 | public var size: Int { 20 | data.count 21 | } 22 | 23 | public var hexString: String { 24 | data.toHexString() 25 | } 26 | 27 | private let implementation: Implementation 28 | 29 | public init(data: Data, signatureAlgorithm: SignatureAlgorithm) throws { 30 | self.algorithm = signatureAlgorithm 31 | 32 | switch signatureAlgorithm { 33 | case .ecdsaP256: 34 | self.data = data 35 | self.implementation = .ecdsaP256(try P256.Signing.PublicKey(rawRepresentation: data)) 36 | case .ecdsaSecp256k1: 37 | let rawData: Data 38 | switch data.count { 39 | case secp256k1.Format.compressed.length, secp256k1.Format.compressed.length - 1: 40 | throw Error.unsupportedCompressFormat 41 | case secp256k1.Format.uncompressed.length: 42 | rawData = data 43 | self.data = data.dropFirst() 44 | case secp256k1.Format.uncompressed.length - 1: 45 | self.data = data 46 | rawData = Data([0x04]) + data 47 | default: 48 | throw Error.incorrectKeySize 49 | } 50 | 51 | let key = try secp256k1.Signing.PublicKey( 52 | rawRepresentation: [UInt8](rawData), 53 | format: .uncompressed) 54 | self.implementation = .ecdsaSecp256k1(key) 55 | } 56 | } 57 | 58 | public func verify(signature: Data, message: Data, hashAlgorithm: HashAlgorithm) throws -> Bool { 59 | switch implementation { 60 | case let .ecdsaP256(key): 61 | let digest = hashAlgorithm.getDigest(message: message) 62 | let ecdsaSignature = try P256.Signing.ECDSASignature(rawRepresentation: signature) 63 | return key.isValidSignature(ecdsaSignature, for: digest) 64 | case let .ecdsaSecp256k1(key): 65 | let digest = hashAlgorithm.getDigest(message: message) 66 | let ecdsaSignature = try secp256k1.Signing.ECDSASignature(compactRepresentation: signature) 67 | return key.ecdsa.isValidSignature(ecdsaSignature, for: digest) 68 | } 69 | } 70 | 71 | } 72 | 73 | // MARK: - Equatable, Hashable 74 | 75 | extension PublicKey: Equatable, Hashable { 76 | 77 | public static func == (lhs: PublicKey, rhs: PublicKey) -> Bool { 78 | lhs.hashValue == rhs.hashValue 79 | } 80 | 81 | public func hash(into hasher: inout Hasher) { 82 | hasher.combine(data) 83 | hasher.combine(algorithm) 84 | } 85 | 86 | } 87 | 88 | // MARK: - Error 89 | 90 | extension PublicKey { 91 | 92 | enum Error: Swift.Error { 93 | case unsupportedCompressFormat 94 | case incorrectKeySize 95 | } 96 | } 97 | 98 | // MARK: - CustomStringConvertible 99 | 100 | extension PublicKey: CustomStringConvertible { 101 | 102 | public var description: String { 103 | hexString 104 | } 105 | } 106 | 107 | // MARK: - Implementation 108 | 109 | extension PublicKey { 110 | 111 | private enum Implementation { 112 | case ecdsaP256(P256.Signing.PublicKey) 113 | case ecdsaSecp256k1(secp256k1.Signing.PublicKey) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/SHA256Digest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SHA256Digest.swift 3 | // 4 | // Created by Scott on 2022/6/6. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import CryptoKit 10 | import secp256k1Swift 11 | 12 | public struct SHA256Digest: CryptoKit.Digest, secp256k1Swift.Digest { 13 | 14 | let bytes: (UInt64, UInt64, UInt64, UInt64) 15 | 16 | init?(data: Data) { 17 | self.init(bytes: [UInt8](data)) 18 | } 19 | 20 | init?(bytes: [UInt8]) { 21 | let some = bytes.withUnsafeBytes { bufferPointer in 22 | return Self(bufferPointer: bufferPointer) 23 | } 24 | 25 | if some != nil { 26 | self = some! 27 | } else { 28 | return nil 29 | } 30 | } 31 | 32 | init?(bufferPointer: UnsafeRawBufferPointer) { 33 | guard bufferPointer.count == 32 else { 34 | return nil 35 | } 36 | 37 | var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0)) 38 | withUnsafeMutableBytes(of: &bytes) { targetPtr in 39 | targetPtr.copyMemory(from: bufferPointer) 40 | } 41 | self.bytes = bytes 42 | } 43 | 44 | public static var byteCount: Int { 45 | return 32 46 | } 47 | 48 | public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { 49 | return try Swift.withUnsafeBytes(of: bytes) { 50 | let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, 51 | count: Self.byteCount) 52 | return try body(boundsCheckedPtr) 53 | } 54 | } 55 | 56 | // MARK: - CustomStringConvertible 57 | 58 | private func toArray() -> ArraySlice { 59 | var array = [UInt8]() 60 | array.appendByte(bytes.0) 61 | array.appendByte(bytes.1) 62 | array.appendByte(bytes.2) 63 | array.appendByte(bytes.3) 64 | return array.prefix(upTo: SHA256Digest.byteCount) 65 | } 66 | 67 | public var description: String { 68 | return "\("SHA256") digest: \(toArray())" 69 | } 70 | 71 | // MARK: - Equatable 72 | 73 | public static func == (lhs: SHA256Digest, rhs: SHA256Digest) -> Bool { 74 | lhs.hashValue == rhs.hashValue 75 | } 76 | 77 | // MARK: - Hashable 78 | 79 | public func hash(into hasher: inout Hasher) { 80 | withUnsafeBytes { hasher.combine(bytes: $0) } 81 | } 82 | 83 | // MARK: - Sequence 84 | 85 | public func makeIterator() -> Array.Iterator { 86 | withUnsafeBytes { 87 | Array($0).makeIterator() 88 | } 89 | } 90 | 91 | } 92 | 93 | extension MutableDataProtocol { 94 | 95 | mutating func appendByte(_ byte: UInt64) { 96 | withUnsafePointer( 97 | to: byte.littleEndian, 98 | { append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) }) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/SignatureAlgorithm.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignatureAlgorithm.swift 3 | // 4 | // Created by Scott on 2022/6/5. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum SignatureAlgorithm: UInt32, RawRepresentable { 11 | case ecdsaP256 = 2 12 | case ecdsaSecp256k1 = 3 13 | } 14 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Crypto/Signer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Signer.swift 3 | // 4 | // Created by Scott on 2022/6/5. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public protocol Signer { 11 | 12 | /// PublicKey returns the verification public key corresponding to the signer 13 | var publicKey: PublicKey { get } 14 | 15 | /// Signs the given message with this signer. 16 | /// - Returns: signature 17 | func sign(message: Data) throws -> Data 18 | } 19 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Extensions/HashAlgorithm+Cadence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashAlgorithm.swift 3 | // 4 | // Created by Scott on 2022/7/24. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | public extension HashAlgorithm { 12 | 13 | var cadenceArugment: Cadence.Argument { 14 | .enum( 15 | id: "HashAlgorithm", 16 | fields: [ 17 | .init( 18 | name: "rawValue", 19 | value: .uint8(cadenceRawValue) 20 | ) 21 | ] 22 | ) 23 | } 24 | 25 | var cadenceRawValue: UInt8 { 26 | switch self { 27 | case .sha2_256: 28 | return 1 29 | case .sha3_256: 30 | return 3 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Extensions/PublickKey+Cadence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicKey.swift 3 | // 4 | // Created by Scott on 2022/7/24. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | public extension PublicKey { 12 | 13 | var cadenceArugment: Cadence.Argument { 14 | .struct( 15 | id: "PublicKey", 16 | fields: [ 17 | .init( 18 | name: "publicKey", 19 | value: .array(data.map { .uint8($0) }) 20 | ), 21 | .init( 22 | name: "signatureAlgorithm", 23 | value: .enum( 24 | id: "SignatureAlgorithm", 25 | fields: [ 26 | .init( 27 | name: "rawValue", 28 | value: .uint8(algorithm.cadenceRawValue)) 29 | ] 30 | ) 31 | ), 32 | ] 33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Extensions/SignatureAlgorithm+Cadence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignatureAlgorithm+Cadence.swift 3 | // 4 | // Created by Scott on 2022/7/12. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public extension SignatureAlgorithm { 11 | 12 | var cadenceRawValue: UInt8 { 13 | switch self { 14 | case .ecdsaP256: 15 | return 1 16 | case .ecdsaSecp256k1: 17 | return 2 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/Account.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Account.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | /// An account on the Flow network. 12 | public struct Account: Equatable { 13 | 14 | public let address: Address 15 | 16 | public let balance: UInt64 17 | 18 | public let code: Data 19 | 20 | public let keys: [AccountKey] 21 | 22 | public let contracts: [String: Data] 23 | 24 | public init( 25 | address: Address, 26 | balance: UInt64, 27 | code: Data, 28 | keys: [AccountKey], 29 | contracts: [String: Data] 30 | ) { 31 | self.address = address 32 | self.balance = balance 33 | self.code = code 34 | self.keys = keys 35 | self.contracts = contracts 36 | } 37 | 38 | init(_ value: Flow_Entities_Account) throws { 39 | self.address = Address(data: value.address) 40 | self.balance = value.balance 41 | self.code = value.code 42 | self.keys = try value.keys.map { try AccountKey($0) } 43 | self.contracts = value.contracts 44 | } 45 | } 46 | 47 | /// A public key associated with an account. 48 | public struct AccountKey: Equatable { 49 | 50 | /// The total key weight required to authorize access to an account. 51 | public static let weightThreshold = 1000 52 | 53 | public let index: Int 54 | 55 | public let publicKey: PublicKey 56 | 57 | public let signatureAlgorithm: SignatureAlgorithm 58 | 59 | public let hashAlgorithm: HashAlgorithm 60 | 61 | public let weight: Int 62 | 63 | public let sequenceNumber: UInt64 64 | 65 | public let revoked: Bool 66 | 67 | public init( 68 | index: Int, 69 | publicKey: PublicKey, 70 | signatureAlgorithm: SignatureAlgorithm, 71 | hashAlgorithm: HashAlgorithm, 72 | weight: Int, 73 | sequenceNumber: UInt64, 74 | revoked: Bool = false 75 | ) { 76 | self.index = index 77 | self.publicKey = publicKey 78 | self.signatureAlgorithm = signatureAlgorithm 79 | self.hashAlgorithm = hashAlgorithm 80 | self.weight = weight 81 | self.sequenceNumber = sequenceNumber 82 | self.revoked = revoked 83 | } 84 | 85 | init(_ value: Flow_Entities_AccountKey) throws { 86 | self.index = Int(value.index) 87 | guard let signatureAlgorithm = SignatureAlgorithm(rawValue: value.signAlgo) else { 88 | throw Error.unsupportedSignatureAlgorithm 89 | } 90 | self.signatureAlgorithm = signatureAlgorithm 91 | guard let hashAlgorithm = HashAlgorithm(rawValue: value.hashAlgo) else { 92 | throw Error.unsupportedHashAlgorithm 93 | } 94 | self.hashAlgorithm = hashAlgorithm 95 | self.publicKey = try PublicKey(data: value.publicKey, signatureAlgorithm: signatureAlgorithm) 96 | self.weight = Int(value.weight) 97 | self.sequenceNumber = UInt64(value.sequenceNumber) 98 | self.revoked = value.revoked 99 | } 100 | 101 | public enum Error: Swift.Error { 102 | case unsupportedSignatureAlgorithm 103 | case unsupportedHashAlgorithm 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/Block.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Block.swift 3 | // 4 | // Created by Scott on 2022/5/18. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Block is a set of state mutations applied to the Flow blockchain. 11 | public struct Block: Equatable { 12 | 13 | public let blockHeader: BlockHeader 14 | 15 | public let blockPayload: BlockPayload 16 | 17 | public var id: Identifier { 18 | blockHeader.id 19 | } 20 | 21 | public init(blockHeader: BlockHeader, blockPayload: BlockPayload) { 22 | self.blockHeader = blockHeader 23 | self.blockPayload = blockPayload 24 | } 25 | 26 | init(_ value: Flow_Entities_Block) { 27 | self.blockHeader = BlockHeader( 28 | id: Identifier(data: value.id), 29 | parentId: Identifier(data: value.parentID), 30 | height: value.height, 31 | timestamp: value.hasTimestamp ? value.timestamp.date : nil) 32 | self.blockPayload = BlockPayload( 33 | collectionGuarantees: value.collectionGuarantees.map { 34 | CollectionGuarantee(collectionId: Identifier(data: $0.collectionID)) 35 | }, 36 | seals: value.blockSeals.map { 37 | BlockSeal( 38 | blockID: Identifier(data: $0.blockID), 39 | executionReceiptID: Identifier(data: $0.executionReceiptID)) 40 | }) 41 | } 42 | } 43 | 44 | /// BlockHeader is a summary of a full block. 45 | public struct BlockHeader: Equatable { 46 | 47 | public let id: Identifier 48 | 49 | public let parentId: Identifier 50 | 51 | public let height: UInt64 52 | 53 | public let timestamp: Date? 54 | 55 | public init( 56 | id: Identifier, 57 | parentId: Identifier, 58 | height: UInt64, 59 | timestamp: Date? 60 | ) { 61 | self.id = id 62 | self.parentId = parentId 63 | self.height = height 64 | self.timestamp = timestamp 65 | } 66 | 67 | init(_ value: Flow_Entities_BlockHeader) { 68 | self.id = Identifier(data: value.id) 69 | self.parentId = Identifier(data: value.parentID) 70 | self.height = value.height 71 | self.timestamp = value.hasTimestamp ? value.timestamp.date : nil 72 | } 73 | 74 | } 75 | 76 | /// BlockPayload is the full contents of a block. 77 | /// 78 | /// A payload contains the collection guarantees and seals for a block. 79 | public struct BlockPayload: Equatable { 80 | public let collectionGuarantees: [CollectionGuarantee] 81 | public let seals: [BlockSeal] 82 | } 83 | 84 | /// BlockSeal is the attestation by verification nodes that the transactions in a previously 85 | /// executed block have been verified. 86 | public struct BlockSeal: Equatable { 87 | 88 | /// The ID of the block this Seal refers to (which will be of lower height than this block) 89 | public let blockID: Identifier 90 | 91 | /// The ID of the execution receipt generated by the Verifier nodes; the work of verifying a 92 | /// block produces the same receipt among all verifying nodes 93 | public let executionReceiptID: Identifier 94 | } 95 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/BlockEvents.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlockEvents.swift 3 | // 4 | // Created by Scott on 2022/6/1. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// The events that occurred in a specific block. 11 | public struct BlockEvents: Equatable { 12 | 13 | public let blockId: Identifier 14 | 15 | public let height: UInt64 16 | 17 | public let blockDate: Date 18 | 19 | public let events: [Event] 20 | 21 | public init( 22 | blockId: Identifier, 23 | height: UInt64, 24 | blockDate: Date, 25 | events: [Event] 26 | ) { 27 | self.blockId = blockId 28 | self.height = height 29 | self.blockDate = blockDate 30 | self.events = events 31 | } 32 | 33 | init(_ value: Flow_Access_EventsResponse.Result) throws { 34 | self.blockId = Identifier(data: value.blockID) 35 | self.height = value.blockHeight 36 | self.blockDate = value.blockTimestamp.date 37 | self.events = try value.events.map { try Event($0) } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/Collection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Collection.swift 3 | // 4 | // Created by Scott on 2022/5/18. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// A Collection is a list of transactions bundled together for inclusion in a block. 11 | public struct Collection: Equatable { 12 | 13 | public let transactionIds: [Identifier] 14 | 15 | public init(transactionIds: [Identifier]) { 16 | self.transactionIds = transactionIds 17 | } 18 | 19 | init(_ value: Flow_Entities_Collection) { 20 | self.transactionIds = value.transactionIds.map { Identifier(data: $0) } 21 | } 22 | } 23 | 24 | /// A CollectionGuarantee is an attestation signed by the nodes that have guaranteed a collection. 25 | public struct CollectionGuarantee: Equatable { 26 | 27 | public let collectionId: Identifier 28 | } 29 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/DomainTag.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DomainTag.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | private let domainTagLength = 32 11 | 12 | /// A domain tag is encoded as UTF-8 bytes, right padded to a total length of 32 bytes. 13 | public enum DomainTag: String { 14 | 15 | /// The prefix of all signed transaction payloads. 16 | case transaction = "FLOW-V0.0-transaction" 17 | 18 | /// The prefix of all signed user space payloads. 19 | case user = "FLOW-V0.0-user" 20 | 21 | /// The prefix of all signed accountProof message. 22 | case accountProof = "FCL-ACCOUNT-PROOF-V0.0" 23 | 24 | public var rightPaddedData: Data { 25 | var data = rawValue.data(using: .utf8) ?? Data() 26 | while data.count < domainTagLength { 27 | data.append(0) 28 | } 29 | return data 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/Event.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Event.swift 3 | // 4 | // Created by Scott on 2022/5/20. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | public struct Event: Equatable { 12 | /// The qualified event type. 13 | public let type: String 14 | 15 | /// The ID of the transaction this event was emitted from. 16 | public let transactionId: Identifier 17 | 18 | /// The index of the transaction this event was emitted from, within its containing block. 19 | public let transactionIndex: Int 20 | 21 | /// The index of the event within the transaction it was emitted from. 22 | public let eventIndex: Int 23 | 24 | /// Value contains the event data. 25 | public let value: Cadence.CompositeEvent 26 | 27 | /// Bytes representing event data. 28 | public let payload: Data 29 | 30 | public init( 31 | type: String, 32 | transactionId: Identifier, 33 | transactionIndex: Int, 34 | eventIndex: Int, 35 | value: Cadence.CompositeEvent, 36 | payload: Data 37 | ) { 38 | self.type = type 39 | self.transactionId = transactionId 40 | self.transactionIndex = transactionIndex 41 | self.eventIndex = eventIndex 42 | self.value = value 43 | self.payload = payload 44 | } 45 | 46 | init(_ value: Flow_Entities_Event) throws { 47 | self.type = value.type 48 | self.transactionId = Identifier(data: value.transactionID) 49 | self.transactionIndex = Int(value.transactionIndex) 50 | self.eventIndex = Int(value.eventIndex) 51 | self.payload = value.payload 52 | 53 | if case let .event(event) = try Cadence.Argument.decode(data: value.payload).value { 54 | self.value = event 55 | } else { 56 | throw Error.notEventArgument 57 | } 58 | } 59 | } 60 | 61 | // MARK: - Error 62 | extension Event { 63 | 64 | public enum Error: Swift.Error { 65 | case notEventArgument 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/ExecutionResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExecutionResult.swift 3 | // 4 | // Created by Scott on 2022/6/1. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct ExecutionResult: Equatable { 11 | 12 | public let previousResultId: Identifier 13 | 14 | public let blockId: Identifier 15 | 16 | public let chunks: [Chunk] 17 | 18 | public let serviceEvents: [ServiceEvent] 19 | 20 | public init( 21 | previousResultId: Identifier, 22 | blockId: Identifier, 23 | chunks: [Chunk], 24 | serviceEvents: [ServiceEvent] 25 | ) { 26 | self.previousResultId = previousResultId 27 | self.blockId = blockId 28 | self.chunks = chunks 29 | self.serviceEvents = serviceEvents 30 | } 31 | 32 | init(_ value: Flow_Entities_ExecutionResult) { 33 | self.previousResultId = Identifier(data: value.previousResultID) 34 | self.blockId = Identifier(data: value.blockID) 35 | self.chunks = value.chunks.map { Chunk($0) } 36 | self.serviceEvents = value.serviceEvents.map { ServiceEvent($0) } 37 | } 38 | } 39 | 40 | public typealias StateCommitment = Identifier 41 | 42 | public struct Chunk: Equatable { 43 | 44 | public let collectionIndex: UInt 45 | 46 | /// start state when starting executing this chunk 47 | public let startState: StateCommitment 48 | 49 | /// Hash of events generated by executing results 50 | public let eventCollection: Data 51 | 52 | /// Block id of the execution result this chunk belongs to 53 | public let blockId: Identifier 54 | 55 | /// total amount of computation used by running all txs in this chunk 56 | public let totalComputationUsed: UInt64 57 | 58 | /// number of transactions inside the collection 59 | public let numberOfTransactions: UInt32 60 | 61 | /// chunk index inside the ER (starts from zero) 62 | public let index: UInt64 63 | 64 | /// endState inferred from next chunk or from the ER 65 | public let endState: StateCommitment 66 | 67 | public init( 68 | collectionIndex: UInt, 69 | startState: StateCommitment, 70 | eventCollection: Data, 71 | blockId: Identifier, 72 | totalComputationUsed: UInt64, 73 | numberOfTransactions: UInt32, 74 | index: UInt64, 75 | endState: StateCommitment 76 | ) { 77 | self.collectionIndex = collectionIndex 78 | self.startState = startState 79 | self.eventCollection = eventCollection 80 | self.blockId = blockId 81 | self.totalComputationUsed = totalComputationUsed 82 | self.numberOfTransactions = numberOfTransactions 83 | self.index = index 84 | self.endState = endState 85 | } 86 | 87 | init(_ value: Flow_Entities_Chunk) { 88 | self.collectionIndex = UInt(value.collectionIndex) 89 | self.startState = StateCommitment(data: value.startState) 90 | self.eventCollection = value.eventCollection 91 | self.blockId = Identifier(data: value.blockID) 92 | self.totalComputationUsed = value.totalComputationUsed 93 | self.numberOfTransactions = value.numberOfTransactions 94 | self.index = value.index 95 | self.endState = StateCommitment(data: value.endState) 96 | } 97 | } 98 | 99 | public struct ServiceEvent: Equatable { 100 | 101 | public let type: String 102 | 103 | public let payload: Data 104 | 105 | public init(type: String, payload: Data) { 106 | self.type = type 107 | self.payload = payload 108 | } 109 | 110 | init(_ value: Flow_Entities_ServiceEvent) { 111 | self.type = value.type 112 | self.payload = value.payload 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/Identifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Identifier.swift 3 | // 4 | // Created by Scott on 2022/5/18. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import CryptoSwift 10 | 11 | public struct Identifier: Equatable { 12 | 13 | public static let empty = Identifier(data: Data(repeating: 0, count: 32)) 14 | 15 | public let data: Data 16 | 17 | public var hexString: String { 18 | data.toHexString() 19 | } 20 | 21 | public init(data: Data) { 22 | self.data = data 23 | } 24 | 25 | public init(hexString: String) { 26 | self.init(data: Data(hex: hexString)) 27 | } 28 | } 29 | 30 | // MARK: - CustomStringConvertible 31 | extension Identifier: CustomStringConvertible { 32 | 33 | public var description: String { 34 | hexString 35 | } 36 | } 37 | 38 | // MARK: - ExpressibleByStringLiteral 39 | extension Identifier: ExpressibleByStringLiteral { 40 | 41 | public init(stringLiteral value: String) { 42 | self.init(hexString: value) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/TransactionProposalKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransactionProposalKey.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | extension Transaction { 12 | 13 | /// The key that specifies the proposal key and sequence number for a transaction. 14 | public struct ProposalKey: Equatable { 15 | public let address: Address 16 | public let keyIndex: Int 17 | public let sequenceNumber: UInt64 18 | 19 | public init(address: Address, keyIndex: Int, sequenceNumber: UInt64) { 20 | self.address = address 21 | self.keyIndex = keyIndex 22 | self.sequenceNumber = sequenceNumber 23 | } 24 | 25 | init(_ value: Flow_Entities_Transaction.ProposalKey) { 26 | self.address = Address(data: value.address) 27 | self.keyIndex = Int(value.keyID) 28 | self.sequenceNumber = value.sequenceNumber 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/TransactionResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransactionResult.swift 3 | // 4 | // Created by Scott on 2022/5/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public struct TransactionResult: Equatable { 11 | public let status: TransactionStatus? 12 | public let errorMessage: String? 13 | public let events: [Event] 14 | public let blockId: Identifier 15 | 16 | public init( 17 | status: TransactionStatus?, 18 | errorMessage: String?, 19 | events: [Event], 20 | blockId: Identifier 21 | ) { 22 | self.status = status 23 | self.errorMessage = errorMessage 24 | self.events = events 25 | self.blockId = blockId 26 | } 27 | 28 | init(_ value: Flow_Access_TransactionResultResponse) throws { 29 | let errorMessage: String? 30 | if value.statusCode != 0 { 31 | errorMessage = value.errorMessage == "" ? "transaction execution failed" : value.errorMessage 32 | } else { 33 | errorMessage = nil 34 | } 35 | self.status = value.status 36 | self.errorMessage = errorMessage 37 | self.events = try value.events.map { try Event($0) } 38 | self.blockId = Identifier(data: value.blockID) 39 | } 40 | } 41 | 42 | // MARK: - TransactionStatus 43 | 44 | public typealias TransactionStatus = Flow_Entities_TransactionStatus 45 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Models/TransactionSignature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransactionSignature.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import Cadence 10 | 11 | extension Transaction { 12 | 13 | /// A signature associated with a specific account key. 14 | public struct Signature: Equatable { 15 | public var address: Address 16 | public var signerIndex: Int 17 | public let keyIndex: Int 18 | public let signature: Data 19 | 20 | public init( 21 | address: Address, 22 | signerIndex: Int, 23 | keyIndex: Int, 24 | signature: Data 25 | ) { 26 | self.address = address 27 | self.signerIndex = signerIndex 28 | self.keyIndex = keyIndex 29 | self.signature = signature 30 | } 31 | } 32 | } 33 | 34 | extension Transaction.Signature: RLPDecodable { 35 | 36 | public init(rlpItem: RLPItem) throws { 37 | let items = try rlpItem.getListItems() 38 | guard items.count == 3 else { 39 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 40 | } 41 | 42 | self.address = Address.emptyAddress 43 | self.signerIndex = Int(try UInt(rlpItem: items[0])) 44 | self.keyIndex = Int(try UInt(rlpItem: items[1])) 45 | self.signature = try Data(rlpItem: items[2]) 46 | } 47 | } 48 | 49 | extension Transaction.Signature: RLPEncodableList { 50 | 51 | public var rlpList: RLPEncoableArray { 52 | [ 53 | UInt(signerIndex), 54 | UInt(keyIndex), 55 | signature 56 | ] 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Network.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Network.swift 3 | // 4 | // Created by Scott on 2022/6/21. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum Network { 11 | case mainnet 12 | case testnet 13 | case canarynet 14 | case sandboxnet 15 | case emulator 16 | case custom(host: String, port: Int) 17 | 18 | var endpoint: Endpoint { 19 | switch self { 20 | case .mainnet: 21 | return Endpoint(host: "access.mainnet.nodes.onflow.org", port: 9000) 22 | case .testnet: 23 | return Endpoint(host: "access.devnet.nodes.onflow.org", port: 9000) 24 | case .canarynet: 25 | return Endpoint(host: "access.canary.nodes.onflow.org", port: 9000) 26 | case .sandboxnet: 27 | return Endpoint(host: "access.sandboxnet.nodes.onflow.org", port: 9000) 28 | case .emulator: 29 | return Endpoint(host: "127.0.0.1", port: 3569) 30 | case let .custom(host, port): 31 | return Endpoint(host: host, port: port) 32 | } 33 | } 34 | } 35 | 36 | // MARK: - Endpoint 37 | 38 | extension Network { 39 | 40 | public struct Endpoint { 41 | 42 | public let host: String 43 | public let port: Int 44 | 45 | public init(host: String, port: Int) { 46 | self.host = host 47 | self.port = port 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/account.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/account.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_Account { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var address: Data = Data() 29 | 30 | public var balance: UInt64 = 0 31 | 32 | public var code: Data = Data() 33 | 34 | public var keys: [Flow_Entities_AccountKey] = [] 35 | 36 | public var contracts: Dictionary = [:] 37 | 38 | public var unknownFields = SwiftProtobuf.UnknownStorage() 39 | 40 | public init() {} 41 | } 42 | 43 | public struct Flow_Entities_AccountKey { 44 | // SwiftProtobuf.Message conformance is added in an extension below. See the 45 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 46 | // methods supported on all messages. 47 | 48 | public var index: UInt32 = 0 49 | 50 | public var publicKey: Data = Data() 51 | 52 | public var signAlgo: UInt32 = 0 53 | 54 | public var hashAlgo: UInt32 = 0 55 | 56 | public var weight: UInt32 = 0 57 | 58 | public var sequenceNumber: UInt32 = 0 59 | 60 | public var revoked: Bool = false 61 | 62 | public var unknownFields = SwiftProtobuf.UnknownStorage() 63 | 64 | public init() {} 65 | } 66 | 67 | #if swift(>=5.5) && canImport(_Concurrency) 68 | extension Flow_Entities_Account: @unchecked Sendable {} 69 | extension Flow_Entities_AccountKey: @unchecked Sendable {} 70 | #endif // swift(>=5.5) && canImport(_Concurrency) 71 | 72 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 73 | 74 | fileprivate let _protobuf_package = "flow.entities" 75 | 76 | extension Flow_Entities_Account: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 77 | public static let protoMessageName: String = _protobuf_package + ".Account" 78 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 79 | 1: .same(proto: "address"), 80 | 2: .same(proto: "balance"), 81 | 3: .same(proto: "code"), 82 | 4: .same(proto: "keys"), 83 | 5: .same(proto: "contracts"), 84 | ] 85 | 86 | public mutating func decodeMessage(decoder: inout D) throws { 87 | while let fieldNumber = try decoder.nextFieldNumber() { 88 | // The use of inline closures is to circumvent an issue where the compiler 89 | // allocates stack space for every case branch when no optimizations are 90 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 91 | switch fieldNumber { 92 | case 1: try { try decoder.decodeSingularBytesField(value: &self.address) }() 93 | case 2: try { try decoder.decodeSingularUInt64Field(value: &self.balance) }() 94 | case 3: try { try decoder.decodeSingularBytesField(value: &self.code) }() 95 | case 4: try { try decoder.decodeRepeatedMessageField(value: &self.keys) }() 96 | case 5: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: &self.contracts) }() 97 | default: break 98 | } 99 | } 100 | } 101 | 102 | public func traverse(visitor: inout V) throws { 103 | if !self.address.isEmpty { 104 | try visitor.visitSingularBytesField(value: self.address, fieldNumber: 1) 105 | } 106 | if self.balance != 0 { 107 | try visitor.visitSingularUInt64Field(value: self.balance, fieldNumber: 2) 108 | } 109 | if !self.code.isEmpty { 110 | try visitor.visitSingularBytesField(value: self.code, fieldNumber: 3) 111 | } 112 | if !self.keys.isEmpty { 113 | try visitor.visitRepeatedMessageField(value: self.keys, fieldNumber: 4) 114 | } 115 | if !self.contracts.isEmpty { 116 | try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: self.contracts, fieldNumber: 5) 117 | } 118 | try unknownFields.traverse(visitor: &visitor) 119 | } 120 | 121 | public static func ==(lhs: Flow_Entities_Account, rhs: Flow_Entities_Account) -> Bool { 122 | if lhs.address != rhs.address {return false} 123 | if lhs.balance != rhs.balance {return false} 124 | if lhs.code != rhs.code {return false} 125 | if lhs.keys != rhs.keys {return false} 126 | if lhs.contracts != rhs.contracts {return false} 127 | if lhs.unknownFields != rhs.unknownFields {return false} 128 | return true 129 | } 130 | } 131 | 132 | extension Flow_Entities_AccountKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 133 | public static let protoMessageName: String = _protobuf_package + ".AccountKey" 134 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 135 | 1: .same(proto: "index"), 136 | 2: .standard(proto: "public_key"), 137 | 3: .standard(proto: "sign_algo"), 138 | 4: .standard(proto: "hash_algo"), 139 | 5: .same(proto: "weight"), 140 | 6: .standard(proto: "sequence_number"), 141 | 7: .same(proto: "revoked"), 142 | ] 143 | 144 | public mutating func decodeMessage(decoder: inout D) throws { 145 | while let fieldNumber = try decoder.nextFieldNumber() { 146 | // The use of inline closures is to circumvent an issue where the compiler 147 | // allocates stack space for every case branch when no optimizations are 148 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 149 | switch fieldNumber { 150 | case 1: try { try decoder.decodeSingularUInt32Field(value: &self.index) }() 151 | case 2: try { try decoder.decodeSingularBytesField(value: &self.publicKey) }() 152 | case 3: try { try decoder.decodeSingularUInt32Field(value: &self.signAlgo) }() 153 | case 4: try { try decoder.decodeSingularUInt32Field(value: &self.hashAlgo) }() 154 | case 5: try { try decoder.decodeSingularUInt32Field(value: &self.weight) }() 155 | case 6: try { try decoder.decodeSingularUInt32Field(value: &self.sequenceNumber) }() 156 | case 7: try { try decoder.decodeSingularBoolField(value: &self.revoked) }() 157 | default: break 158 | } 159 | } 160 | } 161 | 162 | public func traverse(visitor: inout V) throws { 163 | if self.index != 0 { 164 | try visitor.visitSingularUInt32Field(value: self.index, fieldNumber: 1) 165 | } 166 | if !self.publicKey.isEmpty { 167 | try visitor.visitSingularBytesField(value: self.publicKey, fieldNumber: 2) 168 | } 169 | if self.signAlgo != 0 { 170 | try visitor.visitSingularUInt32Field(value: self.signAlgo, fieldNumber: 3) 171 | } 172 | if self.hashAlgo != 0 { 173 | try visitor.visitSingularUInt32Field(value: self.hashAlgo, fieldNumber: 4) 174 | } 175 | if self.weight != 0 { 176 | try visitor.visitSingularUInt32Field(value: self.weight, fieldNumber: 5) 177 | } 178 | if self.sequenceNumber != 0 { 179 | try visitor.visitSingularUInt32Field(value: self.sequenceNumber, fieldNumber: 6) 180 | } 181 | if self.revoked != false { 182 | try visitor.visitSingularBoolField(value: self.revoked, fieldNumber: 7) 183 | } 184 | try unknownFields.traverse(visitor: &visitor) 185 | } 186 | 187 | public static func ==(lhs: Flow_Entities_AccountKey, rhs: Flow_Entities_AccountKey) -> Bool { 188 | if lhs.index != rhs.index {return false} 189 | if lhs.publicKey != rhs.publicKey {return false} 190 | if lhs.signAlgo != rhs.signAlgo {return false} 191 | if lhs.hashAlgo != rhs.hashAlgo {return false} 192 | if lhs.weight != rhs.weight {return false} 193 | if lhs.sequenceNumber != rhs.sequenceNumber {return false} 194 | if lhs.revoked != rhs.revoked {return false} 195 | if lhs.unknownFields != rhs.unknownFields {return false} 196 | return true 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/block.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/block.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_Block { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var id: Data { 29 | get {return _storage._id} 30 | set {_uniqueStorage()._id = newValue} 31 | } 32 | 33 | public var parentID: Data { 34 | get {return _storage._parentID} 35 | set {_uniqueStorage()._parentID = newValue} 36 | } 37 | 38 | public var height: UInt64 { 39 | get {return _storage._height} 40 | set {_uniqueStorage()._height = newValue} 41 | } 42 | 43 | public var timestamp: SwiftProtobuf.Google_Protobuf_Timestamp { 44 | get {return _storage._timestamp ?? SwiftProtobuf.Google_Protobuf_Timestamp()} 45 | set {_uniqueStorage()._timestamp = newValue} 46 | } 47 | /// Returns true if `timestamp` has been explicitly set. 48 | public var hasTimestamp: Bool {return _storage._timestamp != nil} 49 | /// Clears the value of `timestamp`. Subsequent reads from it will return its default value. 50 | public mutating func clearTimestamp() {_uniqueStorage()._timestamp = nil} 51 | 52 | public var collectionGuarantees: [Flow_Entities_CollectionGuarantee] { 53 | get {return _storage._collectionGuarantees} 54 | set {_uniqueStorage()._collectionGuarantees = newValue} 55 | } 56 | 57 | public var blockSeals: [Flow_Entities_BlockSeal] { 58 | get {return _storage._blockSeals} 59 | set {_uniqueStorage()._blockSeals = newValue} 60 | } 61 | 62 | public var signatures: [Data] { 63 | get {return _storage._signatures} 64 | set {_uniqueStorage()._signatures = newValue} 65 | } 66 | 67 | public var executionReceiptMetaList: [Flow_Entities_ExecutionReceiptMeta] { 68 | get {return _storage._executionReceiptMetaList} 69 | set {_uniqueStorage()._executionReceiptMetaList = newValue} 70 | } 71 | 72 | public var executionResultList: [Flow_Entities_ExecutionResult] { 73 | get {return _storage._executionResultList} 74 | set {_uniqueStorage()._executionResultList = newValue} 75 | } 76 | 77 | public var blockHeader: Flow_Entities_BlockHeader { 78 | get {return _storage._blockHeader ?? Flow_Entities_BlockHeader()} 79 | set {_uniqueStorage()._blockHeader = newValue} 80 | } 81 | /// Returns true if `blockHeader` has been explicitly set. 82 | public var hasBlockHeader: Bool {return _storage._blockHeader != nil} 83 | /// Clears the value of `blockHeader`. Subsequent reads from it will return its default value. 84 | public mutating func clearBlockHeader() {_uniqueStorage()._blockHeader = nil} 85 | 86 | public var unknownFields = SwiftProtobuf.UnknownStorage() 87 | 88 | public init() {} 89 | 90 | fileprivate var _storage = _StorageClass.defaultInstance 91 | } 92 | 93 | #if swift(>=5.5) && canImport(_Concurrency) 94 | extension Flow_Entities_Block: @unchecked Sendable {} 95 | #endif // swift(>=5.5) && canImport(_Concurrency) 96 | 97 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 98 | 99 | fileprivate let _protobuf_package = "flow.entities" 100 | 101 | extension Flow_Entities_Block: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 102 | public static let protoMessageName: String = _protobuf_package + ".Block" 103 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 104 | 1: .same(proto: "id"), 105 | 2: .standard(proto: "parent_id"), 106 | 3: .same(proto: "height"), 107 | 4: .same(proto: "timestamp"), 108 | 5: .standard(proto: "collection_guarantees"), 109 | 6: .standard(proto: "block_seals"), 110 | 7: .same(proto: "signatures"), 111 | 8: .standard(proto: "execution_receipt_metaList"), 112 | 9: .standard(proto: "execution_result_list"), 113 | 10: .standard(proto: "block_header"), 114 | ] 115 | 116 | fileprivate class _StorageClass { 117 | var _id: Data = Data() 118 | var _parentID: Data = Data() 119 | var _height: UInt64 = 0 120 | var _timestamp: SwiftProtobuf.Google_Protobuf_Timestamp? = nil 121 | var _collectionGuarantees: [Flow_Entities_CollectionGuarantee] = [] 122 | var _blockSeals: [Flow_Entities_BlockSeal] = [] 123 | var _signatures: [Data] = [] 124 | var _executionReceiptMetaList: [Flow_Entities_ExecutionReceiptMeta] = [] 125 | var _executionResultList: [Flow_Entities_ExecutionResult] = [] 126 | var _blockHeader: Flow_Entities_BlockHeader? = nil 127 | 128 | static let defaultInstance = _StorageClass() 129 | 130 | private init() {} 131 | 132 | init(copying source: _StorageClass) { 133 | _id = source._id 134 | _parentID = source._parentID 135 | _height = source._height 136 | _timestamp = source._timestamp 137 | _collectionGuarantees = source._collectionGuarantees 138 | _blockSeals = source._blockSeals 139 | _signatures = source._signatures 140 | _executionReceiptMetaList = source._executionReceiptMetaList 141 | _executionResultList = source._executionResultList 142 | _blockHeader = source._blockHeader 143 | } 144 | } 145 | 146 | fileprivate mutating func _uniqueStorage() -> _StorageClass { 147 | if !isKnownUniquelyReferenced(&_storage) { 148 | _storage = _StorageClass(copying: _storage) 149 | } 150 | return _storage 151 | } 152 | 153 | public mutating func decodeMessage(decoder: inout D) throws { 154 | _ = _uniqueStorage() 155 | try withExtendedLifetime(_storage) { (_storage: _StorageClass) in 156 | while let fieldNumber = try decoder.nextFieldNumber() { 157 | // The use of inline closures is to circumvent an issue where the compiler 158 | // allocates stack space for every case branch when no optimizations are 159 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 160 | switch fieldNumber { 161 | case 1: try { try decoder.decodeSingularBytesField(value: &_storage._id) }() 162 | case 2: try { try decoder.decodeSingularBytesField(value: &_storage._parentID) }() 163 | case 3: try { try decoder.decodeSingularUInt64Field(value: &_storage._height) }() 164 | case 4: try { try decoder.decodeSingularMessageField(value: &_storage._timestamp) }() 165 | case 5: try { try decoder.decodeRepeatedMessageField(value: &_storage._collectionGuarantees) }() 166 | case 6: try { try decoder.decodeRepeatedMessageField(value: &_storage._blockSeals) }() 167 | case 7: try { try decoder.decodeRepeatedBytesField(value: &_storage._signatures) }() 168 | case 8: try { try decoder.decodeRepeatedMessageField(value: &_storage._executionReceiptMetaList) }() 169 | case 9: try { try decoder.decodeRepeatedMessageField(value: &_storage._executionResultList) }() 170 | case 10: try { try decoder.decodeSingularMessageField(value: &_storage._blockHeader) }() 171 | default: break 172 | } 173 | } 174 | } 175 | } 176 | 177 | public func traverse(visitor: inout V) throws { 178 | try withExtendedLifetime(_storage) { (_storage: _StorageClass) in 179 | // The use of inline closures is to circumvent an issue where the compiler 180 | // allocates stack space for every if/case branch local when no optimizations 181 | // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and 182 | // https://github.com/apple/swift-protobuf/issues/1182 183 | if !_storage._id.isEmpty { 184 | try visitor.visitSingularBytesField(value: _storage._id, fieldNumber: 1) 185 | } 186 | if !_storage._parentID.isEmpty { 187 | try visitor.visitSingularBytesField(value: _storage._parentID, fieldNumber: 2) 188 | } 189 | if _storage._height != 0 { 190 | try visitor.visitSingularUInt64Field(value: _storage._height, fieldNumber: 3) 191 | } 192 | try { if let v = _storage._timestamp { 193 | try visitor.visitSingularMessageField(value: v, fieldNumber: 4) 194 | } }() 195 | if !_storage._collectionGuarantees.isEmpty { 196 | try visitor.visitRepeatedMessageField(value: _storage._collectionGuarantees, fieldNumber: 5) 197 | } 198 | if !_storage._blockSeals.isEmpty { 199 | try visitor.visitRepeatedMessageField(value: _storage._blockSeals, fieldNumber: 6) 200 | } 201 | if !_storage._signatures.isEmpty { 202 | try visitor.visitRepeatedBytesField(value: _storage._signatures, fieldNumber: 7) 203 | } 204 | if !_storage._executionReceiptMetaList.isEmpty { 205 | try visitor.visitRepeatedMessageField(value: _storage._executionReceiptMetaList, fieldNumber: 8) 206 | } 207 | if !_storage._executionResultList.isEmpty { 208 | try visitor.visitRepeatedMessageField(value: _storage._executionResultList, fieldNumber: 9) 209 | } 210 | try { if let v = _storage._blockHeader { 211 | try visitor.visitSingularMessageField(value: v, fieldNumber: 10) 212 | } }() 213 | } 214 | try unknownFields.traverse(visitor: &visitor) 215 | } 216 | 217 | public static func ==(lhs: Flow_Entities_Block, rhs: Flow_Entities_Block) -> Bool { 218 | if lhs._storage !== rhs._storage { 219 | let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in 220 | let _storage = _args.0 221 | let rhs_storage = _args.1 222 | if _storage._id != rhs_storage._id {return false} 223 | if _storage._parentID != rhs_storage._parentID {return false} 224 | if _storage._height != rhs_storage._height {return false} 225 | if _storage._timestamp != rhs_storage._timestamp {return false} 226 | if _storage._collectionGuarantees != rhs_storage._collectionGuarantees {return false} 227 | if _storage._blockSeals != rhs_storage._blockSeals {return false} 228 | if _storage._signatures != rhs_storage._signatures {return false} 229 | if _storage._executionReceiptMetaList != rhs_storage._executionReceiptMetaList {return false} 230 | if _storage._executionResultList != rhs_storage._executionResultList {return false} 231 | if _storage._blockHeader != rhs_storage._blockHeader {return false} 232 | return true 233 | } 234 | if !storagesAreEqual {return false} 235 | } 236 | if lhs.unknownFields != rhs.unknownFields {return false} 237 | return true 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/block_header.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/block_header.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_BlockHeader { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var id: Data = Data() 29 | 30 | public var parentID: Data = Data() 31 | 32 | public var height: UInt64 = 0 33 | 34 | public var timestamp: SwiftProtobuf.Google_Protobuf_Timestamp { 35 | get {return _timestamp ?? SwiftProtobuf.Google_Protobuf_Timestamp()} 36 | set {_timestamp = newValue} 37 | } 38 | /// Returns true if `timestamp` has been explicitly set. 39 | public var hasTimestamp: Bool {return self._timestamp != nil} 40 | /// Clears the value of `timestamp`. Subsequent reads from it will return its default value. 41 | public mutating func clearTimestamp() {self._timestamp = nil} 42 | 43 | public var payloadHash: Data = Data() 44 | 45 | public var view: UInt64 = 0 46 | 47 | /// deprecated!! value will be empty. replaced by parent_vote_indices 48 | public var parentVoterIds: [Data] = [] 49 | 50 | public var parentVoterSigData: Data = Data() 51 | 52 | public var proposerID: Data = Data() 53 | 54 | public var proposerSigData: Data = Data() 55 | 56 | public var chainID: String = String() 57 | 58 | public var parentVoterIndices: Data = Data() 59 | 60 | public var unknownFields = SwiftProtobuf.UnknownStorage() 61 | 62 | public init() {} 63 | 64 | fileprivate var _timestamp: SwiftProtobuf.Google_Protobuf_Timestamp? = nil 65 | } 66 | 67 | #if swift(>=5.5) && canImport(_Concurrency) 68 | extension Flow_Entities_BlockHeader: @unchecked Sendable {} 69 | #endif // swift(>=5.5) && canImport(_Concurrency) 70 | 71 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 72 | 73 | fileprivate let _protobuf_package = "flow.entities" 74 | 75 | extension Flow_Entities_BlockHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 76 | public static let protoMessageName: String = _protobuf_package + ".BlockHeader" 77 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 78 | 1: .same(proto: "id"), 79 | 2: .standard(proto: "parent_id"), 80 | 3: .same(proto: "height"), 81 | 4: .same(proto: "timestamp"), 82 | 5: .standard(proto: "payload_hash"), 83 | 6: .same(proto: "view"), 84 | 7: .standard(proto: "parent_voter_ids"), 85 | 8: .standard(proto: "parent_voter_sig_data"), 86 | 9: .standard(proto: "proposer_id"), 87 | 10: .standard(proto: "proposer_sig_data"), 88 | 11: .standard(proto: "chain_id"), 89 | 12: .standard(proto: "parent_voter_indices"), 90 | ] 91 | 92 | public mutating func decodeMessage(decoder: inout D) throws { 93 | while let fieldNumber = try decoder.nextFieldNumber() { 94 | // The use of inline closures is to circumvent an issue where the compiler 95 | // allocates stack space for every case branch when no optimizations are 96 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 97 | switch fieldNumber { 98 | case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() 99 | case 2: try { try decoder.decodeSingularBytesField(value: &self.parentID) }() 100 | case 3: try { try decoder.decodeSingularUInt64Field(value: &self.height) }() 101 | case 4: try { try decoder.decodeSingularMessageField(value: &self._timestamp) }() 102 | case 5: try { try decoder.decodeSingularBytesField(value: &self.payloadHash) }() 103 | case 6: try { try decoder.decodeSingularUInt64Field(value: &self.view) }() 104 | case 7: try { try decoder.decodeRepeatedBytesField(value: &self.parentVoterIds) }() 105 | case 8: try { try decoder.decodeSingularBytesField(value: &self.parentVoterSigData) }() 106 | case 9: try { try decoder.decodeSingularBytesField(value: &self.proposerID) }() 107 | case 10: try { try decoder.decodeSingularBytesField(value: &self.proposerSigData) }() 108 | case 11: try { try decoder.decodeSingularStringField(value: &self.chainID) }() 109 | case 12: try { try decoder.decodeSingularBytesField(value: &self.parentVoterIndices) }() 110 | default: break 111 | } 112 | } 113 | } 114 | 115 | public func traverse(visitor: inout V) throws { 116 | // The use of inline closures is to circumvent an issue where the compiler 117 | // allocates stack space for every if/case branch local when no optimizations 118 | // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and 119 | // https://github.com/apple/swift-protobuf/issues/1182 120 | if !self.id.isEmpty { 121 | try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) 122 | } 123 | if !self.parentID.isEmpty { 124 | try visitor.visitSingularBytesField(value: self.parentID, fieldNumber: 2) 125 | } 126 | if self.height != 0 { 127 | try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 3) 128 | } 129 | try { if let v = self._timestamp { 130 | try visitor.visitSingularMessageField(value: v, fieldNumber: 4) 131 | } }() 132 | if !self.payloadHash.isEmpty { 133 | try visitor.visitSingularBytesField(value: self.payloadHash, fieldNumber: 5) 134 | } 135 | if self.view != 0 { 136 | try visitor.visitSingularUInt64Field(value: self.view, fieldNumber: 6) 137 | } 138 | if !self.parentVoterIds.isEmpty { 139 | try visitor.visitRepeatedBytesField(value: self.parentVoterIds, fieldNumber: 7) 140 | } 141 | if !self.parentVoterSigData.isEmpty { 142 | try visitor.visitSingularBytesField(value: self.parentVoterSigData, fieldNumber: 8) 143 | } 144 | if !self.proposerID.isEmpty { 145 | try visitor.visitSingularBytesField(value: self.proposerID, fieldNumber: 9) 146 | } 147 | if !self.proposerSigData.isEmpty { 148 | try visitor.visitSingularBytesField(value: self.proposerSigData, fieldNumber: 10) 149 | } 150 | if !self.chainID.isEmpty { 151 | try visitor.visitSingularStringField(value: self.chainID, fieldNumber: 11) 152 | } 153 | if !self.parentVoterIndices.isEmpty { 154 | try visitor.visitSingularBytesField(value: self.parentVoterIndices, fieldNumber: 12) 155 | } 156 | try unknownFields.traverse(visitor: &visitor) 157 | } 158 | 159 | public static func ==(lhs: Flow_Entities_BlockHeader, rhs: Flow_Entities_BlockHeader) -> Bool { 160 | if lhs.id != rhs.id {return false} 161 | if lhs.parentID != rhs.parentID {return false} 162 | if lhs.height != rhs.height {return false} 163 | if lhs._timestamp != rhs._timestamp {return false} 164 | if lhs.payloadHash != rhs.payloadHash {return false} 165 | if lhs.view != rhs.view {return false} 166 | if lhs.parentVoterIds != rhs.parentVoterIds {return false} 167 | if lhs.parentVoterSigData != rhs.parentVoterSigData {return false} 168 | if lhs.proposerID != rhs.proposerID {return false} 169 | if lhs.proposerSigData != rhs.proposerSigData {return false} 170 | if lhs.chainID != rhs.chainID {return false} 171 | if lhs.parentVoterIndices != rhs.parentVoterIndices {return false} 172 | if lhs.unknownFields != rhs.unknownFields {return false} 173 | return true 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/block_seal.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/block_seal.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_BlockSeal { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var blockID: Data = Data() 29 | 30 | public var executionReceiptID: Data = Data() 31 | 32 | public var executionReceiptSignatures: [Data] = [] 33 | 34 | public var resultApprovalSignatures: [Data] = [] 35 | 36 | public var finalState: Data = Data() 37 | 38 | public var resultID: Data = Data() 39 | 40 | public var aggregatedApprovalSigs: [Flow_Entities_AggregatedSignature] = [] 41 | 42 | public var unknownFields = SwiftProtobuf.UnknownStorage() 43 | 44 | public init() {} 45 | } 46 | 47 | public struct Flow_Entities_AggregatedSignature { 48 | // SwiftProtobuf.Message conformance is added in an extension below. See the 49 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 50 | // methods supported on all messages. 51 | 52 | public var verifierSignatures: [Data] = [] 53 | 54 | public var signerIds: [Data] = [] 55 | 56 | public var unknownFields = SwiftProtobuf.UnknownStorage() 57 | 58 | public init() {} 59 | } 60 | 61 | #if swift(>=5.5) && canImport(_Concurrency) 62 | extension Flow_Entities_BlockSeal: @unchecked Sendable {} 63 | extension Flow_Entities_AggregatedSignature: @unchecked Sendable {} 64 | #endif // swift(>=5.5) && canImport(_Concurrency) 65 | 66 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 67 | 68 | fileprivate let _protobuf_package = "flow.entities" 69 | 70 | extension Flow_Entities_BlockSeal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 71 | public static let protoMessageName: String = _protobuf_package + ".BlockSeal" 72 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 73 | 1: .standard(proto: "block_id"), 74 | 2: .standard(proto: "execution_receipt_id"), 75 | 3: .standard(proto: "execution_receipt_signatures"), 76 | 4: .standard(proto: "result_approval_signatures"), 77 | 5: .standard(proto: "final_state"), 78 | 6: .standard(proto: "result_id"), 79 | 7: .standard(proto: "aggregated_approval_sigs"), 80 | ] 81 | 82 | public mutating func decodeMessage(decoder: inout D) throws { 83 | while let fieldNumber = try decoder.nextFieldNumber() { 84 | // The use of inline closures is to circumvent an issue where the compiler 85 | // allocates stack space for every case branch when no optimizations are 86 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 87 | switch fieldNumber { 88 | case 1: try { try decoder.decodeSingularBytesField(value: &self.blockID) }() 89 | case 2: try { try decoder.decodeSingularBytesField(value: &self.executionReceiptID) }() 90 | case 3: try { try decoder.decodeRepeatedBytesField(value: &self.executionReceiptSignatures) }() 91 | case 4: try { try decoder.decodeRepeatedBytesField(value: &self.resultApprovalSignatures) }() 92 | case 5: try { try decoder.decodeSingularBytesField(value: &self.finalState) }() 93 | case 6: try { try decoder.decodeSingularBytesField(value: &self.resultID) }() 94 | case 7: try { try decoder.decodeRepeatedMessageField(value: &self.aggregatedApprovalSigs) }() 95 | default: break 96 | } 97 | } 98 | } 99 | 100 | public func traverse(visitor: inout V) throws { 101 | if !self.blockID.isEmpty { 102 | try visitor.visitSingularBytesField(value: self.blockID, fieldNumber: 1) 103 | } 104 | if !self.executionReceiptID.isEmpty { 105 | try visitor.visitSingularBytesField(value: self.executionReceiptID, fieldNumber: 2) 106 | } 107 | if !self.executionReceiptSignatures.isEmpty { 108 | try visitor.visitRepeatedBytesField(value: self.executionReceiptSignatures, fieldNumber: 3) 109 | } 110 | if !self.resultApprovalSignatures.isEmpty { 111 | try visitor.visitRepeatedBytesField(value: self.resultApprovalSignatures, fieldNumber: 4) 112 | } 113 | if !self.finalState.isEmpty { 114 | try visitor.visitSingularBytesField(value: self.finalState, fieldNumber: 5) 115 | } 116 | if !self.resultID.isEmpty { 117 | try visitor.visitSingularBytesField(value: self.resultID, fieldNumber: 6) 118 | } 119 | if !self.aggregatedApprovalSigs.isEmpty { 120 | try visitor.visitRepeatedMessageField(value: self.aggregatedApprovalSigs, fieldNumber: 7) 121 | } 122 | try unknownFields.traverse(visitor: &visitor) 123 | } 124 | 125 | public static func ==(lhs: Flow_Entities_BlockSeal, rhs: Flow_Entities_BlockSeal) -> Bool { 126 | if lhs.blockID != rhs.blockID {return false} 127 | if lhs.executionReceiptID != rhs.executionReceiptID {return false} 128 | if lhs.executionReceiptSignatures != rhs.executionReceiptSignatures {return false} 129 | if lhs.resultApprovalSignatures != rhs.resultApprovalSignatures {return false} 130 | if lhs.finalState != rhs.finalState {return false} 131 | if lhs.resultID != rhs.resultID {return false} 132 | if lhs.aggregatedApprovalSigs != rhs.aggregatedApprovalSigs {return false} 133 | if lhs.unknownFields != rhs.unknownFields {return false} 134 | return true 135 | } 136 | } 137 | 138 | extension Flow_Entities_AggregatedSignature: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 139 | public static let protoMessageName: String = _protobuf_package + ".AggregatedSignature" 140 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 141 | 1: .standard(proto: "verifier_signatures"), 142 | 2: .standard(proto: "signer_ids"), 143 | ] 144 | 145 | public mutating func decodeMessage(decoder: inout D) throws { 146 | while let fieldNumber = try decoder.nextFieldNumber() { 147 | // The use of inline closures is to circumvent an issue where the compiler 148 | // allocates stack space for every case branch when no optimizations are 149 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 150 | switch fieldNumber { 151 | case 1: try { try decoder.decodeRepeatedBytesField(value: &self.verifierSignatures) }() 152 | case 2: try { try decoder.decodeRepeatedBytesField(value: &self.signerIds) }() 153 | default: break 154 | } 155 | } 156 | } 157 | 158 | public func traverse(visitor: inout V) throws { 159 | if !self.verifierSignatures.isEmpty { 160 | try visitor.visitRepeatedBytesField(value: self.verifierSignatures, fieldNumber: 1) 161 | } 162 | if !self.signerIds.isEmpty { 163 | try visitor.visitRepeatedBytesField(value: self.signerIds, fieldNumber: 2) 164 | } 165 | try unknownFields.traverse(visitor: &visitor) 166 | } 167 | 168 | public static func ==(lhs: Flow_Entities_AggregatedSignature, rhs: Flow_Entities_AggregatedSignature) -> Bool { 169 | if lhs.verifierSignatures != rhs.verifierSignatures {return false} 170 | if lhs.signerIds != rhs.signerIds {return false} 171 | if lhs.unknownFields != rhs.unknownFields {return false} 172 | return true 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/collection.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/collection.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_Collection { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var id: Data = Data() 29 | 30 | public var transactionIds: [Data] = [] 31 | 32 | public var unknownFields = SwiftProtobuf.UnknownStorage() 33 | 34 | public init() {} 35 | } 36 | 37 | public struct Flow_Entities_CollectionGuarantee { 38 | // SwiftProtobuf.Message conformance is added in an extension below. See the 39 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 40 | // methods supported on all messages. 41 | 42 | public var collectionID: Data = Data() 43 | 44 | public var signatures: [Data] = [] 45 | 46 | public var referenceBlockID: Data = Data() 47 | 48 | public var signature: Data = Data() 49 | 50 | /// deprecated!! value will be empty. replaced by signer_indices 51 | public var signerIds: [Data] = [] 52 | 53 | public var signerIndices: Data = Data() 54 | 55 | public var unknownFields = SwiftProtobuf.UnknownStorage() 56 | 57 | public init() {} 58 | } 59 | 60 | #if swift(>=5.5) && canImport(_Concurrency) 61 | extension Flow_Entities_Collection: @unchecked Sendable {} 62 | extension Flow_Entities_CollectionGuarantee: @unchecked Sendable {} 63 | #endif // swift(>=5.5) && canImport(_Concurrency) 64 | 65 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 66 | 67 | fileprivate let _protobuf_package = "flow.entities" 68 | 69 | extension Flow_Entities_Collection: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 70 | public static let protoMessageName: String = _protobuf_package + ".Collection" 71 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 72 | 1: .same(proto: "id"), 73 | 2: .standard(proto: "transaction_ids"), 74 | ] 75 | 76 | public mutating func decodeMessage(decoder: inout D) throws { 77 | while let fieldNumber = try decoder.nextFieldNumber() { 78 | // The use of inline closures is to circumvent an issue where the compiler 79 | // allocates stack space for every case branch when no optimizations are 80 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 81 | switch fieldNumber { 82 | case 1: try { try decoder.decodeSingularBytesField(value: &self.id) }() 83 | case 2: try { try decoder.decodeRepeatedBytesField(value: &self.transactionIds) }() 84 | default: break 85 | } 86 | } 87 | } 88 | 89 | public func traverse(visitor: inout V) throws { 90 | if !self.id.isEmpty { 91 | try visitor.visitSingularBytesField(value: self.id, fieldNumber: 1) 92 | } 93 | if !self.transactionIds.isEmpty { 94 | try visitor.visitRepeatedBytesField(value: self.transactionIds, fieldNumber: 2) 95 | } 96 | try unknownFields.traverse(visitor: &visitor) 97 | } 98 | 99 | public static func ==(lhs: Flow_Entities_Collection, rhs: Flow_Entities_Collection) -> Bool { 100 | if lhs.id != rhs.id {return false} 101 | if lhs.transactionIds != rhs.transactionIds {return false} 102 | if lhs.unknownFields != rhs.unknownFields {return false} 103 | return true 104 | } 105 | } 106 | 107 | extension Flow_Entities_CollectionGuarantee: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 108 | public static let protoMessageName: String = _protobuf_package + ".CollectionGuarantee" 109 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 110 | 1: .standard(proto: "collection_id"), 111 | 2: .same(proto: "signatures"), 112 | 3: .standard(proto: "reference_block_id"), 113 | 4: .same(proto: "signature"), 114 | 5: .standard(proto: "signer_ids"), 115 | 6: .standard(proto: "signer_indices"), 116 | ] 117 | 118 | public mutating func decodeMessage(decoder: inout D) throws { 119 | while let fieldNumber = try decoder.nextFieldNumber() { 120 | // The use of inline closures is to circumvent an issue where the compiler 121 | // allocates stack space for every case branch when no optimizations are 122 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 123 | switch fieldNumber { 124 | case 1: try { try decoder.decodeSingularBytesField(value: &self.collectionID) }() 125 | case 2: try { try decoder.decodeRepeatedBytesField(value: &self.signatures) }() 126 | case 3: try { try decoder.decodeSingularBytesField(value: &self.referenceBlockID) }() 127 | case 4: try { try decoder.decodeSingularBytesField(value: &self.signature) }() 128 | case 5: try { try decoder.decodeRepeatedBytesField(value: &self.signerIds) }() 129 | case 6: try { try decoder.decodeSingularBytesField(value: &self.signerIndices) }() 130 | default: break 131 | } 132 | } 133 | } 134 | 135 | public func traverse(visitor: inout V) throws { 136 | if !self.collectionID.isEmpty { 137 | try visitor.visitSingularBytesField(value: self.collectionID, fieldNumber: 1) 138 | } 139 | if !self.signatures.isEmpty { 140 | try visitor.visitRepeatedBytesField(value: self.signatures, fieldNumber: 2) 141 | } 142 | if !self.referenceBlockID.isEmpty { 143 | try visitor.visitSingularBytesField(value: self.referenceBlockID, fieldNumber: 3) 144 | } 145 | if !self.signature.isEmpty { 146 | try visitor.visitSingularBytesField(value: self.signature, fieldNumber: 4) 147 | } 148 | if !self.signerIds.isEmpty { 149 | try visitor.visitRepeatedBytesField(value: self.signerIds, fieldNumber: 5) 150 | } 151 | if !self.signerIndices.isEmpty { 152 | try visitor.visitSingularBytesField(value: self.signerIndices, fieldNumber: 6) 153 | } 154 | try unknownFields.traverse(visitor: &visitor) 155 | } 156 | 157 | public static func ==(lhs: Flow_Entities_CollectionGuarantee, rhs: Flow_Entities_CollectionGuarantee) -> Bool { 158 | if lhs.collectionID != rhs.collectionID {return false} 159 | if lhs.signatures != rhs.signatures {return false} 160 | if lhs.referenceBlockID != rhs.referenceBlockID {return false} 161 | if lhs.signature != rhs.signature {return false} 162 | if lhs.signerIds != rhs.signerIds {return false} 163 | if lhs.signerIndices != rhs.signerIndices {return false} 164 | if lhs.unknownFields != rhs.unknownFields {return false} 165 | return true 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /Sources/FlowSDK/Protobuf/Generated/flow/entities/event.pb.swift: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. 2 | // swift-format-ignore-file 3 | // 4 | // Generated by the Swift generator plugin for the protocol buffer compiler. 5 | // Source: flow/entities/event.proto 6 | // 7 | // For information on using the generated types, please see the documentation: 8 | // https://github.com/apple/swift-protobuf/ 9 | 10 | import Foundation 11 | import SwiftProtobuf 12 | 13 | // If the compiler emits an error on this type, it is because this file 14 | // was generated by a version of the `protoc` Swift plug-in that is 15 | // incompatible with the version of SwiftProtobuf to which you are linking. 16 | // Please ensure that you are building against the same version of the API 17 | // that was used to generate this file. 18 | fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { 19 | struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} 20 | typealias Version = _2 21 | } 22 | 23 | public struct Flow_Entities_Event { 24 | // SwiftProtobuf.Message conformance is added in an extension below. See the 25 | // `Message` and `Message+*Additions` files in the SwiftProtobuf library for 26 | // methods supported on all messages. 27 | 28 | public var type: String = String() 29 | 30 | public var transactionID: Data = Data() 31 | 32 | public var transactionIndex: UInt32 = 0 33 | 34 | public var eventIndex: UInt32 = 0 35 | 36 | public var payload: Data = Data() 37 | 38 | public var unknownFields = SwiftProtobuf.UnknownStorage() 39 | 40 | public init() {} 41 | } 42 | 43 | #if swift(>=5.5) && canImport(_Concurrency) 44 | extension Flow_Entities_Event: @unchecked Sendable {} 45 | #endif // swift(>=5.5) && canImport(_Concurrency) 46 | 47 | // MARK: - Code below here is support for the SwiftProtobuf runtime. 48 | 49 | fileprivate let _protobuf_package = "flow.entities" 50 | 51 | extension Flow_Entities_Event: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { 52 | public static let protoMessageName: String = _protobuf_package + ".Event" 53 | public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 54 | 1: .same(proto: "type"), 55 | 2: .standard(proto: "transaction_id"), 56 | 3: .standard(proto: "transaction_index"), 57 | 4: .standard(proto: "event_index"), 58 | 5: .same(proto: "payload"), 59 | ] 60 | 61 | public mutating func decodeMessage(decoder: inout D) throws { 62 | while let fieldNumber = try decoder.nextFieldNumber() { 63 | // The use of inline closures is to circumvent an issue where the compiler 64 | // allocates stack space for every case branch when no optimizations are 65 | // enabled. https://github.com/apple/swift-protobuf/issues/1034 66 | switch fieldNumber { 67 | case 1: try { try decoder.decodeSingularStringField(value: &self.type) }() 68 | case 2: try { try decoder.decodeSingularBytesField(value: &self.transactionID) }() 69 | case 3: try { try decoder.decodeSingularUInt32Field(value: &self.transactionIndex) }() 70 | case 4: try { try decoder.decodeSingularUInt32Field(value: &self.eventIndex) }() 71 | case 5: try { try decoder.decodeSingularBytesField(value: &self.payload) }() 72 | default: break 73 | } 74 | } 75 | } 76 | 77 | public func traverse(visitor: inout V) throws { 78 | if !self.type.isEmpty { 79 | try visitor.visitSingularStringField(value: self.type, fieldNumber: 1) 80 | } 81 | if !self.transactionID.isEmpty { 82 | try visitor.visitSingularBytesField(value: self.transactionID, fieldNumber: 2) 83 | } 84 | if self.transactionIndex != 0 { 85 | try visitor.visitSingularUInt32Field(value: self.transactionIndex, fieldNumber: 3) 86 | } 87 | if self.eventIndex != 0 { 88 | try visitor.visitSingularUInt32Field(value: self.eventIndex, fieldNumber: 4) 89 | } 90 | if !self.payload.isEmpty { 91 | try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 5) 92 | } 93 | try unknownFields.traverse(visitor: &visitor) 94 | } 95 | 96 | public static func ==(lhs: Flow_Entities_Event, rhs: Flow_Entities_Event) -> Bool { 97 | if lhs.type != rhs.type {return false} 98 | if lhs.transactionID != rhs.transactionID {return false} 99 | if lhs.transactionIndex != rhs.transactionIndex {return false} 100 | if lhs.eventIndex != rhs.eventIndex {return false} 101 | if lhs.payload != rhs.payload {return false} 102 | if lhs.unknownFields != rhs.unknownFields {return false} 103 | return true 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPDecodable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RLPDecodable.swift 3 | // 4 | // Created by Scott on 2022/8/5. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BigInt 10 | 11 | public protocol RLPDecodable { 12 | init(rlpItem: RLPItem) throws 13 | } 14 | 15 | // MARK: - Data 16 | 17 | extension Data: RLPDecodable { 18 | 19 | public init(rlpItem: RLPItem) throws { 20 | switch rlpItem { 21 | case .empty: 22 | self = Data() 23 | case let .data(data): 24 | self = data 25 | case .list: 26 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 27 | } 28 | } 29 | 30 | } 31 | 32 | // MARK: - Unsigned Integer 33 | 34 | extension UInt: RLPDecodable { 35 | 36 | public init(rlpItem: RLPItem) throws { 37 | self = UInt(try BigUInt(rlpItem: rlpItem)) 38 | } 39 | } 40 | 41 | extension UInt8: RLPDecodable { 42 | 43 | public init(rlpItem: RLPItem) throws { 44 | self = UInt8(try BigUInt(rlpItem: rlpItem)) 45 | } 46 | } 47 | 48 | extension UInt16: RLPDecodable { 49 | 50 | public init(rlpItem: RLPItem) throws { 51 | self = UInt16(try BigUInt(rlpItem: rlpItem)) 52 | } 53 | } 54 | 55 | extension UInt32: RLPDecodable { 56 | 57 | public init(rlpItem: RLPItem) throws { 58 | self = UInt32(try BigUInt(rlpItem: rlpItem)) 59 | } 60 | } 61 | 62 | extension UInt64: RLPDecodable { 63 | 64 | public init(rlpItem: RLPItem) throws { 65 | self = UInt64(try BigUInt(rlpItem: rlpItem)) 66 | } 67 | } 68 | 69 | extension BigUInt: RLPDecodable { 70 | 71 | public init(rlpItem: RLPItem) throws { 72 | switch rlpItem { 73 | case .empty, .list: 74 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 75 | case let .data(data): 76 | self = BigUInt(data) 77 | } 78 | } 79 | } 80 | 81 | // MARK: - String 82 | 83 | extension String: RLPDecodable { 84 | 85 | public init(rlpItem: RLPItem) throws { 86 | switch rlpItem { 87 | case .empty, .list: 88 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 89 | case let .data(data): 90 | self = String(data: data, encoding: .utf8) ?? "" 91 | } 92 | } 93 | } 94 | 95 | // MARK: - Bool 96 | 97 | extension Bool: RLPDecodable { 98 | 99 | public init(rlpItem: RLPItem) throws { 100 | switch rlpItem { 101 | case .empty, .list: 102 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 103 | case let .data(data): 104 | switch data.count { 105 | case 0: 106 | self = false 107 | case 1: 108 | self = (data[0] == 1) 109 | default: 110 | throw RLPDecodingError.invalidType(rlpItem, type: Self.self) 111 | } 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPDecoder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RLPDecoder.swift 3 | // 4 | // Created by Scott on 2022/8/6. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BigInt 10 | 11 | final public class RLPDecoder { 12 | 13 | public init() { } 14 | 15 | public func decodeRLPData(_ data: Data) throws -> RLPItem { 16 | try decodeRLPData(data, isList: false) 17 | } 18 | 19 | private func decodeRLPData(_ data: Data, isList: Bool) throws -> RLPItem { 20 | if data.count == 0 { 21 | if isList { 22 | return .list([]) 23 | } else { 24 | return .empty 25 | } 26 | } 27 | 28 | var finalItems = [RLPItem]() 29 | var currentData = Data(data) 30 | while currentData.count != 0 { 31 | let (offset, dataLength, type) = try decodeLength(currentData) 32 | switch type { 33 | case .empty: 34 | break 35 | case .data: 36 | let slice = try slice( 37 | data: currentData, 38 | offset: offset, 39 | length: dataLength) 40 | let data = Data(slice) 41 | finalItems.append(.data(data)) 42 | case .list: 43 | let slice = try slice( 44 | data: currentData, 45 | offset: offset, 46 | length: dataLength) 47 | let list = try decodeRLPData(Data(slice), isList: true) 48 | finalItems.append(list) 49 | } 50 | currentData = sliceRest( 51 | data: currentData, 52 | start: offset + dataLength) 53 | } 54 | if isList { 55 | return RLPItem.list(finalItems) 56 | } else { 57 | guard finalItems.count == 1 else { 58 | throw RLPDecodingError.invalidFormat 59 | } 60 | return finalItems[0] 61 | } 62 | } 63 | 64 | private func decodeLength(_ input: Data) throws -> (offset: BigUInt, length: BigUInt, type: RLPItemType) { 65 | let length = BigUInt(input.count) 66 | if (length == BigUInt(0)) { 67 | return (0, 0, .empty) 68 | } 69 | let prefixByte = input[0] 70 | if prefixByte <= 0x7f { 71 | return (0, 1, .data) 72 | } else if prefixByte <= 0xb7 && length > BigUInt(prefixByte - 0x80) { 73 | let dataLength = BigUInt(prefixByte - 0x80) 74 | return (1, dataLength, .data) 75 | } else if try prefixByte <= 0xbf && length > BigUInt(prefixByte - 0xb7) && length > BigUInt(prefixByte - 0xb7) + toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xb7))) { 76 | let lengthOfLength = BigUInt(prefixByte - 0xb7) 77 | let dataLength = try toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xb7))) 78 | return (1 + lengthOfLength, dataLength, .data) 79 | } else if prefixByte <= 0xf7 && length > BigUInt(prefixByte - 0xc0) { 80 | let listLen = BigUInt(prefixByte - 0xc0) 81 | return (1, listLen, .list) 82 | } else if try prefixByte <= 0xff && length > BigUInt(prefixByte - 0xf7) && length > BigUInt(prefixByte - 0xf7) + toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xf7))) { 83 | let lengthOfListLength = BigUInt(prefixByte - 0xf7) 84 | let listLength = try toBigUInt(slice(data: input, offset: BigUInt(1), length: BigUInt(prefixByte - 0xf7))) 85 | return (1 + lengthOfListLength, listLength, .list) 86 | } else { 87 | throw RLPDecodingError.invalidFormat 88 | } 89 | } 90 | 91 | private func slice(data: Data, offset: BigUInt, length: BigUInt) throws -> Data { 92 | if BigUInt(data.count) < offset + length { 93 | throw RLPDecodingError.invalidFormat 94 | } 95 | let slice = data[UInt64(offset) ..< UInt64(offset + length)] 96 | return Data(slice) 97 | } 98 | 99 | private func sliceRest(data: Data, start: BigUInt) -> Data { 100 | if BigUInt(data.count) < start { 101 | return Data() 102 | } else { 103 | let slice = data[UInt64(start) ..< UInt64(data.count)] 104 | return Data(slice) 105 | } 106 | } 107 | 108 | private func toBigUInt(_ data: Data) throws -> BigUInt { 109 | if data.count == 0 { 110 | throw RLPDecodingError.invalidFormat 111 | } else if data.count == 1 { 112 | return BigUInt.init(data) 113 | } else { 114 | let slice = data[0 ..< data.count - 1] 115 | return try BigUInt(data[data.count-1]) + toBigUInt(slice)*256 116 | } 117 | } 118 | 119 | } 120 | 121 | private enum RLPItemType { 122 | case empty 123 | case data 124 | case list 125 | } 126 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPDecodingError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RLPDecodingError.swift 3 | // 4 | // Created by Scott on 2022/8/6. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum RLPDecodingError: Swift.Error { 11 | case invalidFormat 12 | case invalidType(RLPItem, type: Any.Type) 13 | case notListType 14 | } 15 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPEncodable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RLPEncodable.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BigInt 10 | 11 | public protocol RLPEncodable { 12 | var rlpData: Data { get } 13 | } 14 | 15 | extension RLPEncodable { 16 | 17 | fileprivate func encodeLength(_ length: UInt64, offset: UInt8) -> Data { 18 | if length < 56 { 19 | return Data([UInt8(length) + offset]) 20 | } else { 21 | let binaryData = length.bigEndianBinaryData 22 | return Data([UInt8(binaryData.count) + offset + 55]) + binaryData 23 | } 24 | } 25 | } 26 | 27 | // MARK: - RLPEncoableArray 28 | 29 | public typealias RLPEncoableArray = [RLPEncodable] 30 | 31 | extension RLPEncoableArray: RLPEncodable { 32 | 33 | public var rlpData: Data { 34 | get { 35 | var output = Data() 36 | for value in self { 37 | output += value.rlpData 38 | } 39 | return encodeLength(UInt64(output.count), offset: 0xc0) + output 40 | } 41 | } 42 | } 43 | 44 | // MARK: - Data 45 | 46 | extension Data: RLPEncodable { 47 | 48 | public var rlpData: Data { 49 | if count == 1 && self[0] <= 0x7f { 50 | return self 51 | } else { 52 | var output = encodeLength(UInt64(count), offset: 0x80) 53 | output.append(self) 54 | return output 55 | } 56 | } 57 | } 58 | 59 | // MARK: - Unsigned Integer 60 | 61 | extension UInt: RLPEncodable { 62 | 63 | public var rlpData: Data { 64 | BigUInt(self).rlpData 65 | } 66 | } 67 | 68 | extension UInt8: RLPEncodable { 69 | 70 | public var rlpData: Data { 71 | BigUInt(self).rlpData 72 | } 73 | } 74 | 75 | extension UInt16: RLPEncodable { 76 | 77 | public var rlpData: Data { 78 | BigUInt(self).rlpData 79 | } 80 | } 81 | 82 | extension UInt32: RLPEncodable { 83 | 84 | public var rlpData: Data { 85 | BigUInt(self).rlpData 86 | } 87 | } 88 | 89 | extension UInt64: RLPEncodable { 90 | 91 | public var rlpData: Data { 92 | BigUInt(self).rlpData 93 | } 94 | } 95 | 96 | extension BigUInt: RLPEncodable { 97 | 98 | public var rlpData: Data { 99 | serialize().rlpData 100 | } 101 | } 102 | 103 | // MARK: - String 104 | 105 | extension String: RLPEncodable { 106 | 107 | public var rlpData: Data { 108 | (data(using: .utf8) ?? Data()).rlpData 109 | } 110 | } 111 | 112 | // MARK: - Bool 113 | 114 | extension Bool: RLPEncodable { 115 | 116 | public var rlpData: Data { 117 | ((self ? 1 : 0) as UInt).rlpData 118 | } 119 | } 120 | 121 | // MARK: - Private 122 | 123 | private extension UInt64 { 124 | 125 | var bigEndianBinaryData: Data { 126 | var value = self 127 | let bytes: [UInt8] = withUnsafeBytes(of: &value) { Array($0) }.reversed() 128 | if let index = bytes.firstIndex(where: { $0 != 0x0 }) { 129 | return Data(bytes[index...]) 130 | } else { 131 | return Data([0]) 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPEncodableList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public protocol RLPEncodableList { 11 | var rlpList: RLPEncoableArray { get } 12 | } 13 | -------------------------------------------------------------------------------- /Sources/FlowSDK/RLP/RLPItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RLPItem.swift 3 | // 4 | // Created by Scott on 2022/8/6. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum RLPItem: Equatable { 11 | case empty 12 | case data(Data) 13 | indirect case list([RLPItem]) 14 | 15 | public func getListItems() throws -> [RLPItem] { 16 | switch self { 17 | case .empty, .data: 18 | throw RLPDecodingError.notListType 19 | case let .list(items): 20 | return items 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/CadenceTests/AddressTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressTests.swift 3 | // 4 | // Created by Scott on 2022/5/22. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | import Cadence 10 | 11 | final class AddressTests: XCTestCase { 12 | 13 | func testHexToAddress() throws { 14 | XCTAssertEqual( 15 | Address(hexString: "123").data, 16 | Data([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x23])) 17 | XCTAssertEqual( 18 | Address(hexString: "1").data, 19 | Data([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1])) 20 | XCTAssertEqual( 21 | Address(hexString: "01").data, 22 | Data([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1])) 23 | } 24 | 25 | func testCodable() throws { 26 | // Arrange 27 | let address = Address(hexString: "0xe242ccfb4b8ea3e2") 28 | let decoder = JSONDecoder() 29 | let encoder = JSONEncoder() 30 | 31 | // Act 32 | let result = try decoder.decode( 33 | Address.self, 34 | from: try encoder.encode(address)) 35 | 36 | // Assert 37 | XCTAssertEqual(address, result) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/Crypto/PrivateKeyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrivateKeyTests.swift 3 | // 4 | // Created by Scott on 2022/6/5. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import FlowSDK 10 | 11 | final class PrivateKeyTests: XCTestCase { 12 | 13 | func testECDSAP256() throws { 14 | // Arrange 15 | let rawKey = Data(hex: "a7dc70afa6feae50093c87a01495cfafccac3cdadeee1f5c9e4f47a5111ae757") 16 | 17 | // Act 18 | let privateKey = try PrivateKey(data: rawKey, signatureAlgorithm: .ecdsaP256) 19 | 20 | // Assert 21 | XCTAssertEqual(privateKey.data, rawKey) 22 | let expectedPublicKey = "62f08d451022b9f4db449a04add774223c59d34b944b0eb33f20e96dbff4c33ba4efa10df35bc79e8c9cabb120c457ba28e33d13c88c65cc02bc9d70adf156da" 23 | XCTAssertEqual(privateKey.publicKey.hexString, expectedPublicKey) 24 | } 25 | 26 | func testECDSASECP256k1() throws { 27 | // Arrange 28 | let rawKey = Data(hex: "3968d37c7a6937e3cb0d8840f43710fb13b1f6f746e8650d985579d9a0e89e7b") 29 | 30 | // Act 31 | let privateKey = try PrivateKey(data: rawKey, signatureAlgorithm: .ecdsaSecp256k1) 32 | 33 | // Assert 34 | XCTAssertEqual(privateKey.data, rawKey) 35 | let expectedPublicKey = "935b03da17972da239e764b7679e14bb5c664f886f254517048fb17efa7784b6d12c68e7d741836fb48716087681d0c5a5837cf4082fb0bf0ba36bd44b5b8f64" 36 | XCTAssertEqual(privateKey.publicKey.hexString, expectedPublicKey) 37 | } 38 | 39 | func testSign() throws { 40 | // Arrange 41 | let hashAlgorithms: [HashAlgorithm] = [.sha2_256, .sha3_256] 42 | let signatureAlgorithms: [SignatureAlgorithm] = [.ecdsaP256, .ecdsaSecp256k1] 43 | let rawKey = Data(hex: "80aa5dc9cf71e401dddfecf326b646d0c6bbedc0d9ad00ccfc02c2c32a3b44fa") 44 | let message = "ABC".data(using: .utf8)! 45 | 46 | try signatureAlgorithms.forEach { signatureAlgorithm in 47 | // Arrange 48 | let privateKey = try PrivateKey(data: rawKey, signatureAlgorithm: signatureAlgorithm) 49 | 50 | try hashAlgorithms.forEach { hashAlgorithm in 51 | // Act 52 | let sigature = try privateKey.sign(message: message, hashAlgorithm: hashAlgorithm) 53 | let result = try privateKey.publicKey.verify( 54 | signature: sigature, 55 | message: message, 56 | hashAlgorithm: hashAlgorithm) 57 | 58 | // Assert 59 | XCTAssertTrue(result) 60 | 61 | // Act 62 | var fakeSignature = sigature 63 | fakeSignature[0] += 1 64 | let result2 = try privateKey.publicKey.verify( 65 | signature: fakeSignature, 66 | message: message, 67 | hashAlgorithm: hashAlgorithm) 68 | 69 | // Assert 70 | XCTAssertFalse(result2) 71 | } 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/Crypto/PublicKeyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicKeyTests.swift 3 | // 4 | // Created by Scott on 2022/6/5. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import FlowSDK 10 | 11 | final class PublicKeyTests: XCTestCase { 12 | 13 | func testECDSAP256() throws { 14 | // Arrange 15 | let hexText = "4d46d1a9f301d2eb5e7e05cfebf7abb69da67ca5056d81baeac60940349ec2f73f4b31757de1ffe66cedf0743cf78249ae63fdfa76c4f49f234e903a68dff2f6" 16 | let data = Data(hex: hexText) 17 | 18 | // Act 19 | let result = try PublicKey(data: data, signatureAlgorithm: .ecdsaP256) 20 | 21 | // Assert 22 | XCTAssertEqual(result.data, data) 23 | XCTAssertEqual(result.size, 64) 24 | XCTAssertEqual(result.algorithm, .ecdsaP256) 25 | XCTAssertEqual(result.hexString, hexText) 26 | XCTAssertEqual(result.description, hexText) 27 | } 28 | 29 | func testECDSASECP256k1() throws { 30 | // Arrange 31 | let hexText = "f0f493b8dbaee23049d456590d20e0da04e28362b0eb6ae2f29b575711e0d803ee30ce467e5d4d6c19ec39418db0ecf94b9707eee2110215b702a2b572e84218" 32 | let data = Data(hex: hexText) 33 | 34 | // Act 35 | let result = try PublicKey(data: data, signatureAlgorithm: .ecdsaSecp256k1) 36 | 37 | // Assert 38 | XCTAssertEqual(result.data, data) 39 | XCTAssertEqual(result.size, 64) 40 | XCTAssertEqual(result.algorithm, .ecdsaSecp256k1) 41 | XCTAssertEqual(result.hexString, hexText) 42 | XCTAssertEqual(result.description, hexText) 43 | } 44 | 45 | func testECDSASECP256k1WithPrefix() throws { 46 | // Arrange 47 | let hexText1 = "f0f493b8dbaee23049d456590d20e0da04e28362b0eb6ae2f29b575711e0d803ee30ce467e5d4d6c19ec39418db0ecf94b9707eee2110215b702a2b572e84218" 48 | let hexText2 = "04f0f493b8dbaee23049d456590d20e0da04e28362b0eb6ae2f29b575711e0d803ee30ce467e5d4d6c19ec39418db0ecf94b9707eee2110215b702a2b572e84218" 49 | let data1 = Data(hex: hexText1) 50 | let data2 = Data(hex: hexText2) 51 | 52 | // Act 53 | let key1 = try PublicKey(data: data1, signatureAlgorithm: .ecdsaSecp256k1) 54 | let key2 = try PublicKey(data: data2, signatureAlgorithm: .ecdsaSecp256k1) 55 | 56 | // Assert 57 | XCTAssertEqual(key1, key2) 58 | } 59 | 60 | func testECDSAP256Sha2256Verify() throws { 61 | // Arrange 62 | let message = "ABC".data(using: .utf8)! 63 | let rawKey = Data(hex: "e4784fd7cac1a5b3647119e02247c029e5c4d574943703297e23dc7bd00ab2ce25552ad544eacb956c81b02234742d5f8753165d542f3870705f585a4d93c371") 64 | let publicKey = try PublicKey( 65 | data: rawKey, 66 | signatureAlgorithm: .ecdsaP256) 67 | let signature = Data(hex: "710979fbfb6aa41b62e418f6f802a1ba8bea0a7228aab3450aab3577be3a0c07536a4b76afed839f16895e6b6225d1b2ec5faef4dda2bd1f94239fbe059bf064") 68 | 69 | // Act 70 | let result = try publicKey.verify( 71 | signature: signature, 72 | message: message, 73 | hashAlgorithm: .sha2_256) 74 | 75 | // Assert 76 | XCTAssertTrue(result) 77 | } 78 | 79 | func testECDSAP256Sha3256Verify() throws { 80 | // Arrange 81 | let message = "ABC".data(using: .utf8)! 82 | let rawKey = Data(hex: "c4ad1364dbd386316767b9efdad226d9f4bdb0d3371f6bbb02ed4444e9458110149363709b783afec9b6b39f180970d9fb79a8e0397941e02de4c25916734b1a") 83 | let publicKey = try PublicKey( 84 | data: rawKey, 85 | signatureAlgorithm: .ecdsaP256) 86 | let signature = Data(hex: "f62d6304a965df643c14de8e2f059e6cbf8051bad77b66862f7f7b108ac37dd085012e66b5f10ade34eb9f88994bb1092039749da0b5621e55083f4dcf7a3436") 87 | 88 | // Act 89 | let result = try publicKey.verify( 90 | signature: signature, 91 | message: message, 92 | hashAlgorithm: .sha3_256) 93 | 94 | // Assert 95 | XCTAssertTrue(result) 96 | } 97 | 98 | func testECDSASecp256k1Sha2256Verify() throws { 99 | // Arrange 100 | let message = "ABC".data(using: .utf8)! 101 | let rawKey = Data(hex: "ca9f859498165d504adb2ac25dcbd547e9eb32d76305c22e2f4ab52439cbd27057dd0eb34675d1fc71ec6240f7e718b9360a73c88b24f3ff67f9c7846bd87e94") 102 | let publicKey = try PublicKey( 103 | data: rawKey, 104 | signatureAlgorithm: .ecdsaSecp256k1) 105 | let signature = Data(hex: "8521e3d93705b0aa093ee032de7fbb6abf9d78376a510c77bfae1d0f7449230dd9519545d42b2ff8e060e472e96a8f412fffc0d8c54fc41cbc86e5762add088c") 106 | 107 | // Act 108 | let result = try publicKey.verify( 109 | signature: signature, 110 | message: message, 111 | hashAlgorithm: .sha2_256) 112 | 113 | // Assert 114 | XCTAssertTrue(result) 115 | } 116 | 117 | func testECDSASecp256k1Sha3256Verify() throws { 118 | // Arrange 119 | // 0xd6a7f5323ad4410e5b55d8d4450e46755a47bc82ceb0cb342c4f7b29feff9257 120 | let message = "ABC".data(using: .utf8)! 121 | let rawKey = Data(hex: "e813f199f08207784f823ea0246eb6dac7e8e61330dc3f677fda52b992dc31953b2ae7a2e5d96ab92f2dd19eba58dae7c9286f4f4e6a079fa98d3deee192a78a") 122 | let publicKey = try PublicKey( 123 | data: rawKey, 124 | signatureAlgorithm: .ecdsaSecp256k1) 125 | let signature = Data(hex: "6cfe0ce2c5bf71a187ddcd7ecb639d9477b4e37f8ee4081701540ff66fd07396a81f8b5a14cfe6df73ac1d6fcf0bf8b30c2a948bf2a8d2df87b4bc614b206483") 126 | 127 | // Act 128 | let result = try publicKey.verify( 129 | signature: signature, 130 | message: message, 131 | hashAlgorithm: .sha3_256) 132 | 133 | // Assert 134 | XCTAssertTrue(result) 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/Integration/SendScriptTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SendScriptTests.swift 3 | // 4 | // Created by Scott on 2022/7/15. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | import Cadence 10 | @testable import FlowSDK 11 | 12 | final class SendScriptTests: XCTestCase { 13 | 14 | private var client: Client! 15 | 16 | override func setUpWithError() throws { 17 | client = Client(network: .testnet) 18 | } 19 | 20 | override func tearDownWithError() throws { 21 | client = nil 22 | } 23 | 24 | func testFlowPing() async throws { 25 | try await client.ping() 26 | } 27 | 28 | func testFlowFee() async throws { 29 | // Act 30 | let result = try await client.executeScriptAtLatestBlock( 31 | script: try Utils.getTestData(name: "getFlowFees.cdc"), 32 | arguments: [] 33 | ) 34 | 35 | // Assert 36 | XCTAssertEqual(result, .struct( 37 | id: "A.912d5440f7e3769e.FlowFees.FeeParameters", 38 | fields: [ 39 | .init(name: "surgeFactor", value: .ufix64(Decimal(string: "1")!)), 40 | .init(name: "inclusionEffortCost", value: .ufix64(Decimal(string: "0.000001")!)), 41 | .init(name: "executionEffortCost", value: .ufix64(Decimal(string: "4.99049905")!)), 42 | ] 43 | )) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/Integration/SendTransactionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SendTransactionTests.swift 3 | // 4 | // Created by Scott on 2022/7/15. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | import Cadence 10 | @testable import FlowSDK 11 | 12 | final class SendTransactionTests: XCTestCase { 13 | 14 | func testCreateAccount() async throws { 15 | // Arrange 16 | let client = Client(network: .testnet) 17 | let address = Address(hexString: "0xe242ccfb4b8ea3e2") 18 | let rawKey = Data(hex: "1eb79c40023143821983dc79b4e639789ea42452e904fda719f5677a1f144208") 19 | let privateKey = try PrivateKey(data: rawKey, signatureAlgorithm: .ecdsaP256) 20 | 21 | let signer = InMemorySigner(privateKey: privateKey, hashAlgorithm: .sha2_256) 22 | guard let adminAccount = try await client.getAccountAtLatestBlock(address: address) else { 23 | XCTFail("adminAccount not found.") 24 | return 25 | } 26 | let selectedAccountKey = adminAccount.keys.first { $0.publicKey == privateKey.publicKey } 27 | guard let adminAccountKey = selectedAccountKey else { 28 | XCTFail("adminAccountKey not found.") 29 | return 30 | } 31 | let userAccountKey = AccountKey( 32 | index: -1, 33 | publicKey: privateKey.publicKey, 34 | signatureAlgorithm: .ecdsaP256, 35 | hashAlgorithm: .sha2_256, 36 | weight: 1000, 37 | sequenceNumber: 0 38 | ) 39 | guard let referenceBlock = try await client.getLatestBlock(isSealed: true) else { 40 | XCTFail("getLatestBlock is nil") 41 | return 42 | } 43 | 44 | var transaction = try Transaction( 45 | script: try Utils.getTestData(name: "createAccount.cdc"), 46 | arguments: [ 47 | userAccountKey.publicKey.cadenceArugment, 48 | userAccountKey.hashAlgorithm.cadenceArugment, 49 | .ufix64(Decimal(userAccountKey.weight)), 50 | ], 51 | referenceBlockId: referenceBlock.blockHeader.id, 52 | gasLimit: 1000, 53 | proposalKey: Transaction.ProposalKey( 54 | address: address, 55 | keyIndex: adminAccountKey.index, 56 | sequenceNumber: adminAccountKey.sequenceNumber 57 | ), 58 | payer: address, 59 | authorizers: [address] 60 | ) 61 | 62 | try transaction.signEnvelope(address: address, keyIndex: 0, signer: signer) 63 | 64 | // Act 65 | let identifier = try await client.sendTransaction(transaction: transaction) 66 | debugPrint(identifier.hexString) 67 | 68 | // Assert 69 | var result: TransactionResult? 70 | while result?.status != .sealed { 71 | result = try await client.getTransactionResult(id: identifier) 72 | sleep(5) 73 | } 74 | guard let finalResult = result else { 75 | XCTFail("result is nil") 76 | return 77 | } 78 | debugPrint(finalResult) 79 | XCTAssertNil(finalResult.errorMessage) 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/FlowToken.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | 3 | pub contract FlowToken: FungibleToken { 4 | 5 | // Total supply of Flow tokens in existence 6 | pub var totalSupply: UFix64 7 | 8 | // Event that is emitted when the contract is created 9 | pub event TokensInitialized(initialSupply: UFix64) 10 | 11 | // Event that is emitted when tokens are withdrawn from a Vault 12 | pub event TokensWithdrawn(amount: UFix64, from: Address?) 13 | 14 | // Event that is emitted when tokens are deposited to a Vault 15 | pub event TokensDeposited(amount: UFix64, to: Address?) 16 | 17 | // Event that is emitted when new tokens are minted 18 | pub event TokensMinted(amount: UFix64) 19 | 20 | // Event that is emitted when tokens are destroyed 21 | pub event TokensBurned(amount: UFix64) 22 | 23 | // Event that is emitted when a new minter resource is created 24 | pub event MinterCreated(allowedAmount: UFix64) 25 | 26 | // Event that is emitted when a new burner resource is created 27 | pub event BurnerCreated() 28 | 29 | // Vault 30 | // 31 | // Each user stores an instance of only the Vault in their storage 32 | // The functions in the Vault and governed by the pre and post conditions 33 | // in FungibleToken when they are called. 34 | // The checks happen at runtime whenever a function is called. 35 | // 36 | // Resources can only be created in the context of the contract that they 37 | // are defined in, so there is no way for a malicious user to create Vaults 38 | // out of thin air. A special Minter resource needs to be defined to mint 39 | // new tokens. 40 | // 41 | pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance { 42 | 43 | // holds the balance of a users tokens 44 | pub var balance: UFix64 45 | 46 | // initialize the balance at resource creation time 47 | init(balance: UFix64) { 48 | self.balance = balance 49 | } 50 | 51 | // withdraw 52 | // 53 | // Function that takes an integer amount as an argument 54 | // and withdraws that amount from the Vault. 55 | // It creates a new temporary Vault that is used to hold 56 | // the money that is being transferred. It returns the newly 57 | // created Vault to the context that called so it can be deposited 58 | // elsewhere. 59 | // 60 | pub fun withdraw(amount: UFix64): @FungibleToken.Vault { 61 | self.balance = self.balance - amount 62 | emit TokensWithdrawn(amount: amount, from: self.owner?.address) 63 | return <-create Vault(balance: amount) 64 | } 65 | 66 | // deposit 67 | // 68 | // Function that takes a Vault object as an argument and adds 69 | // its balance to the balance of the owners Vault. 70 | // It is allowed to destroy the sent Vault because the Vault 71 | // was a temporary holder of the tokens. The Vault's balance has 72 | // been consumed and therefore can be destroyed. 73 | pub fun deposit(from: @FungibleToken.Vault) { 74 | let vault <- from as! @FlowToken.Vault 75 | self.balance = self.balance + vault.balance 76 | emit TokensDeposited(amount: vault.balance, to: self.owner?.address) 77 | vault.balance = 0.0 78 | destroy vault 79 | } 80 | 81 | destroy() { 82 | FlowToken.totalSupply = FlowToken.totalSupply - self.balance 83 | } 84 | } 85 | 86 | // createEmptyVault 87 | // 88 | // Function that creates a new Vault with a balance of zero 89 | // and returns it to the calling context. A user must call this function 90 | // and store the returned Vault in their storage in order to allow their 91 | // account to be able to receive deposits of this token type. 92 | // 93 | pub fun createEmptyVault(): @FungibleToken.Vault { 94 | return <-create Vault(balance: 0.0) 95 | } 96 | 97 | pub resource Administrator { 98 | // createNewMinter 99 | // 100 | // Function that creates and returns a new minter resource 101 | // 102 | pub fun createNewMinter(allowedAmount: UFix64): @Minter { 103 | emit MinterCreated(allowedAmount: allowedAmount) 104 | return <-create Minter(allowedAmount: allowedAmount) 105 | } 106 | 107 | // createNewBurner 108 | // 109 | // Function that creates and returns a new burner resource 110 | // 111 | pub fun createNewBurner(): @Burner { 112 | emit BurnerCreated() 113 | return <-create Burner() 114 | } 115 | } 116 | 117 | // Minter 118 | // 119 | // Resource object that token admin accounts can hold to mint new tokens. 120 | // 121 | pub resource Minter { 122 | 123 | // the amount of tokens that the minter is allowed to mint 124 | pub var allowedAmount: UFix64 125 | 126 | // mintTokens 127 | // 128 | // Function that mints new tokens, adds them to the total supply, 129 | // and returns them to the calling context. 130 | // 131 | pub fun mintTokens(amount: UFix64): @FlowToken.Vault { 132 | pre { 133 | amount > UFix64(0): "Amount minted must be greater than zero" 134 | amount <= self.allowedAmount: "Amount minted must be less than the allowed amount" 135 | } 136 | FlowToken.totalSupply = FlowToken.totalSupply + amount 137 | self.allowedAmount = self.allowedAmount - amount 138 | emit TokensMinted(amount: amount) 139 | return <-create Vault(balance: amount) 140 | } 141 | 142 | init(allowedAmount: UFix64) { 143 | self.allowedAmount = allowedAmount 144 | } 145 | } 146 | 147 | // Burner 148 | // 149 | // Resource object that token admin accounts can hold to burn tokens. 150 | // 151 | pub resource Burner { 152 | 153 | // burnTokens 154 | // 155 | // Function that destroys a Vault instance, effectively burning the tokens. 156 | // 157 | // Note: the burned tokens are automatically subtracted from the 158 | // total supply in the Vault destructor. 159 | // 160 | pub fun burnTokens(from: @FungibleToken.Vault) { 161 | let vault <- from as! @FlowToken.Vault 162 | let amount = vault.balance 163 | destroy vault 164 | emit TokensBurned(amount: amount) 165 | } 166 | } 167 | 168 | init(adminAccount: AuthAccount) { 169 | self.totalSupply = 0.0 170 | 171 | // Create the Vault with the total supply of tokens and save it in storage 172 | // 173 | let vault <- create Vault(balance: self.totalSupply) 174 | adminAccount.save(<-vault, to: /storage/flowTokenVault) 175 | 176 | // Create a public capability to the stored Vault that only exposes 177 | // the `deposit` method through the `Receiver` interface 178 | // 179 | adminAccount.link<&FlowToken.Vault{FungibleToken.Receiver}>( 180 | /public/flowTokenReceiver, 181 | target: /storage/flowTokenVault 182 | ) 183 | 184 | // Create a public capability to the stored Vault that only exposes 185 | // the `balance` field through the `Balance` interface 186 | // 187 | adminAccount.link<&FlowToken.Vault{FungibleToken.Balance}>( 188 | /public/flowTokenBalance, 189 | target: /storage/flowTokenVault 190 | ) 191 | 192 | let admin <- create Administrator() 193 | adminAccount.save(<-admin, to: /storage/flowTokenAdmin) 194 | 195 | // Emit an event that shows that the contract was initialized 196 | emit TokensInitialized(initialSupply: self.totalSupply) 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/createAccount.cdc: -------------------------------------------------------------------------------- 1 | import Crypto 2 | 3 | transaction(publicKey: PublicKey, hashAlgorithm: HashAlgorithm, weight: UFix64) { 4 | prepare(signer: AuthAccount) { 5 | let account = AuthAccount(payer: signer) 6 | 7 | // add a key to the account 8 | account.keys.add(publicKey: publicKey, hashAlgorithm: hashAlgorithm, weight: weight) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/getFlowBalance.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import FlowToken from 0x7e60df042a9c0868 3 | 4 | pub fun main(account: Address): UFix64 { 5 | 6 | let vaultRef = getAccount(account) 7 | .getCapability(/public/flowTokenBalance) 8 | .borrow<&FlowToken.Vault{FungibleToken.Balance}>() 9 | ?? panic("Could not borrow Balance reference to the Vault") 10 | 11 | return vaultRef.balance 12 | } 13 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/getFlowFees.cdc: -------------------------------------------------------------------------------- 1 | import FlowFees from 0x912d5440f7e3769e 2 | 3 | pub fun main(): FlowFees.FeeParameters { 4 | return FlowFees.getFeeParameters() 5 | } 6 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/greetingScript.cdc: -------------------------------------------------------------------------------- 1 | transaction(greeting: String) { 2 | execute { 3 | log(greeting.concat(", World!")) 4 | } 5 | } -------------------------------------------------------------------------------- /Tests/FlowSDKTests/TestData/transferFlow.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import FlowToken from 0x7e60df042a9c0868 3 | 4 | transaction(amount: UFix64, to: Address) { 5 | 6 | // The Vault resource that holds the tokens that are being transferred 7 | let sentVault: @FungibleToken.Vault 8 | 9 | prepare(signer: AuthAccount) { 10 | 11 | // Get a reference to the signer's stored vault 12 | let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) 13 | ?? panic("Could not borrow reference to the owner's Vault!") 14 | 15 | // Withdraw tokens from the signer's stored vault 16 | self.sentVault <- vaultRef.withdraw(amount: amount) 17 | } 18 | 19 | execute { 20 | 21 | // Get the recipient's public account object 22 | let recipient = getAccount(to) 23 | 24 | // Get a reference to the recipient's Receiver 25 | let receiverRef = recipient.getCapability(/public/flowTokenReceiver) 26 | .borrow<&{FungibleToken.Receiver}>() 27 | ?? panic("Could not borrow receiver reference to the recipient's Vault") 28 | 29 | // Deposit the withdrawn tokens in the recipient's receiver 30 | receiverRef.deposit(from: <-self.sentVault) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/FlowSDKTests/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // 4 | // Created by Scott on 2022/6/30. 5 | // Copyright © 2022 portto. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | enum Utils { 11 | 12 | static func getHexData(name: String) throws -> Data { 13 | let data = try getTestData(name: name) 14 | let hexText = (String(data: data, encoding: .utf8) ?? "") 15 | .trimmingCharacters(in: .whitespacesAndNewlines) 16 | return Data(hex: hexText) 17 | } 18 | 19 | static func getTestData(name: String) throws -> Data { 20 | try getFile("TestData/\(name)") 21 | } 22 | 23 | private static func getFile(_ name: String, ext: String = "") throws -> Data { 24 | guard let url = Bundle.module.url(forResource: name, withExtension: ext) else { 25 | throw Error.fileNotFound 26 | } 27 | return try Data(contentsOf: url) 28 | } 29 | 30 | enum Error: Swift.Error { 31 | case fileNotFound 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/cocoapods/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/cocoapods/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/cocoapods/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/cocoapods/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Example 4 | // 5 | // Created by Scott on 2022/6/9. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | 12 | @StateObject private var viewModel = ViewModel() 13 | 14 | var body: some View { 15 | List { 16 | HStack { 17 | Button("ping") { 18 | Task { 19 | await viewModel.callPing() 20 | } 21 | }.foregroundColor(.green) 22 | if let ping = viewModel.ping { 23 | Text(String(ping)) 24 | } 25 | } 26 | Section { 27 | Button("getLatestBlock") { 28 | Task { 29 | await viewModel.callGetLastest() 30 | } 31 | }.foregroundColor(.green) 32 | if viewModel.latestBlockText.isEmpty == false { 33 | Text(viewModel.latestBlockText) 34 | } 35 | } 36 | Section { 37 | Button("sendTransaction") { 38 | Task { 39 | await viewModel.sendTransaction() 40 | } 41 | }.foregroundColor(.green) 42 | if viewModel.sendTransactionText.isEmpty == false { 43 | Text(viewModel.sendTransactionText) 44 | } 45 | Button("getTransaction") { 46 | Task { 47 | await viewModel.getTransaction() 48 | } 49 | }.foregroundColor(.green) 50 | if viewModel.getTransactionText.isEmpty == false { 51 | Text(viewModel.getTransactionText) 52 | } 53 | Button("getTransactionResult") { 54 | Task { 55 | await viewModel.getTransactionResult() 56 | } 57 | }.foregroundColor(.green) 58 | if viewModel.getTransactionResultText.isEmpty == false { 59 | Text(viewModel.getTransactionResultText) 60 | } 61 | } 62 | Section { 63 | Button("getAccountAtLatestBlock") { 64 | Task { 65 | await viewModel.getAccountAtLatestBlock() 66 | } 67 | }.foregroundColor(.green) 68 | if viewModel.getAccountAtLatestBlockText.isEmpty == false { 69 | Text(viewModel.getAccountAtLatestBlockText) 70 | } 71 | } 72 | Section { 73 | Button("executeScriptAtLatestBlock") { 74 | Task { 75 | await viewModel.executeScriptAtLatestBlock() 76 | } 77 | }.foregroundColor(.green) 78 | if viewModel.executeScriptAtLatestBlockText.isEmpty == false { 79 | Text(viewModel.executeScriptAtLatestBlockText) 80 | } 81 | } 82 | Section { 83 | Button("getEventsForHeightRange") { 84 | Task { 85 | await viewModel.getEventsForHeightRange() 86 | } 87 | }.foregroundColor(.green) 88 | if viewModel.getEventsForHeightRangeText.isEmpty == false { 89 | Text(viewModel.getEventsForHeightRangeText) 90 | } 91 | } 92 | Section { 93 | Button("getNetworkParameters") { 94 | Task { 95 | await viewModel.getNetworkParameters() 96 | } 97 | }.foregroundColor(.green) 98 | if viewModel.getNetworkParametersText.isEmpty == false { 99 | Text(viewModel.getNetworkParametersText) 100 | } 101 | } 102 | } 103 | } 104 | 105 | } 106 | 107 | struct ContentView_Previews: PreviewProvider { 108 | static var previews: some View { 109 | ContentView() 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/ExampleApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleApp.swift 3 | // Example 4 | // 5 | // Created by Scott on 2022/6/9. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct ExampleApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/cocoapods/Example/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // Example 4 | // 5 | // Created by Scott on 2022/7/26. 6 | // 7 | 8 | import Foundation 9 | import FlowSDK 10 | import Cadence 11 | 12 | @MainActor class ViewModel: ObservableObject { 13 | @Published var publicKeyText: String = "" 14 | @Published var ping: Bool? 15 | @Published var latestBlockText: String = "" 16 | @Published var sendTransactionText: String = "" 17 | @Published var getTransactionText: String = "" 18 | @Published var getTransactionResultText: String = "" 19 | @Published var getAccountAtLatestBlockText: String = "" 20 | @Published var executeScriptAtLatestBlockText: String = "" 21 | @Published var getEventsForHeightRangeText: String = "" 22 | @Published var getNetworkParametersText: String = "" 23 | 24 | private let client = Client(network: .testnet) 25 | private lazy var address = Address(hexString: "0x04ed751d5dda4a60") 26 | private lazy var privateKey = try! PrivateKey( 27 | data: Data(hex: "1634cab06b346fa22509c7f12d5ccbfd6f70c29b27038c9909df74e3c01843d2"), 28 | signatureAlgorithm: .ecdsaSecp256k1) 29 | 30 | func callPing() async { 31 | do { 32 | _ = try await client.ping() 33 | ping = true 34 | } catch { 35 | ping = false 36 | } 37 | } 38 | 39 | func callGetLastest() async { 40 | do { 41 | if let block = try await client.getLatestBlock(isSealed: true) { 42 | latestBlockText = "\(block)" 43 | } else { 44 | latestBlockText = "nil" 45 | } 46 | } catch { 47 | latestBlockText = "\(error)" 48 | } 49 | } 50 | 51 | func sendTransaction() async { 52 | do { 53 | guard let latestBlock = try await client.getLatestBlock(isSealed: true) else { 54 | throw Error.noLastestBlock 55 | } 56 | guard let account = try await client.getAccountAtLatestBlock(address: address) else { 57 | throw Error.noAccount 58 | } 59 | guard let accountKey = account.keys.first(where: { privateKey.publicKey == $0.publicKey }) else { 60 | throw Error.noAccountKey 61 | } 62 | 63 | let script = """ 64 | import Crypto 65 | 66 | transaction(publicKey: PublicKey, hashAlgorithm: HashAlgorithm, weight: UFix64) { 67 | prepare(signer: AuthAccount) { 68 | let account = AuthAccount(payer: signer) 69 | 70 | // add a key to the account 71 | account.keys.add(publicKey: publicKey, hashAlgorithm: hashAlgorithm, weight: weight) 72 | } 73 | } 74 | """ 75 | 76 | let newPrivateKey = try PrivateKey(signatureAlgorithm: .ecdsaP256) 77 | let signer = InMemorySigner( 78 | privateKey: privateKey, 79 | hashAlgorithm: .sha3_256) 80 | var transaction = try Transaction( 81 | script: script.data(using: .utf8) ?? Data(), 82 | arguments: [ 83 | newPrivateKey.publicKey.cadenceArugment, 84 | HashAlgorithm.sha3_256.cadenceArugment, 85 | .ufix64(1000) 86 | ], 87 | referenceBlockId: latestBlock.id, 88 | gasLimit: 100, 89 | proposalKey: .init( 90 | address: address, 91 | keyIndex: accountKey.index, 92 | sequenceNumber: accountKey.sequenceNumber), 93 | payer: address, 94 | authorizers: [address]) 95 | try transaction.signEnvelope( 96 | address: address, 97 | keyIndex: accountKey.index, 98 | signer: signer) 99 | let txId = try await client.sendTransaction(transaction: transaction) 100 | debugPrint(txId.description) 101 | sendTransactionText = "txId: \(txId.description)" 102 | } catch { 103 | sendTransactionText = "\(error)" 104 | } 105 | } 106 | 107 | func getTransaction() async { 108 | do { 109 | let id = Identifier(hexString: "54aa361b51b1895db55a4da97f682f31b54602e6ca00237c1b76db419f57c1ff") 110 | guard let transaction = try await client.getTransaction(id: id) else { 111 | throw Error.noTransaction 112 | } 113 | getTransactionText = "\(transaction)" 114 | } catch { 115 | getTransactionText = "\(error)" 116 | } 117 | } 118 | 119 | func getTransactionResult() async { 120 | do { 121 | let id = Identifier(hexString: "54aa361b51b1895db55a4da97f682f31b54602e6ca00237c1b76db419f57c1ff") 122 | let result = try await client.getTransactionResult(id: id) 123 | getTransactionResultText = "\(result)" 124 | } catch { 125 | getTransactionResultText = "\(error)" 126 | } 127 | } 128 | 129 | func getAccountAtLatestBlock() async { 130 | do { 131 | guard let account = try await client.getAccountAtLatestBlock(address: address) else { 132 | throw Error.noAccount 133 | } 134 | getAccountAtLatestBlockText = "\(account)" 135 | } catch { 136 | getAccountAtLatestBlockText = "\(error)" 137 | } 138 | } 139 | 140 | func executeScriptAtLatestBlock() async { 141 | do { 142 | let script = """ 143 | pub fun main(): UInt64 { 144 | return 1 as UInt64 145 | } 146 | """ 147 | let result = try await client.executeScriptAtLatestBlock(script: script.data(using: .utf8)!) 148 | executeScriptAtLatestBlockText = "\(result)" 149 | } catch { 150 | executeScriptAtLatestBlockText = "\(error)" 151 | } 152 | } 153 | 154 | func getEventsForHeightRange() async { 155 | do { 156 | let events = try await client.getEventsForHeightRange( 157 | eventType: "A.7e60df042a9c0868.FlowToken", startHeight: 74804668, endHeight: 74804669) 158 | getEventsForHeightRangeText = "\(events)" 159 | } catch { 160 | getEventsForHeightRangeText = "\(error)" 161 | } 162 | } 163 | 164 | func getNetworkParameters() async { 165 | do { 166 | getNetworkParametersText = try await client.getNetworkParameters() 167 | } catch { 168 | getNetworkParametersText = "\(error)" 169 | } 170 | } 171 | 172 | } 173 | 174 | // MARK: - Error 175 | 176 | extension ViewModel { 177 | 178 | enum Error: Swift.Error { 179 | case noLastestBlock 180 | case noAccount 181 | case noAccountKey 182 | case noTransaction 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /examples/cocoapods/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "cocoapods", "1.15.2" 6 | -------------------------------------------------------------------------------- /examples/cocoapods/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | activesupport (7.1.5.1) 9 | base64 10 | benchmark (>= 0.3) 11 | bigdecimal 12 | concurrent-ruby (~> 1.0, >= 1.0.2) 13 | connection_pool (>= 2.2.5) 14 | drb 15 | i18n (>= 1.6, < 2) 16 | logger (>= 1.4.2) 17 | minitest (>= 5.1) 18 | mutex_m 19 | securerandom (>= 0.3) 20 | tzinfo (~> 2.0) 21 | addressable (2.8.7) 22 | public_suffix (>= 2.0.2, < 7.0) 23 | algoliasearch (1.27.5) 24 | httpclient (~> 2.8, >= 2.8.3) 25 | json (>= 1.5.1) 26 | atomos (0.1.3) 27 | base64 (0.2.0) 28 | benchmark (0.4.0) 29 | bigdecimal (3.1.9) 30 | claide (1.1.0) 31 | cocoapods (1.15.2) 32 | addressable (~> 2.8) 33 | claide (>= 1.0.2, < 2.0) 34 | cocoapods-core (= 1.15.2) 35 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 36 | cocoapods-downloader (>= 2.1, < 3.0) 37 | cocoapods-plugins (>= 1.0.0, < 2.0) 38 | cocoapods-search (>= 1.0.0, < 2.0) 39 | cocoapods-trunk (>= 1.6.0, < 2.0) 40 | cocoapods-try (>= 1.1.0, < 2.0) 41 | colored2 (~> 3.1) 42 | escape (~> 0.0.4) 43 | fourflusher (>= 2.3.0, < 3.0) 44 | gh_inspector (~> 1.0) 45 | molinillo (~> 0.8.0) 46 | nap (~> 1.0) 47 | ruby-macho (>= 2.3.0, < 3.0) 48 | xcodeproj (>= 1.23.0, < 2.0) 49 | cocoapods-core (1.15.2) 50 | activesupport (>= 5.0, < 8) 51 | addressable (~> 2.8) 52 | algoliasearch (~> 1.0) 53 | concurrent-ruby (~> 1.1) 54 | fuzzy_match (~> 2.0.4) 55 | nap (~> 1.0) 56 | netrc (~> 0.11) 57 | public_suffix (~> 4.0) 58 | typhoeus (~> 1.0) 59 | cocoapods-deintegrate (1.0.5) 60 | cocoapods-downloader (2.1) 61 | cocoapods-plugins (1.0.0) 62 | nap 63 | cocoapods-search (1.0.1) 64 | cocoapods-trunk (1.6.0) 65 | nap (>= 0.8, < 2.0) 66 | netrc (~> 0.11) 67 | cocoapods-try (1.2.0) 68 | colored2 (3.1.2) 69 | concurrent-ruby (1.3.4) 70 | connection_pool (2.5.0) 71 | drb (2.2.1) 72 | escape (0.0.4) 73 | ethon (0.16.0) 74 | ffi (>= 1.15.0) 75 | ffi (1.17.1-arm64-darwin) 76 | fourflusher (2.3.1) 77 | fuzzy_match (2.0.4) 78 | gh_inspector (1.1.3) 79 | httpclient (2.8.3) 80 | i18n (1.14.6) 81 | concurrent-ruby (~> 1.0) 82 | json (2.9.1) 83 | logger (1.6.5) 84 | minitest (5.25.4) 85 | molinillo (0.8.0) 86 | mutex_m (0.3.0) 87 | nanaimo (0.4.0) 88 | nap (1.1.0) 89 | netrc (0.11.0) 90 | nkf (0.2.0) 91 | public_suffix (4.0.7) 92 | rexml (3.4.0) 93 | ruby-macho (2.5.1) 94 | securerandom (0.3.2) 95 | typhoeus (1.4.1) 96 | ethon (>= 0.9.0) 97 | tzinfo (2.0.6) 98 | concurrent-ruby (~> 1.0) 99 | xcodeproj (1.27.0) 100 | CFPropertyList (>= 2.3.3, < 4.0) 101 | atomos (~> 0.1.3) 102 | claide (>= 1.0.2, < 2.0) 103 | colored2 (~> 3.1) 104 | nanaimo (~> 0.4.0) 105 | rexml (>= 3.3.6, < 4.0) 106 | 107 | PLATFORMS 108 | arm64-darwin-24 109 | 110 | DEPENDENCIES 111 | cocoapods (= 1.15.2) 112 | 113 | BUNDLED WITH 114 | 2.3.4 115 | -------------------------------------------------------------------------------- /examples/cocoapods/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '13.0' 2 | 3 | target 'Example' do 4 | use_frameworks! 5 | 6 | pod 'FlowSDK', :path => '../../' 7 | pod 'Cadence', :path => '../../' 8 | end 9 | 10 | post_install do |installer| 11 | installer.generated_projects.each do |project| 12 | project.targets.each do |target| 13 | target.build_configurations.each do |config| 14 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /examples/cocoapods/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - _NIODataStructures (2.40.0) 3 | - BigInt (5.2.0) 4 | - Cadence (0.7.1): 5 | - BigInt (~> 5.2.0) 6 | - CryptoSwift (~> 1.5.1) 7 | - CGRPCZlibp (1.8.2) 8 | - CNIOAtomics (2.40.0) 9 | - CNIOBoringSSL (2.19.0) 10 | - CNIOBoringSSLShims (2.19.0): 11 | - CNIOBoringSSL (= 2.19.0) 12 | - CNIODarwin (2.40.0) 13 | - CNIOHTTPParser (2.40.0) 14 | - CNIOLinux (2.40.0) 15 | - CNIOWindows (2.40.0) 16 | - CryptoSwift (1.5.1) 17 | - FlowSDK (0.7.1): 18 | - FlowSDK/FlowSDK (= 0.7.1) 19 | - FlowSDK/FlowSDK (0.7.1): 20 | - BigInt (~> 5.2.0) 21 | - Cadence (~> 0.7.1) 22 | - CryptoSwift (~> 1.5.1) 23 | - gRPC-Swiftp (= 1.8.2) 24 | - secp256k1Swift (~> 0.7.4) 25 | - SwiftProtobuf (= 1.9.0) 26 | - gRPC-Swiftp (1.8.2): 27 | - CGRPCZlibp (= 1.8.2) 28 | - Logging (< 2.0.0, >= 1.4.0) 29 | - SwiftNIO (< 3.0.0, >= 2.32.0) 30 | - SwiftNIOExtras (< 2.0.0, >= 1.4.0) 31 | - SwiftNIOHTTP2 (< 2.0.0, >= 1.18.2) 32 | - SwiftNIOSSL (< 3.0.0, >= 2.14.0) 33 | - SwiftNIOTransportServices (< 2.0.0, >= 1.11.1) 34 | - SwiftProtobuf (< 2.0.0, >= 1.9.0) 35 | - Logging (1.4.0) 36 | - secp256k1Swift (0.7.4): 37 | - secp256k1Wrapper (~> 0.0.5) 38 | - secp256k1Wrapper (0.0.5) 39 | - SwiftNIO (2.40.0): 40 | - _NIODataStructures (= 2.40.0) 41 | - CNIOAtomics (= 2.40.0) 42 | - CNIODarwin (= 2.40.0) 43 | - CNIOLinux (= 2.40.0) 44 | - CNIOWindows (= 2.40.0) 45 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 46 | - SwiftNIOCore (= 2.40.0) 47 | - SwiftNIOEmbedded (= 2.40.0) 48 | - SwiftNIOPosix (= 2.40.0) 49 | - SwiftNIOConcurrencyHelpers (2.40.0): 50 | - CNIOAtomics (= 2.40.0) 51 | - SwiftNIOCore (2.40.0): 52 | - CNIOAtomics (= 2.40.0) 53 | - CNIOLinux (= 2.40.0) 54 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 55 | - SwiftNIOEmbedded (2.40.0): 56 | - _NIODataStructures (= 2.40.0) 57 | - CNIOAtomics (= 2.40.0) 58 | - CNIOLinux (= 2.40.0) 59 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 60 | - SwiftNIOCore (= 2.40.0) 61 | - SwiftNIOExtras (1.11.0): 62 | - _NIODataStructures (< 3, >= 2.32.0) 63 | - CNIOAtomics (< 3, >= 2.32.0) 64 | - CNIODarwin (< 3, >= 2.32.0) 65 | - CNIOLinux (< 3, >= 2.32.0) 66 | - CNIOWindows (< 3, >= 2.32.0) 67 | - SwiftNIO (< 3, >= 2.32.0) 68 | - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) 69 | - SwiftNIOCore (< 3, >= 2.32.0) 70 | - SwiftNIOEmbedded (< 3, >= 2.32.0) 71 | - SwiftNIOPosix (< 3, >= 2.32.0) 72 | - SwiftNIOFoundationCompat (2.40.0): 73 | - _NIODataStructures (= 2.40.0) 74 | - CNIOAtomics (= 2.40.0) 75 | - CNIODarwin (= 2.40.0) 76 | - CNIOLinux (= 2.40.0) 77 | - CNIOWindows (= 2.40.0) 78 | - SwiftNIO (= 2.40.0) 79 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 80 | - SwiftNIOCore (= 2.40.0) 81 | - SwiftNIOEmbedded (= 2.40.0) 82 | - SwiftNIOPosix (= 2.40.0) 83 | - SwiftNIOHPACK (1.22.0): 84 | - _NIODataStructures (< 3, >= 2.35.0) 85 | - CNIOAtomics (< 3, >= 2.35.0) 86 | - CNIODarwin (< 3, >= 2.35.0) 87 | - CNIOHTTPParser (< 3, >= 2.35.0) 88 | - CNIOLinux (< 3, >= 2.35.0) 89 | - CNIOWindows (< 3, >= 2.35.0) 90 | - SwiftNIO (< 3, >= 2.35.0) 91 | - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) 92 | - SwiftNIOCore (< 3, >= 2.35.0) 93 | - SwiftNIOEmbedded (< 3, >= 2.35.0) 94 | - SwiftNIOHTTP1 (< 3, >= 2.35.0) 95 | - SwiftNIOPosix (< 3, >= 2.35.0) 96 | - SwiftNIOHTTP1 (2.40.0): 97 | - _NIODataStructures (= 2.40.0) 98 | - CNIOAtomics (= 2.40.0) 99 | - CNIODarwin (= 2.40.0) 100 | - CNIOHTTPParser (= 2.40.0) 101 | - CNIOLinux (= 2.40.0) 102 | - CNIOWindows (= 2.40.0) 103 | - SwiftNIO (= 2.40.0) 104 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 105 | - SwiftNIOCore (= 2.40.0) 106 | - SwiftNIOEmbedded (= 2.40.0) 107 | - SwiftNIOPosix (= 2.40.0) 108 | - SwiftNIOHTTP2 (1.22.0): 109 | - _NIODataStructures (< 3, >= 2.35.0) 110 | - CNIOAtomics (< 3, >= 2.35.0) 111 | - CNIODarwin (< 3, >= 2.35.0) 112 | - CNIOHTTPParser (< 3, >= 2.35.0) 113 | - CNIOLinux (< 3, >= 2.35.0) 114 | - CNIOWindows (< 3, >= 2.35.0) 115 | - SwiftNIO (< 3, >= 2.35.0) 116 | - SwiftNIOConcurrencyHelpers (< 3, >= 2.35.0) 117 | - SwiftNIOCore (< 3, >= 2.35.0) 118 | - SwiftNIOEmbedded (< 3, >= 2.35.0) 119 | - SwiftNIOHPACK (= 1.22.0) 120 | - SwiftNIOHTTP1 (< 3, >= 2.35.0) 121 | - SwiftNIOPosix (< 3, >= 2.35.0) 122 | - SwiftNIOTLS (< 3, >= 2.35.0) 123 | - SwiftNIOPosix (2.40.0): 124 | - _NIODataStructures (= 2.40.0) 125 | - CNIOAtomics (= 2.40.0) 126 | - CNIODarwin (= 2.40.0) 127 | - CNIOLinux (= 2.40.0) 128 | - CNIOWindows (= 2.40.0) 129 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 130 | - SwiftNIOCore (= 2.40.0) 131 | - SwiftNIOSSL (2.19.0): 132 | - _NIODataStructures (< 3, >= 2.32.0) 133 | - CNIOAtomics (< 3, >= 2.32.0) 134 | - CNIOBoringSSL (= 2.19.0) 135 | - CNIOBoringSSLShims (= 2.19.0) 136 | - CNIODarwin (< 3, >= 2.32.0) 137 | - CNIOLinux (< 3, >= 2.32.0) 138 | - CNIOWindows (< 3, >= 2.32.0) 139 | - SwiftNIO (< 3, >= 2.32.0) 140 | - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) 141 | - SwiftNIOCore (< 3, >= 2.32.0) 142 | - SwiftNIOEmbedded (< 3, >= 2.32.0) 143 | - SwiftNIOPosix (< 3, >= 2.32.0) 144 | - SwiftNIOTLS (< 3, >= 2.32.0) 145 | - SwiftNIOTLS (2.40.0): 146 | - _NIODataStructures (= 2.40.0) 147 | - CNIOAtomics (= 2.40.0) 148 | - CNIODarwin (= 2.40.0) 149 | - CNIOLinux (= 2.40.0) 150 | - CNIOWindows (= 2.40.0) 151 | - SwiftNIO (= 2.40.0) 152 | - SwiftNIOConcurrencyHelpers (= 2.40.0) 153 | - SwiftNIOCore (= 2.40.0) 154 | - SwiftNIOEmbedded (= 2.40.0) 155 | - SwiftNIOPosix (= 2.40.0) 156 | - SwiftNIOTransportServices (1.12.0): 157 | - _NIODataStructures (< 3, >= 2.32.0) 158 | - CNIOAtomics (< 3, >= 2.32.0) 159 | - CNIODarwin (< 3, >= 2.32.0) 160 | - CNIOLinux (< 3, >= 2.32.0) 161 | - CNIOWindows (< 3, >= 2.32.0) 162 | - SwiftNIO (< 3, >= 2.32.0) 163 | - SwiftNIOConcurrencyHelpers (< 3, >= 2.32.0) 164 | - SwiftNIOCore (< 3, >= 2.32.0) 165 | - SwiftNIOEmbedded (< 3, >= 2.32.0) 166 | - SwiftNIOFoundationCompat (< 3, >= 2.32.0) 167 | - SwiftNIOPosix (< 3, >= 2.32.0) 168 | - SwiftNIOTLS (< 3, >= 2.32.0) 169 | - SwiftProtobuf (1.9.0) 170 | 171 | DEPENDENCIES: 172 | - Cadence (from `../../`) 173 | - FlowSDK (from `../../`) 174 | 175 | SPEC REPOS: 176 | trunk: 177 | - _NIODataStructures 178 | - BigInt 179 | - CGRPCZlibp 180 | - CNIOAtomics 181 | - CNIOBoringSSL 182 | - CNIOBoringSSLShims 183 | - CNIODarwin 184 | - CNIOHTTPParser 185 | - CNIOLinux 186 | - CNIOWindows 187 | - CryptoSwift 188 | - gRPC-Swiftp 189 | - Logging 190 | - secp256k1Swift 191 | - secp256k1Wrapper 192 | - SwiftNIO 193 | - SwiftNIOConcurrencyHelpers 194 | - SwiftNIOCore 195 | - SwiftNIOEmbedded 196 | - SwiftNIOExtras 197 | - SwiftNIOFoundationCompat 198 | - SwiftNIOHPACK 199 | - SwiftNIOHTTP1 200 | - SwiftNIOHTTP2 201 | - SwiftNIOPosix 202 | - SwiftNIOSSL 203 | - SwiftNIOTLS 204 | - SwiftNIOTransportServices 205 | - SwiftProtobuf 206 | 207 | EXTERNAL SOURCES: 208 | Cadence: 209 | :path: "../../" 210 | FlowSDK: 211 | :path: "../../" 212 | 213 | SPEC CHECKSUMS: 214 | _NIODataStructures: 3d45d8e70a1d17a15b1dc59d102c63dbc0525ffd 215 | BigInt: f668a80089607f521586bbe29513d708491ef2f7 216 | Cadence: c8a624ee9e7d517def42073a7a74b1cda9e70750 217 | CGRPCZlibp: 2f3e1e7a6d6cb481d4d1a26d3ec09aefacf09cbb 218 | CNIOAtomics: 8edf08644e5e6fa0f021c239be9e8beb1cd9ef18 219 | CNIOBoringSSL: 2c9c96c2e95f15e83fb8d26b9738d939cc39ae33 220 | CNIOBoringSSLShims: c5c9346e7bbd1040f4f8793a35441dda7487539a 221 | CNIODarwin: 93850990d29f2626b05306c6c9309f9be0d74c2f 222 | CNIOHTTPParser: 8ce395236fa1d09ac3b4f4bcfba79b849b2ac684 223 | CNIOLinux: 62e3505f50de558c393dc2f273dde71dcce518da 224 | CNIOWindows: 3047f2d8165848a3936a0a755fee27c6b5ee479b 225 | CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082 226 | FlowSDK: 8487d7a00b17beb034d01c4d62fa1171666e8423 227 | gRPC-Swiftp: 1f5a05ce5b544bff3dce93223e72829daac26113 228 | Logging: beeb016c9c80cf77042d62e83495816847ef108b 229 | secp256k1Swift: ea49d2b06724444a03cf7938a2d3fc7acc4c0f08 230 | secp256k1Wrapper: 0378417cd06d51187bbc9e178ec318e7902e2120 231 | SwiftNIO: 829958aab300642625091f82fc2f49cb7cf4ef24 232 | SwiftNIOConcurrencyHelpers: 697370136789b1074e4535eaae75cbd7f900370e 233 | SwiftNIOCore: 473fdfe746534d7aa25766916459eeaf6f92ef49 234 | SwiftNIOEmbedded: ffcb5147db67d9686c8366b7f8427b36132f2c8a 235 | SwiftNIOExtras: 481f74d6bf0b0ef699905ed66439cb019c4975c9 236 | SwiftNIOFoundationCompat: b9cdbea4806e4a12e9f66d9696fa3b98c4c3232b 237 | SwiftNIOHPACK: e7d3ff5bd671528adfb11cd4e0c84ddfdc3c4453 238 | SwiftNIOHTTP1: ef56706550a1dc135ea69d65215b9941e643c23b 239 | SwiftNIOHTTP2: cc81d7a6ba70d2ddc5376f471904b27ef5d2b7b8 240 | SwiftNIOPosix: b49af4bdbecaadfadd5c93dfe28594d6722b75e4 241 | SwiftNIOSSL: d153c5a6fc5b2301b0519b4c4d037a9414212da6 242 | SwiftNIOTLS: 598af547490133e9aac52aed0c23c4a90c31dcfc 243 | SwiftNIOTransportServices: 0b2b407819d82eb63af558c5396e33c945759503 244 | SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932 245 | 246 | PODFILE CHECKSUM: 261f01bf031de73c070a9562a5b917a453d5f0a0 247 | 248 | COCOAPODS: 1.15.2 249 | -------------------------------------------------------------------------------- /images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blocto/flow-swift-sdk/c5f9c8a60d6e30b66a177bc99631037680c0bd7b/images/logo.jpg --------------------------------------------------------------------------------